Skip to content

Commit 94e6504

Browse files
committed
Merge branch 'master' of github.com:nipy/nipype into add_antsMotionCorr
2 parents 3b5f99d + 4dc5ab1 commit 94e6504

File tree

6 files changed

+120
-36
lines changed

6 files changed

+120
-36
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ install:
3333
conda config --add channels conda-forge &&
3434
conda update --yes conda &&
3535
conda update --all -y python=$TRAVIS_PYTHON_VERSION &&
36-
conda install -y nipype &&
36+
conda install -y nipype icu==56.1 &&
3737
rm -r /home/travis/miniconda/lib/python${TRAVIS_PYTHON_VERSION}/site-packages/nipype* &&
3838
pip install -r requirements.txt &&
3939
pip install -e .[$NIPYPE_EXTRAS]; }

doc/devel/interface_specs.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ CommandLine
353353
be fixed it's recommended to just use ``usedefault``.
354354

355355
``sep``
356-
For List traits the string with witch elements of the list will be joined.
356+
For List traits the string with which elements of the list will be joined.
357357

358358
``name_source``
359359
Indicates the list of input fields from which the value of the current File

doc/users/config_file.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Execution
5555
Should the input files be checked for changes using their content (slow, but
5656
100% accurate) or just their size and modification date (fast, but
5757
potentially prone to errors)? (possible values: ``content`` and
58-
``timestamp``; default value: ``content``)
58+
``timestamp``; default value: ``timestamp``)
5959

6060
*keep_inputs*
6161
Ensures that all inputs that are created in the nodes working directory are

nipype/interfaces/fsl/epi.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,20 @@ class EddyOutputSpec(TraitedSpec):
454454
out_parameter = File(exists=True,
455455
desc=('text file with parameters definining the '
456456
'field and movement for each scan'))
457+
out_rotated_bvecs = File(exists=True,
458+
desc=('File containing rotated b-values for all volumes'))
459+
out_movement_rms = File(exists=True,
460+
desc=('Summary of the "total movement" in each volume'))
461+
out_restricted_movement_rms = File(exists=True,
462+
desc=('Summary of the "total movement" in each volume '
463+
'disregarding translation in the PE direction'))
464+
out_shell_alignment_parameters = File(exists=True,
465+
desc=('File containing rigid body movement parameters '
466+
'between the different shells as estimated by a '
467+
'post-hoc mutual information based registration'))
468+
out_outlier_report = File(exists=True,
469+
desc=('Text-file with a plain language report '
470+
'on what outlier slices eddy has found'))
457471

458472

459473
class Eddy(FSLCommand):
@@ -526,6 +540,30 @@ def _list_outputs(self):
526540
'%s.nii.gz' % self.inputs.out_base)
527541
outputs['out_parameter'] = os.path.abspath(
528542
'%s.eddy_parameters' % self.inputs.out_base)
543+
544+
# File generation might depend on the version of EDDY
545+
out_rotated_bvecs = os.path.abspath(
546+
'%s.eddy_rotated_bvecs' % self.inputs.out_base)
547+
out_movement_rms = os.path.abspath(
548+
'%s.eddy_movement_rms' % self.inputs.out_base)
549+
out_restricted_movement_rms = os.path.abspath(
550+
'%s.eddy_restricted_movement_rms' % self.inputs.out_base)
551+
out_shell_alignment_parameters = os.path.abspath(
552+
'%s.eddy_post_eddy_shell_alignment_parameters' % self.inputs.out_base)
553+
out_outlier_report = os.path.abspath(
554+
'%s.eddy_outlier_report' % self.inputs.out_base)
555+
556+
if os.path.exists(out_rotated_bvecs):
557+
outputs['out_rotated_bvecs'] = out_rotated_bvecs
558+
if os.path.exists(out_movement_rms):
559+
outputs['out_movement_rms'] = out_movement_rms
560+
if os.path.exists(out_restricted_movement_rms):
561+
outputs['out_restricted_movement_rms'] = out_restricted_movement_rms
562+
if os.path.exists(out_shell_alignment_parameters):
563+
outputs['out_shell_alignment_parameters'] = out_shell_alignment_parameters
564+
if os.path.exists(out_outlier_report):
565+
outputs['out_outlier_report'] = out_outlier_report
566+
529567
return outputs
530568

531569

