Skip to content

Commit 000bdfd

Browse files
committed
ANTS clean up and better Bool support.
1 parent beda7cd commit 000bdfd

File tree

2 files changed

+4
-281
lines changed

2 files changed

+4
-281
lines changed

nipype/interfaces/ants/ANTS.py

Lines changed: 3 additions & 280 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ class ANTSInputSpec(ANTSCommandInputSpec):
2424
metric_weight = traits.List(traits.Float(), requires=['metric'], desc='')
2525
radius = traits.List(traits.Int(), requires=['metric'], desc='')
2626

27-
output_transform_prefix = traits.Str('out', usedefault=True, argstr='%s', mandatory=True, desc='')
27+
output_transform_prefix = traits.Str('out', usedefault=True, argstr='--output-naming %s', mandatory=True, desc='')
2828
transformation_model = traits.Enum('Diff', 'Elast', 'Exp', 'Greedy Exp', 'SyN', argstr='%s', mandatory=True, desc='')
2929
gradient_step_length = traits.Float(requires=['transformation_model'], desc='')
3030
number_of_time_steps = traits.Float(requires=['gradient_step_length'], desc='')
3131
delta_time = traits.Float(requires=['number_of_time_steps'], desc='')
3232
symmetry_type = traits.Float(requires=['delta_time'], desc='')
3333

