ASL Processing

Please contact cfmri@ucsd.edu for any questions about this page.

ASL Processing Overview

For standard ASL processing on data acquired from the CFMRI Prisma scanner, our servers are setup to utilize the open source ASLPrep pipeline for processing. Details on the ASLPrep pipeline can be found in their Read the Docs page or in their Nature Methods paper. Briefly, the pipeline attempts to make use of the best tools from AFNI, FSL, FreeSurfer, ANTs, and other major neuroimaging software packages to provide the most robust processing stream possible.

Servers

This pipeline is available to users with an account on either fmri1 or fmri3.

Setup

Setup consists of configuring a setup script, where you specify paths for processing. Our standard approach is to make a setup script for each subject/session you process. An example setup script is given below. A template for your use can be found on the server under the cbfprocpath location on the server, under the SampleSetups/ folder.

You will also need a dcm2bids_config.json configuration file for converting the T1w and ASL DICOMs to BIDS-formatted NIFTI files. There are a few examples under the cbfprocpath location, under the SampleConfigs/ folder. However, please contact Conan for on the dcm2bids_config.json configuration file as this setup can be tricky.

Attention

For the asl_dirs specified in the setup script, put the original ASL DICOM series - NOT the derived Perfusion_Weighted or relCBF scans.

#!/usr/bin/python3

# This script serves as the CFMRI entry point into running ASLPrep.
# Make a copy of this script with a naming convention, e.g. aslprep_SETUP_SubjID, for each subject session.
# Please contact Conan Chen for help with any issues or questions.
#
# Once setup, this script can be called with (type in the terminal):
#
# python3 aslprep_SETUP
#

## --------------------------------- Set repository and singularity paths -------------------------------- ##

# Comment/uncomment depending on your server
# For fmri3
cbfprocpath='/software/cfmri/cbfproc'
simg='/software/singularity_images/aslprep-0.2.8.simg'

# For fmri1
#cbfprocpath='/apps/matlabcode/cbfproc'
#simg='/apps/singularity_images/aslprep-0.2.8.simg'

# Imports and updating path
import sys
sys.path.insert(1, cbfprocpath)
import socket
import aslprep_run


## ---------------------------- Modify fields below for each subject/session ----------------------------- ##

# Base directory
basedir='/data/coc004_group/data/StudyName/SubjID'

# Participant label - cannot contain underscores or dashes!
plabel='SubjID'

# Anatomical DICOM directory
anatdir='0014_ABCD_T1w_MPR_vNav'

# PCASL DICOM directories
asldatasets = [
    # First dataset
    {
        'asl_dir': '0017_PCASL_3mm_14_21_2_Run1_RR'
    }
    # Second dataset
    ,{
        'asl_dir': '0020_PCASL_3mm_14_21_2_Run2_RR'
    }
    # Third dataset
    #,{
    #    'asl_dir': 'pcasldir3'
    #}
]

# Config file for dcm2bids for converting anatomical and PCASL directories - can be relative to basedir, or an absolute path.
config='/data/coc004_group/data/StudyName/dcm2bids_config.json'

# BIDS-formatted directory - can be relative to basedir, or an absolute path.
bidsdir='/data/coc004_group/data/StudyName/sourcedata'

# Output directory - can be relative to basedir, or an absolute path
outdir='/data/coc004_group/data/StudyName/derivatives'


## ---------------------------- Do not modify anything below this line ----------------------------- ##

# Calling dcm2bids, gen_aslcontext, and ASLPrep!
aslprep_run.aslprep_run(cbfprocpath=cbfprocpath, basedir=basedir, anatdir=anatdir, asldatasets=asldatasets, plabel=plabel, config=config,    bidsdir=bidsdir, outdir=outdir)

The pipeline will intake the anatomical and ASL DICOM directories, convert them to BIDS-formatted NIFTI files, and then make the call to ASLPrep. The BIDS-formatted files will be located under the bidsdir directory. The ASLPrep output will be located under the outdir directory.

Initiating Pipeline

After your setup script is ready, simply type python3 aslprep_SETUP_SubjID into the terminal to launch processing.

ASLPrep call

