Skip to content

Commit 334272c

Browse files
committed
ENH: Replicates N4BiasFieldCorrection output style
This replicates the method from in N4BiasFieldCorrection used to specify more than one output file (as suggested by blakedewey). It updates the doctest and test_auto_DenoiseImage.py with new variables save_noise and noise_image. It alse removes the version, help, and short_help options since nipype is a pipelining tool and a pipeline would not need to see the output if those options are set.
1 parent 5a60036 commit 334272c

File tree

2 files changed

+69
-36
lines changed

2 files changed

+69
-36
lines changed

nipype/interfaces/ants/segmentation.py

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -813,58 +813,89 @@ class DenoiseImageInputSpec(ANTSCommandInputSpec):
813813
'the input image can be resampled. The shrink '
814814
'factor, specified as a single integer, describes '
815815
'this resampling. Shrink factor = 1 is the default.'))
816-
output_image = traits.List(traits.Str(), argstr="",
817-
desc='The output consists of the noise corrected '
818-
'version of the input image. Optionally, one '
819-
'can also output the estimated noise image.')
820-
version = traits.Bool(False, argstr="--version", desc=('Get version information.'))
816+
output_image = traits.Str(argstr="-o %s", genfile=True, hash_files=False,
817+
desc='The output consists of the noise corrected '
818+
'version of the input image.')
819+
save_noise = traits.Bool(False, mandatory=True, usedefault=True,
820+
desc=('True if the estimated noise should be saved '
821+
'to file.'), xor=['noise_image'])
822+
noise_image = File(desc='Filename for the estimated noise.', hash_files=False)
821823
verbose = traits.Bool(False, argstr="-v", desc=('Verbose output.'))
822-
short_help = traits.Bool(False, argstr="-h", desc=('Print the help menu (short version).'))
823-
help = traits.Bool(False, argstr="--help", desc=('Print the help menu.'))
824824

825825

826826
class DenoiseImageOutputSpec(TraitedSpec):
827-
output_corrected_image = File(exists=True)
828-
output_noise_image = File(exists=True)
827+
output_image = File(exists=True)
828+
noise_image = File(exists=True)
829829

830830

831831
class DenoiseImage(ANTSCommand):
832832
"""
833833
Examples
834834
--------
835+
>>> import copy
835836
>>> from nipype.interfaces.ants import DenoiseImage
836837
>>> denoise = DenoiseImage()
837838
>>> denoise.inputs.dimension = 3
838839
>>> denoise.inputs.input_image = 'im1.nii'
839-
>>> denoise.inputs.output_image = ['output_corrected_image.nii.gz']
840840
>>> denoise.cmdline
841-
'DenoiseImage -d 3 -i im1.nii -n Gaussian -o output_corrected_image.nii.gz -s 1'
841+
'DenoiseImage -d 3 -i im1.nii -n Gaussian -o im1_noise_corrected.nii -s 1'
842842
843-
>>> denoise.inputs.noise_model = 'Rician'
844-
>>> denoise.inputs.shrink_factor = 2
845-
>>> denoise.cmdline
843+
>>> denoise_2 = copy.deepcopy(denoise)
844+
>>> denoise_2.inputs.output_image = 'output_corrected_image.nii.gz'
845+
>>> denoise_2.inputs.noise_model = 'Rician'
846+
>>> denoise_2.inputs.shrink_factor = 2
847+
>>> denoise_2.cmdline
846848
'DenoiseImage -d 3 -i im1.nii -n Rician -o output_corrected_image.nii.gz -s 2'
847849
848-
>>> denoise.inputs.output_image = ['output_corrected_image.nii.gz', 'output_noise_image.nii.gz']
849-
>>> denoise.cmdline
850-
'DenoiseImage -d 3 -i im1.nii -n Rician -o [output_corrected_image.nii.gz,output_noise_image.nii.gz] -s 2'
850+
>>> denoise_3 = DenoiseImage()
851+
>>> denoise_3.inputs.input_image = 'im1.nii'
852+
>>> denoise_3.inputs.save_noise = True
853+
>>> denoise_3.cmdline
854+
'DenoiseImage -i im1.nii -n Gaussian -o [ im1_noise_corrected.nii, im1_noise.nii ] -s 1'
851855
"""
852856
input_spec = DenoiseImageInputSpec
853857
output_spec = DenoiseImageOutputSpec
854858
_cmd = 'DenoiseImage'
855859

