Satra once called the Function
module, the "do anything you want card". Which is a perfect description. Because it allows you to put any code you want into an empty node, which you than can put in your workflow exactly where it needs to be.
You might have already seen the Function
module in the example section in the Node tutorial. Let's take a closer look at it again.
In [ ]:
# Import Node and Function module
from nipype import Node, Function
# Create a small example function
def add_two(x_input):
return x_input + 2
# Create Node
addtwo = Node(Function(input_names=["x_input"],
output_names=["val_output"],
function=add_two),
name='add_node')
There are only two traps that you should be aware when you're using the Function
module. The first one is about naming the input variables. The variable name for the node input has to be the exactly the same name as the function input parameter, in this case this is x_input
.
Otherwise you get the following error:
TypeError: add_two() got an unexpected keyword argument 'x_input'
Interface Function failed to run.
In [ ]:
from nipype import Node, Function
# Create the Function object
def get_random_array(array_shape):
# Import random function
from numpy.random import random
return random(array_shape)
# Create Function Node that executes get_random_array
rndArray = Node(Function(input_names=["array_shape"],
output_names=["random_array"],
function=get_random_array),
name='rndArray_node')
# Specify the array_shape of the random array
rndArray.inputs.array_shape = (3, 3)
# Run node
rndArray.run()
# Print output
print rndArray.result.outputs
Now, let's see what happens if we move the import of random
outside the scope of get_random_array
:
In [ ]:
from nipype import Node, Function
# Import random function
from numpy.random import random
# Create the Function object
def get_random_array(array_shape):
return random(array_shape)
# Create Function Node that executes get_random_array
rndArray = Node(Function(input_names=["array_shape"],
output_names=["random_array"],
function=get_random_array),
name='rndArray_node')
# Specify the array_shape of the random array
rndArray.inputs.array_shape = (3, 3)
# Run node
rndArray.run()
# Print output
print rndArray.result.outputs
As you can see, if we don't import random
inside the scope of the function, we receive the following error:
NameError: global name 'random' is not defined
Interface Function failed to run.