nipype/interfaces/fsl/preprocess.py

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
from ..base import (TraitedSpec, File, InputMultiPath,
2626
OutputMultiPath, Undefined, traits,
2727
isdefined)
28-
from .base import FSLCommand, FSLCommandInputSpec
28+
from .base import FSLCommand, FSLCommandInputSpec, Info
2929

3030

3131
class BETInputSpec(FSLCommandInputSpec):
@@ -750,10 +750,12 @@ class FNIRTInputSpec(FSLCommandInputSpec):
750750
desc='name of file containing affine transform')
751751
inwarp_file = File(exists=True, argstr='--inwarp=%s',
752752
desc='name of file containing initial non-linear warps')
753-
in_intensitymap_file = File(exists=True, argstr='--intin=%s',
754-
desc=('name of file/files containing initial '
755-
'intensity maping usually generated by '
756-
'previous fnirt run'))
753+
in_intensitymap_file = traits.List(File(exists=True), argstr='--intin=%s',
754+
copyfiles=False, minlen=1, maxlen=2,
755+
desc=('name of file/files containing '
756+
'initial intensity mapping '
757+
'usually generated by previous '
758+
'fnirt run'))
757759
fieldcoeff_file = traits.Either(
758760
traits.Bool, File, argstr='--cout=%s',
759761
desc='name of output file with field coefficients or true')
@@ -907,8 +909,9 @@ class FNIRTOutputSpec(TraitedSpec):
907909
field_file = File(desc='file with warp field')
908910
jacobian_file = File(desc='file containing Jacobian of the field')
909911
modulatedref_file = File(desc='file containing intensity modulated --ref')
910-
out_intensitymap_file = File(
911-
desc='file containing info pertaining to intensity mapping')
912+
out_intensitymap_file = traits.List(
913+
File, minlen=2, maxlen=2,
914+
desc='files containing info pertaining to intensity mapping')
912915
log_file = File(desc='Name of log-file')
913916

914917

@@ -975,9 +978,23 @@ def _list_outputs(self):
975978
change_ext=change_ext)
976979
else:
977980
outputs[key] = os.path.abspath(inval)
981+
982+
if key == 'out_intensitymap_file' and isdefined(outputs[key]):
983+
basename = FNIRT.intensitymap_file_basename(outputs[key])
984+
outputs[key] = [
985+
outputs[key],
986+
'%s.txt' % basename,
987+
]
978988
return outputs
979989

980990
def _format_arg(self, name, spec, value):
991+
if name in ('in_intensitymap_file', 'out_intensitymap_file'):
992+
if name == 'out_intensitymap_file':
993+
value = self._list_outputs()[name]
994+
value = [FNIRT.intensitymap_file_basename(v) for v in value]
995+
assert len(set(value)) == 1, (
996+
'Found different basenames for {}: {}'.format(name, value))
997+
return spec.argstr % value[0]
981998
if name in list(self.filemap.keys()):
982999
return spec.argstr % self._list_outputs()[name]
9831000
return super(FNIRT, self)._format_arg(name, spec, value)
@@ -1005,6 +1022,17 @@ def write_config(self, configfile):
10051022
fid.write('%s\n' % (item))
10061023
fid.close()
10071024

1025+
@classmethod
1026+
def intensitymap_file_basename(cls, f):
1027+
"""Removes valid intensitymap extensions from `f`, returning a basename
1028+
that can refer to both intensitymap files.
1029+
"""
1030+
for ext in list(Info.ftypes.values()) + ['.txt']:
1031+
if f.endswith(ext):
1032+
return f[:-len(ext)]
1033+
# TODO consider warning for this case
1034+
return f
1035+
10081036

