Skip to content

FIX: Create out_reg_file correctly in RobustRegister #2205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 89 additions & 72 deletions nipype/interfaces/freesurfer/preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -1457,76 +1457,102 @@ def _gen_filename(self, name):

class RobustRegisterInputSpec(FSTraitedSpec):

source_file = File(mandatory=True, argstr='--mov %s',
source_file = File(exists=True, mandatory=True, argstr='--mov %s',
desc='volume to be registered')
target_file = File(mandatory=True, argstr='--dst %s',
target_file = File(exists=True, mandatory=True, argstr='--dst %s',
desc='target volume for the registration')
out_reg_file = File(genfile=True, argstr='--lta %s',
desc='registration file to write')
registered_file = traits.Either(traits.Bool, File, argstr='--warp %s',
desc='registered image; either True or filename')
weights_file = traits.Either(traits.Bool, File, argstr='--weights %s',
desc='weights image to write; either True or filename')
est_int_scale = traits.Bool(argstr='--iscale',
desc='estimate intensity scale (recommended for unnormalized images)')
out_reg_file = traits.Either(
True, File, default=True, usedefault=True, argstr='--lta %s',
desc='registration file; either True or filename')
registered_file = traits.Either(
traits.Bool, File, argstr='--warp %s',
desc='registered image; either True or filename')
weights_file = traits.Either(
traits.Bool, File, argstr='--weights %s',
desc='weights image to write; either True or filename')
est_int_scale = traits.Bool(
argstr='--iscale',
desc='estimate intensity scale (recommended for unnormalized images)')
trans_only = traits.Bool(argstr='--transonly',
desc='find 3 parameter translation only')
in_xfm_file = File(exists=True, argstr='--transform',
desc='use initial transform on source')
half_source = traits.Either(traits.Bool, File, argstr='--halfmov %s',
desc="write source volume mapped to halfway space")
half_targ = traits.Either(traits.Bool, File, argstr="--halfdst %s",
desc="write target volume mapped to halfway space")
half_weights = traits.Either(traits.Bool, File, argstr="--halfweights %s",
desc="write weights volume mapped to halfway space")
half_source_xfm = traits.Either(traits.Bool, File, argstr="--halfmovlta %s",
desc="write transform from source to halfway space")
half_targ_xfm = traits.Either(traits.Bool, File, argstr="--halfdstlta %s",
desc="write transform from target to halfway space")
auto_sens = traits.Bool(argstr='--satit', xor=['outlier_sens'], mandatory=True,
desc='auto-detect good sensitivity')
outlier_sens = traits.Float(argstr='--sat %.4f', xor=['auto_sens'], mandatory=True,
desc='set outlier sensitivity explicitly')
least_squares = traits.Bool(argstr='--leastsquares',
desc='use least squares instead of robust estimator')
half_source = traits.Either(
traits.Bool, File, argstr='--halfmov %s',
desc="write source volume mapped to halfway space")
half_targ = traits.Either(
traits.Bool, File, argstr="--halfdst %s",
desc="write target volume mapped to halfway space")
half_weights = traits.Either(
traits.Bool, File, argstr="--halfweights %s",
desc="write weights volume mapped to halfway space")
half_source_xfm = traits.Either(
traits.Bool, File, argstr="--halfmovlta %s",
desc="write transform from source to halfway space")
half_targ_xfm = traits.Either(
traits.Bool, File, argstr="--halfdstlta %s",
desc="write transform from target to halfway space")
auto_sens = traits.Bool(
argstr='--satit', xor=['outlier_sens'], mandatory=True,
desc='auto-detect good sensitivity')
outlier_sens = traits.Float(
argstr='--sat %.4f', xor=['auto_sens'], mandatory=True,
desc='set outlier sensitivity explicitly')
least_squares = traits.Bool(
argstr='--leastsquares',
desc='use least squares instead of robust estimator')
no_init = traits.Bool(argstr='--noinit', desc='skip transform init')
init_orient = traits.Bool(argstr='--initorient',
desc='use moments for initial orient (recommended for stripped brains)')
init_orient = traits.Bool(
argstr='--initorient',
desc='use moments for initial orient (recommended for stripped brains)'
)
max_iterations = traits.Int(argstr='--maxit %d',
desc='maximum # of times on each resolution')
high_iterations = traits.Int(argstr='--highit %d',
desc='max # of times on highest resolution')
iteration_thresh = traits.Float(argstr='--epsit %.3f',
desc='stop iterations when below threshold')
subsample_thresh = traits.Int(argstr='--subsample %d',
desc='subsample if dimension is above threshold size')
iteration_thresh = traits.Float(
argstr='--epsit %.3f', desc='stop iterations when below threshold')
subsample_thresh = traits.Int(
argstr='--subsample %d',
desc='subsample if dimension is above threshold size')
outlier_limit = traits.Float(argstr='--wlimit %.3f',
desc='set maximal outlier limit in satit')
write_vo2vox = traits.Bool(argstr='--vox2vox',
desc='output vox2vox matrix (default is RAS2RAS)')
no_multi = traits.Bool(argstr='--nomulti', desc='work on highest resolution')
write_vo2vox = traits.Bool(
argstr='--vox2vox', desc='output vox2vox matrix (default is RAS2RAS)')
no_multi = traits.Bool(argstr='--nomulti',
desc='work on highest resolution')
mask_source = File(exists=True, argstr='--maskmov %s',
desc='image to mask source volume with')
mask_target = File(exists=True, argstr='--maskdst %s',
desc='image to mask target volume with')
force_double = traits.Bool(argstr='--doubleprec', desc='use double-precision intensities')
force_float = traits.Bool(argstr='--floattype', desc='use float intensities')
force_double = traits.Bool(argstr='--doubleprec',
desc='use double-precision intensities')
force_float = traits.Bool(argstr='--floattype',
desc='use float intensities')


class RobustRegisterOutputSpec(TraitedSpec):

out_reg_file = File(exists=True, desc="output registration file")
registered_file = File(desc="output image with registration applied")
weights_file = File(desc="image of weights used")
half_source = File(desc="source image mapped to halfway space")
half_targ = File(desc="target image mapped to halfway space")
half_weights = File(desc="weights image mapped to halfway space")
half_source_xfm = File(desc="transform file to map source image to halfway space")
half_targ_xfm = File(desc="transform file to map target image to halfway space")
registered_file = File(exists=True,
desc="output image with registration applied")
weights_file = File(exists=True, desc="image of weights used")
half_source = File(exists=True,
desc="source image mapped to halfway space")
half_targ = File(exists=True, desc="target image mapped to halfway space")
half_weights = File(exists=True,
desc="weights image mapped to halfway space")
half_source_xfm = File(
exists=True,
desc="transform file to map source image to halfway space")
half_targ_xfm = File(
exists=True,
desc="transform file to map target image to halfway space")


class RobustRegister(FSCommand):
"""Perform intramodal linear registration (translation and rotation) using robust statistics.
"""Perform intramodal linear registration (translation and rotation) using
robust statistics.

Examples
--------
Expand All @@ -1536,13 +1562,13 @@ class RobustRegister(FSCommand):
>>> reg.inputs.target_file = 'T1.nii'
>>> reg.inputs.auto_sens = True
>>> reg.inputs.init_orient = True
>>> reg.cmdline # doctest: +ALLOW_UNICODE
'mri_robust_register --satit --initorient --lta structural_robustreg.lta --mov structural.nii --dst T1.nii'
>>> reg.cmdline # doctest: +ALLOW_UNICODE +ELLIPSIS
'mri_robust_register --satit --initorient --lta .../structural_robustreg.lta --mov structural.nii --dst T1.nii'

References
----------
Reuter, M, Rosas, HD, and Fischl, B, (2010). Highly Accurate Inverse Consistent Registration:
A Robust Approach. Neuroimage 53(4) 1181-96.
Reuter, M, Rosas, HD, and Fischl, B, (2010). Highly Accurate Inverse
Consistent Registration: A Robust Approach. Neuroimage 53(4) 1181-96.

"""

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

def _format_arg(self, name, spec, value):
for option in ["registered_file", "weights_file", "half_source", "half_targ",
"half_weights", "half_source_xfm", "half_targ_xfm"]:
if name == option:
if isinstance(value, bool):
fname = self._list_outputs()[name]
else:
fname = value
return spec.argstr % fname
options = ("out_reg_file", "registered_file", "weights_file",
"half_source", "half_targ", "half_weights",
"half_source_xfm", "half_targ_xfm")
if name in options and isinstance(value, bool):
value = self._list_outputs()[name]
return super(RobustRegister, self)._format_arg(name, spec, value)

def _list_outputs(self):
outputs = self.output_spec().get()
outputs['out_reg_file'] = self.inputs.out_reg_file
if not isdefined(self.inputs.out_reg_file) and self.inputs.source_file:
outputs['out_reg_file'] = fname_presuffix(self.inputs.source_file,
suffix='_robustreg.lta', use_ext=False)
prefices = dict(src=self.inputs.source_file, trg=self.inputs.target_file)
suffices = dict(registered_file=("src", "_robustreg", True),
cwd = os.getcwd()
prefices = dict(src=self.inputs.source_file,
trg=self.inputs.target_file)
suffices = dict(out_reg_file=("src", "_robustreg.lta", False),
registered_file=("src", "_robustreg", True),
weights_file=("src", "_robustweights", True),
half_source=("src", "_halfway", True),
half_targ=("trg", "_halfway", True),
Expand All @@ -1577,21 +1599,16 @@ def _list_outputs(self):
half_targ_xfm=("trg", "_robustxfm.lta", False))
for name, sufftup in list(suffices.items()):
value = getattr(self.inputs, name)
if isdefined(value):
if isinstance(value, bool):
if value:
if value is True:
outputs[name] = fname_presuffix(prefices[sufftup[0]],
suffix=sufftup[1],
newpath=os.getcwd(),
newpath=cwd,
use_ext=sufftup[2])
else:
outputs[name] = value
outputs[name] = os.path.abspath(value)
return outputs

def _gen_filename(self, name):
if name == 'out_reg_file':
return self._list_outputs()[name]
return None


class FitMSParamsInputSpec(FSTraitedSpec):

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def test_RobustRegister_inputs():
no_multi=dict(argstr='--nomulti',
),
out_reg_file=dict(argstr='--lta %s',
genfile=True,
usedefault=True,
),
outlier_limit=dict(argstr='--wlimit %.3f',
),
Expand Down
6 changes: 4 additions & 2 deletions nipype/interfaces/freesurfer/tests/test_preprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def test_robustregister(create_files_in_directory):
filelist, outdir = create_files_in_directory

reg = freesurfer.RobustRegister()
cwd = os.getcwd()

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

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