Skip to content

Commit 5360d04

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents 59d2fd4 + 8fc22f5 commit 5360d04

File tree

13 files changed

+229
-34
lines changed

13 files changed

+229
-34
lines changed

nipype/interfaces/afni/preprocess.py

100755100644
File mode changed.

nipype/interfaces/base.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1450,10 +1450,13 @@ def _format_arg(self, name, trait_spec, value):
14501450
def _filename_from_source(self, name):
14511451
trait_spec = self.inputs.trait(name)
14521452
retval = getattr(self.inputs, name)
1453-
if not isdefined(retval):
1453+
if not isdefined(retval) or "%s" in retval:
14541454
if not trait_spec.name_source:
14551455
return retval
1456-
name_template = trait_spec.name_template
1456+
if isdefined(retval) and "%s" in retval:
1457+
name_template = retval
1458+
else:
1459+
name_template = trait_spec.name_template
14571460
if not name_template:
14581461
name_template = "%s_generated"
14591462
if isinstance(trait_spec.name_source, list):

nipype/interfaces/camino2trackvis/convert.py

100755100644
File mode 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: 28 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,30 @@ 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(exists=True, mandatory=True, argstr='%s', position=1,
1032+
desc='input surface file')
1033+
out_file = File(name_template='%s.maincmp', name_source='in_file',
1034+
argstr='%s', position=2,
1035+
desc='surface containing main component')
1036+
1037+
class ExtractMainComponentOutputSpec(TraitedSpec):
1038+
out_file = File(exists=True, desc='surface containing main component')
1039+
1040+
class ExtractMainComponent(CommandLine):
1041+
"""Extract the main component of a tesselated surface
1042+
1043+
Examples
1044+
--------
1045+
1046+
>>> from nipype.interfaces.freesurfer import ExtractMainComponent
1047+
>>> mcmp = ExtractMainComponent(in_file='lh.pial')
1048+
>>> mcmp.cmdline
1049+
'mris_extract_main_component lh.pial lh.maincmp'
1050+
1051+
"""
1052+
1053+
_cmd='mris_extract_main_component'
1054+
input_spec=ExtractMainComponentInputSpec
1055+
output_spec=ExtractMainComponentOutputSpec

nipype/interfaces/fsl/epi.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
<http://www.fmrib.ox.ac.uk/fsl/index.html>`_ command line tools. This
55
was written to work with FSL version 5.0.4.
66
7-
Examples
8-
--------
9-
See the docstrings of the individual classes for examples.
10-
7+
Change directory to provide relative paths for doctests
8+
>>> import os
9+
>>> filepath = os.path.dirname( os.path.realpath( __file__ ) )
10+
>>> datadir = os.path.realpath(os.path.join(filepath, '../../testing/data'))
11+
>>> os.chdir(datadir)
1112
"""
1213

1314
import os

nipype/interfaces/fsl/model.py

100755100644
Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,9 +1663,10 @@ def _list_outputs(self):
16631663
class GLMInputSpec(FSLCommandInputSpec):
16641664
in_file = File(exists=True, argstr='-i %s', mandatory=True, position=1,
16651665
desc='input file name (text matrix or 3D/4D image file)')
1666-
out_file = File(argstr='-o %s', genfile=True, position=3,
1666+
out_file = File(name_template="%s_glm.txt", argstr='-o %s', position=3,
16671667
desc=('filename for GLM parameter estimates'
1668-
+ ' (GLM betas)'))
1668+
+ ' (GLM betas)'),
1669+
name_source="in_file", keep_extension=True)
16691670
design = File(exists=True, argstr='-d %s', mandatory=True, position=2,
16701671
desc=('file name of the GLM design matrix (text time'
16711672
+ ' courses for temporal regression or an image'
@@ -1761,7 +1762,7 @@ class GLM(FSLCommand):
17611762
>>> import nipype.interfaces.fsl as fsl
17621763
>>> glm = fsl.GLM(in_file='functional.nii', design='maps.nii')
17631764
>>> glm.cmdline
1764-
'fsl_glm -d maps.nii -i functional.nii -o functional_glm.txt'
1765+
'fsl_glm -i functional.nii -d maps.nii -o functional_glm.txt'
17651766
17661767
"""
17671768
_cmd = 'fsl_glm'
@@ -1813,7 +1814,3 @@ def _list_outputs(self):
18131814

18141815
return outputs
18151816

1816-
def _gen_filename(self, name):
1817-
if name in ['out_file']:
1818-
return self._gen_fname(self.inputs.in_file, suffix='_glm')
1819-
return None

nipype/interfaces/mrtrix/tracking.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from nipype.interfaces.base import CommandLineInputSpec, CommandLine, traits, TraitedSpec, File
1313
from nipype.utils.filemanip import split_filename
1414
import os, os.path as op
15+
from nipype.interfaces.traits_extension import isdefined
1516

