Skip to main content

Extract morphometric measures from FreeSurfer-processed subjects using arbitrary atlases

Project description

fsatlas logo

fsatlas

Automated atlas-based morphometry extraction for FreeSurfer-processed brain MRI

PyPI version Python License: MIT FreeSurfer


The Problem

FreeSurfer's recon-all produces cortical statistics for its built-in atlases (Desikan-Killiany, Destrieux, DKT), but extracting measures with any other atlas requires manually chaining together multiple commands:

mri_surf2surf → mris_anatomical_stats → parse output
mri_vol2vol   → mri_segstats         → parse output

fsatlas automates this entire workflow into a single command — for any atlas, for any number of subjects.


Features

  • 22 built-in atlases — Schaefer 2018 (100–1000 parcels × 7/17 networks), Tian 2020 subcortical (Scales I–IV), HCP-MMP1, DKT, Desikan, Destrieux. Auto-downloads on first use.
  • Custom atlas support — Point at any .annot (surface) or .nii.gz (volumetric, MNI space) file.
  • Surface pipeline — Transfers annotations from fsaverage → subject via mri_surf2surf, extracts 9 cortical measures via mris_anatomical_stats.
  • Volumetric pipeline — Registers MNI-space NIfTI → native space via mri_vol2vol + talairach.xfm, extracts 7 subcortical measures via mri_segstats.
  • Tidy TSV output — Long-format output: subject_id | atlas | hemisphere | region | measure | value.
  • Batch processing — Process all subjects in $SUBJECTS_DIR or a specified list.
  • Failure resilience — Pipeline continues on per-subject errors; all failures logged to a separate TSV.
  • Docker image — Run without a local FreeSurfer installation.

Requirements

Requirement Version
Python ≥ 3.10
FreeSurfer 8.x
FREESURFER_HOME must be set
SUBJECTS_DIR must be set

Subjects must have completed recon-all.


Installation

pip install fsatlas

From source:

git clone https://github.com/GalKepler/fsatlas.git
cd fsatlas
pip install -e ".[dev]"

Quick Start

List available atlases

fsatlas list-atlases

Extract Schaefer 100-parcel cortical stats for all subjects

fsatlas extract --atlas schaefer100-7 --output-dir ./results

Target specific subjects

fsatlas extract --atlas schaefer100-7 -s sub-01 -s sub-02 -o ./results

Load subjects from a file

fsatlas extract --atlas schaefer400-17 --subjects-file subjects.txt -o ./results

Extract subcortical stats with the Tian atlas

fsatlas extract --atlas tian-s2 -o ./results

Use a custom surface atlas

# Provide one hemisphere; the other is auto-detected
fsatlas extract --atlas /path/to/lh.myatlas.annot -o ./results

Use a custom volumetric atlas (MNI space)

fsatlas extract --atlas /path/to/subcortical_atlas.nii.gz -o ./results

Pre-download an atlas

fsatlas download schaefer400-7

Built-in Atlas Catalog

ID Family Type Parcels Space
schaefer100-7 Schaefer 2018 Surface 100 fsaverage
schaefer200-7 Schaefer 2018 Surface 200 fsaverage
schaefer300-7 Schaefer 2018 Surface 300 fsaverage
schaefer400-7 Schaefer 2018 Surface 400 fsaverage
schaefer500-7 Schaefer 2018 Surface 500 fsaverage
schaefer600-7 Schaefer 2018 Surface 600 fsaverage
schaefer700-7 Schaefer 2018 Surface 700 fsaverage
schaefer800-7 Schaefer 2018 Surface 800 fsaverage
schaefer900-7 Schaefer 2018 Surface 900 fsaverage
schaefer1000-7 Schaefer 2018 Surface 1000 fsaverage
schaefer100-17 Schaefer 2018 Surface 100 fsaverage
schaefer200-17 Schaefer 2018 Surface 200 fsaverage
schaefer300-17 Schaefer 2018 Surface 300 fsaverage
schaefer400-17 Schaefer 2018 Surface 400 fsaverage
tian-s1 Tian 2020 Volumetric 16 MNI152NLin6Asym
tian-s2 Tian 2020 Volumetric 32 MNI152NLin6Asym
tian-s3 Tian 2020 Volumetric 50 MNI152NLin6Asym
tian-s4 Tian 2020 Volumetric 54 MNI152NLin6Asym
hcp-mmp HCP-MMP 1.0 Surface 360 fsaverage
desikan FreeSurfer Surface 68 built-in
destrieux FreeSurfer Surface 148 built-in
dkt FreeSurfer Surface 62 built-in

