def is_per_image_tprs(
    per_image_tprs: torch.Tensor,
    image_classes: torch.Tensor,
) -> None:
    """Validate per-image true positive rates.

    Args:
        per_image_tprs: Tensor of TPR values for each image.
        image_classes: Binary tensor indicating normal (0) or anomalous (1)
            images.

    Raises:
        ValueError: If TPRs have invalid values or wrong monotonicity.

    Example:
        >>> tprs = torch.zeros(10, 5)  # 10 images, 5 thresholds
        >>> classes = torch.zeros(10, dtype=torch.bool)
        >>> is_per_image_tprs(tprs, classes)  # No error
    """
    is_images_classes(image_classes)
    # general validations
    is_per_image_rate_curves(
        per_image_tprs,
        nan_allowed=True,  # normal images have NaN TPRs
        decreasing=None,  # not checked here
    )

    # specific to anomalous images
    is_per_image_rate_curves(
        per_image_tprs[image_classes == 1],
        nan_allowed=False,
        decreasing=True,
    )

    # specific to normal images
    normal_images_tprs = per_image_tprs[image_classes == 0]
    if not normal_images_tprs.isnan().all():
        msg = "Expected all normal images to have NaN TPRs, but some have non-NaN values."
        raise ValueError(msg)
Validate per-image true positive rates.

    Args:
        per_image_tprs: Tensor of TPR values for each image.
        image_classes: Binary tensor indicating normal (0) or anomalous (1)
            images.

    Raises:
        ValueError: If TPRs have invalid values or wrong monotonicity.

    Example:
        >>> tprs = torch.zeros(10, 5)  # 10 images, 5 thresholds
        >>> classes = torch.zeros(10, dtype=torch.bool)
        >>> is_per_image_tprs(tprs, classes)  # No error
    
src/anomalib/metrics/pimo/_validate.py