What is Nipype?

  • Nipype is an open-source, community-developed software package written in Python.
  • Provides unified way of interfacing with heterogeneous neuroimaging software like SPM, FSL, FreeSurfer, AFNI, ANTS, Camino, MRtrix, MNE, Slicer and many more.
  • Allows users to create flexible, complex workflows consisting of multiple processing steps using any software package above
  • Efficient and optimized computation through parallel execution plugins

I don't need that, I'm happy with SPM12!

I mean, there's no problem with SPM's batch system...

ok, ok... it get's tiring to have a separate batch script for each subject and MATLAB license issues are sometimes a pain. But hey, the nice looking GUI makes it so easy to use!

Using SPM12 with Nipype is simpler than any matlabbatch and it's intuitive to read:

from nipype.interfaces.spm import Smooth
smooth = Smooth()
smooth.inputs.in_files = 'functional.nii'
smooth.inputs.fwhm = 6
smooth.run()

I don't need that, I'm happy with FSL!

The GUI might look a bit old fashion but the command line interface gives me all the flexibility I need!

I don't care that it might be more difficult to learn than other neuroimaging softwares. At least it doesn't take me 20 clicks to do simple motion correction. And once you figure out the underlying commands, it's rather simple to script.

Nipype makes using FSL even easier:

from nipype.interfaces.fsl import MCFLIRT
mcflt = MCFLIRT()
mcflt.inputs.in_file = 'functional.nii'
mcflt.run()

And gives you transparency to what's happening under the hood with one additional line:

In [1]: mcflt.cmdline
Out[1]: 'mcflirt -in functional.nii -out functional_mcf.nii'

I don't need that, I'm happy with FreeSurfer!

You and your problems with fMRI data. I'm perfectly happy with FreeSurfer's command line interface. It gives me all I need to do surface based analyses.

Of course, you can run your sequential FreeSurfer scripts as you want. But wouldn't it be nice to optimize computation time by using parallel computation?

Let's imagine you want to do smoothing on the surface, with two different FWHM values, on both hemispheres and this on six subjects, all in parallel? With Nipype this is as simple as that:

from nipype.interfaces.freesurfer import SurfaceSmooth
smoother = SurfaceSmooth()
smoother.inputs.in_file = "{hemi}.func.mgz"
smoother.iterables = [("hemi", ['lh', 'rh']),
                      ("fwhm", [4, 8]),
                      ("subject_id", ['sub01', 'sub02', 'sub03',
                                      'sub04', 'sub05', 'sub06']),
                      ]
smoother.run(mode='parallel')

But I like my neuorimaging toolbox

  • You can keep it! But instead of being stuck in MATLAB with SPM, or having scripting issues with FreeSurfer, ANTs or FSL,..
  • Nipype gives you the possibility to select the algorithms that you prefer from many different sofware packages.
  • In short, you can have all the advantages without the disadvantage of being stuck with a programming language or software package

A short Example

Let's assume we want to do preprocessing that uses SPM for motion correction, FreeSurfer for coregistration, ANTS for normalization and FSL for smoothing. Normally this would be a hell of a mess. It would mean switching between multiple scripts in different programming languages with a lot of manual intervention. Nipype comes to the rescue!

Code Example

The code to create an Nipype workflow like the example before would look something like this:

# Import modules
import nipype
from nipype.interfaces.freesurfer import BBRegister
from nipype.interfaces.ants       import WarpTimeSeriesImageMultiTransform
from nipype.interfaces.fsl        import SUSAN
from nipype.interfaces.spm        import Realing

# Motion Correction (SPM)
realign = Realing(register_to_mean=True)

# Coregistration (FreeSurfer)
coreg = BBRegister()

# Normalization (ANTS)
normalize = WarpTimeSeriesImageMultiTransform()

# Smoothing (FSL)
smooth = SUSAN(fwhm=6.0)
# Where can the raw data be found?
grabber = nipype.DataGrabber()
grabber.inputs.base_directory = '~/experiment_folder/data'
grabber.inputs.subject_id = ['subject1', 'subject2', 'subject3']

# Where should the output data be stored at?
sink = nipype.DataSink()
sink.inputs.base_directory = '~/experiment_folder/output_folder'
# Create a workflow to connect all those nodes
preprocflow = nipype.Workflow()

# Connect the nodes to each other
preprocflow.connect([(grabber   -> realign  ),
                     (realign   -> coreg    ),
                     (coreg     -> normalize),
                     (normalize -> smooth   ),
                     (smooth    -> sink     )
                     ])

# Run the workflow in parallel
preprocflow.run(mode='parallel')

Important: This code is a shortened and simplified version of the real Nipype code. But it gives you a good idea of how intuitive it is to use Nipype for your neuroimaging analysis.

So again, what is Nipype?

Nipype consists of many parts, but the most important ones are Interfaces, the Workflow Engine and the Execution Plugins:

  • Interface: Wraps a program or function

  • Node/MapNode: Wraps an Interface for use in a Workflow that provides caching and other goodies (e.g., pseudo-sandbox)

  • Workflow: A graph or forest of graphs whose nodes are of type Node, MapNode or Workflow and whose edges represent data flow

  • Plugin: A component that describes how a Workflow should be executed

Slideshow Mode


In [ ]:
!jupyter-nbconvert --to slides introduction_nipype.ipynb --reveal-prefix=reveal.js