Skip to content

[WIP] Feature: Add nobrainer.qc module for brain MRI quality control #377

Description

@dhritimandas

A new nobrainer/qc/ module that provides:

  1. 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.

  2. 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).

  3. 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.

  4. Slice extraction (slice_extractor.py) — 3D → 2D extraction with mid-slice and max-information strategies, for feeding brain MRI to 2D vision-language models.

  5. VLM response parsing (evaluate.py) — Standardized prompt template and score/reason parser for VLM-based quality assessment.

  6. Pipeline gating (gate.py) — Threshold-based accept/reject/review decisions from quality scores.

  7. CLI integrationnobrainer 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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions