fMRI: Coregistration - Slicer, BRAINS

This is currently not working and will raise an exception in release 0.3. It will be fixed in a later release:

python fmri_slicer_coregistration.py
# raise RuntimeWarning, 'Slicer not fully implmented'
from nipype.interfaces.slicer import BRAINSFit, BRAINSResample

Import necessary modules from nipype.

import nipype.interfaces.io as nio  # Data i/o
import nipype.interfaces.utility as util  # utility
import nipype.pipeline.engine as pe  # pypeline engine
import os  # system functions

Preliminaries

Confirm package dependencies are installed. (This is only for the tutorial, rarely would you put this in your own code.)

from nipype.utils.misc import package_check

package_check('numpy', '1.3', 'tutorial1')
package_check('scipy', '0.7', 'tutorial1')
package_check('IPython', '0.10', 'tutorial1')

The nipype tutorial contains data for two subjects. Subject data is in two subdirectories, s1 and s2. Each subject directory contains four functional volumes: f3.nii, f5.nii, f7.nii, f10.nii. And one anatomical volume named struct.nii.

Below we set some variables to inform the datasource about the layout of our data. We specify the location of the data, the subject sub-directories and a dictionary that maps each run to a mnemonic (or field) for the run type (struct or func). These fields become the output fields of the datasource node in the pipeline.

In the example below, run ‘f3’ is of type ‘func’ and gets mapped to a nifti filename through a template ‘%s.nii’. So ‘f3’ would become ‘f3.nii’.

# Specify the location of the data.
data_dir = os.path.abspath('data')
# Specify the subject directories
subject_list = ['s1', 's3']
# Map field names to individual subject runs.
info = dict(func=[['subject_id', 'f3']], struct=[['subject_id', 'struct']])

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

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 contained in subject_list.

infosource.iterables = ('subject_id', subject_list)

Preprocessing pipeline nodes

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

datasource = pe.Node(
    interface=nio.DataGrabber(
        infields=['subject_id'], outfields=['func', 'struct']),
    name='datasource')
datasource.inputs.base_directory = data_dir
datasource.inputs.template = '%s/%s.nii'
datasource.inputs.template_args = info
datasource.inputs.sort_filelist = True

coregister = pe.Node(interface=BRAINSFit(), name="coregister")
coregister.inputs.outputTransform = True
coregister.inputs.outputVolume = True
coregister.inputs.transformType = ["Affine"]

reslice = pe.Node(interface=BRAINSResample(), name="reslice")
reslice.inputs.outputVolume = True

pipeline = pe.Workflow(name="pipeline")
pipeline.base_dir = os.path.abspath('slicer_tutorial/workingdir')

pipeline.connect([(infosource, datasource, [('subject_id', 'subject_id')]),
                  (datasource, coregister, [('func', 'movingVolume')]),
                  (datasource, coregister,
                   [('struct', 'fixedVolume')]), (coregister, reslice, [
                       ('outputTransform', 'warpTransform')
                   ]), (datasource, reslice, [('func', 'inputVolume')]),
                  (datasource, reslice, [('struct', 'referenceVolume')])])

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

Example source code

You can download the full source code of this example. This same script is also included in Nipype1 Examples Niflow under the package/niflow/nipype1/examples directory.