functions
Pure per-scan compute for the lesion calculation step.
Version-agnostic: parses one scan's B-scan predictions once, measures every
configured group (area, volume, per-lesion detail, fovea-relative geometry),
and lifts the result into the cache-facing LesionMetrics dataclass.
Module
Functions
compute_lesion_metrics_for_scan
def compute_lesion_metrics_for_scan( bscan_predictions: tuple[str, ...], groups: Mapping[str, MaskGroupSpec], scale: VoxelScale, *, fovea_centre: tuple[int, int, int] | None = None, roi_radius_mm: float | None = None, max_lesions_per_group: int = 256, declared_num_bscans: int | None = None, angular_span_min_radius_mm: float | None = None,) ‑> LesionMetrics:Measure every configured group for one scan.
Every area-eligible segmentation is parsed (not only the labels the
configured groups name), because parse_mask_json requires a contiguous
label-index space sized to the mapping it is given. The groups are handed to
the parse rather than applied after it, because a group's voxel count has to
be accumulated while each B-scan's raster still carries axial positions —
combining per-label counts afterwards cannot recover them. Depth is
collected only when scale supports a volume, so a group with no axial
spacing pays nothing for a measurement it cannot report, and only for groups
whose volume is meaningful (group_reports_volume).
Arguments
bscan_predictions: One raw prediction string per B-scan.groups: Named label groups to measure.scale: The cube's voxel dimensions.fovea_centre:(bscan, column, row)voxel index of the fovea landmark, orNonewhen no landmark was available for this scan. Only the first two elements (bscan,column) are used as the en-face reference; the third (the axial row) is carried through unused, since the en-face plane has already collapsed that axis.roi_radius_mm: Radius in mm of a region of interest centred onfovea_centre, orNoneto skip it. Has no effect without a fovea reference.max_lesions_per_group: Cap on lesions measured in detail per group; the largest are kept.declared_num_bscans: The scan's own frame count, so trailing padding from the inference run's wider scans is not measured. Seeparse_bscan_masks.angular_span_min_radius_mm: Radius inside which cells contribute no angle toaggregate_angular_span, orNonefor no floor. SeeLesionCalculationConfig.angular_span_min_radius_mmfor why a trial has to choose one.
Returns The scan's per-group metrics.
Raises
Exception: Propagates any parsing or computation failure so the caller can record it against the file.