[BUG]: fMRIPrepConfoundRemover sets incorrect t_r due to nilearn.image.clean_img #420

Merged
synchon merged 3 commits from fix/fmriprepconfoundremover-tr into main 2025-01-24 09:39:23 +00:00
3 changed files with 33 additions and 10 deletions

View file

@ -0,0 +1 @@
Fix ``t_r`` tampering by :func:`nilearn.image.clean_img` in :class:`.fMRIPrepConfoundRemover` by `Fede Raimondo`_ and `Synchon Mandal`_

View file

@ -596,6 +596,8 @@ class fMRIPrepConfoundRemover(BasePreprocessor):
t_r=t_r,
mask_img=mask_img,
)
# Fix t_r as nilearn messes it up
cleaned_img.header["pixdim"][4] = t_r
# Save deconfounded data
deconfounded_img_path = element_tempdir / "deconfounded_data.nii.gz"
nib.save(cleaned_img, deconfounded_img_path)

View file

@ -460,22 +460,32 @@ def test_fMRIPrepConfoundRemover_fit_transform() -> None:
with PartlyCloudyTestingDataGrabber(reduce_confounds=False) as dg:
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
orig_bold = element_data["BOLD"]["data"].get_fdata().copy()
# Get original data
input_img = element_data["BOLD"]["data"]
input_bold = input_img.get_fdata().copy()
input_tr = input_img.header.get_zooms()[3]
# Fit-transform
output = confound_remover.fit_transform(element_data)
trans_bold = output["BOLD"]["data"].get_fdata()
output_img = output["BOLD"]["data"]
output_bold = output_img.get_fdata()
output_tr = output_img.header.get_zooms()[3]
# Transformation is in place
assert_array_equal(
trans_bold, element_data["BOLD"]["data"].get_fdata()
output_bold, element_data["BOLD"]["data"].get_fdata()
)
# Data should have the same shape
assert orig_bold.shape == trans_bold.shape
assert input_bold.shape == output_bold.shape
# but be different
assert_raises(
AssertionError, assert_array_equal, orig_bold, trans_bold
AssertionError, assert_array_equal, input_bold, output_bold
)
# Check t_r
assert input_tr == output_tr
assert "meta" in output["BOLD"]
assert "preprocess" in output["BOLD"]["meta"]
t_meta = output["BOLD"]["meta"]["preprocess"]
@ -506,22 +516,32 @@ def test_fMRIPrepConfoundRemover_fit_transform_masks() -> None:
with PartlyCloudyTestingDataGrabber(reduce_confounds=False) as dg:
element_data = DefaultDataReader().fit_transform(dg["sub-01"])
orig_bold = element_data["BOLD"]["data"].get_fdata().copy()
# Get original data
input_img = element_data["BOLD"]["data"]
input_bold = input_img.get_fdata().copy()
input_tr = input_img.header.get_zooms()[3]
# Fit-transform
output = confound_remover.fit_transform(element_data)
trans_bold = output["BOLD"]["data"].get_fdata()
output_img = output["BOLD"]["data"]
output_bold = output_img.get_fdata()
output_tr = output_img.header.get_zooms()[3]
# Transformation is in place
assert_array_equal(
trans_bold, element_data["BOLD"]["data"].get_fdata()
output_bold, element_data["BOLD"]["data"].get_fdata()
)
# Data should have the same shape
assert orig_bold.shape == trans_bold.shape
assert input_bold.shape == output_bold.shape
# but be different
assert_raises(
AssertionError, assert_array_equal, orig_bold, trans_bold
AssertionError, assert_array_equal, input_bold, output_bold
)
# Check t_r
assert input_tr == output_tr
assert "meta" in output["BOLD"]
assert "preprocess" in output["BOLD"]["meta"]
t_meta = output["BOLD"]["meta"]["preprocess"]