Skip to content

Commit 8fea0b0

Browse files
committed
Merge pull request #647 from satra/fix/cherrypicked
Fix/cherrypicked
2 parents c021039 + 9faf08c commit 8fea0b0

File tree

6 files changed

+82
-49
lines changed

6 files changed

+82
-49
lines changed

examples/smri_ants_registration.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,27 +59,29 @@
5959
reg.inputs.output_transform_prefix = 'thisTransform'
6060
reg.inputs.output_warped_image = 'INTERNAL_WARPED.nii.gz'
6161

62+
reg.inputs.output_transform_prefix = "output_"
6263
reg.inputs.transforms = ['Translation', 'Rigid', 'Affine', 'SyN']
63-
reg.inputs.transform_parameters = [(0.1,), (0.1,), (0.1,), (0.3, 3.0, 0.0)]
64-
reg.inputs.number_of_iterations = [[10000, 0, 0], [10000, 0, 0], [10000, 0, 0], [10, 0, 0]]
64+
reg.inputs.transform_parameters = [(0.1,), (0.1,), (0.1,), (0.2, 3.0, 0.0)]
65+
reg.inputs.number_of_iterations = ([[10000, 111110, 11110]]*3 +
66+
[[100, 50, 30]])
6567
reg.inputs.dimension = 3
6668
reg.inputs.write_composite_transform = True
67-
reg.inputs.collapse_output_transforms = True
68-
reg.inputs.metric = ['Mattes']*4
69-
reg.inputs.metric_weight = [1]*4 # Default (value ignored currently by ANTs)
70-
reg.inputs.radius_or_number_of_bins = [32]*4
71-
reg.inputs.sampling_strategy = ['Regular']*3 + [None]
72-
reg.inputs.sampling_percentage = [0.1]*3 + [None]
73-
reg.inputs.convergence_threshold = [1.e-8]*4
74-
reg.inputs.convergence_window_size = [20]*4
75-
reg.inputs.smoothing_sigmas = [[4,2,1]]*3 + [[2,1,0]]
76-
reg.inputs.sigma_units = ['vox']*4
77-
reg.inputs.shrink_factors = [[6,4,2]]*3 + [[4,2,1]]
78-
reg.inputs.use_estimate_learning_rate_once = [True, True, True, True]
79-
reg.inputs.use_histogram_matching = [False]*3 + [True] # This is the default
69+
reg.inputs.collapse_output_transforms = False
70+
reg.inputs.metric = ['Mattes'] * 3 + [['Mattes', 'CC']]
71+
reg.inputs.metric_weight = [1] * 3 + [[0.5, 0.5]]
72+
reg.inputs.radius_or_number_of_bins = [32] * 3 + [[32, 4]]
73+
reg.inputs.sampling_strategy = ['Regular'] * 3 + [[None, None]]
74+
reg.inputs.sampling_percentage = [0.3] * 3 + [[None, None]]
75+
reg.inputs.convergence_threshold = [1.e-8] * 3 + [-0.01]
76+
reg.inputs.convergence_window_size = [20] * 3 + [5]
77+
reg.inputs.smoothing_sigmas = [[4, 2, 1]] * 3 + [[1, 0.5, 0]]
78+
reg.inputs.sigma_units = ['vox'] * 4
79+
reg.inputs.shrink_factors = [[6, 4, 2]] + [[3, 2, 1]]*2 + [[4, 2, 1]]
80+
reg.inputs.use_estimate_learning_rate_once = [True] * 4
81+
reg.inputs.use_histogram_matching = [False] * 3 + [True]
8082
reg.inputs.initial_moving_transform_com = True
81-
reg.inputs.output_warped_image = True
82-
reg.cmdline
83+
84+
print reg.cmdline
8385

8486