For reference, our call to ASLPrep via Singularity is given below. (This will be called automatically by initiating the pipeline. You do not need to type this out - it is just shared here for reference.)

singularity run --cleanenv --containall                         `# run with cleaned and contained env`  \
    -B ${indir}:/data:ro                                        `# input directory`                     \
    -B ${outdir}:/out                                           `# output directory`                    \
    -B ${workdir}:/work                                         `# ASLPrep intermediate`                \
    -B ${fs_license_localpath}/license.txt:/fs_license.txt      `# freesurfer license file`             \
    -B ${tmpdir}:/tmp                                           `# tmp binding`                         \
    ${simg}                                                     `# singularity container name`          \
    /data                                                       `# input directory within singularity`  \
    /out                                                        `# output directory within singularity` \
    participant                                                 `# participant processing options`      \
    --participant-label $plabel                                 `# participant label`                   \
    --skip-bids-validation                                      `# skip BIDs validation`                \
    --ignore fieldmaps slicetiming sbref                        `# skip steps that are irrelevant here` \
    --m0_scale 10                                               `# scale M0 by 10`                      \
    --force-bbr                                                 `# force boundary-based registration`   \
    --output-spaces MNI152NLin2009cAsym:res-2 anat asl          `# outputs in std, anat, asl spaces`    \
    --fs-license-file /fs_license.txt                           `# freesurfer license in singularity`   \
    --work-dir /work                                            `# work directory in singularity`       \
    --scorescrub                                                `# use SCORE and SCRUB denoising`       \
    --basil                                                     `# use oxford_asl and PVC`

Outputs

You can find a brief description of the outputs on the Read the Docs > Outputs of ASLPrep page. Below is a complete list of expected outputs from this pipeline call.

