def pro_score(
    predictions: torch.Tensor,
    comps: torch.Tensor,
    threshold: float = 0.5,
) -> torch.Tensor:
    """Calculate the PRO score for a batch of predictions.

    Args:
        predictions (torch.Tensor): Predicted anomaly masks of shape
            ``(B, 1, H, W)``
        comps (torch.Tensor): Labeled connected components of shape ``(B, H, W)``.
            Components should be labeled from 0 to N
        threshold (float, optional): Threshold for binarizing float predictions.
            Defaults to ``0.5``

    Returns:
        torch.Tensor: Scalar tensor containing the average PRO score

    Example:
        >>> # Assuming predictions and components are properly shaped tensors
        >>> score = pro_score(predictions, components, threshold=0.5)
        >>> print(f"PRO Score: {score:.4f}")
    """
    if predictions.dtype == torch.float:
        predictions = predictions > threshold

    n_comps = len(comps.unique())

    preds = comps.clone()
    # match the shapes in case one of the tensors is N1HW
    preds = preds.reshape(predictions.shape)
    preds[~predictions] = 0
    if n_comps == 1:  # only background
        return torch.Tensor([1.0])

    # Even though ignore_index is set to 0, the final average computed with
    # "macro" takes the entire length of the tensor into account. That's why we
    # need to manually subtract 1 from the number of components after taking the
    # sum
    recall_tensor = recall(
        preds.flatten(),
        comps.flatten(),
        task="multiclass",
        num_classes=n_comps,
        average=None,
        ignore_index=0,
    )
    return recall_tensor.sum() / (n_comps - 1)
Calculate the PRO score for a batch of predictions.

    Args:
        predictions (torch.Tensor): Predicted anomaly masks of shape
            ``(B, 1, H, W)``
        comps (torch.Tensor): Labeled connected components of shape ``(B, H, W)``.
            Components should be labeled from 0 to N
        threshold (float, optional): Threshold for binarizing float predictions.
            Defaults to ``0.5``

    Returns:
        torch.Tensor: Scalar tensor containing the average PRO score

    Example:
        >>> # Assuming predictions and components are properly shaped tensors
        >>> score = pro_score(predictions, components, threshold=0.5)
        >>> print(f"PRO Score: {score:.4f}")
    
src/anomalib/metrics/pro.py