Saving Workflows and Nodes to a file (experimental)

On top of the standard way of saving (i.e. serializing) objects in Python (see pickle) Nipype provides methods to turn Workflows and nodes into human readable code. This is useful if you want to save a Workflow that you have generated on the fly for future use.

To generate Python code for a Workflow use the export method:

from nipype.interfaces.fsl import BET, ImageMaths
from nipype.pipeline.engine import Workflow, Node, MapNode, format_node
from nipype.interfaces.utility import Function, IdentityInterface

bet = Node(BET(), name='bet')
bet.iterables = ('frac', [0.3, 0.4])

bet2 = MapNode(BET(), name='bet2', iterfield=['infile'])
bet2.iterables = ('frac', [0.4, 0.5])

maths = Node(ImageMaths(), name='maths')

def testfunc(in1):
    """dummy func
    """
    out = in1 + 'foo' + "out1"
    return out

funcnode = Node(Function(input_names=['a'], output_names=['output'], function=testfunc),
                name='testfunc')
funcnode.inputs.in1 = '-sub'
func = lambda x: x

inode = Node(IdentityInterface(fields=['a']), name='inode')

wf = Workflow('testsave')
wf.add_nodes([bet2])
wf.connect(bet, 'mask_file', maths, 'in_file')
wf.connect(bet2, ('mask_file', func), maths, 'in_file2')
wf.connect(inode, 'a', funcnode, 'in1')
wf.connect(funcnode, 'output', maths, 'op_string')

wf.export()

This will create a file “outputtestsave.py” with the following content:

from nipype.pipeline.engine import Workflow, Node, MapNode
from nipype.interfaces.utility import IdentityInterface
from nipype.interfaces.utility import Function
from nipype.utils.misc import getsource
from nipype.interfaces.fsl.preprocess import BET
from nipype.interfaces.fsl.utils import ImageMaths
# Functions
func = lambda x: x
# Workflow
testsave = Workflow("testsave")
# Node: testsave.inode
inode = Node(IdentityInterface(fields=['a'], mandatory_inputs=True), name="inode")
# Node: testsave.testfunc
testfunc = Node(Function(input_names=['a'], output_names=['output']), name="testfunc")
def testfunc_1(in1):
    """dummy func
    """
    out = in1 + 'foo' + "out1"
    return out

testfunc.inputs.function_str = getsource(testfunc_1)
testfunc.inputs.ignore_exception = False
testfunc.inputs.in1 = '-sub'
testsave.connect(inode, "a", testfunc, "in1")
# Node: testsave.bet2
bet2 = MapNode(BET(), iterfield=['infile'], name="bet2")
bet2.iterables = ('frac', [0.4, 0.5])
bet2.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'}
bet2.inputs.ignore_exception = False
bet2.inputs.output_type = 'NIFTI_GZ'
bet2.inputs.terminal_output = 'stream'
# Node: testsave.bet
bet = Node(BET(), name="bet")
bet.iterables = ('frac', [0.3, 0.4])
bet.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'}
bet.inputs.ignore_exception = False
bet.inputs.output_type = 'NIFTI_GZ'
bet.inputs.terminal_output = 'stream'
# Node: testsave.maths
maths = Node(ImageMaths(), name="maths")
maths.inputs.environ = {'FSLOUTPUTTYPE': 'NIFTI_GZ'}
maths.inputs.ignore_exception = False
maths.inputs.output_type = 'NIFTI_GZ'
maths.inputs.terminal_output = 'stream'
testsave.connect(bet2, ('mask_file', func), maths, "in_file2")
testsave.connect(bet, "mask_file", maths, "in_file")
testsave.connect(testfunc, "output", maths, "op_string")

The file is ready to use and includes all the necessary imports.