From faef2390122e82f7052255829ed96e2e4764ea27 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Thu, 14 Aug 2025 19:24:50 +0200 Subject: [PATCH 1/3] fix: respect singleton 4d --- nitransforms/resampling.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nitransforms/resampling.py b/nitransforms/resampling.py index 2428a769..8cb20594 100644 --- a/nitransforms/resampling.py +++ b/nitransforms/resampling.py @@ -234,6 +234,7 @@ def apply( if isinstance(spatialimage, (str, Path)): spatialimage = _nbload(str(spatialimage)) + singleton_4d = spatialimage.ndim == 4 and spatialimage.shape[-1] == 1 spatialimage = squeeze_image(spatialimage) # Avoid opening the data array just yet @@ -370,7 +371,8 @@ def apply( with suppress(ValueError): resampled = np.squeeze(resampled, axis=3) - moved = spatialimage.__class__(resampled, _ref.affine, hdr) + moved = spatialimage.__class__( + resampled[..., None] if singleton_4d else resampled, _ref.affine, hdr) return moved output_dtype = output_dtype or input_dtype From bfa39e15ad3be7aef941e9ae443322a2801a02e4 Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Fri, 15 Aug 2025 08:27:21 +0200 Subject: [PATCH 2/3] tst: ensure singleton 4th dim is respected --- nitransforms/tests/test_resampling.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nitransforms/tests/test_resampling.py b/nitransforms/tests/test_resampling.py index 3ff8fb36..f2ca1fb7 100644 --- a/nitransforms/tests/test_resampling.py +++ b/nitransforms/tests/test_resampling.py @@ -57,7 +57,8 @@ def test_apply_singleton_time_dimension(): data = np.reshape(np.arange(27, dtype=np.uint8), (3, 3, 3, 1)) nii = nb.Nifti1Image(data, np.eye(4)) xfm = nitl.Affine(np.eye(4), reference=nii) - apply(xfm, nii) + movednii = apply(xfm, nii) + assert movednii.shape == nii.shape @pytest.mark.parametrize( From ebae5c751029c400dff248829774818e7cb4bb6a Mon Sep 17 00:00:00 2001 From: Oscar Esteban Date: Fri, 15 Aug 2025 08:31:40 +0200 Subject: [PATCH 3/3] tst: improve test with more specific inputs The shape of the output is defined by the reference shape in space, and by the input and the transform in the 4th dimension. --- nitransforms/tests/test_resampling.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nitransforms/tests/test_resampling.py b/nitransforms/tests/test_resampling.py index f2ca1fb7..f9b88577 100644 --- a/nitransforms/tests/test_resampling.py +++ b/nitransforms/tests/test_resampling.py @@ -56,9 +56,13 @@ def test_apply_singleton_time_dimension(): data = np.reshape(np.arange(27, dtype=np.uint8), (3, 3, 3, 1)) nii = nb.Nifti1Image(data, np.eye(4)) - xfm = nitl.Affine(np.eye(4), reference=nii) + ref = nb.Nifti1Image(np.zeros((4, 4, 4)), np.eye(4)) + xfm = nitl.Affine(np.eye(4), reference=ref) movednii = apply(xfm, nii) - assert movednii.shape == nii.shape + assert movednii.shape == ref.shape + (1, ) + + movednii = apply(xfm, nii, reference=ref) + assert movednii.shape == ref.shape + (1, ) @pytest.mark.parametrize(