From 4a515495ba26355679ea5c6774755c0ca14ea3bd Mon Sep 17 00:00:00 2001 From: SID Date: Sat, 27 Jun 2026 16:11:51 -0400 Subject: [PATCH 1/2] fix(data): avoid divide-by-zero in pydicom affine for single-slice volumes Signed-off-by: SID --- monai/data/image_reader.py | 2 +- tests/data/test_init_reader.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/monai/data/image_reader.py b/monai/data/image_reader.py index a85eb95c20..56ed1f9ca3 100644 --- a/monai/data/image_reader.py +++ b/monai/data/image_reader.py @@ -758,7 +758,7 @@ def _get_affine(self, metadata: dict, lps_to_ras: bool = True): affine[2, 3] = sz # 3d - if "lastImagePositionPatient" in metadata: + if "lastImagePositionPatient" in metadata and metadata[MetaKeys.SPATIAL_SHAPE][-1] > 1: t1n, t2n, t3n = metadata["lastImagePositionPatient"] n = metadata[MetaKeys.SPATIAL_SHAPE][-1] k1, k2, k3 = (t1n - sx) / (n - 1), (t2n - sy) / (n - 1), (t3n - sz) / (n - 1) diff --git a/tests/data/test_init_reader.py b/tests/data/test_init_reader.py index 169fd20a5f..1bcd042611 100644 --- a/tests/data/test_init_reader.py +++ b/tests/data/test_init_reader.py @@ -19,6 +19,7 @@ from monai.data import ITKReader, NibabelReader, NrrdReader, NumpyReader, PILReader, PydicomReader from monai.transforms import LoadImage, LoadImaged +from monai.utils import MetaKeys from tests.test_utils import SkipIfNoModule @@ -100,6 +101,38 @@ def test_nibabel_reader_avoids_eager_c_order_copy(self): # (F-order) layout from nibabel should be preserved here. self.assertFalse(data.flags.c_contiguous) + def test_pydicom_reader_get_affine_single_slice_with_last_position(self): + reader = PydicomReader() + metadata = { + "00200037": {"Value": [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]}, + "00200032": {"Value": [10.0, 20.0, 30.0]}, + "00280030": {"Value": [0.5, 0.25]}, + "lastImagePositionPatient": np.array([10.0, 20.0, 30.0]), + MetaKeys.SPATIAL_SHAPE: np.array([64, 64, 1]), + } + + affine = reader._get_affine(metadata, lps_to_ras=False) + + np.testing.assert_allclose(affine[0, 2], 0.0) + np.testing.assert_allclose(affine[1, 2], 0.0) + np.testing.assert_allclose(affine[2, 2], 1.0) + + def test_pydicom_reader_get_affine_multi_slice_uses_last_position(self): + reader = PydicomReader() + metadata = { + "00200037": {"Value": [1.0, 0.0, 0.0, 0.0, 1.0, 0.0]}, + "00200032": {"Value": [0.0, 0.0, 0.0]}, + "00280030": {"Value": [1.0, 1.0]}, + "lastImagePositionPatient": np.array([0.0, 0.0, 4.0]), + MetaKeys.SPATIAL_SHAPE: np.array([8, 8, 5]), + } + + affine = reader._get_affine(metadata, lps_to_ras=False) + + np.testing.assert_allclose(affine[0, 2], 0.0) + np.testing.assert_allclose(affine[1, 2], 0.0) + np.testing.assert_allclose(affine[2, 2], 1.0) + if __name__ == "__main__": unittest.main() From 6b5f388810eef300fed3a89cbd782803fb610e11 Mon Sep 17 00:00:00 2001 From: SID Date: Sat, 27 Jun 2026 16:21:33 -0400 Subject: [PATCH 2/2] test(data): skip pydicom affine tests when Pydicom is unavailable Signed-off-by: SID --- tests/data/test_init_reader.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/data/test_init_reader.py b/tests/data/test_init_reader.py index 1bcd042611..bad58cd42f 100644 --- a/tests/data/test_init_reader.py +++ b/tests/data/test_init_reader.py @@ -101,6 +101,7 @@ def test_nibabel_reader_avoids_eager_c_order_copy(self): # (F-order) layout from nibabel should be preserved here. self.assertFalse(data.flags.c_contiguous) + @SkipIfNoModule("Pydicom") def test_pydicom_reader_get_affine_single_slice_with_last_position(self): reader = PydicomReader() metadata = { @@ -117,6 +118,7 @@ def test_pydicom_reader_get_affine_single_slice_with_last_position(self): np.testing.assert_allclose(affine[1, 2], 0.0) np.testing.assert_allclose(affine[2, 2], 1.0) + @SkipIfNoModule("Pydicom") def test_pydicom_reader_get_affine_multi_slice_uses_last_position(self): reader = PydicomReader() metadata = {