How to use

PyASL supports two types of workflows based on the type of ASL data:

  • 🧠 Human Data Processing

  • 🐭 Preclinical Data Processing

Each workflow consists of multiple modules for data conversion, preprocessing, and feature map generation.


Human Data Processing

Step 1: Import and Convert Raw Data

Before processing, you need to convert your dataset into ASL-BIDS format using the load_data function. This step also generates a data_description.json file that stores key metadata for further processing.

πŸ“ Prepare Your Dataset

Your raw data should follow this basic structure:

ExampleStudy/
  rawdata/
      sub001/
        ses1/
          anat/
            sub001_ses1_t1w.hdr
            sub001_ses1_t1w.img
          perf/
            sub001_ses1_run1.hdr
            sub001_ses1_run1.img
            sub001_ses1_run2.hdr
            sub001_ses1_run2.img
            sub001_ses1_M0.hdr
            sub001_ses1_M0.img
        ses2/
          ...
      sub002/
        ...

βœ… Notes:

  • Data can be in Analyze (.hdr + .img) or NIfTI (.nii) format

  • The directory must contain a rawdata/ folder and perf/ subfolders

  • The anat/ folder is optional

  • The M0 file name must contain β€œM0”

  • You may rename subject/session folders as needed

βš™οΈ Define ASL metadata

Create a JSON file containing acquisition parameters. This will be used to generate valid BIDS sidecar files.

Note

For a full list of available fields, see JSON Parameters.

{
    "anat": {
        "Manufacturer": "Siemens",
        "ManufacturersModelName": "Prisma",
        "MagneticFieldStrength": 3.0,
        "RepetitionTime": 4.38,
        "EchoTime": 0.0204,
        "FlipAngle": 90
    },
    "M0": {
        "Manufacturer": "Siemens",
        "ManufacturersModelName": "Prisma",
        "MagneticFieldStrength": 3.0,
        "RepetitionTime": 4.38,
        "EchoTime": 0.0204,
        "FlipAngle": 90
    },
    "ASL": {
        "Manufacturer": "Siemens",
        "ManufacturersModelName": "Prisma",
        "MagneticFieldStrength": 3.0,
        "RepetitionTime": 4.38,
        "EchoTime": 0.0204,
        "FlipAngle": 90,
        "ArterialSpinLabelingType": "PCASL",
        "PostLabelingDelay": 2,
        "LabelingDuration": 1.8,
        "M0Type": "Separate",
        "MRAcquisitionType": "3D",
        "BackgroundSuppression": true,
        "BackgroundSuppressionNumberPulses": 2,
        "BackgroundSuppressionPulseTime": [
            1,
            1
        ],
        "LabelingEfficiency": 0.85,
    }
}

πŸš€ Run the Conversion

Use the following command to convert your dataset into ASL-BIDS format:

from pyasl import load_data

load_data(
    "path-to-your-dataset/ExampleStudy",
    "path-to-your-jsonfile/example_parameters.json",
    convert=True,
    is_singledelay=True,
    is_labelcontrol=False
)

After conversion, all images are converted to .nii format, with accompanying .json and .tsv sidecars. A data_description.json file is also generated at the root of the dataset.

Example output structure:

ExampleStudy/
  rawdata/
      sub001/
        ses1/
          anat/
            sub001_ses1_t1w.nii
            sub001_ses1_t1w.json
          perf/
            sub001_ses1_run1.nii
            sub001_ses1_run1.json
            sub001_ses1_run1_aslcontext.tsv
            sub001_ses1_run2.nii
            sub001_ses1_run2.json
            sub001_ses1_run2_aslcontext.tsv
            sub001_ses1_M0.nii
            sub001_ses1_M0.json
        ses2/
          ...
      sub002/
        ...

πŸ—ƒοΈ Load Existing BIDS Dataset (Skip Conversion)

If your dataset is already in ASL-BIDS format, you can skip the conversion step and simply generate the data_description.json file:

load_data("path-to-your-dataset/ExampleStudy", None, convert=False)

Step 2: Run processing functions

After converting your data to ASL-BIDS format (see Step 1), you can run any of the following processing functions. All outputs will be saved in the derivatives/ folder under your dataset root.

Data preparation Step 1: Import / Convert to ASL-BIDS

Use load_data to convert (or validate) your dataset and to create a data_description.json used by most modules.

πŸ“ Expected raw layout

