Skip to content

Commit 6814fa7

Browse files
authored
Merge pull request #1455 from poldracklab/revert-1443-fix/compcor_nans
Revert "[MRG] FIX: Output NaN columns for CompCor on failure"
2 parents 4369e64 + ddcef70 commit 6814fa7

File tree

5 files changed

+32
-110
lines changed

5 files changed

+32
-110
lines changed

docs/environment.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ dependencies:
2020
- python-dateutil
2121
- pydot>=1.2.3
2222
- cython
23-
- nipype>=1.1.7
23+
- nipype>=1.1.6
2424

2525
- pip:
2626
- sphinx-argparse

fmriprep/__about__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
'indexed_gzip>=0.8.8',
8989
'nibabel>=2.2.1',
9090
'nilearn',
91-
'nipype>=1.1.7',
91+
'nipype>=1.1.6',
9292
'nitime',
9393
'niworkflows>=0.5.2.post5,<0.5.3',
9494
'numpy',

fmriprep/interfaces/patches.py

Lines changed: 28 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -12,104 +12,49 @@
1212

1313
from numpy.linalg.linalg import LinAlgError
1414
from nipype.algorithms import confounds as nac
15-
from nipype.interfaces.base import File
16-
from nipype.interfaces.mixins import reporting
1715

1816

19-
class RetryCompCorInputSpecMixin(reporting.ReportCapableInputSpec):
20-
out_report = File('report.html', usedefault=True, hash_files=False,
21-
desc='filename for warning HTML snippet')
17+
class RobustACompCor(nac.ACompCor):
18+
"""
19+
Runs aCompCor several times if it suddenly fails with
20+
https://github.com/poldracklab/fmriprep/issues/776
2221
22+
"""
2323

24-
class RetryCompCorMixin(reporting.ReportCapableInterface):
2524
def _run_interface(self, runtime):
26-
warn = self.inputs.failure_mode == 'NaN'
27-
2825
failures = 0
29-
save_exc = None
3026
while True:
31-
success = True
32-
# Identifiy success/failure in both error and NaN mode
3327
try:
34-
runtime = super()._run_interface(runtime)
35-
if warn and self._is_allnans():
36-
success = False
37-
except LinAlgError as exc:
38-
success = False
39-
save_exc = exc
40-
41-
if success:
28+
runtime = super(RobustACompCor, self)._run_interface(runtime)
4229
break
43-
44-
failures += 1
45-
if failures > 10:
46-
if warn:
47-
break
48-
raise save_exc
49-
start = (failures - 1) * 10
50-
sleep(randint(start + 4, start + 10))
30+
except LinAlgError:
31+
failures += 1
32+
if failures > 10:
33+
raise
34+
start = (failures - 1) * 10
35+
sleep(randint(start + 4, start + 10))
5136

5237
return runtime
5338

54-
def _is_allnans(self):
55-
import numpy as np
56-
outputs = self._list_outputs()
57-
components = np.loadtxt(outputs['components_file'], skiprows=1)
58-
return np.isnan(components).all()
59-
60-
def _generate_report(self):
61-
snippet = '<!-- {} completed without error -->'.format(self._header)
62-
if self._is_allnans():
63-
snippet = '''\
64-
<p class="elem-desc">
65-
Warning: {} components could not be estimated, due to a linear algebra error.
66-
While not definitive, this may be an indication of a poor mask.
67-
Please inspect the {} contours above to ensure that they are located
68-
in the white matter/CSF.
69-
</p>
70-
'''.format(self._header, 'magenta' if self._header[0] == 'a' else 'blue')
71-
72-
with open(self._out_report, 'w') as fobj:
73-
fobj.write(snippet)
74-
75-
76-
class RobustACompCorInputSpec(RetryCompCorInputSpecMixin, nac.CompCorInputSpec):
77-
pass
78-
79-
80-
class RobustACompCorOutputSpec(reporting.ReportCapableOutputSpec, nac.CompCorOutputSpec):
81-
pass
82-
83-
84-
class RobustACompCor(RetryCompCorMixin, nac.ACompCor):
85-
"""
86-
Runs aCompCor several times if it suddenly fails with
87-
https://github.com/poldracklab/fmriprep/issues/776
88-
89-
Warns by default, rather than failing, on linear algebra errors.
90-
https://github.com/poldracklab/fmriprep/issues/1433
9139

40+
class RobustTCompCor(nac.TCompCor):
9241
"""
93-
input_spec = RobustACompCorInputSpec
94-
output_spec = RobustACompCorOutputSpec
95-
96-
97-
class RobustTCompCorInputSpec(RetryCompCorInputSpecMixin, nac.TCompCorInputSpec):
98-
pass
99-
100-
101-
class RobustTCompCorOutputSpec(reporting.ReportCapableOutputSpec, nac.TCompCorOutputSpec):
102-
pass
103-
42+
Runs tCompCor several times if it suddenly fails with
43+
https://github.com/poldracklab/fmriprep/issues/940
10444
105-
class RobustTCompCor(RetryCompCorMixin, nac.TCompCor):
10645
"""
107-
Runs tCompCor several times if it suddenly fails with
108-
https://github.com/poldracklab/fmriprep/issues/776
10946

110-
Warns by default, rather than failing, on linear algebra errors.
111-
https://github.com/poldracklab/fmriprep/issues/1433
47+
def _run_interface(self, runtime):
48+
failures = 0
49+
while True:
50+
try:
51+
runtime = super(RobustTCompCor, self)._run_interface(runtime)
52+
break
53+
except LinAlgError:
54+
failures += 1
55+
if failures > 10:
56+
raise
57+
start = (failures - 1) * 10
58+
sleep(randint(start + 4, start + 10))
11259

113-
"""
114-
input_spec = RobustTCompCorInputSpec
115-
output_spec = RobustTCompCorOutputSpec
60+
return runtime