8587
"""

nipype/interfaces/ants/registration.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ class RegistrationInputSpec(ANTSCommandInputSpec):
283283
traits.Float())))
284284
# Convergence flags
285285
number_of_iterations = traits.List(traits.List(traits.Int()))
286-
smoothing_sigmas = traits.List(traits.List(traits.Int()), mandatory=True)
286+
smoothing_sigmas = traits.List(traits.List(traits.Float()), mandatory=True)
287287
sigma_units = traits.List(traits.Enum('mm', 'vox'),
288288
requires=['smoothing_sigmas'],
289289
desc="units for smoothing sigmas", mandatory=True)
@@ -356,37 +356,37 @@ class Registration(ANTSCommand):
356356
>>> reg1.inputs.winsorize_lower_quantile = 0.025
357357
>>> reg1.inputs.collapse_linear_transforms_to_fixed_image_header = False
358358
>>> reg1.cmdline
359-
'antsRegistration --collapse-linear-transforms-to-fixed-image-header 0 --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1x0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2x1x0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 1.0 ] --write-composite-transform 1'
359+
'antsRegistration --collapse-linear-transforms-to-fixed-image-header 0 --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 1.0 ] --write-composite-transform 1'
360360
>>> reg1.run() #doctest: +SKIP
361361
362362
>>> reg2 = copy.deepcopy(reg)
363363
>>> reg2.inputs.winsorize_upper_quantile = 0.975
364364
>>> reg2.cmdline
365-
'antsRegistration --collapse-linear-transforms-to-fixed-image-header 0 --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1x0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2x1x0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 0.975 ] --write-composite-transform 1'
365+
'antsRegistration --collapse-linear-transforms-to-fixed-image-header 0 --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 0.975 ] --write-composite-transform 1'
366366
367367
>>> reg3 = copy.deepcopy(reg)
368368
>>> reg3.inputs.winsorize_lower_quantile = 0.025
369369
>>> reg3.inputs.winsorize_upper_quantile = 0.975
370370
>>> reg3.cmdline
371-
'antsRegistration --collapse-linear-transforms-to-fixed-image-header 0 --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1x0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2x1x0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 0.975 ] --write-composite-transform 1'
371+
'antsRegistration --collapse-linear-transforms-to-fixed-image-header 0 --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes[ fixed1.nii, moving1.nii, 1, 32 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.025, 0.975 ] --write-composite-transform 1'
372372
373-
# Test collapse transforms flag
373+
>>> # Test collapse transforms flag
374374
>>> reg4 = copy.deepcopy(reg)
375375
>>> reg4.inputs.collapse_output_transforms = True
376376
>>> outputs = reg4._list_outputs()
377377
>>> print outputs #doctest: +ELLIPSIS
378378
{'reverse_invert_flags': [True, False], 'inverse_composite_transform': ['.../nipype/testing/data/output_InverseComposite.h5'], 'warped_image': '.../nipype/testing/data/output_warped_image.nii.gz', 'inverse_warped_image': <undefined>, 'forward_invert_flags': [False, False], 'reverse_transforms': ['.../nipype/testing/data/output_0GenericAffine.mat', '.../nipype/testing/data/output_1InverseWarp.nii.gz'], 'composite_transform': ['.../nipype/testing/data/output_Composite.h5'], 'forward_transforms': ['.../nipype/testing/data/output_0GenericAffine.mat', '.../nipype/testing/data/output_1Warp.nii.gz']}
379379
>>> reg4.aggregate_outputs() #doctest: +SKIP
380380
381-
# Test multiple metrics per stage
381+
>>> # Test multiple metrics per stage
382382
>>> reg5 = copy.deepcopy(reg)
383383
>>> reg5.inputs.metric = ['CC', ['CC', 'Mattes']]
384384
>>> reg5.inputs.metric_weight = [1, [.5]*2]
385385
>>> reg5.inputs.radius_or_number_of_bins = [4, [32]*2]
386386
>>> reg5.inputs.sampling_strategy = ['Random', None] # use default strategy in second stage
387387
>>> reg5.inputs.sampling_percentage = [0.05, [0.05, 0.10]]
388388
>>> reg5.cmdline
389-
'antsRegistration --collapse-linear-transforms-to-fixed-image-header 0 --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric CC[ fixed1.nii, moving1.nii, 1, 4, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1x0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric CC[ fixed1.nii, moving1.nii, 0.5, 32, Dense, 0.05 ] --metric Mattes[ fixed1.nii, moving1.nii, 0.5, 32, Dense, 0.1 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2x1x0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1'
389+
'antsRegistration --collapse-linear-transforms-to-fixed-image-header 0 --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --transform Affine[ 2.0 ] --metric CC[ fixed1.nii, moving1.nii, 1, 4, Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric CC[ fixed1.nii, moving1.nii, 0.5, 32, Dense, 0.05 ] --metric Mattes[ fixed1.nii, moving1.nii, 0.5, 32, Dense, 0.1 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1'
390390
"""
391391
DEF_SAMPLING_STRATEGY = 'Dense'
392392
"""The default sampling stratey argument."""

nipype/interfaces/ants/resampling.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,16 @@ def _list_outputs(self):
208208

209209

