Skip to content

Commit 3826795

Browse files
committed
Merge tag '25.2.4'
25.2.4 (January 14, 2026) Bug-fix release in the 25.2.x series. This release addresses some errors in multi-echo and multi-session processing. * FIX: Set source_file in ds_report* nodes at resampling level (#3590) * FIX: Ravel multi-echo data for BIDSSourceFile with precomputed smriprep (#3583) * FIX: Ensure multi-echo processing and slice timing correction text is in boilerplate (#3577) * FIX: Pass session_id to fieldmap finder (#3573) * FIX: Import LinAlgError from a stable location (#3572) * ENH: Raise error if two-echo data are provided (#3570) * MNT: Prune Ubuntu environment before building docker images (#3571)
2 parents 37e151d + d1e486e commit 3826795

File tree

9 files changed

+107
-86
lines changed

9 files changed

+107
-86
lines changed

CHANGES.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
25.2.4 (January 14, 2026)
2+
=========================
3+
Bug-fix release in the 25.2.x series.
4+
5+
This release addresses some errors in multi-echo and multi-session processing.
6+
7+
* FIX: Set source_file in ds_report* nodes at resampling level (#3590)
8+
* FIX: Ravel multi-echo data for BIDSSourceFile with precomputed smriprep (#3583)
9+
* FIX: Ensure multi-echo processing and slice timing correction text is in boilerplate (#3577)
10+
* FIX: Pass session_id to fieldmap finder (#3573)
11+
* FIX: Import LinAlgError from a stable location (#3572)
12+
* ENH: Raise error if two-echo data are provided (#3570)
13+
* MNT: Prune Ubuntu environment before building docker images (#3571)
14+
115
25.2.3 (October 17, 2025)
216
=========================
317
Bug-fix release in the 25.2.x series.

fmriprep/data/boilerplate.bib

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,3 +379,16 @@ @article{onavg
379379
pages = {1736--1742},
380380
doi = {10.1038/s41592-024-02346-y},
381381
}
382+
383+
@article{DuPre2021,
384+
doi = {10.21105/joss.03669},
385+
url = {https://doi.org/10.21105/joss.03669},
386+
year = {2021},
387+
publisher = {The Open Journal},
388+
volume = {6},
389+
number = {66},
390+
pages = {3669},
391+
author = {DuPre, Elizabeth and Salo, Taylor and Ahmed, Zaki and Bandettini, Peter A. and Bottenhorn, Katherine L. and Caballero-Gaudes, César and Dowdle, Logan T. and Gonzalez-Castillo, Javier and Heunis, Stephan and Kundu, Prantik and Laird, Angela R. and Markello, Ross and Markiewicz, Christopher J. and Moia, Stefano and Staden, Isla and Teves, Joshua B. and Uruñuela, Eneko and Vaziri-Pashkam, Maryam and Whitaker, Kirstie and Handwerker, Daniel A.},
392+
title = {TE-dependent analysis of multi-echo fMRI with *tedana*},
393+
journal = {Journal of Open Source Software},
394+
}

fmriprep/interfaces/bids.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def _run_interface(self, runtime):
8585
src = self.inputs.bids_info[self.inputs.anat_type]
8686

8787
if not src and self.inputs.precomputed.get(f'{self.inputs.anat_type}_preproc'):
88-
src = self.inputs.bids_info['bold']
88+
src = _ravel(self.inputs.bids_info['bold'])
8989
self._results['source_file'] = _create_multi_source_file(src)
9090
return runtime
9191

fmriprep/interfaces/tests/test_bids.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""Tests for fmriprep.interfaces.bids."""
22

3+
import pytest
4+
35

46
def test_BIDSURI():
57
"""Test the BIDSURI interface."""
@@ -70,3 +72,62 @@ def test_BIDSURI():
7072
'bids:deriv-0:sub-01/func/sub-01_task-rest_bold.nii.gz',
7173
'/out/sub-01/func/sub-01_task-rest_bold.nii.gz', # No change
7274
]
75+
76+
77+
bids_infos_anat = [
78+
[{'t1w': ['sub-01/anat/sub-01_T1w.nii.gz']}, {}],
79+
[{'t2w': ['sub-01/anat/sub-01_T2w.nii.gz']}, {}],
80+
[
81+
{'t1w': []},
82+
{'t1w_preproc': ['sourcedata/smriprep/sub-01/anat/sub-01_desc-preproc_T1w.nii.gz']},
83+
],
84+
[
85+
{'t2w': []},
86+
{'t2w_preproc': ['sourcedata/smriprep/sub-01/anat/sub-01_desc-preproc_T2w.nii.gz']},
87+
],
88+
]
89+
90+
bids_infos_func = {
91+
'single-echo': {
92+
'bold': ['sub-01/func/sub-01_task-rest_bold.nii.gz'],
93+
},
94+
'multi-echo': {
95+
'bold': [
96+
[
97+
'sub-01/func/sub-01_task-rest_echo-1_bold.nii.gz',
98+
'sub-01/func/sub-01_task-rest_echo-2_bold.nii.gz',
99+
'sub-01/func/sub-01_task-rest_echo-3_bold.nii.gz',
100+
],
101+
],
102+
},
103+
}
104+
105+
106+
@pytest.mark.parametrize(
107+
('bids_info_anat', 'bids_info_func', 'precomputed_infos'),
108+
[
109+
(bids_info_anat, bids_info_func, precomputed_infos)
110+
for bids_info_anat, precomputed_infos in bids_infos_anat
111+
for func_case, bids_info_func in bids_infos_func.items()
112+
],
113+
)
114+
def test_BIDSSourceFile(bids_info_anat, bids_info_func, precomputed_infos):
115+
"""Test the BIDSSourceFile interface"""
116+
from fmriprep.interfaces.bids import BIDSSourceFile
117+
118+
interface = BIDSSourceFile()
119+
anat_type = next(iter(bids_info_anat))
120+
interface.inputs.anat_type = anat_type
121+
interface.inputs.bids_info = {**bids_info_anat, **bids_info_func}
122+
interface.inputs.precomputed = precomputed_infos
123+
results = interface.run()
124+
125+
if precomputed_infos:
126+
bold = (
127+
'sub-01/func/sub-01_bold.nii.gz'
128+
if isinstance(bids_info_func['bold'][0], list)
129+
else 'sub-01/func/sub-01_task-rest_bold.nii.gz'
130+
)
131+
assert results.outputs.source_file == bold
132+
else:
133+
assert results.outputs.source_file == bids_info_anat[anat_type][0]

fmriprep/workflows/bold/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ def init_bold_wf(
374374
for node in workflow.list_node_names():
375375
if node.split('.')[-1].startswith('ds_report'):
376376
workflow.get_node(node).inputs.base_directory = fmriprep_dir
377+
workflow.get_node(node).inputs.source_file = bold_file
377378
return workflow
378379

379380
# Pass along BOLD reference as a source file for provenance

fmriprep/workflows/bold/fit.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,7 @@ def init_bold_native_wf(
802802
.. _optimal combination: https://tedana.readthedocs.io/en/stable/approach.html#optimal-combination
803803
804804
"""
805+
from niworkflows.engine.workflows import LiterateWorkflow as Workflow
805806

806807
layout = config.execution.layout
807808

@@ -830,7 +831,7 @@ def init_bold_native_wf(
830831

831832
run_stc = bool(metadata.get('SliceTiming')) and 'slicetiming' not in config.workflow.ignore
832833

833-
workflow = pe.Workflow(name=name)
834+
workflow = Workflow(name=name)
834835

835836
inputnode = pe.Node(
836837
niu.IdentityInterface(

fmriprep/workflows/bold/t2s.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ def init_bold_t2s_wf(
9999
fit_str = 'log-linear regression'
100100

101101
workflow.__desc__ = f"""\
102-
A T2<sup>★</sup> map was estimated from the preprocessed EPI echoes, by voxel-wise fitting
103-
the maximal number of echoes with reliable signal in that voxel to a monoexponential signal
104-
decay model with {fit_str}.
102+
A T2<sup>★</sup> map was estimated from the preprocessed EPI echoes using tedana's t2smap
103+
workflow [@DuPre2021], by voxel-wise fitting the maximal number of echoes with reliable signal in
104+
that voxel to a monoexponential signal decay model with {fit_str}.
105105
The calculated T2<sup>★</sup> map was then used to optimally combine preprocessed BOLD across
106106
echoes following the method described in [@posse_t2s].
107107
The optimally combined time series was carried forward as the *preprocessed BOLD*.

pixi.lock

Lines changed: 11 additions & 80 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ dependencies = [
2727
"nireports >= 24.1.0",
2828
"nitime >= 0.9",
2929
"nitransforms >= 25.0.1",
30-
"niworkflows >= 1.14.2",
30+
"niworkflows >= 1.14.4",
3131
"numpy >= 2.0",
3232
"packaging >= 24",
3333
"pandas >= 2.2",

0 commit comments

Comments
 (0)