Skip to content

Commit ead0dcb

Browse files
committed
Merge branch 'master' of https://github.com/nipy/nipype
2 parents 68a8bf6 + 23379eb commit ead0dcb

File tree

6 files changed

+191
-14
lines changed

6 files changed

+191
-14
lines changed

nipype/interfaces/afni/utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,9 @@ class CatMatvec(AFNICommand):
619619

620620
def _format_arg(self, name, spec, value):
621621
if name == 'in_file':
622-
return spec.argstr % (' '.join([i[0] + ' -' + i[1]
623-
for i in value]))
622+
# Concatenate a series of filenames, with optional opkeys
623+
return ' '.join('%s -%s' % (mfile, opkey) if opkey else mfile
624+
for mfile, opkey in value)
624625
return super(CatMatvec, self)._format_arg(name, spec, value)
625626

626627

nipype/interfaces/base/core.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -476,9 +476,9 @@ def aggregate_outputs(self, runtime=None, needed_outputs=None):
476476
setattr(outputs, key, val)
477477
except TraitError as error:
478478
if 'an existing' in getattr(error, 'info', 'default'):
479-
msg = "No such file or directory for output '%s' of a %s interface" % \
480-
(key, self.__class__.__name__)
481-
raise FileNotFoundError(val, message=msg)
479+
msg = "No such file or directory '%s' for output '%s' of a %s interface" % \
480+
(val, key, self.__class__.__name__)
481+
raise FileNotFoundError(msg)
482482
raise error
483483
return outputs
484484

nipype/interfaces/mrtrix3/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
# -*- coding: utf-8 -*-
55

66
from .utils import (Mesh2PVE, Generate5tt, BrainMask, TensorMetrics,
7-
ComputeTDI, TCK2VTK, MRMath, MRConvert, DWIExtract)
7+
ComputeTDI, TCK2VTK, MRMath, MRConvert, MRResize,
8+
DWIExtract)
89
from .preprocess import (ResponseSD, ACTPrepareFSL, ReplaceFSwithFIRST,
910
DWIDenoise, MRDeGibbs, DWIBiasCorrect)
1011
from .tracking import Tractography
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
2+
from __future__ import unicode_literals
3+
from ..utils import MRResize
4+
5+
6+
def test_MRResize_inputs():
7+
input_map = dict(
8+
args=dict(argstr='%s', ),
9+
bval_scale=dict(argstr='-bvalue_scaling %s', ),
10+
environ=dict(
11+
nohash=True,
12+
usedefault=True,
13+
),
14+
grad_file=dict(
15+
argstr='-grad %s',
16+
extensions=None,
17+
xor=['grad_fsl'],
18+
),
19+
grad_fsl=dict(
20+
argstr='-fslgrad %s %s',
21+
xor=['grad_file'],
22+
),
23+
image_size=dict(
24+
argstr='-size %d,%d,%d',
25+
mandatory=True,
26+
xor=['voxel_size', 'scale_factor'],
27+
),
28+
in_bval=dict(extensions=None, ),
29+
in_bvec=dict(
30+
argstr='-fslgrad %s %s',
31+
extensions=None,
32+
),
33+
in_file=dict(
34+
argstr='%s',
35+
extensions=None,
36+
mandatory=True,
37+
position=-2,
38+
),
39+
interpolation=dict(
40+
argstr='-interp %s',
41+
usedefault=True,
42+
),
43+
nthreads=dict(
44+
argstr='-nthreads %d',
45+
nohash=True,
46+
),
47+
out_file=dict(
48+
argstr='%s',
49+
extensions=None,
50+
keep_extension=True,
51+
name_source=['in_file'],
52+
name_template='%s_resized',
53+
position=-1,
54+
),
55+
scale_factor=dict(
56+
argstr='-scale %g,%g,%g',
57+
mandatory=True,
58+
xor=['image_size', 'voxel_size'],
59+
),
60+
voxel_size=dict(
61+
argstr='-voxel %g,%g,%g',
62+
mandatory=True,
63+
xor=['image_size', 'scale_factor'],
64+
),
65+
)
66+
inputs = MRResize.input_spec()
67+
68+
for key, metadata in list(input_map.items()):
69+
for metakey, value in list(metadata.items()):
70+
assert getattr(inputs.traits()[key], metakey) == value
71+
def test_MRResize_outputs():
72+
output_map = dict(out_file=dict(extensions=None, ), )
73+
outputs = MRResize.output_spec()
74+
75+
for key, metadata in list(output_map.items()):
76+
for metakey, value in list(metadata.items()):
77+
assert getattr(outputs.traits()[key], metakey) == value

