Skip to main content

SimCortexPP (SCPP) is a modular pipeline for cortical surface reconstruction (preproc, seg, initsurf, deform)

Project description

SimCortexPP (SCPP)

SimCortexPP (SCPP) is a modular pipeline for cortical surface reconstruction in MNI space. It provides four stages:

  1. Preprocessing (FreeSurfer to MNI152)
    Export key FreeSurfer volumes/surfaces, register them to MNI152, and write outputs in a BIDS-derivatives-style layout.

  2. Segmentation (3D U-Net, MNI space)
    Train and apply a 3D U-Net to predict a 9-class segmentation in MNI152 space, with inference and evaluation utilities.

  3. Initial Surfaces (InitSurf)
    Generate initial White Matter and Pial surfaces from segmentation predictions (plus ribbon SDF/probability outputs).

  4. Deformation (Deform)
    Deform the initial surfaces toward MNI-aligned FreeSurfer surfaces using geometric losses and optional collision metrics, and write deformed surfaces as BIDS-derivatives.

This README focuses on how to run the pipeline correctly (inputs, outputs, folder/file naming, and commands).


Table of Contents


Installation

From the repository root:

pip install -e .
scpp --help
scpp seg --help
scpp initsurf --help
scpp deform --help

Recommended environment

  • Python 3.10+
  • PyTorch + MONAI
  • nibabel, numpy, pandas, openpyxl
  • trimesh, scipy, tqdm
  • External tools for Stage 1: NiftyReg (reg_aladin, reg_resample)
  • Optional (Deform metrics):
    • python-fcl for collision metrics
    • pymeshlab for SIF (self-intersection fraction) in Deform evaluation

Configuration

