Skip to content

Commit f3bb9e8

Browse files
authored
Merge pull request #2205 from effigies/fix/robust_register
FIX: Create out_reg_file correctly in RobustRegister
2 parents 3fde2fb + efaaaa2 commit f3bb9e8

File tree

3 files changed

+94
-75
lines changed

3 files changed

+94
-75
lines changed

nipype/interfaces/freesurfer/preprocess.py

Lines changed: 89 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,76 +1457,102 @@ def _gen_filename(self, name):
14571457

14581458
class RobustRegisterInputSpec(FSTraitedSpec):
14591459

1460-
source_file = File(mandatory=True, argstr='--mov %s',
1460+
source_file = File(exists=True, mandatory=True, argstr='--mov %s',
14611461
desc='volume to be registered')
1462-
target_file = File(mandatory=True, argstr='--dst %s',
1462+
target_file = File(exists=True, mandatory=True, argstr='--dst %s',
14631463
desc='target volume for the registration')
1464-
out_reg_file = File(genfile=True, argstr='--lta %s',
1465-
desc='registration file to write')
1466-
registered_file = traits.Either(traits.Bool, File, argstr='--warp %s',
1467-
desc='registered image; either True or filename')
1468-
weights_file = traits.Either(traits.Bool, File, argstr='--weights %s',
1469-
desc='weights image to write; either True or filename')
1470-
est_int_scale = traits.Bool(argstr='--iscale',
1471-
desc='estimate intensity scale (recommended for unnormalized images)')
1464+
out_reg_file = traits.Either(
1465+
True, File, default=True, usedefault=True, argstr='--lta %s',
1466+
desc='registration file; either True or filename')
1467+
registered_file = traits.Either(
1468+
traits.Bool, File, argstr='--warp %s',
1469+
desc='registered image; either True or filename')
1470+
weights_file = traits.Either(
1471+
traits.Bool, File, argstr='--weights %s',
1472+
desc='weights image to write; either True or filename')
1473+
est_int_scale = traits.Bool(
1474+
argstr='--iscale',
1475+
desc='estimate intensity scale (recommended for unnormalized images)')
14721476
trans_only = traits.Bool(argstr='--transonly',
14731477
desc='find 3 parameter translation only')
14741478
in_xfm_file = File(exists=True, argstr='--transform',
14751479
desc='use initial transform on source')
1476-
half_source = traits.Either(traits.Bool, File, argstr='--halfmov %s',
1477-
desc="write source volume mapped to halfway space")
1478-
half_targ = traits.Either(traits.Bool, File, argstr="--halfdst %s",
1479-
desc="write target volume mapped to halfway space")
1480-
half_weights = traits.Either(traits.Bool, File, argstr="--halfweights %s",
1481-
desc="write weights volume mapped to halfway space")
1482-
half_source_xfm = traits.Either(traits.Bool, File, argstr="--halfmovlta %s",
1483-
desc="write transform from source to halfway space")
1484-
half_targ_xfm = traits.Either(traits.Bool, File, argstr="--halfdstlta %s",
1485-
desc="write transform from target to halfway space")
1486-
auto_sens = traits.Bool(argstr='--satit', xor=['outlier_sens'], mandatory=True,
1487-
desc='auto-detect good sensitivity')
1488-
outlier_sens = traits.Float(argstr='--sat %.4f', xor=['auto_sens'], mandatory=True,
1489-
desc='set outlier sensitivity explicitly')
1490-
least_squares = traits.Bool(argstr='--leastsquares',
1491-
desc='use least squares instead of robust estimator')
1480+
half_source = traits.Either(
1481+
traits.Bool, File, argstr='--halfmov %s',
1482+
desc="write source volume mapped to halfway space")
1483+
half_targ = traits.Either(
1484+
traits.Bool, File, argstr="--halfdst %s",
1485+
desc="write target volume mapped to halfway space")
1486+
half_weights = traits.Either(
1487+
traits.Bool, File, argstr="--halfweights %s",
1488+
desc="write weights volume mapped to halfway space")
1489+
half_source_xfm = traits.Either(
1490+
traits.Bool, File, argstr="--halfmovlta %s",
1491+
desc="write transform from source to halfway space")
1492+
half_targ_xfm = traits.Either(
1493+
traits.Bool, File, argstr="--halfdstlta %s",
1494+
desc="write transform from target to halfway space")
1495+
auto_sens = traits.Bool(
1496+
argstr='--satit', xor=['outlier_sens'], mandatory=True,
1497+
desc='auto-detect good sensitivity')
1498+
outlier_sens = traits.Float(
1499+
argstr='--sat %.4f', xor=['auto_sens'], mandatory=True,
1500+
desc='set outlier sensitivity explicitly')
1501+
least_squares = traits.Bool(
1502+
argstr='--leastsquares',
1503+
desc='use least squares instead of robust estimator')
14921504
no_init = traits.Bool(argstr='--noinit', desc='skip transform init')
1493-
init_orient = traits.Bool(argstr='--initorient',
1494-
desc='use moments for initial orient (recommended for stripped brains)')
1505+
init_orient = traits.Bool(
1506+
argstr='--initorient',
1507+
desc='use moments for initial orient (recommended for stripped brains)'
1508+
)
14951509
max_iterations = traits.Int(argstr='--maxit %d',
14961510
desc='maximum # of times on each resolution')
14971511
high_iterations = traits.Int(argstr='--highit %d',
14981512
desc='max # of times on highest resolution')
1499-
iteration_thresh = traits.Float(argstr='--epsit %.3f',
1500-
desc='stop iterations when below threshold')
1501-
subsample_thresh = traits.Int(argstr='--subsample %d',
1502-
desc='subsample if dimension is above threshold size')
1513+
iteration_thresh = traits.Float(
1514+
argstr='--epsit %.3f', desc='stop iterations when below threshold')
1515+
subsample_thresh = traits.Int(
1516+
argstr='--subsample %d',
1517+
desc='subsample if dimension is above threshold size')
15031518
outlier_limit = traits.Float(argstr='--wlimit %.3f',
15041519
desc='set maximal outlier limit in satit')
1505-
write_vo2vox = traits.Bool(argstr='--vox2vox',
1506-
desc='output vox2vox matrix (default is RAS2RAS)')
1507-
no_multi = traits.Bool(argstr='--nomulti', desc='work on highest resolution')
1520+
write_vo2vox = traits.Bool(
1521+
argstr='--vox2vox', desc='output vox2vox matrix (default is RAS2RAS)')
1522+
no_multi = traits.Bool(argstr='--nomulti',
1523+
desc='work on highest resolution')
15081524
mask_source = File(exists=True, argstr='--maskmov %s',
15091525
desc='image to mask source volume with')
15101526
mask_target = File(exists=True, argstr='--maskdst %s',
15111527
desc='image to mask target volume with')
1512-
force_double = traits.Bool(argstr='--doubleprec', desc='use double-precision intensities')
1513-
force_float = traits.Bool(argstr='--floattype', desc='use float intensities')
1528+
force_double = traits.Bool(argstr='--doubleprec',
1529+
desc='use double-precision intensities')
1530+
force_float = traits.Bool(argstr='--floattype',
1531+
desc='use float intensities')
15141532

15151533

15161534
class RobustRegisterOutputSpec(TraitedSpec):
15171535

15181536
out_reg_file = File(exists=True, desc="output registration file")
1519-
registered_file = File(desc="output image with registration applied")
1520-
weights_file = File(desc="image of weights used")
1521-
half_source = File(desc="source image mapped to halfway space")
1522-
half_targ = File(desc="target image mapped to halfway space")
1523-
half_weights = File(desc="weights image mapped to halfway space")
1524-
half_source_xfm = File(desc="transform file to map source image to halfway space")
1525-
half_targ_xfm = File(desc="transform file to map target image to halfway space")
1537+
registered_file = File(exists=True,
1538+
desc="output image with registration applied")
1539+
weights_file = File(exists=True, desc="image of weights used")
1540+
half_source = File(exists=True,
1541+
desc="source image mapped to halfway space")
1542+
half_targ = File(exists=True, desc="target image mapped to halfway space")
1543+
half_weights = File(exists=True,
1544+
desc="weights image mapped to halfway space")
1545+
half_source_xfm = File(
1546+
exists=True,
1547+
desc="transform file to map source image to halfway space")
1548+
half_targ_xfm = File(
1549+
exists=True,
1550+
desc="transform file to map target image to halfway space")
15261551

15271552

15281553
class RobustRegister(FSCommand):
1529-
"""Perform intramodal linear registration (translation and rotation) using robust statistics.
1554+
"""Perform intramodal linear registration (translation and rotation) using
1555+
robust statistics.
15301556
15311557
Examples
15321558
--------
@@ -1536,13 +1562,13 @@ class RobustRegister(FSCommand):
15361562
>>> reg.inputs.target_file = 'T1.nii'
15371563
>>> reg.inputs.auto_sens = True
15381564
>>> reg.inputs.init_orient = True
1539-
>>> reg.cmdline # doctest: +ALLOW_UNICODE
1540-
'mri_robust_register --satit --initorient --lta structural_robustreg.lta --mov structural.nii --dst T1.nii'
1565+
>>> reg.cmdline # doctest: +ALLOW_UNICODE +ELLIPSIS
1566+
'mri_robust_register --satit --initorient --lta .../structural_robustreg.lta --mov structural.nii --dst T1.nii'
15411567
15421568
References
15431569
----------
1544-
Reuter, M, Rosas, HD, and Fischl, B, (2010). Highly Accurate Inverse Consistent Registration:
1545-
A Robust Approach. Neuroimage 53(4) 1181-96.
1570+
Reuter, M, Rosas, HD, and Fischl, B, (2010). Highly Accurate Inverse
1571+
Consistent Registration: A Robust Approach. Neuroimage 53(4) 1181-96.
15461572
15471573
"""
15481574

@@ -1551,24 +1577,20 @@ class RobustRegister(FSCommand):
15511577
output_spec = RobustRegisterOutputSpec
15521578

15531579
def _format_arg(self, name, spec, value):
1554-
for option in ["registered_file", "weights_file", "half_source", "half_targ",
1555-
"half_weights", "half_source_xfm", "half_targ_xfm"]:
1556-
if name == option:
1557-
if isinstance(value, bool):
1558-
fname = self._list_outputs()[name]
1559-
else:
1560-
fname = value
1561-
return spec.argstr % fname
1580+
options = ("out_reg_file", "registered_file", "weights_file",
1581+
"half_source", "half_targ", "half_weights",
1582+
"half_source_xfm", "half_targ_xfm")
1583+
if name in options and isinstance(value, bool):
1584+
value = self._list_outputs()[name]
15621585
return super(RobustRegister, self)._format_arg(name, spec, value)
15631586

15641587
def _list_outputs(self):
15651588
outputs = self.output_spec().get()
1566-
outputs['out_reg_file'] = self.inputs.out_reg_file
1567-
if not isdefined(self.inputs.out_reg_file) and self.inputs.source_file:
1568-
outputs['out_reg_file'] = fname_presuffix(self.inputs.source_file,
1569-
suffix='_robustreg.lta', use_ext=False)
1570-
prefices = dict(src=self.inputs.source_file, trg=self.inputs.target_file)
1571-
suffices = dict(registered_file=("src", "_robustreg", True),
1589+
cwd = os.getcwd()
1590+
prefices = dict(src=self.inputs.source_file,
1591+
trg=self.inputs.target_file)
1592+
suffices = dict(out_reg_file=("src", "_robustreg.lta", False),
1593+
registered_file=("src", "_robustreg", True),
15721594
weights_file=("src", "_robustweights", True),
15731595
half_source=("src", "_halfway", True),
15741596
half_targ=("trg", "_halfway", True),
@@ -1577,21 +1599,16 @@ def _list_outputs(self):
15771599
half_targ_xfm=("trg", "_robustxfm.lta", False))
15781600
for name, sufftup in list(suffices.items()):
15791601
value = getattr(self.inputs, name)
1580-
if isdefined(value):
1581-
if isinstance(value, bool):
1602+
if value:
1603+
if value is True:
15821604
outputs[name] = fname_presuffix(prefices[sufftup[0]],
15831605
suffix=sufftup[1],
1584-
newpath=os.getcwd(),
1606+
newpath=cwd,
15851607
use_ext=sufftup[2])
15861608
else:
1587-
outputs[name] = value
1609+
outputs[name] = os.path.abspath(value)
15881610
return outputs
15891611

1590-
def _gen_filename(self, name):
1591-
if name == 'out_reg_file':
1592-
return self._list_outputs()[name]
1593-
return None
1594-
15951612

15961613
class FitMSParamsInputSpec(FSTraitedSpec):
15971614

nipype/interfaces/freesurfer/tests/test_auto_RobustRegister.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def test_RobustRegister_inputs():
5353
no_multi=dict(argstr='--nomulti',
5454
),
5555
out_reg_file=dict(argstr='--lta %s',
56-
genfile=True,
56+
usedefault=True,
5757
),
5858
outlier_limit=dict(argstr='--wlimit %.3f',
5959
),

nipype/interfaces/freesurfer/tests/test_preprocess.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ def test_robustregister(create_files_in_directory):
1717
filelist, outdir = create_files_in_directory
1818

1919
reg = freesurfer.RobustRegister()
20+
cwd = os.getcwd()
2021

2122
# make sure command gets called
2223
assert reg.cmd == 'mri_robust_register'
@@ -28,8 +29,9 @@ def test_robustregister(create_files_in_directory):
2829
reg.inputs.source_file = filelist[0]
2930
reg.inputs.target_file = filelist[1]
3031
reg.inputs.auto_sens = True
31-
assert reg.cmdline == ('mri_robust_register '
32-
'--satit --lta %s_robustreg.lta --mov %s --dst %s' % (filelist[0][:-4], filelist[0], filelist[1]))
32+
assert reg.cmdline == ('mri_robust_register --satit --lta '
33+
'%s/%s_robustreg.lta --mov %s --dst %s' %
34+
(cwd, filelist[0][:-4], filelist[0], filelist[1]))
3335

3436
# constructor based parameter setting
3537
reg2 = freesurfer.RobustRegister(source_file=filelist[0], target_file=filelist[1], outlier_sens=3.0,

0 commit comments

Comments
 (0)