Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Next release
============

* ENH: Provides a Nipype wrapper for ANTs DenoiseImage (https://github.com/nipy/nipype/pull/1291)
* FIX: Minor bugfix logging hash differences (https://github.com/nipy/nipype/pull/1298)
* FIX: Use released Prov python library (https://github.com/nipy/nipype/pull/1279)
* ENH: Support for Python 3 (https://github.com/nipy/nipype/pull/1221)
Expand Down
2 changes: 1 addition & 1 deletion nipype/interfaces/ants/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

# Segmentation Programs
from .segmentation import (Atropos, LaplacianThickness, N4BiasFieldCorrection, JointFusion, CorticalThickness,
BrainExtraction)
BrainExtraction, DenoiseImage)

# Visualization Programs
from .visualization import ConvertScalarImageToRGB, CreateTiledMosaic
Expand Down
104 changes: 104 additions & 0 deletions nipype/interfaces/ants/segmentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -795,3 +795,107 @@ def _list_outputs(self):
outputs['output_label_image'] = os.path.abspath(
self.inputs.output_label_image)
return outputs


class DenoiseImageInputSpec(ANTSCommandInputSpec):
dimension = traits.Enum(2, 3, 4, argstr='-d %d', usedefault=False,
desc='This option forces the image to be treated '
'as a specified-dimensional image. If not '
'specified, the program tries to infer the '
'dimensionality from the input image.')
input_image = File(exists=True, argstr="-i %s", mandatory=True,
desc='A scalar image is expected as input for noise correction.')
noise_model = traits.Enum('Gaussian', 'Rician', argstr='-n %s', usedefault=True,
desc=('Employ a Rician or Gaussian noise model.'))
shrink_factor = traits.Int(default_value=1, usedefault=True, argstr='-s %s',
desc=('Running noise correction on large images can '
'be time consuming. To lessen computation time, '
'the input image can be resampled. The shrink '
'factor, specified as a single integer, describes '
'this resampling. Shrink factor = 1 is the default.'))
output_image = traits.Str(argstr="-o %s", genfile=True, hash_files=False,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can skip genfile (and the need to define _gen_filename) if you use name_source and name_template (more info here: http://nipy.org/nipype/devel/cmd_interface_devel.html#creating-outputs-on-the-fly). This will simplify the interface.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same thing applies for noise_image

desc='The output consists of the noise corrected '
'version of the input image.')
save_noise = traits.Bool(False, mandatory=True, usedefault=True,
desc=('True if the estimated noise should be saved '
'to file.'), xor=['noise_image'])
noise_image = File(desc='Filename for the estimated noise.', hash_files=False)
verbose = traits.Bool(False, argstr="-v", desc=('Verbose output.'))


class DenoiseImageOutputSpec(TraitedSpec):
output_image = File(exists=True)
noise_image = File(exists=True)


class DenoiseImage(ANTSCommand):
"""
Examples
--------
>>> import copy
>>> from nipype.interfaces.ants import DenoiseImage
>>> denoise = DenoiseImage()
>>> denoise.inputs.dimension = 3
>>> denoise.inputs.input_image = 'im1.nii'
>>> denoise.cmdline
'DenoiseImage -d 3 -i im1.nii -n Gaussian -o im1_noise_corrected.nii -s 1'

>>> denoise_2 = copy.deepcopy(denoise)
>>> denoise_2.inputs.output_image = 'output_corrected_image.nii.gz'
>>> denoise_2.inputs.noise_model = 'Rician'
>>> denoise_2.inputs.shrink_factor = 2
>>> denoise_2.cmdline
'DenoiseImage -d 3 -i im1.nii -n Rician -o output_corrected_image.nii.gz -s 2'

>>> denoise_3 = DenoiseImage()
>>> denoise_3.inputs.input_image = 'im1.nii'
>>> denoise_3.inputs.save_noise = True
>>> denoise_3.cmdline
'DenoiseImage -i im1.nii -n Gaussian -o [ im1_noise_corrected.nii, im1_noise.nii ] -s 1'
"""
input_spec = DenoiseImageInputSpec
output_spec = DenoiseImageOutputSpec
_cmd = 'DenoiseImage'

def _gen_filename(self, name):
if name == 'output_image':
output = self.inputs.output_image
if not isdefined(output):
_, name, ext = split_filename(self.inputs.input_image)
output = name + '_noise_corrected' + ext
return output

if name == 'noise_image':
output = self.inputs.noise_image
if not isdefined(output):
_, name, ext = split_filename(self.inputs.input_image)
output = name + '_noise' + ext
return output
return None

def _format_arg(self, name, trait_spec, value):
if ((name == 'output_image') and
(self.inputs.save_noise or isdefined(self.inputs.noise_image))):
noise_image = self._gen_filename('noise_image')
output = self._gen_filename('output_image')
newval = '[ %s, %s ]' % (output, noise_image)
return trait_spec.argstr % newval

return super(DenoiseImage,
self)._format_arg(name, trait_spec, value)

def _parse_inputs(self, skip=None):
if skip is None:
skip = []
skip += ['save_noise', 'noise_image']
return super(DenoiseImage, self)._parse_inputs(skip=skip)

def _list_outputs(self):
outputs = self._outputs().get()
outputs['output_image'] = os.path.abspath(
self._gen_filename('output_image'))

if self.inputs.save_noise or isdefined(self.inputs.noise_image):
outputs['noise_image'] = os.path.abspath(
self._gen_filename('noise_image'))
return outputs
60 changes: 60 additions & 0 deletions nipype/interfaces/ants/tests/test_auto_DenoiseImage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# AUTO-GENERATED by tools/checkspecs.py - DO NOT EDIT
from ....testing import assert_equal
from ..segmentation import DenoiseImage


def test_DenoiseImage_inputs():
input_map = dict(args=dict(argstr='%s',
),
dimension=dict(argstr='-d %d',
usedefault=False,
),
environ=dict(nohash=True,
usedefault=True,
),
ignore_exception=dict(nohash=True,
usedefault=True,
),
input_image=dict(argstr='-i %s',
mandatory=True,
),
noise_image=dict(hash_files=False,
),
noise_model=dict(argstr='-n %s',
usedefault=True,
),
num_threads=dict(nohash=True,
usedefault=True,
),
output_image=dict(argstr='-o %s',
genfile=True,
hash_files=False,
),
save_noise=dict(mandatory=True,
usedefault=True,
xor=['noise_image'],
),
shrink_factor=dict(argstr='-s %s',
usedefault=True,
),
terminal_output=dict(nohash=True,
),
verbose=dict(argstr='-v',
),
)
inputs = DenoiseImage.input_spec()

for key, metadata in list(input_map.items()):
for metakey, value in list(metadata.items()):
yield assert_equal, getattr(inputs.traits()[key], metakey), value


def test_DenoiseImage_outputs():
output_map = dict(noise_image=dict(),
output_image=dict(),
)
outputs = DenoiseImage.output_spec()

for key, metadata in list(output_map.items()):
for metakey, value in list(metadata.items()):
yield assert_equal, getattr(outputs.traits()[key], metakey), value