All stages use Hydra YAML configs shipped with the package (see src/simcortexpp/configs/<stage>/*.yaml).

You have two ways to configure a run:

  1. Edit the stage YAML (recommended for longer runs / stable experiments), then run commands with no extra arguments, e.g.:

    • scpp deform eval
  2. Use Hydra overrides on the CLI (recommended for quick tests), e.g.:

    • scpp deform eval dataset.split_name=test outputs.out_dir=/tmp/deform_eval

Data and Folder Conventions

You will typically work with two roots:

  1. Code repository (this repository)
    Contains code, configs, and scripts (no data).

  2. Dataset root (BIDS + derivatives)
    Each dataset has its own root directory. Recommended structure:

datasets/<dataset-name>/
  bids/                 # raw BIDS dataset
  derivatives/          # processed outputs (BIDS derivatives)
    freesurfer-7.4.1/
    scpp-preproc-0.1/
    scpp-seg-0.1/
    scpp-initsurf-0.1/
    scpp-deform-0.1/
  splits/
    <dataset>_split.csv

SCPP reads inputs from derivatives/ and writes outputs back to derivatives/ using BIDS-derivatives-style naming.

Important: keep the dataset root naming consistent (e.g., use datasets/... everywhere).


Split File Format

A split CSV is required for Segmentation, InitSurf, and Deform.

Single-dataset split

Minimal columns:

  • subject (e.g., sub-0001)
  • split in {train, val, test}

Multi-dataset split

Include an additional column:

  • dataset (string key that matches config keys, e.g., HCP_YA, OASIS1)

Example:

subject,split,dataset
sub-100307,test,HCP_YA
sub-101915,test,HCP_YA
sub-0001,test,OASIS1

Stage 1 - Preprocessing (FreeSurfer to MNI152)

This stage exports key FreeSurfer outputs (volumes + surfaces), registers them to MNI152, and writes results to a BIDS-derivatives-style folder.

Inputs

  • FreeSurfer derivatives root (contains sub-* folders)
  • MNI template (e.g., src/MNI152_T1_1mm.nii.gz)

Dependencies (system tools)

  • NiftyReg: reg_aladin, reg_resample must be in PATH
  • FreeSurfer tools are recommended (e.g., mri_convert, mris_convert) for consistent conversions

Run (all subjects discovered automatically)

scpp fs-to-mni   --freesurfer-root /path/to/datasets/<dataset>/derivatives/freesurfer-7.4.1   --out-deriv-root  /path/to/datasets/<dataset>/derivatives/scpp-preproc-0.1   --mni-template    /path/to/SimCortexPP/src/MNI152_T1_1mm.nii.gz   --decimate 0.3   -v

Run (selected subjects)

scpp fs-to-mni   --freesurfer-root /path/to/datasets/<dataset>/derivatives/freesurfer-7.4.1   --out-deriv-root  /path/to/datasets/<dataset>/derivatives/scpp-preproc-0.1   --mni-template    /path/to/SimCortexPP/src/MNI152_T1_1mm.nii.gz   -p sub-0001 -p sub-0019   -v

Output layout (example)

scpp-preproc-0.1/
  dataset_description.json
  sub-XXXX/
    ses-01/
      anat/
        sub-XXXX_ses-01_space-MNI152_desc-preproc_T1w.nii.gz
        sub-XXXX_ses-01_space-MNI152_desc-aparc+aseg_dseg.nii.gz
        sub-XXXX_ses-01_space-MNI152_desc-filled_T1w.nii.gz
        sub-XXXX_ses-01_from-T1w_to-MNI152_mode-image_xfm.txt
      surfaces/
        sub-XXXX_ses-01_space-MNI152_hemi-L_white.surf.ply
        sub-XXXX_ses-01_space-MNI152_hemi-L_pial.surf.ply
        sub-XXXX_ses-01_space-MNI152_hemi-R_white.surf.ply
        sub-XXXX_ses-01_space-MNI152_hemi-R_pial.surf.ply

Stage 2 - Segmentation (3D U-Net, MNI space)

This stage trains and applies a 3D U-Net to predict a 9-class segmentation in MNI152 space using Stage 1 outputs.

Expected inputs (from Stage 1)

Under scpp-preproc-*, for each subject:

  • ..._desc-preproc_T1w.nii.gz
  • ..._desc-aparc+aseg_dseg.nii.gz
  • ..._desc-filled_T1w.nii.gz

Output naming (predictions)

Predictions are written under scpp-seg-*:

  • sub-XXXX/ses-01/anat/sub-XXXX_ses-01_space-MNI152_desc-seg9_dseg.nii.gz

Train (single GPU)

scpp seg train   dataset.path=/path/to/datasets/<dataset>/derivatives/scpp-preproc-0.1   dataset.split_file=/path/to/datasets/<dataset>/splits/<dataset>_split.csv   outputs.root=/path/to/scpp-runs/seg/exp01   trainer.use_ddp=false

Train (multi-GPU, torchrun)

scpp seg train --torchrun --nproc-per-node 2   dataset.path=/path/to/datasets/<dataset>/derivatives/scpp-preproc-0.1   dataset.split_file=/path/to/datasets/<dataset>/splits/<dataset>_split.csv   outputs.root=/path/to/scpp-runs/seg/exp01   trainer.use_ddp=true

Inference

scpp seg infer   dataset.path=/path/to/datasets/<dataset>/derivatives/scpp-preproc-0.1   dataset.split_file=/path/to/datasets/<dataset>/splits/<dataset>_split.csv   dataset.split_name=test   model.ckpt_path=/path/to/seg_best_dice.pt   outputs.out_root=/path/to/datasets/<dataset>/derivatives/scpp-seg-0.1

Evaluation (multi-dataset example)

scpp seg eval   dataset.split_file=/path/to/datasets/splits/dataset_split.csv   dataset.split_name=test   dataset.roots.HCP_YA=/path/to/datasets/hcpya-u100/derivatives/scpp-preproc-0.1   dataset.roots.OASIS1=/path/to/datasets/oasis-1/derivatives/scpp-preproc-0.1   outputs.pred_roots.HCP_YA=/path/to/datasets/hcpya-u100/derivatives/scpp-seg-0.1   outputs.pred_roots.OASIS1=/path/to/datasets/oasis-1/derivatives/scpp-seg-0.1   outputs.eval_csv=/path/to/scpp-runs/seg/exp01/evals/seg_eval_test.csv   outputs.eval_xlsx=/path/to/scpp-runs/seg/exp01/evals/seg_eval_test.xlsx

Stage 3 — Initial Surfaces (InitSurf)

This stage generates initial cortical surfaces from saved segmentation predictions (not end-to-end).

Inputs

  • Preproc roots (scpp-preproc-*) for MNI T1
  • Seg roots (scpp-seg-*) for ..._desc-seg9_dseg.nii.gz
  • Split CSV (same format as Stage 2)

Outputs

BIDS-derivatives-style outputs under scpp-initsurf-* (meshes + SDF volumes + ribbon prob):

scpp-initsurf-0.1/
  dataset_description.json
  sub-XXXX/
    ses-01/
      anat/
        sub-XXXX_ses-01_space-MNI152_desc-lh_white_sdf.nii.gz
        sub-XXXX_ses-01_space-MNI152_desc-rh_white_sdf.nii.gz
        sub-XXXX_ses-01_space-MNI152_desc-lh_pial_sdf.nii.gz
        sub-XXXX_ses-01_space-MNI152_desc-rh_pial_sdf.nii.gz
        sub-XXXX_ses-01_space-MNI152_desc-ribbon_sdf.nii.gz
        sub-XXXX_ses-01_space-MNI152_desc-ribbon_prob.nii.gz
      surfaces/
        sub-XXXX_ses-01_space-MNI152_hemi-L_white.surf.ply
        sub-XXXX_ses-01_space-MNI152_hemi-L_pial.surf.ply
        sub-XXXX_ses-01_space-MNI152_hemi-R_white.surf.ply
        sub-XXXX_ses-01_space-MNI152_hemi-R_pial.surf.ply

Run (multi-dataset example)

scpp initsurf generate   dataset.split_file=/path/to/datasets/splits/dataset_split.csv   dataset.split_name=all   dataset.roots.HCP_YA=/path/to/datasets/hcpya-u100/derivatives/scpp-preproc-0.1   dataset.roots.OASIS1=/path/to/datasets/oasis-1/derivatives/scpp-preproc-0.1   dataset.seg_roots.HCP_YA=/path/to/datasets/hcpya-u100/derivatives/scpp-seg-0.1   dataset.seg_roots.OASIS1=/path/to/datasets/oasis-1/derivatives/scpp-seg-0.1   outputs.out_roots.HCP_YA=/path/to/datasets/hcpya-u100/derivatives/scpp-initsurf-0.1   outputs.out_roots.OASIS1=/path/to/datasets/oasis-1/derivatives/scpp-initsurf-0.1   outputs.log_dir=/path/to/scpp-runs/initsurf/exp01/logs_generate

Typical runtime: ~31 s/subject (hardware-dependent).


Stage 4 - Deformation (Deform)

This stage deforms InitSurf meshes using input volumes and geometric losses, and writes deformed surfaces to a BIDS-derivatives folder.

Inputs

  • Preproc root (scpp-preproc-*): MNI T1 + GT FreeSurfer surfaces in MNI space
  • InitSurf root (scpp-initsurf-*): ribbon probability + initial surfaces
  • Split CSV (same format as Stage 2)

Outputs

Deformed surfaces under scpp-deform-*:

scpp-deform-0.1/
  dataset_description.json
  sub-XXXX/
    ses-01/
      surfaces/
        sub-XXXX_ses-01_space-MNI152_desc-deform_hemi-L_white.surf.ply
        sub-XXXX_ses-01_space-MNI152_desc-deform_hemi-L_pial.surf.ply
        sub-XXXX_ses-01_space-MNI152_desc-deform_hemi-R_white.surf.ply
        sub-XXXX_ses-01_space-MNI152_desc-deform_hemi-R_pial.surf.ply

Train (multi-GPU example)

scpp deform train --torchrun --nproc-per-node 2   outputs.root=/path/to/scpp-runs/deform/exp01

Inference

scpp deform infer

Evaluation

scpp deform eval

Evaluation writes four Excel files:

  • surface_metrics.xlsx
  • collision_metrics.xlsx
  • collision_metrics_enhanced.xlsx
  • collision_summary.xlsx

Outputs Summary

For each dataset root:

  • derivatives/scpp-preproc-0.1/
    MNI T1, aparc+aseg, filled, transforms, and MNI-aligned FreeSurfer surfaces.

  • derivatives/scpp-seg-0.1/
    9-class segmentation predictions (*_desc-seg9_dseg.nii.gz).

  • derivatives/scpp-initsurf-0.1/
    Initial surfaces (*.surf.ply) + SDF volumes + ribbon SDF/probability.

  • derivatives/scpp-deform-0.1/
    Deformed surfaces (*_desc-deform_*.surf.ply).


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

simcortexpp-0.1.3.tar.gz (63.7 kB view details)

Uploaded Source

Built Distribution

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

simcortexpp-0.1.3-py3-none-any.whl (72.9 kB view details)

Uploaded Python 3

File details

Details for the file simcortexpp-0.1.3.tar.gz.

File metadata

  • Download URL: simcortexpp-0.1.3.tar.gz
  • Upload date:
  • Size: 63.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.19

File hashes

Hashes for simcortexpp-0.1.3.tar.gz
Algorithm Hash digest
SHA256 c659d7c76c0692412f63f0da6e748f10c6311058d59d7e0459ae5341ced58feb
MD5 4353accd9ca72e570051c8cb3629c573
BLAKE2b-256 096b485704f1f14e00677f9f787973913f29fca7a58fe920086045b127c7de96

See more details on using hashes here.

File details

Details for the file simcortexpp-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: simcortexpp-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 72.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.19

File hashes

Hashes for simcortexpp-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 c7f520d0266115440117f426d397f566cc53dc715ecf8567dc2027284aabef46
MD5 a993dfecb577dfe161bc9324b291e5ab
BLAKE2b-256 4b9b927ebcd1b0b218dad615abc10488f02873c6e994d4b4b0cc862450a0120c

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