A simple tool for extracting regional statistics from scalar neuroimaging maps.
Project description
parcellate
Extract regional statistics from scalar neuroimaging maps using atlas-based parcellation.
What It Does
parcellate is a Python tool that extracts regional statistics from volumetric brain images using atlas-based parcellation. Given a scalar map (e.g., gray matter density, fractional anisotropy) and a labeled atlas, it computes summary statistics for each brain region.
Key Features:
- 🧠 Multiple Pipeline Support: Integrates with CAT12 (VBM) and QSIRecon (diffusion MRI) outputs
- 📊 Rich Statistics: 13+ built-in metrics including mean, median, volume, robust statistics, and higher-order moments
- ⚡ Performance: Parallel processing, smart caching, and optimized resampling
- 📁 BIDS-Compatible: Outputs follow BIDS-derivative conventions
- 🔧 Flexible: Python API and CLI interfaces, custom atlases and statistics
Supported Input Formats:
- CAT12: Gray matter (GM), white matter (WM), CSF volumes, cortical thickness maps
- QSIRecon: Diffusion scalar maps (FA, MD, AD, RD, etc.)
Output Format:
- TSV files with regional statistics (one row per brain region)
- BIDS-derivative compatible directory structure
Installation
pip install parcellate
For CAT12 CSV batch processing with environment variable support:
pip install parcellate[dotenv]
Quick Start
CAT12 Pipeline
Process CAT12 VBM outputs with a TOML configuration file:
parcellate cat12 config.toml
Example config.toml:
input_root = "/data/cat12_derivatives"
output_dir = "/data/parcellations"
subjects = ["sub-01", "sub-02"] # Optional: process specific subjects
force = false # Skip existing outputs
log_level = "INFO"
n_jobs = 4 # Parallel jobs within subject
n_procs = 2 # Parallel processes across subjects
[[atlases]]
name = "Schaefer400"
path = "/atlases/Schaefer2018_400Parcels_7Networks_order_FSLMNI152_1mm.nii.gz"
lut = "/atlases/Schaefer2018_400Parcels_7Networks_order.tsv"
space = "MNI152NLin2009cAsym"
Example output:
parcellations/
└── sub-01/
└── anat/
├── sub-01_space-MNI152NLin2009cAsym_atlas-Schaefer400_desc-gm_stats.tsv
├── sub-01_space-MNI152NLin2009cAsym_atlas-Schaefer400_desc-wm_stats.tsv
└── sub-01_space-MNI152NLin2009cAsym_atlas-Schaefer400_desc-ct_stats.tsv
QSIRecon Pipeline
Process QSIRecon diffusion outputs:
parcellate qsirecon --config config.toml --input-root /data/qsirecon
Example config.toml:
input_root = "/data/qsirecon_derivatives"
output_dir = "/data/parcellations"
sessions = ["ses-01"]
n_jobs = 4
[[atlases]]
name = "JHU"
path = "/atlases/JHU-ICBM-labels-1mm.nii.gz"
lut = "/atlases/JHU-ICBM-labels-1mm.tsv"
space = "MNI152NLin6Asym"
CAT12 CSV Mode (Batch Processing)
Process multiple subjects from a CSV file:
parcellate-cat12 subjects.csv --root /data/cat12 --atlas-path /atlases/schaefer400.nii.gz
Example subjects.csv:
subject_id,session_id
sub-01,ses-baseline
sub-02,ses-baseline
Environment variables can be used for configuration:
export CAT12_ROOT=/data/cat12_derivatives
export CAT12_OUTPUT_DIR=/data/parcellations
export CAT12_ATLAS_PATHS=/atlases/atlas1.nii.gz,/atlases/atlas2.nii.gz
export CAT12_ATLAS_NAMES=Schaefer400,AAL3
parcellate-cat12 subjects.csv
Configuration Reference
TOML Configuration
| Field | Type | Description | Default |
|---|---|---|---|
input_root |
string | Path to preprocessing derivatives | Required |
output_dir |
string | Output directory for parcellations | {input_root}/parcellations |
subjects |
list | Subject IDs to process | All discovered |
sessions |
list | Session IDs to process | All discovered |
mask |
string | Brain mask path or builtin (gm, wm, brain) |
None |
force |
boolean | Overwrite existing outputs | false |
log_level |
string | Logging verbosity (DEBUG, INFO, WARNING) |
INFO |
n_jobs |
integer | Parallel jobs within subject | 1 |
n_procs |
integer | Parallel processes across subjects | 1 |
Atlas Definition
[[atlases]]
name = "MyAtlas" # Atlas identifier
path = "/path/to/atlas.nii.gz" # NIfTI file with integer labels
lut = "/path/to/atlas.tsv" # Optional: TSV with columns 'index' and 'label'
space = "MNI152NLin2009cAsym" # Template space
The LUT (lookup table) TSV should have:
index: Integer region IDs matching atlas labelslabel: Region names
Environment Variables (CAT12 CSV Mode)
| Variable | Description |
|---|---|
CAT12_ROOT |
Input root directory (required) |
CAT12_OUTPUT_DIR |
Output directory |
CAT12_ATLAS_PATHS |
Comma-separated atlas paths |
CAT12_ATLAS_NAMES |
Comma-separated atlas names |
CAT12_ATLAS_SPACE |
Space for all atlases |
CAT12_MASK |
Mask path or builtin name |
CAT12_LOG_LEVEL |
Logging level |
Output Format
Each parcellation produces a TSV file with one row per brain region:
| Column | Description |
|---|---|
index |
Region ID from atlas |
label |
Region name (if LUT provided) |
mean |
Mean intensity |
std |
Standard deviation |
median |
Median intensity |
mad_median |
Median absolute deviation |
min |
Minimum intensity |
max |
Maximum intensity |
range |
Max - Min |
volume |
Sum of intensities |
voxel_count |
Number of voxels in region |
z_filtered_mean |
Mean after removing outliers ( |
z_filtered_std |
Std after removing outliers |
skewness |
Distribution skewness |
kurtosis |
Distribution kurtosis |
Available Statistics
| Statistic | Description | Edge Case Behavior |
|---|---|---|
mean |
Arithmetic mean | NaN for empty regions |
std |
Standard deviation | 0 for constant values |
median |
50th percentile | NaN for empty regions |
mad_median |
Median absolute deviation | Robust alternative to std |
min / max |
Extreme values | NaN for empty regions |
range |
Max - Min | 0 for constant values |
volume |
Sum of all values | Region-specific metric |
voxel_count |
Number of non-zero voxels | Proxy for region size |
z_filtered_mean |
Mean excluding | z |
z_filtered_std |
Std excluding outliers | Robust variance estimate |
iqr_filtered_mean |
Mean excluding IQR outliers | Alternative robust mean |
robust_mean |
MAD-based filtered mean | Highly robust |
skewness |
Asymmetry of distribution | Higher moments |
kurtosis |
Tail heaviness | Outlier sensitivity |
Python API
Use the core parcellation engine directly:
from parcellate import VolumetricParcellator
import nibabel as nib
import pandas as pd
# Load atlas
atlas_img = nib.load("atlas.nii.gz")
lut = pd.read_csv("atlas.tsv", sep="\t")
# Initialize parcellator
parcellator = VolumetricParcellator(
atlas_img=atlas_img,
lut=lut,
background_label=0,
resampling_target="data" # Resample to scalar map space
)
# Parcellate a scalar map
scalar_img = nib.load("gm_map.nii.gz")
parcellator.fit(scalar_img)
stats = parcellator.transform(scalar_img)
print(stats.head())
Custom Statistics
Define custom aggregation functions:
def range_iqr(values):
"""Interquartile range."""
q75, q25 = np.percentile(values[~np.isnan(values)], [75, 25])
return q75 - q25
parcellator = VolumetricParcellator(
atlas_img=atlas_img,
stat_functions={"range_iqr": range_iqr}
)
Development
Setup
# Clone repository
git clone https://github.com/GalKepler/parcellate.git
cd parcellate
# Install development dependencies
make install
# Run tests
make test
# Run code quality checks
make check
Running Tests
# All tests
uv run python -m pytest
# Specific test file
uv run python -m pytest tests/test_parcellator.py
# With coverage
uv run python -m pytest --cov=src/parcellate --cov-report=html
Contributing
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and quality checks (
make check && make test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Documentation
Full documentation is available at https://GalKepler.github.io/parcellate/
License
This project is licensed under the MIT License - see the LICENSE file for details.
Citation
If you use this tool in your research, please cite:
@software{parcellate,
author = {Kepler, Gal},
title = {parcellate: Atlas-based parcellation of neuroimaging data},
url = {https://github.com/GalKepler/parcellate},
year = {2024}
}
Acknowledgments
Repository initiated with fpgmaas/cookiecutter-uv.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file parcellate-0.2.0.tar.gz.
File metadata
- Download URL: parcellate-0.2.0.tar.gz
- Upload date:
- Size: 325.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d07a9837d580c0165cdd4aaea277ed58379426cf37d8f1561f1157add5b3950b
|
|
| MD5 |
16c2b6a0558d7eb34d36ea36eb06bf1d
|
|
| BLAKE2b-256 |
4ea489efdffaefd429623752dc79449e3ffdff18fa71482db52420aaf8e290bb
|
File details
Details for the file parcellate-0.2.0-py3-none-any.whl.
File metadata
- Download URL: parcellate-0.2.0-py3-none-any.whl
- Upload date:
- Size: 47.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.9.28 {"installer":{"name":"uv","version":"0.9.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
80c49cc117481dc21b9c87e58897e3b8a3ab94f0bb21daeaf1c35a915521d7a1
|
|
| MD5 |
8eaac8abaa68e2cdbd50095d78ecc429
|
|
| BLAKE2b-256 |
b8bcd8b56afa0d267c46239299966bfe2ee84c427fc411ec69194371b2e60ada
|