def _get_region_based_metrics(
    outputs: torch.Tensor,
    targets: torch.Tensor,
    metric_fn: Callable,
    class_dim=None,
    threshold: float = None,
    mode: str = "per-class",
    weights: Optional[List[float]] = None,
) -> torch.Tensor:
    """
    Get aggregated metric

    Args:
        outputs: [N; K; ...] tensor that for each of the N examples
            indicates the probability of the example belonging to each of
            the K classes, according to the model.
        targets:  binary [N; K; ...] tensor that encodes which of the K
            classes are associated with the N-th input
        metric_fn: metric function, that get statistics and return score
        class_dim: indicates class dimention (K) for
            ``outputs`` and ``targets`` tensors (default = 1), if
            mode = "micro" means nothing
        threshold: threshold for outputs binarization
        mode: class summation strategy. Must be one of ['micro', 'macro',
            'weighted', 'per-class']. If mode='micro', classes are ignored,
             and metric are calculated generally. If mode='macro', metric are
             calculated per-class and than are averaged over all classes. If
             mode='weighted', metric are calculated per-class and than summed
             over all classes with weights. If mode='per-class', metric are
             calculated separately for all classes
        weights: class weights(for mode="weighted")

    Returns:
        computed metric
    """
    assert mode in ["per-class", "micro", "macro", "weighted"]
    segmentation_stats = get_segmentation_statistics(
        outputs=outputs, targets=targets, class_dim=class_dim, threshold=threshold
    )
    if mode == "micro":
        segmentation_stats = [torch.sum(stats) for stats in segmentation_stats]
        metric = metric_fn(*segmentation_stats)

    metrics_per_class = metric_fn(*segmentation_stats)

    if mode == "macro":
        metric = torch.mean(metrics_per_class)
    elif mode == "weighted":
        assert len(weights) == len(segmentation_stats[0])
        device = metrics_per_class.device
        metrics = torch.tensor(weights).to(device) * metrics_per_class
        metric = torch.sum(metrics)
    elif mode == "per-class":
        metric = metrics_per_class

    return metric

    Get aggregated metric

    Args:
        outputs: [N; K; ...] tensor that for each of the N examples
            indicates the probability of the example belonging to each of
            the K classes, according to the model.
        targets:  binary [N; K; ...] tensor that encodes which of the K
            classes are associated with the N-th input
        metric_fn: metric function, that get statistics and return score
        class_dim: indicates class dimention (K) for
            ``outputs`` and ``targets`` tensors (default = 1), if
            mode = "micro" means nothing
        threshold: threshold for outputs binarization
        mode: class summation strategy. Must be one of ['micro', 'macro',
            'weighted', 'per-class']. If mode='micro', classes are ignored,
             and metric are calculated generally. If mode='macro', metric are
             calculated per-class and than are averaged over all classes. If
             mode='weighted', metric are calculated per-class and than summed
             over all classes with weights. If mode='per-class', metric are
             calculated separately for all classes
        weights: class weights(for mode="weighted")

    Returns:
        computed metric
    
catalyst/metrics/functional/_segmentation.py