210210
class ApplyTransformsInputSpec(ANTSCommandInputSpec):
211-
dimension = traits.Enum(
212-
3, 2, argstr='--dimensionality %d', usedefault=True,
213-
desc='image dimension (2 or 3)')
211+
dimension = traits.Enum(2, 3, 4, argstr='--dimensionality %d',
212+
desc=('This option forces the image to be treated '
213+
'as a specified-dimensional image. If not '
214+
'specified, antsWarp tries to infer the '
215+
'dimensionality from the input image.'))
216+
input_image_type = traits.Enum(0, 1, 2, 3,
217+
argstr='--input-image-type %d',
218+
desc=('Option specifying the input image '
219+
'type of scalar (default), vector, '
220+
'tensor, or time series.'))
214221
input_image = File(argstr='--input %s', mandatory=True,
215222
desc=('image to apply transformation to (generally a '
216223
'coregistered functional)'),

nipype/interfaces/base.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -701,18 +701,28 @@ def safe_encode(x):
701701
return pm.Literal(int(x), pm.XSD['integer'])
702702
if isinstance(x, (float,)):
703703
return pm.Literal(x, pm.XSD['float'])
704+
if isinstance(x, dict):
705+
outdict = {}
706+
for key, value in x.items():
707+
encoded_value = safe_encode(value)
708+
if isinstance(encoded_value, (pm.Literal,)):
709+
outdict[key] = encoded_value.json_representation()
710+
else:
711+
outdict[key] = encoded_value
712+
return pm.Literal(json.dumps(outdict), pm.XSD['string'])
713+
if isinstance(x, list):
714+
outlist = []
715+
for value in x:
716+
encoded_value = safe_encode(value)
717+
if isinstance(encoded_value, (pm.Literal,)):
718+
outlist.append(encoded_value.json_representation())
719+
else:
720+
outlist.append(encoded_value)
721+
return pm.Literal(json.dumps(outlist), pm.XSD['string'])
704722
try:
705-
if isinstance(x, dict):
706-
outdict = {}
707-
for key, value in x.items():
708-
outdict[key] = safe_encode(value)
709-
return pm.Literal(json.dumps(outdict), pm.XSD['string'])
710-
if isinstance(x, list):
711-
outlist = [safe_encode(value) for value in x]
712-
return pm.Literal(json.dumps(outlist), pm.XSD['string'])
713-
return pm.Literal(dumps(x),
714-
nipype['pickle'])
715-
except TypeError:
723+
return pm.Literal(dumps(x), nipype['pickle'])
724+
except TypeError, e:
725+
iflogger.info(e)
716726
return pm.Literal("Could not encode", pm.XSD['string'])
717727

718728

nipype/interfaces/freesurfer/preprocess.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -784,6 +784,8 @@ class ApplyVolTransformInputSpec(FSTraitedSpec):
784784
desc='Output template volume', mandatory=True)
785785
tal = traits.Bool(argstr='--tal', xor=_targ_xor, mandatory=True,
786786
desc='map to a sub FOV of MNI305 (with --reg only)')
787+
tal_resolution = traits.Float(argstr="--talres %.10f",
788+
desc="Resolution to sample when using tal")
787789
fs_target = traits.Bool(argstr='--fstarg', xor=_targ_xor, mandatory=True,
788790
requires=['reg_file'],
789791
desc='use orig.mgz from subject in regfile as target')
@@ -805,10 +807,30 @@ class ApplyVolTransformInputSpec(FSTraitedSpec):
805807
desc='set matrix = identity and use subject for any templates')
806808
inverse = traits.Bool(desc='sample from target to source',
807809
argstr='--inv')
808-
interp = traits.Enum('trilin', 'nearest', argstr='--interp %s',
810+
interp = traits.Enum('trilin', 'nearest', 'cubic', argstr='--interp %s',
809811
desc='Interpolation method (<trilin> or nearest)')
810812
no_resample = traits.Bool(desc='Do not resample; just change vox2ras matrix',
811813
argstr='--no-resample')
814+
m3z_file = File(argstr="--m3z %s",
815+
desc=('This is the morph to be applied to the volume. '
816+
'Unless the morph is in mri/transforms (eg.: for '
817+
'talairach.m3z computed by reconall), you will need '
818+
'to specify the full path to this morph and use the '
819+
'--noDefM3zPath flag.'))
820+
no_ded_m3z_path = traits.Bool(argstr="--noDefM3zPath",
821+
requires=['m3z_file'],
822+
desc=('To be used with the m3z flag. '
823+
'Instructs the code not to look for the'
824+
'm3z morph in the default location '
825+
'(SUBJECTS_DIR/subj/mri/transforms), '
826+
'but instead just use the path '
827+
'indicated in --m3z.'))
828+
829+
invert_morph = traits.Bool(argstr="--inv-morph",
830+
requires=['m3z_file'],
831+
desc=('Compute and use the inverse of the '
832+
'non-linear morph to resample the input '
833+
'volume. To be used by --m3z.'))
812834

813835

814836
class ApplyVolTransformOutputSpec(TraitedSpec):
@@ -853,7 +875,7 @@ def _get_outfile(self):
853875

854876
def _list_outputs(self):
855877
outputs = self.output_spec().get()
856-
outputs['transformed_file'] = self._get_outfile()
878+
outputs['transformed_file'] = os.path.abspath(self._get_outfile())
857879
return outputs
858880

859881
def _gen_filename(self, name):
@@ -1192,11 +1214,3 @@ def _gen_filename(self, name):
11921214
if name == "out_file":
11931215
return self._list_outputs()["out_file"]
11941216
return None
1195-
1196-
'''
1197-
interfaces to do:
1198-
1199-
mri_vol2surf
1200-
mri_surf2vol
1201-
mri_surf2surf
1202-
'''

nipype/pipeline/engine.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,7 @@ def hash_exists(self, updatehash=False):
12111211
outdir = self.output_dir()
12121212
hashfiles = glob(os.path.join(outdir, '_0x*.json'))
12131213
if len(hashfiles) > 1:
1214-
warn('Removing multiple hashfiles and forcing node to rerun')
1214+
logger.info('Removing multiple hashfiles and forcing node to rerun')
12151215
for hashfile in hashfiles:
12161216
os.unlink(hashfile)
12171217
hashfile = os.path.join(outdir, '_0x%s.json' % hashvalue)

0 commit comments

Comments
 (0)