Skip to content

Commit a7e756a

Browse files
authored
Merge pull request #1799 from cgc/intmap_ext
fix: FSL FNIRT intensity mapping files
2 parents 7d4d5e4 + 7a8eb07 commit a7e756a

File tree

2 files changed

+79
-33
lines changed

2 files changed

+79
-33
lines changed

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)