fmriprep/viz/config.json

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -98,16 +98,6 @@
9898
"title": "ROIs in BOLD space",
9999
"description": "Brain mask calculated on the BOLD signal (red contour), along with the masks used for a/tCompCor.<br />The aCompCor mask (magenta contour) is a conservative CSF and white-matter mask for extracting physiological and movement confounds. <br />The fCompCor mask (blue contour) contains the top 5% most variable voxels within a heavily-eroded brain-mask."
100100
},
101-
{
102-
"name": "epi/warn_tcompcor",
103-
"file_pattern": "func/.*_acompcor\\.",
104-
"raw": true
105-
},
106-
{
107-
"name": "epi/warn_tcompcor",
108-
"file_pattern": "func/.*_tcompcor\\.",
109-
"raw": true
110-
},
111101
{
112102
"name": "epi_mean_t1_registration/flirt",
113103
"file_pattern": "func/.*_flirtnobbr",

fmriprep/workflows/bold/confounds.py

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,12 @@ def init_bold_confs_wf(mem_gb, metadata, name="bold_confs_wf"):
183183
# a/t-CompCor
184184
tcompcor = pe.Node(
185185
TCompCor(components_file='tcompcor.tsv', header_prefix='t_comp_cor_', pre_filter='cosine',
186-
save_pre_filter=True, percentile_threshold=.05, failure_mode='NaN',
187-
generate_report=True),
186+
save_pre_filter=True, percentile_threshold=.05),
188187
name="tcompcor", mem_gb=mem_gb)
189188

190189
acompcor = pe.Node(
191190
ACompCor(components_file='acompcor.tsv', header_prefix='a_comp_cor_', pre_filter='cosine',
192-
save_pre_filter=True, failure_mode='NaN', generate_report=True),
191+
save_pre_filter=True),
193192
name="acompcor", mem_gb=mem_gb)
194193

195194
# Set TR if present
@@ -224,16 +223,6 @@ def init_bold_confs_wf(mem_gb, metadata, name="bold_confs_wf"):
224223
name='ds_report_bold_rois', run_without_submitting=True,
225224
mem_gb=DEFAULT_MEMORY_MIN_GB)
226225

227-
ds_report_warn_acompcor = pe.Node(
228-
DerivativesDataSink(suffix='acompcor'),
229-
name='ds_report_warn_acompcor', run_without_submitting=True,
230-
mem_gb=DEFAULT_MEMORY_MIN_GB)
231-
232-
ds_report_warn_tcompcor = pe.Node(
233-
DerivativesDataSink(suffix='tcompcor'),
234-
name='ds_report_warn_tcompcor', run_without_submitting=True,
235-
mem_gb=DEFAULT_MEMORY_MIN_GB)
236-
237226
def _pick_csf(files):
238227
return files[0]
239228

@@ -314,8 +303,6 @@ def _pick_wm(files):
314303
(acc_msk, mrg_compcor, [('out', 'in2')]),
315304
(mrg_compcor, rois_plot, [('out', 'in_rois')]),
316305
(rois_plot, ds_report_bold_rois, [('out_report', 'in_file')]),
317-
(acompcor, ds_report_warn_acompcor, [('out_report', 'in_file')]),
318-
(tcompcor, ds_report_warn_tcompcor, [('out_report', 'in_file')]),
319306
])
320307

321308
return workflow

0 commit comments

Comments
 (0)