A new nobrainer/qc/ module that provides:
-
Severity-calibrated corruption generation (corruption_configs.py, corrupt.py) — 8 corruption types (motion, ghosting, spike, noise, bias field, blur, downsampling, gamma) with severity levels, with fixed seeds and JSON sidecar metadata for reproducibility.
-
Signal-based IQM extraction (metrics.py) — SNR, CNR, EFC, FBER, CJV computed in pure PyTorch, using SynthSeg segmentations for tissue classification (Otsu fallback when unavailable).
-
Machine preference scoring (preference.py) — Per-structure Dice between reference and corrupted SynthSeg segmentations, using monai.metrics.DiceMetric and FreeSurfer label IDs from nobrainer.data.tissue_classes.
-
Slice extraction (slice_extractor.py) — 3D → 2D extraction with mid-slice and max-information strategies, for feeding brain MRI to 2D vision-language models.
-
VLM response parsing (evaluate.py) — Standardized prompt template and score/reason parser for VLM-based quality assessment.
-
Pipeline gating (gate.py) — Threshold-based accept/reject/review decisions from quality scores.
-
CLI integration — nobrainer qc corrupt and nobrainer qc iqms subcommands via Click, following existing CLI patterns.
Nobrainer currently provides training infrastructure (models, losses, augmentation, prediction) but lacks a quality control component. There is no existing tool in the nobrainer/NiPreps ecosystem that:
- Systematically generates calibrated corruptions for QC benchmarking
- Quantifies how much a corruption degrades downstream task performance
- Integrates multimodal LLM-based quality scoring into a gating decision
This module addresses that gap.
Design decisions
Corruption engine uses TorchIO (not MONAI): The existing nobrainer.augmentation module uses MONAI dictionary transforms for on-the-fly training augmentation via TrainableCompose.
The QC module has different requirements: deterministic offline corruption with metadata tracking, operating on tio.Subject objects. TorchIO also provides k-space physics simulation (motion, ghosting, spike) that MONAI does not. Keeping these separate avoids coupling QC corruption to the training augmentation pipeline.
No modifications to existing modules. The only change to existing code is adding a @cli.group() entry point for nobrainer qc in cli/main.py. nobrainer.augmentation, nobrainer.dataset, nobrainer.metrics, and nobrainer.losses are untouched.
Reuses existing infrastructure. FreeSurfer label IDs come from nobrainer.data.tissue_classes. Type hints, docstrings, and test patterns follow the conventions in metrics.py, losses.py, and tests/unit/test_synthseg.py.
Proposed file structure
nobrainer/qc/
├── __init__.py
├── corruption_configs.py
├── corrupt.py
├── metrics.py
├── preference.py
├── slice_extractor.py
├── evaluate.py
└── gate.py
nobrainer/tests/unit/
├── test_qc_corruption_configs.py
├── test_qc_corrupt.py
├── test_qc_metrics.py
├── test_qc_preference.py
├── test_qc_slice_extractor.py
└── test_qc_gate.py
New dependency
torchio — already a common companion to nobrainer in neuroimaging workflows. Used for corruption simulation only.
Advantages
- Enables systematic QC benchmarking for any nobrainer segmentation or prediction pipeline
- Provides a reusable corruption generation tool
- Bridges traditional signal-based QC (mriqc-style IQMs) with emerging VLM-based approaches
- Works both standalone (research benchmarking) and integrated (as a pipeline gating step before
nobrainer predict)
A new nobrainer/qc/ module that provides:
Severity-calibrated corruption generation (
corruption_configs.py,corrupt.py) — 8 corruption types (motion, ghosting, spike, noise, bias field, blur, downsampling, gamma) with severity levels, with fixed seeds and JSON sidecar metadata for reproducibility.Signal-based IQM extraction (
metrics.py) — SNR, CNR, EFC, FBER, CJV computed in pure PyTorch, using SynthSeg segmentations for tissue classification (Otsu fallback when unavailable).Machine preference scoring (
preference.py) — Per-structure Dice between reference and corrupted SynthSeg segmentations, usingmonai.metrics.DiceMetricand FreeSurfer label IDs fromnobrainer.data.tissue_classes.Slice extraction (
slice_extractor.py) — 3D → 2D extraction with mid-slice and max-information strategies, for feeding brain MRI to 2D vision-language models.VLM response parsing (
evaluate.py) — Standardized prompt template and score/reason parser for VLM-based quality assessment.Pipeline gating (
gate.py) — Threshold-based accept/reject/review decisions from quality scores.CLI integration —
nobrainer qc corruptandnobrainer qc iqmssubcommands via Click, following existing CLI patterns.Nobrainer currently provides training infrastructure (models, losses, augmentation, prediction) but lacks a quality control component. There is no existing tool in the nobrainer/NiPreps ecosystem that:
This module addresses that gap.
Design decisions
Corruption engine uses TorchIO (not MONAI): The existing
nobrainer.augmentationmodule uses MONAI dictionary transforms for on-the-fly training augmentation viaTrainableCompose.The QC module has different requirements: deterministic offline corruption with metadata tracking, operating on
tio.Subjectobjects. TorchIO also provides k-space physics simulation (motion, ghosting, spike) that MONAI does not. Keeping these separate avoids coupling QC corruption to the training augmentation pipeline.No modifications to existing modules. The only change to existing code is adding a
@cli.group()entry point fornobrainer qcincli/main.py.nobrainer.augmentation,nobrainer.dataset,nobrainer.metrics, andnobrainer.lossesare untouched.Reuses existing infrastructure. FreeSurfer label IDs come from
nobrainer.data.tissue_classes. Type hints, docstrings, and test patterns follow the conventions inmetrics.py,losses.py, andtests/unit/test_synthseg.py.Proposed file structure
New dependency
torchio— already a common companion to nobrainer in neuroimaging workflows. Used for corruption simulation only.Advantages
nobrainer predict)