Add supervised WMH detection module (FSL BIANCA)#116
Merged
Conversation
Add a self-contained, sourceable module src/modules/wmh_bianca.sh implementing supervised white-matter-hyperintensity detection via FSL BIANCA, plus a documented, default-OFF config block. The literature (Griffanti et al. 2016) shows supervised tools (BIANCA, LST) outperform unsupervised intensity thresholding for small-lesion sensitivity, which matters for brainstem/pons WMH. Module (entry function run_bianca_wmh): - Detects bianca + make_bianca_mask; graceful non-fatal skip if absent. - Builds a query masterfile (FLAIR [+T1], brain mask, FLAIR->MNI .mat for spatial features) and runs bianca with tunable featuresubset / spatialweight / patchsizes / matfeaturenum / trainingnums / save+load classifier data. - Supports either training from a manual-mask masterfile or loading a pre-trained classifier; graceful skip (with clear guidance) when neither is configured (expected on a fresh deployment). - When training, aligns the appended query row to the training column layout by inserting a placeholder at the label column and shifting auto-derived feature indices accordingly; trains only on real training rows (never the query). - Thresholds the probability map at BIANCA_THRESHOLD (default 0.9), optional min-cluster-size post-processing, reports cluster count + volume. - Intersects the WMH mask with the pipeline's brainstem mask and reports brainstem-restricted WMH separately, using safe_fslmaths throughout. Config: WMH_BIANCA_ENABLED=false plus BIANCA_TRAINING_MASTERFILE, BIANCA_TRAINING_DIR, BIANCA_LOAD/SAVE_CLASSIFIER, BIANCA_THRESHOLD, BIANCA_PATCHSIZES, BIANCA_SPATIALWEIGHT, and column-layout/feature options. Hardened against the pipeline's `set -e -u -o pipefail`: guarded grep/find/pipe substitutions, numeric validation of threshold/min-cluster, space-in-path detection (BIANCA masterfiles cannot quote), and CWD-independent config sourcing. Not wired into the pipeline yet (left to a follow-up integration unit). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts: # config/default_config.sh
davidj-brewster
added a commit
that referenced
this pull request
Jun 15, 2026
Add a self-contained, sourceable module src/modules/wmh_bianca.sh implementing supervised white-matter-hyperintensity detection via FSL BIANCA, plus a documented, default-OFF config block. The literature (Griffanti et al. 2016) shows supervised tools (BIANCA, LST) outperform unsupervised intensity thresholding for small-lesion sensitivity, which matters for brainstem/pons WMH. Module (entry function run_bianca_wmh): - Detects bianca + make_bianca_mask; graceful non-fatal skip if absent. - Builds a query masterfile (FLAIR [+T1], brain mask, FLAIR->MNI .mat for spatial features) and runs bianca with tunable featuresubset / spatialweight / patchsizes / matfeaturenum / trainingnums / save+load classifier data. - Supports either training from a manual-mask masterfile or loading a pre-trained classifier; graceful skip (with clear guidance) when neither is configured (expected on a fresh deployment). - When training, aligns the appended query row to the training column layout by inserting a placeholder at the label column and shifting auto-derived feature indices accordingly; trains only on real training rows (never the query). - Thresholds the probability map at BIANCA_THRESHOLD (default 0.9), optional min-cluster-size post-processing, reports cluster count + volume. - Intersects the WMH mask with the pipeline's brainstem mask and reports brainstem-restricted WMH separately, using safe_fslmaths throughout. Config: WMH_BIANCA_ENABLED=false plus BIANCA_TRAINING_MASTERFILE, BIANCA_TRAINING_DIR, BIANCA_LOAD/SAVE_CLASSIFIER, BIANCA_THRESHOLD, BIANCA_PATCHSIZES, BIANCA_SPATIALWEIGHT, and column-layout/feature options. Hardened against the pipeline's `set -e -u -o pipefail`: guarded grep/find/pipe substitutions, numeric validation of threshold/min-cluster, space-in-path detection (BIANCA masterfiles cannot quote), and CWD-independent config sourcing. Not wired into the pipeline yet (left to a follow-up integration unit). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a self-contained, sourceable module
src/modules/wmh_bianca.shimplementing supervised white-matter-hyperintensity (WMH) detection via FSL BIANCA, plus a documented, default-OFF config block inconfig/default_config.sh.The literature (Griffanti et al., NeuroImage 2016) shows supervised tools (BIANCA, LST) outperform unsupervised intensity thresholding for small-lesion sensitivity — exactly the regime relevant to brainstem/pons WMH. This is the FSL BIANCA unit of a parallel best-practices upgrade.
This module is not yet wired into the pipeline — it is intentionally kept conflict-free for a follow-up integration unit.
Dependency
bianca,make_bianca_mask, andcluster/flirtfor post-processing). All detected at runtime; absence is a graceful, non-fatal skip (never crashes the pipeline).Training-data requirement (important)
BIANCA is a k-NN supervised classifier. It requires either:
BIANCA_TRAINING_MASTERFILE), orBIANCA_LOAD_CLASSIFIER, produced by a prior--saveclassifierdatarun).With neither configured (the common case on a fresh deployment), the module logs a clear warning explaining the requirement and skips gracefully. This is expected and documented prominently in both the module header and the config comments.
What
run_bianca_wmh()does.matfor spatial features if not supplied.biancawith tunable--featuresubset,--spatialweight,--patchsizes,--matfeaturenum,--trainingnums, and--saveclassifierdata/--loadclassifierdata.BIANCA_THRESHOLD(default 0.9) → binary WMH mask; optionalBIANCA_MIN_CLUSTER_SIZEpost-processing; reports cluster count + total volume.*brainstem*mask*.nii.gz) and reports brainstem-restricted WMH separately, usingsafe_fslmathsthroughout.Config (default_config.sh, all default-safe)
WMH_BIANCA_ENABLED=false,BIANCA_TRAINING_MASTERFILE,BIANCA_TRAINING_DIR,BIANCA_LOAD_CLASSIFIER,BIANCA_SAVE_CLASSIFIER,BIANCA_THRESHOLD=0.9,BIANCA_PATCHSIZES,BIANCA_SPATIALWEIGHT,BIANCA_PATCH3D,BIANCA_TRAININGPTS,BIANCA_NONLESPTS,BIANCA_SELECTPTS,BIANCA_MIN_CLUSTER_SIZE, plus column-layout overrides (BIANCA_LABEL_FEATURENUM,BIANCA_BRAINMASK_FEATURENUM,BIANCA_FEATURESUBSET,BIANCA_MATFEATURENUM,BIANCA_TRAININGNUMS).Integration hook (for the coordinator to wire later)
Add this one line to the analysis stage (after the brainstem mask + standard-space FLAIR/T1 exist), guarded so a non-fatal skip never aborts the stage:
(and
source src/modules/wmh_bianca.shalongside the other module sources.)Verification
bash -nandshellcheck --severity=errorclean across the whole repo.test_environment_unit.sh(100),test_pipeline_control_unit.sh(98),test_import_unit.sh(29); pytest 26 passed.bash src/pipeline.sh --help | grep -q "Usage:"passes.set -e -u -o pipefail:run_bianca_wmhdefined, double-sourcing is a no-op, and the absent-tool / no-training / missing-input / empty-training paths all log a graceful skip and return non-zero without crashing the shell. Masterfile column alignment (placeholder insertion, shifted feature indices,trainingnumswithout trailing comma) verified end-to-end with mock training data.Real end-to-end BIANCA execution needs training data + FSL + MRI and is out of scope for CI.
🤖 Generated with Claude Code