From 8e952443d375bc1dbf0fafa579e7a6add2cc7a82 Mon Sep 17 00:00:00 2001 From: Michael Joseph Date: Sun, 15 Sep 2019 07:33:35 -0400 Subject: [PATCH 1/7] add mrresize --- nipype/interfaces/mrtrix3/__init__.py | 3 +- .../mrtrix3/tests/test_auto_MRResize.py | 74 +++++++++++++++++ nipype/interfaces/mrtrix3/utils.py | 83 +++++++++++++++++++ 3 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 nipype/interfaces/mrtrix3/tests/test_auto_MRResize.py diff --git a/nipype/interfaces/mrtrix3/__init__.py b/nipype/interfaces/mrtrix3/__init__.py index c9c131dde3..87b12e7442 100644 --- a/nipype/interfaces/mrtrix3/__init__.py +++ b/nipype/interfaces/mrtrix3/__init__.py @@ -4,7 +4,8 @@ # -*- coding: utf-8 -*- from .utils import (Mesh2PVE, Generate5tt, BrainMask, TensorMetrics, - ComputeTDI, TCK2VTK, MRMath, MRConvert, DWIExtract) + ComputeTDI, TCK2VTK, MRMath, MRConvert, MRResize, + DWIExtract) from .preprocess import (ResponseSD, ACTPrepareFSL, ReplaceFSwithFIRST, DWIDenoise, MRDeGibbs, DWIBiasCorrect) from .tracking import Tractography diff --git a/nipype/interfaces/mrtrix3/tests/test_auto_MRResize.py b/nipype/interfaces/mrtrix3/tests/test_auto_MRResize.py new file mode 100644 index 0000000000..448d7809db --- /dev/null +++ b/nipype/interfaces/mrtrix3/tests/test_auto_MRResize.py @@ -0,0 +1,74 @@ +# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT +from __future__ import unicode_literals +from ..utils import MRResize + + +def test_MRResize_inputs(): + input_map = dict( + args=dict(argstr='%s', ), + bval_scale=dict(argstr='-bvalue_scaling %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'], + ), + image_size=dict( + argstr='-size %d,%d,%d', + mandatory=True, + xor=['voxel_size', 'scale_factor'], + ), + in_bval=dict(extensions=None, ), + in_bvec=dict( + argstr='-fslgrad %s %s', + extensions=None, + ), + in_file=dict( + argstr='%s', + extensions=None, + mandatory=True, + position=-2, + ), + interp=dict(argstr='-interp %s', ), + nthreads=dict( + argstr='-nthreads %d', + nohash=True, + ), + out_file=dict( + argstr='%s', + extensions=None, + keep_extension=True, + name_source=['in_file'], + name_template='%s_resized', + position=-1, + ), + scale_factor=dict( + argstr='-scale %d,%d,%d', + mandatory=True, + xor=['image_size', 'voxel_size'], + ), + voxel_size=dict( + argstr='-voxel %d,%d,%d', + mandatory=True, + xor=['image_size', 'scale_factor'], + ), + ) + inputs = MRResize.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_MRResize_outputs(): + output_map = dict(out_file=dict(extensions=None, ), ) + outputs = MRResize.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 a667c716f4..b97ca900c2 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -677,3 +677,86 @@ def _list_outputs(self): outputs = self.output_spec().get() outputs['out_file'] = op.abspath(self.inputs.out_file) return outputs + + +class MRResizeInputSpec(MRTrix3BaseInputSpec): + in_file = File( + exists=True, + argstr='%s', + position=-2, + mandatory=True, + desc='input DWI image' + ) + image_size = traits.Tuple( + (traits.Int, traits.Int, traits.Int), + argstr='-size %d,%d,%d', + mandatory=True, + desc='define the new image size for the output image. This should be ' + 'specified as a comma-separated list.', + xor=['voxel_size', 'scale_factor'], + ) + voxel_size = traits.Tuple( + (traits.Float, traits.Float, traits.Float), + argstr='-voxel %d,%d,%d', + mandatory=True, + desc='define the new voxel size for the output image. This can be ' + 'specified either as a single value to be used for all ' + 'dimensions, or as a comma-separated list of the size for each ' + 'voxel dimension.', + xor=['image_size', 'scale_factor'], + ) + scale_factor = traits.Tuple( + (traits.Float, traits.Float, traits.Float), + argstr='-scale %d,%d,%d', + mandatory=True, + desc='scale the image resolution by the supplied factor. This can be ' + 'specified either as a single value to be used for all ' + 'dimensions, or as a comma-separated list of scale factors for ' + 'each dimension.', + xor=['image_size', 'voxel_size'], + ) + interp = traits.Enum( + 'cubic', + 'nearest', + 'linear', + 'sinc', + argstr='-interp %s', + desc='set the interpolation method to use when resizing (choices: ' + 'nearest, linear, cubic, sinc. Default: cubic).', + ) + out_file = File( + argstr='%s', + name_template='%s_resized', + name_source=['in_file'], + keep_extension=True, + position=-1, + desc='the output resized DWI image', + ) + + +class MRResizeOutputSpec(TraitedSpec): + out_file = File(desc='the output resized DWI image', exists=True) + + +class MRResize(MRTrix3Base): + """ + Resize an image by defining the new image resolution, voxel size or a + scale factor. If the image is 4D, then only the first 3 dimensions can be + resized. Also, if the image is down-sampled, the appropriate smoothing is + automatically applied using Gaussian smoothing. + For more information, see + + Example + ------- + >>> import nipype.interfaces.mrtrix3 as mrt + >>> resize = mrt.MRResize() + >>> resize.inputs.in_file = 'dwi.mif' + >>> resize.inputs.voxel_size = (1, 1, 1) + >>> resize.cmdline # doctest: +ELLIPSIS + 'mrresize -voxel 1,1,1 dwi.mif dwi_resized.mif' + >>> resize.run() # doctest: +SKIP + """ + + _cmd = 'mrresize' + input_spec = MRResizeInputSpec + output_spec = MRResizeOutputSpec From d38f71c10fd1cff6d3509509da905de2db6d382a Mon Sep 17 00:00:00 2001 From: Michael Joseph Date: Mon, 16 Sep 2019 10:35:43 -0400 Subject: [PATCH 2/7] Apply suggestions from code review Co-Authored-By: Chris Markiewicz --- nipype/interfaces/mrtrix3/utils.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index b97ca900c2..caacf41911 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -692,12 +692,11 @@ class MRResizeInputSpec(MRTrix3BaseInputSpec): argstr='-size %d,%d,%d', mandatory=True, desc='define the new image size for the output image. This should be ' - 'specified as a comma-separated list.', xor=['voxel_size', 'scale_factor'], ) voxel_size = traits.Tuple( (traits.Float, traits.Float, traits.Float), - argstr='-voxel %d,%d,%d', + argstr='-voxel %g,%g,%g', mandatory=True, desc='define the new voxel size for the output image. This can be ' 'specified either as a single value to be used for all ' @@ -707,7 +706,7 @@ class MRResizeInputSpec(MRTrix3BaseInputSpec): ) scale_factor = traits.Tuple( (traits.Float, traits.Float, traits.Float), - argstr='-scale %d,%d,%d', + argstr='-scale %g,%g,%g', mandatory=True, desc='scale the image resolution by the supplied factor. This can be ' 'specified either as a single value to be used for all ' @@ -715,7 +714,7 @@ class MRResizeInputSpec(MRTrix3BaseInputSpec): 'each dimension.', xor=['image_size', 'voxel_size'], ) - interp = traits.Enum( + interpolation = traits.Enum( 'cubic', 'nearest', 'linear', @@ -746,6 +745,7 @@ class MRResize(MRTrix3Base): automatically applied using Gaussian smoothing. For more information, see + Example ------- >>> import nipype.interfaces.mrtrix3 as mrt From 270de321fa5450464f717ec43aaf4a97562e8b68 Mon Sep 17 00:00:00 2001 From: Michael Joseph Date: Mon, 16 Sep 2019 10:37:30 -0400 Subject: [PATCH 3/7] Apply suggestions from code review Co-Authored-By: Chris Markiewicz --- nipype/interfaces/mrtrix3/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index caacf41911..e55c23475b 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -691,7 +691,7 @@ class MRResizeInputSpec(MRTrix3BaseInputSpec): (traits.Int, traits.Int, traits.Int), argstr='-size %d,%d,%d', mandatory=True, - desc='define the new image size for the output image. This should be ' + desc='Number of voxels in each dimension of output image' xor=['voxel_size', 'scale_factor'], ) voxel_size = traits.Tuple( From 1327e5bc1ad4d70051318de1ec9a3b32e35de9df Mon Sep 17 00:00:00 2001 From: Michael Joseph Date: Mon, 16 Sep 2019 10:39:04 -0400 Subject: [PATCH 4/7] Apply suggestions from code review Co-Authored-By: Chris Markiewicz --- nipype/interfaces/mrtrix3/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index e55c23475b..c4be5b6211 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -720,6 +720,7 @@ class MRResizeInputSpec(MRTrix3BaseInputSpec): 'linear', 'sinc', argstr='-interp %s', + usedefault=True, desc='set the interpolation method to use when resizing (choices: ' 'nearest, linear, cubic, sinc. Default: cubic).', ) From 0f0924a76c7086ab2054ea71d42c472e4267bd0c Mon Sep 17 00:00:00 2001 From: mjoseph Date: Mon, 16 Sep 2019 11:25:12 -0400 Subject: [PATCH 5/7] include multiple examples --- nipype/interfaces/mrtrix3/utils.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index c4be5b6211..81060b5669 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -698,20 +698,14 @@ class MRResizeInputSpec(MRTrix3BaseInputSpec): (traits.Float, traits.Float, traits.Float), argstr='-voxel %g,%g,%g', mandatory=True, - desc='define the new voxel size for the output image. This can be ' - 'specified either as a single value to be used for all ' - 'dimensions, or as a comma-separated list of the size for each ' - 'voxel dimension.', + desc='Desired voxel size in mm for the output image', xor=['image_size', 'scale_factor'], ) scale_factor = traits.Tuple( (traits.Float, traits.Float, traits.Float), argstr='-scale %g,%g,%g', mandatory=True, - desc='scale the image resolution by the supplied factor. This can be ' - 'specified either as a single value to be used for all ' - 'dimensions, or as a comma-separated list of scale factors for ' - 'each dimension.', + desc='Scale factors to rescale the image by in each dimension', xor=['image_size', 'voxel_size'], ) interpolation = traits.Enum( @@ -752,9 +746,17 @@ class MRResize(MRTrix3Base): >>> import nipype.interfaces.mrtrix3 as mrt >>> resize = mrt.MRResize() >>> resize.inputs.in_file = 'dwi.mif' + >>> resize.inputs.image_size = (256, 256, 144) + >>> resize.cmdline # doctest: +ELLIPSIS + 'mrresize -interp cubic -size 256,256,144 dwi.mif dwi_resized.mif' + >>> resize.run() # doctest: +SKIP >>> resize.inputs.voxel_size = (1, 1, 1) >>> resize.cmdline # doctest: +ELLIPSIS - 'mrresize -voxel 1,1,1 dwi.mif dwi_resized.mif' + 'mrresize -interp cubic -voxel 1,1,1 dwi.mif dwi_resized.mif' + >>> resize.run() # doctest: +SKIP + >>> resize.inputs.scale_factor = (2.0,2.0,2.0) + >>> resize.cmdline # doctest: +ELLIPSIS + 'mrresize -interp cubic -scale 2.0,2.0,2.0 dwi.mif dwi_resized.mif' >>> resize.run() # doctest: +SKIP """ From 593aea8ece337522cd0ecfb0daf77a4dbcc1ba68 Mon Sep 17 00:00:00 2001 From: mjoseph Date: Mon, 16 Sep 2019 14:30:55 -0400 Subject: [PATCH 6/7] update doctests --- nipype/interfaces/mrtrix3/utils.py | 38 +++++++++++++++++++----------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/nipype/interfaces/mrtrix3/utils.py b/nipype/interfaces/mrtrix3/utils.py index 81060b5669..52122189bf 100644 --- a/nipype/interfaces/mrtrix3/utils.py +++ b/nipype/interfaces/mrtrix3/utils.py @@ -691,7 +691,7 @@ class MRResizeInputSpec(MRTrix3BaseInputSpec): (traits.Int, traits.Int, traits.Int), argstr='-size %d,%d,%d', mandatory=True, - desc='Number of voxels in each dimension of output image' + desc='Number of voxels in each dimension of output image', xor=['voxel_size', 'scale_factor'], ) voxel_size = traits.Tuple( @@ -744,20 +744,30 @@ class MRResize(MRTrix3Base): Example ------- >>> import nipype.interfaces.mrtrix3 as mrt - >>> resize = mrt.MRResize() - >>> resize.inputs.in_file = 'dwi.mif' - >>> resize.inputs.image_size = (256, 256, 144) - >>> resize.cmdline # doctest: +ELLIPSIS - 'mrresize -interp cubic -size 256,256,144 dwi.mif dwi_resized.mif' - >>> resize.run() # doctest: +SKIP - >>> resize.inputs.voxel_size = (1, 1, 1) - >>> resize.cmdline # doctest: +ELLIPSIS + + Defining the new image resolution: + >>> image_resize = mrt.MRResize() + >>> image_resize.inputs.in_file = 'dwi.mif' + >>> image_resize.inputs.image_size = (256, 256, 144) + >>> image_resize.cmdline # doctest: +ELLIPSIS + 'mrresize -size 256,256,144 -interp cubic dwi.mif dwi_resized.mif' + >>> image_resize.run() # doctest: +SKIP + + Defining the new image's voxel size: + >>> voxel_resize = mrt.MRResize() + >>> voxel_resize.inputs.in_file = 'dwi.mif' + >>> voxel_resize.inputs.voxel_size = (1, 1, 1) + >>> voxel_resize.cmdline # doctest: +ELLIPSIS 'mrresize -interp cubic -voxel 1,1,1 dwi.mif dwi_resized.mif' - >>> resize.run() # doctest: +SKIP - >>> resize.inputs.scale_factor = (2.0,2.0,2.0) - >>> resize.cmdline # doctest: +ELLIPSIS - 'mrresize -interp cubic -scale 2.0,2.0,2.0 dwi.mif dwi_resized.mif' - >>> resize.run() # doctest: +SKIP + >>> voxel_resize.run() # doctest: +SKIP + + Defining the scale factor of each image dimension: + >>> scale_resize = mrt.MRResize() + >>> scale_resize.inputs.in_file = 'dwi.mif' + >>> scale_resize.inputs.scale_factor = (0.5,0.5,0.5) + >>> scale_resize.cmdline # doctest: +ELLIPSIS + 'mrresize -interp cubic -scale 0.5,0.5,0.5 dwi.mif dwi_resized.mif' + >>> scale_resize.run() # doctest: +SKIP """ _cmd = 'mrresize' From 57e83fdc70d14f89356deb75fa525749aa7eba23 Mon Sep 17 00:00:00 2001 From: Michael Joseph Date: Mon, 16 Sep 2019 15:47:58 -0400 Subject: [PATCH 7/7] update test --- nipype/interfaces/mrtrix3/tests/test_auto_MRResize.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/mrtrix3/tests/test_auto_MRResize.py b/nipype/interfaces/mrtrix3/tests/test_auto_MRResize.py index 448d7809db..a81528d44a 100644 --- a/nipype/interfaces/mrtrix3/tests/test_auto_MRResize.py +++ b/nipype/interfaces/mrtrix3/tests/test_auto_MRResize.py @@ -36,7 +36,10 @@ def test_MRResize_inputs(): mandatory=True, position=-2, ), - interp=dict(argstr='-interp %s', ), + interpolation=dict( + argstr='-interp %s', + usedefault=True, + ), nthreads=dict( argstr='-nthreads %d', nohash=True, @@ -50,12 +53,12 @@ def test_MRResize_inputs(): position=-1, ), scale_factor=dict( - argstr='-scale %d,%d,%d', + argstr='-scale %g,%g,%g', mandatory=True, xor=['image_size', 'voxel_size'], ), voxel_size=dict( - argstr='-voxel %d,%d,%d', + argstr='-voxel %g,%g,%g', mandatory=True, xor=['image_size', 'scale_factor'], ),