856-
def _format_arg(self, opt, spec, val):
857-
if opt == 'output_image':
858-
if len(val) == 1:
859-
retval = '-o {0}'.format(val[0])
860-
elif len(val) == 2:
861-
retval = '-o [{0},{1}]'.format(val[0], val[1])
862-
return retval
863-
return super(ANTSCommand, self)._format_arg(opt, spec, val)
860+
def _gen_filename(self, name):
861+
if name == 'output_image':
862+
output = self.inputs.output_image
863+
if not isdefined(output):
864+
_, name, ext = split_filename(self.inputs.input_image)
865+
output = name + '_noise_corrected' + ext
866+
return output
867+
868+
if name == 'noise_image':
869+
output = self.inputs.noise_image
870+
if not isdefined(output):
871+
_, name, ext = split_filename(self.inputs.input_image)
872+
output = name + '_noise' + ext
873+
return output
874+
return None
875+
876+
def _format_arg(self, name, trait_spec, value):
877+
if ((name == 'output_image') and
878+
(self.inputs.save_noise or isdefined(self.inputs.noise_image))):
879+
noise_image = self._gen_filename('noise_image')
880+
output = self._gen_filename('output_image')
881+
newval = '[ %s, %s ]' % (output, noise_image)
882+
return trait_spec.argstr % newval
883+
884+
return super(DenoiseImage,
885+
self)._format_arg(name, trait_spec, value)
886+
887+
def _parse_inputs(self, skip=None):
888+
if skip is None:
889+
skip = []
890+
skip += ['save_noise', 'noise_image']
891+
return super(DenoiseImage, self)._parse_inputs(skip=skip)
864892

865893
def _list_outputs(self):
866894
outputs = self._outputs().get()
867-
outputs['output_corrected_image'] = os.path.abspath(self.inputs.output_image[0])
868-
if len(self.inputs.output_image) == 2:
869-
outputs['output_noise_image'] = os.path.abspath(self.inputs.output_image[1])
895+
outputs['output_image'] = os.path.abspath(
896+
self._gen_filename('output_image'))
897+
898+
if self.inputs.save_noise or isdefined(self.inputs.noise_image):
899+
outputs['noise_image'] = os.path.abspath(
900+
self._gen_filename('noise_image'))
870901
return outputs

nipype/interfaces/ants/tests/test_auto_DenoiseImage.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,27 @@ def test_DenoiseImage_inputs():
1212
environ=dict(nohash=True,
1313
usedefault=True,
1414
),
15-
help=dict(argstr='--help',
16-
),
1715
ignore_exception=dict(nohash=True,
1816
usedefault=True,
1917
),
2018
input_image=dict(argstr='-i %s',
2119
mandatory=True,
2220
),
21+
noise_image=dict(hash_files=False,
22+
),
2323
noise_model=dict(argstr='-n %s',
2424
usedefault=True,
2525
),
2626
num_threads=dict(nohash=True,
2727
usedefault=True,
2828
),
29-
output_image=dict(argstr='',
29+
output_image=dict(argstr='-o %s',
30+
genfile=True,
31+
hash_files=False,
3032
),
31-
short_help=dict(argstr='-h',
33+
save_noise=dict(mandatory=True,
34+
usedefault=True,
35+
xor=['noise_image'],
3236
),
3337
shrink_factor=dict(argstr='-s %s',
3438
usedefault=True,
@@ -37,8 +41,6 @@ def test_DenoiseImage_inputs():
3741
),
3842
verbose=dict(argstr='-v',
3943
),
40-
version=dict(argstr='--version',
41-
),
4244
)
4345
inputs = DenoiseImage.input_spec()
4446

@@ -48,8 +50,8 @@ def test_DenoiseImage_inputs():
4850

4951

5052
def test_DenoiseImage_outputs():
51-
output_map = dict(output_corrected_image=dict(),
52-
output_noise_image=dict(),
53+
output_map = dict(noise_image=dict(),
54+
output_image=dict(),
5355
)
5456
outputs = DenoiseImage.output_spec()
5557

0 commit comments

Comments
 (0)