>> tree sub-SubjID
sub-SubjID
├── anat
│   ├── sub-SubjID_desc-brain_mask.json                                                 # T1w space, brain mask json   ├── sub-SubjID_desc-brain_mask.nii.gz                                               # T1w space, brain mask   ├── sub-SubjID_desc-preproc_T1w.json                                                # T1w space, T1w json   ├── sub-SubjID_desc-preproc_T1w.nii.gz                                              # T1w space, T1w   ├── sub-SubjID_dseg.nii.gz                                                          # T1w space, T1w after tissue segmentation   ├── sub-SubjID_label-CSF_probseg.nii.gz                                             # T1w space, CSF tissue probability map   ├── sub-SubjID_label-GM_probseg.nii.gz                                              # T1w space, GM tissue probability map   ├── sub-SubjID_label-WM_probseg.nii.gz                                              # T1w space, WM tissue probability map   ├── sub-SubjID_space-MNI152NLin2009cAsym_desc-brain_mask.json                       # MNI space, brain mask json   ├── sub-SubjID_space-MNI152NLin2009cAsym_desc-brain_mask.nii.gz                     # MNI space, brain mask   ├── sub-SubjID_space-MNI152NLin2009cAsym_desc-preproc_T1w.json                      # MNI space, T1w json   ├── sub-SubjID_space-MNI152NLin2009cAsym_desc-preproc_T1w.nii.gz                    # MNI space, T1w   ├── sub-SubjID_space-MNI152NLin2009cAsym_dseg.nii.gz                                # MNI space, T1w after tissue segmentation   ├── sub-SubjID_space-MNI152NLin2009cAsym_label-CSF_probseg.nii.gz                   # MNI space, CSF tissue probability map   ├── sub-SubjID_space-MNI152NLin2009cAsym_label-GM_probseg.nii.gz                    # MNI space, GM tissue probability map   ├── sub-SubjID_space-MNI152NLin2009cAsym_label-WM_probseg.nii.gz                    # MNI space, WM tissue probability map   ├── sub-SubjID_from-MNI152NLin2009cAsym_to-T1w_mode-image_xfm.h5                    # transform from MNI to T1w space   └── sub-SubjID_from-T1w_to-MNI152NLin2009cAsym_mode-image_xfm.h5                    # transform from T1w space to MNI
├── figures
│   ├── sub-SubjID_desc-about_T1w.html                                                  # summary of ASLPrep call   ├── sub-SubjID_desc-summary_T1w.html                                                # summary of inputted datasets   ├── sub-SubjID_desc-conform_T1w.html                                                # info on T1w acquisition   ├── sub-SubjID_<run-#>_desc-summary_asl.html                                        # summary of ASL processing   ├── sub-SubjID_<run-#>_desc-validation_asl.html                                     # processing errors (if any)   ├── sub-SubjID_dseg.svg                                                             # image of tissue segmentation   ├── sub-SubjID_<run-#>_desc-flirtbbr_asl.svg                                        # image of T1w-ASL registration   ├── sub-SubjID_space-MNI152NLin2009cAsym_T1w.svg                                    # image of T1w-MNI normalization   ├── sub-SubjID_<run-#>_desc-carpetplot_asl.json                                     # image of ASL time series carpet plot, json   ├── sub-SubjID_<run-#>_desc-carpetplot_asl.svg                                      # image of ASL time series carpet plot   ├── sub-SubjID_<run-#>_desc-cbftsplot_asl.json                                      # image of CBF time series carpet plot, json   ├── sub-SubjID_<run-#>_desc-cbftsplot_asl.svg                                       # image of CBF time series carpet plot   ├── sub-SubjID_<run-#>_desc-cbfplot_asl.json                                        # image of CBF map, json   ├── sub-SubjID_<run-#>_desc-cbfplot_asl.svg                                         # image of CBF map   ├── sub-SubjID_<run-#>_desc-basilplot_asl.json                                      # image of BASIL CBF map, json   ├── sub-SubjID_<run-#>_desc-basilplot_asl.svg                                       # image of BASIL CBF map   ├── sub-SubjID_<run-#>_desc-pvcplot_asl.json                                        # image of GM PVC CBF map, json   ├── sub-SubjID_<run-#>_desc-pvcplot_asl.svg                                         # image of GM PVC CBF map   ├── sub-SubjID_<run-#>_desc-scoreplot_asl.json                                      # image of SCORE CBF map, json   ├── sub-SubjID_<run-#>_desc-scoreplot_asl.svg                                       # image of SCORE CBF map   ├── sub-SubjID_<run-#>_desc-scrubplot_asl.json                                      # image of SCRUB CBF map, json   └── sub-SubjID_<run-#>_desc-scrubplot_asl.svg                                       # image of SCRUB CBF map
├── log
│   └── 20220730-075842_48cc819d-759d-453b-be23-74cb3e868ac2                            # folder with timestamp of processing run       └── aslprep.toml                                                                # processing log with workflow params
└── perf
    ├── sub-SubjID_<run-#>_aslref.nii.gz                                                # native space, ASL reference image (M0)
    ├── sub-SubjID_<run-#>_cbf.nii.gz                                                   # native space, CBF time series
    ├── sub-SubjID_<run-#>_desc-basil_cbf.nii.gz                                        # native space, BASIL CBF map
    ├── sub-SubjID_<run-#>_desc-bat_cbf.nii.gz                                          # native space, BASIL BAT map
    ├── sub-SubjID_<run-#>_desc-brain_mask.json                                         # native space, brain mask json
    ├── sub-SubjID_<run-#>_desc-brain_mask.nii.gz                                       # native space, brain mask
    ├── sub-SubjID_<run-#>_desc-preproc_asl.json                                        # native space, ASL time series json
    ├── sub-SubjID_<run-#>_desc-preproc_asl.nii.gz                                      # native space, ASL time series
    ├── sub-SubjID_<run-#>_desc-pvGM_cbf.nii.gz                                         # native space, GM PVC CBF map
    ├── sub-SubjID_<run-#>_desc-pvWM_cbf.nii.gz                                         # native space, WM PVC CBF map
    ├── sub-SubjID_<run-#>_desc-score_cbf.nii.gz                                        # native space, CBF time series after SCORE censoring
    ├── sub-SubjID_<run-#>_desc-score_mean_cbf.nii.gz                                   # native space, SCORE CBF map
    ├── sub-SubjID_<run-#>_desc-scrub_cbf.nii.gz                                        # native space, SCRUB CBF map
    ├── sub-SubjID_<run-#>_mean_cbf.nii.gz                                              # native space, mean CBF map
    ├── sub-SubjID_<run-#>_space-T1w_aslref.nii.gz                                      # T1w space, ASL reference image (M0)
    ├── sub-SubjID_<run-#>_space-T1w_cbf.nii.gz                                         # T1w space, CBF time series
    ├── sub-SubjID_<run-#>_space-T1w_desc-basil_cbf.nii.gz                              # T1w space, BASIL CBF map
    ├── sub-SubjID_<run-#>_space-T1w_desc-bat_cbf.nii.gz                                # T1w space, BASIL BAT map
    ├── sub-SubjID_<run-#>_space-T1w_desc-brain_mask.json                               # T1w space, brain mask json
    ├── sub-SubjID_<run-#>_space-T1w_desc-brain_mask.nii.gz                             # T1w space, brain mask json
    ├── sub-SubjID_<run-#>_space-T1w_desc-preproc_asl.json                              # T1w space, ASL time series json
    ├── sub-SubjID_<run-#>_space-T1w_desc-preproc_asl.nii.gz                            # T1w space, ASL time series
    ├── sub-SubjID_<run-#>_space-T1w_desc-pvGM_cbf.nii.gz                               # T1w space, GM PVC CBF map
    ├── sub-SubjID_<run-#>_space-T1w_desc-pvWM_cbf.nii.gz                               # T1w space, GM PVC CBF map
    ├── sub-SubjID_<run-#>_space-T1w_desc-score_cbf.nii.gz                              # T1w space, CBF time series after SCORE censoring
    ├── sub-SubjID_<run-#>_space-T1w_desc-score_mean_cbf.nii.gz                         # T1w space, SCORE CBF map
    ├── sub-SubjID_<run-#>_space-T1w_desc-scrub_cbf.nii.gz                              # T1w space, SCRUB CBF map
    ├── sub-SubjID_<run-#>_space-T1w_mean_cbf.nii.gz                                    # T1w space, mean CBF map
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_aslref.nii.gz                # MNI space, ASL reference image (M0)
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_cbf.nii.gz                   # MNI space, CBF time series
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_desc-basil_cbf.nii.gz        # MNI space, BASIL CBF map
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_desc-bat_cbf.nii.gz          # MNI space, BASIL BAT map
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_desc-brain_mask.json         # MNI space, brain mask json
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_desc-brain_mask.nii.gz       # MNI space, brain mask
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_desc-preproc_asl.json        # MNI Space, ASL time series json
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_desc-preproc_asl.nii.gz      # MNI space, ASL time series
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_desc-pvGM_cbf.nii.gz         # MNI space, GM PVC map
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_desc-pvWM_cbf.nii.gz         # MNI space, WM PVC map
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_desc-score_cbf.nii.gz        # MNI space, CBF time series after SCORE censoring
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_desc-score_mean_cbf.nii.gz   # MNI space, SCORE CBF map
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_desc-scrub_cbf.nii.gz        # MNI space, SCRUB CBF map
    ├── sub-SubjID_<run-#>_space-MNI152NLin2009cAsym_res-2_mean_cbf.nii.gz              # MNI space, mean CBF map
    ├── sub-SubjID_<run-#>_from-scanner_to-T1w_mode-image_xfm.txt                       # transform from native space to T1w space
    ├── sub-SubjID_<run-#>_from-T1w_to-scanner_mode-image_xfm.txt                       # transform from T1w space to native space
    ├── sub-SubjID_<run-#>_desc-confounds_regressors.tsv                                # confounds regressors
    ├── sub-SubjID_<run-#>_desc-quality_control_cbf.csv                                 # quality-control values
    ├── sub-SubjID_<run-#>_desc-HavardOxford_mean_basil.csv                             # mean values in Harvard-Oxford atlas ROIs in BASIL CBF map
    ├── sub-SubjID_<run-#>_desc-HavardOxford_mean_cbf.csv                               # mean values in Harvard-Oxford atlas ROIs in mean CBF map
    ├── sub-SubjID_<run-#>_desc-HavardOxford_mean_pvc.csv                               # mean values in Harvard-Oxford atlas ROIs in GM PVC CBF map
    ├── sub-SubjID_<run-#>_desc-HavardOxford_mean_score.csv                             # mean values in Harvard-Oxford atlas ROIs in SCORE CBF map
    ├── sub-SubjID_<run-#>_desc-HavardOxford_mean_scrub.csv                             # mean values in Harvard-Oxford atlas ROIs in SCRUB CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer200x7_mean_basil.csv                            # mean values in Schaefer200x7 atlas ROIs in BASIL CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer200x7_mean_cbf.csv                              # mean values in Schaefer200x7 atlas ROIs in mean CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer200x7_mean_pvc.csv                              # mean values in Schaefer200x7 atlas ROIs in GM PVC CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer200x7_mean_score.csv                            # mean values in Schaefer200x7 atlas ROIs in SCORE CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer200x7_mean_scrub.csv                            # mean values in Schaefer200x7 atlas ROIs in SCRUB CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer200x17_mean_basil.csv                           # mean values in Schaefer200x17 atlas ROIs in BASIL CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer200x17_mean_cbf.csv                             # mean values in Schaefer200x17 atlas ROIs in mean CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer200x17_mean_pvc.csv                             # mean values in Schaefer200x17 atlas ROIs in GM PVC CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer200x17_mean_score.csv                           # mean values in Schaefer200x17 atlas ROIs in SCORE CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer200x17_mean_scrub.csv                           # mean values in Schaefer200x17 atlas ROIs in SCRUB CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer400x7_mean_basil.csv                            # mean values in Schaefer400x7 atlas ROIs in BASIL CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer400x7_mean_cbf.csv                              # mean values in Schaefer400x7 atlas ROIs in mean CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer400x7_mean_pvc.csv                              # mean values in Schaefer400x7 atlas ROIs in GM PVC CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer400x7_mean_score.csv                            # mean values in Schaefer400x7 atlas ROIs in SCORE CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer400x7_mean_scrub.csv                            # mean values in Schaefer400x7 atlas ROIs in SCRUB CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer400x17_mean_basil.csv                           # mean values in Schaefer400x17 atlas ROIs in BASIL CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer400x17_mean_cbf.csv                             # mean values in Schaefer400x17 atlas ROIs in mean CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer400x17_mean_pvc.csv                             # mean values in Schaefer400x17 atlas ROIs in GM PVC CBF map
    ├── sub-SubjID_<run-#>_desc-schaefer400x17_mean_score.csv                           # mean values in Schaefer400x17 atlas ROIs in SCORE CBF map
    └── sub-SubjID_<run-#>_desc-schaefer400x17_mean_scrub.csv                           # mean values in Schaefer400x17 atlas ROIs in SCRUB CBF map

