Skip to content

Commit 89c14fb

Browse files
committed
fix: support for FSL 5.0.7 changes to FILM_GLS
1 parent e91d443 commit 89c14fb

File tree

4 files changed

+154
-25
lines changed

4 files changed

+154
-25
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Next Release
2626
* FIX: FNIRT registration pathway and associated OpenFMRI example script
2727
* FIX: spm12b compatibility for Model estimate
2828
* FIX: Batch scheduler controls the number of maximum jobs properly
29+
* FIX: Update for FSL 5.0.7 which deprecated Contrast Manager
30+
* ENH: Added ANTS based openfmri workflow
2931

3032
Release 0.9.2 (January 31, 2014)
3133
============

nipype/interfaces/fsl/model.py

Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,19 @@ class FILMGLSInputSpec505(FSLCommandInputSpec):
548548
results_dir = Directory('results', argstr='--rn=%s', usedefault=True,
549549
desc='directory to store results in')
550550

551+
class FILMGLSInputSpec507(FILMGLSInputSpec505):
552+
threshold = traits.Float(default=-1000., argstr='--thr=%f',
553+
position=-1, usedefault=True,
554+
desc='threshold')
555+
tcon_file = File(exists=True, argstr='--con=%s',
556+
desc='contrast file containing T-contrasts')
557+
fcon_file = File(exists=True, argstr='--fcon=%s',
558+
desc='contrast file containing F-contrasts')
559+
mode = traits.Enum('volumetric', 'surface', argstr="--mode=%s",
560+
desc="Type of analysis to be done")
561+
surface = File(exists=True, argstr="--in2=%s",
562+
desc=("input surface for autocorr smoothing in "
563+
"surface-based analyses"))
551564

552565
class FILMGLSOutputSpec(TraitedSpec):
553566
param_estimates = OutputMultiPath(File(exists=True),
@@ -561,10 +574,40 @@ class FILMGLSOutputSpec(TraitedSpec):
561574
desc='directory storing model estimation output')
562575
corrections = File(exists=True,
563576
desc='statistical corrections used within FILM modelling')
577+
thresholdac = File(exists=True,
578+
desc='The FILM autocorrelation parameters')
564579
logfile = File(exists=True,
565580
desc='FILM run logfile')
566581

567582