ExampleStudy/
  rawdata/
    sub001/
      ses1/
        anat/                     # optional but recommended
          sub001_ses1_T1w.hdr
          sub001_ses1_T1w.img
        perf/
          sub001_ses1_run1.hdr
          sub001_ses1_run1.img
          sub001_ses1_run2.hdr
          sub001_ses1_run2.img
          sub001_ses1_M0.hdr      # M0 filename must contain β€œM0”
          sub001_ses1_M0.img
      ses2/
        ...
    sub002/
      ...

βœ… Notes

  • Images can be Analyze (.hdr + .img) or NIfTI (.nii/.nii.gz).

  • The tree must contain rawdata/<sub>/<ses>/perf; anat is optional.

  • Subject/session folder names are free-form.

βš™οΈ Minimal acquisition JSON

See :doc:json_parameters for the full schema supported by PyASL modules.

{
"anat": {
    "Manufacturer": "Siemens",
    "ManufacturersModelName": "Prisma",
    "MagneticFieldStrength": 3.0,
    "RepetitionTime": 4.38,
    "EchoTime": 0.0204,
    "FlipAngle": 90
},
"M0": {
    "Manufacturer": "Siemens",
    "ManufacturersModelName": "Prisma",
    "MagneticFieldStrength": 3.0,
    "RepetitionTime": 4.38,
    "EchoTime": 0.0204,
    "FlipAngle": 90
},
"ASL": {
    "Manufacturer": "Siemens",
    "ManufacturersModelName": "Prisma",
    "MagneticFieldStrength": 3.0,
    "RepetitionTime": 4.38,
    "EchoTime": 0.0204,
    "FlipAngle": 90,
    "ArterialSpinLabelingType": "PCASL",
    "PostLabelingDelay": 2.0,
    "LabelingDuration": 1.8,
    "M0Type": "Separate",
    "MRAcquisitionType": "3D",
    "BackgroundSuppression": true,
    "BackgroundSuppressionNumberPulses": 2,
    "BackgroundSuppressionPulseTime": [1.0, 1.0],
    "LabelingEfficiency": 0.85
}
}

πŸš€ Run conversion / validation

from pyasl import load_data

load_data(
    "path-to-your-dataset/ExampleStudy",
    "path-to-your-jsonfile/example_parameters.json",
    convert=True,
    is_singledelay=True,
    is_labelcontrol=False
)

After conversion you will get NIfTI + sidecars and a top-level data_description.json:

ExampleStudy/
  rawdata/
    sub001/
      ses1/
        anat/
          sub001_ses1_T1w.nii
          sub001_ses1_T1w.json
        perf/
          sub001_ses1_run1.nii
          sub001_ses1_run1.json
          sub001_ses1_run1_aslcontext.tsv
          sub001_ses1_run2.nii
          sub001_ses1_run2.json
          sub001_ses1_run2_aslcontext.tsv
          sub001_ses1_M0.nii
          sub001_ses1_M0.json
      ses2/ ...
    sub002/ ...

πŸ—ƒοΈ Use existing ASL-BIDS (skip conversion)

load_data("path-to-your-dataset/ExampleStudy", None, convert=False)

There is a unified dispatcher:

Python: pyasl.pipelines.run_pipeline.run_pipeline(input_dir, config_path)

CLI: python -m pyasl.pipelines.run_pipeline –input <dir> –config <yaml>

Each YAML sets type: … and a list of ordered steps. Below are ready-to-run examples for each pipeline family.

ASLtbx (human, single-delay)

Runner: pyasl.pipelines.asltbx_pipeline.run_pipeline

type: asltbx
steps:
  - name: ResetOrientation
  - name: Realign
  - name: Coregister
  - name: Smooth
    params: { fwhm: [6, 6, 6] }
  - name: CreateMask
    params: { thres: 0.1 }
  - name: PerfusionQuantify
    params:
      QuantFlag: 0
      MaskFlag: true
      MeanFlag: true
      BOLDFlag: false
      PerfFlag: false
      SubtractionType: 0
      SubtrationOrder: 1
      Timeshift: 0.5

MRICloud (human, single- or multi-delay)

Runner: pyasl.pipelines.asl_mricloud_pipeline.run_mricloud_pipeline

type: mricloud
steps:
  - name: MRICloudRescale
  - name: Realign
  - name: MRICloudCalculateDiffmap
  - name: MRICloudCalculateM0
    params: { t1_tissue: 1165, bgs_eff: 0.93 }
  - name: MRICloudCalculateCBF
    params: { t1_blood: 1650, part_coef: 0.9, bgs_eff: 0.93 }
  - name: MRICloudReadMPR
  - name: MRICloudCoregMPR
  - name: MRICloudT1ROICBFAverage

