Skip to content

Commit b43941c

Browse files
committed
Merge branch 'master' into enh/ChainedNameSource
Conflicts: CHANGES
2 parents 5f991fb + ee31238 commit b43941c

File tree

8 files changed

+166
-60
lines changed

8 files changed

+166
-60
lines changed

CHANGES

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ Next release
22
============
33

44
* ENH: Inputs with name_source can be now chained in cascade (https://github.com/nipy/nipype/pull/938)
5+
* ENH: Improve JSON interfaces: default settings when reading and consistent output creation
6+
when writing (https://github.com/nipy/nipype/pull/1047)
7+
* FIX: AddCSVRow problems when using infields (https://github.com/nipy/nipype/pull/1028)
8+
* FIX: Removed unused ANTS registration flag (https://github.com/nipy/nipype/pull/999)
59
* FIX: Amend create_tbss_non_fa() workflow to match FSL's tbss_non_fa command. (https://github.com/nipy/nipype/pull/1033)
610
* FIX: remove unused mandatory flag from spm normalize (https://github.com/nipy/nipype/pull/1048)
711
* ENH: Update ANTSCorticalThickness interface (https://github.com/nipy/nipype/pull/1013)

nipype/algorithms/misc.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
from ..interfaces.base import (BaseInterface, traits, TraitedSpec, File,
3535
InputMultiPath, OutputMultiPath,
3636
BaseInterfaceInputSpec, isdefined,
37-
DynamicTraitedSpec)
37+
DynamicTraitedSpec, Undefined)
3838
from nipype.utils.filemanip import fname_presuffix, split_filename
3939
iflogger = logging.getLogger('interface')
4040

@@ -785,7 +785,8 @@ def _list_outputs(self):
785785

786786

787787
class AddCSVRowInputSpec(DynamicTraitedSpec, BaseInterfaceInputSpec):
788-
in_file = traits.File(mandatory=True, desc='Input comma-separated value (CSV) files')
788+
in_file = traits.File(mandatory=True,
789+
desc='Input comma-separated value (CSV) files')
789790
_outputs = traits.Dict(traits.Any, value={}, usedefault=True)
790791

791792
def __setattr__(self, key, value):
@@ -804,13 +805,15 @@ class AddCSVRowOutputSpec(TraitedSpec):
804805

805806

806807
class AddCSVRow(BaseInterface):
808+
807809
"""Simple interface to add an extra row to a csv file
808810
809811
.. note:: Requires `pandas <http://pandas.pydata.org/>`_
810812
811813
.. warning:: Multi-platform thread-safe execution is possible with
812-
`lockfile <https://pythonhosted.org/lockfile/lockfile.html>`_. Please recall that (1)
813-
this module is alpha software; and (2) it should be installed for thread-safe writing.
814+
`lockfile <https://pythonhosted.org/lockfile/lockfile.html>`_. Please
815+
recall that (1) this module is alpha software; and (2) it should be
816+
installed for thread-safe writing.
814817
If lockfile is not installed, then the interface is not thread-safe.
815818
816819
@@ -822,7 +825,7 @@ class AddCSVRow(BaseInterface):
822825
>>> addrow.inputs.in_file = 'scores.csv'
823826
>>> addrow.inputs.si = 0.74
824827
>>> addrow.inputs.di = 0.93
825-
>>> addrow.subject_id = 'S400'
828+
>>> addrow.inputs.subject_id = 'S400'
826829
>>> addrow.inputs.list_of_values = [ 0.4, 0.7, 0.3 ]
827830
>>> addrow.run() # doctest: +SKIP
828831
"""
@@ -850,22 +853,26 @@ def _run_interface(self, runtime):
850853
try:
851854
import pandas as pd
852855
except ImportError:
853-
raise ImportError('This interface requires pandas (http://pandas.pydata.org/) to run.')
856+
raise ImportError(('This interface requires pandas '
857+
'(http://pandas.pydata.org/) to run.'))
854858

855859
try:
856860
import lockfile as pl
857861
self._have_lock = True
858862
except ImportError:
859-
import warnings
860-
warnings.warn(('Python module lockfile was not found: AddCSVRow will not be thread-safe '
861-
'in multi-processor execution'))
863+
from warnings import warn
864+
warn(('Python module lockfile was not found: AddCSVRow will not be'
865+
' thread-safe in multi-processor execution'))
862866

863867
input_dict = {}
864868
for key, val in self.inputs._outputs.items():
865869
# expand lists to several columns
870+
if key == 'trait_added' and val in self.inputs.copyable_trait_names():
871+
continue
872+
866873
if isinstance(val, list):
867-
for i,v in enumerate(val):
868-
input_dict['%s_%d' % (key,i)]=v
874+
for i, v in enumerate(val):
875+
input_dict['%s_%d' % (key, i)] = v
869876
else:
870877
input_dict[key] = val
871878

@@ -887,6 +894,13 @@ def _run_interface(self, runtime):
887894
if self._have_lock:
888895
self._lock.release()
889896

897+
# Using nipype.external.portalocker this might be something like:
898+
# with pl.Lock(self.inputs.in_file, timeout=1) as fh:
899+
# if op.exists(fh):
900+
# formerdf = pd.read_csv(fh, index_col=0)
901+
# df = pd.concat([formerdf, df], ignore_index=True)
902+
# df.to_csv(fh)
903+
890904
return runtime
891905

892906
def _list_outputs(self):

nipype/interfaces/ants/registration.py

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,6 @@ class RegistrationInputSpec(ANTSCommandInputSpec):
320320
low=0.0, high=1.0, value=1.0, argstr='%s', usedefault=True, desc="The Upper quantile to clip image ranges")
321321
winsorize_lower_quantile = traits.Range(
322322
low=0.0, high=1.0, value=0.0, argstr='%s', usedefault=True, desc="The Lower quantile to clip image ranges")
323-
collapse_linear_transforms_to_fixed_image_header = traits.Bool(
324-
argstr='%s', default=False, usedefault=True, desc='')
325323

326324

327325
class RegistrationOutputSpec(TraitedSpec):
@@ -376,29 +374,35 @@ class Registration(ANTSCommand):
376374
377375
>>> reg1 = copy.deepcopy(reg)
378376
>>> reg1.inputs.winsorize_lower_quantile = 0.025
379-
>>> reg1.inputs.collapse_linear_transforms_to_fixed_image_header = False
380377
>>> reg1.cmdline
381-
'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'
378+
'antsRegistration --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'
382379
>>> reg1.run() #doctest: +SKIP
383380
384381
>>> reg2 = copy.deepcopy(reg)
385382
>>> reg2.inputs.winsorize_upper_quantile = 0.975
386383
>>> reg2.cmdline
387-
'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'
384+
'antsRegistration --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'
388385
389386
>>> reg3 = copy.deepcopy(reg)
390387
>>> reg3.inputs.winsorize_lower_quantile = 0.025
391388
>>> reg3.inputs.winsorize_upper_quantile = 0.975
392389
>>> reg3.cmdline
393-
'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'
390+
'antsRegistration --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'
394391
395392
>>> # Test collapse transforms flag
396393
>>> reg4 = copy.deepcopy(reg)
397394
>>> reg4.inputs.collapse_output_transforms = True
398395
>>> outputs = reg4._list_outputs()
399396
>>> print outputs #doctest: +ELLIPSIS
400-
{'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']}
401-
>>> reg4.aggregate_outputs() #doctest: +SKIP
397+
{'reverse_invert_flags': [], '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': [], 'reverse_transforms': [], 'composite_transform': ['.../nipype/testing/data/output_Composite.h5'], 'forward_transforms': []}
398+
399+
>>> # Test collapse transforms flag
400+
>>> reg4b = copy.deepcopy(reg4)
401+
>>> reg4b.inputs.write_composite_transform = False
402+
>>> outputs = reg4b._list_outputs()
403+
>>> print outputs #doctest: +ELLIPSIS
404+
{'reverse_invert_flags': [True, False], 'inverse_composite_transform': <undefined>, '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': <undefined>, 'forward_transforms': ['.../nipype/testing/data/output_0GenericAffine.mat', '.../nipype/testing/data/output_1Warp.nii.gz']}
405+
>>> reg4b.aggregate_outputs() #doctest: +SKIP
402406
403407
>>> # Test multiple metrics per stage
404408
>>> reg5 = copy.deepcopy(reg)
@@ -408,7 +412,7 @@ class Registration(ANTSCommand):
408412
>>> reg5.inputs.sampling_strategy = ['Random', None] # use default strategy in second stage
409413
>>> reg5.inputs.sampling_percentage = [0.05, [0.05, 0.10]]
410414
>>> reg5.cmdline
411-
'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, None, 0.05 ] --metric Mattes[ fixed1.nii, moving1.nii, 0.5, 32, None, 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'
415+
'antsRegistration --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, None, 0.05 ] --metric Mattes[ fixed1.nii, moving1.nii, 0.5, 32, None, 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'
412416
"""
413417
DEF_SAMPLING_STRATEGY = 'None'
414418
"""The default sampling strategy argument."""
@@ -579,9 +583,11 @@ def _formatWinsorizeImageIntensities(self):
579583

580584
def _formatCollapseLinearTransformsToFixedImageHeader(self):
581585
if self.inputs.collapse_linear_transforms_to_fixed_image_header:
582-
return '--collapse-linear-transforms-to-fixed-image-header 1'
586+
# return '--collapse-linear-transforms-to-fixed-image-header 1'
587+
return ''
583588
else:
584-
return '--collapse-linear-transforms-to-fixed-image-header 0'
589+
# return '--collapse-linear-transforms-to-fixed-image-header 0'
590+
return ''
585591

586592
def _format_arg(self, opt, spec, val):
587593
if opt == 'fixed_image_mask':
@@ -710,7 +716,7 @@ def _list_outputs(self):
710716
outputs[
711717
'reverse_invert_flags'].insert(0, reverseInverseMode)
712718
transformCount += 1
713-
else:
719+
elif not self.inputs.write_composite_transform:
714720
transformCount = 0
715721
isLinear = [any(self._linear_transform_names == t)
716722
for t in self.inputs.transforms]

nipype/interfaces/ants/tests/test_auto_Registration.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@
55
def test_Registration_inputs():
66
input_map = dict(args=dict(argstr='%s',
77
),
8-
collapse_linear_transforms_to_fixed_image_header=dict(argstr='%s',
9-
usedefault=True,
10-
),
118
collapse_output_transforms=dict(argstr='--collapse-output-transforms %d',
129
usedefault=True,
1310
),

0 commit comments

Comments
 (0)