nipype/interfaces/mrtrix3/utils.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,3 +677,99 @@ def _list_outputs(self):
677677
outputs = self.output_spec().get()
678678
outputs['out_file'] = op.abspath(self.inputs.out_file)
679679
return outputs
680+
681+
682+
class MRResizeInputSpec(MRTrix3BaseInputSpec):
683+
in_file = File(
684+
exists=True,
685+
argstr='%s',
686+
position=-2,
687+
mandatory=True,
688+
desc='input DWI image'
689+
)
690+
image_size = traits.Tuple(
691+
(traits.Int, traits.Int, traits.Int),
692+
argstr='-size %d,%d,%d',
693+
mandatory=True,
694+
desc='Number of voxels in each dimension of output image',
695+
xor=['voxel_size', 'scale_factor'],
696+
)
697+
voxel_size = traits.Tuple(
698+
(traits.Float, traits.Float, traits.Float),
699+
argstr='-voxel %g,%g,%g',
700+
mandatory=True,
701+
desc='Desired voxel size in mm for the output image',
702+
xor=['image_size', 'scale_factor'],
703+
)
704+
scale_factor = traits.Tuple(
705+
(traits.Float, traits.Float, traits.Float),
706+
argstr='-scale %g,%g,%g',
707+
mandatory=True,
708+
desc='Scale factors to rescale the image by in each dimension',
709+
xor=['image_size', 'voxel_size'],
710+
)
711+
interpolation = traits.Enum(
712+
'cubic',
713+
'nearest',
714+
'linear',
715+
'sinc',
716+
argstr='-interp %s',
717+
usedefault=True,
718+
desc='set the interpolation method to use when resizing (choices: '
719+
'nearest, linear, cubic, sinc. Default: cubic).',
720+
)
721+
out_file = File(
722+
argstr='%s',
723+
name_template='%s_resized',
724+
name_source=['in_file'],
725+
keep_extension=True,
726+
position=-1,
727+
desc='the output resized DWI image',
728+
)
729+
730+
731+
class MRResizeOutputSpec(TraitedSpec):
732+
out_file = File(desc='the output resized DWI image', exists=True)
733+
734+
735+
class MRResize(MRTrix3Base):
736+
"""
737+
Resize an image by defining the new image resolution, voxel size or a
738+
scale factor. If the image is 4D, then only the first 3 dimensions can be
739+
resized. Also, if the image is down-sampled, the appropriate smoothing is
740+
automatically applied using Gaussian smoothing.
741+
For more information, see
742+
<https://mrtrix.readthedocs.io/en/latest/reference/commands/mrresize.html>
743+
744+
Example
745+
-------
746+
>>> import nipype.interfaces.mrtrix3 as mrt
747+
748+
Defining the new image resolution:
749+
>>> image_resize = mrt.MRResize()
750+
>>> image_resize.inputs.in_file = 'dwi.mif'
751+
>>> image_resize.inputs.image_size = (256, 256, 144)
752+
>>> image_resize.cmdline # doctest: +ELLIPSIS
753+
'mrresize -size 256,256,144 -interp cubic dwi.mif dwi_resized.mif'
754+
>>> image_resize.run() # doctest: +SKIP
755+
756+
Defining the new image's voxel size:
757+
>>> voxel_resize = mrt.MRResize()
758+
>>> voxel_resize.inputs.in_file = 'dwi.mif'
759+
>>> voxel_resize.inputs.voxel_size = (1, 1, 1)
760+
>>> voxel_resize.cmdline # doctest: +ELLIPSIS
761+
'mrresize -interp cubic -voxel 1,1,1 dwi.mif dwi_resized.mif'
762+
>>> voxel_resize.run() # doctest: +SKIP
763+
764+
Defining the scale factor of each image dimension:
765+
>>> scale_resize = mrt.MRResize()
766+
>>> scale_resize.inputs.in_file = 'dwi.mif'
767+
>>> scale_resize.inputs.scale_factor = (0.5,0.5,0.5)
768+
>>> scale_resize.cmdline # doctest: +ELLIPSIS
769+
'mrresize -interp cubic -scale 0.5,0.5,0.5 dwi.mif dwi_resized.mif'
770+
>>> scale_resize.run() # doctest: +SKIP
771+
"""
772+
773+
_cmd = 'mrresize'
774+
input_spec = MRResizeInputSpec
775+
output_spec = MRResizeOutputSpec

nipype/utils/filemanip.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,16 @@
4040

4141
PY3 = sys.version_info[0] >= 3
4242

43-
44-
class FileNotFoundError(OSError): # noqa
45-
"""Defines the exception for Python 2."""
46-
47-
def __init__(self, path):
48-
"""Initialize the exception."""
49-
super(FileNotFoundError, self).__init__(
50-
2, 'No such file or directory', '%s' % path)
43+
try:
44+
from builtins import FileNotFoundError
45+
except ImportError: # PY27
46+
class FileNotFoundError(OSError): # noqa
47+
"""Defines the exception for Python 2."""
48+
49+
def __init__(self, path):
50+
"""Initialize the exception."""
51+
super(FileNotFoundError, self).__init__(
52+
2, 'No such file or directory', '%s' % path)
5153

5254

5355
USING_PATHLIB2 = False

0 commit comments

Comments
 (0)