10091037
class ApplyWarpInputSpec(FSLCommandInputSpec):
10101038
in_file = File(exists=True, argstr='--in=%s',

nipype/interfaces/fsl/tests/test_preprocess.py

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ def test_mcflirt(setup_flirt):
353353
def test_fnirt(setup_flirt):
354354

355355
tmpdir, infile, reffile = setup_flirt
356+
os.chdir(tmpdir)
356357
fnirt = fsl.FNIRT()
357358
assert fnirt.cmd == 'fnirt'
358359

@@ -404,64 +405,81 @@ def test_fnirt(setup_flirt):
404405
fnirt.run()
405406
fnirt.inputs.in_file = infile
406407
fnirt.inputs.ref_file = reffile
408+
intmap_basename = '%s_intmap' % fsl.FNIRT.intensitymap_file_basename(infile)
409+
intmap_image = fsl_name(fnirt, intmap_basename)
410+
intmap_txt = '%s.txt' % intmap_basename
411+
# doing this to create the file to pass tests for file existence
412+
with open(intmap_image, 'w'):
413+
pass
414+
with open(intmap_txt, 'w'):
415+
pass
407416

408417
# test files
409-
opt_map = {
410-
'affine_file': ('--aff='),
411-
'inwarp_file': ('--inwarp='),
412-
'in_intensitymap_file': ('--intin='),
413-
'config_file': ('--config='),
414-
'refmask_file': ('--refmask='),
415-
'inmask_file': ('--inmask='),
416-
'field_file': ('--fout='),
417-
'jacobian_file': ('--jout='),
418-
'modulatedref_file': ('--refout='),
419-
'out_intensitymap_file': ('--intout='),
420-
'log_file': ('--logout=')}
421-
422-
for name, settings in list(opt_map.items()):
418+
opt_map = [
419+
('affine_file', '--aff=%s' % infile, infile),
420+
('inwarp_file', '--inwarp=%s' % infile, infile),
421+
('in_intensitymap_file', '--intin=%s' % intmap_basename, [intmap_image]),
422+
('in_intensitymap_file',
423+
'--intin=%s' % intmap_basename,
424+
[intmap_image, intmap_txt]),
425+
('config_file', '--config=%s' % infile, infile),
426+
('refmask_file', '--refmask=%s' % infile, infile),
427+
('inmask_file', '--inmask=%s' % infile, infile),
428+
('field_file', '--fout=%s' % infile, infile),
429+
('jacobian_file', '--jout=%s' % infile, infile),
430+
('modulatedref_file', '--refout=%s' % infile, infile),
431+
('out_intensitymap_file',
432+
'--intout=%s' % intmap_basename, True),
433+
('out_intensitymap_file', '--intout=%s' % intmap_basename, intmap_image),
434+
('fieldcoeff_file', '--cout=%s' % infile, infile),
435+
('log_file', '--logout=%s' % infile, infile)]
436+
437+
for (name, settings, arg) in opt_map:
423438
fnirt = fsl.FNIRT(in_file=infile,
424439
ref_file=reffile,
425-
**{name: infile})
440+
**{name: arg})
426441

427-
if name in ('config_file', 'affine_file', 'field_file'):
428-
cmd = 'fnirt %s%s --in=%s '\
442+
if name in ('config_file', 'affine_file', 'field_file', 'fieldcoeff_file'):
443+
cmd = 'fnirt %s --in=%s '\
429444
'--logout=%s '\
430-
'--ref=%s --iout=%s' % (settings, infile, infile, log,
445+
'--ref=%s --iout=%s' % (settings, infile, log,
431446
reffile, iout)
432447
elif name in ('refmask_file'):
433448
cmd = 'fnirt --in=%s '\
434449
'--logout=%s --ref=%s '\
435-
'%s%s '\
450+
'%s '\
436451
'--iout=%s' % (infile, log,
437452
reffile,
438-
settings, infile,
453+
settings,
439454
iout)
440455
elif name in ('in_intensitymap_file', 'inwarp_file', 'inmask_file', 'jacobian_file'):
441456
cmd = 'fnirt --in=%s '\
442-
'%s%s '\
457+
'%s '\
443458
'--logout=%s --ref=%s '\
444459
'--iout=%s' % (infile,
445-
settings, infile,
460+
settings,
446461
log,
447462
reffile,
448463
iout)
449464
elif name in ('log_file'):
450465
cmd = 'fnirt --in=%s '\
451-
'%s%s --ref=%s '\
466+
'%s --ref=%s '\
452467
'--iout=%s' % (infile,
453-
settings, infile,
468+
settings,
454469
reffile,
455470
iout)
456471
else:
457472
cmd = 'fnirt --in=%s '\
458-
'--logout=%s %s%s '\
473+
'--logout=%s %s '\
459474
'--ref=%s --iout=%s' % (infile, log,
460-
settings, infile,
475+
settings,
461476
reffile, iout)
462477

463478
assert fnirt.cmdline == cmd
464479

480+
if name == 'out_intensitymap_file':
481+
assert fnirt._list_outputs()['out_intensitymap_file'] == [
482+
intmap_image, intmap_txt]
465483

466484
@pytest.mark.skipif(no_fsl(), reason="fsl is not installed")
467485
def test_applywarp(setup_flirt):

0 commit comments

Comments
 (0)