Skip to content

Commit 3bd4c4f

Browse files
Shizoquaericspod
andauthored
Warn when PydicomReader falls back to an identity affine (#8468) (#8934)
### Description Fixes #8468. When `ImageOrientationPatient` (0020,0037) and `ImagePositionPatient` (0020,0032) are missing from the metadata (e.g. some multi-frame Enhanced DICOM), `PydicomReader._get_affine` returned `np.eye(4)` with no indication, so downstream orientation and spacing were silently wrong. This adds a `UserWarning` that names the missing tags, states the affine defaults to identity, and suggests `ITKReader` for such files. The fallback behaviour itself is unchanged — this only surfaces it. ### Types of changes - [x] Non-breaking change (fix or new feature that would not break existing functionality). - [x] New tests added to cover the changes. ### Testing Added `tests/data/test_pydicom_reader.py` asserting that `_get_affine` warns (`UserWarning`) and returns identity when the orientation/position tags are absent or only partially present. ``` python -m unittest tests.data.test_pydicom_reader # Ran 2 tests ... OK ``` Signed-off-by: Lanre Shittu <136805224+Shizoqua@users.noreply.github.com> Signed-off-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com> Co-authored-by: Eric Kerfoot <17726042+ericspod@users.noreply.github.com>
1 parent 1a26bc9 commit 3bd4c4f

2 files changed

Lines changed: 49 additions & 5 deletions

File tree

monai/data/image_reader.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -744,11 +744,11 @@ def _get_affine(self, metadata: dict, lps_to_ras: bool = True):
744744
affine: np.ndarray = np.eye(4)
745745
if not ("00200037" in metadata and "00200032" in metadata):
746746
warnings.warn(
747-
"PydicomReader: ImageOrientationPatient (00200037) or "
748-
"ImagePositionPatient (00200032) not found in DICOM metadata. "
749-
"The affine matrix will be set to identity, which may be incorrect. "
750-
"This commonly occurs with multiframe DICOM files (e.g., Enhanced CT). "
751-
"Consider using ITKReader for accurate spatial metadata.",
747+
"PydicomReader: ImageOrientationPatient (0020,0037) and/or "
748+
"ImagePositionPatient (0020,0032) tags are missing, so the affine "
749+
"matrix cannot be derived and defaults to the identity. The image "
750+
"orientation and spacing may be incorrect (e.g. for multi-frame "
751+
"Enhanced DICOM); consider using ITKReader for such files.",
752752
stacklevel=2,
753753
)
754754
return affine

tests/data/test_pydicom_reader.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Copyright (c) MONAI Consortium
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
# Unless required by applicable law or agreed to in writing, software
7+
# distributed under the License is distributed on an "AS IS" BASIS,
8+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
# See the License for the specific language governing permissions and
10+
# limitations under the License.
11+
12+
from __future__ import annotations
13+
14+
import unittest
15+
16+
import numpy as np
17+
18+
from monai.data import PydicomReader
19+
from tests.test_utils import SkipIfNoModule
20+
21+
22+
@SkipIfNoModule("pydicom")
23+
class TestPydicomReaderAffine(unittest.TestCase):
24+
def test_missing_orientation_tags_warns_and_returns_identity(self):
25+
# Without ImageOrientationPatient (0020,0037) and ImagePositionPatient
26+
# (0020,0032) the affine cannot be derived. The reader falls back to the
27+
# identity matrix; regression test for #8468 ensures this is no longer
28+
# silent so users know orientation/spacing may be wrong.
29+
reader = PydicomReader()
30+
with self.assertWarns(UserWarning):
31+
affine = reader._get_affine({})
32+
np.testing.assert_array_equal(affine, np.eye(4))
33+
34+
def test_partial_orientation_tags_warns(self):
35+
# Only one of the two required tags present is still insufficient.
36+
reader = PydicomReader()
37+
metadata = {"00200037": {"Value": [1, 0, 0, 0, 1, 0]}} # orientation only
38+
with self.assertWarns(UserWarning):
39+
affine = reader._get_affine(metadata)
40+
np.testing.assert_array_equal(affine, np.eye(4))
41+
42+
43+
if __name__ == "__main__":
44+
unittest.main()

0 commit comments

Comments
 (0)