bioimage_py.evaluation.cremi_score

CREMI score: the geometric mean of the variation of information and the adapted rand error.

This was the evaluation metric of the CREMI challenge. It reuses a single contingency table to compute both the variation of information and the adapted rand error.

 1"""CREMI score: the geometric mean of the variation of information and the adapted rand error.
 2
 3This was the evaluation metric of the CREMI challenge. It reuses a single contingency table to compute
 4both the variation of information and the adapted rand error.
 5"""
 6from __future__ import annotations
 7
 8from typing import Optional, Sequence, Tuple
 9
10import numpy as np
11
12from ..runner.config import RunnerConfig
13from ..sources import SourceLike
14from ._common import build_table
15from .contingency_table import ContingencyTable
16from .rand_index import rand_scores
17from .variation_of_information import vi_scores
18
19__all__ = ["cremi_scores", "cremi_score"]
20
21
22def cremi_scores(table: ContingencyTable, *, use_log2: bool = True) -> Tuple[float, float, float, float]:
23    """Compute the CREMI score and its components from a single contingency table.
24
25    Args:
26        table: A contingency table built as ``contingency_table(segmentation, groundtruth)``.
27        use_log2: Whether to use ``log2`` (bits) or natural ``log`` (nats) for the VI part.
28
29    Returns:
30        The split variation of information, the merge variation of information, the adapted rand error,
31        and the CREMI score (``sqrt(adapted_rand_error * (vi_split + vi_merge))``).
32    """
33    vi_split, vi_merge = vi_scores(table, use_log2=use_log2)
34    adapted_rand_error, _ = rand_scores(table)
35    cremi = float(np.sqrt(adapted_rand_error * (vi_split + vi_merge)))
36    return vi_split, vi_merge, adapted_rand_error, cremi
37
38
39def cremi_score(
40    segmentation: SourceLike,
41    groundtruth: SourceLike,
42    *,
43    ignore_seg: Optional[Sequence[int]] = None,
44    ignore_gt: Optional[Sequence[int]] = None,
45    use_log2: bool = True,
46    num_workers: int = 1,
47    block_shape: Optional[Tuple[int, ...]] = None,
48    job_type: str = "local",
49    job_config: Optional[RunnerConfig] = None,
50    mask: Optional[SourceLike] = None,
51) -> Tuple[float, float, float, float]:
52    """Compute the CREMI score between two segmentations.
53
54    Args:
55        segmentation: Candidate segmentation to evaluate (a numpy/zarr/n5 array or a `Source`).
56        groundtruth: The groundtruth segmentation; same shape as ``segmentation``.
57        ignore_seg: Labels to ignore in the segmentation (their voxels are excluded).
58        ignore_gt: Labels to ignore in the groundtruth (their voxels are excluded).
59        use_log2: Whether to use ``log2`` (bits) or natural ``log`` (nats) for the VI part.
60        num_workers: Number of parallel workers used to build the contingency table.
61        block_shape: Shape of the processing blocks. Defaults to the input chunk shape.
62        job_type: Execution backend: one of ``"local"``, ``"subprocess"`` or ``"slurm"``.
63        job_config: Backend configuration (a `RunnerConfig` / `SlurmConfig`).
64        mask: Optional binary mask; voxels outside the mask are excluded.
65
66    Returns:
67        The split variation of information, the merge variation of information, the adapted rand error,
68        and the CREMI score.
69    """
70    table = build_table(segmentation, groundtruth, ignore_seg=ignore_seg, ignore_gt=ignore_gt,
71                        num_workers=num_workers, block_shape=block_shape, job_type=job_type,
72                        job_config=job_config, mask=mask)
73    return cremi_scores(table, use_log2=use_log2)
def cremi_scores( table: bioimage_py.evaluation.ContingencyTable, *, use_log2: bool = True) -> Tuple[float, float, float, float]:
23def cremi_scores(table: ContingencyTable, *, use_log2: bool = True) -> Tuple[float, float, float, float]:
24    """Compute the CREMI score and its components from a single contingency table.
25
26    Args:
27        table: A contingency table built as ``contingency_table(segmentation, groundtruth)``.
28        use_log2: Whether to use ``log2`` (bits) or natural ``log`` (nats) for the VI part.
29
30    Returns:
31        The split variation of information, the merge variation of information, the adapted rand error,
32        and the CREMI score (``sqrt(adapted_rand_error * (vi_split + vi_merge))``).
33    """
34    vi_split, vi_merge = vi_scores(table, use_log2=use_log2)
35    adapted_rand_error, _ = rand_scores(table)
36    cremi = float(np.sqrt(adapted_rand_error * (vi_split + vi_merge)))
37    return vi_split, vi_merge, adapted_rand_error, cremi

