Renal BOLD MRI Analysis Framework with Multi-Layer Concentric Object (MLCO) Analysis, K-Means Zone Clustering, and Group-Level Statistics
BoldPy is a Python framework for quantitative BOLD MRI analysis using Multi-Layer Concentric Objects (MLCO). Developed for renal oxygenation studies in mouse models, it is applicable to any organ with concentric architecture (kidney, heart, eye).
The pipeline extracts T2*, R2*, and perfusion maps from raw MRI data, creates radial layer-by-layer segmentations from organ surface to center, and generates quantitative profiles enabling cortex-to-medulla-to-papilla analysis. Group-level comparisons, data-driven zone boundary detection, and heterogeneity analysis are built in.
Pipeline mode (looper): You can use looper to run the full pipeline automatically across all samples defined in a PEP project config:
looper run looper_config.yaml # runs per-sample pipeline on all samples
looper collate looper_config.yaml # runs project-level group analysisSee PEP Integration for setup details.
Standalone mode: Run individual scripts directly with their own CLI arguments — no looper or PEP config required. The Quick Start below follows this approach.
- MLCO analysis — 24-layer (configurable) bilateral radial segmentation from surface to center
- T2/R2/perfusion quantification** — per-layer bilateral statistics, ΔT2* oxygen response
- Intelligent T2 frame detection* — tiered: Bruker metadata → heuristic scoring → manual override
- Data-driven zone boundaries — k-means clustering on per-layer T2*/R2*/perfusion medians
- Two-workflow group comparison — shared reference (Workflow A) or per-sample boundaries (Workflow B)
- Project-level analysis — cross-group MLCO profiles, overlay visualization, heterogeneity metrics
- 18+ plotting functions — PNG/PDF/SVG, dynamic zone color support
- Bruker PvDatasets + DICOM support —
prepare_data.py/prepare_dicom.py - Robust missing-layer handling — NaN fill, no crashes on incomplete data
- YAML zone configuration — static or data-driven zone definitions
Group-level scripts now accept --pep project_config.yaml instead of --config groups_config.json.
The groups_config.json format is superseded by a PEP project_config.yaml + sample_table.csv
pair. All analysis scripts expose a run() function for programmatic use in addition to their CLI.
See PEP Integration for details.
Three generic, config-driven scripts replace the previous collection of per-project analysis
scripts. All accept --pep project_config.yaml and work with any experiment:
group_analysis.py— Cross-group MLCO profile comparison (mean ± SEM per layer, Mann-Whitney tests, zone-level summary statistics)overlay_analysis.py— K-means zone overlays + MLCO layer overlays + zone statistics dot-plot in one pass (k-means computed once, reused for all figure types)heterogeneity.py— Within-layer T2* heterogeneity profiling + focal disruption analysis (pixel distributions, spatial local-CV maps)
See pipeline/examples/project_config.yaml for the config template.
Data-driven zone boundary detection replaces fixed layer-to-zone mappings:
# Per-sample clustering (Workflow B)
python boldpy_analyze.py --config sample.json --cluster-zones --n-clusters 3
# Apply one reference to all samples (Workflow A)
python boldpy_analyze.py --group1-config g1.json --group2-config g2.json \
--compare --cluster-reference configs/zones/reference_k3.yamlSee K-Means Zone Clustering for full details.
git clone https://github.com/jpsmith5/boldpy
cd boldpy
pip install -e . # standard install
pip install -e ".[dev]" # with pytest, black, flake8
pip install -e ".[dicom]" # with DICOM support (pydicom)
pip install -e ".[docs]" # with MkDocs (for building this site)Requirements: Python >= 3.8, numpy, scipy, matplotlib, scikit-image, scikit-learn, Pillow, tqdm
Typical install time: ~2–5 minutes (first install, internet required); under 1 minute with a warm pip cache.
Tested on Python 3.10–3.12 with numpy 1.24–2.0, scipy 1.11–1.13, matplotlib 3.7–3.9, scikit-image 0.21–0.22, scikit-learn 1.3–1.5, Pillow 10.x, pydicom 2.4+ on Ubuntu 22.04 and Windows 11 (WSL2).
requirements.txt specifies minimum compatible version bounds. For exact version pinning (e.g., STAR Methods reproducibility requirements), run pip freeze > requirements-lock.txt after installation.
| Step | Typical time |
|---|---|
Data extraction (prepare_data.py / prepare_dicom.py) |
10–60 s |
ROI drawing (roi_drawer.py, interactive) |
2–5 min/sample |
MLCO generation (generate_mlco.py) |
5–30 s |
Per-sample analysis (boldpy_analyze.py) |
30–120 s |
| Project-level analysis (all three scripts, 5–10 samples) | 1–3 min |
A 10-sample cohort takes roughly 45–90 minutes total, dominated by interactive ROI drawing.
# Step 1: Extract maps from raw data
python prepare_data.py --input scan.PvDatasets --output-dir prepared/ --both-t2star
# or for DICOM:
python prepare_dicom.py --input /path/to/dicom/ --output-dir prepared/
# Step 2: Draw ROI interactively
python roi_drawer.py --image prepared/sample_reference.npy --output roi.npy
# Step 3: Generate MLCO layers (24-layer bilateral)
python generate_mlco.py --mask roi.npy --split \
--anatomical prepared/sample_reference.npy \
--n-layers 24 --output-dir mlco/ --label sample
# Step 4: Per-sample analysis
python boldpy_analyze.py --config sample_config.json \
--n-layers 24 --output-dir results/sample/sample_config.json (see example_config.json for a complete template):
{
"id": "sample_id",
"t2star_maps": {
"air": "prepared/sample_air_t2star_custom.npy",
"oxygen_1": "prepared/sample_oxygen1_t2star_custom.npy",
"oxygen_2": "prepared/sample_oxygen2_t2star_custom.npy"
},
"r2star_maps": {
"air": "prepared/sample_air_r2star_custom.npy",
"oxygen_1": "prepared/sample_oxygen1_r2star_custom.npy",
"oxygen_2": "prepared/sample_oxygen2_r2star_custom.npy"
},
"perfusion_map": "prepared/sample_perfusion.npy",
"mlco_mask": "mlco/sample_mlco_layers.npy"
}After running boldpy_analyze.py for all samples, create a project_config.yaml
(see pipeline/examples/project_config.yaml) and run:
python group_analysis.py --pep project_config.yaml
python overlay_analysis.py --pep project_config.yaml
python heterogeneity.py --pep project_config.yaml| Document | Description |
|---|---|
| Quick Start | Full 5-step workflow from raw data to group analysis |
| User Guide | Comprehensive per-sample and project-level workflow |
| Scripts Reference | All scripts with full options and outputs |
| K-Means Zone Clustering | Data-driven zone boundaries |
| Metrics Documentation | T2*, R2*, perfusion interpretation |
| Examples with Data | Expected outputs and result interpretation |
| Installation | Detailed setup and platform-specific notes |
| Changelog | Version history |
Build the documentation site locally:
pip install -e ".[docs]"
mkdocs serveboldpy/
├── boldpy_analyze.py # Per-sample pipeline orchestrator
├── prepare_data.py # Data extraction (Bruker PvDatasets)
├── prepare_dicom.py # Data extraction (DICOM)
├── roi_drawer.py # Interactive ROI drawing
├── generate_mlco.py # MLCO mask generation
├── mlco_analysis.py # Layer-by-layer quantification
├── boldpy_plots.py # 18+ plotting functions
├── boldpy_plots_multiregion.py # Multiregion comparison plots
├── cluster_zones.py # K-means zone boundary clustering
├── tissue_zones.py # Zone config management
├── group_analysis.py # Project: cross-group MLCO profiles
├── overlay_analysis.py # Project: K-means + MLCO overlays
├── heterogeneity.py # Project: heterogeneity analysis
├── fit_t2star.py # Standalone T2* fitting
├── roi_format_utils.py # ROI format utilities
├── boldpy/ # Python package (pip-installable)
│ ├── analysis/ # Perfusion analysis
│ ├── fitting/ # T2*/R2* curve fitting
│ └── loaders/ # Bruker PvDatasets + DICOM loaders
├── pipeline/ # Looper/PyPiper pipeline wrappers
│ ├── boldpy_pipeline.py # Per-sample pipeline entry point
│ ├── boldpy_prepare.py # Data extraction pipeline entry point
│ ├── boldpy_collate.py # Project-level collation entry point
│ ├── boldpy_*_interface.yaml # Looper pipeline interface definitions
│ ├── boldpy_pep_schema.yaml # Sample table validation schema
│ ├── boldpy_pipestat_schema.yaml# Pipestat result schema
│ └── examples/ # PEP config templates (copy and edit)
├── configs/ # Zone and threshold YAML configs
├── examples/ # Tutorial data and example configs
└── docs/ # Documentation (mkdocs)
If you use BoldPy in your research, please cite:
@software{boldpy2026,
title = {BoldPy: Renal BOLD MRI Analysis Framework with MLCO and K-Means Zone Clustering},
author = {Jason Smith},
year = {2026},
version = {3.0.0},
url = {https://github.com/jpsmith5/boldpy}
}MIT License. See LICENSE for details.
Built on NumPy, SciPy, Matplotlib, scikit-image, scikit-learn.