Home · Quickstart · Documentation · About · Nipy

# dMRI: Preprocessing

## Introduction

This script, dmri_preprocessing.py, demonstrates how to prepare dMRI data for tractography and connectivity analysis with nipype.

We perform this analysis using the FSL course data, which can be acquired from here: http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz

Can be executed in command line using `python dmri_preprocessing.py`

Import necessary modules from nipype.

    import os  # system functions
    import nipype.interfaces.io as nio  # Data i/o
    import nipype.interfaces.utility as niu  # utility
    import nipype.algorithms.misc as misc

    import nipype.pipeline.engine as pe  # pypeline engine

    from nipype.interfaces import fsl
    from nipype.interfaces import ants

Load specific nipype’s workflows for preprocessing of dMRI data: `nipype.workflows.dmri.preprocess.epi.all_peb_pipeline`, as data include a b0 volume with reverse encoding direction (P>>>A, or y), in contrast with the general acquisition encoding that is A>>>P or -y (in RAS systems).

    from nipype.workflows.dmri.fsl.artifacts import all_fsl_pipeline, remove_bias

Map field names into individual subject runs

    info = dict(
        dwi=[['subject_id', 'dwidata']],
        bvecs=[['subject_id', 'bvecs']],
        bvals=[['subject_id', 'bvals']],
        dwi_rev=[['subject_id', 'nodif_PA']])

    infosource = pe.Node(
        interface=niu.IdentityInterface(fields=['subject_id']), name="infosource")

    # Set the subject 1 identifier in subject_list,
    # we choose the preproc dataset as it contains uncorrected files.
    subject_list = ['subj1_preproc']

Here we set up iteration over all the subjects. The following line is a particular example of the flexibility of the system. The `datasource` attribute `iterables` tells the pipeline engine that it should repeat the analysis on each of the items in the `subject_list`. In the current example, the entire first level preprocessing and estimation will be repeated for each subject _list.

    infosource.iterables = ('subject_id', subject_list)

Now we create a `nipype.interfaces.io.DataGrabber` object and fill in the information from above about the layout of our data. The `Node` module wraps the interface object and provides additional housekeeping and pipeline specific functionality.

    datasource = pe.Node(
        nio.DataGrabber(infields=['subject_id'], outfields=list(info.keys())),
        name='datasource')

    datasource.inputs.template = "%s/%s"

    # This needs to point to the fdt folder you can find after extracting
    # http://www.fmrib.ox.ac.uk/fslcourse/fsl_course_data2.tar.gz
    datasource.inputs.base_directory = os.path.abspath('fdt1')
    datasource.inputs.field_template = dict(
        dwi='%s/%s.nii.gz', dwi_rev='%s/%s.nii.gz')
    datasource.inputs.template_args = info
    datasource.inputs.sort_filelist = True

An inputnode is used to pass the data obtained by the data grabber to the

    inputnode = pe.Node(
        niu.IdentityInterface(fields=["dwi", "bvecs", "bvals", "dwi_rev"]),
        name="inputnode")

## Setup for dMRI preprocessing

In this section we initialize the appropriate workflow for preprocessing of diffusion images.

### Artifacts correction

We will use the combination of `topup` and `eddy` as suggested by FSL.

In order to configure the susceptibility distortion correction (SDC), we first write the specific parameters of our echo-planar imaging (EPI) images.

Particularly, we look into the `acqparams.txt` file of the selected subject to gather the encoding direction, acceleration factor (in parallel sequences it is > 1), and readout time or echospacing.

    epi_AP = {'echospacing': 66.5e-3, 'enc_dir': 'y-'}
    epi_PA = {'echospacing': 66.5e-3, 'enc_dir': 'y'}
    prep = all_fsl_pipeline(epi_params=epi_AP, altepi_params=epi_PA)

### Bias field correction

Finally, we set up a node to correct for a single multiplicative bias field from computed on the b0 image, as suggested in [Jeurissen2014].

    bias = remove_bias()

## Connect nodes in workflow

We create a higher level workflow to connect the nodes. Please excuse the author for writing the arguments of the `connect` function in a not-standard style with readability aims.

    wf = pe.Workflow(name="dMRI_Preprocessing")
    wf.base_dir = os.path.abspath('preprocessing_dmri_tutorial')
    wf.connect([(infosource, datasource, [('subject_id', 'subject_id')]),
                (datasource, prep,
                 [('dwi', 'inputnode.in_file'), ('dwi_rev', 'inputnode.alt_file'),
                  ('bvals', 'inputnode.in_bval'), ('bvecs', 'inputnode.in_bvec')]),
                (prep, bias, [('outputnode.out_file', 'inputnode.in_file'),
                              ('outputnode.out_mask', 'inputnode.in_mask')]),
                (datasource, bias, [('bvals', 'inputnode.in_bval')])])

Run the workflow as command line executable

    if __name__ == '__main__':
        wf.run()
        wf.write_graph()

Example source code

You can download `the full source code of this example`. This same script is also included in the Nipype source distribution under the `examples` directory.