Compute the CREMI score and its components from a single contingency table.

Args: table: A contingency table built as contingency_table(segmentation, groundtruth). use_log2: Whether to use log2 (bits) or natural log (nats) for the VI part.

Returns: The split variation of information, the merge variation of information, the adapted rand error, and the CREMI score (sqrt(adapted_rand_error * (vi_split + vi_merge))).

def cremi_score( segmentation: 'SourceLike', groundtruth: 'SourceLike', *, ignore_seg: Optional[Sequence[int]] = None, ignore_gt: Optional[Sequence[int]] = None, use_log2: bool = True, num_workers: int = 1, block_shape: Optional[Tuple[int, ...]] = None, job_type: str = 'local', job_config: Optional[bioimage_py.runner.RunnerConfig] = None, mask: 'Optional[SourceLike]' = None) -> Tuple[float, float, float, float]:
40def cremi_score(
41    segmentation: SourceLike,
42    groundtruth: SourceLike,
43    *,
44    ignore_seg: Optional[Sequence[int]] = None,
45    ignore_gt: Optional[Sequence[int]] = None,
46    use_log2: bool = True,
47    num_workers: int = 1,
48    block_shape: Optional[Tuple[int, ...]] = None,
49    job_type: str = "local",
50    job_config: Optional[RunnerConfig] = None,
51    mask: Optional[SourceLike] = None,
52) -> Tuple[float, float, float, float]:
53    """Compute the CREMI score between two segmentations.
54
55    Args:
56        segmentation: Candidate segmentation to evaluate (a numpy/zarr/n5 array or a `Source`).
57        groundtruth: The groundtruth segmentation; same shape as ``segmentation``.
58        ignore_seg: Labels to ignore in the segmentation (their voxels are excluded).
59        ignore_gt: Labels to ignore in the groundtruth (their voxels are excluded).
60        use_log2: Whether to use ``log2`` (bits) or natural ``log`` (nats) for the VI part.
61        num_workers: Number of parallel workers used to build the contingency table.
62        block_shape: Shape of the processing blocks. Defaults to the input chunk shape.
63        job_type: Execution backend: one of ``"local"``, ``"subprocess"`` or ``"slurm"``.
64        job_config: Backend configuration (a `RunnerConfig` / `SlurmConfig`).
65        mask: Optional binary mask; voxels outside the mask are excluded.
66
67    Returns:
68        The split variation of information, the merge variation of information, the adapted rand error,
69        and the CREMI score.
70    """
71    table = build_table(segmentation, groundtruth, ignore_seg=ignore_seg, ignore_gt=ignore_gt,
72                        num_workers=num_workers, block_shape=block_shape, job_type=job_type,
73                        job_config=job_config, mask=mask)
74    return cremi_scores(table, use_log2=use_log2)

Compute the CREMI score between two segmentations.

Args: segmentation: Candidate segmentation to evaluate (a numpy/zarr/n5 array or a Source). groundtruth: The groundtruth segmentation; same shape as segmentation. ignore_seg: Labels to ignore in the segmentation (their voxels are excluded). ignore_gt: Labels to ignore in the groundtruth (their voxels are excluded). use_log2: Whether to use log2 (bits) or natural log (nats) for the VI part. num_workers: Number of parallel workers used to build the contingency table. block_shape: Shape of the processing blocks. Defaults to the input chunk shape. job_type: Execution backend: one of "local", "subprocess" or "slurm". job_config: Backend configuration (a RunnerConfig / SlurmConfig). mask: Optional binary mask; voxels outside the mask are excluded.

Returns: The split variation of information, the merge variation of information, the adapted rand error, and the CREMI score.