Output Format

Results are written as long-format (tidy) TSV files to the specified output directory.

Cortical ({atlas}_cortical.tsv):

subject_id atlas hemisphere region measure value
sub-01 schaefer100-7 lh 7Networks_LH_Vis_1 thickness_mean_mm 2.341
sub-01 schaefer100-7 lh 7Networks_LH_Vis_1 surface_area_mm2 843.0
sub-01 schaefer100-7 lh 7Networks_LH_Vis_1 gray_matter_volume_mm3 2110.0

Cortical measures: thickness_mean_mm, surface_area_mm2, gray_matter_volume_mm3, mean_curvature, gauss_curvature, fold_index, curvature_index, integrated_rect_curvature, eTIV

Subcortical ({atlas}_subcortical.tsv):

subject_id atlas hemisphere region measure value
sub-01 tian-s2 lh CAU-lh volume_mm3 1248.0
sub-01 tian-s2 lh CAU-lh intensity_mean 72.34

Subcortical measures: volume_mm3, intensity_mean, intensity_std, intensity_min, intensity_max, intensity_range, voxel_count

Failures ({atlas}_failures.tsv) — subjects that could not be processed, with error messages.


Docker

docker build -t fsatlas .

docker run --rm \
    -v /path/to/SUBJECTS_DIR:/subjects \
    -v /path/to/license.txt:/opt/freesurfer/license.txt \
    -e SUBJECTS_DIR=/subjects \
    fsatlas extract --atlas schaefer100-7 -o /subjects/results

The Docker image is based on freesurfer/freesurfer:8.0.0 and includes a self-contained Python environment at /opt/fsatlas-venv.


Architecture

src/fsatlas/
├── cli/
│   └── main.py           # Click CLI: extract, list-atlases, download
├── atlases/
│   ├── catalog.yaml      # Built-in atlas definitions (13 atlases)
│   └── registry.py       # Atlas loading, downloading, custom atlas support
└── core/
    ├── environment.py    # FreeSurfer detection, subject discovery, path resolution
    ├── pipeline.py       # Orchestrator: validate → transfer → extract → aggregate
    ├── transfer.py       # mri_surf2surf / mri_vol2vol wrappers (600s timeout)
    └── extract.py        # mris_anatomical_stats / mri_segstats + long-format parsing

Data flow:

CLI
 └─ resolve atlas + discover subjects
     └─ Pipeline (per subject)
         ├─ validate subject directory structure
         ├─ transfer atlas → subject space (cached)
         │   ├─ surface: mri_surf2surf (fsaverage → subject)
         │   └─ volumetric: mri_vol2vol (MNI → native via talairach.xfm)
         └─ extract stats
             ├─ cortical: mris_anatomical_stats → 9 measures (long format)
             └─ subcortical: mri_segstats → 7 measures (long format)
 └─ concatenate → {atlas}_cortical.tsv / {atlas}_subcortical.tsv

Development

pip install -e ".[dev]"
pytest                 # run tests
ruff check src/        # lint
ruff format src/       # format
mypy                   # type check

Citation

If you use fsatlas in your research, please cite the relevant atlas papers (shown via fsatlas list-atlases) and:

fsatlas: Automated atlas-based morphometry extraction for FreeSurfer. https://github.com/GalKepler/fsatlas


License

MIT © Gal Kepler

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fsatlas-0.1.0.tar.gz (374.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fsatlas-0.1.0-py3-none-any.whl (21.7 kB view details)

Uploaded Python 3

File details

Details for the file fsatlas-0.1.0.tar.gz.

File metadata

  • Download URL: fsatlas-0.1.0.tar.gz
  • Upload date:
  • Size: 374.5 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

Hashes for fsatlas-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6b895055ec0108bb48d54cfefcb1445ee1952f93f940d7aabee5bbdbc507a628
MD5 fb0a21f0a7590508bd5851a007e7e1ca
BLAKE2b-256 fc3eefbcfa7f9fe5da4dc52a03c9dfb25f1615a6e9e36b5561797e533cdccd3f

See more details on using hashes here.

File details

Details for the file fsatlas-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: fsatlas-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 21.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

Hashes for fsatlas-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a358e8a5137abe96f3ec9b8802a27becd7239981975e4dadbd0c27c06272a31a
MD5 5952b0773b0d4234a58b2deab1e342ba
BLAKE2b-256 26dc8e40373d7d2ace7aa01b283d40457cc9d61f7daeec16d07ced0aee8b27b8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page