Multidelay variant (fit CBF + ATT, or estimate M0 across PLDs):

type: mricloud
steps:
  - name: MRICloudRescale
  - name: Realign
  - name: MRICloudCalculateDiffmap
  - name: MRICloudMultidelayCalculateM0
  - name: MRICloudMultidelayCalculateCBFATT
  - name: MRICloudReadMPR
  - name: MRICloudCoregMPR

DeepASL / DLASL (denoising)

Runner: pyasl.pipelines.dlasl_pipeline.run_dlasl_pipeline

type: dlasl
steps:
  - name: DLASLBuildMask
    params:
      out_mask: "{root}/derivatives/sub-001/ses-001/perf/dlasl_mask.nii.gz"
  - name: DLASLDenoiseCBF
    params:
      model_selection: 1         # 0=model_068, 1=model_099
      glob_patterns: ["*aCBF*.nii", "*CBF*.nii.gz"]

Oxford ASL (FSL oxford_asl)

Runner: pyasl.pipelines.oxford_asl_pipeline.run_oxford_asl_pipeline

type: oxford_asl
steps:
  - name: OxfordASLSplitM0             # splits out embedded m0scan if present
  - name: OxfordASLRun
    params:
      useStructural: true
      useCalibration: false
      wp: true
      mc: true
      ibf: rpt
      # Optional physiology:
      # bat: 1.3
      # t1: 1.3
      # t1b: 1.65
      # sliceband: 1

Preclinical: single-delay pCASL

Runner: pyasl.pipelines.preclinical_pcasl_pipeline.run_preclinical_pcasl_pipeline

type: pcasl
steps:
  - name: BrukerLoader
    params: { root: "{root}", expno: 18, procno: 1 }
  - name: SteadyStateTrim
    params: { trim: 2 }
  - name: ControlLabelSplit
    params: { control_first: true }
  - name: MotionCheck
  - name: DiffImage
  - name: ComputeM0
    params: { TR: from_meta, T1t: 1900 }
  - name: SlicePLDAdjust
    params: { SGap: 31, T1blood: 2800 }
  - name: CBFRelative
    params: { vmax: 10 }
  - name: BrainMask
    params: { thres: 0.2, open_iter: 2, close_iter: 2 }
  - name: SaveOutputs
    params: { config_echo: "" }

Preclinical: multi-TI PASL (absolute CBF via T1 fit)

Runner: pyasl.pipelines.preclinical_mti_pipeline.run_preclinical_mti_pipeline

type: mti
steps:
  - name: NIfTILoader
    params:
      path: "{root}/data/preclinical_MTI_PASL/FAIREPI.img"
      target: AbsData
      savedir: "{root}/results_mti"
  - name: AbsCBF_T1Fit
    params:
      sel_index: [0, 2, 4, 6]
      glo_index: [1, 3, 5, 7]
      TI_list:   [300, 600, 900, 1200]
      save_curves_every: 200
  - name: SaveOutputs

β€œCustom” pipeline (advanced power-user)

Runner: pyasl.pipelines.custom_pipeline.run_custom_pipeline

Accepts step names or fully-qualified class names.

Automatically resolves relative paths against data_dir.

Replaces any β€œfrom_meta” value with Context[key] if available.

type: custom
steps:
  - module: pyasl.modules.preclinical_loader_nifti.NIfTILoader
    params: { path: "{root}/data.nii.gz", target: AbsData }
  - module: AbsCBF_T1Fit
    params: { sel_index: [0,2], glo_index: [1,3], TI_list: [300, 800] }
  - module: SaveOutputs

Running the pipelines

from pyasl.pipelines.run_pipeline import run_pipeline
run_pipeline("path/to/ExampleStudy", "path/to/config.yaml")

CLI

python -m pyasl.pipelines.run_pipeline \
  --input path/to/ExampleStudy \
  --config path/to/config.yaml
  • YAML not rendering in docs: in rST use .. code-block:: yaml followed by a blank line and then indent the YAML by at least 4 spaces.

  • Relative paths: You can use {root} placeholder; runners resolve it to the dataset root.

  • Missing modules: check the exact step names listed above; for the custom runner you may use a fully-qualified class name.

  • Oxford ASL: requires FSL/oxford_asl in PATH. The runner injects a safe CLI environment; you can extend via params.env.