diff --git a/doc/devel/matlab_example1.py b/doc/devel/matlab_example1.py index aaf6c4cb3a..9f15389669 100644 --- a/doc/devel/matlab_example1.py +++ b/doc/devel/matlab_example1.py @@ -1,13 +1,17 @@ from nipype.interfaces.matlab import MatlabCommand -from nipype.interfaces.base import TraitedSpec, \ - BaseInterface, BaseInterfaceInputSpec, File +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) + out_file = File("cmatrix.mat", usedefault=True) class ConmapTxt2MatOutputSpec(TraitedSpec): @@ -19,14 +23,15 @@ class ConmapTxt2Mat(BaseInterface): output_spec = ConmapTxt2MatOutputSpec def _run_interface(self, runtime): - d = dict(in_file=self.inputs.in_file, - out_file=self.inputs.out_file) + 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'; + script = Template( + """in_file = '$in_file'; out_file = '$out_file'; ConmapTxt2Mat(in_file, out_file); exit; - """).substitute(d) + """ + ).substitute(d) # mfile = True will create an .m file with your script and executed. # Alternatively @@ -43,5 +48,5 @@ def _run_interface(self, runtime): def _list_outputs(self): outputs = self._outputs().get() - outputs['out_file'] = os.path.abspath(self.inputs.out_file) + outputs["out_file"] = os.path.abspath(self.inputs.out_file) return outputs diff --git a/doc/devel/matlab_example2.py b/doc/devel/matlab_example2.py index 8d683ea45f..7d75e307b1 100644 --- a/doc/devel/matlab_example2.py +++ b/doc/devel/matlab_example2.py @@ -4,8 +4,7 @@ class HelloWorldInputSpec(MatlabInputSpec): - name = traits.Str(mandatory=True, - desc='Name of person to say hello to') + name = traits.Str(mandatory=True, desc="Name of person to say hello to") class HelloWorldOutputSpec(TraitedSpec): @@ -29,6 +28,7 @@ class HelloWorld(MatlabCommand): >>> out = hello.run() >>> print out.outputs.matlab_output """ + input_spec = HelloWorldInputSpec output_spec = HelloWorldOutputSpec @@ -37,7 +37,9 @@ def _my_script(self): script = """ disp('Hello %s Python') two = 1 + 1 - """ % (self.inputs.name) + """ % ( + self.inputs.name + ) return script def run(self, **inputs): diff --git a/nipype/interfaces/mrtrix/convert.py b/nipype/interfaces/mrtrix/convert.py index d09a388c33..5b62fc1daa 100644 --- a/nipype/interfaces/mrtrix/convert.py +++ b/nipype/interfaces/mrtrix/convert.py @@ -124,7 +124,9 @@ def track_gen(track_points): "Expecting %s points, found only %s" % (stream_count, n_streams) ) iflogger.error( - "Expecting %s points, found only %s", stream_count, n_streams + "Expecting %s points, found only %s", + stream_count, + n_streams, ) break pts = np.ndarray(shape=(n_pts, pt_cols), dtype=f4dt, buffer=pts_str) @@ -225,7 +227,8 @@ def _run_interface(self, runtime): self.inputs.registration_image_file ): iflogger.info( - "Applying transformation from matrix file %s", self.inputs.matrix_file + "Applying transformation from matrix file %s", + self.inputs.matrix_file, ) xfm = np.genfromtxt(self.inputs.matrix_file) iflogger.info(xfm) diff --git a/nipype/interfaces/mrtrix/defhdr.mat b/nipype/interfaces/mrtrix/defhdr.mat deleted file mode 100644 index e27ddf576f..0000000000 Binary files a/nipype/interfaces/mrtrix/defhdr.mat and /dev/null differ diff --git a/nipype/interfaces/mrtrix/preprocess.py b/nipype/interfaces/mrtrix/preprocess.py index c79f9016e9..64456460f8 100644 --- a/nipype/interfaces/mrtrix/preprocess.py +++ b/nipype/interfaces/mrtrix/preprocess.py @@ -595,7 +595,11 @@ class GenerateWhiteMatterMaskInputSpec(CommandLineInputSpec): desc="Diffusion-weighted images", ) binary_mask = File( - exists=True, argstr="%s", mandatory=True, position=-2, desc="Binary brain mask" + exists=True, + argstr="%s", + mandatory=True, + position=-2, + desc="Binary brain mask", ) out_WMProb_filename = File( genfile=True, @@ -669,7 +673,9 @@ class ErodeInputSpec(CommandLineInputSpec): argstr="-npass %s", desc="the number of passes (default: 1)" ) dilate = traits.Bool( - argstr="-dilate", position=1, desc="Perform dilation rather than erosion" + argstr="-dilate", + position=1, + desc="Perform dilation rather than erosion", ) quiet = traits.Bool( argstr="-quiet", @@ -729,7 +735,10 @@ class ThresholdInputSpec(CommandLineInputSpec): desc="The input image to be thresholded", ) out_filename = File( - genfile=True, argstr="%s", position=-1, desc="The output binary image mask." + genfile=True, + argstr="%s", + position=-1, + desc="The output binary image mask.", ) absolute_threshold_value = traits.Float( argstr="-abs %s", desc="Specify threshold value as absolute intensity." diff --git a/nipype/interfaces/mrtrix3/__init__.py b/nipype/interfaces/mrtrix3/__init__.py index 9ea9850b1b..0ff8daa510 100644 --- a/nipype/interfaces/mrtrix3/__init__.py +++ b/nipype/interfaces/mrtrix3/__init__.py @@ -2,29 +2,32 @@ # vi: set ft=python sts=4 ts=4 sw=4 et: # -*- coding: utf-8 -*- """MRTrix3 provides software tools to perform various types of diffusion MRI analyses.""" +from .connectivity import BuildConnectome, LabelConfig, LabelConvert +from .preprocess import ( + ACTPrepareFSL, + DWIBiasCorrect, + DWIDenoise, + DWIPreproc, + MRDeGibbs, + ReplaceFSwithFIRST, + ResponseSD, +) +from .reconst import ConstrainedSphericalDeconvolution, EstimateFOD, FitTensor +from .tracking import Tractography from .utils import ( - Mesh2PVE, - Generate5tt, + TCK2VTK, BrainMask, - TensorMetrics, ComputeTDI, - TCK2VTK, - MRMath, + DWIExtract, + Generate5tt, + Mesh2PVE, + MRCat, MRConvert, + MRMath, MRResize, - DWIExtract, - SHConv, + MRTransform, SH2Amp, + SHConv, + TensorMetrics, + TransformFSLConvert, ) -from .preprocess import ( - ResponseSD, - ACTPrepareFSL, - ReplaceFSwithFIRST, - DWIPreproc, - DWIDenoise, - MRDeGibbs, - DWIBiasCorrect, -) -from .tracking import Tractography -from .reconst import FitTensor, EstimateFOD, ConstrainedSphericalDeconvolution -from .connectivity import LabelConfig, LabelConvert, BuildConnectome diff --git a/nipype/interfaces/mrtrix3/base.py b/nipype/interfaces/mrtrix3/base.py index 7684e06cd7..1a4af955fb 100644 --- a/nipype/interfaces/mrtrix3/base.py +++ b/nipype/interfaces/mrtrix3/base.py @@ -2,15 +2,15 @@ # vi: set ft=python sts=4 ts=4 sw=4 et: # -*- coding: utf-8 -*- -from ... import logging, LooseVersion +from ... import LooseVersion, logging from ...utils.filemanip import which from ..base import ( - CommandLineInputSpec, CommandLine, - traits, + CommandLineInputSpec, File, - isdefined, PackageInfo, + isdefined, + traits, ) iflogger = logging.getLogger("nipype.interface") @@ -79,6 +79,15 @@ class MRTrix3BaseInputSpec(CommandLineInputSpec): exists=True, argstr="-fslgrad %s %s", desc="bvecs file in FSL format" ) in_bval = File(exists=True, desc="bvals file in FSL format") + out_bvec = File( + exists=False, + argstr="-export_grad_fsl %s %s", + desc="export bvec file in FSL format", + ) + out_bval = File( + exists=False, + desc="export bval file in FSL format", + ) class MRTrix3Base(CommandLine): @@ -96,6 +105,8 @@ def _format_arg(self, name, trait_spec, value): if name == "in_bvec": return trait_spec.argstr % (value, self.inputs.in_bval) + if name == "out_bvec": + return trait_spec.argstr % (value, self.inputs.out_bval) return super(MRTrix3Base, self)._format_arg(name, trait_spec, value) diff --git a/nipype/interfaces/mrtrix3/preprocess.py b/nipype/interfaces/mrtrix3/preprocess.py index ef67365f0b..1fcb2ce36a 100644 --- a/nipype/interfaces/mrtrix3/preprocess.py +++ b/nipype/interfaces/mrtrix3/preprocess.py @@ -19,7 +19,11 @@ class DWIDenoiseInputSpec(MRTrix3BaseInputSpec): in_file = File( - exists=True, argstr="%s", position=-2, mandatory=True, desc="input DWI image" + exists=True, + argstr="%s", + position=-2, + mandatory=True, + desc="input DWI image", ) mask = File(exists=True, argstr="-mask %s", position=1, desc="mask image") extent = traits.Tuple( @@ -88,7 +92,11 @@ class DWIDenoise(MRTrix3Base): class MRDeGibbsInputSpec(MRTrix3BaseInputSpec): in_file = File( - exists=True, argstr="%s", position=-2, mandatory=True, desc="input DWI image" + exists=True, + argstr="%s", + position=-2, + mandatory=True, + desc="input DWI image", ) axes = traits.ListInt( default_value=[0, 1], @@ -177,7 +185,11 @@ class MRDeGibbs(MRTrix3Base): class DWIBiasCorrectInputSpec(MRTrix3BaseInputSpec): in_file = File( - exists=True, argstr="%s", position=-2, mandatory=True, desc="input DWI image" + exists=True, + argstr="%s", + position=-2, + mandatory=True, + desc="input DWI image", ) in_mask = File(argstr="-mask %s", desc="input mask image for bias field estimation") use_ants = traits.Bool( @@ -245,7 +257,11 @@ def _format_arg(self, name, trait_spec, value): class DWIPreprocInputSpec(MRTrix3BaseInputSpec): in_file = File( - exists=True, argstr="%s", position=0, mandatory=True, desc="input DWI image" + exists=True, + argstr="%s", + position=0, + mandatory=True, + desc="input DWI image", ) out_file = File( "preproc.mif", @@ -292,7 +308,8 @@ class DWIPreprocInputSpec(MRTrix3BaseInputSpec): desc="Manually provide additional command-line options to the topup command", ) export_grad_mrtrix = traits.Bool( - argstr="-export_grad_mrtrix", desc="export new gradient files in mrtrix format" + argstr="-export_grad_mrtrix", + desc="export new gradient files in mrtrix format", ) export_grad_fsl = traits.Bool( argstr="-export_grad_fsl", desc="export gradient files in FSL format" @@ -387,7 +404,11 @@ class ResponseSDInputSpec(MRTrix3BaseInputSpec): desc="response estimation algorithm (multi-tissue)", ) in_file = File( - exists=True, argstr="%s", position=-5, mandatory=True, desc="input DWI image" + exists=True, + argstr="%s", + position=-5, + mandatory=True, + desc="input DWI image", ) mtt_file = File(argstr="%s", position=-4, desc="input 5tt image") wm_file = File( @@ -511,10 +532,17 @@ class ReplaceFSwithFIRSTInputSpec(CommandLineInputSpec): desc="input anatomical image", ) in_t1w = File( - exists=True, argstr="%s", mandatory=True, position=-3, desc="input T1 image" + exists=True, + argstr="%s", + mandatory=True, + position=-3, + desc="input T1 image", ) in_config = File( - exists=True, argstr="%s", position=-2, desc="connectome configuration file" + exists=True, + argstr="%s", + position=-2, + desc="connectome configuration file", ) out_file = File( diff --git a/nipype/interfaces/mrtrix3/tests/test_auto_MRCat.py b/nipype/interfaces/mrtrix3/tests/test_auto_MRCat.py new file mode 100644 index 0000000000..5659da4507 --- /dev/null +++ b/nipype/interfaces/mrtrix3/tests/test_auto_MRCat.py @@ -0,0 +1,73 @@ +# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT +from ..utils import MRCat + + +def test_MRCat_inputs(): + input_map = dict( + args=dict( + argstr="%s", + ), + axis=dict( + argstr="-axis %s", + ), + bval_scale=dict( + argstr="-bvalue_scaling %s", + ), + datatype=dict( + argstr="-datatype %s", + ), + environ=dict( + nohash=True, + usedefault=True, + ), + grad_file=dict( + argstr="-grad %s", + extensions=None, + xor=["grad_fsl"], + ), + grad_fsl=dict( + argstr="-fslgrad %s %s", + xor=["grad_file"], + ), + in_bval=dict( + extensions=None, + ), + in_bvec=dict( + argstr="-fslgrad %s %s", + extensions=None, + ), + in_files=dict( + argstr="%s", + mandatory=True, + position=-2, + ), + nthreads=dict( + argstr="-nthreads %d", + nohash=True, + ), + out_file=dict( + argstr="%s", + extensions=None, + mandatory=True, + position=-1, + usedefault=True, + ), + ) + inputs = MRCat.input_spec() + + for key, metadata in list(input_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(inputs.traits()[key], metakey) == value + + +def test_MRCat_outputs(): + output_map = dict( + out_file=dict( + extensions=None, + ), + ) + outputs = MRCat.output_spec() + + for key, metadata in list(output_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(outputs.traits()[key], metakey) == value diff --git a/nipype/interfaces/mrtrix3/tests/test_auto_MRConvert.py b/nipype/interfaces/mrtrix3/tests/test_auto_MRConvert.py index 578ffb9b1a..6c1f874273 100644 --- a/nipype/interfaces/mrtrix3/tests/test_auto_MRConvert.py +++ b/nipype/interfaces/mrtrix3/tests/test_auto_MRConvert.py @@ -44,6 +44,16 @@ def test_MRConvert_inputs(): mandatory=True, position=-2, ), + json_export=dict( + argstr="-json_export %s", + extensions=None, + mandatory=False, + ), + json_import=dict( + argstr="-json_import %s", + extensions=None, + mandatory=False, + ), nthreads=dict( argstr="-nthreads %d", nohash=True, @@ -73,6 +83,9 @@ def test_MRConvert_inputs(): def test_MRConvert_outputs(): output_map = dict( + json_export=dict( + extensions=None, + ), out_file=dict( extensions=None, ), diff --git a/nipype/interfaces/mrtrix3/tests/test_auto_MRTransform.py b/nipype/interfaces/mrtrix3/tests/test_auto_MRTransform.py new file mode 100644 index 0000000000..b50ee2c67f --- /dev/null +++ b/nipype/interfaces/mrtrix3/tests/test_auto_MRTransform.py @@ -0,0 +1,113 @@ +# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT +from ..utils import MRTransform + + +def test_MRTransform_inputs(): + input_map = dict( + args=dict( + argstr="%s", + ), + bval_scale=dict( + argstr="-bvalue_scaling %s", + ), + debug=dict( + argstr="-debug", + position=1, + ), + environ=dict( + nohash=True, + usedefault=True, + ), + flip_x=dict( + argstr="-flipx", + position=1, + ), + grad_file=dict( + argstr="-grad %s", + extensions=None, + xor=["grad_fsl"], + ), + grad_fsl=dict( + argstr="-fslgrad %s %s", + xor=["grad_file"], + ), + in_bval=dict( + extensions=None, + ), + in_bvec=dict( + argstr="-fslgrad %s %s", + extensions=None, + ), + in_files=dict( + argstr="%s", + mandatory=True, + position=-2, + ), + invert=dict( + argstr="-inverse", + position=1, + ), + linear_transform=dict( + argstr="-linear %s", + extensions=None, + position=1, + ), + nthreads=dict( + argstr="-nthreads %d", + nohash=True, + ), + out_bval=dict( + extensions=None, + ), + out_bvec=dict( + argstr="-export_grad_fsl %s %s", + extensions=None, + ), + out_file=dict( + argstr="%s", + extensions=None, + genfile=True, + position=-1, + ), + quiet=dict( + argstr="-quiet", + position=1, + ), + reference_image=dict( + argstr="-reference %s", + extensions=None, + position=1, + ), + replace_transform=dict( + argstr="-replace", + position=1, + ), + template_image=dict( + argstr="-template %s", + extensions=None, + position=1, + ), + transformation_file=dict( + argstr="-transform %s", + extensions=None, + position=1, + ), + ) + inputs = MRTransform.input_spec() + + for key, metadata in list(input_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(inputs.traits()[key], metakey) == value + + +def test_MRTransform_outputs(): + output_map = dict( + out_file=dict( + extensions=None, + ), + ) + outputs = MRTransform.output_spec() + + for key, metadata in list(output_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(outputs.traits()[key], metakey) == value diff --git a/nipype/interfaces/mrtrix3/tests/test_auto_TransformFSLConvert.py b/nipype/interfaces/mrtrix3/tests/test_auto_TransformFSLConvert.py new file mode 100644 index 0000000000..48a528a75e --- /dev/null +++ b/nipype/interfaces/mrtrix3/tests/test_auto_TransformFSLConvert.py @@ -0,0 +1,93 @@ +# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT +from ..utils import TransformFSLConvert + + +def test_TransformFSLConvert_inputs(): + input_map = dict( + args=dict( + argstr="%s", + ), + bval_scale=dict( + argstr="-bvalue_scaling %s", + ), + environ=dict( + nohash=True, + usedefault=True, + ), + flirt_import=dict( + argstr="flirt_import", + mandatory=True, + position=-2, + usedefault=True, + ), + grad_file=dict( + argstr="-grad %s", + extensions=None, + xor=["grad_fsl"], + ), + grad_fsl=dict( + argstr="-fslgrad %s %s", + xor=["grad_file"], + ), + in_bval=dict( + extensions=None, + ), + in_bvec=dict( + argstr="-fslgrad %s %s", + extensions=None, + ), + in_file=dict( + argstr="%s", + extensions=None, + mandatory=True, + position=1, + ), + in_transform=dict( + argstr="%s", + extensions=None, + mandatory=True, + position=0, + ), + nthreads=dict( + argstr="-nthreads %d", + nohash=True, + ), + out_bval=dict( + extensions=None, + ), + out_bvec=dict( + argstr="-export_grad_fsl %s %s", + extensions=None, + ), + out_transform=dict( + argstr="%s", + extensions=None, + mandatory=True, + position=-1, + usedefault=True, + ), + reference=dict( + argstr="%s", + extensions=None, + mandatory=True, + position=2, + ), + ) + inputs = TransformFSLConvert.input_spec() + + for key, metadata in list(input_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(inputs.traits()[key], metakey) == value + + +def test_TransformFSLConvert_outputs(): + output_map = dict( + out_transform=dict( + extensions=None, + ), + ) + outputs = TransformFSLConvert.output_spec() + + for key, metadata in list(output_map.items()): + for metakey, value in list(metadata.items()): + assert getattr(outputs.traits()[key], metakey) == value diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 77c3047f20..193ebb10fe 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -4,16 +4,17 @@ import os.path as op +from ...utils.filemanip import split_filename from ..base import ( - CommandLineInputSpec, CommandLine, - traits, - TraitedSpec, + CommandLineInputSpec, File, InputMultiPath, + TraitedSpec, isdefined, + traits, ) -from .base import MRTrix3BaseInputSpec, MRTrix3Base +from .base import MRTrix3Base, MRTrix3BaseInputSpec class BrainMaskInputSpec(MRTrix3BaseInputSpec): @@ -64,9 +65,108 @@ def _list_outputs(self): return outputs +class MRCatInputSpec(MRTrix3BaseInputSpec): + in_files = traits.List( + File(exists=True), + argstr="%s", + position=-2, + mandatory=True, + desc="files to concatenate", + ) + + out_file = File( + "concatenated.mif", + argstr="%s", + mandatory=True, + position=-1, + usedefault=True, + desc="output concatenated image", + ) + + axis = traits.Int( + argstr="-axis %s", + desc="""specify axis along which concatenation should be performed. By default, + the program will use the last non-singleton, non-spatial axis of any of + the input images - in other words axis 3 or whichever axis (greater than + 3) of the input images has size greater than one""", + ) + + datatype = traits.Enum( + "float32", + "float32le", + "float32be", + "float64", + "float64le", + "float64be", + "int64", + "uint64", + "int64le", + "uint64le", + "int64be", + "uint64be", + "int32", + "uint32", + "int32le", + "uint32le", + "int32be", + "uint32be", + "int16", + "uint16", + "int16le", + "uint16le", + "int16be", + "uint16be", + "cfloat32", + "cfloat32le", + "cfloat32be", + "cfloat64", + "cfloat64le", + "cfloat64be", + "int8", + "uint8", + "bit", + argstr="-datatype %s", + desc="specify output image data type", + ) + + +class MRCatOutputSpec(TraitedSpec): + out_file = File(exists=True, desc="the output concatenated image") + + +class MRCat(CommandLine): + """ + Concatenate several images into one + + + Example + ------- + + >>> import nipype.interfaces.mrtrix3 as mrt + >>> mrcat = mrt.MRCat() + >>> mrcat.inputs.in_files = ['dwi.mif','mask.mif'] + >>> mrcat.cmdline # doctest: +ELLIPSIS + 'mrcat dwi.mif mask.mif concatenated.mif' + >>> mrcat.run() # doctest: +SKIP + """ + + _cmd = "mrcat" + input_spec = MRCatInputSpec + output_spec = MRCatOutputSpec + + def _list_outputs(self): + outputs = self.output_spec().get() + outputs["out_file"] = op.abspath(self.inputs.out_file) + return outputs + + class Mesh2PVEInputSpec(CommandLineInputSpec): in_file = File( - exists=True, argstr="%s", mandatory=True, position=-3, desc="input mesh" + exists=True, + argstr="%s", + mandatory=True, + position=-3, + desc="input mesh", ) reference = File( exists=True, @@ -134,7 +234,11 @@ class Generate5ttInputSpec(MRTrix3BaseInputSpec): desc="tissue segmentation algorithm", ) in_file = File( - exists=True, argstr="%s", mandatory=True, position=-2, desc="input image" + exists=True, + argstr="%s", + mandatory=True, + position=-2, + desc="input image", ) out_file = File(argstr="%s", mandatory=True, position=-1, desc="output image") @@ -173,11 +277,20 @@ def _list_outputs(self): class TensorMetricsInputSpec(CommandLineInputSpec): in_file = File( - exists=True, argstr="%s", mandatory=True, position=-1, desc="input DTI image" + exists=True, + argstr="%s", + mandatory=True, + position=-1, + desc="input DTI image", ) out_fa = File(argstr="-fa %s", desc="output FA file") out_adc = File(argstr="-adc %s", desc="output ADC file") + out_ad = File(argstr="-ad %s", desc="output AD file") + out_rd = File(argstr="-rd %s", desc="output RD file") + out_cl = File(argstr="-cl %s", desc="output CL file") + out_cp = File(argstr="-cp %s", desc="output CP file") + out_cs = File(argstr="-cs %s", desc="output CS file") out_evec = File(argstr="-vector %s", desc="output selected eigenvector(s) file") out_eval = File(argstr="-value %s", desc="output selected eigenvalue(s) file") component = traits.List( @@ -209,6 +322,11 @@ class TensorMetricsInputSpec(CommandLineInputSpec): class TensorMetricsOutputSpec(TraitedSpec): out_fa = File(desc="output FA file") out_adc = File(desc="output ADC file") + out_ad = File(desc="output AD file") + out_rd = File(desc="output RD file") + out_cl = File(desc="output CL file") + out_cp = File(desc="output CP file") + out_cs = File(desc="output CS file") out_evec = File(desc="output selected eigenvector(s) file") out_eval = File(desc="output selected eigenvalue(s) file") @@ -246,10 +364,18 @@ def _list_outputs(self): class ComputeTDIInputSpec(CommandLineInputSpec): in_file = File( - exists=True, argstr="%s", mandatory=True, position=-2, desc="input tractography" + exists=True, + argstr="%s", + mandatory=True, + position=-2, + desc="input tractography", ) out_file = File( - "tdi.mif", argstr="%s", usedefault=True, position=-1, desc="output TDI file" + "tdi.mif", + argstr="%s", + usedefault=True, + position=-1, + desc="output TDI file", ) reference = File( exists=True, @@ -353,7 +479,8 @@ class ComputeTDIInputSpec(CommandLineInputSpec): "(these lengths are then taken into account during TWI calculation)", ) ends_only = traits.Bool( - argstr="-ends_only", desc="only map the streamline" " endpoints to the image" + argstr="-ends_only", + desc="only map the streamline" " endpoints to the image", ) tck_weights = File( @@ -438,10 +565,18 @@ def _list_outputs(self): class TCK2VTKInputSpec(CommandLineInputSpec): in_file = File( - exists=True, argstr="%s", mandatory=True, position=-2, desc="input tractography" + exists=True, + argstr="%s", + mandatory=True, + position=-2, + desc="input tractography", ) out_file = File( - "tracks.vtk", argstr="%s", usedefault=True, position=-1, desc="output VTK file" + "tracks.vtk", + argstr="%s", + usedefault=True, + position=-1, + desc="output VTK file", ) reference = File( exists=True, @@ -498,7 +633,11 @@ def _list_outputs(self): class DWIExtractInputSpec(MRTrix3BaseInputSpec): in_file = File( - exists=True, argstr="%s", mandatory=True, position=-2, desc="input image" + exists=True, + argstr="%s", + mandatory=True, + position=-2, + desc="input image", ) out_file = File(argstr="%s", mandatory=True, position=-1, desc="output image") bzero = traits.Bool(argstr="-bzero", desc="extract b=0 volumes") @@ -549,7 +688,11 @@ def _list_outputs(self): class MRConvertInputSpec(MRTrix3BaseInputSpec): in_file = File( - exists=True, argstr="%s", mandatory=True, position=-2, desc="input image" + exists=True, + argstr="%s", + mandatory=True, + position=-2, + desc="input image", ) out_file = File( "dwi.mif", @@ -559,6 +702,7 @@ class MRConvertInputSpec(MRTrix3BaseInputSpec): usedefault=True, desc="output image", ) + coord = traits.List( traits.Int, sep=" ", @@ -566,7 +710,10 @@ class MRConvertInputSpec(MRTrix3BaseInputSpec): desc="extract data at the specified coordinates", ) vox = traits.List( - traits.Float, sep=",", argstr="-vox %s", desc="change the voxel dimensions" + traits.Float, + sep=",", + argstr="-vox %s", + desc="change the voxel dimensions", ) axes = traits.List( traits.Int, @@ -580,10 +727,28 @@ class MRConvertInputSpec(MRTrix3BaseInputSpec): argstr="-scaling %s", desc="specify the data scaling parameter", ) + json_import = File( + exists=True, + argstr="-json_import %s", + mandatory=False, + desc="import data from a JSON file into header key-value pairs", + ) + json_export = File( + exists=False, + argstr="-json_export %s", + mandatory=False, + desc="export data from an image header key-value pairs into a JSON file", + ) class MRConvertOutputSpec(TraitedSpec): out_file = File(exists=True, desc="output image") + json_export = File( + exists=True, + desc="exported data from an image header key-value pairs in a JSON file", + ) + out_bvec = File(exists=True, desc="export bvec file in FSL format") + out_bval = File(exists=True, desc="export bvec file in FSL format") class MRConvert(MRTrix3Base): @@ -610,12 +775,189 @@ class MRConvert(MRTrix3Base): def _list_outputs(self): outputs = self.output_spec().get() outputs["out_file"] = op.abspath(self.inputs.out_file) + if self.inputs.json_export: + outputs["json_export"] = op.abspath(self.inputs.json_export) + if self.inputs.out_bvec: + outputs["out_bvec"] = op.abspath(self.inputs.out_bvec) + if self.inputs.out_bval: + outputs["out_bval"] = op.abspath(self.inputs.out_bval) return outputs +class TransformFSLConvertInputSpec(MRTrix3BaseInputSpec): + in_file = File( + exists=True, + argstr="%s", + mandatory=True, + position=1, + desc="FLIRT input image", + ) + reference = File( + exists=True, + argstr="%s", + mandatory=True, + position=2, + desc="FLIRT reference image", + ) + in_transform = File( + exists=True, + argstr="%s", + mandatory=True, + position=0, + desc="FLIRT output transformation matrix", + ) + out_transform = File( + "transform_mrtrix.txt", + argstr="%s", + mandatory=True, + position=-1, + usedefault=True, + desc="output transformed affine in mrtrix3's format", + ) + flirt_import = traits.Bool( + True, + argstr="flirt_import", + mandatory=True, + usedefault=True, + position=-2, + desc="import transform from FSL's FLIRT.", + ) + + +class TransformFSLConvertOutputSpec(TraitedSpec): + out_transform = File( + exists=True, desc="output transformed affine in mrtrix3's format" + ) + + +class TransformFSLConvert(MRTrix3Base): + """ + Perform conversion between FSL's transformation matrix format to mrtrix3's. + """ + + _cmd = "transformconvert" + input_spec = TransformFSLConvertInputSpec + output_spec = TransformFSLConvertOutputSpec + + def _list_outputs(self): + outputs = self.output_spec().get() + outputs["out_transform"] = op.abspath(self.inputs.out_transform) + return outputs + + +class MRTransformInputSpec(MRTrix3BaseInputSpec): + in_files = InputMultiPath( + File(exists=True), + argstr="%s", + mandatory=True, + position=-2, + desc="Input images to be transformed", + ) + out_file = File( + genfile=True, + argstr="%s", + position=-1, + desc="Output image", + ) + invert = traits.Bool( + argstr="-inverse", + position=1, + desc="Invert the specified transform before using it", + ) + linear_transform = File( + exists=True, + argstr="-linear %s", + position=1, + desc=( + "Specify a linear transform to apply, in the form of a 3x4 or 4x4 ascii file. " + "Note the standard reverse convention is used, " + "where the transform maps points in the template image to the moving image. " + "Note that the reverse convention is still assumed even if no -template image is supplied." + ), + ) + replace_transform = traits.Bool( + argstr="-replace", + position=1, + desc="replace the current transform by that specified, rather than applying it to the current transform", + ) + transformation_file = File( + exists=True, + argstr="-transform %s", + position=1, + desc="The transform to apply, in the form of a 4x4 ascii file.", + ) + template_image = File( + exists=True, + argstr="-template %s", + position=1, + desc="Reslice the input image to match the specified template image.", + ) + reference_image = File( + exists=True, + argstr="-reference %s", + position=1, + desc="in case the transform supplied maps from the input image onto a reference image, use this option to specify the reference. Note that this implicitly sets the -replace option.", + ) + flip_x = traits.Bool( + argstr="-flipx", + position=1, + desc="assume the transform is supplied assuming a coordinate system with the x-axis reversed relative to the MRtrix convention (i.e. x increases from right to left). This is required to handle transform matrices produced by FSL's FLIRT command. This is only used in conjunction with the -reference option.", + ) + quiet = traits.Bool( + argstr="-quiet", + position=1, + desc="Do not display information messages or progress status.", + ) + debug = traits.Bool(argstr="-debug", position=1, desc="Display debugging messages.") + + +class MRTransformOutputSpec(TraitedSpec): + out_file = File(exists=True, desc="the output image of the transformation") + + +class MRTransform(MRTrix3Base): + """ + Apply spatial transformations or reslice images + + Example + ------- + + >>> MRxform = MRTransform() + >>> MRxform.inputs.in_files = 'anat_coreg.mif' + >>> MRxform.run() # doctest: +SKIP + """ + + _cmd = "mrtransform" + input_spec = MRTransformInputSpec + output_spec = MRTransformOutputSpec + + def _list_outputs(self): + outputs = self.output_spec().get() + outputs["out_file"] = self.inputs.out_file + if not isdefined(outputs["out_file"]): + outputs["out_file"] = op.abspath(self._gen_outfilename()) + else: + outputs["out_file"] = op.abspath(outputs["out_file"]) + return outputs + + def _gen_filename(self, name): + if name == "out_file": + return self._gen_outfilename() + else: + return None + + def _gen_outfilename(self): + _, name, _ = split_filename(self.inputs.in_files[0]) + return name + "_MRTransform.mif" + + class MRMathInputSpec(MRTrix3BaseInputSpec): in_file = File( - exists=True, argstr="%s", mandatory=True, position=-3, desc="input image" + exists=True, + argstr="%s", + mandatory=True, + position=-3, + desc="input image", ) out_file = File(argstr="%s", mandatory=True, position=-1, desc="output image") operation = traits.Enum( @@ -637,7 +979,9 @@ class MRMathInputSpec(MRTrix3BaseInputSpec): desc="operation to computer along a specified axis", ) axis = traits.Int( - 0, argstr="-axis %d", desc="specfied axis to perform the operation along" + 0, + argstr="-axis %d", + desc="specfied axis to perform the operation along", ) @@ -677,7 +1021,11 @@ def _list_outputs(self): class MRResizeInputSpec(MRTrix3BaseInputSpec): in_file = File( - exists=True, argstr="%s", position=-2, mandatory=True, desc="input DWI image" + exists=True, + argstr="%s", + position=-2, + mandatory=True, + desc="input DWI image", ) image_size = traits.Tuple( (traits.Int, traits.Int, traits.Int), diff --git a/tools/checkspecs.py b/tools/checkspecs.py index 032fd122cc..f57502aa42 100644 --- a/tools/checkspecs.py +++ b/tools/checkspecs.py @@ -13,8 +13,7 @@ # Functions and classes class InterfaceChecker(object): - """Class for checking all interface specifications - """ + """Class for checking all interface specifications""" def __init__( self, @@ -23,7 +22,7 @@ def __init__( module_skip_patterns=None, class_skip_patterns=None, ): - r""" Initialize package for parsing + r"""Initialize package for parsing Parameters ---------- @@ -387,7 +386,7 @@ def test_specs(self, uri): return bad_specs def _survives_exclude(self, matchstr, match_type): - """ Returns True if *matchstr* does not match patterns + """Returns True if *matchstr* does not match patterns ``self.package_name`` removed from front of string if present @@ -429,7 +428,7 @@ def _survives_exclude(self, matchstr, match_type): return True def discover_modules(self): - """ Return module sequence discovered from ``self.package_name`` + """Return module sequence discovered from ``self.package_name`` Parameters diff --git a/tools/gitwash_dumper.py b/tools/gitwash_dumper.py index 36efd7f83e..2c08547bac 100755 --- a/tools/gitwash_dumper.py +++ b/tools/gitwash_dumper.py @@ -50,9 +50,7 @@ def cp_files(in_path, globs, out_path): def filename_search_replace(sr_pairs, filename, backup=False): - """ Search and replace for expressions in files - - """ + """Search and replace for expressions in files""" in_txt = open(filename, "rt").read(-1) out_txt = in_txt[:] for in_exp, out_exp in sr_pairs: @@ -94,7 +92,7 @@ def make_link_targets( url=None, ml_url=None, ): - """ Check and make link targets + """Check and make link targets If url is None or ml_url is None, check if there are links present for these in `known_link_fname`. If not, raise error. The check is: diff --git a/tools/run_examples.py b/tools/run_examples.py index 20382ef74d..bd77f1a0a4 100644 --- a/tools/run_examples.py +++ b/tools/run_examples.py @@ -4,9 +4,15 @@ if __name__ == "__main__": - print(dedent("""Nipype examples have been moved to niflow-nipype1-examples. + print( + dedent( + """Nipype examples have been moved to niflow-nipype1-examples. -Install with: pip install niflow-nipype1-examples""")) +Install with: pip install niflow-nipype1-examples""" + ) + ) if sys.argv[1:]: - print("Run this command with: niflow-nipype1-examples " + " ".join(sys.argv[1:])) + print( + "Run this command with: niflow-nipype1-examples " + " ".join(sys.argv[1:]) + ) sys.exit(1) diff --git a/tools/toollib.py b/tools/toollib.py index 77d864f142..e740787575 100644 --- a/tools/toollib.py +++ b/tools/toollib.py @@ -31,7 +31,9 @@ def sh(cmd): def compile_tree(): """Compile all Python files below current directory.""" vstr = ".".join(map(str, sys.version_info[:2])) - stat = os.system("%s %s/lib/python%s/compileall.py ." % (sys.executable, sys.prefix, vstr)) + stat = os.system( + "%s %s/lib/python%s/compileall.py ." % (sys.executable, sys.prefix, vstr) + ) if stat: msg = "*** ERROR: Some Python files in tree do NOT compile! ***\n" msg += "See messages above for the actual file that produced it.\n"