Skip to content

Python API

HemiSpec is designed to be used from Python first when you need reproducible PyTorch/model setup, batch execution, and downstream statistics in the same environment. The package distribution name is hemispec-toolkit; the public import path is hemispec. The PyPI project is not public yet.

python -m pip install -e .[model,classifier]
import hemispec
print(hemispec.__version__)

The API below was checked against HemiSpec v0.1.0. Prefer the high-level workflow API for new analyses; use lower-level APIs only when you need to split inference, metric computation, or validation manually.

Covered public entry points include run_bilateral_workflow, ensure_default_dgn_models, ensure_default_classifier_models, ROI summarization helpers, validate_specificity, validate_reliability, validate_hemisphere_classification, lower-level DGN/metric functions, and the synthetic quickstart helper.

run_bilateral_workflow() is the main Python entry point. It runs both DGN directions, computes bilateral ANS/RNS maps, writes subject summaries, and optionally exports ROI feature tables, hemisphere-classifier validation, and test-retest reliability.

from pathlib import Path

from hemispec import BilateralWorkflowConfig, run_bilateral_workflow

result = run_bilateral_workflow(
    BilateralWorkflowConfig(
        input_glob="derivatives/*_GM_masked.nii.gz",
        out_dir=Path("outputs/hemispec_workflow"),
        device="auto",          # "auto", "cuda", or "cpu"
    )
)

print(result.out_dir)
print(result.hemi_maps_dir)          # final ANS.L / ANS.R / RNS.L / RNS.R maps
print(result.subject_summary_csv)    # per-subject voxel-wise means

ROI export is enabled by default when an atlas is available. Set export_roi_table=False only when you want voxel-wise maps and subject summaries without ROI features.

Primary outputs are:

outputs/hemispec_workflow/
  voxel_maps/<subject>_ANS.L.nii.gz
  voxel_maps/<subject>_ANS.R.nii.gz
  voxel_maps/<subject>_RNS.L.nii.gz
  voxel_maps/<subject>_RNS.R.nii.gz
  tables/subject_metric_summary.csv

Model assets from Python

Release-wheel and source installs keep large model binaries outside the Python wheel. The workflow downloads missing released DGN checkpoints automatically on first use unless automatic downloads are disabled. You can also pre-download assets explicitly:

from hemispec import ensure_default_classifier_models, ensure_default_dgn_models

# Returns the DGN model root (.../models/dgn).
dgn_root = ensure_default_dgn_models()

# Optional: classifier bundle for hemisphere-classifier validation.
classifier_dir = ensure_default_classifier_models(mode="single")

Then pass those paths into the workflow when you want explicit control:

from pathlib import Path
from hemispec import BilateralWorkflowConfig, run_bilateral_workflow

result = run_bilateral_workflow(
    BilateralWorkflowConfig(
        input_glob="derivatives/*_GM_masked.nii.gz",
        out_dir=Path("outputs/hemispec_with_models"),
        model_root=dgn_root,
        run_classifier=True,
        classifier_model_dir=classifier_dir,
        roi_atlas=Path("atlas/custom_atlas.nii.gz"),
        roi_label_table=Path("atlas/custom_labels.xlsx"),
    )
)

Useful environment variables:

HEMISPEC_MODEL_CACHE              # user cache root for downloaded model assets
HEMISPEC_DGN_MODEL_ROOT           # override DGN checkpoint root
HEMISPEC_CLASSIFIER_MODEL_DIR     # override classifier bundle directory
HEMISPEC_GLASSER_ATLAS            # default atlas path for ROI export
HEMISPEC_GLASSER_LABEL_TABLE      # default label table path
HEMISPEC_DISABLE_MODEL_AUTO_DOWNLOAD=1

ROI feature tables for downstream analysis

Provide an atlas to create ROI-level features for statistical models or machine-learning classifiers. The long table stores one row per subject / map / ROI; the wide table stores one row per subject with feature columns such as ANS.L_roi_1 or RNS.R_roi_180.

from pathlib import Path
from hemispec import BilateralWorkflowConfig, run_bilateral_workflow

result = run_bilateral_workflow(
    BilateralWorkflowConfig(
        input_glob="derivatives/*_GM_masked.nii.gz",
        out_dir=Path("outputs/hemispec_roi"),
        roi_atlas=Path("atlas/custom_atlas.nii.gz"),
        roi_label_table=Path("atlas/custom_labels.xlsx"),
        export_roi_table=True,
    )
)