1617
class Tracks2ProbInputSpec(CommandLineInputSpec):
1718
in_file = File(exists=True, argstr='%s', mandatory=True, position=-2,
@@ -54,7 +55,11 @@ class Tracks2Prob(CommandLine):
5455

5556
def _list_outputs(self):
5657
outputs = self.output_spec().get()
57-
outputs['tract_image'] = op.abspath(self._gen_outfilename())
58+
outputs['tract_image'] = self.inputs.out_filename
59+
if not isdefined(outputs['tract_image']):
60+
outputs['tract_image'] = op.abspath(self._gen_outfilename())
61+
else:
62+
outputs['tract_image'] = os.path.abspath(outputs['tract_image'])
5863
return outputs
5964

6065
def _gen_filename(self, name):

nipype/interfaces/spm/preprocess.py

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,9 @@ class SliceTimingInputSpec(SPMCommandInputSpec):
5555

5656

5757
class SliceTimingOutputSpec(TraitedSpec):
58-
timecorrected_files = OutputMultiPath(File(exist=True,
59-
desc='slice time corrected files'))
58+
timecorrected_files = OutputMultiPath(traits.Either(traits.List(File(exists=True)),
59+
File(exists=True)),
60+
desc='slice time corrected files')
6061

6162

6263
class SliceTiming(SPMCommand):
@@ -100,15 +101,11 @@ def _list_outputs(self):
100101

101102
filelist = filename_to_list(self.inputs.in_files)
102103
for f in filelist:
103-
run = []
104104
if isinstance(f, list):
105-
for inner_f in filename_to_list(f):
106-
run.append(fname_presuffix(inner_f,
107-
prefix=self.inputs.out_prefix))
105+
run = [fname_presuffix(in_f, prefix=self.inputs.out_prefix) for in_f in f]
108106
else:
109-
realigned_run = fname_presuffix(f,
110-
prefix=self.inputs.out_prefix)
111-
outputs['timecorrected_files'].append(realigned_run)
107+
run = fname_presuffix(f, prefix=self.inputs.out_prefix)
108+
outputs['timecorrected_files'].append(run)
112109
return outputs
113110

114111

@@ -152,9 +149,18 @@ class RealignInputSpec(SPMCommandInputSpec):
152149

153150
class RealignOutputSpec(TraitedSpec):
154151
mean_image = File(exists=True, desc='Mean image file from the realignment')
152+
modified_in_files = OutputMultiPath(traits.Either(traits.List(File(exists=True)),
153+
File(exists=True)),
154+
desc='Copies of all files passed to in_files.\
155+
Headers will have been modified to align all\
156+
images with the first, or optionally to first\
157+
do that, extract a mean image, and re-align to\
158+
that mean image.')
155159
realigned_files = OutputMultiPath(traits.Either(traits.List(File(exists=True)),
156160
File(exists=True)),
157-
desc='Realigned files')
161+
desc='If jobtype is write or estwrite, these will be the\
162+
resliced files. Otherwise, they will be copies of\
163+
in_files that have had their headers rewritten.')
158164
realignment_parameters = OutputMultiPath(File(exists=True),
159165
desc='Estimated translation and rotation parameters')
160166

@@ -213,6 +219,10 @@ def _list_outputs(self):
213219
use_ext=False))
214220
if not isinstance(imgf, list) and func_is_3d(imgf):
215221
break
222+
if self.inputs.jobtype == "estimate":
223+
outputs['realigned_files'] = self.inputs.in_files
224+
if self.inputs.jobtype == "estimate" or self.inputs.jobtype == "estwrite":
225+
outputs['modified_in_files'] = self.inputs.in_files
216226
if self.inputs.jobtype == "write" or self.inputs.jobtype == "estwrite":
217227
if isinstance(self.inputs.in_files[0], list):
218228
first_image = self.inputs.in_files[0][0]
@@ -367,8 +377,11 @@ class NormalizeInputSpec(SPMCommandInputSpec):
367377
jobtype = traits.Enum('estwrite', 'est', 'write',
368378
desc='one of: est, write, estwrite (opt, estwrite)',
369379
usedefault=True)
370-
apply_to_files = InputMultiPath(File(exists=True), field='subj.resample',
371-
desc='files to apply transformation to (opt)', copyfile=True)
380+
apply_to_files = InputMultiPath(traits.Either(File(exists=True),
381+
traits.List(File(exists=True))),
382+
field='subj.resample',
383+
desc='files to apply transformation to (opt)',
384+
copyfile=True)
372385
parameter_file = File(field='subj.matname', mandatory=True,
373386
xor=['source', 'template'],
374387
desc='normalization parameter file*_sn.mat', copyfile=False)
@@ -481,9 +494,13 @@ def _list_outputs(self):
481494
elif 'write' in self.inputs.jobtype:
482495
outputs['normalized_files'] = []
483496
if isdefined(self.inputs.apply_to_files):
484-
for imgf in filename_to_list(self.inputs.apply_to_files):
485-
outputs['normalized_files'].append(fname_presuffix(imgf, prefix=self.inputs.out_prefix))
486-
497+
filelist = filename_to_list(self.inputs.apply_to_files)
498+
for f in filelist:
499+
if isinstance(f, list):
500+
run = [fname_presuffix(in_f, prefix=self.inputs.out_prefix) for in_f in f]
501+
else:
502+
run = [fname_presuffix(f, prefix=self.inputs.out_prefix)]
503+
outputs['normalized_files'].extend(run)
487504
if isdefined(self.inputs.source):
488505
outputs['normalized_source'] = []
489506
for imgf in filename_to_list(self.inputs.source):

0 commit comments

Comments
 (0)