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 |
AFNI (3dvolreg, 3dAllineate, 1dplot) |
subtract --mc / --split-mc |
subtract --mc fails -- not bundled (1dplot only makes the motion plot; optional) |
Each external binary is found via an explicit flag first, then an environment variable, then
PATH: --dcm2niix-bin/$ASL_MRI_UTILS_DCM2NIIX for dcm2niix, --afni-bindir/
$ASL_MRI_UTILS_AFNI_BINDIR (a directory) for the AFNI programs.
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
(The *_asl.nii.gz files above only exist when convert had something to remove -- M0 volumes or a
trailing unpaired block. Otherwise use the raw *_echo-01.nii.gz, which oxasl_params.json's
asl_file names; a dedicated M0 series yields only *_mzero.nii.gz.)
Step 3 is optional: subtract does not need split's output. Running it separately just lets you
inspect the per-TI/label/control NIfTIs on their own, e.g. in fsleyes or afni.
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, ti_index,
temporal_index, asl_context, acq_time, delta_t (seconds since the first image).
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. The_aslfile is only written when it removes something from the raw file (M0 volumes or a trailing unpaired block); a series with neither is already oxasl-ready as-is, andoxasl_params.json'sasl_filepoints at the raw NIfTI. A dedicated M0 series (folder name has anM0token, or--m0-series) gets only_mzero.nii.gz.oxasl_params.jsonis the source of truth for which files to feedoxasl. *_echo-0N_oxasl_params.json, recording the(iaf, order, ntis, tis_ms, rpts)shapeoxaslneeds.tis_mscomes from--slice-timing FILE(the sequence's TimingInfo file, which also gives per-slice TIs), else--tis, else the DICOM header where the protocol stored it there; otherwisenull, 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] [--m0-series | --no-m0-series]
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 (the same decimated
pairs as standard, written as *_LCdiff/*_CLdiff). 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.
--methods running: pairwise difference at every adjacent label/control pair (2N-1 outputs), vsstandard's decimated pairs (N outputs).surroundandsincalso give one output per acquired volume. No method adds information, and full-rate outputs are autocorrelated (lag-1 ~0.5 running, ~0.67 surround, ~0.64 sinc, ~0 standard) in a way that cannot be prewhitened (spectral nulls of the filter), so fit the unsubtracted data or use decimatedstandardpairs. See docs/subtract.md for the L C L C illustration.--combine diff|avg|both|auto: besides the perfusion difference (control - label), write the BOLD-weighted average(control + label) / 2through the same filter (*_avg.nii.gz).autowrites the difference for the lowest echo and the average for later echoes. Full-rate averages cannot be prewhitened any more than the differences can; for BOLD statistics use the raw later-echo data or the decimatedstandard --combine avgwith an AR fit.--grid midpoint:sincinterpolates both conditions to the midpoints between volumes.--label-first: write the difference aslabel - control(files get an_LCsuffix) for sequences where the label image is the brighter one. Sign convention only; see docs/subtract.md.--mc: motion-correct the whole timeseries first (AFNI3dvolreg, base volume 0), then split into TIs and label/control from the corrected file. Every output is then named off the resulting_volregfile. Also saves*_volreg.aff12.1D(matrices),*_volreg_motion.1Dand a motion plot. On a multi-echo dataset, run the lowest echo first:--mcon every other echo then automatically applies that echo's*_volreg.aff12.1D(3dAllineate), so all echoes share one motion estimate.--split-mc: like--mc(implies it), but estimate motion in two passes -- controls registered to control volume 0, labels registered to that same control volume 0 -- then interleave back to the original volume order. Saves the same*_volreg.aff12.1D(one matrix per original volume), which other echoes apply unchanged.--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|running|surround|sinc ...] [--recommend block|event_related]
[--combine diff|avg|both|auto] [--grid sample|midpoint] [--label-first]
[--sinc-interp truncated|windowed_sinc|fft|gp|kalman]
[--mc | --split-mc] [--afni-bindir DIR] [--mean] [--tsnr] [--outdir DIR]
glm: OLS on subtracted ASL, corrected for the filter
asl-mri-utils glm <nii> <order_tsv> --method surround --design regressors.tsv --contrast act=perfact_ti1:1
fits contrasts on the subtracted series of each TI with the variance and degrees of freedom corrected
for the subtraction filter (FEAT's perfusion-subtraction route, which cannot use prewhitening because
the filter's correlation has spectral nulls). It builds the filter from the raw volumes, passes the
design through it (a ti<k> baseline is annihilated and dropped, perf_ti<k> becomes the intercept),
and writes *_cope/*_varcope/*_tstat maps plus a *_glm.json with the effective degrees of
freedom. It warns when the brain-mean C/L differs from 1 by more than 2% (BOLD then leaks into the
perfusion contrast). See docs/glm.md
and docs/filters.md.
regressors: design columns for unsubtracted ASL
asl-mri-utils regressors <nii> <order_tsv> writes <stem>_regressors.tsv: per volume, the
control/label modulation (+0.5 / -0.5, 0 for M0) and, per TI, a baseline indicator ti<k> and a
perfusion modulation perf_ti<k>, for fitting the unsubtracted data in FEAT or AFNI (Mumford et
al. 2006, NeuroImage 33:103-14) with an AR noise model (FILM / 3dREMLfit).
--task NAME=FILE (repeatable; onset duration [amplitude] per line, seconds) adds FEAT's full-model
EVs per TI, at each volume's true acquisition time: bold_ti<k>_NAME (task x HRF) and
perfact_ti<k>_NAME (task x perf_ti<k>). --format afni|fsl|all also exports .1D / per-EV text files.
See docs/perfusion-fmri.md.
lcratio and autocorr: noise and contrast diagnostics
asl-mri-utils lcratio <nii> <order_tsv> reports the brain-mean label/control ratio per TI and warns
about a large static difference (BOLD leaking into the perfusion contrast) or a negative C - L.
asl-mri-utils autocorr <nii> <order_tsv> [--method running] maps the residual autocorrelation (raw, or
through a subtraction filter next to the filter's exact value). See
docs/autocorr.md.
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, AFNI) |
| 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/autocorr.md | autocorr and lcratio noise diagnostics |
| docs/perfusion-fmri.md | Perfusion fMRI analysis plan, task EVs, AFNI recipe |
| docs/interpolate.md | Windowed-sinc, FFT, Gaussian process, and Kalman/RTS interpolation, with worked examples |
Metadata
Release files for asl-mri-utils 0.17.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 | Provenance | |
|---|---|---|---|---|
| asl_mri_utils-0.17.0.tar.gz | 238.7 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| asl_mri_utils-0.17.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 328.3 kB
Release files / asl_mri_utils-0.17.0.tar.gz
| Download URL | asl_mri_utils-0.17.0.tar.gz |
|---|---|
| Size | 238.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8143aca95762b4c7b8ab9e544875da75b7b46047d189dd68c272694e7e18d324
|
|
BLAKE2b-256 checksum How to use checksums |
191837caf2f41c3203f70582c06198576ad181d8a68847d972863d48d14dac7f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 24, 2026.
Transparency logRelease files / asl_mri_utils-0.17.0-py3-none-any.whl
| Download URL | asl_mri_utils-0.17.0-py3-none-any.whl |
|---|---|
| Size | 89.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3257a6b5b11af6b13341ae94bd554eed928ab8bae4694fd80420977d49804431
|
|
BLAKE2b-256 checksum How to use checksums |
50ec6b1f35fa5b2367a8bfb0b45c9cd1563bcc553740437b445241e21eaf26b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
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 24, 2026.
Transparency logSecurity for asl-mri-utils 0.17.0
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.17.0.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 24, 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.