Run this notebook
A Robust Preprocessing Pipeline for ASL Data¶
Author: Steffen Bollmann & Monika Doerig
Date: 17 Oct 2024
License:
Note: If this notebook uses neuroimaging tools from Neurocontainers, those tools retain their original licenses. Please see Neurodesk citation guidelines for details.
Citation and Resources¶
Tools included in this workflow¶
ASLPrep:
Adebimpe, A., Bertolero, M., Dolui, S. et al. ASLPrep: a platform for processing of arterial spin labeled MRI and quantification of regional brain perfusion. Nat Methods 19, 683–686 (2022). Adebimpe et al. (2022)
FreeSurfer:
Dale, A.M., Fischl, B., Sereno, M.I. (1999). Cortical surface-based analysis. I. Segmentation and surface reconstruction. NeuroImage, 9(2), 179–194. Dale et al. (1999)
Fischl, B., Sereno, M.I., Dale, A.M. (1999). Cortical surface-based analysis. II: Inflation, flattening, and a surface-based coordinate system. NeuroImage, 9(2), 195–207. Fischl et al. (1999)
Fischl, B. & Dale, A.M. (2000). Measuring the thickness of the human cerebral cortex from magnetic resonance images. Proceedings of the National Academy of Sciences, 97(20), 11050–11055. Fischl & Dale (2000)
Dataset¶
Opensource Data from OpenNeuro:
Alvaro Galiano and Reyes Garcia de Eulate and Marta Vidorreta and Miriam Recio and Mario Riverol and José L. Zubieta and Maria A. Fernandez-Seara PhD (2021). Resting State Perfusion in Healthy Aging. OpenNeuro Dataset ds000240.doi: 10.18112/openneuro.ds000240.v2.0.0
Educational resources¶
Introduction¶
Arterial Spin Labeling (ASL) MRI is a non-invasive technique for measuring cerebral blood flow (CBF) without the need for contrast agents. However, processing ASL data involves multiple complex steps — motion correction, registration to anatomical images, partial volume correction, and CBF quantification — each requiring careful parameter choices and quality control.
ASLPrep is an ASL preprocessing and CBF computation pipeline designed to be robust to variations in scan acquisition protocols while requiring minimal user input. It adapts its preprocessing steps depending on the input dataset and uses a combination of tools from well-known software packages (FSL, ANTs, FreeSurfer, and AFNI), selecting the best available implementation for each step. ASLPrep is largely based on fMRIPrep and is part of the NiPreps community, but accounts for key differences between ASL and fMRI —for example, separate motion correction per volume type, slice-timing–aware CBF calculation instead of slice timing correction, and reference image selection based on highest-contrast volume type.
This notebook demonstrates how to run ASLPrep on a publicly available dataset using Neurodesk, making quantitative perfusion imaging accessible without manual installation of the required dependencies.

