11"""ANTs' utilities."""
22import os
3+ from warnings import warn
34from ..base import traits , isdefined , TraitedSpec , File , Str , InputMultiObject
45from ..mixins import CopyHeaderInterface
56from .base import ANTSCommandInputSpec , ANTSCommand
@@ -47,6 +48,10 @@ class ImageMathInputSpec(ANTSCommandInputSpec):
4748 "GO" ,
4849 "GC" ,
4950 "TruncateImageIntensity" ,
51+ "Laplacian" ,
52+ "GetLargestComponent" ,
53+ "FillHoles" ,
54+ "PadImage" ,
5055 mandatory = True ,
5156 position = 3 ,
5257 argstr = "%s" ,
@@ -73,8 +78,8 @@ class ImageMath(ANTSCommand, CopyHeaderInterface):
7378 """
7479 Operations over images.
7580
76- Example
77- -------
81+ Examples
82+ --------
7883 >>> ImageMath(
7984 ... op1='structural.nii',
8085 ... operation='+',
@@ -99,13 +104,55 @@ class ImageMath(ANTSCommand, CopyHeaderInterface):
99104 ... op2='0.005 0.999 256').cmdline
100105 'ImageMath 3 structural_maths.nii TruncateImageIntensity structural.nii 0.005 0.999 256'
101106
107+ By default, Nipype copies headers from the first input image (``op1``)
108+ to the output image.
109+ For the ``PadImage`` operation, the header cannot be copied from inputs to
110+ outputs, and so ``copy_header`` option is automatically set to ``False``.
111+
112+ >>> pad = ImageMath(
113+ ... op1='structural.nii',
114+ ... operation='PadImage')
115+ >>> pad.inputs.copy_header
116+ False
117+
118+ While the operation is set to ``PadImage``,
119+ setting ``copy_header = True`` will have no effect.
120+
121+ >>> pad.inputs.copy_header = True
122+ >>> pad.inputs.copy_header
123+ False
124+
125+ For any other operation, ``copy_header`` can be enabled/disabled normally:
126+
127+ >>> pad.inputs.operation = "ME"
128+ >>> pad.inputs.copy_header = True
129+ >>> pad.inputs.copy_header
130+ True
131+
102132 """
103133
104134 _cmd = "ImageMath"
105135 input_spec = ImageMathInputSpec
106136 output_spec = ImageMathOuputSpec
107137 _copy_header_map = {"output_image" : "op1" }
108138
139+ def __init__ (self , ** inputs ):
140+ super (ImageMath , self ).__init__ (** inputs )
141+ if self .inputs .operation in ("PadImage" , ):
142+ self .inputs .copy_header = False
143+
144+ self .inputs .on_trait_change (self ._operation_update , "operation" )
145+ self .inputs .on_trait_change (self ._copyheader_update , "copy_header" )
146+
147+ def _operation_update (self ):
148+ if self .inputs .operation in ("PadImage" , ):
149+ self .inputs .copy_header = False
150+
151+ def _copyheader_update (self ):
152+ if self .inputs .copy_header and self .inputs .operation in ("PadImage" , ):
153+ warn ("copy_header cannot be updated to True with PadImage as operation." )
154+ self .inputs .copy_header = False
155+
109156
110157class ResampleImageBySpacingInputSpec (ANTSCommandInputSpec ):
111158 dimension = traits .Int (
@@ -143,19 +190,13 @@ class ResampleImageBySpacingInputSpec(ANTSCommandInputSpec):
143190 nn_interp = traits .Bool (
144191 argstr = "%d" , desc = "nn interpolation" , position = - 1 , requires = ["addvox" ]
145192 )
146- copy_header = traits .Bool (
147- True ,
148- mandatory = True ,
149- usedefault = True ,
150- desc = "copy headers of the original image into the output (corrected) file" ,
151- )
152193
153194
154195class ResampleImageBySpacingOutputSpec (TraitedSpec ):
155196 output_image = File (exists = True , desc = "resampled file" )
156197
157198
158- class ResampleImageBySpacing (ANTSCommand , CopyHeaderInterface ):
199+ class ResampleImageBySpacing (ANTSCommand ):
159200 """
160201 Resample an image with a given spacing.
161202
@@ -191,7 +232,6 @@ class ResampleImageBySpacing(ANTSCommand, CopyHeaderInterface):
191232 _cmd = "ResampleImageBySpacing"
192233 input_spec = ResampleImageBySpacingInputSpec
193234 output_spec = ResampleImageBySpacingOutputSpec
194- _copy_header_map = {"output_image" : "input_image" }
195235
196236 def _format_arg (self , name , trait_spec , value ):
197237 if name == "out_spacing" :
0 commit comments