From a1eb1e7d2814ebd94b9718f25624538f4eeb7eba Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Wed, 30 Jul 2014 18:40:32 +0200 Subject: [PATCH 01/46] warping meshes --- nipype/algorithms/mesh.py | 62 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/nipype/algorithms/mesh.py b/nipype/algorithms/mesh.py index c556407912..a5e4ce62e1 100644 --- a/nipype/algorithms/mesh.py +++ b/nipype/algorithms/mesh.py @@ -22,6 +22,68 @@ iflogger = logging.getLogger('interface') +class WarpPointsInputSpec(BaseInterfaceInputSpec): + points = File(exists=True, mandatory=True, + desc=('file containing the point set')) + warp = File(exists=True, mandatory=True, + desc=('dense deformation field to be applied')) + interp = traits.Enum('cubic', 'nearest', 'linear', usedefault=True, + mandatory=True, desc='interpolation') + out_points = File(name_source='points', name_template='%s_warped', + output_name='out_points', keep_extension=True, + desc='the warped point set') + +class WarpPointsOutputSpec(TraitedSpec): + out_points = File(desc='the warped point set') + +class WarpPoints(BaseInterface): + """ + Applies a warp field to a point set in vtk + """ + input_spec = WarpPointsInputSpec + output_spec = WarpPointsOutputSpec + + def _overload_extension(self, value, name): + return value + '.vtk' + + def _run_interface(self, runtime): + from tvtk.api import tvtk + import nibabel as nb + import numpy as np + from scipy import ndimage + + r = tvtk.PolyDataReader(file_name=self.inputs.points) + r.update() + mesh = r.output + points = np.array(mesh.points) + warp_dims = nb.funcs.four_to_three(nb.load(self.inputs.warp)) + + affine = warp_dims[0].get_affine() + voxsize = warp_dims[0].get_header().get_zooms() + R = np.linalg.inv(affine[0:3,0:3]) + origin = affine[0:3,3] + points = points - origin[np.newaxis,:] + points = np.array([np.dot(R,p) for p in points]) + + warps = [] + for axis in warp_dims: + wdata = axis.get_data() + if np.any(wdata!=0): + warps.append([ndimage.map_coordinates(wdata, points.transpose())]) + else: + warps.append([np.zeros((points.shape[0],))]) + warps = np.squeeze(np.array(warps)).reshape(-1,3) + print warps.shape + print points.shape + + newpoints = [ p + d for p,d in zip(points, warps)] + mesh.points = newpoints + w = tvtk.PolyDataWriter(input=mesh) + w.file_name = self._filename_from_source('out_points') + w.write() + + return runtime + class P2PDistanceInputSpec(BaseInterfaceInputSpec): surface1 = File(exists=True, mandatory=True, desc=("Reference surface (vtk format) to which compute " From e3fdae714a4ff35bcfeeadab73574da9cacc8db2 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Wed, 30 Jul 2014 22:07:03 +0200 Subject: [PATCH 02/46] Edited CHANGES, added doctets, fixed errors --- CHANGES | 1 + nipype/algorithms/mesh.py | 61 ++++++++++++++++++++++++++++++--------- 2 files changed, 48 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index 15d4824398..eaf0ba0318 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ Next Release ============ +* ENH: New algorithm: mesh.WarpPoints applies displacements fields to point sets. * ENH: FUGUE interface has been refactored to use the name_template system, 3 examples added to doctests, some bugs solved. * ENH: Added new interfaces (fsl.utils.WarpUtils, ConvertWarp) to fnirtfileutils and convertwarp diff --git a/nipype/algorithms/mesh.py b/nipype/algorithms/mesh.py index a5e4ce62e1..7c936e5ac2 100644 --- a/nipype/algorithms/mesh.py +++ b/nipype/algorithms/mesh.py @@ -38,13 +38,35 @@ class WarpPointsOutputSpec(TraitedSpec): class WarpPoints(BaseInterface): """ - Applies a warp field to a point set in vtk + Applies a displacement field to a point set in vtk + + Example + ------- + + >>> from nipype.algorithms.mesh import WarpPoints + >>> wp = mesh.P2PDistance() + >>> wp.inputs.points = 'surf1.vtk' + >>> wp.inputs.warp = 'warpfield.nii' + >>> res = wp.run() # doctest: +SKIP """ input_spec = WarpPointsInputSpec output_spec = WarpPointsOutputSpec - def _overload_extension(self, value, name): - return value + '.vtk' + def _gen_fname(self, in_file, suffix='generated', ext=None): + import os.path as op + + fname, fext = op.splitext(op.basename(in_file)) + + if fext == '.gz': + fname, fext2 = op.splitext(fname) + fext = fext2+fext + + if ext is None: + ext = fext + + if ext[0] == '.': + ext = ext[1:] + return op.abspath('%s_%s.%s' % (fname, suffix, ext)) def _run_interface(self, runtime): from tvtk.api import tvtk @@ -60,30 +82,41 @@ def _run_interface(self, runtime): affine = warp_dims[0].get_affine() voxsize = warp_dims[0].get_header().get_zooms() - R = np.linalg.inv(affine[0:3,0:3]) + vox2ras = affine[0:3,0:3] + ras2vox = np.linalg.inv(vox2ras) origin = affine[0:3,3] - points = points - origin[np.newaxis,:] - points = np.array([np.dot(R,p) for p in points]) + voxpoints = np.array([np.dot(ras2vox, + (p-origin)) for p in points]) warps = [] for axis in warp_dims: wdata = axis.get_data() if np.any(wdata!=0): - warps.append([ndimage.map_coordinates(wdata, points.transpose())]) + + warp = ndimage.map_coordinates(wdata, + voxpoints.transpose()) else: - warps.append([np.zeros((points.shape[0],))]) - warps = np.squeeze(np.array(warps)).reshape(-1,3) - print warps.shape - print points.shape + warp = np.zeros((points.shape[0],)) + + warps.append(warp) - newpoints = [ p + d for p,d in zip(points, warps)] + disps = np.squeeze(np.dstack(warps)) + newpoints = [p+d for p,d in zip(points, disps)] mesh.points = newpoints w = tvtk.PolyDataWriter(input=mesh) - w.file_name = self._filename_from_source('out_points') + w.file_name = self._gen_fname(self.inputs.points, + suffix='warped', + ext='.vtk') w.write() - return runtime + def _list_outputs(self): + outputs = self._outputs().get() + outputs['out_points'] = self._gen_fname(self.inputs.points, + suffix='warped', + ext='.vtk') + return outputs + class P2PDistanceInputSpec(BaseInterfaceInputSpec): surface1 = File(exists=True, mandatory=True, desc=("Reference surface (vtk format) to which compute " From 9769e1bd2cc51e2ac29c1f132d0473e7ef294b59 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Thu, 31 Jul 2014 01:01:45 +0200 Subject: [PATCH 03/46] fixed error in doctest --- nipype/algorithms/mesh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/algorithms/mesh.py b/nipype/algorithms/mesh.py index 7c936e5ac2..26080b0967 100644 --- a/nipype/algorithms/mesh.py +++ b/nipype/algorithms/mesh.py @@ -44,7 +44,7 @@ class WarpPoints(BaseInterface): ------- >>> from nipype.algorithms.mesh import WarpPoints - >>> wp = mesh.P2PDistance() + >>> wp = WarpPoints() >>> wp.inputs.points = 'surf1.vtk' >>> wp.inputs.warp = 'warpfield.nii' >>> res = wp.run() # doctest: +SKIP From cf38e495d884362885b21b874c431abd13b8d2e0 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Thu, 31 Jul 2014 01:53:15 +0200 Subject: [PATCH 04/46] Added ETSConfig to avoid display errors Also fixed some PEP8 errors --- nipype/algorithms/mesh.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/nipype/algorithms/mesh.py b/nipype/algorithms/mesh.py index 26080b0967..7bb71d9668 100644 --- a/nipype/algorithms/mesh.py +++ b/nipype/algorithms/mesh.py @@ -33,9 +33,11 @@ class WarpPointsInputSpec(BaseInterfaceInputSpec): output_name='out_points', keep_extension=True, desc='the warped point set') + class WarpPointsOutputSpec(TraitedSpec): out_points = File(desc='the warped point set') + class WarpPoints(BaseInterface): """ Applies a displacement field to a point set in vtk @@ -69,6 +71,8 @@ def _gen_fname(self, in_file, suffix='generated', ext=None): return op.abspath('%s_%s.%s' % (fname, suffix, ext)) def _run_interface(self, runtime): + from traits.etsconfig.api import ETSConfig # This is necessary to + ETSConfig.toolkit = 'null' # avoid 'unable to connect display' errors from tvtk.api import tvtk import nibabel as nb import numpy as np @@ -82,26 +86,26 @@ def _run_interface(self, runtime): affine = warp_dims[0].get_affine() voxsize = warp_dims[0].get_header().get_zooms() - vox2ras = affine[0:3,0:3] + vox2ras = affine[0:3, 0:3] ras2vox = np.linalg.inv(vox2ras) - origin = affine[0:3,3] + origin = affine[0:3, 3] voxpoints = np.array([np.dot(ras2vox, (p-origin)) for p in points]) warps = [] for axis in warp_dims: wdata = axis.get_data() - if np.any(wdata!=0): + if np.any(wdata != 0): warp = ndimage.map_coordinates(wdata, - voxpoints.transpose()) + voxpoints.transpose()) else: warp = np.zeros((points.shape[0],)) warps.append(warp) disps = np.squeeze(np.dstack(warps)) - newpoints = [p+d for p,d in zip(points, disps)] + newpoints = [p+d for p, d in zip(points, disps)] mesh.points = newpoints w = tvtk.PolyDataWriter(input=mesh) w.file_name = self._gen_fname(self.inputs.points, @@ -117,6 +121,7 @@ def _list_outputs(self): ext='.vtk') return outputs + class P2PDistanceInputSpec(BaseInterfaceInputSpec): surface1 = File(exists=True, mandatory=True, desc=("Reference surface (vtk format) to which compute " @@ -126,8 +131,8 @@ class P2PDistanceInputSpec(BaseInterfaceInputSpec): "distance.")) weighting = traits.Enum("none", "surface", usedefault=True, desc=('"none": no weighting is performed, ' - '"surface": edge distance is weighted by the ' - 'corresponding surface area')) + '"surface": edge distance is weighted by the' + ' corresponding surface area')) class P2PDistanceOutputSpec(TraitedSpec): distance = traits.Float(desc="computed distance") From 7aee50da144cef6968fbcd9b2f04163d83296521 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 30 Jan 2015 18:35:08 +0100 Subject: [PATCH 05/46] 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 06/46] 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 07/46] 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 08/46] 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 09/46] 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 10/46] 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 11/46] 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 12/46] 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 13/46] 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 14/46] 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 15/46] 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 16/46] 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 17/46] 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 18/46] 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 19/46] 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 20/46] 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 21/46] 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 22/46] 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 23/46] 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 efefdb1c2709c1326e5377867a54041d82863229 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Wed, 29 Jul 2015 17:17:16 +0200 Subject: [PATCH 24/46] fix conflicts --- nipype/algorithms/mesh.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/nipype/algorithms/mesh.py b/nipype/algorithms/mesh.py index 15b429f26e..ef1494cf46 100644 --- a/nipype/algorithms/mesh.py +++ b/nipype/algorithms/mesh.py @@ -25,7 +25,6 @@ iflogger = logging.getLogger('interface') -<<<<<<< HEAD class WarpPointsInputSpec(BaseInterfaceInputSpec): points = File(exists=True, mandatory=True, desc=('file containing the point set')) @@ -43,6 +42,7 @@ class WarpPointsOutputSpec(TraitedSpec): class WarpPoints(BaseInterface): + """ Applies a displacement field to a point set in vtk @@ -57,6 +57,7 @@ class WarpPoints(BaseInterface): """ input_spec = WarpPointsInputSpec output_spec = WarpPointsOutputSpec + _redirect_x = True def _gen_fname(self, in_file, suffix='generated', ext=None): import os.path as op @@ -114,7 +115,7 @@ def _run_interface(self, runtime): ras2vox = np.linalg.inv(vox2ras) origin = affine[0:3, 3] voxpoints = np.array([np.dot(ras2vox, - (p-origin)) for p in points]) + (p-origin)) for p in points]) warps = [] for axis in warp_dims: @@ -151,22 +152,12 @@ def _list_outputs(self): return outputs -class P2PDistanceInputSpec(BaseInterfaceInputSpec): -======= class ComputeMeshWarpInputSpec(BaseInterfaceInputSpec): ->>>>>>> master surface1 = File(exists=True, mandatory=True, desc=('Reference surface (vtk format) to which compute ' 'distance.')) surface2 = File(exists=True, mandatory=True, -<<<<<<< HEAD - desc=("Test surface (vtk format) from which compute " - "distance.")) - weighting = traits.Enum("none", "surface", usedefault=True, - desc=('"none": no weighting is performed, ' - '"surface": edge distance is weighted by the' - ' corresponding surface area')) -======= + desc=('Test surface (vtk format) from which compute ' 'distance.')) metric = traits.Enum('euclidean', 'sqeuclidean', usedefault=True, @@ -180,7 +171,6 @@ class ComputeMeshWarpInputSpec(BaseInterfaceInputSpec): 'to surface2') out_file = File('distance.npy', usedefault=True, desc='numpy file keeping computed distances and weights') ->>>>>>> master class ComputeMeshWarpOutputSpec(TraitedSpec): From b83a1ecee68daa52e6b0990dbf46a145a388531b Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Thu, 30 Jul 2015 12:02:43 +0200 Subject: [PATCH 25/46] describe the input displacement field --- nipype/algorithms/mesh.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/nipype/algorithms/mesh.py b/nipype/algorithms/mesh.py index 51d7f56096..25b5541867 100644 --- a/nipype/algorithms/mesh.py +++ b/nipype/algorithms/mesh.py @@ -44,7 +44,11 @@ class WarpPointsOutputSpec(TraitedSpec): class WarpPoints(BaseInterface): """ - Applies a displacement field to a point set in vtk + Applies a displacement field to a point set given in vtk format. + Any discrete deformation field, given in physical coordinates and + which volume covers the extent of the vtk point set, is a valid + ``warp`` file. FSL interfaces are compatible, for instance any + field computed with :class:`nipype.interfaces.fsl.utils.ConvertWarp`. Example ------- From abd899ab4cb7b40f3ce019fa77d52711603a3e2d Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Mon, 3 Aug 2015 11:00:43 +0200 Subject: [PATCH 26/46] remove unncecessary pass statements --- nipype/algorithms/mesh.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/nipype/algorithms/mesh.py b/nipype/algorithms/mesh.py index 25b5541867..7fde3cfa03 100644 --- a/nipype/algorithms/mesh.py +++ b/nipype/algorithms/mesh.py @@ -86,7 +86,6 @@ def _run_interface(self, runtime): vtk_major = vtk.VTK_MAJOR_VERSION except ImportError: iflogger.warn(('python-vtk could not be imported')) - pass try: from tvtk.api import tvtk @@ -98,10 +97,8 @@ def _run_interface(self, runtime): ETSConfig.toolkit = 'null' except ImportError: iflogger.warn(('ETS toolkit could not be imported')) - pass except ValueError: iflogger.warn(('ETS toolkit could not be set to null')) - pass import nibabel as nb import numpy as np @@ -233,10 +230,8 @@ def _run_interface(self, runtime): ETSConfig.toolkit = 'null' except ImportError: iflogger.warn(('ETS toolkit could not be imported')) - pass except ValueError: iflogger.warn(('ETS toolkit is already set')) - pass r1 = tvtk.PolyDataReader(file_name=self.inputs.surface1) r2 = tvtk.PolyDataReader(file_name=self.inputs.surface2) @@ -256,7 +251,6 @@ def _run_interface(self, runtime): errvector = nla.norm(diff, axis=1) except TypeError: # numpy < 1.9 errvector = np.apply_along_axis(nla.norm, 1, diff) - pass if self.inputs.metric == 'sqeuclidean': errvector = errvector ** 2 @@ -367,10 +361,8 @@ def _run_interface(self, runtime): ETSConfig.toolkit = 'null' except ImportError: iflogger.warn(('ETS toolkit could not be imported')) - pass except ValueError: iflogger.warn(('ETS toolkit is already set')) - pass r1 = tvtk.PolyDataReader(file_name=self.inputs.in_surf) vtk1 = r1.output From f03dec07acfb6cacccbc4097d38c4c10168f14a2 Mon Sep 17 00:00:00 2001 From: Chris Filo Gorgolewski Date: Fri, 11 Sep 2015 17:45:18 -0700 Subject: [PATCH 27/46] added support for boolean flags --- nipype/utils/nipype_cmd.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/nipype/utils/nipype_cmd.py b/nipype/utils/nipype_cmd.py index b29ea8898f..749650ef51 100644 --- a/nipype/utils/nipype_cmd.py +++ b/nipype/utils/nipype_cmd.py @@ -2,7 +2,7 @@ import argparse import inspect import sys -from nipype.interfaces.base import Interface, InputMultiPath +from nipype.interfaces.base import Interface, InputMultiPath, traits from nipype.utils.misc import str2bool def listClasses(module=None): @@ -24,6 +24,9 @@ def add_options(parser=None, module=None, function=None): for name, spec in sorted(interface.inputs.traits(transient=None).items()): desc = "\n".join(interface._get_trait_desc(inputs, name, spec))[len(name)+2:] args = {} + + if spec.is_trait_type(traits.Bool): + args["action"] = 'store_true' if hasattr(spec, "mandatory") and spec.mandatory: if spec.is_trait_type(InputMultiPath): @@ -43,16 +46,17 @@ def run_instance(interface, options): for input_name, _ in interface.inputs.items(): if getattr(options, input_name) != None: value = getattr(options, input_name) - #traits cannot cast from string to float or int - try: - value = float(value) - except: - pass - #try to cast string input to boolean - try: - value = str2bool(value) - except: - pass + if not isinstance(value, bool): + #traits cannot cast from string to float or int + try: + value = float(value) + except: + pass + #try to cast string input to boolean + try: + value = str2bool(value) + except: + pass try: setattr(interface.inputs, input_name, value) From 13edf840e2e1e949f5f41685aacadc9971c73759 Mon Sep 17 00:00:00 2001 From: Chris Filo Gorgolewski Date: Fri, 11 Sep 2015 23:18:53 -0700 Subject: [PATCH 28/46] fixed tests --- nipype/utils/tests/test_cmd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nipype/utils/tests/test_cmd.py b/nipype/utils/tests/test_cmd.py index 3aedc87c9c..368dc7cbf8 100644 --- a/nipype/utils/tests/test_cmd.py +++ b/nipype/utils/tests/test_cmd.py @@ -88,7 +88,7 @@ def test_run_4d_realign_without_arguments(self): self.assertEqual(stderr.getvalue(), """usage: nipype_cmd nipype.interfaces.nipy FmriRealign4d [-h] [--between_loops [BETWEEN_LOOPS [BETWEEN_LOOPS ...]]] - [--ignore_exception IGNORE_EXCEPTION] + [--ignore_exception] [--loops [LOOPS [LOOPS ...]]] [--slice_order SLICE_ORDER] [--speedup [SPEEDUP [SPEEDUP ...]]] @@ -113,4 +113,4 @@ def test_run_4d_realign_help(self): self.assertTrue("Run FmriRealign4d" in stdout.getvalue()) if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() From f5c206da611769ce7ad5357bc687f0763ea18602 Mon Sep 17 00:00:00 2001 From: Satrajit Ghosh Date: Sat, 12 Sep 2015 11:48:55 -0400 Subject: [PATCH 29/46] Update .travis.yml --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 87224b60e5..744efcf545 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,8 +42,9 @@ deploy: provider: pypi user: satra password: - secure: ZaN6Y4hfybPMi1rW3Qe03irCe/3GU4J4BJsjG+tClVN5Fjc3FCJaYU0k4wNd9q2kMjuRDv1efA9BN/5QasJS32oqs6wHvxzIWA18ucel4BBnAAkuviC1vqi/8Hk/DGB6e1gnmZ1Nv58zVLfn0MwlOKmsGDtvGQWc+HbaV2fS5NA= + secure: OCO0FXb4f+pH4Uw7zWCIRp3qOJ1t7rhky4K8MjNU8tyVCJgd6O/Bv8GJgceS0LktPodlAAjB8SxAhTORPAQZ1D/44PJYy3NQIisvej1zjLpaA9TEGfl6W7MqhDpRyMHW+cnSi/n84SAmdr+Z4vOxScDHdwr13EPmGyOIlHMAGnE= on: tags: true repo: nipy/nipype branch: master + distributions: "sdist bdist_wheel" From 346cdc843f0301f8d52c7c6ffa4005914538d535 Mon Sep 17 00:00:00 2001 From: Mathieu Dubois Date: Fri, 30 Jan 2015 18:35:08 +0100 Subject: [PATCH 30/46] 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 31/46] 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 32/46] 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 33/46] 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 34/46] 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 35/46] 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 36/46] 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 37/46] 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 38/46] 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 39/46] 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 40/46] 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 41/46] 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 42/46] 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 43/46] 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 44/46] 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 45/46] 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 46/46] 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