Learning Objectives¶
By the end of this notebook, you will be able to:
Set up and run ASLPrep on a BIDS-formatted ASL dataset using Neurodesk
Navigate and interpret ASLPrep’s visual quality control outputs, including brain segmentation, spatial normalisation, ASL-to-T1w registration, and CBF maps
Identify common issues in ASL processing from the visual reports (carpet plots, registration overlays)
Load software tools¶
# load aslprep
import os
import module
await module.load('aslprep/26.0.2')
await module.list()['aslprep/26.0.2']Set up FreeSurfer license¶
# Request a freesurfer license and store it in your homedirectory.
# This is just an example - please replace with your license id:
license_path = os.path.expanduser("~/.license")
# Create the license file using Python (more reliable than ! commands in batch execution)
license_content = """Steffen.Bollmann@cai.uq.edu.au
21029
*Cqyn12sqTCxo
FSxgcvGkNR59Y
"""
with open(license_path, 'w') as f:
f.write(license_content)
# Verify the license file was created
if os.path.exists(license_path):
print(f"✅ FreeSurfer license file created at: {license_path}")
with open(license_path, 'r') as f:
print(f" Lines: {len(f.readlines())}")
else:
raise RuntimeError(f"❌ Failed to create FreeSurfer license file at {license_path}")✅ FreeSurfer license file created at: /home/jovyan/.license
Lines: 4
Download data using DataLad¶
!datalad install https://github.com/OpenNeuroDatasets/ds000240.git
!cd ds000240 && datalad get sub-01Cloning: 0%| | 0.00/2.00 [00:00<?, ? candidates/s]
Enumerating: 0.00 Objects [00:00, ? Objects/s]
Counting: 0%| | 0.00/1.20k [00:00<?, ? Objects/s]
Compressing: 0%| | 0.00/883 [00:00<?, ? Objects/s]
Receiving: 0%| | 0.00/2.39k [00:00<?, ? Objects/s]
Resolving: 0%| | 0.00/256 [00:00<?, ? Deltas/s]
[INFO ] Remote origin not usable by git-annex; setting annex-ignore
[INFO ] https://github.com/OpenNeuroDatasets/ds000240.git/config download failed: Not Found
[INFO ] access to 1 dataset sibling s3-PRIVATE not auto-enabled, enable with:
| datalad siblings -d "/home/jovyan/workspace/books/examples/quantitative_imaging/ds000240" enable -s s3-PRIVATE
install(ok): /home/jovyan/workspace/books/examples/quantitative_imaging/ds000240 (dataset)
Total: 0%| | 0.00/18.0M [00:00<?, ? Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 0%| | 0.00/9.52M [00:00<?, ? Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 0%| | 33.4k/9.52M [00:00<00:59, 159k Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 1%| | 68.2k/9.52M [00:00<00:55, 169k Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 1%| | 138k/9.52M [00:00<00:39, 236k Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 3%|▏ | 294k/9.52M [00:00<00:21, 434k Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 6%|▎ | 608k/9.52M [00:01<00:11, 810k Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 13%|▍ | 1.23M/9.52M [00:01<00:05, 1.54M Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 26%|▊ | 2.49M/9.52M [00:01<00:02, 3.34M Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 31%|▉ | 2.96M/9.52M [00:01<00:01, 3.62M Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 48%|█▍ | 4.55M/9.52M [00:01<00:00, 6.32M Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 70%|██ | 6.70M/9.52M [00:01<00:00, 6.81M Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 86%|██▌| 8.19M/9.52M [00:02<00:00, 8.33M Bytes/s]
Get sub-01/a .. 1_T1w.nii.gz: 0%| | 0.00/9.52M [00:00<?, ? Bytes/s]
Total: 53%|█████████████▊ | 9.52M/18.0M [00:03<00:03, 2.78M Bytes/s]
Get sub-01/p .. 1_asl.nii.gz: 0%| | 0.00/8.48M [00:00<?, ? Bytes/s]
Get sub-01/p .. 1_asl.nii.gz: 18%|▌ | 1.49M/8.48M [00:00<00:00, 14.8M Bytes/s]
Get sub-01/p .. 1_asl.nii.gz: 37%|█ | 3.13M/8.48M [00:00<00:00, 15.4M Bytes/s]
Get sub-01/p .. 1_asl.nii.gz: 74%|██▏| 6.24M/8.48M [00:00<00:00, 12.3M Bytes/s]
Get sub-01/p .. 1_asl.nii.gz: 0%| | 0.00/8.48M [00:00<?, ? Bytes/s]
get(ok): sub-01/anat/sub-01_T1w.nii.gz (file) [from s3-PUBLIC...]
get(ok): sub-01/perf/sub-01_asl.nii.gz (file) [from s3-PUBLIC...]
get(ok): sub-01 (directory)
action summary:
get (ok: 3)
Run ASLPrep¶
The next cell runs ASLPrep on one participant from the ds000240 dataset and writes outputs to aslprep-output/.
A few practical notes:
The FreeSurfer license file should exist at
~/.license(created above).Runtime depends heavily on available CPUs and memory. It will likely take a few of hours (~4-6 hours) to run.
On small nodes, set resource limits explicitly (
--nthreads,--omp-nthreads,--mem-mb) so ASLPrep doesn’t oversubscribe RAM and get OOM (out of memory) killed. The cell below detects the available resources automatically.To check progress, open a Terminal and run
top, ortail -f aslprep.logIf a previous run left intermediates in
aslprep-work/, ASLPrep will reuse them and finish much faster. To force a clean run, deleteaslprep-work/first.ASLPrep handles the full pipeline: anatomical preprocessing (brain extraction, segmentation, surface reconstruction, spatial normalisation), ASL preprocessing (motion correction, distortion correction, ASL-to-T1w registration), and CBF quantification. Short version (one sentence, to append):
Sidecar workaround: The ds000240 sidecars ship with
RepetitionTimePreparation: 0. ASLPrep 26.x reads this field asm0trin the M0-recovery correction (1 − exp(−m0tr/T1blood)) — when it is 0, the term collapses to 0 and every CBF voxel becomes zero with no error. As a workaround we copy the value ofRepetitionTimeintoRepetitionTimePreparationin the patching cell above, which restores physiologically plausible CBF. Older ASLPrep versions (0.7.x) did not consume this field and were unaffected.
import json
from pathlib import Path
sidecar = Path("ds000240/sub-01/perf/sub-01_asl.json")
meta = json.loads(sidecar.read_text())
if meta.get("RepetitionTimePreparation") in (None, 0, 0.0):
meta["RepetitionTimePreparation"] = meta["RepetitionTime"]
sidecar.write_text(json.dumps(meta, indent=4))
print(f"Patched {sidecar}: RepetitionTimePreparation -> {meta['RepetitionTimePreparation']}")
else:
print(f"No change: RepetitionTimePreparation = {meta['RepetitionTimePreparation']}")Patched ds000240/sub-01/perf/sub-01_asl.json: RepetitionTimePreparation -> 3.5
%%bash
set -u -o pipefail
# FreeSurfer expects the subjects directory to exist at startup
mkdir -p "$HOME/freesurfer-subjects-dir"
# Detect available resources
N_CPUS=$(nproc)
MEM_MB=$(awk '/MemTotal/ {printf "%d", $2/1024}' /proc/meminfo)
# Leave headroom: ~75% of RAM, cap OMP threads at 2
ASLPREP_MEM=$(( MEM_MB * 75 / 100 ))
OMP_THREADS=$(( N_CPUS < 2 ? 1 : 2 ))
echo "Using ${N_CPUS} CPUs, ${ASLPREP_MEM} MB RAM, omp=${OMP_THREADS}"
aslprep ds000240 \
aslprep-output \
participant \
--participant-label 01 \
--fs-license-file ~/.license \
-w aslprep-work \
--nthreads "${N_CPUS}" \
--omp-nthreads "${OMP_THREADS}" \
--mem-mb "${ASLPREP_MEM}" \
2>&1 | tee aslprep.log
# Verify aslprep produced expected outputs
if [ ! -f "aslprep-output/sub-01.html" ]; then
echo "ERROR: ASLPrep did not produce the expected report (sub-01.html)"
exit 1
fiASLPrep Results¶
The full result report is in aslprep-output/sub-01.html and you can open this webpage in Jupyterlab or in the browser. Here a few items from the report as an example and for a quick checking:
Brain mask and brain tissue segmentation of the T1w¶
This panel shows the template T1-weighted image (if several T1w images were found), with contours delineating the detected brain mask and brain tissue segmentations.
from IPython.core.display import SVG
SVG(filename='aslprep-output/sub-01/figures/sub-01_dseg.svg')Spatial normalization of the anatomical T1w reference¶
Results of nonlinear alignment of the T1w reference to the MNI152NLin2009cAsym template.
SVG(filename='aslprep-output/sub-01/figures/sub-01_space-MNI152NLin2009cAsym_T1w.svg')Surface reconstruction¶
Surfaces (white and pial) reconstructed with FreeSurfer (recon-all) overlaid on the participant’s T1w template.
SVG(filename='aslprep-output/sub-01/figures/sub-01_desc-reconall_T1w.svg')Alignment of functional and anatomical MRI data (volume based)¶
mri_coreg (FreeSurfer) was used to generate transformations from EPI space to T1 Space - bbregister refinement rejected. Note that Nearest Neighbor interpolation is used in the reportlets in order to highlight potential spin-history and other artifacts, whereas final images are resampled using Lanczos interpolation.
SVG(filename='aslprep-output/sub-01/figures/sub-01_desc-coreg_asl.svg')ASL Summary¶
Summary statistics are plotted, which may reveal trends or artifacts in the ASL data. DVARS and FD show the standardized DVARS and framewise-displacement measures for each time point. A carpet plot shows the time series for all voxels within the brain mask. Voxels are grouped into cortical (blue), and subcortical (orange) gray matter, cerebellum (green) and white matter and CSF (red), indicated by the color map on the left-hand side.
SVG(filename='aslprep-output/sub-01/figures/sub-01_desc-carpetplot_asl.svg')CBF¶
The maps plot cerebral blood flow (CBF) for basic CBF. The unit is mL/100 g/min.
SVG(filename='aslprep-output/sub-01/figures/sub-01_desc-brain_cbf.svg')Dependencies in Jupyter/Python¶
Using the package watermark to document system environment and software versions used in this notebook, alongside the Neurodesktop version extracted from the
JUPYTER_IMAGEorNEURODESKTOP_VERSIONenvironment variables.
import os
%load_ext watermark
%watermark
%watermark --iversions
neurodesktop_version = (
os.environ.get('JUPYTER_IMAGE', '').split(':')[-1] or
os.environ.get('NEURODESKTOP_VERSION', 'unknown')
)
print(f"Neurodesktop version: {neurodesktop_version}")Last updated: 2026-04-18T04:59:36.592592+00:00
Python implementation: CPython
Python version : 3.13.9
IPython version : 9.7.0
Compiler : GCC 14.3.0
OS : Linux
Release : 5.15.0-171-generic
Machine : x86_64
Processor : x86_64
CPU cores : 32
Architecture: 64bit
IPython: 9.7.0
json : 2.0.9
Neurodesktop version: 2025-12-20
- Adebimpe, A., Bertolero, M., Dolui, S., Cieslak, M., Murtha, K., Baller, E. B., Boeve, B., Boxer, A., Butler, E. R., Cook, P., Colcombe, S., Covitz, S., Davatzikos, C., Davila, D. G., Elliott, M. A., Flounders, M. W., Franco, A. R., Gur, R. E., Gur, R. C., … Satterthwaite, T. D. (2022). ASLPrep: a platform for processing of arterial spin labeled MRI and quantification of regional brain perfusion. Nature Methods, 19(6), 683–686. 10.1038/s41592-022-01458-7
- Dale, A. M., Fischl, B., & Sereno, M. I. (1999). Cortical Surface-Based Analysis. NeuroImage, 9(2), 179–194. 10.1006/nimg.1998.0395
- Fischl, B., Sereno, M. I., & Dale, A. M. (1999). Cortical Surface-Based Analysis. NeuroImage, 9(2), 195–207. 10.1006/nimg.1998.0396
- Fischl, B., & Dale, A. M. (2000). Measuring the thickness of the human cerebral cortex from magnetic resonance images. Proceedings of the National Academy of Sciences, 97(20), 11050–11055. 10.1073/pnas.200033797