From 7aee50da144cef6968fbcd9b2f04163d83296521 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 30 Jan 2015 18:35:08 +0100 Subject: [PATCH 01/40] DOC Updated doc/devel/matlab_interface_devel.rst: remove invalid caracters in example, PEP8-ize examples, language. --- doc/devel/matlab_interface_devel.rst | 211 +++++++++++++-------------- 1 file changed, 103 insertions(+), 108 deletions(-) diff --git a/doc/devel/matlab_interface_devel.rst b/doc/devel/matlab_interface_devel.rst index 2633dee90e..5773a90122 100644 --- a/doc/devel/matlab_interface_devel.rst +++ b/doc/devel/matlab_interface_devel.rst @@ -4,59 +4,62 @@ How to wrap a MATLAB script =========================== -This is minimal script for wrapping MATLAB code. You should replace the MATLAB -code template, and define approriate inputs and outputs. - Example 1 +++++++++ -.. testcode:: +This is a minimal script for wrapping MATLAB code. You should replace the MATLAB +code template, and define approriate inputs and outputs. - from nipype.interfaces.matlab import MatlabCommand - from nipype.interfaces.base import TraitedSpec, BaseInterface, BaseInterfaceInputSpec, File - import os - from string import Template - - class ConmapTxt2MatInputSpec(BaseInterfaceInputSpec): - in_file = File(exists=True, mandatory=True) - out_file = File('cmatrix.mat', usedefault=True) - - class ConmapTxt2MatOutputSpec(TraitedSpec): - out_file = File(exists=True) - - class ConmapTxt2Mat(BaseInterface): - input_spec = ConmapTxt2MatInputSpec - output_spec = ConmapTxt2MatOutputSpec - - def _run_interface(self, runtime): - d = dict(in_file=self.inputs.in_file, - out_file=self.inputs.out_file) - #this is your MATLAB code template - script = Template("""in_file = ‘$in_file'; - out_file = ‘$out_file'; - ConmapTxt2Mat(in_file, out_file); - exit; - """).substitute(d) - - # mfile = True will create an .m file with your script and executed. - # Alternatively - # mfile can be set to False which will cause the matlab code to be - # passed - # as a commandline argument to the matlab executable - # (without creating any files). - # This, however, is less reliable and harder to debug - # (code will be reduced to - # a single line and stripped of any comments). +.. testcode:: - mlab = MatlabCommand(script=script, mfile=True) - result = mlab.run() - return result.runtime - - def _list_outputs(self): - outputs = self._outputs().get() - outputs['out_file'] = os.path.abspath(self.inputs.out_file) - return outputs + from nipype.interfaces.matlab import MatlabCommand + from nipype.interfaces.base import TraitedSpec, \ + BaseInterface, BaseInterfaceInputSpec, File + import os + from string import Template + + + class ConmapTxt2MatInputSpec(BaseInterfaceInputSpec): + in_file = File(exists=True, mandatory=True) + out_file = File('cmatrix.mat', usedefault=True) + + + class ConmapTxt2MatOutputSpec(TraitedSpec): + out_file = File(exists=True) + + + class ConmapTxt2Mat(BaseInterface): + input_spec = ConmapTxt2MatInputSpec + output_spec = ConmapTxt2MatOutputSpec + + def _run_interface(self, runtime): + d = dict(in_file=self.inputs.in_file, + out_file=self.inputs.out_file) + # This is your MATLAB code template + script = Template("""in_file = '$in_file'; + out_file = '$out_file'; + ConmapTxt2Mat(in_file, out_file); + exit; + """).substitute(d) + + # mfile = True will create an .m file with your script and executed. + # Alternatively + # mfile can be set to False which will cause the matlab code to be + # passed + # as a commandline argument to the matlab executable + # (without creating any files). + # This, however, is less reliable and harder to debug + # (code will be reduced to + # a single line and stripped of any comments). + mlab = MatlabCommand(script=script, mfile=True) + result = mlab.run() + return result.runtime + + def _list_outputs(self): + outputs = self._outputs().get() + outputs['out_file'] = os.path.abspath(self.inputs.out_file) + return outputs Example 2 @@ -65,66 +68,58 @@ Example 2 By subclassing **MatlabCommand** for your main class, and **MatlabInputSpec** for your input and output spec, you gain access to some useful MATLAB hooks .. testcode:: - - import os - from nipype.interfaces.base import File, traits - from nipype.interfaces.matlab import MatlabCommand, MatlabInputSpec - - - class HelloWorldInputSpec( MatlabInputSpec): - name = traits.Str( mandatory = True, - desc = 'Name of person to say hello to') - - class HelloWorldOutputSpec( MatlabInputSpec): - matlab_output = traits.Str( ) - - class HelloWorld( MatlabCommand): - """ Basic Hello World that displays Hello in MATLAB - - Returns - ------- - - matlab_output : capture of matlab output which may be - parsed by user to get computation results - - Examples - -------- - - >>> hello = HelloWorld() - >>> hello.inputs.name = 'hello_world' - >>> out = hello.run() - >>> print out.outputs.matlab_output - """ - input_spec = HelloWorldInputSpec - output_spec = HelloWorldOutputSpec - - def _my_script(self): - """This is where you implement your script""" - script = """ - disp('Hello %s Python') - two = 1 + 1 - """%(self.inputs.name) - return script - - - def run(self, **inputs): - ## inject your script - self.inputs.script = self._my_script() - results = super(MatlabCommand, self).run( **inputs) - stdout = results.runtime.stdout - # attach stdout to outputs to access matlab results - results.outputs.matlab_output = stdout - return results - - - def _list_outputs(self): - outputs = self._outputs().get() - return outputs - - - - - - + from nipype.interfaces.base import traits + from nipype.interfaces.matlab import MatlabCommand, MatlabInputSpec + + + class HelloWorldInputSpec(MatlabInputSpec): + name = traits.Str(mandatory=True, + desc='Name of person to say hello to') + + + class HelloWorldOutputSpec(MatlabInputSpec): + matlab_output = traits.Str() + + + class HelloWorld(MatlabCommand): + """Basic Hello World that displays Hello in MATLAB + + Returns + ------- + + matlab_output : capture of matlab output which may be + parsed by user to get computation results + + Examples + -------- + + >>> hello = HelloWorld() + >>> hello.inputs.name = 'hello_world' + >>> out = hello.run() + >>> print out.outputs.matlab_output + """ + input_spec = HelloWorldInputSpec + output_spec = HelloWorldOutputSpec + + def _my_script(self): + """This is where you implement your script""" + script = """ + disp('Hello %s Python') + two = 1 + 1 + """ % (self.inputs.name) + return script + + def run(self, **inputs): + # Inject your script + self.inputs.script = self._my_script() + results = super(MatlabCommand, self).run(**inputs) + stdout = results.runtime.stdout + # Attach stdout to outputs to access matlab results + results.outputs.matlab_output = stdout + return results + + def _list_outputs(self): + outputs = self._outputs().get() + return outputs From c6d4d064f35a87a65762351afd91ff28d8bea558 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 2 Feb 2015 15:53:01 +0100 Subject: [PATCH 02/40] DOC Fix typo. --- doc/quickstart.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/quickstart.rst b/doc/quickstart.rst index 2a78cf9bf5..1dc0ee6aba 100644 --- a/doc/quickstart.rst +++ b/doc/quickstart.rst @@ -16,7 +16,7 @@ Downloading and installing Beginner's guide ================ -Beginner's tutorials (IPython Notebooks). `Availible here`__ +Beginner's tutorials (IPython Notebooks). `Available here`__ Michael Notter's Nipype guide. `Available here`__ From 552d06d99f87a4344c44d5e152c8d98080698c06 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 2 Feb 2015 15:53:13 +0100 Subject: [PATCH 03/40] DOC Fix typo. --- doc/users/function_interface.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/users/function_interface.rst b/doc/users/function_interface.rst index cd7ff3f1bf..511df3d8ae 100644 --- a/doc/users/function_interface.rst +++ b/doc/users/function_interface.rst @@ -146,6 +146,6 @@ the string would be Unlike when using a function object, this input can be set like any other, meaning that you could write a function that outputs different function strings depending on some run-time contingencies, and connect that output -the the ``function_str`` input of a downstream Function interface. +the ``function_str`` input of a downstream Function interface. .. include:: ../links_names.txt From ee6c25d91a59abdf4348444ac13b72a87338f273 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 2 Feb 2015 16:06:19 +0100 Subject: [PATCH 04/40] DOC reworked devel/matlab_interface_devel.rst: move code to external files and correct output specification in example 2. --- doc/devel/matlab_example1.py | 47 ++++++++++++ doc/devel/matlab_example2.py | 54 +++++++++++++ doc/devel/matlab_interface_devel.rst | 110 ++------------------------- 3 files changed, 107 insertions(+), 104 deletions(-) create mode 100644 doc/devel/matlab_example1.py create mode 100644 doc/devel/matlab_example2.py diff --git a/doc/devel/matlab_example1.py b/doc/devel/matlab_example1.py new file mode 100644 index 0000000000..5fef8a9b18 --- /dev/null +++ b/doc/devel/matlab_example1.py @@ -0,0 +1,47 @@ +from nipype.interfaces.matlab import MatlabCommand +from nipype.interfaces.base import TraitedSpec, \ + BaseInterface, BaseInterfaceInputSpec, File +import os +from string import Template + + +class ConmapTxt2MatInputSpec(BaseInterfaceInputSpec): + in_file = File(exists=True, mandatory=True) + out_file = File('cmatrix.mat', usedefault=True) + + +class ConmapTxt2MatOutputSpec(TraitedSpec): + out_file = File(exists=True) + + +class ConmapTxt2Mat(BaseInterface): + input_spec = ConmapTxt2MatInputSpec + output_spec = ConmapTxt2MatOutputSpec + + def _run_interface(self, runtime): + d = dict(in_file=self.inputs.in_file, + out_file=self.inputs.out_file) + # This is your MATLAB code template + script = Template("""in_file = '$in_file'; + out_file = '$out_file'; + ConmapTxt2Mat(in_file, out_file); + exit; + """).substitute(d) + + # mfile = True will create an .m file with your script and executed. + # Alternatively + # mfile can be set to False which will cause the matlab code to be + # passed + # as a commandline argument to the matlab executable + # (without creating any files). + # This, however, is less reliable and harder to debug + # (code will be reduced to + # a single line and stripped of any comments). + mlab = MatlabCommand(script=script, mfile=True) + result = mlab.run() + return result.runtime + + def _list_outputs(self): + outputs = self._outputs().get() + outputs['out_file'] = os.path.abspath(self.inputs.out_file) + return outputs \ No newline at end of file diff --git a/doc/devel/matlab_example2.py b/doc/devel/matlab_example2.py new file mode 100644 index 0000000000..836f407c26 --- /dev/null +++ b/doc/devel/matlab_example2.py @@ -0,0 +1,54 @@ +from nipype.interfaces.base import traits +from nipype.interfaces.base import TraitedSpec +from nipype.interfaces.matlab import MatlabCommand, MatlabInputSpec + + +class HelloWorldInputSpec(MatlabInputSpec): + name = traits.Str(mandatory=True, + desc='Name of person to say hello to') + + +class HelloWorldOutputSpec(TraitedSpec): + matlab_output = traits.Str() + + +class HelloWorld(MatlabCommand): + """Basic Hello World that displays Hello in MATLAB + + Returns + ------- + + matlab_output : capture of matlab output which may be + parsed by user to get computation results + + Examples + -------- + + >>> hello = HelloWorld() + >>> hello.inputs.name = 'hello_world' + >>> out = hello.run() + >>> print out.outputs.matlab_output + """ + input_spec = HelloWorldInputSpec + output_spec = HelloWorldOutputSpec + + def _my_script(self): + """This is where you implement your script""" + script = """ + disp('Hello %s Python') + two = 1 + 1 + """ % (self.inputs.name) + return script + + def run(self, **inputs): + # Inject your script + self.inputs.script = self._my_script() + results = super(MatlabCommand, self).run(**inputs) + stdout = results.runtime.stdout + # Attach stdout to outputs to access matlab results + results.outputs.matlab_output = stdout + return results + + def _list_outputs(self): + outputs = self._outputs().get() + return outputs \ No newline at end of file diff --git a/doc/devel/matlab_interface_devel.rst b/doc/devel/matlab_interface_devel.rst index 5773a90122..61ef8a08b6 100644 --- a/doc/devel/matlab_interface_devel.rst +++ b/doc/devel/matlab_interface_devel.rst @@ -11,115 +11,17 @@ Example 1 This is a minimal script for wrapping MATLAB code. You should replace the MATLAB code template, and define approriate inputs and outputs. -.. testcode:: - - from nipype.interfaces.matlab import MatlabCommand - from nipype.interfaces.base import TraitedSpec, \ - BaseInterface, BaseInterfaceInputSpec, File - import os - from string import Template - - - class ConmapTxt2MatInputSpec(BaseInterfaceInputSpec): - in_file = File(exists=True, mandatory=True) - out_file = File('cmatrix.mat', usedefault=True) - - - class ConmapTxt2MatOutputSpec(TraitedSpec): - out_file = File(exists=True) - - - class ConmapTxt2Mat(BaseInterface): - input_spec = ConmapTxt2MatInputSpec - output_spec = ConmapTxt2MatOutputSpec - - def _run_interface(self, runtime): - d = dict(in_file=self.inputs.in_file, - out_file=self.inputs.out_file) - # This is your MATLAB code template - script = Template("""in_file = '$in_file'; - out_file = '$out_file'; - ConmapTxt2Mat(in_file, out_file); - exit; - """).substitute(d) - - # mfile = True will create an .m file with your script and executed. - # Alternatively - # mfile can be set to False which will cause the matlab code to be - # passed - # as a commandline argument to the matlab executable - # (without creating any files). - # This, however, is less reliable and harder to debug - # (code will be reduced to - # a single line and stripped of any comments). - mlab = MatlabCommand(script=script, mfile=True) - result = mlab.run() - return result.runtime - - def _list_outputs(self): - outputs = self._outputs().get() - outputs['out_file'] = os.path.abspath(self.inputs.out_file) - return outputs +.. literalinclude:: matlab_example1.py +:download:`Download the source code of this example `. Example 2 +++++++++ -By subclassing **MatlabCommand** for your main class, and **MatlabInputSpec** for your input and output spec, you gain access to some useful MATLAB hooks +By subclassing :class:`nipype.interfaces.matlab.MatlabCommand` for your main class, and :class:`nipype.interfaces.matlab.MatlabInputSpec` for your input spec, you gain access to some useful MATLAB hooks -.. testcode:: +.. literalinclude:: matlab_example2.py - from nipype.interfaces.base import traits - from nipype.interfaces.matlab import MatlabCommand, MatlabInputSpec - - - class HelloWorldInputSpec(MatlabInputSpec): - name = traits.Str(mandatory=True, - desc='Name of person to say hello to') - - - class HelloWorldOutputSpec(MatlabInputSpec): - matlab_output = traits.Str() - - - class HelloWorld(MatlabCommand): - """Basic Hello World that displays Hello in MATLAB - - Returns - ------- - - matlab_output : capture of matlab output which may be - parsed by user to get computation results - - Examples - -------- - - >>> hello = HelloWorld() - >>> hello.inputs.name = 'hello_world' - >>> out = hello.run() - >>> print out.outputs.matlab_output - """ - input_spec = HelloWorldInputSpec - output_spec = HelloWorldOutputSpec - - def _my_script(self): - """This is where you implement your script""" - script = """ - disp('Hello %s Python') - two = 1 + 1 - """ % (self.inputs.name) - return script - - def run(self, **inputs): - # Inject your script - self.inputs.script = self._my_script() - results = super(MatlabCommand, self).run(**inputs) - stdout = results.runtime.stdout - # Attach stdout to outputs to access matlab results - results.outputs.matlab_output = stdout - return results - - def _list_outputs(self): - outputs = self._outputs().get() - return outputs +:download:`Download the source code of this example `. +.. include:: ../links_names.txt From 20a742cfcbfb0627a8ee3adc9850b16f5b3d2672 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 2 Feb 2015 16:31:56 +0100 Subject: [PATCH 05/40] DOC add blank line in matlab examples --- doc/devel/matlab_example1.py | 2 +- doc/devel/matlab_example2.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/devel/matlab_example1.py b/doc/devel/matlab_example1.py index 5fef8a9b18..aaf6c4cb3a 100644 --- a/doc/devel/matlab_example1.py +++ b/doc/devel/matlab_example1.py @@ -44,4 +44,4 @@ def _run_interface(self, runtime): def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = os.path.abspath(self.inputs.out_file) - return outputs \ No newline at end of file + return outputs diff --git a/doc/devel/matlab_example2.py b/doc/devel/matlab_example2.py index 836f407c26..8d683ea45f 100644 --- a/doc/devel/matlab_example2.py +++ b/doc/devel/matlab_example2.py @@ -51,4 +51,4 @@ def run(self, **inputs): def _list_outputs(self): outputs = self._outputs().get() - return outputs \ No newline at end of file + return outputs From cb62ced37880353ee260c6b664c7464755540063 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Tue, 3 Feb 2015 12:21:07 +0100 Subject: [PATCH 06/40] DOC fix literal block issues in nipype/interfaces/fsl/preprocess.py --- nipype/interfaces/fsl/preprocess.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/fsl/preprocess.py b/nipype/interfaces/fsl/preprocess.py index c69a2caad6..3e13f987f1 100644 --- a/nipype/interfaces/fsl/preprocess.py +++ b/nipype/interfaces/fsl/preprocess.py @@ -1255,7 +1255,7 @@ class FUGUE(FSLCommand): -------- - Unwarping an input image (shift map is known) :: + Unwarping an input image (shift map is known): >>> from nipype.interfaces.fsl.preprocess import FUGUE >>> fugue = FUGUE() @@ -1269,7 +1269,7 @@ class FUGUE(FSLCommand): >>> fugue.run() #doctest: +SKIP - Warping an input image (shift map is known) :: + Warping an input image (shift map is known): >>> from nipype.interfaces.fsl.preprocess import FUGUE >>> fugue = FUGUE() @@ -1284,7 +1284,7 @@ class FUGUE(FSLCommand): >>> fugue.run() #doctest: +SKIP - Computing the vsm (unwrapped phase map is known) :: + Computing the vsm (unwrapped phase map is known): >>> from nipype.interfaces.fsl.preprocess import FUGUE >>> fugue = FUGUE() From dbf58c2e7b284dfebffd002c53329f2ed8fe98bd Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 6 Feb 2015 10:22:20 +0100 Subject: [PATCH 07/40] DOC updates in users/tutorial_101: move code in external file (and update it), mention that nodes need absolut file path correct typos and add download section. --- doc/users/tutorial_101.py | 59 +++++++++++++++++++++++++++++ doc/users/tutorial_101.rst | 77 ++++++++++++++++---------------------- 2 files changed, 91 insertions(+), 45 deletions(-) create mode 100644 doc/users/tutorial_101.py diff --git a/doc/users/tutorial_101.py b/doc/users/tutorial_101.py new file mode 100644 index 0000000000..4ed0142282 --- /dev/null +++ b/doc/users/tutorial_101.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +import os +import nipype.interfaces.spm as spm # the spm interfaces +import nipype.pipeline.engine as pe # the workflow and node wrappers + +import nipype.interfaces.matlab as mlab # how to run matlab +# Path to matlab +mlab.MatlabCommand.set_default_matlab_cmd("/full/path/to/matlab_exe") +# Add SPM to MATLAB path if not present +mlab.MatlabCommand.set_default_paths("/full/path/to/spm") + +# +# Define nodes +# + +realigner = pe.Node(interface=spm.Realign(), name='realign') +realigner.inputs.in_files = os.abspath('somefuncrun.nii') +realigner.inputs.register_to_mean = True + +smoother = pe.Node(interface=spm.Smooth(fwhm=6), name='smooth') + +# +# Creating and configuring a workflow +# +workflow = pe.Workflow(name='preproc') +workflow.base_dir = '.' + +# +# Connecting nodes to each other +# +workflow.connect(realigner, 'realigned_files', smoother, 'in_files') + + +# +# Visualizing the workflow +# +workflow.write_graph() + +# +# Extend it +# +import nipype.algorithms.rapidart as ra +artdetect = pe.Node(interface=ra.ArtifactDetect(), name='artdetect') +artdetect.inputs.use_differences = [True, False] +artdetect.inputs.use_norm = True +artdetect.inputs.norm_threshold = 0.5 +artdetect.inputs.zintensity_threshold = 3 +artdetect.inputs.parameter_source = 'SPM' +artdetect.inputs.mask_type = 'spm_global' +workflow.connect([(realigner, artdetect, + [('realigned_files', 'realigned_files'), + ('realignment_parameters', 'realignment_parameters')] + )]) +workflow.write_graph() + +# +# Execute the workflow +# +workflow.run() diff --git a/doc/users/tutorial_101.rst b/doc/users/tutorial_101.rst index f74e36ac0a..19ace96cae 100644 --- a/doc/users/tutorial_101.rst +++ b/doc/users/tutorial_101.rst @@ -25,30 +25,24 @@ setting up a workflow is separate from executing it. **1. Import appropriate modules** -.. testcode:: - - import nipype.interfaces.spm as spm # the spm interfaces - import nipype.pipeline.engine as pe # the workflow and node wrappers +.. literalinclude:: tutorial_101.py + :lines: 2-4 **2. Define nodes** Here we take instances of interfaces and make them pipeline compatible by wrapping them with pipeline specific elements. To determine the inputs and outputs of a given interface, please see :ref:`interface_tutorial`. Let's -start with defining a realign node using the interface -:class:`nipype.interfaces.spm.Realign` +start with defining a realign node using the :ref:`Realign ` interface: -.. testcode:: - - realigner = pe.Node(interface=spm.Realign(), name='realign') - realigner.inputs.in_files = 'somefuncrun.nii' - realigner.inputs.register_to_mean = True +.. literalinclude:: tutorial_101.py + :lines: 16-18 This would be equivalent to: .. testcode:: - realigner = pe.Node(interface=spm.Realign(infile='somefuncrun.nii', + realigner = pe.Node(interface=spm.Realign(infile=os.abspath('somefuncrun.nii'), register_to_mean = True), name='realign') @@ -58,15 +52,17 @@ later or while initializing the interface. .. note:: - In the above example, 'somefuncrun.nii' has to exist, otherwise the - commands won't work. A node will check if appropriate inputs are - being supplied. + a) In the above example, 'somefuncrun.nii' has to exist in the current directory, + otherwise the commands won't work. A node will check if appropriate + inputs are being supplied. -Similar to the realigner node, we now set up a smoothing node. + b) As noted above, you have to use the absolute path + of the file otherwise the workflow will fail to run. -.. testcode:: +Similar to the realigner node, we now set up a smoothing node. - smoother = pe.Node(interface=spm.Smooth(fwhm=6), name='smooth') +.. literalinclude:: tutorial_101.py + :lines: 20 Now we have two nodes with their inputs defined. Note that we have not defined an input file for the smoothing node. This will be done by connecting the @@ -77,17 +73,15 @@ realigner to the smoother in step 5. Here we create an instance of a workflow and indicate that it should operate in the current directory. -.. testcode:: - - workflow = pe.Workflow(name='preproc') - workflow.base_dir = '.' +.. literalinclude:: tutorial_101.py + :lines: 25-26 **4. Adding nodes to workflows (optional)** If nodes are going to be connected (see step 5), this step is not necessary. However, if you would like to run a node by itself without connecting it to any other node, then you need to add it to the -workflow. For adding nodes, order of nodes is not important. +workflow. When adding nodes, the order is not important. .. testcode:: @@ -100,15 +94,14 @@ This results in a workflow containing two isolated nodes: **5. Connecting nodes to each other** We want to connect the output produced by realignment to the input of -smoothing. This is done as follows. +smoothing. This is done as follows: -.. testcode:: - - workflow.connect(realigner, 'realigned_files', smoother, 'in_files') +.. literalinclude:: tutorial_101.py + :lines: 31 or alternatively, a more flexible notation can be used. Although not shown here, the following notation can be used to connect multiple outputs from one node to -multiple inputs (see step 7 below). +multiple inputs (see step 7 below): .. testcode:: @@ -121,8 +114,8 @@ This results in a workflow containing two connected nodes: **6. Visualizing the workflow** The workflow is represented as a directed acyclic graph (DAG) and one -can visualize this using the following command. In fact, the pictures -above were generated using this. +can visualize this using the following command (in fact, the pictures +above were generated using this): .. testcode:: @@ -147,18 +140,9 @@ options: Now that you have seen a basic pipeline let's add another node to the above pipeline. -.. testcode:: - - import nipype.algorithms.rapidart as ra - artdetect = pe.Node(interface=ra.ArtifactDetect(), name='artdetect') - artdetect.inputs.use_differences = [True, False] - art.inputs.use_norm = True - art.inputs.norm_threshold = 0.5 - art.inputs.zintensity_threshold = 3 - workflow.connect([(realigner, artdetect, - [('realigned_files', 'realigned_files'), - ('realignment_parameters','realignment_parameters')] - )]) + +.. literalinclude:: tutorial_101.py + :lines: 42-53 .. note:: @@ -180,12 +164,15 @@ This results in Assuming that **somefuncrun.nii** is actually a file or you've replaced it with an appropriate one, you can run the pipeline with: -.. testcode:: - - workflow.run() +.. literalinclude:: tutorial_101.py + :lines: 59 This should create a folder called preproc in your current directory, inside which are three folders: realign, smooth and artdetect (the names of the nodes). The outputs of these routines are in these folders. +.. admonition:: Example source code + + You can download :download:`the source code of this example `. + .. include:: ../links_names.txt From 343389c406c26c3bab7ac35183ac91bf77793af0 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 6 Feb 2015 10:32:25 +0100 Subject: [PATCH 08/40] DOC correct download sections in devel/matlab_interface_devel.rst --- doc/devel/matlab_interface_devel.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/devel/matlab_interface_devel.rst b/doc/devel/matlab_interface_devel.rst index 61ef8a08b6..2c8c2a4359 100644 --- a/doc/devel/matlab_interface_devel.rst +++ b/doc/devel/matlab_interface_devel.rst @@ -13,7 +13,9 @@ code template, and define approriate inputs and outputs. .. literalinclude:: matlab_example1.py -:download:`Download the source code of this example `. +.. admonition:: Example source code + + You can download :download:`the source code of this example `. Example 2 +++++++++ @@ -22,6 +24,8 @@ By subclassing :class:`nipype.interfaces.matlab.MatlabCommand` for your main cla .. literalinclude:: matlab_example2.py -:download:`Download the source code of this example `. +.. admonition:: Example source code + + You can download :download:`the source code of this example `. .. include:: ../links_names.txt From 4af477364f09dc02088883d0465382c000a24d45 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 6 Feb 2015 10:33:25 +0100 Subject: [PATCH 09/40] WIP minimal modifications in users/interface_tutorial.rst --- doc/users/interface_tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/users/interface_tutorial.rst b/doc/users/interface_tutorial.rst index de9c1e2cb6..f5d9dd5645 100644 --- a/doc/users/interface_tutorial.rst +++ b/doc/users/interface_tutorial.rst @@ -10,7 +10,7 @@ Specifying options The nipype interface modules provide a Python interface to external packages like FSL_ and SPM_. Within the module are a series of Python classes which wrap specific package functionality. For example, in -the fsl module, the class :class:`nipype.interfaces.fsl.Bet` wraps the +the :ref:`fsl ` module, the class :ref:`BET ` wraps the ``bet`` command-line tool. Using the command-line tool, one would specify options using flags like ``-o``, ``-m``, ``-f ``, etc... However, in nipype, options are assigned to Python attributes and can From 7639c66f693a2b62db89b5ccd8d93dd6bdcc41ff Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 6 Feb 2015 13:19:20 +0100 Subject: [PATCH 10/40] DOC correct indentation error in doc/index.rst --- doc/index.rst | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/doc/index.rst b/doc/index.rst index 76524e968f..d600dd504f 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -2,33 +2,34 @@ * - .. image:: images/nipype_architecture_overview2.png :width: 100 % + - .. container:: - Current neuroimaging software offer users an incredible opportunity to - analyze data using a variety of different algorithms. However, this has - resulted in a heterogeneous collection of specialized applications - without transparent interoperability or a uniform operating interface. - - *Nipype*, an open-source, community-developed initiative under the - umbrella of NiPy_, is a Python project that provides a uniform interface - to existing neuroimaging software and facilitates interaction between - these packages within a single workflow. Nipype provides an environment - that encourages interactive exploration of algorithms from different - packages (e.g., ANTS_, SPM_, FSL_, FreeSurfer_, Camino_, MRtrix_, MNE_, AFNI_, - Slicer_), eases the design of workflows within and between packages, and - reduces the learning curve necessary to use different packages. Nipype is - creating a collaborative platform for neuroimaging software development - in a high-level language and addressing limitations of existing pipeline - systems. - - *Nipype* allows you to: - - * easily interact with tools from different software packages - * combine processing steps from different software packages - * develop new workflows faster by reusing common steps from old ones - * process data faster by running it in parallel on many cores/machines - * make your research easily reproducible - * share your processing workflows with the community + Current neuroimaging software offer users an incredible opportunity to + analyze data using a variety of different algorithms. However, this has + resulted in a heterogeneous collection of specialized applications + without transparent interoperability or a uniform operating interface. + + *Nipype*, an open-source, community-developed initiative under the + umbrella of NiPy_, is a Python project that provides a uniform interface + to existing neuroimaging software and facilitates interaction between + these packages within a single workflow. Nipype provides an environment + that encourages interactive exploration of algorithms from different + packages (e.g., ANTS_, SPM_, FSL_, FreeSurfer_, Camino_, MRtrix_, MNE_, AFNI_, + Slicer_), eases the design of workflows within and between packages, and + reduces the learning curve necessary to use different packages. Nipype is + creating a collaborative platform for neuroimaging software development + in a high-level language and addressing limitations of existing pipeline + systems. + + *Nipype* allows you to: + + * easily interact with tools from different software packages + * combine processing steps from different software packages + * develop new workflows faster by reusing common steps from old ones + * process data faster by running it in parallel on many cores/machines + * make your research easily reproducible + * share your processing workflows with the community .. admonition:: Reference From d5d344b14dee2881c44b5be13ef9a406de1a6b3e Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 6 Feb 2015 13:20:14 +0100 Subject: [PATCH 11/40] DOC correct indentation error in doc/users/config.rst --- doc/users/config_file.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/users/config_file.rst b/doc/users/config_file.rst index e6ca4f66c6..6ef2e35c41 100644 --- a/doc/users/config_file.rst +++ b/doc/users/config_file.rst @@ -104,10 +104,10 @@ Execution done after a job finish is detected. (float in seconds; default value: 5) *remove_node_directories (EXPERIMENTAL)* - Removes directories whose outputs have already been used - up. Doesn't work with IdentiInterface or any node that patches - data through (without copying) (possible values: ``true`` and - ``false``; default value: ``false``) + Removes directories whose outputs have already been used + up. Doesn't work with IdentiInterface or any node that patches + data through (without copying) (possible values: ``true`` and + ``false``; default value: ``false``) *stop_on_unknown_version* If this is set to True, an underlying interface will raise an error, when no @@ -118,7 +118,7 @@ Execution If this is set to True, the node's output directory will contain full parameterization of any iterable, otherwise parameterizations over 32 characters will be replaced by their hash. (possible values: ``true`` and - ``false``; default value: ``true``) + ``false``; default value: ``true``) *poll_sleep_duration* This controls how long the job submission loop will sleep between submitting From 54fefedf2610b3d16efe45b5c049958377ed6353 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 6 Feb 2015 13:21:40 +0100 Subject: [PATCH 12/40] DOC correct references in doc/devel/devel/cmd_interface_devel.rst --- doc/devel/cmd_interface_devel.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/devel/cmd_interface_devel.rst b/doc/devel/cmd_interface_devel.rst index 1bbc7cd1f9..6107a2b75f 100644 --- a/doc/devel/cmd_interface_devel.rst +++ b/doc/devel/cmd_interface_devel.rst @@ -39,7 +39,7 @@ above example we have used the ``desc`` metadata which holds human readable description of the input. The ``mandatory`` flag forces Nipype to throw an exception if the input was not set. ``exists`` is a special flag that works only for ``File traits`` and checks if the provided file exists. More details can be -found at `interface_specs`_. +found at :ref:`interface_specs`. The input and output specifications have to be connected to the our example interface class: @@ -80,7 +80,7 @@ symbols. For an input defined in InputSpec to be included into the executed commandline ``argstr`` has to be included. Additionally inside the main interface class you need to specify the name of the executable by assigning it to the ``_cmd`` field. Also the main interface class needs to inherit from -`CommandLine`_: +:class:`CommandLine `: .. testcode:: @@ -92,7 +92,7 @@ to the ``_cmd`` field. Also the main interface class needs to inherit from There is one more thing we need to take care of. When the executable finishes processing it will presumably create some output files. We need to know which files to look for, check if they exist and expose them to whatever node would -like to use them. This is done by implementing `_list_outputs`_ method in the +like to use them. This is done by implementing :func:`_list_outputs ` method in the main interface class. Basically what it does is assigning the expected output files to the fields of our output spec: From 8b89b73dcd9bd1e3a7dfac1b6f0e7673e1973a93 Mon Sep 17 00:00:00 2001 From: Nolan Nichols Date: Sun, 8 Feb 2015 11:36:25 -0800 Subject: [PATCH 13/40] fix: documentation indentation and highlighting --- .../rsfmri_vol_surface_preprocessing_nipy.py | 52 +++++++++++-------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/examples/rsfmri_vol_surface_preprocessing_nipy.py b/examples/rsfmri_vol_surface_preprocessing_nipy.py index aaf535bd56..4d34195d35 100644 --- a/examples/rsfmri_vol_surface_preprocessing_nipy.py +++ b/examples/rsfmri_vol_surface_preprocessing_nipy.py @@ -40,9 +40,10 @@ specifically the 2mm versions of: -- `Joint Fusion Atlas `_ -- `MNI template `_ + * `Joint Fusion Atlas `_ + * `MNI template `_ +Import necessary modules from nipype. """ import os @@ -71,6 +72,10 @@ import scipy as sp import nibabel as nb +""" +A list of modules and functions to import inside of nodes +""" + imports = ['import os', 'import nibabel as nb', 'import numpy as np', @@ -79,6 +84,10 @@ 'from scipy.special import legendre' ] +""" +Define utility functions for use in workflow nodes +""" + def get_info(dicom_files): """Given a Siemens dicom file return metadata @@ -341,25 +350,26 @@ def combine_hemi(left, right): fmt=','.join(['%d'] + ['%.10f'] * (all_data.shape[1] - 1))) return os.path.abspath(filename) +""" +Create a Registration Workflow +""" + def create_reg_workflow(name='registration'): """Create a FEAT preprocessing workflow together with freesurfer Parameters ---------- - - :: - name : name of workflow (default: 'registration') - Inputs:: + Inputs: inputspec.source_files : files (filename or list of filenames to register) inputspec.mean_image : reference image to use inputspec.anatomical_image : anatomical image to coregister to inputspec.target_image : registration target - Outputs:: + Outputs: outputspec.func2anat_transform : FLIRT transform outputspec.anat2target_transform : FLIRT+FNIRT transform @@ -368,7 +378,7 @@ def create_reg_workflow(name='registration'): Example ------- - + See code below """ register = Workflow(name=name) @@ -438,6 +448,7 @@ def create_reg_workflow(name='registration'): """ Apply inverse transform to take segmentations to functional space """ + applyxfm = MapNode(freesurfer.ApplyVolTransform(inverse=True, interp='nearest'), iterfield=['target_file'], @@ -450,6 +461,7 @@ def create_reg_workflow(name='registration'): """ Apply inverse transform to aparc file """ + aparcxfm = Node(freesurfer.ApplyVolTransform(inverse=True, interp='nearest'), name='aparc_inverse_transform') @@ -467,16 +479,17 @@ def create_reg_workflow(name='registration'): convert2itk.inputs.fsl2ras = True convert2itk.inputs.itk_transform = True register.connect(bbregister, 'out_fsl_file', convert2itk, 'transform_file') - register.connect(inputnode, 'mean_image',convert2itk, 'source_file') + register.connect(inputnode, 'mean_image', convert2itk, 'source_file') register.connect(stripper, 'out_file', convert2itk, 'reference_file') """ Compute registration between the subject's structural and MNI template - This is currently set to perform a very quick registration. However, the - registration can be made significantly more accurate for cortical - structures by increasing the number of iterations - All parameters are set using the example from: - #https://github.com/stnava/ANTs/blob/master/Scripts/newAntsExample.sh + + * All parameters are set using the example from: \ + `newAntsExample.sh `_ + * This is currently set to perform a very quick registration. However,\ + the registration can be made significantly more accurate for cortical\ + structures by increasing the number of iterations. """ reg = Node(ants.Registration(), name='antsRegister') @@ -509,7 +522,6 @@ def create_reg_workflow(name='registration'): register.connect(stripper, 'out_file', reg, 'moving_image') register.connect(inputnode,'target_image', reg,'fixed_image') - """ Concatenate the affine and ants transforms into a list """ @@ -520,10 +532,10 @@ def create_reg_workflow(name='registration'): register.connect(convert2itk, 'itk_transform', merge, 'in2') register.connect(reg, ('composite_transform', pickfirst), merge, 'in1') - """ Transform the mean image. First to anatomical and then to target """ + warpmean = Node(ants.ApplyTransforms(), name='warpmean') warpmean.inputs.input_image_type = 3 warpmean.inputs.interpolation = 'BSpline' @@ -536,7 +548,6 @@ def create_reg_workflow(name='registration'): register.connect(inputnode, 'mean_image', warpmean, 'input_image') register.connect(merge, 'out', warpmean, 'transforms') - """ Assign all the output files """ @@ -557,7 +568,6 @@ def create_reg_workflow(name='registration'): return register - """ Creates the main preprocessing workflow """ @@ -607,15 +617,16 @@ def create_workflow(files, name='median') wf.connect(tsnr, 'detrended_file', calc_median, 'in_files') - """Segment and Register """ + Segment and Register + """ + registration = create_reg_workflow(name='registration') wf.connect(calc_median, 'median_file', registration, 'inputspec.mean_image') registration.inputs.inputspec.subject_id = subject_id registration.inputs.inputspec.subjects_dir = subjects_dir registration.inputs.inputspec.target_image = target_file - """Use :class:`nipype.algorithms.rapidart` to determine which of the images in the functional series are outliers based on deviations in intensity or movement. @@ -629,7 +640,6 @@ def create_workflow(files, art.inputs.mask_type = 'spm_global' art.inputs.parameter_source = 'NiPy' - """Here we are connecting all the nodes together. Notice that we add the merge node only if you choose to use 4D. Also `get_vox_dims` function is passed along the input volume of normalise to set the optimal voxel sizes. From 868b24865ff3bb1acde6dccab68d873fe6cf1c76 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 9 Feb 2015 12:10:33 +0100 Subject: [PATCH 14/40] DOC minor fix in examples/rsfmri_vol_surface_preprocessing_nipy.py --- examples/rsfmri_vol_surface_preprocessing_nipy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rsfmri_vol_surface_preprocessing_nipy.py b/examples/rsfmri_vol_surface_preprocessing_nipy.py index 4d34195d35..87d88a2ac4 100644 --- a/examples/rsfmri_vol_surface_preprocessing_nipy.py +++ b/examples/rsfmri_vol_surface_preprocessing_nipy.py @@ -21,7 +21,7 @@ python rsfmri_preprocessing.py -d /data/12345-34-1.dcm -f /data/Resting.nii -s subj001 -o output -p PBS --plugin_args "dict(qsub_args='-q many')" - or +or:: python rsfmri_vol_surface_preprocessing.py -f SUB_1024011/E?/func/rest.nii -t OASIS-30_Atropos_template_in_MNI152_2mm.nii.gz --TR 2 -s SUB_1024011 From 6d818230dd77bf7769079f454cca74fa1a2d1706 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 9 Feb 2015 12:37:56 +0100 Subject: [PATCH 15/40] DOC fix formatting in examples/fmri_ants_openfmri.py --- examples/fmri_ants_openfmri.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/fmri_ants_openfmri.py b/examples/fmri_ants_openfmri.py index 2e140f4cee..bcbd3534ac 100755 --- a/examples/fmri_ants_openfmri.py +++ b/examples/fmri_ants_openfmri.py @@ -362,6 +362,7 @@ def analyze_openfmri_dataset(data_dir, subject=None, model_id=None, """ Return data components as anat, bold and behav """ + contrast_file = os.path.join(data_dir, 'models', 'model%03d' % model_id, 'task_contrasts.txt') has_contrast = os.path.exists(contrast_file) From d67d503ee9a71c61c563ec650baed97dd3e14d67 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 9 Feb 2015 12:39:35 +0100 Subject: [PATCH 16/40] DOC PEP8 edits in examples/fmri_ants_openfmri.py --- examples/fmri_ants_openfmri.py | 102 ++++++++++++++++----------------- 1 file changed, 50 insertions(+), 52 deletions(-) diff --git a/examples/fmri_ants_openfmri.py b/examples/fmri_ants_openfmri.py index bcbd3534ac..5e21f984b9 100755 --- a/examples/fmri_ants_openfmri.py +++ b/examples/fmri_ants_openfmri.py @@ -70,11 +70,11 @@ def create_reg_workflow(name='registration'): register = pe.Workflow(name=name) inputnode = pe.Node(interface=niu.IdentityInterface(fields=['source_files', - 'mean_image', - 'anatomical_image', - 'target_image', - 'target_image_brain', - 'config_file']), + 'mean_image', + 'anatomical_image', + 'target_image', + 'target_image_brain', + 'config_file']), name='inputspec') outputnode = pe.Node(interface=niu.IdentityInterface(fields=['func2anat_transform', 'anat2target_transform', @@ -136,7 +136,7 @@ def create_reg_workflow(name='registration'): convert2itk.inputs.fsl2ras = True convert2itk.inputs.itk_transform = True register.connect(mean2anatbbr, 'out_matrix_file', convert2itk, 'transform_file') - register.connect(inputnode, 'mean_image',convert2itk, 'source_file') + register.connect(inputnode, 'mean_image', convert2itk, 'source_file') register.connect(stripper, 'out_file', convert2itk, 'reference_file') """ @@ -177,8 +177,7 @@ def create_reg_workflow(name='registration'): reg.inputs.num_threads = 2 reg.plugin_args = {'qsub_args': '-pe orte 2'} register.connect(stripper, 'out_file', reg, 'moving_image') - register.connect(inputnode,'target_image_brain', reg,'fixed_image') - + register.connect(inputnode, 'target_image_brain', reg, 'fixed_image') """ Concatenate the affine and ants transforms into a list @@ -190,7 +189,6 @@ def create_reg_workflow(name='registration'): register.connect(convert2itk, 'itk_transform', merge, 'in2') register.connect(reg, ('composite_transform', pickfirst), merge, 'in1') - """ Transform the mean image. First to anatomical and then to target """ @@ -202,7 +200,7 @@ def create_reg_workflow(name='registration'): warpmean.inputs.invert_transform_flags = [False, False] warpmean.inputs.terminal_output = 'file' - register.connect(inputnode,'target_image_brain', warpmean,'reference_image') + register.connect(inputnode, 'target_image_brain', warpmean, 'reference_image') register.connect(inputnode, 'mean_image', warpmean, 'input_image') register.connect(merge, 'out', warpmean, 'transforms') @@ -218,11 +216,10 @@ def create_reg_workflow(name='registration'): warpall.inputs.invert_transform_flags = [False, False] warpall.inputs.terminal_output = 'file' - register.connect(inputnode,'target_image_brain',warpall,'reference_image') - register.connect(inputnode,'source_files', warpall, 'input_image') + register.connect(inputnode, 'target_image_brain', warpall, 'reference_image') + register.connect(inputnode, 'source_files', warpall, 'input_image') register.connect(merge, 'out', warpall, 'transforms') - """ Assign all the output files """ @@ -240,6 +237,7 @@ def create_reg_workflow(name='registration'): Get info for a given subject """ + def get_subjectinfo(subject_id, base_dir, task_id, model_id): """Get info for a given subject @@ -284,7 +282,7 @@ def get_subjectinfo(subject_id, base_dir, task_id, model_id): for idx in range(n_tasks): taskidx = np.where(taskinfo[:, 0] == 'task%03d' % (idx + 1)) conds.append([condition.replace(' ', '_') for condition - in taskinfo[taskidx[0], 2]]) # if 'junk' not in condition]) + in taskinfo[taskidx[0], 2]]) # if 'junk' not in condition]) files = sorted(glob(os.path.join(base_dir, subject_id, 'BOLD', @@ -298,6 +296,7 @@ def get_subjectinfo(subject_id, base_dir, task_id, model_id): Analyzes an open fmri dataset """ + def analyze_openfmri_dataset(data_dir, subject=None, model_id=None, task_id=None, output_dir=None, subj_prefix='*', hpcutoff=120., use_derivatives=True, @@ -368,15 +367,15 @@ def analyze_openfmri_dataset(data_dir, subject=None, model_id=None, has_contrast = os.path.exists(contrast_file) if has_contrast: datasource = pe.Node(nio.DataGrabber(infields=['subject_id', 'run_id', - 'task_id', 'model_id'], - outfields=['anat', 'bold', 'behav', - 'contrasts']), - name='datasource') + 'task_id', 'model_id'], + outfields=['anat', 'bold', 'behav', + 'contrasts']), + name='datasource') else: datasource = pe.Node(nio.DataGrabber(infields=['subject_id', 'run_id', - 'task_id', 'model_id'], - outfields=['anat', 'bold', 'behav']), - name='datasource') + 'task_id', 'model_id'], + outfields=['anat', 'bold', 'behav']), + name='datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '*' @@ -388,19 +387,19 @@ def analyze_openfmri_dataset(data_dir, subject=None, model_id=None, 'contrasts': ('models/model%03d/' 'task_contrasts.txt')} datasource.inputs.template_args = {'anat': [['subject_id']], - 'bold': [['subject_id', 'task_id']], - 'behav': [['subject_id', 'model_id', - 'task_id', 'run_id']], - 'contrasts': [['model_id']]} + 'bold': [['subject_id', 'task_id']], + 'behav': [['subject_id', 'model_id', + 'task_id', 'run_id']], + 'contrasts': [['model_id']]} else: datasource.inputs.field_template = {'anat': '%s/anatomy/highres001.nii.gz', 'bold': '%s/BOLD/task%03d_r*/bold.nii.gz', 'behav': ('%s/model/model%03d/onsets/task%03d_' 'run%03d/cond*.txt')} datasource.inputs.template_args = {'anat': [['subject_id']], - 'bold': [['subject_id', 'task_id']], - 'behav': [['subject_id', 'model_id', - 'task_id', 'run_id']]} + 'bold': [['subject_id', 'task_id']], + 'behav': [['subject_id', 'model_id', + 'task_id', 'run_id']]} datasource.inputs.sort_filelist = True @@ -443,7 +442,7 @@ def get_contrasts(contrast_file, task_id, conds): for row in contrast_def: if row[0] != 'task%03d' % task_id: continue - con = [row[1], 'T', ['cond%03d' % (i + 1) for i in range(len(conds))], + con = [row[1], 'T', ['cond%03d' % (i + 1) for i in range(len(conds))], row[2:].astype(float).tolist()] contrasts.append(con) # add auto contrasts for each column @@ -469,7 +468,7 @@ def get_contrasts(contrast_file, task_id, conds): name="art") modelspec = pe.Node(interface=model.SpecifyModel(), - name="modelspec") + name="modelspec") modelspec.inputs.input_units = 'secs' def check_behav_list(behav, run_id, conds): @@ -483,9 +482,9 @@ def check_behav_list(behav, run_id, conds): return behav_array.reshape(num_elements/num_conds, num_conds).tolist() reshape_behav = pe.Node(niu.Function(input_names=['behav', 'run_id', 'conds'], - output_names=['behav'], - function=check_behav_list), - name='reshape_behav') + output_names=['behav'], + function=check_behav_list), + name='reshape_behav') wf.connect(subjinfo, 'TR', modelspec, 'time_repetition') wf.connect(datasource, 'behav', reshape_behav, 'behav') @@ -553,7 +552,7 @@ def sort_copes(copes, varcopes, contrasts): ('varcopes', 'inputspec.varcopes'), ('n_runs', 'l2model.num_copes')]), (modelfit, fixed_fx, [('outputspec.dof_file', - 'inputspec.dof_files'), + 'inputspec.dof_files'), ]) ]) @@ -576,9 +575,9 @@ def merge_files(copes, varcopes, zstats): mergefunc = pe.Node(niu.Function(input_names=['copes', 'varcopes', 'zstats'], - output_names=['out_files', 'splits'], - function=merge_files), - name='merge_files') + output_names=['out_files', 'splits'], + function=merge_files), + name='merge_files') wf.connect([(fixed_fx.get_node('outputspec'), mergefunc, [('copes', 'copes'), ('varcopes', 'varcopes'), @@ -596,24 +595,23 @@ def split_files(in_files, splits): output_names=['copes', 'varcopes', 'zstats'], function=split_files), - name='split_files') + name='split_files') wf.connect(mergefunc, 'splits', splitfunc, 'splits') wf.connect(registration, 'outputspec.transformed_files', splitfunc, 'in_files') - """ Connect to a datasink """ def get_subs(subject_id, conds, model_id, task_id): subs = [('_subject_id_%s_' % subject_id, '')] - subs.append(('_model_id_%d' % model_id, 'model%03d' %model_id)) + subs.append(('_model_id_%d' % model_id, 'model%03d' % model_id)) subs.append(('task_id_%d/' % task_id, '/task%03d_' % task_id)) subs.append(('bold_dtype_mcf_mask_smooth_mask_gms_tempfilt_mean_warp', - 'mean')) + 'mean')) subs.append(('bold_dtype_mcf_mask_smooth_mask_gms_tempfilt_mean_flirt', - 'affine')) + 'affine')) for i in range(len(conds)): subs.append(('_flameo%d/cope1.' % i, 'cope%02d.' % (i + 1))) @@ -699,7 +697,7 @@ def get_subs(subject_id, conds, model_id, task_id): help="Model index" + defstr) parser.add_argument('-x', '--subjectprefix', default='sub*', help="Subject prefix" + defstr) - parser.add_argument('-t', '--task', default=1, #nargs='+', + parser.add_argument('-t', '--task', default=1, type=int, help="Task index" + defstr) parser.add_argument('--hpfilter', default=120., type=float, help="High pass filter cutoff (in secs)" + defstr) @@ -729,16 +727,16 @@ def get_subs(subject_id, conds, model_id, task_id): 'task%03d' % int(args.task)) derivatives = args.derivatives if derivatives is None: - derivatives = False + derivatives = False wf = analyze_openfmri_dataset(data_dir=os.path.abspath(args.datasetdir), - subject=args.subject, - model_id=int(args.model), - task_id=[int(args.task)], - subj_prefix=args.subjectprefix, - output_dir=outdir, - hpcutoff=args.hpfilter, - use_derivatives=derivatives, - fwhm=args.fwhm) + subject=args.subject, + model_id=int(args.model), + task_id=[int(args.task)], + subj_prefix=args.subjectprefix, + output_dir=outdir, + hpcutoff=args.hpfilter, + use_derivatives=derivatives, + fwhm=args.fwhm) wf.base_dir = work_dir if args.plugin_args: wf.run(args.plugin, plugin_args=eval(args.plugin_args)) From 181255e9f070acf9142fe46692a37f427d24b1da Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Wed, 11 Feb 2015 21:51:28 +0100 Subject: [PATCH 17/40] DOC Added ANTS to the list of wrapped tools. --- doc/users/install.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/users/install.rst b/doc/users/install.rst index fadf4bdc16..8cfc11e321 100644 --- a/doc/users/install.rst +++ b/doc/users/install.rst @@ -174,6 +174,9 @@ Slicer_ Nipy_ 0.1.2+20110404 or later +ANTS_ + ANTS version 2.1 or later + Nitime_ (optional) From bfb88bad05d0aa5092b0b32f73cd1bee841656fa Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Wed, 11 Feb 2015 21:54:34 +0100 Subject: [PATCH 18/40] Revert "DOC Added ANTS to the list of wrapped tools." This reverts commit 181255e9f070acf9142fe46692a37f427d24b1da. --- doc/users/install.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/users/install.rst b/doc/users/install.rst index 8cfc11e321..fadf4bdc16 100644 --- a/doc/users/install.rst +++ b/doc/users/install.rst @@ -174,9 +174,6 @@ Slicer_ Nipy_ 0.1.2+20110404 or later -ANTS_ - ANTS version 2.1 or later - Nitime_ (optional) From 0eb52cf39051115895c796ed9cefcf747075d178 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 13 Feb 2015 13:26:16 +0100 Subject: [PATCH 19/40] WIP Updates in examples/fmri_ants_openfmri.py --- examples/fmri_ants_openfmri.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/fmri_ants_openfmri.py b/examples/fmri_ants_openfmri.py index ade364c453..721ce5d123 100755 --- a/examples/fmri_ants_openfmri.py +++ b/examples/fmri_ants_openfmri.py @@ -10,6 +10,12 @@ This script demonstrates how to use nipype to analyze a data set:: python fmri_ants_openfmri.py --datasetdir ds107 + +This workflow also requires 2mm subcortical templates that are available from +`MindBoggle `_. +Specifically the 2mm version of the `MNI template `_. + +Import necessary modules from nipype. """ from nipype import config @@ -672,7 +678,7 @@ def analyze_openfmri_dataset(data_dir, subject=None, model_id=None, datasource.inputs.template = '*' if has_contrast: - datasource.inputs.field_template = {'anat': '%s/anatomy/T1_001.nii.gz', + datasource.inputs.field_template = {'anat': '%s/anatomy/highres001.nii.gz', 'bold': '%s/BOLD/task%03d_r*/bold.nii.gz', 'behav': ('%s/model/model%03d/onsets/task%03d_' 'run%03d/cond*.txt'), From 346cdc843f0301f8d52c7c6ffa4005914538d535 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 30 Jan 2015 18:35:08 +0100 Subject: [PATCH 20/40] DOC Updated doc/devel/matlab_interface_devel.rst: remove invalid caracters in example, PEP8-ize examples, language. --- doc/devel/matlab_interface_devel.rst | 118 +++------------------------ 1 file changed, 10 insertions(+), 108 deletions(-) diff --git a/doc/devel/matlab_interface_devel.rst b/doc/devel/matlab_interface_devel.rst index c64622b390..8ccbb2f42a 100644 --- a/doc/devel/matlab_interface_devel.rst +++ b/doc/devel/matlab_interface_devel.rst @@ -4,127 +4,29 @@ How to wrap a MATLAB script =========================== -This is minimal script for wrapping MATLAB code. You should replace the MATLAB -code template, and define approriate inputs and outputs. - Example 1 +++++++++ -.. testcode:: - - from nipype.interfaces.matlab import MatlabCommand - from nipype.interfaces.base import TraitedSpec, BaseInterface, BaseInterfaceInputSpec, File - import os - from string import Template - - class ConmapTxt2MatInputSpec(BaseInterfaceInputSpec): - in_file = File(exists=True, mandatory=True) - out_file = File('cmatrix.mat', usedefault=True) - - class ConmapTxt2MatOutputSpec(TraitedSpec): - out_file = File(exists=True) - - class ConmapTxt2Mat(BaseInterface): - input_spec = ConmapTxt2MatInputSpec - output_spec = ConmapTxt2MatOutputSpec - - def _run_interface(self, runtime): - d = dict(in_file=self.inputs.in_file, - out_file=self.inputs.out_file) - #this is your MATLAB code template - script = Template("""in_file = ‘$in_file'; - out_file = ‘$out_file'; - ConmapTxt2Mat(in_file, out_file); - exit; - """).substitute(d) - - # mfile = True will create an .m file with your script and executed. - # Alternatively - # mfile can be set to False which will cause the matlab code to be - # passed - # as a commandline argument to the matlab executable - # (without creating any files). - # This, however, is less reliable and harder to debug - # (code will be reduced to - # a single line and stripped of any comments). +This is a minimal script for wrapping MATLAB code. You should replace the MATLAB +code template, and define approriate inputs and outputs. - mlab = MatlabCommand(script=script, mfile=True) - result = mlab.run() - return result.runtime +.. literalinclude:: matlab_example1.py - def _list_outputs(self): - outputs = self._outputs().get() - outputs['out_file'] = os.path.abspath(self.inputs.out_file) - return outputs +.. admonition:: Example source code + You can download :download:`the source code of this example `. Example 2 +++++++++ -By subclassing **MatlabCommand** for your main class, and **MatlabInputSpec** for your input and output spec, you gain access to some useful MATLAB hooks - -.. testcode:: - - import os - from nipype.interfaces.base import File, traits - from nipype.interfaces.matlab import MatlabCommand, MatlabInputSpec - - - class HelloWorldInputSpec( MatlabInputSpec): - name = traits.Str( mandatory = True, - desc = 'Name of person to say hello to') - - class HelloWorldOutputSpec( MatlabInputSpec): - matlab_output = traits.Str( ) - - class HelloWorld( MatlabCommand): - """ Basic Hello World that displays Hello in MATLAB - - Returns - ------- - - matlab_output : capture of matlab output which may be - parsed by user to get computation results - - Examples - -------- - - >>> hello = HelloWorld() - >>> hello.inputs.name = 'hello_world' - >>> out = hello.run() - >>> print out.outputs.matlab_output - """ - input_spec = HelloWorldInputSpec - output_spec = HelloWorldOutputSpec - - def _my_script(self): - """This is where you implement your script""" - script = """ - disp('Hello %s Python') - two = 1 + 1 - """%(self.inputs.name) - return script - - - def run(self, **inputs): - ## inject your script - self.inputs.script = self._my_script() - results = super(MatlabCommand, self).run( **inputs) - stdout = results.runtime.stdout - # attach stdout to outputs to access matlab results - results.outputs.matlab_output = stdout - return results - - - def _list_outputs(self): - outputs = self._outputs().get() - return outputs - - - +By subclassing :class:`nipype.interfaces.matlab.MatlabCommand` for your main class, and :class:`nipype.interfaces.matlab.MatlabInputSpec` for your input spec, you gain access to some useful MATLAB hooks +.. literalinclude:: matlab_example2.py +.. admonition:: Example source code + You can download :download:`the source code of this example `. +.. include:: ../links_names.txt From d2fca1cfc2c81a68111459e26ccecea4784edc37 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 2 Feb 2015 15:53:13 +0100 Subject: [PATCH 21/40] DOC Fix typo. --- doc/users/function_interface.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/users/function_interface.rst b/doc/users/function_interface.rst index 9b5697c6d2..7466469a42 100644 --- a/doc/users/function_interface.rst +++ b/doc/users/function_interface.rst @@ -146,6 +146,6 @@ the string would be Unlike when using a function object, this input can be set like any other, meaning that you could write a function that outputs different function strings depending on some run-time contingencies, and connect that output -the the ``function_str`` input of a downstream Function interface. +the ``function_str`` input of a downstream Function interface. .. include:: ../links_names.txt From ef6c57c28ba92feff8ad63f08c1280b91a91af59 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 2 Feb 2015 16:06:19 +0100 Subject: [PATCH 22/40] DOC reworked devel/matlab_interface_devel.rst: move code to external files and correct output specification in example 2. --- doc/devel/matlab_example1.py | 47 +++++++++++++++++++++++++++++++ doc/devel/matlab_example2.py | 54 ++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 doc/devel/matlab_example1.py create mode 100644 doc/devel/matlab_example2.py diff --git a/doc/devel/matlab_example1.py b/doc/devel/matlab_example1.py new file mode 100644 index 0000000000..5fef8a9b18 --- /dev/null +++ b/doc/devel/matlab_example1.py @@ -0,0 +1,47 @@ +from nipype.interfaces.matlab import MatlabCommand +from nipype.interfaces.base import TraitedSpec, \ + BaseInterface, BaseInterfaceInputSpec, File +import os +from string import Template + + +class ConmapTxt2MatInputSpec(BaseInterfaceInputSpec): + in_file = File(exists=True, mandatory=True) + out_file = File('cmatrix.mat', usedefault=True) + + +class ConmapTxt2MatOutputSpec(TraitedSpec): + out_file = File(exists=True) + + +class ConmapTxt2Mat(BaseInterface): + input_spec = ConmapTxt2MatInputSpec + output_spec = ConmapTxt2MatOutputSpec + + def _run_interface(self, runtime): + d = dict(in_file=self.inputs.in_file, + out_file=self.inputs.out_file) + # This is your MATLAB code template + script = Template("""in_file = '$in_file'; + out_file = '$out_file'; + ConmapTxt2Mat(in_file, out_file); + exit; + """).substitute(d) + + # mfile = True will create an .m file with your script and executed. + # Alternatively + # mfile can be set to False which will cause the matlab code to be + # passed + # as a commandline argument to the matlab executable + # (without creating any files). + # This, however, is less reliable and harder to debug + # (code will be reduced to + # a single line and stripped of any comments). + mlab = MatlabCommand(script=script, mfile=True) + result = mlab.run() + return result.runtime + + def _list_outputs(self): + outputs = self._outputs().get() + outputs['out_file'] = os.path.abspath(self.inputs.out_file) + return outputs \ No newline at end of file diff --git a/doc/devel/matlab_example2.py b/doc/devel/matlab_example2.py new file mode 100644 index 0000000000..836f407c26 --- /dev/null +++ b/doc/devel/matlab_example2.py @@ -0,0 +1,54 @@ +from nipype.interfaces.base import traits +from nipype.interfaces.base import TraitedSpec +from nipype.interfaces.matlab import MatlabCommand, MatlabInputSpec + + +class HelloWorldInputSpec(MatlabInputSpec): + name = traits.Str(mandatory=True, + desc='Name of person to say hello to') + + +class HelloWorldOutputSpec(TraitedSpec): + matlab_output = traits.Str() + + +class HelloWorld(MatlabCommand): + """Basic Hello World that displays Hello in MATLAB + + Returns + ------- + + matlab_output : capture of matlab output which may be + parsed by user to get computation results + + Examples + -------- + + >>> hello = HelloWorld() + >>> hello.inputs.name = 'hello_world' + >>> out = hello.run() + >>> print out.outputs.matlab_output + """ + input_spec = HelloWorldInputSpec + output_spec = HelloWorldOutputSpec + + def _my_script(self): + """This is where you implement your script""" + script = """ + disp('Hello %s Python') + two = 1 + 1 + """ % (self.inputs.name) + return script + + def run(self, **inputs): + # Inject your script + self.inputs.script = self._my_script() + results = super(MatlabCommand, self).run(**inputs) + stdout = results.runtime.stdout + # Attach stdout to outputs to access matlab results + results.outputs.matlab_output = stdout + return results + + def _list_outputs(self): + outputs = self._outputs().get() + return outputs \ No newline at end of file From 2027c70a8ae98b888224575e3b036d3fd7b977c0 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 2 Feb 2015 16:31:56 +0100 Subject: [PATCH 23/40] DOC add blank line in matlab examples --- doc/devel/matlab_example1.py | 2 +- doc/devel/matlab_example2.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/devel/matlab_example1.py b/doc/devel/matlab_example1.py index 5fef8a9b18..aaf6c4cb3a 100644 --- a/doc/devel/matlab_example1.py +++ b/doc/devel/matlab_example1.py @@ -44,4 +44,4 @@ def _run_interface(self, runtime): def _list_outputs(self): outputs = self._outputs().get() outputs['out_file'] = os.path.abspath(self.inputs.out_file) - return outputs \ No newline at end of file + return outputs diff --git a/doc/devel/matlab_example2.py b/doc/devel/matlab_example2.py index 836f407c26..8d683ea45f 100644 --- a/doc/devel/matlab_example2.py +++ b/doc/devel/matlab_example2.py @@ -51,4 +51,4 @@ def run(self, **inputs): def _list_outputs(self): outputs = self._outputs().get() - return outputs \ No newline at end of file + return outputs From 55238c108ce3a8f25b6a5a619d5d7a1ce03a8b05 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Tue, 3 Feb 2015 12:21:07 +0100 Subject: [PATCH 24/40] DOC fix literal block issues in nipype/interfaces/fsl/preprocess.py --- nipype/interfaces/fsl/preprocess.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nipype/interfaces/fsl/preprocess.py b/nipype/interfaces/fsl/preprocess.py index e1246b457b..7b82e22e65 100644 --- a/nipype/interfaces/fsl/preprocess.py +++ b/nipype/interfaces/fsl/preprocess.py @@ -1256,7 +1256,7 @@ class FUGUE(FSLCommand): -------- - Unwarping an input image (shift map is known) + Unwarping an input image (shift map is known): >>> from nipype.interfaces.fsl.preprocess import FUGUE >>> fugue = FUGUE() @@ -1270,7 +1270,7 @@ class FUGUE(FSLCommand): >>> fugue.run() #doctest: +SKIP - Warping an input image (shift map is known) + Warping an input image (shift map is known): >>> from nipype.interfaces.fsl.preprocess import FUGUE >>> fugue = FUGUE() @@ -1285,7 +1285,7 @@ class FUGUE(FSLCommand): >>> fugue.run() #doctest: +SKIP - Computing the vsm (unwrapped phase map is known) + Computing the vsm (unwrapped phase map is known): >>> from nipype.interfaces.fsl.preprocess import FUGUE >>> fugue = FUGUE() @@ -1601,4 +1601,4 @@ def _gen_mesh_names(self, name, structures): bvar = prefix + '-' + struct + '_first.bvars' bvars.append(op.abspath(bvar)) return bvars - return None \ No newline at end of file + return None From e652674761d465259302f8640640db5a6cd85fa2 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 6 Feb 2015 10:22:20 +0100 Subject: [PATCH 25/40] DOC updates in users/tutorial_101: move code in external file (and update it), mention that nodes need absolut file path correct typos and add download section. --- doc/users/tutorial_101.py | 59 +++++++++++++++++++++++++++ doc/users/tutorial_101.rst | 81 ++++++++++++++++---------------------- 2 files changed, 93 insertions(+), 47 deletions(-) create mode 100644 doc/users/tutorial_101.py diff --git a/doc/users/tutorial_101.py b/doc/users/tutorial_101.py new file mode 100644 index 0000000000..4ed0142282 --- /dev/null +++ b/doc/users/tutorial_101.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +import os +import nipype.interfaces.spm as spm # the spm interfaces +import nipype.pipeline.engine as pe # the workflow and node wrappers + +import nipype.interfaces.matlab as mlab # how to run matlab +# Path to matlab +mlab.MatlabCommand.set_default_matlab_cmd("/full/path/to/matlab_exe") +# Add SPM to MATLAB path if not present +mlab.MatlabCommand.set_default_paths("/full/path/to/spm") + +# +# Define nodes +# + +realigner = pe.Node(interface=spm.Realign(), name='realign') +realigner.inputs.in_files = os.abspath('somefuncrun.nii') +realigner.inputs.register_to_mean = True + +smoother = pe.Node(interface=spm.Smooth(fwhm=6), name='smooth') + +# +# Creating and configuring a workflow +# +workflow = pe.Workflow(name='preproc') +workflow.base_dir = '.' + +# +# Connecting nodes to each other +# +workflow.connect(realigner, 'realigned_files', smoother, 'in_files') + + +# +# Visualizing the workflow +# +workflow.write_graph() + +# +# Extend it +# +import nipype.algorithms.rapidart as ra +artdetect = pe.Node(interface=ra.ArtifactDetect(), name='artdetect') +artdetect.inputs.use_differences = [True, False] +artdetect.inputs.use_norm = True +artdetect.inputs.norm_threshold = 0.5 +artdetect.inputs.zintensity_threshold = 3 +artdetect.inputs.parameter_source = 'SPM' +artdetect.inputs.mask_type = 'spm_global' +workflow.connect([(realigner, artdetect, + [('realigned_files', 'realigned_files'), + ('realignment_parameters', 'realignment_parameters')] + )]) +workflow.write_graph() + +# +# Execute the workflow +# +workflow.run() diff --git a/doc/users/tutorial_101.rst b/doc/users/tutorial_101.rst index 64b9be2a3c..965c9cb818 100644 --- a/doc/users/tutorial_101.rst +++ b/doc/users/tutorial_101.rst @@ -25,30 +25,24 @@ setting up a workflow is separate from executing it. **1. Import appropriate modules** -.. testcode:: - - import nipype.interfaces.spm as spm # the spm interfaces - import nipype.pipeline.engine as pe # the workflow and node wrappers +.. literalinclude:: tutorial_101.py + :lines: 2-4 **2. Define nodes** Here we take instances of interfaces and make them pipeline compatible by wrapping them with pipeline specific elements. To determine the inputs and outputs of a given interface, please see :ref:`interface_tutorial`. Let's -start with defining a realign node using the interface -:class:`nipype.interfaces.spm.Realign` +start with defining a realign node using the :ref:`Realign ` interface: -.. testcode:: - - realigner = pe.Node(interface=spm.Realign(), name='realign') - realigner.inputs.in_files = 'somefuncrun.nii' - realigner.inputs.register_to_mean = True +.. literalinclude:: tutorial_101.py + :lines: 16-18 This would be equivalent to: .. testcode:: - - realigner = pe.Node(interface=spm.Realign(infile='somefuncrun.nii', + + realigner = pe.Node(interface=spm.Realign(infile=os.abspath('somefuncrun.nii'), register_to_mean = True), name='realign') @@ -58,15 +52,17 @@ later or while initializing the interface. .. note:: - In the above example, 'somefuncrun.nii' has to exist, otherwise the - commands won't work. A node will check if appropriate inputs are - being supplied. + a) In the above example, 'somefuncrun.nii' has to exist in the current directory, + otherwise the commands won't work. A node will check if appropriate + inputs are being supplied. -Similar to the realigner node, we now set up a smoothing node. + b) As noted above, you have to use the absolute path + of the file otherwise the workflow will fail to run. -.. testcode:: +Similar to the realigner node, we now set up a smoothing node. - smoother = pe.Node(interface=spm.Smooth(fwhm=6), name='smooth') +.. literalinclude:: tutorial_101.py + :lines: 20 Now we have two nodes with their inputs defined. Note that we have not defined an input file for the smoothing node. This will be done by connecting the @@ -77,17 +73,15 @@ realigner to the smoother in step 5. Here we create an instance of a workflow and indicate that it should operate in the current directory. -.. testcode:: - - workflow = pe.Workflow(name='preproc') - workflow.base_dir = '.' +.. literalinclude:: tutorial_101.py + :lines: 25-26 **4. Adding nodes to workflows (optional)** If nodes are going to be connected (see step 5), this step is not necessary. However, if you would like to run a node by itself without connecting it to any other node, then you need to add it to the -workflow. For adding nodes, order of nodes is not important. +workflow. When adding nodes, the order is not important. .. testcode:: @@ -100,15 +94,14 @@ This results in a workflow containing two isolated nodes: **5. Connecting nodes to each other** We want to connect the output produced by the node realignment to the input of -the node smoothing. This is done as follows. - -.. testcode:: +the node smoothing. This is done as follows: - workflow.connect(realigner, 'realigned_files', smoother, 'in_files') +.. literalinclude:: tutorial_101.py + :lines: 31 - -Although not shown here, the following notation can be used to connect multiple outputs from one node to -multiple inputs (see step 7 below). +or alternatively, a more flexible notation can be used. Although not shown here, +the following notation can be used to connect multiple outputs from one node to +multiple inputs (see step 7 below): .. testcode:: @@ -121,8 +114,8 @@ This results in a workflow containing two connected nodes: **6. Visualizing the workflow** The workflow is represented as a directed acyclic graph (DAG) and one -can visualize this using the following command. In fact, the pictures -above were generated using this. +can visualize this using the following command (in fact, the pictures +above were generated using this): .. testcode:: @@ -147,18 +140,9 @@ options: Now that you have seen a basic pipeline let's add another node to the above pipeline. -.. testcode:: - import nipype.algorithms.rapidart as ra - artdetect = pe.Node(interface=ra.ArtifactDetect(), name='artdetect') - artdetect.inputs.use_differences = [True, False] - art.inputs.use_norm = True - art.inputs.norm_threshold = 0.5 - art.inputs.zintensity_threshold = 3 - workflow.connect([(realigner, artdetect, - [('realigned_files', 'realigned_files'), - ('realignment_parameters','realignment_parameters')] - )]) +.. literalinclude:: tutorial_101.py + :lines: 42-53 .. note:: @@ -180,14 +164,17 @@ This results in Assuming that **somefuncrun.nii** is actually a file or you've replaced it with an appropriate one, you can run the pipeline with: -.. testcode:: - - workflow.run() +.. literalinclude:: tutorial_101.py + :lines: 59 This should create a folder called preproc in your current directory, inside which are three folders: realign, smooth and artdetect (the names of the nodes). The outputs of these routines are in these folders. +.. admonition:: Example source code + + You can download :download:`the source code of this example `. + .. include:: ../links_names.txt .. glossary:: From 81fa2768cb973d49d30f66ddf0fb09631a2e7450 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 6 Feb 2015 10:33:25 +0100 Subject: [PATCH 26/40] WIP minimal modifications in users/interface_tutorial.rst --- doc/users/interface_tutorial.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/users/interface_tutorial.rst b/doc/users/interface_tutorial.rst index 1c356c1b5d..dba865977c 100644 --- a/doc/users/interface_tutorial.rst +++ b/doc/users/interface_tutorial.rst @@ -10,7 +10,7 @@ Specifying options The nipype interface modules provide a Python interface to external packages like FSL_ and SPM_. Within the module are a series of Python classes which wrap specific package functionality. For example, in -the fsl module, the class :class:`nipype.interfaces.fsl.Bet` wraps the +the :ref:`fsl ` module, the class :ref:`BET ` wraps the ``bet`` command-line tool. Using the command-line tool, one would specify options using flags like ``-o``, ``-m``, ``-f ``, etc... However, in nipype, options are assigned to Python attributes and can From 2eeb5677125a482e1302e24631c79db36d5cbc3d Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 6 Feb 2015 13:19:20 +0100 Subject: [PATCH 27/40] DOC correct indentation error in doc/index.rst --- doc/index.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/index.rst b/doc/index.rst index f9cc156a67..d600dd504f 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -2,6 +2,7 @@ * - .. image:: images/nipype_architecture_overview2.png :width: 100 % + - .. container:: Current neuroimaging software offer users an incredible opportunity to @@ -14,10 +15,10 @@ to existing neuroimaging software and facilitates interaction between these packages within a single workflow. Nipype provides an environment that encourages interactive exploration of algorithms from different - packages (e.g., ANTS_, SPM_, FSL_, FreeSurfer_, Camino_, MRtrix_, MNE_, AFNI_, + packages (e.g., ANTS_, SPM_, FSL_, FreeSurfer_, Camino_, MRtrix_, MNE_, AFNI_, Slicer_), eases the design of workflows within and between packages, and reduces the learning curve necessary to use different packages. Nipype is - creating a collaborative platform for neuroimaging software development + creating a collaborative platform for neuroimaging software development in a high-level language and addressing limitations of existing pipeline systems. From bc2bce0d6039cae718a42ceb0b44eb5b549ef1a1 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 6 Feb 2015 13:20:14 +0100 Subject: [PATCH 28/40] DOC correct indentation error in doc/users/config.rst --- doc/users/config_file.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/users/config_file.rst b/doc/users/config_file.rst index 1f37dbe047..d09dd660d6 100644 --- a/doc/users/config_file.rst +++ b/doc/users/config_file.rst @@ -115,10 +115,10 @@ Execution done after a job finish is detected. (float in seconds; default value: 5) *remove_node_directories (EXPERIMENTAL)* - Removes directories whose outputs have already been used - up. Doesn't work with IdentiInterface or any node that patches - data through (without copying) (possible values: ``true`` and - ``false``; default value: ``false``) + Removes directories whose outputs have already been used + up. Doesn't work with IdentiInterface or any node that patches + data through (without copying) (possible values: ``true`` and + ``false``; default value: ``false``) *stop_on_unknown_version* If this is set to True, an underlying interface will raise an error, when no From 0fab2e422e59ae4d7b2e3a2908d81308c8df0852 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 6 Feb 2015 13:21:40 +0100 Subject: [PATCH 29/40] DOC correct references in doc/devel/devel/cmd_interface_devel.rst --- doc/devel/cmd_interface_devel.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/devel/cmd_interface_devel.rst b/doc/devel/cmd_interface_devel.rst index 9ee2c43f48..1a764b4c87 100644 --- a/doc/devel/cmd_interface_devel.rst +++ b/doc/devel/cmd_interface_devel.rst @@ -80,7 +80,7 @@ symbols. For an input defined in InputSpec to be included into the executed commandline ``argstr`` has to be included. Additionally inside the main interface class you need to specify the name of the executable by assigning it to the ``_cmd`` field. Also the main interface class needs to inherit from -:class:`nipype.interfaces.base.CommandLine`: +:class:`CommandLine `: .. testcode:: @@ -92,7 +92,7 @@ to the ``_cmd`` field. Also the main interface class needs to inherit from There is one more thing we need to take care of. When the executable finishes processing it will presumably create some output files. We need to know which files to look for, check if they exist and expose them to whatever node would -like to use them. This is done by implementing ``_list_outputs`` method in the +like to use them. This is done by implementing :func:`_list_outputs ` method in the main interface class. Basically what it does is assigning the expected output files to the fields of our output spec: From 5899dec7738fcd5be69835b62749a4418ac8614a Mon Sep 17 00:00:00 2001 From: Nolan Nichols Date: Sun, 8 Feb 2015 11:36:25 -0800 Subject: [PATCH 30/40] fix: documentation indentation and highlighting --- .../rsfmri_vol_surface_preprocessing_nipy.py | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/examples/rsfmri_vol_surface_preprocessing_nipy.py b/examples/rsfmri_vol_surface_preprocessing_nipy.py index 8a61c3c202..68c1c029a3 100644 --- a/examples/rsfmri_vol_surface_preprocessing_nipy.py +++ b/examples/rsfmri_vol_surface_preprocessing_nipy.py @@ -39,9 +39,10 @@ specifically the 2mm versions of: -- `Joint Fusion Atlas `_ -- `MNI template `_ + * `Joint Fusion Atlas `_ + * `MNI template `_ +Import necessary modules from nipype. """ import os @@ -70,6 +71,10 @@ import scipy as sp import nibabel as nb +""" +A list of modules and functions to import inside of nodes +""" + imports = ['import os', 'import nibabel as nb', 'import numpy as np', @@ -78,6 +83,10 @@ 'from scipy.special import legendre' ] +""" +Define utility functions for use in workflow nodes +""" + def get_info(dicom_files): """Given a Siemens dicom file return metadata @@ -340,28 +349,35 @@ def combine_hemi(left, right): fmt=','.join(['%d'] + ['%.10f'] * (all_data.shape[1] - 1))) return os.path.abspath(filename) +""" +Create a Registration Workflow +""" + def create_reg_workflow(name='registration'): """Create a FEAT preprocessing workflow together with freesurfer Parameters ---------- - name : name of workflow (default: 'registration') - Inputs:: + Inputs: inputspec.source_files : files (filename or list of filenames to register) inputspec.mean_image : reference image to use inputspec.anatomical_image : anatomical image to coregister to inputspec.target_image : registration target - Outputs:: + Outputs: outputspec.func2anat_transform : FLIRT transform outputspec.anat2target_transform : FLIRT+FNIRT transform outputspec.transformed_files : transformed files in target space outputspec.transformed_mean : mean image in target space + + Example + ------- + See code below """ register = Workflow(name=name) @@ -463,16 +479,17 @@ def create_reg_workflow(name='registration'): convert2itk.inputs.fsl2ras = True convert2itk.inputs.itk_transform = True register.connect(bbregister, 'out_fsl_file', convert2itk, 'transform_file') - register.connect(inputnode, 'mean_image',convert2itk, 'source_file') + register.connect(inputnode, 'mean_image', convert2itk, 'source_file') register.connect(stripper, 'out_file', convert2itk, 'reference_file') """ Compute registration between the subject's structural and MNI template - This is currently set to perform a very quick registration. However, the - registration can be made significantly more accurate for cortical - structures by increasing the number of iterations - All parameters are set using the example from: - #https://github.com/stnava/ANTs/blob/master/Scripts/newAntsExample.sh + + * All parameters are set using the example from: \ + `newAntsExample.sh `_ + * This is currently set to perform a very quick registration. However,\ + the registration can be made significantly more accurate for cortical\ + structures by increasing the number of iterations. """ reg = Node(ants.Registration(), name='antsRegister') @@ -505,7 +522,6 @@ def create_reg_workflow(name='registration'): register.connect(stripper, 'out_file', reg, 'moving_image') register.connect(inputnode,'target_image', reg,'fixed_image') - """ Concatenate the affine and ants transforms into a list """ @@ -514,7 +530,6 @@ def create_reg_workflow(name='registration'): register.connect(convert2itk, 'itk_transform', merge, 'in2') register.connect(reg, 'composite_transform', merge, 'in1') - """ Transform the mean image. First to anatomical and then to target """ @@ -532,7 +547,6 @@ def create_reg_workflow(name='registration'): register.connect(inputnode, 'mean_image', warpmean, 'input_image') register.connect(merge, 'out', warpmean, 'transforms') - """ Assign all the output files """ @@ -555,7 +569,6 @@ def create_reg_workflow(name='registration'): return register - """ Creates the main preprocessing workflow """ @@ -637,7 +650,6 @@ def create_workflow(files, art.inputs.mask_type = 'spm_global' art.inputs.parameter_source = 'NiPy' - """Here we are connecting all the nodes together. Notice that we add the merge node only if you choose to use 4D. Also `get_vox_dims` function is passed along the input volume of normalise to set the optimal voxel sizes. From 104464104c7336687b8f0435fce844f68dd19307 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 9 Feb 2015 12:10:33 +0100 Subject: [PATCH 31/40] DOC minor fix in examples/rsfmri_vol_surface_preprocessing_nipy.py --- examples/rsfmri_vol_surface_preprocessing_nipy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rsfmri_vol_surface_preprocessing_nipy.py b/examples/rsfmri_vol_surface_preprocessing_nipy.py index 68c1c029a3..273fe0b997 100644 --- a/examples/rsfmri_vol_surface_preprocessing_nipy.py +++ b/examples/rsfmri_vol_surface_preprocessing_nipy.py @@ -20,7 +20,7 @@ python rsfmri_preprocessing.py -d /data/12345-34-1.dcm -f /data/Resting.nii -s subj001 -o output -p PBS --plugin_args "dict(qsub_args='-q many')" - or +or:: python rsfmri_vol_surface_preprocessing.py -f SUB_1024011/E?/func/rest.nii -t OASIS-30_Atropos_template_in_MNI152_2mm.nii.gz --TR 2 -s SUB_1024011 From 3ff1dbd55d4f6d4947a50ea673dbbd5c4ff9caf8 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Mon, 9 Feb 2015 12:39:35 +0100 Subject: [PATCH 32/40] DOC PEP8 edits in examples/fmri_ants_openfmri.py --- examples/fmri_ants_openfmri.py | 80 +++++++++++++++++----------------- 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/examples/fmri_ants_openfmri.py b/examples/fmri_ants_openfmri.py index a4ea61c1c1..8d9f0dbb53 100755 --- a/examples/fmri_ants_openfmri.py +++ b/examples/fmri_ants_openfmri.py @@ -110,11 +110,11 @@ def create_reg_workflow(name='registration'): register = pe.Workflow(name=name) inputnode = pe.Node(interface=niu.IdentityInterface(fields=['source_files', - 'mean_image', - 'anatomical_image', - 'target_image', - 'target_image_brain', - 'config_file']), + 'mean_image', + 'anatomical_image', + 'target_image', + 'target_image_brain', + 'config_file']), name='inputspec') outputnode = pe.Node(interface=niu.IdentityInterface(fields=['func2anat_transform', 'anat2target_transform', @@ -185,7 +185,7 @@ def create_reg_workflow(name='registration'): convert2itk.inputs.fsl2ras = True convert2itk.inputs.itk_transform = True register.connect(mean2anatbbr, 'out_matrix_file', convert2itk, 'transform_file') - register.connect(inputnode, 'mean_image',convert2itk, 'source_file') + register.connect(inputnode, 'mean_image', convert2itk, 'source_file') register.connect(stripper, 'out_file', convert2itk, 'reference_file') """ @@ -226,7 +226,7 @@ def create_reg_workflow(name='registration'): reg.plugin_args = {'qsub_args': '-pe orte 4', 'sbatch_args': '--mem=6G -c 4'} register.connect(stripper, 'out_file', reg, 'moving_image') - register.connect(inputnode,'target_image_brain', reg,'fixed_image') + register.connect(inputnode, 'target_image_brain', reg, 'fixed_image') """ Concatenate the affine and ants transforms into a list @@ -249,7 +249,7 @@ def create_reg_workflow(name='registration'): warpmean.inputs.invert_transform_flags = [False, False] warpmean.inputs.terminal_output = 'file' - register.connect(inputnode,'target_image_brain', warpmean,'reference_image') + register.connect(inputnode, 'target_image_brain', warpmean, 'reference_image') register.connect(inputnode, 'mean_image', warpmean, 'input_image') register.connect(merge, 'out', warpmean, 'transforms') @@ -265,8 +265,8 @@ def create_reg_workflow(name='registration'): warpall.inputs.invert_transform_flags = [False, False] warpall.inputs.terminal_output = 'file' - register.connect(inputnode,'target_image_brain',warpall,'reference_image') - register.connect(inputnode,'source_files', warpall, 'input_image') + register.connect(inputnode, 'target_image_brain', warpall, 'reference_image') + register.connect(inputnode, 'source_files', warpall, 'input_image') register.connect(merge, 'out', warpall, 'transforms') """ @@ -515,6 +515,7 @@ def create_fs_reg_workflow(name='registration'): Get info for a given subject """ + def get_subjectinfo(subject_id, base_dir, task_id, model_id): """Get info for a given subject @@ -559,7 +560,7 @@ def get_subjectinfo(subject_id, base_dir, task_id, model_id): for idx in range(n_tasks): taskidx = np.where(taskinfo[:, 0] == 'task%03d' % (idx + 1)) conds.append([condition.replace(' ', '_') for condition - in taskinfo[taskidx[0], 2]]) # if 'junk' not in condition]) + in taskinfo[taskidx[0], 2]]) # if 'junk' not in condition]) files = sorted(glob(os.path.join(base_dir, subject_id, 'BOLD', @@ -588,6 +589,7 @@ def get_subjectinfo(subject_id, base_dir, task_id, model_id): Analyzes an open fmri dataset """ + def analyze_openfmri_dataset(data_dir, subject=None, model_id=None, task_id=None, output_dir=None, subj_prefix='*', hpcutoff=120., use_derivatives=True, @@ -661,15 +663,15 @@ def analyze_openfmri_dataset(data_dir, subject=None, model_id=None, has_contrast = os.path.exists(contrast_file) if has_contrast: datasource = pe.Node(nio.DataGrabber(infields=['subject_id', 'run_id', - 'task_id', 'model_id'], - outfields=['anat', 'bold', 'behav', - 'contrasts']), - name='datasource') + 'task_id', 'model_id'], + outfields=['anat', 'bold', 'behav', + 'contrasts']), + name='datasource') else: datasource = pe.Node(nio.DataGrabber(infields=['subject_id', 'run_id', - 'task_id', 'model_id'], - outfields=['anat', 'bold', 'behav']), - name='datasource') + 'task_id', 'model_id'], + outfields=['anat', 'bold', 'behav']), + name='datasource') datasource.inputs.base_directory = data_dir datasource.inputs.template = '*' @@ -681,19 +683,19 @@ def analyze_openfmri_dataset(data_dir, subject=None, model_id=None, 'contrasts': ('models/model%03d/' 'task_contrasts.txt')} datasource.inputs.template_args = {'anat': [['subject_id']], - 'bold': [['subject_id', 'task_id']], - 'behav': [['subject_id', 'model_id', - 'task_id', 'run_id']], - 'contrasts': [['model_id']]} + 'bold': [['subject_id', 'task_id']], + 'behav': [['subject_id', 'model_id', + 'task_id', 'run_id']], + 'contrasts': [['model_id']]} else: datasource.inputs.field_template = {'anat': '%s/anatomy/T1_001.nii.gz', 'bold': '%s/BOLD/task%03d_r*/bold.nii.gz', 'behav': ('%s/model/model%03d/onsets/task%03d_' 'run%03d/cond*.txt')} datasource.inputs.template_args = {'anat': [['subject_id']], - 'bold': [['subject_id', 'task_id']], - 'behav': [['subject_id', 'model_id', - 'task_id', 'run_id']]} + 'bold': [['subject_id', 'task_id']], + 'behav': [['subject_id', 'model_id', + 'task_id', 'run_id']]} datasource.inputs.sort_filelist = True @@ -736,7 +738,7 @@ def get_contrasts(contrast_file, task_id, conds): for row in contrast_def: if row[0] != 'task%03d' % task_id: continue - con = [row[1], 'T', ['cond%03d' % (i + 1) for i in range(len(conds))], + con = [row[1], 'T', ['cond%03d' % (i + 1) for i in range(len(conds))], row[2:].astype(float).tolist()] contrasts.append(con) # add auto contrasts for each column @@ -762,7 +764,7 @@ def get_contrasts(contrast_file, task_id, conds): name="art") modelspec = pe.Node(interface=model.SpecifyModel(), - name="modelspec") + name="modelspec") modelspec.inputs.input_units = 'secs' def check_behav_list(behav, run_id, conds): @@ -776,9 +778,9 @@ def check_behav_list(behav, run_id, conds): return behav_array.reshape(num_elements/num_conds, num_conds).tolist() reshape_behav = pe.Node(niu.Function(input_names=['behav', 'run_id', 'conds'], - output_names=['behav'], - function=check_behav_list), - name='reshape_behav') + output_names=['behav'], + function=check_behav_list), + name='reshape_behav') wf.connect(subjinfo, 'TR', modelspec, 'time_repetition') wf.connect(datasource, 'behav', reshape_behav, 'behav') @@ -858,7 +860,7 @@ def sort_copes(copes, varcopes, contrasts): ('varcopes', 'inputspec.varcopes'), ('n_runs', 'l2model.num_copes')]), (modelfit, fixed_fx, [('outputspec.dof_file', - 'inputspec.dof_files'), + 'inputspec.dof_files'), ]) ]) @@ -888,9 +890,9 @@ def merge_files(copes, varcopes, zstats): mergefunc = pe.Node(niu.Function(input_names=['copes', 'varcopes', 'zstats'], - output_names=['out_files', 'splits'], - function=merge_files), - name='merge_files') + output_names=['out_files', 'splits'], + function=merge_files), + name='merge_files') wf.connect([(fixed_fx.get_node('outputspec'), mergefunc, [('copes', 'copes'), ('varcopes', 'varcopes'), @@ -908,7 +910,7 @@ def split_files(in_files, splits): output_names=['copes', 'varcopes', 'zstats'], function=split_files), - name='split_files') + name='split_files') wf.connect(mergefunc, 'splits', splitfunc, 'splits') wf.connect(registration, 'outputspec.transformed_files', splitfunc, 'in_files') @@ -932,12 +934,12 @@ def split_files(in_files, splits): def get_subs(subject_id, conds, run_id, model_id, task_id): subs = [('_subject_id_%s_' % subject_id, '')] - subs.append(('_model_id_%d' % model_id, 'model%03d' %model_id)) + subs.append(('_model_id_%d' % model_id, 'model%03d' % model_id)) subs.append(('task_id_%d/' % task_id, '/task%03d_' % task_id)) subs.append(('bold_dtype_mcf_mask_smooth_mask_gms_tempfilt_mean_warp', - 'mean')) + 'mean')) subs.append(('bold_dtype_mcf_mask_smooth_mask_gms_tempfilt_mean_flirt', - 'affine')) + 'affine')) for i in range(len(conds)): subs.append(('_flameo%d/cope1.' % i, 'cope%02d.' % (i + 1))) @@ -1058,7 +1060,7 @@ def get_subs(subject_id, conds, run_id, model_id, task_id): help="Model index" + defstr) parser.add_argument('-x', '--subjectprefix', default='sub*', help="Subject prefix" + defstr) - parser.add_argument('-t', '--task', default=1, #nargs='+', + parser.add_argument('-t', '--task', default=1, type=int, help="Task index" + defstr) parser.add_argument('--hpfilter', default=120., type=float, help="High pass filter cutoff (in secs)" + defstr) From fd267ef8348116db3f6625425360d6caf3e9b663 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Wed, 11 Feb 2015 21:51:28 +0100 Subject: [PATCH 33/40] DOC Added ANTS to the list of wrapped tools. --- doc/users/install.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/users/install.rst b/doc/users/install.rst index 20348ebf07..b20c0c0a47 100644 --- a/doc/users/install.rst +++ b/doc/users/install.rst @@ -174,6 +174,9 @@ Slicer_ Nipy_ 0.1.2+20110404 or later +ANTS_ + ANTS version 2.1 or later + Nitime_ (optional) From 941b7ad12201db4280f79c18b27ad34421f08ff1 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Wed, 11 Feb 2015 21:54:34 +0100 Subject: [PATCH 34/40] Revert "DOC Added ANTS to the list of wrapped tools." This reverts commit 181255e9f070acf9142fe46692a37f427d24b1da. --- doc/users/install.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/users/install.rst b/doc/users/install.rst index b20c0c0a47..20348ebf07 100644 --- a/doc/users/install.rst +++ b/doc/users/install.rst @@ -174,9 +174,6 @@ Slicer_ Nipy_ 0.1.2+20110404 or later -ANTS_ - ANTS version 2.1 or later - Nitime_ (optional) From b4d0eee69eface6e2b0bfe5372b2894d4e2803b6 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 13 Feb 2015 13:26:16 +0100 Subject: [PATCH 35/40] WIP Updates in examples/fmri_ants_openfmri.py --- examples/fmri_ants_openfmri.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/fmri_ants_openfmri.py b/examples/fmri_ants_openfmri.py index 8d9f0dbb53..b073531d00 100755 --- a/examples/fmri_ants_openfmri.py +++ b/examples/fmri_ants_openfmri.py @@ -10,6 +10,12 @@ This script demonstrates how to use nipype to analyze a data set:: python fmri_ants_openfmri.py --datasetdir ds107 + +This workflow also requires 2mm subcortical templates that are available from +`MindBoggle `_. +Specifically the 2mm version of the `MNI template `_. + +Import necessary modules from nipype. """ from nipype import config @@ -676,7 +682,7 @@ def analyze_openfmri_dataset(data_dir, subject=None, model_id=None, datasource.inputs.template = '*' if has_contrast: - datasource.inputs.field_template = {'anat': '%s/anatomy/T1_001.nii.gz', + datasource.inputs.field_template = {'anat': '%s/anatomy/highres001.nii.gz', 'bold': '%s/BOLD/task%03d_r*/bold.nii.gz', 'behav': ('%s/model/model%03d/onsets/task%03d_' 'run%03d/cond*.txt'), From 8da068c13783b0e727b89909caeed24682a31ba5 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Tue, 15 Sep 2015 22:26:45 +0200 Subject: [PATCH 36/40] DOC remove some leftovers. --- doc/devel/cmd_interface_devel.rst | 4 ---- doc/devel/matlab_interface_devel.rst | 10 ---------- doc/users/tutorial_101.rst | 4 ---- 3 files changed, 18 deletions(-) diff --git a/doc/devel/cmd_interface_devel.rst b/doc/devel/cmd_interface_devel.rst index 24bef23b90..753b9057a8 100644 --- a/doc/devel/cmd_interface_devel.rst +++ b/doc/devel/cmd_interface_devel.rst @@ -39,11 +39,7 @@ above example we have used the ``desc`` metadata which holds human readable description of the input. The ``mandatory`` flag forces Nipype to throw an exception if the input was not set. ``exists`` is a special flag that works only for ``File traits`` and checks if the provided file exists. More details can be -<<<<<<< HEAD -found at :doc:`interface_specs`. -======= found at :ref:`interface_specs`. ->>>>>>> cb80e24fc2a68758defcb16c7ab70092aa35b693 The input and output specifications have to be connected to the our example interface class: diff --git a/doc/devel/matlab_interface_devel.rst b/doc/devel/matlab_interface_devel.rst index a22779965e..8ccbb2f42a 100644 --- a/doc/devel/matlab_interface_devel.rst +++ b/doc/devel/matlab_interface_devel.rst @@ -21,7 +21,6 @@ Example 2 +++++++++ By subclassing :class:`nipype.interfaces.matlab.MatlabCommand` for your main class, and :class:`nipype.interfaces.matlab.MatlabInputSpec` for your input spec, you gain access to some useful MATLAB hooks -<<<<<<< HEAD .. literalinclude:: matlab_example2.py @@ -30,13 +29,4 @@ By subclassing :class:`nipype.interfaces.matlab.MatlabCommand` for your main cla You can download :download:`the source code of this example `. .. include:: ../links_names.txt -======= -.. literalinclude:: matlab_example2.py - -.. admonition:: Example source code - - You can download :download:`the source code of this example `. ->>>>>>> cb80e24fc2a68758defcb16c7ab70092aa35b693 - -.. include:: ../links_names.txt diff --git a/doc/users/tutorial_101.rst b/doc/users/tutorial_101.rst index 401136ac94..8aec74df57 100644 --- a/doc/users/tutorial_101.rst +++ b/doc/users/tutorial_101.rst @@ -43,11 +43,7 @@ This would be equivalent to: .. testcode:: realigner = pe.Node(interface=spm.Realign(infile=os.abspath('somefuncrun.nii'), -<<<<<<< HEAD register_to_mean = True), -======= - register_to_mean = True), ->>>>>>> cb80e24fc2a68758defcb16c7ab70092aa35b693 name='realign') In Pythonic terms, this is saying that interface option in Node accepts From 75c7b2ade333edaef6b92f709b60630ea6b47f1f Mon Sep 17 00:00:00 2001 From: Dorota Jarecka Date: Thu, 22 Feb 2018 15:06:13 -0500 Subject: [PATCH 37/40] removing tutorials that are not used anymore (not included in the intex page) --- doc/users/interface_tutorial.rst | 251 ------------------------------- doc/users/pipeline_tutorial.rst | 70 --------- doc/users/tutorial_101.py | 59 -------- doc/users/tutorial_101.rst | 200 ------------------------ doc/users/tutorial_102.rst | 158 ------------------- doc/users/tutorial_103.rst | 117 -------------- doc/users/vagrant.rst | 52 ------- 7 files changed, 907 deletions(-) delete mode 100644 doc/users/interface_tutorial.rst delete mode 100644 doc/users/pipeline_tutorial.rst delete mode 100644 doc/users/tutorial_101.py delete mode 100644 doc/users/tutorial_101.rst delete mode 100644 doc/users/tutorial_102.rst delete mode 100644 doc/users/tutorial_103.rst delete mode 100644 doc/users/vagrant.rst diff --git a/doc/users/interface_tutorial.rst b/doc/users/interface_tutorial.rst deleted file mode 100644 index 0cd2dc6c3d..0000000000 --- a/doc/users/interface_tutorial.rst +++ /dev/null @@ -1,251 +0,0 @@ -.. _interface_tutorial: - -======================= - Tutorial : Interfaces -======================= - -Specifying input settings -------------------------- - -The nipype interface modules provide a Python interface to external -packages like FSL_ and SPM_. Within the module are a series of Python -classes which wrap specific package functionality. For example, in -the :ref:`fsl ` module, the class -:class:`nipype.interfaces.fsl.BET>` wraps the -``bet`` command-line tool. Using the command-line tool, one would -specify input settings using flags like ``-o``, ``-m``, ``-f ``, etc... -However, in nipype, options are assigned to Python attributes and can -be specified in the following ways: - -Settings can be assigned when you first create an interface object: - -.. testcode:: - - import nipype.interfaces.fsl as fsl - mybet = fsl.BET(in_file='foo.nii', out_file='bar.nii') - result = mybet.run() - -Settings can be assigned through the ``inputs`` attribute: - -.. testcode:: - - import nipype.interfaces.fsl as fsl - mybet = fsl.BET() - mybet.inputs.in_file = 'foo.nii' - mybet.inputs.out_file = 'bar.nii' - result = mybet.run() - -Settings can be assigned when calling the ``run`` method: - -.. testcode:: - - import nipype.interfaces.fsl as fsl - mybet = fsl.BET() - result = mybet.run(in_file='foo.nii', out_file='bar.nii', frac=0.5) - -Settings can be saved to a json file: - -.. testcode:: - - import nipype.interfaces.fsl as fsl - mybet = fsl.BET(in_file='foo.nii', out_file='bar.nii', frac=0.5) - mybet.save_inputs_to_json('bet-settings.json') - -Once saved, the three inputs set for ``mybet`` will be stored in a JSON -file. These settings can also be loaded from a json file: - -.. testcode:: - - import nipype.interfaces.fsl as fsl - mybet = fsl.BET() - mybet.load_inputs_from_json('bet-settings.json', overwrite=False) - - -Loading settings will overwrite previously set inputs by default, unless -the ``overwrite`` argument is ``False``. Conveniently, the settings can be -also read during the interface instantiation: - -.. testcode:: - - import nipype.interfaces.fsl as fsl - mybet = fsl.BET(from_file='bet-settings.json') - -If the user provides settings during interface creation, they will take -precedence over those loaded using ``from_file``: - -.. testcode:: - - import nipype.interfaces.fsl as fsl - mybet = fsl.BET(from_file='bet-settings.json', frac=0.7) - -In this case, ``mybet.inputs.frac`` will contain the value ``0.7`` regardless -the value that could be stored in the ``bet-settings.json`` file. - - -Getting Help ------------- - -In IPython_ you can view the docstrings which provide some basic -documentation and examples. - -.. sourcecode:: ipython - - In [2]: fsl.FAST? - Type: type - Base Class: - String Form: - Namespace: Interactive - File: /Users/satra/sp/nipype/interfaces/fsl/preprocess.py - Docstring: - Use FSL FAST for segmenting and bias correction. - - For complete details, see the `FAST Documentation. - `_ - - Examples - -------- - >>> from nipype.interfaces import fsl - >>> from nipype.testing import anatfile - - Assign options through the ``inputs`` attribute: - - >>> fastr = fsl.FAST() - >>> fastr.inputs.in_files = anatfile - >>> out = fastr.run() #doctest: +SKIP - - Constructor information: - Definition: fsl.FAST(self, **inputs) - -.. sourcecode:: ipython - - In [5]: spm.Realign? - Type: type - Base Class: - String Form: - Namespace: Interactive - File: /Users/satra/sp/nipype/interfaces/spm/preprocess.py - Docstring: - Use spm_realign for estimating within modality rigid body alignment - - http://www.fil.ion.ucl.ac.uk/spm/doc/manual.pdf#page=25 - - Examples - -------- - - >>> import nipype.interfaces.spm as spm - >>> realign = spm.Realign() - >>> realign.inputs.in_files = 'functional.nii' - >>> realign.inputs.register_to_mean = True - >>> realign.run() # doctest: +SKIP - - Constructor information: - Definition: spm.Realign(self, **inputs) - - -All of the nipype.interfaces classes have an ``help`` method -which provides information on each of the options one can assign. - -.. sourcecode:: ipython - - In [6]: fsl.BET.help() - Inputs - ------ - - Mandatory: - in_file: input file to skull strip - - Optional: - args: Additional parameters to the command - center: center of gravity in voxels - environ: Environment variables (default={}) - frac: fractional intensity threshold - functional: apply to 4D fMRI data - mutually exclusive: functional, reduce_bias - mask: create binary mask image - mesh: generate a vtk mesh brain surface - no_output: Don't generate segmented output - out_file: name of output skull stripped image - outline: create surface outline image - output_type: FSL output type - radius: head radius - reduce_bias: bias field and neck cleanup - mutually exclusive: functional, reduce_bias - skull: create skull image - threshold: apply thresholding to segmented brain image and mask - vertical_gradient: vertical gradient in fractional intensity threshold (-1, 1) - - Outputs - ------- - mask_file: path/name of binary brain mask (if generated) - meshfile: path/name of vtk mesh file (if generated) - out_file: path/name of skullstripped file - outline_file: path/name of outline file (if generated) - -.. sourcecode:: ipython - - In [7]: spm.Realign.help() - Inputs - ------ - - Mandatory: - in_files: list of filenames to realign - - Optional: - fwhm: gaussian smoothing kernel width - interp: degree of b-spline used for interpolation - jobtype: one of: estimate, write, estwrite (default=estwrite) - matlab_cmd: None - mfile: Run m-code using m-file (default=True) - paths: Paths to add to matlabpath - quality: 0.1 = fast, 1.0 = precise - register_to_mean: Indicate whether realignment is done to the mean image - separation: sampling separation in mm - weight_img: filename of weighting image - wrap: Check if interpolation should wrap in [x,y,z] - write_interp: degree of b-spline used for interpolation - write_mask: True/False mask output image - write_which: determines which images to reslice - write_wrap: Check if interpolation should wrap in [x,y,z] - - Outputs - ------- - mean_image: Mean image file from the realignment - realigned_files: Realigned files - realignment_parameters: Estimated translation and rotation parameters - - -Our :ref:`interface-index` documentation provides html versions of our -docstrings and includes links to the specific package -documentation. For instance, the :class:`nipype.interfaces.fsl.Bet` -docstring has a direct link to the online BET Documentation. - - -FSL interface example ---------------------- - -Using FSL_ to realign a time_series: - -.. testcode:: - - import nipype.interfaces.fsl as fsl - realigner = fsl.McFlirt() - realigner.inputs.in_file='timeseries4D.nii' - result = realigner.run() - - -SPM interface example ---------------------- - -Using SPM_ to realign a time-series: - -.. testcode:: - - import nipype.interfaces.spm as spm - from glob import glob - allepi = glob('epi*.nii') # this will return an unsorted list - allepi.sort() - realigner = spm.Realign() - realigner.inputs.in_files = allepi - result = realigner.run() - -.. include:: ../links_names.txt diff --git a/doc/users/pipeline_tutorial.rst b/doc/users/pipeline_tutorial.rst deleted file mode 100644 index 084860d692..0000000000 --- a/doc/users/pipeline_tutorial.rst +++ /dev/null @@ -1,70 +0,0 @@ -.. _pipeline_tutorial: - -===================== - Tutorial : Workflows -===================== - -This section presents several tutorials on how to setup and use pipelines. Make -sure that you have the requirements satisfied and go through the steps required -for the analysis tutorials. - -Essential reading -================= - -.. toctree:: - :maxdepth: 1 - :glob: - - tutorial_101 - tutorial_102 - tutorial_103 - mapnode_and_iterables - grabbing_and_sinking - -Beginner's guide -================ - -By Michael Notter. `Available here`__ - -__ http://miykael.github.com/nipype-beginner-s-guide/index.html - -Example workflows -================= - -.. toctree:: - :maxdepth: 1 - :glob: - - examples/* - -Requirements -============ - - All tutorials - - - Release 0.4 of nipype and it's dependencies have been installed - - Analysis tutorials - - - FSL_, FreeSurfer_, Camino_, ConnectomeViewer and MATLAB_ are available and - callable from the command line - - - SPM_ 5/8/12 is installed and callable in matlab - - - Space: 3-10 GB - -Checklist for analysis tutorials -================================ - -For the analysis tutorials, we will be using a slightly modified version of the -FBIRN Phase I travelling data set. - -1. Download and extract the `Pipeline tutorial data (429MB). -`_ -(md5: d175083784c5167de4ea11b43b37c166) - -2. Ensure that all programs are available by calling ``bet``, ``matlab`` -and then ``which spm`` within matlab to ensure you have spm5/8/12 in your -matlab path. - -.. include:: ../links_names.txt diff --git a/doc/users/tutorial_101.py b/doc/users/tutorial_101.py deleted file mode 100644 index 4ed0142282..0000000000 --- a/doc/users/tutorial_101.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -import os -import nipype.interfaces.spm as spm # the spm interfaces -import nipype.pipeline.engine as pe # the workflow and node wrappers - -import nipype.interfaces.matlab as mlab # how to run matlab -# Path to matlab -mlab.MatlabCommand.set_default_matlab_cmd("/full/path/to/matlab_exe") -# Add SPM to MATLAB path if not present -mlab.MatlabCommand.set_default_paths("/full/path/to/spm") - -# -# Define nodes -# - -realigner = pe.Node(interface=spm.Realign(), name='realign') -realigner.inputs.in_files = os.abspath('somefuncrun.nii') -realigner.inputs.register_to_mean = True - -smoother = pe.Node(interface=spm.Smooth(fwhm=6), name='smooth') - -# -# Creating and configuring a workflow -# -workflow = pe.Workflow(name='preproc') -workflow.base_dir = '.' - -# -# Connecting nodes to each other -# -workflow.connect(realigner, 'realigned_files', smoother, 'in_files') - - -# -# Visualizing the workflow -# -workflow.write_graph() - -# -# Extend it -# -import nipype.algorithms.rapidart as ra -artdetect = pe.Node(interface=ra.ArtifactDetect(), name='artdetect') -artdetect.inputs.use_differences = [True, False] -artdetect.inputs.use_norm = True -artdetect.inputs.norm_threshold = 0.5 -artdetect.inputs.zintensity_threshold = 3 -artdetect.inputs.parameter_source = 'SPM' -artdetect.inputs.mask_type = 'spm_global' -workflow.connect([(realigner, artdetect, - [('realigned_files', 'realigned_files'), - ('realignment_parameters', 'realignment_parameters')] - )]) -workflow.write_graph() - -# -# Execute the workflow -# -workflow.run() diff --git a/doc/users/tutorial_101.rst b/doc/users/tutorial_101.rst deleted file mode 100644 index bad89c2f94..0000000000 --- a/doc/users/tutorial_101.rst +++ /dev/null @@ -1,200 +0,0 @@ -.. _tutorial_101: - -============ -Pipeline 101 -============ - -A workflow or pipeline is built by connecting processes or nodes to each -other. In the context of nipype, every interface can be treated as a pipeline -node having defined inputs and outputs. Creating a workflow then is a matter -of connecting appropriate outputs to inputs. Currently, workflows are limited -to being directional and cannot have any loops, thereby creating an ordering to -data flow. The following nipype component architecture might help understanding -some of the tutorials presented here. - -.. image:: images/componentarchitecture.png - :width: 600 px - -My first pipeline -================= - -Although the most trivial workflow consists of a single node, we will -create a workflow with two nodes: a realign node that will send -the realigned functional data to a smoothing node. It is important to note that -setting up a workflow is separate from executing it. - -**1. Import appropriate modules** - -.. literalinclude:: tutorial_101.py - :lines: 2-4 - -**2. Define nodes** - -Here we take instances of interfaces and make them pipeline compatible by -wrapping them with pipeline specific elements. To determine the inputs and outputs -of a given interface, please see :ref:`interface_tutorial`. Let's -start with defining a realign node using the :ref:`Realign ` interface: - -.. literalinclude:: tutorial_101.py - :lines: 16-18 - -This would be equivalent to: - -.. testcode:: - - realigner = pe.Node(interface=spm.Realign(infile=os.abspath('somefuncrun.nii'), - register_to_mean = True), - name='realign') - -In Pythonic terms, this is saying that interface option in Node accepts -an *instance* of an interface. The inputs to this interface can be set either -later or while initializing the interface. - -.. note:: - - a) In the above example, 'somefuncrun.nii' has to exist in the current directory, - otherwise the commands won't work. A node will check if appropriate - inputs are being supplied. - - b) As noted above, you have to use the absolute path - of the file otherwise the workflow will fail to run. - -Similar to the realigner node, we now set up a smoothing node. - -.. literalinclude:: tutorial_101.py - :lines: 20 - -Now we have two nodes with their inputs defined. Note that we have not defined -an input file for the smoothing node. This will be done by connecting the -realigner to the smoother in step 5. - -**3. Creating and configuring a workflow** - -Here we create an instance of a workflow and indicate that it should operate in -the current directory. The workflow's output will be placed in the ``preproc`` -directory. - -.. literalinclude:: tutorial_101.py - :lines: 25-26 - -**4. Adding nodes to workflows (optional)** - -If nodes are going to be connected (see step 5), this step is not -necessary. However, if you would like to run a node by itself without -connecting it to any other node, then you need to add it to the -workflow. When adding nodes, the order is not important. - -.. testcode:: - - workflow.add_nodes([smoother, realigner]) - -This results in a workflow containing two isolated nodes: - -.. image:: images/smoothrealignunconnected.png - -**5. Connecting nodes to each other** - -We want to connect the output produced by the node realignment to the input of -the node smoothing. This is done as follows: - -.. literalinclude:: tutorial_101.py - :lines: 31 - -or alternatively, a more flexible notation can be used. Although not shown here, -the following notation can be used to connect multiple outputs from one node to -multiple inputs (see step 7 below): - -.. testcode:: - - workflow.connect([(realigner, smoother, [('realigned_files', 'in_files')])]) - -This results in a workflow containing two connected nodes: - -.. image:: images/smoothrealignconnected.png - -**6. Visualizing the workflow** - -The workflow is represented as a directed acyclic graph (DAG) and one -can visualize this using the following command (in fact, the pictures -above were generated using this): - -.. testcode:: - - workflow.write_graph() - -This creates two files ``graph.dot`` and ``graph_detailed.dot`` inside -``./preproc`` and if -graphviz_ is installed on your system it automatically converts it -to png files. If graphviz is not installed you can take the dot files -and load them in a graphviz visualizer elsewhere. You can specify how detailed -the graph is going to be, by using the ``graph2use`` argument which takes -the following -options: - -* hierarchical - creates a graph showing all embedded workflows (default) -* orig - creates a top level graph without expanding internal workflow nodes -* flat - expands workflow nodes recursively -* exec - expands workflows to depict iterables (be careful - can generate really - large graphs) - - -**7. Extend it** - -Now that you have seen a basic pipeline let's add another node to the -above pipeline. - - -.. literalinclude:: tutorial_101.py - :lines: 42-53 - -.. note:: - - a) How an alternative form of connect was used to connect multiple - output fields from the realign node to corresponding input - fields of the artifact detection node. - - b) The current visualization only shows connected input and - output ports. It does not show all the parameters that you have - set for a node. - -This results in - -.. image:: images/threecomponentpipe.png - :width: 650 px - -**8. Execute the workflow** - -Assuming that **somefuncrun.nii** is actually a file or you've -replaced it with an appropriate one, you can run the pipeline with: - -.. literalinclude:: tutorial_101.py - :lines: 59 - -This should create a folder called preproc in your current directory, -inside which are three folders: realign, smooth and artdetect (the names -of the nodes). The outputs of these routines are in these folders. - -.. admonition:: Example source code - - You can download :download:`the source code of this example `. - -.. include:: ../links_names.txt - -.. glossary:: - - pipeline - Connected series of processes (processes can be run parallel and or sequential) - - workflow - (kind of synonymous to pipeline) = hosting the nodes - - node - = switching-point within a pipeline, you can give it a name (in the above example e.g. realigner), - a node usually requires an or several inputs and will produce an or several outputs - - interface - = specific software (e.g. FSL, SPM ...) are wrapped in interfaces, within a node instances of an - interface can be run - - modules - for each interface the according modules have to be imported in the usual pythonic manner diff --git a/doc/users/tutorial_102.rst b/doc/users/tutorial_102.rst deleted file mode 100644 index 60668d9bd5..0000000000 --- a/doc/users/tutorial_102.rst +++ /dev/null @@ -1,158 +0,0 @@ -.. _tutorial_102: - -============ -Pipeline 102 -============ - -Now that you know how to construct a workflow and execute it, we will go -into more advanced concepts. This tutorial focuses on -:class:`nipype.pipeline.engine.Workflow` -:class:`nipype.pipeline.engine.Node` and -:class:`nipype.pipeline.engine.MapNode`. - -A workflow is a **directed acyclic graph (DAG)** consisting of nodes -which can be of type `Workflow`, `Node` or `MapNode`. Workflows can -be re-used and hierarchical workflows can be easily constructed. - -'name' : the mandatory keyword arg -================================== - -When instantiating a Workflow, Node or MapNode, a `name` has to be -provided. For any given level of a workflow, no two nodes can have the -same name. The engine will let you know if this is the case when you add -nodes to a workflow either directly using `add_nodes` or using the -`connect` function. - -Names have many internal uses. They determine the name of the directory -in which the workflow/node is run and the outputs are stored. - -.. testcode:: - - realigner = pe.Node(interface=spm.Realign(), - name='RealignSPM') - -Now this output will be stored in a directory called -*RealignSPM*. Proper naming of your nodes can be advantageous -from the perspective that it provides a semantic descriptor aligned with -your thought process. This name parameter is also used to refer to nodes in -embedded workflows. - -iterables ---------- - -This can only be set for Node and MapNode. This is syntactic sugar for -running a subgraph with the Node/MapNode at its root in a ``for`` -loop. For example, consider an fMRI preprocessing pipeline that you -would like to run for all your subjects. You can define a workflow and -then execute it for every single subject inside a ``for`` loop. Consider -the simplistic example below, where startnode is a node belonging to -workflow 'mywork.' - -.. testcode:: - - for s in subjects: - startnode.inputs.subject_id = s - mywork.run() - -The pipeline engine provides a convenience function that simplifies -this: - -.. testcode:: - - startnode.iterables = ('subject_id', subjects) - mywork.run() - -This will achieve the same exact behavior as the for loop above. The -workflow graph is: - -.. image:: images/proc2subj.png - :width: 650 px - - -Now consider the situation in which you want the last node (typically -smoothing) of your preprocessing pipeline to smooth using two -different kernels (0 mm and 6 mm FWHM). Again the common approach -would be: - -.. testcode:: - - for s in subjects: - startnode.inputs.subject_id = s - uptosmoothingworkflow.run() - smoothnode.inputs.infile = lastnode.output.outfile - for fwhm in [0, 6]: - smoothnode.inputs.fwhm = fwhm - remainingworkflow.run() - -Instead of having multiple ``for`` loops at various stages, you can set up -another set of iterables for the smoothnode. - -.. testcode:: - - startnode.iterables = ('subject_id', subjects) - smoothnode.iterables = ('fwhm', [0, 6]) - mywork.run() - -This will run the preprocessing workflow for two different smoothing -kernels over all subjects. - -.. image:: images/proc2subj2fwhm.png - :width: 650 px - -Thus setting iterables has a multiplicative effect. In the above -examples there is a separate, distinct specifymodel node that's -executed for each combination of subject and smoothing. - - -iterfield ---------- - -This is a mandatory keyword arg for MapNode. This enables running the -underlying interface over a set of inputs and is particularly useful -when the interface can only operate on a single input. For example, the -:class:`nipype.interfaces.fsl.BET` will operate on only one (3d or 4d) -NIfTI file. But wrapping BET in a MapNode can execute it over a list of files: - -.. testcode:: - - better = pe.MapNode(interface=fsl.Bet(), name='stripper', - iterfield=['in_file']) - better.inputs.in_file = ['file1.nii','file2.nii'] - better.run() - -This will create a directory called ``stripper`` and inside it two -subdirectories called ``in_file_0`` and ``in_file_1``. The output of running bet -separately on each of those files will be stored in those two -subdirectories. - -This can be extended to run it on pairwise inputs. For example, - -.. testcode:: - - transform = pe.MapNode(interface=fs.ApplyVolTransform(), - name='warpvol', - iterfield=['source_file', 'reg_file']) - transform.inputs.source_file = ['file1.nii','file2.nii'] - transform.inputs.reg_file = ['file1.reg','file2.reg'] - transform.run() - -The above will be equivalent to running transform by taking corresponding items from -each of the two fields in iterfield. The subdirectories get always -named with respect to the first iterfield. - - -overwrite ---------- - -The overwrite keyword arg forces a node to be rerun. - -The `clone` function --------------------- - -The `clone` function can be used to create a copy of a workflow. No -references to the original workflow are retained. As such the clone -function requires a name keyword arg that specifies a new name for the -duplicate workflow. - - -.. include:: ../links_names.txt diff --git a/doc/users/tutorial_103.rst b/doc/users/tutorial_103.rst deleted file mode 100644 index d508c66deb..0000000000 --- a/doc/users/tutorial_103.rst +++ /dev/null @@ -1,117 +0,0 @@ -.. _tutorial_103: - -============ -Pipeline 103 -============ - -Modifying inputs to pipeline nodes -================================== - -Two nodes can be connected as shown below. - -.. testcode:: - - workflow.connect(realigner, 'realigned_files', smoother, 'infile') - -The connection mechanism allows for a function to be evaluated on the -output field ('realigned files') of the source node (realigner) and -have its result be sent to the input field ('infile') of the -destination node (smoother). - -.. testcode:: - - def reverse_order(inlist): - inlist.reverse() - return inlist - - workflow.connect(realigner, ('realigned_files', reverse_order), - smoother, 'infile') - -This can be extended to provide additional arguments to the -function. For example: - -.. testcode:: - - def reorder(inlist, order): - return [inlist[item] for item in order] - - workflow.connect(realigner, ('realigned_files', reorder, [2, 3, 0, 1]), - smoother, 'infile') - -In this example, we assume the realigned_files produces a list of 4 -files. We can reorder these files in a particular order using the -modifier. Since such modifications are not tracked, they should be -used with extreme care and only in cases where absolutely -necessary. Often, one may find that it is better to insert a node -rather than a function. - - -Distributed computation -======================= - -The pipeline engine has built-in support for distributed computation on -clusters. This can be achieved via plugin-modules for Python_ multiprocessing or -the IPython_ distributed computing interface or SGE/PBS/Condor, provided the -user sets up a workflow on a shared filesystem. These modules can take arguments -that specify additional distribution engine parameters. For IPython_ the -environment needs to be configured for distributed operation. Details are -available at :ref:`plugins`. - -The default behavior is to run in series using the Linear plugin. - -.. testcode:: - - workflow.run() - -In some cases it may be advantageous to run the workflow in series locally -(e.g., debugging, small-short pipelines, large memory only interfaces, -relocating working directory/updating hashes). - -Debugging -========= - -When a crash happens while running a pipeline, a crashdump is stored in -the pipeline's working directory unless the config option 'crashdumpdir' -has been set (see :ref:config_options). - -The crashdump is a compressed numpy file that stores a dictionary -containing three fields: - - 1. node - the node that failed - 2. execgraph - the graph that the node came from - 3. traceback - from local or remote session for the failure. - -We keep extending the information contained in the file and making -it easier to troubleshoot the failures. However, in the meantime the following -can help to recover information related to the failure. - -in IPython_ do (``%pdb`` in IPython_ is similar to ``dbstop`` if error in -Matlab): - -.. testcode:: - - from nipype.utils.filemanip import loadflat - crashinfo = loadflat('crashdump....npz') - %pdb - crashinfo['node'].run() # re-creates the crash - pdb> up #typically, but not necessarily the crash is one stack frame up - pdb> inspect variables - pdb>quit - -Relocation of workdir -===================== - -In some circumstances, one might decide to move their entire working -directory to a new location. It would be convenient to rerun only -necessary components of the pipeline, instead of running all the nodes -all over again. It is possible to do that with the -:func:`~nipype.pipeline.engine.Pipeline.updatehash` function. - -.. testcode:: - - workflow.run(updatehash=True) - -This will execute the workflow and update all the hash values that -were stored without actually running any of the interfaces. - -.. include:: ../links_names.txt diff --git a/doc/users/vagrant.rst b/doc/users/vagrant.rst deleted file mode 100644 index 5ca3908bbc..0000000000 --- a/doc/users/vagrant.rst +++ /dev/null @@ -1,52 +0,0 @@ -.. _debug: - -====================== -Running Nipype in a VM -====================== - -.. tip:: - - Creating the Vagrant VM as described below requires an active internet - connection. - -Container technologies (Vagrant_, Docker_) allow creating and manipulating -lightweight virtual environments. The Nipype_ source now contains a Vagrantfile -to launch a Vagrant_ VM. - -Requirements: - -* Vagrant_ -* Virtualbox_ - -After you have installed Vagrant and Virtualbox, you simply need to download the -latest Nipype source and unzip/tar/compress it. Go into your terminal and switch -to the nipype source directory. Make sure the Vagrantfile is in the directory. -Now you can execute:: - - vagrant up - -This will launch and provision the virtual machine. - -The default virtual machine is built using Ubuntu Precise 64, linked to the -NeuroDebian_ source repo and contains a 2 node Grid Engine for cluster -execution. - -The machine has a default IP address of `192.168.100.20` . From the vagrant -startup directory you can log into the machine using:: - - vagrant ssh - -Now you can install your favorite software using:: - - sudo apt-get install fsl afni - -Also note that the directory in which you call `vagrant up` will be mounted -under `/vagrant` inside the virtual machine. You can also copy the Vagrantfile -or modify it in order to mount a different directory/directories. - -Please read through Vagrant_ documentation on other features. The python -environment is built using a `miniconda `_ -distribution. Hence `conda` can be used to do your python package management -inside the VM. - -.. include:: ../links_names.txt From 42fe6d5edf5fad278c56d53d5b8378f8ff8cce95 Mon Sep 17 00:00:00 2001 From: Dorota Jarecka Date: Thu, 22 Feb 2018 15:47:37 -0500 Subject: [PATCH 38/40] updating fmri_abts example --- examples/fmri_ants_openfmri.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/fmri_ants_openfmri.py b/examples/fmri_ants_openfmri.py index 9c1bd78767..0a331d007d 100755 --- a/examples/fmri_ants_openfmri.py +++ b/examples/fmri_ants_openfmri.py @@ -209,7 +209,7 @@ def create_reg_workflow(name='registration'): merge = pe.Node(niu.Merge(2), iterfield=['in2'], name='mergexfm') register.connect(convert2itk, 'itk_transform', merge, 'in2') - register.connect(reg, ('composite_transform', pickfirst), merge, 'in1') + register.connect(reg, 'composite_transform', merge, 'in1') """ Transform the mean image. First to anatomical and then to target @@ -419,7 +419,7 @@ def create_fs_reg_workflow(name='registration'): merge = Node(Merge(2), iterfield=['in2'], name='mergexfm') register.connect(convert2itk, 'itk_transform', merge, 'in2') - register.connect(reg, ('composite_transform', pickfirst), merge, 'in1') + register.connect(reg, 'composite_transform', merge, 'in1') """ Transform the mean image. First to anatomical and then to target From 5e13478d04446d34b77356f95779c9a242e193a4 Mon Sep 17 00:00:00 2001 From: Dorota Jarecka Date: Thu, 22 Feb 2018 16:22:01 -0500 Subject: [PATCH 39/40] after comments from Chris --- doc/devel/cmd_interface_devel.rst | 6 +- doc/devel/matlab_interface_devel.rst | 55 ------------------- doc/index.rst | 2 +- examples/fmri_ants_openfmri.py | 20 +++---- .../rsfmri_vol_surface_preprocessing_nipy.py | 8 +-- 5 files changed, 17 insertions(+), 74 deletions(-) diff --git a/doc/devel/cmd_interface_devel.rst b/doc/devel/cmd_interface_devel.rst index aedb2d3cb0..bbce39783b 100644 --- a/doc/devel/cmd_interface_devel.rst +++ b/doc/devel/cmd_interface_devel.rst @@ -39,7 +39,7 @@ above example we have used the ``desc`` metadata which holds human readable description of the input. The ``mandatory`` flag forces Nipype to throw an exception if the input was not set. ``exists`` is a special flag that works only for ``File traits`` and checks if the provided file exists. More details can be -found at :ref:`interface_specs`. +found at :doc:`interface_specs`. The input and output specifications have to be connected to the our example interface class: @@ -80,7 +80,7 @@ symbols. For an input defined in InputSpec to be included into the executed commandline ``argstr`` has to be included. Additionally inside the main interface class you need to specify the name of the executable by assigning it to the ``_cmd`` field. Also the main interface class needs to inherit from -:class:`CommandLine `: +:class:`CommandLine `: .. testcode:: @@ -92,7 +92,7 @@ to the ``_cmd`` field. Also the main interface class needs to inherit from There is one more thing we need to take care of. When the executable finishes processing it will presumably create some output files. We need to know which files to look for, check if they exist and expose them to whatever node would -like to use them. This is done by implementing :func:`_list_outputs ` method in the +like to use them. This is done by implementing ``_list_outputs`` method in the main interface class. Basically what it does is assigning the expected output files to the fields of our output spec: diff --git a/doc/devel/matlab_interface_devel.rst b/doc/devel/matlab_interface_devel.rst index 4576c97d22..516e000d43 100644 --- a/doc/devel/matlab_interface_devel.rst +++ b/doc/devel/matlab_interface_devel.rst @@ -24,61 +24,6 @@ By subclassing :class:`nipype.interfaces.matlab.MatlabCommand` for your main class, and :class:`nipype.interfaces.matlab.MatlabInputSpec` for your input and output spec, you gain access to some useful MATLAB hooks -.. testcode:: - - import os - from nipype.interfaces.base import File, traits - from nipype.interfaces.matlab import MatlabCommand, MatlabInputSpec - - class HelloWorldInputSpec( MatlabInputSpec): - name = traits.Str(mandatory = True, - desc = 'Name of person to say hello to') - - class HelloWorldOutputSpec(MatlabInputSpec): - matlab_output = traits.Str() - - class HelloWorld(MatlabCommand): - """ Basic Hello World that displays Hello in MATLAB - - Returns - ------- - - matlab_output : capture of matlab output which may be - parsed by user to get computation results - - Examples - -------- - - >>> hello = HelloWorld() - >>> hello.inputs.name = 'hello_world' - >>> out = hello.run() - >>> print(out.outputs.matlab_output) - """ - input_spec = HelloWorldInputSpec - output_spec = HelloWorldOutputSpec - - def _my_script(self): - """This is where you implement your script""" - script = """ - disp('Hello %s Python') - two = 1 + 1 - """%(self.inputs.name) - return script - - def run(self, **inputs): - ## inject your script - self.inputs.script = self._my_script() - results = super(MatlabCommand, self).run( **inputs) - stdout = results.runtime.stdout - # attach stdout to outputs to access matlab results - results.outputs.matlab_output = stdout - return results - - def _list_outputs(self): - outputs = self._outputs().get() - return outputs - - .. literalinclude:: matlab_example2.py .. admonition:: Example source code diff --git a/doc/index.rst b/doc/index.rst index d600dd504f..11471e7a2d 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -18,7 +18,7 @@ packages (e.g., ANTS_, SPM_, FSL_, FreeSurfer_, Camino_, MRtrix_, MNE_, AFNI_, Slicer_), eases the design of workflows within and between packages, and reduces the learning curve necessary to use different packages. Nipype is - creating a collaborative platform for neuroimaging software development + creating a collaborative platform for neuroimaging software development in a high-level language and addressing limitations of existing pipeline systems. diff --git a/examples/fmri_ants_openfmri.py b/examples/fmri_ants_openfmri.py index 0a331d007d..35684cf595 100755 --- a/examples/fmri_ants_openfmri.py +++ b/examples/fmri_ants_openfmri.py @@ -161,10 +161,10 @@ def create_reg_workflow(name='registration'): """ Compute registration between the subject's structural and MNI template - * All parameters are set using the example from: \ - `newAntsExample.sh `_ - * This is currently set to perform a very quick registration. However,\ - the registration can be made significantly more accurate for cortical\ + * All parameters are set using the example from: + #https://github.com/stnava/ANTs/blob/master/Scripts/newAntsExample.sh + * This is currently set to perform a very quick registration. However, + the registration can be made significantly more accurate for cortical structures by increasing the number of iterations. """ @@ -257,9 +257,7 @@ def create_reg_workflow(name='registration'): def get_aparc_aseg(files): - """ - Return the aparc+aseg.mgz file - """ + """Return the aparc+aseg.mgz file""" for name in files: if 'aparc+aseg.mgz' in name: @@ -371,10 +369,10 @@ def create_fs_reg_workflow(name='registration'): """ Compute registration between the subject's structural and MNI template - * All parameters are set using the example from: \ - `newAntsExample.sh `_ - * This is currently set to perform a very quick registration. However,\ - the registration can be made significantly more accurate for cortical\ + * All parameters are set using the example from: + #https://github.com/stnava/ANTs/blob/master/Scripts/newAntsExample.sh + * This is currently set to perform a very quick registration. However, + the registration can be made significantly more accurate for cortical structures by increasing the number of iterations. """ diff --git a/examples/rsfmri_vol_surface_preprocessing_nipy.py b/examples/rsfmri_vol_surface_preprocessing_nipy.py index e34652293d..d3d9887cc6 100644 --- a/examples/rsfmri_vol_surface_preprocessing_nipy.py +++ b/examples/rsfmri_vol_surface_preprocessing_nipy.py @@ -444,10 +444,10 @@ def create_reg_workflow(name='registration'): """ Compute registration between the subject's structural and MNI template - * All parameters are set using the example from: \ - `newAntsExample.sh `_ - * This is currently set to perform a very quick registration. However,\ - the registration can be made significantly more accurate for cortical\ + * All parameters are set using the example from: + #https://github.com/stnava/ANTs/blob/master/Scripts/newAntsExample.sh + * This is currently set to perform a very quick registration. However, + the registration can be made significantly more accurate for cortical structures by increasing the number of iterations. """ From d4b05ea2bcd011677e6501444b315f1c80df4311 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Thu, 22 Feb 2018 19:56:28 -0500 Subject: [PATCH 40/40] STY: Whitespace [skip ci] --- doc/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/index.rst b/doc/index.rst index 11471e7a2d..62502bd37d 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -15,7 +15,7 @@ to existing neuroimaging software and facilitates interaction between these packages within a single workflow. Nipype provides an environment that encourages interactive exploration of algorithms from different - packages (e.g., ANTS_, SPM_, FSL_, FreeSurfer_, Camino_, MRtrix_, MNE_, AFNI_, + packages (e.g., ANTS_, SPM_, FSL_, FreeSurfer_, Camino_, MRtrix_, MNE_, AFNI_, Slicer_), eases the design of workflows within and between packages, and reduces the learning curve necessary to use different packages. Nipype is creating a collaborative platform for neuroimaging software development