print(result.roi_csv)       # tables/roi_features_bilateral.csv
print(result.roi_wide_csv)  # tables/roi_features_bilateral_wide.csv

If you already have voxel-wise maps, summarize them directly:

For workflow-generated bilateral maps named like sub-001_ANS.L.nii.gz or sub-001_RNS.R.nii.gz, keep the extended file_regex below so the map_hemi column is captured correctly.

from pathlib import Path
from hemispec import RoiSummaryConfig, summarize_bilateral_roi_features, summarize_maps_by_atlas

roi_long = Path("outputs/tables/roi_features_bilateral.csv")
summary = summarize_maps_by_atlas(
    RoiSummaryConfig(
        maps_glob="outputs/hemispec_workflow/voxel_maps/*.nii.gz",
        atlas_path=Path("atlas/custom_atlas.nii.gz"),
        label_table=Path("atlas/custom_labels.xlsx"),
        out_csv=roi_long,
        file_regex=r"(?P<subject>.+?)_(?P<kind>ANS|RNS)[._](?P<map_hemi>L|R)\.nii(?:\.gz)?$",
    )
)
wide = summarize_bilateral_roi_features(roi_long, Path("outputs/tables/roi_features_bilateral_wide.csv"))

Validation APIs

Use validation APIs when you want explicit Python control over output folders or parameters.

The examples below read intermediate/combined_maps. Run the bilateral workflow with keep_intermediate=True before using those paths; the default workflow removes intermediate/ after successful completion.

from pathlib import Path
from hemispec import HemisphereClassificationConfig, ValidationConfig
from hemispec import validate_hemisphere_classification, validate_reliability, validate_specificity

specificity = validate_specificity(
    ValidationConfig(
        maps_dir=Path("outputs/hemispec_workflow/intermediate/combined_maps"),
        out_dir=Path("outputs/validation/specificity"),
        hemis=("L", "R"),
        dgn_direction="bilateral",
    )
)
print(specificity.to_dataframe())

trt = validate_reliability(
    ValidationConfig(
        maps_dir=Path("outputs/hemispec_workflow/intermediate/combined_maps"),
        out_dir=Path("outputs/validation/trt"),
        file_regex=r"(sub-MSC\d+).*?(run-\d+)",
        session_a="run-01",
        session_b="run-02",
        dgn_direction="bilateral",
    )
)

classifier = validate_hemisphere_classification(
    HemisphereClassificationConfig(
        maps_dir=Path("outputs/hemispec_workflow/voxel_maps"),
        roi_csv=Path("outputs/hemispec_workflow/tables/roi_features_bilateral.csv"),
        atlas_path=Path("atlas/custom_atlas.nii.gz"),
        label_table=Path("atlas/custom_labels.xlsx"),
        out_dir=Path("outputs/validation/hemi_classify"),
    )
)
print(classifier.accuracy, classifier.predictions_csv)

Lower-level inference and metric APIs

Use these only when you need a custom pipeline layout, a single DGN direction, or ANS/RNS computation from already reconstructed maps.

from pathlib import Path
from hemispec import DGNInferenceConfig, MetricComputeConfig
from hemispec import compute_metrics, discover_local_dgn_bundles, run_dgn_inference

bundles = discover_local_dgn_bundles()
reconstructed = run_dgn_inference(
    DGNInferenceConfig(
        model=bundles["L_to_R"],
        input_glob="derivatives/*_GM_masked.nii.gz",
        out_dir=Path("outputs/recon_L_to_R"),
        device="auto",
        direction="L_to_R",
    )
)

metrics = compute_metrics(
    MetricComputeConfig(
        actual_glob="derivatives/*_GM_masked.nii.gz",
        reconstructed_glob="outputs/recon_L_to_R/*_PRED_LR_full.nii.gz",
        out_dir=Path("outputs/specificity_L_to_R"),
        save_subject_maps=True,
    )
)
print(metrics.subject_maps_dir)

Synthetic smoke test from Python

For documentation, CI, or environment checks that should not download model weights or touch private MRI data:

from pathlib import Path
from hemispec import run_synthetic_quickstart

run_synthetic_quickstart(Path("outputs/hemispec_quickstart"))

What is intentionally not public API

Training code, private manuscript analyses, and raw-data preprocessing decisions are not exposed as stable public Python API. For new user-facing work, document examples with from hemispec import ... and keep CLI/GUI examples aligned with the same package-installed environment.

ANS/RNS and the cross-hemispheric DGN framework originate from Wang et al. (2024); see Citation.