34-
use_histogram_matching = traits.Bool(argstr='%s', default=True, usedefault=True)
34+
use_histogram_matching = traits.Bool(argstr='--use-Histogram-Matching %d', default=True, usedefault=True)
3535
number_of_iterations = traits.List(traits.Int(), argstr='--number-of-iterations %s', sep='x')
3636
smoothing_sigmas = traits.List(traits.Int(), argstr='--gaussian-smoothing-sigmas %s', sep='x')
3737
subsampling_factors = traits.List(traits.Int(), argstr='--subsampling-factors %s', sep='x')
@@ -142,17 +142,10 @@ def _affine_gradient_descent_option_constructor(self):
142142
def _format_arg(self, opt, spec, val):
143143
if opt == 'moving_image':
144144
return self._image_metric_constructor()
145-
elif opt == 'output_transform_prefix':
146-
return '--output-naming %s' % self.inputs.output_transform_prefix
147145
elif opt == 'transformation_model':
148146
return self._transformation_constructor()
149147
elif opt == 'regularization':
150148
return self._regularization_constructor()
151-
elif opt == 'use_histogram_matching':
152-
if self.inputs.use_histogram_matching:
153-
return '--use-Histogram-Matching 1'
154-
else:
155-
return '--use-Histogram-Matching 0'
156149
elif opt == 'affine_gradient_descent_option':
157150
return self._affine_gradient_descent_option_constructor()
158151
return super(ANTS, self)._format_arg(opt, spec, val)
@@ -164,274 +157,4 @@ def _list_outputs(self):
164157
outputs['inverse_warp_transform'] = os.path.abspath(self.inputs.output_transform_prefix + 'InverseWarp.nii.gz')
165158
#outputs['metaheader'] = os.path.abspath(self.inputs.output_transform_prefix + 'velocity.mhd')
166159
#outputs['metaheader_raw'] = os.path.abspath(self.inputs.output_transform_prefix + 'velocity.raw')
167-
return outputs
168-
169-
"""
170-
COMMAND:
171-
ANTS
172-
173-
OPTIONS:
174-
-x, --mask-image maskFileName
175-
this mask -- defined in the 'fixed' image space defines the region of interest
176-
over which the registration is computed ==> above 0.1 means inside mask ==>
177-
continuous values in range [0.1,1.0] effect optimization like a probability. ==>
178-
values > 1 are treated as = 1.0
179-
180-
-m, --image-metric
181-
The metric weights are relative to the weights on the N other metrics passed to
182-
ANTS --- N is unlimited. So, the weight, w_i on the i^{th} metric will be
183-
w_i=w_i/ ( sum_i w_i ).
184-
185-
Intensity-Based Metrics:
186-
* CC/cross-correlation/CrossCorrelation[fixedImage,movingImage,weight,radius/OrForMI-#histogramBins]
187-
* MI/mutual-information/MutualInformation[fixedImage,movingImage,weight,radius/OrForMI-#histogramBins]
188-
* SMI/spatial-mutual-information/SpatialMutualInformation[fixedImage,movingImage,weight,radius/OrForMI-#histogramBins]
189-
* PR/probabilistic/Probabilistic[fixedImage,movingImage,weight,radius/OrForMI-#histogramBins]
190-
* SSD/difference[fixedImage,movingImage,weight,radius/OrForMI-#histogramBins]
191-
* MSQ/mean-squares/MeanSquares/deriv.[fixedImage,movingImage,weight,radius/OrForMI-#histogramBins]
192-
193-
Point-Set-Based Metrics:
194-
* PSE/point-set-expectation/PointSetExpectation[fixedImage,movingImage,fixedPoints,movingPoints,weight,pointSetPercentage,pointSetSigma,boundaryPointsOnly,kNeighborhood,PartialMatchingIterations=100000]
195-
+ the partial matching option assumes the complete labeling is in the first set of label parameters more iterations leads to more symmetry in the matching - 0 iterations means full asymmetry
196-
* JTB/jensen-tsallis-bspline/JensenTsallisBSpline[fixedImage,movingImage,fixedPoints,movingPoints,weight,pointSetPercentage,pointSetSigma,boundaryPointsOnly,kNeighborhood,alpha,meshResolution,splineOrder,numberOfLevels,useAnisotropicCovariances]
197-
198-
-o, --output-naming
199-
The name for the output - a prefix or a name+type : e.g. -o OUT or -o OUT.nii or
200-
-o OUT.mha
201-
202-
--R TODO/FIXME: the --R sets an ROI option -- it passes a vector of parameters that
203-
sets the center and bounding box of the region of interest for a sub-registration. e.g. in 3D the option setting
204-
205-
-r 10x12x15x50x50x25
206-
sets up a bounding box of size 50,50,25 with origin at 10,12,15 in voxel (should this be physical?) coordinates.
207-
<VALUES>: 0
208-
209-
-i, --number-of-iterations
210-
number of iterations per level -- a 'vector' e.g. : 100x100x20
211-
<VALUES>: 10x10x5
212-
213-
--Restrict-Deformation
214-
restrict the gradient that drives the deformation by scalar factors along
215-
specified dimensions -- a TReal 'vector' of length ImageDimension to multiply
216-
against the similarity metric's gradient values --- e.g. in 3D : 0.1x1x0 ---
217-
will set the z gradient to zero and scale the x gradient by 0.1 and y by 1 (no
218-
change). Thus, you get a 2.5-Dimensional registration as there is still 3D
219-
continuity in the mapping.
220-
<VALUES>: 1x1
221-
222-
-v, --verbose
223-
verbose output
224-
225-
--use-all-metrics-for-convergence
226-
enable to use weighted sum of all metric terms for convergence computation. By
227-
default, only the first metric is used
228-
<VALUES>: 0
229-
230-
-h
231-
Print the help menu (short version).
232-
<VALUES>: 0
233-
234-
--help
235-
Print the help menu.
236-
<VALUES>: 1, 0
237-
-t, --transformation-model
238-
TRANSFORMATION[gradient-step-length,number-of-time-steps,DeltaTime,symmetry-type].
239-
Choose one of the following TRANSFORMATIONS:
240-
* Diff = diffeomorphic
241-
* Elast = Elastic
242-
* Exp = exponential diff
243-
* Greedy Exp = greedy exponential diff, diffeomorphic demons. same parameters.
244-
* SyN = symmetric normalization
245-
246-
DeltaTime is the integration time-discretization step - sub-voxel - n-time steps currently fixed at 2
247-
<VALUES>: SyN[0.5]
248-
249-
-r, --regularization
250-
REGULARIZATION[gradient-field-sigma,def-field-sigma,truncation]
251-
Choose one of the following REGULARIZATIONS:
252-
* Gauss = gaussian
253-
* DMFFD = directly manipulated free form deformation
254-
<VALUES>: Gauss[3,0.5]
255-
256-
-a, --initial-affine
257-
use the input file as the initial affine parameter
258-
259-
-F, --fixed-image-initial-affine
260-
use the input file as the initial affine parameter for the fixed image
261-
262-
--fixed-image-initial-affine-ref-image
263-
reference space for using the input file as the initial affine parameter for the
264-
fixed image
265-
266-
-T, --geodesic
267-
0 / 1 / 2
268-
0 = not time-dependent, 1 = asymmetric , 2 = symmetric
269-
270-
-G, --go-faster
271-
true / false -- if true, SyN is faster but loses some accuracy wrt
272-
inverse-identity constraint, see Avants MIA 2008.
273-
<VALUES>: false
274-
275-
--continue-affine
276-
true (default) | false, do (not) perform affine given the initial affine
277-
parameters
278-
<VALUES>: true
279-
280-
--number-of-affine-iterations
281-
AxBxC
282-
number of iterations per level -- a 'vector' e.g. : 100x100x20
283-
<VALUES>: 10000x10000x10000
284-
285-
--use-NN
286-
use nearest neighbor interpolation
287-
<VALUES>: 0
288-
289-
--use-Histogram-Matching
290-
use histogram matching of moving to fixed image
291-
<VALUES>: 0
292-
293-
--affine-metric-type <type>
294-
MI: mutual information (default), MSQ: mean square error, SSD, CC: Normalized
295-
correlation, CCH: Histogram-based correlation coefficient (not recommended), GD:
296-
gradient difference (not recommended)
297-
<VALUES>: MI
298-
299-
--MI-option <AxB>
300-
option of mutual information: MI_bins x MI_samples (default: 32x32000)
301-
<VALUES>: 32x5000
302-
303-
--rigid-affine
304-
use rigid transformation : true / false(default)
305-
<VALUES>: false
306-
307-
--do-rigid
308-
use rigid transformation : true / false(default)
309-
<VALUES>: false
310-
311-
--affine-gradient-descent-option
312-
option of gradient descent in affine transformation: maximum_step_length x
313-
relaxation_factor x minimum_step_length x translation_scales
314-
<VALUES>: 0.1x0.5x1.e-4x1.e-4
315-
316-
--use-rotation-header
317-
use rotation matrix in image headers: true (default) / false
318-
<VALUES>: false
319-
320-
--ignore-void-origin
321-
ignore the apparently unmatched origins (when use-rotation-header is false and
322-
the rotation matrix is identity: true (default) / false
323-
<VALUES>: false
324-
325-
--gaussian-smoothing-sigmas
326-
At each resolution level the image is subsampled and smoothed by Gaussian
327-
convolution. This option allows the user to override the default smoothing by
328-
specifying sigma values (in mm) for smoothing both fixed and moving images for
329-
each resolution level.
330-
<VALUES>:
331-
332-
--subsampling-factors
333-
At each resolution level the image is subsampled and smoothed by Gaussian
334-
convolution. This option allows the user to override the default subsampling by
335-
specifying the subsampling factor for both fixed and moving images for each
336-
resolution level.
337-
<VALUES>:
338-
339-
=======================================================================
340-
341-
How to run the test case:
342-
343-
cd {TEST_DATA}/EXPERIEMENTS/ANTS_NIPYPE_SMALL_TEST
344-
{BINARIES_DIRECTORY}/bin/ANTS \
345-
3 \
346-
--output-naming OrigANTS_20120430_1348_ANTS6_ \
347-
-m CC[SUBJ_A_T1_resampled.nii.gz,SUBJ_B_T1_resampled.nii.gz,1,5] \
348-
-t Affine[0.25] \
349-
-t SyN[0.25,3.0,0.0] \
350-
-i 100x70x20 \
351-
--subsampling-factors 3x2x1 \
352-
--gaussian-smoothing-sigmas 0x0x0 \
353-
--use-Histogram-Matching 1
354-
355-
//OPTIONAL INTERFACE FOR MULTI_MODAL_REGISTRATION:
356-
# -m 'CC[SUBJ_A_T2.nii.gz,SUBJ_B_T2.nii.gz,1,5]' \
357-
358-
Nipype interface proposal
359-
ants.inputs.dimensionality = 3 # [2,3]
360-
ants.inputs.fixed_image_mask = 'maskImageFileName'
361-
===========================================
362-
### Note: multiple metrics can be used ###
363-
===========================================
364-
ants.inputs.metric = ['CC','MI','PSE']
365-
= ['CrossCorrelation','MutualInformation','PointSetExpectation']
366-
= ['cross-correlation','mutual-information','point-set-expectation']
367-
ants.inputs.fixed_image = ['fixedImageFileName']
368-
ants.inputs.moving_image = ['movingImageFileName']
369-
ants.inputs.metric_weight = [0.3,0.4,0.3] # len() == number of metrics
370-
ants.inputs.radius = [3] # Requires specific metrics
371-
ants.inputs.histogram_bins = [25] # Requires specific metrics: MI & SMI
372-
===========================================
373-
# Requires specific metrics: PointSet-based
374-
===========================================
375-
ants.inputs.point_set_percentage = ... ### TODO: Find allowed values ###
376-
ants.inputs.point_set_sigma = ... ### TODO: Find allowed values ###
377-
ants.inputs.boundary_points_only = False
378-
ants.inputs.k_neignborhood = ... ### TODO: Find allowed values ### Is this for kNN? Int or Float?
379-
ants.inputs.partial_matching_iterations = 50000 # Default:100000
380-
===========================================
381-
ants.inputs.output_transform_prefix = 'outputFilePrefix'
382-
= 'outputFileName.extension'
383-
ants.inputs.roi_size = [50,50,25] # In voxels!!!
384-
ants.inputs.roi_origin = [10,12.15] # In voxels!!!
385-
ants.inputs.number_of_iterations = [100,100,20]
386-
ants.inputs.restrict_deformation = True
387-
ants.inputs.use_all_metrics_for_convergence = True # Default: False
388-
===========================================
389-
### Note: multiple transformations can be used ###
390-
===========================================
391-
ants.inputs.transformation_model = 'SyN' # ['Diff', 'Elast', 'Exp', Greedy Exp', 'SyN']
392-
ants.inputs.transformation_gradient_step_length = 0.25
393-
ants.inputs.transformation_number_of_time_steps = 3.0
394-
ants.inputs.transformation_delta_time = 0.0
395-
ants.inputs.transformation_symmetry_type = ... ### TODO: Find allowed values ###
396-
===========================================
397-
ants.inputs.regularization = 'Gauss' # ['Gauss', 'DMFFD']
398-
ants.inputs.regularization_gradient_field_sigma = 3
399-
ants.inputs.regularization_deformation_field_sigma = 0.5
400-
ants.inputs.regularization_truncation = ... ### TODO: Find allowed values ###
401-
===========================================
402-
ants.inputs.initial_affine = 'initialAffineTransformFileName'
403-
ants.inputs.fixed_image_initial_affine = 'initialFixedImageAffineTransformFileName'
404-
ants.inputs.fixed_image_initial_affine_reference_image = 'initialFixedImageAffineReferenceImageFileName'
405-
ants.inputs.geodesic = 0 # [0,1,2]
406-
= 'time-independent' ['time-independent', 'asymmetric', 'symmetric'] ### TODO: Discuss this feature with Hans ###
407-
ants.inputs.goFaster = True # This may be dependent on transformation type?
408-
ants.inputs.continueAffine = True # (Default)
409-
ants.inputs.numberOfAffineIterations = [10000, 10000, 10000] # len() = number of levels
410-
ants.inputs.useNN = True
411-
ants.inputs.useHistogramMatching = True
412-
ants.inputs.affineMetricType = 'MI' # ['MI', 'MSQ', 'SSD', 'CC', 'CCH', 'GD'] ('CCH' & 'GD' are NOT recommended)
413-
ants.inputs.MIOption = [32, 32000] # (Default) ### TODO: Which metric does this apply to? ###
414-
ants.inputs.rigidAffine = False # (Default)
415-
ants.inputs.doRigid = False #(Default)
416-
===========================================
417-
### TODO: What option does this section affect/require? Or does it? ###
418-
ants.inputs.affineGradientDesentMaxStepLength = 0.1
419-
ants.inputs.affineGradientDesentRelaxationFactor = 0.5
420-
ants.inputs.affineGradientDesentMinStepLength = 1e-4
421-
ants.inputs.affineGradientDesentTranslationScales = 1e-4
422-
===========================================
423-
ants.inputs.useRotationHeader = True # (default)
424-
ants.inputs.ignoreVoidOrigin = True # (default) Requires: useRotationHeader == False AND rotationMatrix == Identity
425-
ants.inputs.gaussianSmoothingSigmas = ...
426-
ants.inputs.subsamplingFactors = [...] # len() == 2 x (number of levels) <-- 2 == number of image 'types' (fixed, moving)
427-
===========================================
428-
429-
=======================================================================
430-
431-
Change directory to provide relative paths for doctests
432-
>>> import os
433-
>>> filepath = os.path.dirname( os.path.realpath( __file__ ) )
434-
>>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data'))
435-
>>> os.chdir(datadir)
436-
437-
"""
160+
return outputs

nipype/interfaces/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,7 +1133,7 @@ def _format_arg(self, name, trait_spec, value):
11331133
"""
11341134
argstr = trait_spec.argstr
11351135
iflogger.debug('%s_%s' %(name, str(value)))
1136-
if trait_spec.is_trait_type(traits.Bool):
1136+
if trait_spec.is_trait_type(traits.Bool) and "%" not in argstr:
11371137
if value:
11381138
# Boolean options have no format string. Just append options
11391139
# if True.

0 commit comments

Comments
 (0)