presurfer-box 
MATLAB-free MP2RAGE preprocessing using SPM Standalone in Docker, Singularity, or Apptainer.
presurfer-box runs presurfer workflows in the
official SPM Standalone container, so it
does not need a local MATLAB installation or licence. The original MATLAB
implementation remains available as a Git submodule.
Status: This implementation uses SPM25 Standalone. Results have not yet been numerically validated against the historical SPM12/MATLAB pipeline.
Install
presurfer-box needs Python 3.11 or later and either Docker, Singularity,
or Apptainer. Install it from PyPI:
pip install presurfer
To work on the code, clone the repository instead:
git clone https://github.com/srikash/presurfer-box.git
cd presurfer-box
Fetch the pinned legacy MATLAB submodule only when you need to inspect or run the historical implementation:
git submodule update --init --recursive
Docker
docker pull ghcr.io/spm/spm-docker:docker-matlab-25.01.02
presurfer-box --check
Singularity / Apptainer
singularity pull --name spm.sif \
oras://ghcr.io/spm/spm-docker:singularity-matlab-25.01.02
presurfer-box --sif spm.sif --check
Quick start
# Create a bias-corrected image and bias field
presurfer-box biascorrect IMAGE.nii
# Create MPRAGEised UNI
presurfer-box MPRAGEise INV2.nii UNI.nii
# Create an INV2-derived strip mask
presurfer-box stripmask INV2.nii
# Create UNI tissue classes, brain mask, and white-matter mask
presurfer-box brainmask UNI.nii
Use a local Singularity or Apptainer image with --sif:
presurfer-box --sif spm.sif stripmask INV2.nii
Docker is the default runtime. Use --image IMAGE to select another image.
Each run writes to a new UTC timestamped directory beside its input, for
example 250101T12:34:56_presurfer/presurf_INV2/. Same-second runs receive a
numeric suffix. MPRAGEise's intermediate bias-correction directory begins
with tmp_ and is removed after processing.
Development
uv sync
uv run ruff format --check
uv run ruff check
uv run mypy .
uv run pytest
Choose a workflow
| Need | CLI command | Python function | Primary output |
|---|---|---|---|
| Bias-correct an image | biascorrect IMAGE |
spm_biascorrect() |
Bias-corrected image and bias field |
| Create MPRAGEised UNI | MPRAGEise INV2 UNI |
spm_mprageise() |
*_MPRAGEised.nii |
| Create a strip mask | stripmask INV2 |
spm_stripmask() |
*_stripmask.nii |
| Create UNI-derived masks | brainmask UNI |
spm_seg() |
Tissue classes, brain mask, and WM mask |
MPRAGEise bias-corrects INV2, min-max normalises the corrected INV2,
then multiplies it voxelwise with UNI. It does not run the strip-mask workflow.
Python API
from presurfer import spm_biascorrect, spm_mprageise, spm_seg, spm_stripmask
spm_biascorrect("INV2.nii")
spm_mprageise("INV2.nii", "UNI.nii")
spm_stripmask("INV2.nii")
spm_seg("UNI.nii")
All functions accept image= and runtime= keywords. Use
runtime="singularity" with a local SIF path passed as image=.
Outputs
Each workflow writes its output beneath a timestamped run directory beside the input:
YYMMDDThh:mm:ss_presurfer/presurf_biascorrect/
YYMMDDThh:mm:ss_presurfer/presurf_MPRAGEise/
YYMMDDThh:mm:ss_presurfer/presurf_INV2/
YYMMDDThh:mm:ss_presurfer/presurf_UNI/
Compressed .nii.gz inputs are supported. The source file stays unchanged and
the workflow creates an uncompressed working copy in the output directory.
Legacy MATLAB implementation
The original MATLAB implementation lives in srikash/presurfer and remains available here as a pinned Git submodule:
src/matlab/presurfer
For MATLAB use:
addpath('src/matlab/presurfer/func')
Update the submodule only when adopting a newer presurfer commit deliberately.
Reproducibility and validation
- Default image:
ghcr.io/spm/spm-docker:docker-matlab-25.01.02 - SPM runtime: SPM25 Standalone
- Historical implementation: SPM12 with MATLAB
- Numerical equivalence has not yet been validated with reference NIfTI data.
Licence
MIT. See LICENSE.
Citation
See CITATION.cff.
Metadata
Release files for presurfer 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| presurfer-2.0.0.tar.gz | 14.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| presurfer-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 28.8 kB
Release files / presurfer-2.0.0.tar.gz
| Download URL | presurfer-2.0.0.tar.gz |
|---|---|
| Size | 14.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5d6e994baea68fc8dce036d40f92b74f25138ca8e8547543e009413148eddb80
|
|
BLAKE2b-256 checksum How to use checksums |
79fd41f9f993853bd73963d4ab19053484bb5d6368890cf2537d09f1c9f9f18f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency logRelease files / presurfer-2.0.0-py3-none-any.whl
| Download URL | presurfer-2.0.0-py3-none-any.whl |
|---|---|
| Size | 14.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
356ba9cf47843e48ecc0082ba6fc7aca9c98d9122acfbdb6d360e56c0ca62b77
|
|
BLAKE2b-256 checksum How to use checksums |
39d091c65b74adc63c0320f1e0e9b56966e50f18cac48cb3ef4caf8b159627df
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 10, 2026.
Transparency log