583+
class FILMGLSOutputSpec507(TraitedSpec):
584+
param_estimates = OutputMultiPath(File(exists=True),
585+
desc='Parameter estimates for each column of the design matrix')
586+
residual4d = File(exists=True,
587+
desc='Model fit residual mean-squared error for each time point')
588+
dof_file = File(exists=True, desc='degrees of freedom')
589+
sigmasquareds = File(
590+
exists=True, desc='summary of residuals, See Woolrich, et. al., 2001')
591+
results_dir = Directory(exists=True,
592+
desc='directory storing model estimation output')
593+
thresholdac = File(exists=True,
594+
desc='The FILM autocorrelation parameters')
595+
logfile = File(exists=True,
596+
desc='FILM run logfile')
597+
copes = OutputMultiPath(File(exists=True),
598+
desc='Contrast estimates for each contrast')
599+
varcopes = OutputMultiPath(File(exists=True),
600+
desc='Variance estimates for each contrast')
601+
zstats = OutputMultiPath(File(exists=True),
602+
desc='z-stat file for each contrast')
603+
tstats = OutputMultiPath(File(exists=True),
604+
desc='t-stat file for each contrast')
605+
fstats = OutputMultiPath(File(exists=True),
606+
desc='f-stat file for each contrast')
607+
zfstats = OutputMultiPath(File(exists=True),
608+
desc='z-stat file for each F contrast')
609+
610+
568611
class FILMGLS(FSLCommand):
569612
"""Use FSL film_gls command to fit a design matrix to voxel timeseries
570613
@@ -597,11 +640,16 @@ class FILMGLS(FSLCommand):
597640

598641
_cmd = 'film_gls'
599642

600-
if Info.version() and LooseVersion(Info.version()) > LooseVersion('5.0.4'):
643+
if Info.version() and LooseVersion(Info.version()) > LooseVersion('5.0.6'):
644+
input_spec = FILMGLSInputSpec507
645+
elif Info.version() and LooseVersion(Info.version()) > LooseVersion('5.0.4'):
601646
input_spec = FILMGLSInputSpec505
602647
else:
603648
input_spec = FILMGLSInputSpec
604-
output_spec = FILMGLSOutputSpec
649+
if Info.version() and LooseVersion(Info.version()) > LooseVersion('5.0.6'):
650+
output_spec = FILMGLSOutputSpec507
651+
else:
652+
output_spec = FILMGLSOutputSpec
605653

606654
def _get_pe_files(self, cwd):
607655
files = None
@@ -618,6 +666,25 @@ def _get_pe_files(self, cwd):
618666
fp.close()
619667
return files
620668

669+
def _get_numcons(self):
670+
numtcons = 0
671+
numfcons = 0
672+
if isdefined(self.inputs.tcon_file):
673+
fp = open(self.inputs.tcon_file, 'rt')
674+
for line in fp.readlines():
675+
if line.startswith('/NumContrasts'):
676+
numtcons = int(line.split()[-1])
677+
break
678+
fp.close()
679+
if isdefined(self.inputs.fcon_file):
680+
fp = open(self.inputs.fcon_file, 'rt')
681+
for line in fp.readlines():
682+
if line.startswith('/NumContrasts'):
683+
numfcons = int(line.split()[-1])
684+
break
685+
fp.close()
686+
return numtcons, numfcons
687+
621688
def _list_outputs(self):
622689
outputs = self._outputs().get()
623690
cwd = os.getcwd()
@@ -630,11 +697,50 @@ def _list_outputs(self):
630697
outputs['dof_file'] = os.path.join(results_dir, 'dof')
631698
outputs['sigmasquareds'] = self._gen_fname('sigmasquareds.nii',
632699
cwd=results_dir)
633-
outputs['corrections'] = self._gen_fname('corrections.nii',
700+
outputs['thresholdac'] = self._gen_fname('threshac1.nii',
634701
cwd=results_dir)
702+
if Info.version() and LooseVersion(Info.version()) < LooseVersion('5.0.7'):
703+
outputs['corrections'] = self._gen_fname('corrections.nii',
704+
cwd=results_dir)
635705
outputs['logfile'] = self._gen_fname('logfile',
636706
change_ext=False,
637707
cwd=results_dir)
708+
709+
if Info.version() and LooseVersion(Info.version()) > LooseVersion('5.0.6'):
710+
pth = results_dir
711+
numtcons, numfcons = self._get_numcons()
712+
base_contrast = 1
713+
copes = []
714+
varcopes = []
715+
zstats = []
716+
tstats = []
717+
neffs = []
718+
for i in range(numtcons):
719+
copes.append(self._gen_fname('cope%d.nii' % (base_contrast + i),
720+
cwd=pth))
721+
varcopes.append(
722+
self._gen_fname('varcope%d.nii' % (base_contrast + i),
723+
cwd=pth))
724+
zstats.append(self._gen_fname('zstat%d.nii' % (base_contrast + i),
725+
cwd=pth))
726+
tstats.append(self._gen_fname('tstat%d.nii' % (base_contrast + i),
727+
cwd=pth))
728+
if copes:
729+
outputs['copes'] = copes
730+
outputs['varcopes'] = varcopes
731+
outputs['zstats'] = zstats
732+
outputs['tstats'] = tstats
733+
fstats = []
734+
zfstats = []
735+
for i in range(numfcons):
736+
fstats.append(self._gen_fname('fstat%d.nii' % (base_contrast + i),
737+
cwd=pth))
738+
zfstats.append(
739+
self._gen_fname('zfstat%d.nii' % (base_contrast + i),
740+
cwd=pth))
741+
if fstats:
742+
outputs['fstats'] = fstats
743+
outputs['zfstats'] = zfstats
638744
return outputs
639745

640746

nipype/workflows/fmri/fsl/estimate.py

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import nipype.interfaces.utility as util # utility
55
import nipype.pipeline.engine as pe # pypeline engine
66

7+
from nipype import LooseVersion
8+
79

810
def create_modelfit_workflow(name='modelfit'):
911
"""Create an FSL individual modelfitting workflow
@@ -40,6 +42,11 @@ def create_modelfit_workflow(name='modelfit'):
4042
misalignment)
4143
"""
4244

45+
version = 0
46+
if fsl.Info.version() and \
47+
LooseVersion(fsl.Info.version()) > LooseVersion('5.0.6'):
48+
version = 507
49+
4350
modelfit = pe.Workflow(name=name)
4451

4552
"""
@@ -57,14 +64,23 @@ def create_modelfit_workflow(name='modelfit'):
5764
level1design = pe.Node(interface=fsl.Level1Design(), name="level1design")
5865
modelgen = pe.MapNode(interface=fsl.FEATModel(), name='modelgen',
5966
iterfield=['fsf_file', 'ev_files'])
60-
modelestimate = pe.MapNode(interface=fsl.FILMGLS(smooth_autocorr=True,
61-
mask_size=5),
62-
name='modelestimate',
63-
iterfield=['design_file', 'in_file'])
64-
conestimate = pe.MapNode(interface=fsl.ContrastMgr(), name='conestimate',
65-
iterfield=['tcon_file', 'param_estimates',
66-
'sigmasquareds', 'corrections',
67-
'dof_file'])
67+
if version < 507:
68+
modelestimate = pe.MapNode(interface=fsl.FILMGLS(smooth_autocorr=True,
69+
mask_size=5),
70+
name='modelestimate',
71+
iterfield=['design_file', 'in_file'])
72+
else:
73+
modelestimate = pe.MapNode(interface=fsl.FILMGLS(smooth_autocorr=True,
74+
mask_size=5),
75+
name='modelestimate',
76+
iterfield=['design_file', 'in_file',
77+
'tcon_file'])
78+
79+
if version < 507:
80+
conestimate = pe.MapNode(interface=fsl.ContrastMgr(), name='conestimate',
81+
iterfield=['tcon_file', 'param_estimates',
82+
'sigmasquareds', 'corrections',
83+
'dof_file'])
6884
ztopval = pe.MapNode(interface=fsl.ImageMaths(op_string='-ztop',
6985
suffix='_pval'),
7086
name='ztop',
@@ -96,18 +112,28 @@ def create_modelfit_workflow(name='modelfit'):
96112
(level1design, modelgen, [('fsf_files', 'fsf_file'),
97113
('ev_files', 'ev_files')]),
98114
(modelgen, modelestimate, [('design_file', 'design_file')]),
99-
(modelgen, conestimate, [('con_file', 'tcon_file')]),
100-
(modelestimate, conestimate, [('param_estimates', 'param_estimates'),
101-
('sigmasquareds', 'sigmasquareds'),
102-
('corrections', 'corrections'),
103-
('dof_file', 'dof_file')]),
104-
(conestimate, ztopval, [(('zstats', pop_lambda), 'in_file')]),
105115
(ztopval, outputspec, [('out_file', 'pfiles')]),
106116
(modelestimate, outputspec, [('param_estimates', 'parameter_estimates'),
107117
('dof_file', 'dof_file')]),
108-
(conestimate, outputspec, [('copes', 'copes'),
109-
('varcopes', 'varcopes')]),
110118
])
119+
if version < 507:
120+
modelfit.connect([
121+
(modelgen, conestimate, [('con_file', 'tcon_file')]),
122+
(modelestimate, conestimate, [('param_estimates', 'param_estimates'),
123+
('sigmasquareds', 'sigmasquareds'),
124+
('corrections', 'corrections'),
125+
('dof_file', 'dof_file')]),
126+
(conestimate, ztopval, [(('zstats', pop_lambda), 'in_file')]),
127+
(conestimate, outputspec, [('copes', 'copes'),
128+
('varcopes', 'varcopes')]),
129+
])
130+
else:
131+
modelfit.connect([
132+
(modelgen, modelestimate, [('con_file', 'tcon_file')]),
133+
(modelestimate, ztopval, [(('zstats', pop_lambda), 'in_file')]),
134+
(modelestimate, outputspec, [('copes', 'copes'),
135+
('varcopes', 'varcopes')]),
136+
])
111137
return modelfit
112138

113139

nipype/workflows/fmri/fsl/preprocess.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -678,14 +678,9 @@ def create_featreg_preproc(name='featpreproc', highpass=True, whichvol='middle')
678678
suffix='_mean'),
679679
iterfield=['in_file'],
680680
name='meanfunc3')
681-
if highpass:
682-
featpreproc.connect(highpass, ('out_file', pickfirst), meanfunc3, 'in_file')
683-
else:
684-
featpreproc.connect(meanscale, ('out_file', pickfirst), meanfunc3, 'in_file')
685681

682+
featpreproc.connect(meanscale, ('out_file', pickfirst), meanfunc3, 'in_file')
686683
featpreproc.connect(meanfunc3, 'out_file', outputnode, 'mean')
687-
688-
689684
return featpreproc
690685

691686

0 commit comments

Comments
 (0)