Skip to content

Commit 1f9919f

Browse files
committed
Merge pull request #673 from bpinsard/enh/freesurfer
Enh/freesurfer resume
2 parents b84fb2f + 63d563a commit 1f9919f

File tree

3 files changed

+154
-4
lines changed

3 files changed

+154
-4
lines changed

nipype/interfaces/freesurfer/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111
SegStats, Label2Vol, MS_LDA)
1212
from .utils import (SampleToSurface, SurfaceSmooth, SurfaceTransform,
1313
SurfaceSnapshots,ApplyMask, MRIsConvert, MRITessellate,
14-
MRIMarchingCubes, SmoothTessellation, MakeAverageSubject)
14+
MRIMarchingCubes, SmoothTessellation, MakeAverageSubject,
15+
ExtractMainComponent)

nipype/interfaces/freesurfer/preprocess.py

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
CommandLineInputSpec, isdefined)
2929

3030

31+
from ... import logging
32+
iflogger = logging.getLogger('interface')
33+
3134
class ParseDICOMDirInputSpec(FSTraitedSpec):
3235
dicom_dir = Directory(exists=True, argstr='--d %s', mandatory=True,
3336
desc='path to siemens dicom directory')
@@ -593,7 +596,8 @@ class ReconAllInputSpec(CommandLineInputSpec):
593596
directive = traits.Enum('all', 'autorecon1', 'autorecon2', 'autorecon2-cp',
594597
'autorecon2-wm', 'autorecon2-inflate1', 'autorecon2-perhemi',
595598
'autorecon3', 'localGI', 'qcache', argstr='-%s',
596-
desc='process directive', usedefault=True)
599+
desc='process directive', usedefault=True,
600+
position=0)
597601
hemi = traits.Enum('lh', 'rh', desc='hemisphere to process', argstr="-hemi %s")
598602
T1_files = InputMultiPath(File(exists=True), argstr='-i %s...',
599603
desc='name of T1 file to process')
@@ -621,14 +625,97 @@ class ReconAll(CommandLine):
621625
>>> reconall.inputs.subjects_dir = '.'
622626
>>> reconall.inputs.T1_files = 'structural.nii'
623627
>>> reconall.cmdline
624-
'recon-all -i structural.nii -all -subjid foo -sd .'
628+
'recon-all -all -i structural.nii -subjid foo -sd .'
625629
626630
"""
627631

628632
_cmd = 'recon-all'
629633
_additional_metadata = ['loc', 'altkey']
630634
input_spec = ReconAllInputSpec
631635
output_spec = ReconAllIOutputSpec
636+
_can_resume = True
637+
638+
639+
_steps = [
640+
#autorecon1
641+
('motioncor', ['mri/rawavg.mgz', 'mri/orig.mgz']),
642+
('talairach', ['mri/transforms/talairach.auto.xfm',
643+
'mri/transforms/talairach.xfm']),
644+
('nuintensitycor', ['mri/nu.mgz']),
645+
('normalization', ['mri/T1.mgz']),
646+
('skullstrip',
647+
['mri/transforms/talairach_with_skull.lta',
648+
'mri/brainmask.auto.mgz',
649+
'mri/brainmask.mgz']),
650+
#autorecon2
651+
('gcareg', ['mri/transforms/talairach.lta']),
652+
('canorm', ['mri/norm.mgz']),
653+
('careg', ['mri/transforms/talairach.m3z']),
654+
('careginv', ['mri/transforms/talairach.m3z.inv.x.mgz',
655+
'mri/transforms/talairach.m3z.inv.y.mgz',
656+
'mri/transforms/talairach.m3z.inv.z.mgz']),
657+
('rmneck', ['mri/nu_noneck.mgz']),
658+
('skull-lta', ['mri/transforms/talairach_with_skull_2.lta']),
659+
('calabel',
660+
['mri/aseg.auto_noCCseg.mgz', 'mri/aseg.auto.mgz', 'mri/aseg.mgz']),
661+
('normalization2', ['mri/brain.mgz']),
662+
('maskbfs', ['mri/brain.finalsurfs.mgz']),
663+
('segmentation', ['mri/wm.asegedit.mgz', 'mri/wm.mgz']),
664+
('fill', ['mri/filled.mgz']),
665+
('tessellate', ['surf/lh.orig.nofix', 'surf/rh.orig.nofix']),
666+
('smooth1', ['surf/lh.smoothwm.nofix', 'surf/rh.smoothwm.nofix']),
667+
('inflate1', ['surf/lh.inflated.nofix', 'surf/rh.inflated.nofix']),
668+
('qsphere', ['surf/lh.qsphere.nofix', 'surf/rh.qsphere.nofix']),
669+
('fix', ['surf/lh.orig', 'surf/rh.orig']),
670+
('white',
671+
['surf/lh.white',
672+
'surf/rh.white',
673+
'surf/lh.curv',
674+
'surf/rh.curv',
675+
'surf/lh.area',
676+
'surf/rh.area',
677+
'label/lh.cortex.label',
678+
'label/rh.cortex.label']),
679+
('smooth2', ['surf/lh.smoothwm', 'surf/rh.smoothwm']),
680+
('inflate2',
681+
['surf/lh.inflated',
682+
'surf/rh.inflated',
683+
'surf/lh.sulc',
684+
'surf/rh.sulc',
685+
'surf/lh.inflated.H',
686+
'surf/rh.inflated.H',
687+
'surf/lh.inflated.K',
688+
'surf/rh.inflated.K']),
689+
#autorecon3
690+
('sphere', ['surf/lh.sphere', 'surf/rh.sphere']),
691+
('surfreg', ['surf/lh.sphere.reg', 'surf/rh.sphere.reg']),
692+
('jacobian_white', ['surf/lh.jacobian_white',
693+
'surf/rh.jacobian_white']),
694+
('avgcurv', ['surf/lh.avg_curv', 'surf/rh.avg_curv']),
695+
('cortparc', ['label/lh.aparc.annot', 'label/rh.aparc.annot']),
696+
('pial',
697+
['surf/lh.pial',
698+
'surf/rh.pial',
699+
'surf/lh.curv.pial',
700+
'surf/rh.curv.pial',
701+
'surf/lh.area.pial',
702+
'surf/rh.area.pial',
703+
'surf/lh.thickness',
704+
'surf/rh.thickness']),
705+
('cortparc2', ['label/lh.aparc.a2009s.annot',
706+
'label/rh.aparc.a2009s.annot']),
707+
('parcstats2',
708+
['stats/lh.aparc.a2009s.stats',
709+
'stats/rh.aparc.a2009s.stats',
710+
'stats/aparc.annot.a2009s.ctab']),
711+
('cortribbon', ['mri/lh.ribbon.mgz', 'mri/rh.ribbon.mgz',
712+
'mri/ribbon.mgz']),
713+
('segstats', ['stats/aseg.stats']),
714+
('aparc2aseg', ['mri/aparc+aseg.mgz', 'mri/aparc.a2009s+aseg.mgz']),
715+
('wmparc', ['mri/wmparc.mgz', 'stats/wmparc.stats']),
716+
('balabels', ['BA.ctab', 'BA.thresh.ctab']),
717+
('label-exvivo-ec', ['label/lh.entorhinal_exvivo.label',
718+
'label/rh.entorhinal_exvivo.label'])]
632719

633720
def _gen_subjects_dir(self):
634721
return os.getcwd()
@@ -660,6 +747,39 @@ def _list_outputs(self):
660747
outputs['subjects_dir'] = subjects_dir
661748
return outputs
662749

750+
@property
751+
def cmdline(self):
752+
subjects_dir = self.inputs.subjects_dir
753+
if not isdefined(subjects_dir):
754+
subjects_dir = self._gen_subjects_dir()
755+
if not os.path.isdir(
756+
os.path.join(subjects_dir,self.inputs.subject_id,'mri')):
757+
return super(ReconAll, self).cmdline
758+
self._check_mandatory_inputs()
759+
skip = ['T1_files']
760+
subjects_dir = self.inputs.subjects_dir
761+
if not isdefined(subjects_dir):
762+
subjects_dir = self._gen_subjects_dir()
763+
flags = []
764+
directive = 'all'
765+
for idx, step in enumerate(self._steps):
766+
step, outfiles = step
767+
if all([os.path.exists(os.path.join(subjects_dir,self.inputs.subject_id,f)) for f in outfiles]):
768+
flags.append('-no%s'%step)
769+
if idx > 4:
770+
directive = 'autorecon2'
771+
elif idx > 23:
772+
directive = 'autorecon3'
773+
else:
774+
flags.append('-%s'%step)
775+
self.inputs.args = ' '.join([self.inputs.args] + flags)
776+
self.inputs.directive = directive
777+
allargs = self._parse_inputs(skip=skip)
778+
allargs.insert(0, self.cmd)
779+
cmd = ' '.join(allargs)
780+
iflogger.info('resume recon-all : %s'%cmd)
781+
return cmd
782+
663783

664784
class BBRegisterInputSpec(FSTraitedSpec):
665785
subject_id = traits.Str(argstr='--s %s',

nipype/interfaces/freesurfer/utils.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
from nipype.utils.filemanip import fname_presuffix, split_filename
1717

1818
from nipype.interfaces.freesurfer.base import FSCommand, FSTraitedSpec
19-
from nipype.interfaces.base import TraitedSpec, File, traits, OutputMultiPath, isdefined
19+
from nipype.interfaces.base import TraitedSpec, File, traits, OutputMultiPath, isdefined, CommandLine, CommandLineInputSpec
2020

2121
filemap = dict(cor='cor', mgh='mgh', mgz='mgz', minc='mnc',
2222
afni='brik', brik='brik', bshort='bshort',
@@ -1026,3 +1026,32 @@ def _list_outputs(self):
10261026
outputs = self.output_spec().get()
10271027
outputs['average_subject_name'] = self.inputs.out_name
10281028
return outputs
1029+
1030+
class ExtractMainComponentInputSpec(CommandLineInputSpec):
1031+
in_file = File(
1032+
exists=True, mandatory=True, argstr='%s', position=1,
1033+
desc='input surface file')
1034+
out_file = File(
1035+
name_template ='%s.maincmp', name_source='in_file',
1036+
argstr='%s', position=2, keep_extension = True,
1037+
desc='surface containing main component')
1038+
1039+
class ExtractMainComponentOutputSpec(TraitedSpec):
1040+
out_file = File(exists=True, desc='surface containing main component')
1041+
1042+
class ExtractMainComponent(CommandLine):
1043+
"""Extract the main component of a tesselated surface
1044+
1045+
Examples
1046+
--------
1047+
1048+
>>> from nipype.interfaces.freesurfer import ExtractMainComponent
1049+
>>> mcmp = ExtractMainComponent(in_file='lh.pial')
1050+
>>> mcmp.cmdline
1051+
'mris_extract_main_component lh.pial lh.pial.maincmp'
1052+
1053+
"""
1054+
1055+
_cmd='mris_extract_main_component'
1056+
input_spec=ExtractMainComponentInputSpec
1057+
output_spec=ExtractMainComponentOutputSpec

0 commit comments

Comments
 (0)