From 39b05a26b120e2e28adf8ef702ab72bcbb7d84ea Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sat, 22 Apr 2017 21:51:53 -0400 Subject: [PATCH 1/3] RF: Check only relevant steps in ReconAll --- nipype/interfaces/freesurfer/preprocess.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/nipype/interfaces/freesurfer/preprocess.py b/nipype/interfaces/freesurfer/preprocess.py index 70af43b598..bfe4314b11 100644 --- a/nipype/interfaces/freesurfer/preprocess.py +++ b/nipype/interfaces/freesurfer/preprocess.py @@ -949,10 +949,22 @@ def cmdline(self): if not isdefined(subjects_dir): subjects_dir = self._gen_subjects_dir() + # Check only relevant steps + directive = self.inputs.directive + if not isdefined(directive): + steps = [] + elif directive == 'autorecon1': + steps = self._autorecon1_steps + elif directive.startswith('autorecon2'): + steps = self._autorecon2_steps + elif directive == 'autorecon3': + steps = self._autorecon3_steps + else: + steps = self._steps + no_run = True flags = [] - for idx, step in enumerate(self._steps): - step, outfiles, infiles = step + for step, outfiles, infiles in steps: flag = '-{}'.format(step) noflag = '-no{}'.format(step) if noflag in cmd: From 1eef448823a051ae7616228412dc12c88f94c938 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Sat, 22 Apr 2017 21:52:13 -0400 Subject: [PATCH 2/3] ENH: Handle expert options more gracefully Set default behavior to refrain from creating/passing a new expert options file if an existing one has the same contents. Also, give access to -xopts-{use,clean,overwrite} options, if users want to override this default. --- nipype/interfaces/freesurfer/preprocess.py | 23 ++++++++++++++++++- .../freesurfer/tests/test_auto_ReconAll.py | 2 ++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/nipype/interfaces/freesurfer/preprocess.py b/nipype/interfaces/freesurfer/preprocess.py index bfe4314b11..ca3b10cd52 100644 --- a/nipype/interfaces/freesurfer/preprocess.py +++ b/nipype/interfaces/freesurfer/preprocess.py @@ -632,6 +632,8 @@ class ReconAllInputSpec(CommandLineInputSpec): desc="Conform to minimum voxel size (for voxels < 1mm)") expert = File(exists=True, argstr='-expert %s', desc="Set parameters using expert file") + xopts = traits.Enum("use", "clean", "overwrite", argstr='-xopts-%s', + desc="Use, delete or overwrite existing expert options file") subjects_dir = Directory(exists=True, argstr='-sd %s', hash_files=False, desc='path to subjects directory', genfile=True) flags = traits.Str(argstr='%s', desc='additional parameters') @@ -1001,11 +1003,30 @@ def _prep_expert_file(self): if lines == []: return '' + contents = ''.join(lines) + if not isdefined(self.inputs.xopts) and \ + self.get_expert_file() == contents: + return ' -xopts-use' + expert_fname = os.path.abspath('expert.opts') with open(expert_fname, 'w') as fobj: - fobj.write(''.join(lines)) + fobj.write(contents) return ' -expert {}'.format(expert_fname) + def _get_expert_file(self): + # Read pre-existing options file, if it exists + if isdefined(self.inputs.subjects_dir): + subjects_dir = self.inputs.subjects_dir + else: + subjects_dir = self._gen_subjects_dir() + + xopts_file = os.path.join(subjects_dir, self.inputs.subject_id, + 'scripts', 'expert-options') + if not os.path.exists(xopts_file): + return '' + with open(xopts_file, 'r') as fobj: + return fobj.read() + class BBRegisterInputSpec(FSTraitedSpec): subject_id = traits.Str(argstr='--s %s', diff --git a/nipype/interfaces/freesurfer/tests/test_auto_ReconAll.py b/nipype/interfaces/freesurfer/tests/test_auto_ReconAll.py index 61f733cc2f..3e0f39656f 100644 --- a/nipype/interfaces/freesurfer/tests/test_auto_ReconAll.py +++ b/nipype/interfaces/freesurfer/tests/test_auto_ReconAll.py @@ -98,6 +98,8 @@ def test_ReconAll_inputs(): use_T2=dict(argstr='-T2pial', min_ver='5.3.0', ), + xopts=dict(argstr='-xopts-%s', + ), ) inputs = ReconAll.input_spec() From 1db7b23aad20586da50aa5380f73696fd2899e26 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Mon, 24 Apr 2017 16:55:06 -0400 Subject: [PATCH 3/3] ENH: Add more recon-all options --- nipype/interfaces/freesurfer/preprocess.py | 23 +++++++++++++++++++ .../freesurfer/tests/test_auto_ReconAll.py | 12 ++++++++++ 2 files changed, 35 insertions(+) diff --git a/nipype/interfaces/freesurfer/preprocess.py b/nipype/interfaces/freesurfer/preprocess.py index ca3b10cd52..29961ee6ed 100644 --- a/nipype/interfaces/freesurfer/preprocess.py +++ b/nipype/interfaces/freesurfer/preprocess.py @@ -630,6 +630,22 @@ class ReconAllInputSpec(CommandLineInputSpec): desc="Enable parallel execution") hires = traits.Bool(argstr="-hires", min_ver='6.0.0', desc="Conform to minimum voxel size (for voxels < 1mm)") + mprage = traits.Bool(argstr='-mprage', + desc=('Assume scan parameters are MGH MP-RAGE ' + 'protocol, which produces darker gray matter')) + big_ventricles = traits.Bool(argstr='-bigventricles', + desc=('For use in subjects with enlarged ' + 'ventricles')) + brainstem = traits.Bool(argstr='-brainstem-structures', + desc='Segment brainstem structures') + hippocampal_subfields_T1 = traits.Bool( + argstr='-hippocampal-subfields-T1', min_ver='6.0.0', + desc='segment hippocampal subfields using input T1 scan') + hippocampal_subfields_T2 = traits.Tuple( + File(exists=True), traits.Str(), + argstr='-hippocampal-subfields-T2 %s %s', min_ver='6.0.0', + desc=('segment hippocampal subfields using T2 scan, identified by ' + 'ID (may be combined with hippocampal_subfields_T1)')) expert = File(exists=True, argstr='-expert %s', desc="Set parameters using expert file") xopts = traits.Enum("use", "clean", "overwrite", argstr='-xopts-%s', @@ -935,6 +951,13 @@ def _format_arg(self, name, trait_spec, value): if name == 'T1_files': if self._is_resuming(): return '' + if name == 'hippocampal_subfields_T1' and \ + isdefined(self.inputs.hippocampal_subfields_T2): + return '' + if all((name == 'hippocampal_subfields_T2', + isdefined(self.inputs.hippocampal_subfields_T1) and + self.inputs.hippocampal_subfields_T1)): + trait_spec.argstr = trait_spec.argstr.replace('T2', 'T1T2') return super(ReconAll, self)._format_arg(name, trait_spec, value) @property diff --git a/nipype/interfaces/freesurfer/tests/test_auto_ReconAll.py b/nipype/interfaces/freesurfer/tests/test_auto_ReconAll.py index 3e0f39656f..c2de3635f6 100644 --- a/nipype/interfaces/freesurfer/tests/test_auto_ReconAll.py +++ b/nipype/interfaces/freesurfer/tests/test_auto_ReconAll.py @@ -11,6 +11,10 @@ def test_ReconAll_inputs(): ), args=dict(argstr='%s', ), + big_ventricles=dict(argstr='-bigventricles', + ), + brainstem=dict(argstr='-brainstem-structures', + ), directive=dict(argstr='-%s', position=0, usedefault=True, @@ -24,12 +28,20 @@ def test_ReconAll_inputs(): ), hemi=dict(argstr='-hemi %s', ), + hippocampal_subfields_T1=dict(argstr='-hippocampal-subfields-T1', + min_ver='6.0.0', + ), + hippocampal_subfields_T2=dict(argstr='-hippocampal-subfields-T2 %s %s', + min_ver='6.0.0', + ), hires=dict(argstr='-hires', min_ver='6.0.0', ), ignore_exception=dict(nohash=True, usedefault=True, ), + mprage=dict(argstr='-mprage', + ), mri_aparc2aseg=dict(xor=['expert'], ), mri_ca_label=dict(xor=['expert'],