asl-mri-utils
Command-line tools for post-processing Siemens arterial spin labeling (ASL) MRI data: recovering true acquisition order from DICOM, converting to NIfTI, splitting timeseries by TI/label/control, and computing perfusion-weighted difference images.
Siemens-only by design. The whole pipeline reads the true LABEL/CONTROL/M0/TI order straight from per-frame DICOM tags, not from filenames or protocol names, so it needs the Siemens tags that provide that: the standard ASL DICOM tags plus one Siemens private tag for TI ordering. If an expected tag is missing, a command raises a specific exception rather than guessing.
Table of contents
Install
pip install asl-mri-utils
For local development, from a clone of this repository:
pip install -e .
Requirements
| Tool | Needed for | Not found? |
|---|---|---|
dcm2niix or dcm2niix_afni |
convert (always) |
convert fails -- not bundled, must be installed separately |
AFNI (3drefit) |
convert's slice-timing embedding |
skipped silently, not an error |
FSL (mcflirt) |
subtract --mc |
subtract --mc fails -- not bundled |
Each external binary is found via an explicit flag first, then an environment variable, then
PATH: --dcm2niix-bin/$ASL_MRI_UTILS_DCM2NIIX for dcm2niix, --mcflirt-bin/
$ASL_MRI_UTILS_MCFLIRT for mcflirt.
Quickstart
A typical run, starting from one Siemens ASL series' exported DICOM folder:
# 1. See what dcm2niix would even produce: LABEL/CONTROL/M0 order, TI index, and timing,
# read straight from the DICOM headers.
asl-mri-utils order 021-my_asl_series
# 2. Convert that series to NIfTI, per echo. This also builds each echo's oxasl-ready
# *_asl.nii.gz/*_mzero.nii.gz and oxasl_params.json.
asl-mri-utils convert 021-my_asl_series ./niftis
# 3. (Optional) Split echo 1 into per-TI, per-label/control NIfTIs -- useful to inspect, or to
# hand to other tools directly.
asl-mri-utils split ./niftis/021_my_asl_series_echo-01_asl.nii.gz \
./niftis/021_my_asl_series_echo-01_order.tsv
# 4. Compute perfusion-weighted difference images. --mc motion-corrects first; --mean adds a
# temporal-mean companion to every diff file (the actual perfusion-weighted map).
asl-mri-utils subtract ./niftis/021_my_asl_series_echo-01_asl.nii.gz \
./niftis/021_my_asl_series_echo-01_order.tsv \
--mc --mean
Step 3 is optional because step 4 does it internally anyway (subtract's default simple method
is built directly on split's own output -- it reuses those files if they already exist, splits
if they don't). Running it separately first just lets you inspect the per-TI/label/control NIfTIs
on their own, e.g. in fsleyes or afni, before computing any difference images from them.
Commands
order: recover acquisition order
Recovers the true LABEL/CONTROL/M0/TI acquisition order of a Siemens ASL series directly from
per-frame DICOM tags (ASL Context, a Siemens private ordering tag), independent of filenames or
protocol names. Writes one order.tsv per echo: volume_index, echo, temporal_position,
asl_context, ti_index, acquisition_time.
asl-mri-utils order <dicom_series_dir> [<dicom_series_dir> ...] [--outdir DIR]
asl-mri-utils order --all [ROOT] [--outdir DIR]
convert: DICOM to NIfTI
Wraps a local dcm2niix/dcm2niix_afni install to convert one series directory to NIfTI, entirely
per echo. For each echo, writes:
- the raw NIfTI + JSON sidecar, renamed to this package's own
*_echo-0Nconvention *_echo-0N_order.tsv(same schema asorder, above)- an oxasl-ready
*_echo-0N_asl.nii.gz(label/control volumes) and*_echo-0N_mzero.nii.gz(M0 volumes), with a matching*_echo-0N_aslcontext.tsv *_echo-0N_oxasl_params.json, recording the(iaf, order, ntis, tis_ms, rpts)shapeoxaslneeds.tis_msis read straight from the DICOM header where the acquisition protocol stored it there; otherwise it'snull, with a note explaining why, not a guess.
If an AFNI install is available and the JSON sidecar has a SliceTiming field, that's also burned
into every NIfTI's header via 3drefit -Tslices.
asl-mri-utils convert <in_dir> <out_dir> [--dcm2niix-bin PATH] [--overwrite]
split: per-TI, label/control timeseries
Splits one echo's timeseries into per-TI NIfTIs, each further split into its label-only and control-only subseries:
<stem>_TI<k>.nii.gz # that TI's label+control volumes, chronological order
<stem>_TI<k>_label.nii.gz # that TI's label volumes only
<stem>_TI<k>_control.nii.gz # that TI's control volumes only
Point it at either the raw per-echo timeseries from convert, or its *_asl.nii.gz -- either
way, pass the matching order.tsv. Which one you gave it is detected automatically, from its own
volume count.
asl-mri-utils split <nii> <order_tsv> [--echo N] [--ti N ...] [--outdir DIR]
subtract: perfusion-weighted difference images
Computes a perfusion-weighted difference image per TI. Like split, it accepts either the raw
timeseries or *_asl.nii.gz.
The default method, simple, is just label - control and its negation, built directly on
split's own per-TI output (reusing it if split already ran, generating it otherwise). Pass
--methods standard surround sinc instead for Liu & Wong (2005, NeuroImage 24:207-215)
pairwise/surround/sinc subtraction -- three different ways of handling the tradeoff between
temporal resolution and noise when differencing an alternating label/control series. --recommend block|event_related picks one of those three automatically, per the paper's own guidance, instead
of listing --methods by hand.
--mc: motion-correct first (mcflirt -spline_final -cost normmi). Every output is then named off the resulting_mcffile.--mean/--tsnr: add a temporal-mean, or temporal-mean/temporal-std, companion to every diff file produced.--mean's output is the perfusion-weighted map most people actually want.--sinc-interp: for thesincmethod only, swap its estimator for an alternative (windowed-sinc, FFT, Gaussian process regression, or a Kalman filter/RTS smoother -- see docs/interpolate.md).
asl-mri-utils subtract <nii> <order_tsv> [--ti N ...]
[--methods simple|standard|surround|sinc ...] [--recommend block|event_related]
[--sinc-interp truncated|windowed_sinc|fft|gp|kalman]
[--mc] [--mcflirt-bin PATH] [--mean] [--tsnr] [--outdir DIR]
discover: find series directories
Finds candidate DICOM series directories under a root, matching the NNN-SeriesDescription
folder convention order --all/convert expect.
asl-mri-utils discover [ROOT]
Further reading
Each module has its own page under docs/, with the implementation detail this README leaves out
(exact DICOM tags, the Liu & Wong equations, worked examples):
| Doc | Covers |
|---|---|
| docs/dicom.md | Siemens tag reading, the ASL Context classification rule, header-derived TI values |
| docs/order.md | Ordering/pairing logic, the order.tsv schema |
| docs/discovery.md | Series discovery, DICM magic-byte sniffing |
| docs/binaries.md | Shared external-binary resolution (dcm2niix, mcflirt) |
| docs/convert.md | dcm2niix wrapping, per-echo oxasl_params.json fields, slice-timing embedding |
| docs/merge.md | Splitting one echo's output into its oxasl-ready asl/mzero pair |
| docs/split.md | Per-TI, per-label/control timeseries splitting |
| docs/subtract.md | The simple method, plus the Liu & Wong (2005) equations for standard/surround/sinc |
| docs/interpolate.md | Windowed-sinc, FFT, Gaussian process, and Kalman/RTS interpolation, with worked examples |
Metadata
Release files for asl-mri-utils 0.8.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| asl_mri_utils-0.8.1.tar.gz | 174.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| asl_mri_utils-0.8.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 223.2 kB
Release files / asl_mri_utils-0.8.1.tar.gz
| Download URL | asl_mri_utils-0.8.1.tar.gz |
|---|---|
| Size | 174.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2fc44e01ff795897a890da0bf797ab6b30e72d440d10b61d4dcdf46955afdd1f
|
|
BLAKE2b-256 checksum How to use checksums |
410fe96722d8f8642b22793f1ac60e41919fbdde5782436cf6335a92e821e1bc
|
| 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 7, 2026.
Transparency logRelease files / asl_mri_utils-0.8.1-py3-none-any.whl
| Download URL | asl_mri_utils-0.8.1-py3-none-any.whl |
|---|---|
| Size | 48.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
be4466d7368029fd9b1e443556eaea4bff28796f2808a0ab5f6f15a722fb3c9e
|
|
BLAKE2b-256 checksum How to use checksums |
c2b752b6d7e862a71542970f4aecc24a8109dfd70f72b43bdbb9568eb69111df
|
| 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 7, 2026.
Transparency logSecurity for asl-mri-utils 0.8.1
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for asl_mri_utils-0.8.1.tar.gz
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 7, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.