mask_groups
A named group of segmentation labels and how its mask is combined.
Shared vocabulary rather than step-local config: lesion_calculation measures
groups, and any later per-lesion morphometry measures the SAME groups, so the
definition of "what counts as GA in this trial" lives in one place.
Classes
LesionConnectivity
class LesionConnectivity(*args, **kwds):Whether a lesion is one component on the en-face plane or in the volume.
EN_FACE matches what a clinician counts looking at the projection, and is
right for drusen, which sit in a thin band above Bruch's membrane. VOLUME
separates biomarkers that genuinely stack axially — two fluid cysts in the
same column are two cysts.
StrEnum for the same reason as MaskCombineMode.
Ancestors
MaskCombineMode
class MaskCombineMode(*args, **kwds):How a group's include labels are combined into one mask.
intersection is the GA definition: a column counts only where EVERY
include label is present (atrophy is evidenced by co-located layers).
union is the drusen definition: hard, soft and confluent drusen are
alternative subtypes, so a column counts where ANY of them is present.
Summing the three per-label areas instead would double-count any column
carrying two subtypes.
StrEnum, so a member is its own YAML/JSON representation: it binds from
the plain string a template writes, and model_dump(mode="json") emits
that same string — which is what flows/dag/hashing.py hashes into
task_hash, so the vocabulary can gain a spelling without rotating a
cache partition.
Ancestors
MaskGroupSpec
class MaskGroupSpec(**data: Any):One named group of segmentation labels, and how to combine them.
Attributes
include: Labels whose masks are combined percombine. An empty list includes nothing (matching the GA parser), never everything.exclude: Labels whose presence removes a cell, combined as a union and applied afterinclude. An empty list excludes nothing.combine:intersection(GA) orunion(drusen).na_bscans: How to treat B-scans the model produced no output for.retainkeeps them as zero rows;dropremoves them before measuring, compacting the B-scan axis.lesion_connectivity: Whether a lesion is one connected component on the en-face plane or in the full volume.measure_lesions: Whether to measure each lesion individually — its own area, volume, diameters and fovea-relative geometry — instead of only the group totals. Off by default because labelling and measuring every lesion is expensive relative to an area sum.
Raises
ValueError: If a label appears in bothincludeandexclude.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
Variables
- static
combine : MaskCombineMode
- static
exclude : list[str]
- static
include : list[str]
- static
lesion_connectivity : LesionConnectivity
- static
measure_lesions : bool
- static
model_config
- static
na_bscans : NaBscanMode
NaBscanMode
class NaBscanMode(*args, **kwds):How a group treats B-scans the model produced no output for.
RETAIN measures them as empty at their true index, which keeps two
lesions either side of a skipped frame distinct. DROP removes them
before measuring, compacting the B-scan axis — the GA path's behaviour,
and what a group must use to reproduce GA's published numbers. Under
DROP, max_area_bscan_index indexes the compacted axis.
Neither mode sees the trailing padding a shorter scan carries: the
inference cache stores one key per column of a run-wide DataFrame, so a
file with fewer frames than the widest in its run is padded with nulls.
parse_bscan_masks truncates that padding for every group before either
mode applies, so distance_from_image_centre is centred on the scan's own
frames rather than the run's widest.
StrEnum for the same reason as MaskCombineMode.