Code for curating, processing, and analyzing the NIBS myelin mapping pilot dataset, developed by the Lifespan Informatics and Neuroimaging Center (LINC) at Penn. The study acquires multi-modal MRI data (T1w, T2w, MP2RAGE, ihMTRAGE, MESE, MEGRE, dMRI) across two sessions to derive and compare myelin-sensitive measures including g-ratio, T1w/T2w ratio, R1, ihMT saturation, T2*, and susceptibility-based metrics.
| Directory | Contents |
|---|---|
configuration/ |
Path configs, BIDS/report specs, and shared scalar metadata (patterns.json, name_mapper.json, scalar_modalities.json, scalar_groups.tsv) |
curation/ |
Numbered pipeline scripts (shell + Python) that convert raw DICOMs into a BIDS dataset |
processing/ |
Python processing pipelines for each imaging modality |
analysis/ |
Scripts for correlation matrices, parcellation, ICC, brain masks, QC reports, and figures |
data/ |
Tabular data (correlation matrices, missingness, manual QC ratings) safe to share on GitHub |
figures/ |
Manuscript figures generated by analysis scripts |
tests/ |
Pytest test suite |
Scripts in curation/ are run in order. Shell scripts (.sh) run on CUBIC — 03_run_heudiconv.sh
and 11_reface_anatomicals.sh are SLURM array jobs, the rest are plain shell.
Python scripts (.py) can be run locally.
| Step | Script | Description |
|---|---|---|
| 00 | 00_download_data.sh |
Download data from the scanner for each subject |
| 01 | 01_unzip_dicom_zips.py |
Unzip top-level DICOM archives |
| 02 | 02_unzip_dicoms.py |
Unzip nested DICOM zips in the scitran layout |
| 03 | 03_run_heudiconv.sh |
Run heudiconv to convert DICOMs to BIDS (uses heuristic.py) |
| 03b | 03b_convert_mp2rage_phase.py |
Convert MP2RAGE RR phase DICOMs to NIfTI with dcm2niix |
| 03c | 03c_fix_mp2rage_phase.py |
Fix MP2RAGE phase filenames and remove bad conversions |
| 04 | 04_split_ihmt.py |
Split 4D ihMTRAGE NIfTIs into individual 3D BIDS volumes |
| 05 | 05_chmod.sh |
Set write permissions for JSON editing |
| 06 | 06_anonymize_acqtimes.py |
Round acquisition times and write session-level metadata |
| 07 | 07_clean_jsons.py |
Remove sensitive/unneeded fields from JSON sidecars |
| 08 | 08_fix_bids.py |
Post-heudiconv fixes (bvec/bval, phase units, MP2RAGE/MESE metadata) |
| 09 | 09_validate_bids.sh |
Run the BIDS validator |
| 10 | 10_initialize_datalad.sh |
Initialize a DataLad dataset and make the initial commit |
| 11 | 11_reface_anatomicals.sh |
Deface T1w, T2w, and MP2RAGE images |
| 12 | 12_rename_bad_mese.py |
Correct swapped PA/AP phase-encoding labels in MESE files |
In a perfect world, 03b_convert_mp2rage_phase.py, 03c_fix_mp2rage_phase.py, and 12_rename_bad_mese.py would be handled by heudiconv or in 08_fix_bids.py.
Each module in processing/ is a standalone script. All share a common utils.py with
load_config, run_command, get_filename, coregister_to_t1, and helper functions.
| Module | Description |
|---|---|
process_mp2rage.py |
B1 correction and R1 mapping via pymp2rage |
process_ihmt.py |
ihMTRAGE processing: motion correction, coregistration, ihMT/MTR maps |
process_t1wt2w_ratio.py |
T1w/T2w myelin-weighted ratio maps |
process_g_ratio_scaling_factors.py |
Per-subject splenium scalar extraction for g-ratio scaling |
aggregate_g_ratio_scaling_factors.py |
Aggregate splenium sidecars and print g-ratio scaling factors |
process_g_ratio.py |
G-ratio computation from myelin and axon volume fractions |
process_mese.py |
Multi-echo spin-echo T2/R2 fitting |
process_megre.py |
Multi-echo GRE T2*/R2* fitting |
process_qsm.py |
QSM estimation via SEPIA and Chi-separation toolbox |
process_qsm_post.py |
Rename MATLAB QSM outputs to BIDS format and warp to standard space |
generate_myelin_reports.py |
HTML reports with scalar map overlays |
generate_coregistration_reports.py |
HTML reports checking cross-modal coregistration |
Upstream pipelines (sMRIPrep, QSIPrep, QSIRecon, NextBrain) and the modality scripts are
submitted on CUBIC via the submit_*.sbatch scripts in the same directory.
See processing/README.md for which steps run on CUBIC versus the lab PC.
| Script | Description |
|---|---|
build_missingness_list.py |
Missingness matrix for acquired modalities |
plot_missingness.py |
Plot missingness results |
build_brain_mask.py |
Build a study-wide brain mask from multi-modal masks |
calculate_brain_mask_dice.py |
Dice overlap between modality-specific brain masks and smriprep |
parcellate_scalar_maps.py |
Extract parcellated values per subject/session |
generate_correlation_matrices.py |
Compute mean Fisher-z correlation matrices across subjects |
plot_correlation_matrices_clustered.py |
Hierarchically clustered correlation heatmaps |
plot_correlation_matrix_diffs.py |
Difference maps between tissue-type correlation matrices |
plot_myelin_scalar_maps.py |
Mean scalar map brain overlays per session |
plot_myelin_scalar_maps_multi.py |
Mean scalar map brain overlays in groups |
plot_myelin_scalar_maps_individual.py |
Per-subject scalar map brain overlays |
compute_dkt_parcel_stats.py |
Per-subject DKT parcel statistics and coverage for scalar maps |
compute_bundle_myelin_stats.py |
QSIRecon-style scalarstats TSVs for warped T1w bundles |
bundle_mapping_utils.py |
Standalone bundle scalar mapping outside QSIRecon |
compute_icc.py |
Parcel-wise GM + WM ICC analysis in MNI152NLin2009cAsym space |
generate_qc_report.py |
Multipage PDF for ACPC/T1w spatial QC and scalar coverage |
workflow_graph.py |
Shared declaration of the processing workflow graph plus drawing primitives |
plot_workflow_modality_sets.py |
Plot source modalities against the scalar sets they produce |
utils.py |
Shared helpers for the analysis scripts |
The submit_*.sbatch / submit_*.sh scripts in analysis/ run the longer jobs
(bundle stats, DKT parcel stats, ICC, QC report) on CUBIC.
Install the dependency set that matches your task:
micromamba env create -f environment_curation.yml --channel-priority=flexible
micromamba env create -f environment_processing.yml --channel-priority=flexibleActivate the environment you need to use:
micromamba activate curation
micromamba activate processing--channel-priority=flexible is required. Both files were produced by
conda env export on CUBIC, where packages were installed from a mix of
conda-forge and defaults. Under the default strict channel priority, the
solver will not fall back to defaults for any package name that conda-forge
also publishes, so the ~39 defaults-only build strings (python,
_libgcc_mutex, qt-main, the xorg-* packages, …) become unsatisfiable and
the solve fails with a long "not installable because it conflicts with any
installable versions previously reported" list. The flag lets the solver mix
channels the same way the cluster environment was actually built.
conda also works in place of micromamba, with the equivalent
--channel-priority flexible.
A few pins were relaxed because the exported set was internally contradictory —
conda env export records whatever is installed, which on a long-lived
environment is not necessarily anything a solver would produce:
| File | Pin | Was | Why |
|---|---|---|---|
environment_processing.yml |
nitransforms |
25.0.0 |
Requires numpy>=2.1, but tensorflow==2.17.0 requires numpy<2.0.0. Unsatisfiable at any numpy. 24.1.4 is the last release before the numpy 2.1 floor; every other pin is unchanged. |
environment_curation.yml |
python |
3.11.0=ha86cf86_0_cpython |
That build predates the conda-forge xz/liblzma split and requires xz<5.3, conflicting with the pinned liblzma=5.8.1. Floated to 3.11 (resolves to 3.11.8). |
environment_curation.yml |
xz |
5.2.6=h166bdaf_0 |
Must version-match liblzma=5.8.1. |
Everything else matches the cluster environment exactly.
All paths are configured in per-machine YAML files in configuration/:
paths_cubic.yml for CUBIC and paths_pc.yml for the lab PC.
Update project_root to match your local or cluster mount point:
project_root: /cbica/projects/nibsScripts load these files via configuration.config.load_config(), which resolves
relative paths against project_root and returns a dictionary of absolute paths.
The config name defaults to 'pc'; pass load_config('cubic') to use the CUBIC paths.
pip install -r requirements_test.txt
pytest/cbica/projects/nibs/
|- code/ # Local clone of the GitHub repository
|- figures/ # Any figures for the manuscript
|_ data/ # Tabular data that may be shared on GitHub
|- dset/ # BIDS-compliant dataset
|- derivatives/ # Derivative data
|_ sourcedata/ # Raw data from the scanner