QA Summary Reports

Besides the NIFTI files, the processing summary report is also an invaluable output from the pipeline, providing an intuitive and informative way to check your data. The reports are the *.html files in the <outdir>/aslprep directory.

>> cd ~/data/StudyName/derivatives/aslprep
>> ls -1
dataset_description.json
logs
sub-001
sub-001.html      <--- these are the summary reports
sub-002
sub-002.html
sub-003
sub-003.html
...

You can open up the reports directly on our servers using firefox sub-001.html. Or, you could download (e.g. using scp, rsync or some other FTP method) the data and reports to your local computer to view them in our web browser of choice. If you want to view them locally, make sure to download both the .html report and the output data folder itself. The .html report includes images from the figures/ folder, which will not render if the output data folder is not also present from where you are viewing the report.

The report provides intuitive checks on major processing steps, such as T1w tissue segmentation, ASL-T1w registration, T1w-MNI normalization, and CBF maps. The recommendation is to review the T1w tissue segmentation, ASL-T1w registration, and T1w-MNI normalization figures. The latter two figures even provide dynamic fading between the ASL-T1w images (or T1w-MNI images) for visual checking.

The CBF figures provide a useful sanity check too. You may also want to supplement this review by opening the NIFTI files in your preferred neuroimaging viewer, such as AFNI or fsleyes, where you have better control of the color map and scales.

Follow this link for a sample ASLPrep report on data collected at CFMRI.