Skip to content

Warn when PydicomReader falls back to an identity affine (#8468)#8934

Open
Shizoqua wants to merge 1 commit into
Project-MONAI:devfrom
Shizoqua:fix/8468-pydicom-affine-warning
Open

Warn when PydicomReader falls back to an identity affine (#8468)#8934
Shizoqua wants to merge 1 commit into
Project-MONAI:devfrom
Shizoqua:fix/8468-pydicom-affine-warning

Conversation

@Shizoqua

Copy link
Copy Markdown

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

  • Non-breaking change (fix or new feature that would not break existing functionality).
  • 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

PydicomReader._get_affine silently returned an identity matrix when the
ImageOrientationPatient (0020,0037) and ImagePositionPatient (0020,0032) tags
were absent (e.g. some multi-frame Enhanced DICOM), leaving the image
orientation and spacing wrong with no indication. Emit a UserWarning naming the
missing tags and recommending ITKReader for such files; the fallback behaviour
is otherwise unchanged.

Fixes Project-MONAI#8468.

Signed-off-by: Lanre Shittu <136805224+Shizoqua@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

PydicomReader._get_affine now calls warnings.warn (with stacklevel=2) when both ImageOrientationPatient and ImagePositionPatient DICOM tags are absent, noting that the affine defaults to identity and may be incorrect for enhanced/multi-frame DICOM files. The identity affine fallback is unchanged. A new test file tests/data/test_pydicom_reader.py verifies this behavior with two cases: completely missing tags and orientation-only tags, both asserting a UserWarning and a 4×4 identity matrix result.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding a warning when PydicomReader falls back to identity affine matrix.
Description check ✅ Passed Description covers issue fix, implementation details, non-breaking change classification, and testing verification with test command output.
Linked Issues check ✅ Passed Code changes fully address issue #8468 by adding UserWarning when orientation/position tags are missing, recommending ITKReader alternative.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the issue: warning in _get_affine method and corresponding tests. No extraneous modifications present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
tests/data/test_pydicom_reader.py (1)

22-40: ⚡ Quick win

Expand test coverage for completeness.

Add tests for:

  1. Only position tag present (00200032 without 00200037) to verify symmetric behavior
  2. Both tags present to verify no warning when metadata is sufficient
🧪 Suggested additional tests
def test_position_only_warns(self):
    """Verify UserWarning when only position tag is present."""
    reader = PydicomReader()
    metadata = {"00200032": {"Value": [0, 0, 0]}}  # position only
    with self.assertWarns(UserWarning):
        affine = reader._get_affine(metadata)
    np.testing.assert_array_equal(affine, np.eye(4))

def test_both_tags_present_no_warning(self):
    """Verify no warning when both required tags are present."""
    reader = PydicomReader()
    metadata = {
        "00200037": {"Value": [1, 0, 0, 0, 1, 0]},
        "00200032": {"Value": [0, 0, 0]},
    }
    # Should not warn when both tags present
    with self.assertRaises(AssertionError):
        with self.assertWarns(UserWarning):
            affine = reader._get_affine(metadata)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/data/test_pydicom_reader.py` around lines 22 - 40, The test class
TestPydicomReaderAffine needs two additional test methods to complete coverage.
Add test_position_only_warns method that instantiates PydicomReader and tests
the _get_affine method with metadata containing only the position tag (00200032)
to verify it warns and returns identity matrix, mirroring the existing
test_partial_orientation_tags_warns behavior. Then add
test_both_tags_present_no_warning method that tests _get_affine with both
required tags (00200037 and 00200032) present to verify that no UserWarning is
raised when metadata is complete.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/data/test_pydicom_reader.py`:
- Around line 24-32: The test method
test_missing_orientation_tags_warns_and_returns_identity is missing a
Google-style docstring. Add a docstring to this method that describes its
purpose, explains what behavior is being tested (that missing orientation tags
trigger a UserWarning and return an identity matrix affine), and clarifies the
regression test context for issue `#8468`. The docstring should be placed
immediately after the method definition line and before any code logic.
- Around line 34-40: The test_partial_orientation_tags_warns method is missing a
Google-style docstring. Add a docstring immediately after the method definition
that describes the test purpose, explains what is being verified (that having
only one of the two required orientation tags results in a UserWarning), and
documents the expected behavior (that the affine matrix returned is the identity
matrix). Follow Google-style docstring conventions with a summary line and
additional details as needed.

---

Nitpick comments:
In `@tests/data/test_pydicom_reader.py`:
- Around line 22-40: The test class TestPydicomReaderAffine needs two additional
test methods to complete coverage. Add test_position_only_warns method that
instantiates PydicomReader and tests the _get_affine method with metadata
containing only the position tag (00200032) to verify it warns and returns
identity matrix, mirroring the existing test_partial_orientation_tags_warns
behavior. Then add test_both_tags_present_no_warning method that tests
_get_affine with both required tags (00200037 and 00200032) present to verify
that no UserWarning is raised when metadata is complete.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ef27f8b3-db81-4769-b9b3-5f336ea7a592

📥 Commits

Reviewing files that changed from the base of the PR and between 15f5073 and 71eaf18.

📒 Files selected for processing (2)
  • monai/data/image_reader.py
  • tests/data/test_pydicom_reader.py

Comment on lines +24 to +32
def test_missing_orientation_tags_warns_and_returns_identity(self):
# Without ImageOrientationPatient (0020,0037) and ImagePositionPatient
# (0020,0032) the affine cannot be derived. The reader falls back to the
# identity matrix; regression test for #8468 ensures this is no longer
# silent so users know orientation/spacing may be wrong.
reader = PydicomReader()
with self.assertWarns(UserWarning):
affine = reader._get_affine({})
np.testing.assert_array_equal(affine, np.eye(4))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add docstring per coding guidelines.

Google-style docstring should describe the test purpose, including what is being verified and expected behavior.

📝 Proposed docstring
 def test_missing_orientation_tags_warns_and_returns_identity(self):
+    """Verify UserWarning is emitted when both orientation and position tags are absent.
+    
+    The affine should default to identity matrix when metadata is empty.
+    """
     # Without ImageOrientationPatient (0020,0037) and ImagePositionPatient
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/data/test_pydicom_reader.py` around lines 24 - 32, The test method
test_missing_orientation_tags_warns_and_returns_identity is missing a
Google-style docstring. Add a docstring to this method that describes its
purpose, explains what behavior is being tested (that missing orientation tags
trigger a UserWarning and return an identity matrix affine), and clarifies the
regression test context for issue `#8468`. The docstring should be placed
immediately after the method definition line and before any code logic.

Source: Coding guidelines

Comment on lines +34 to +40
def test_partial_orientation_tags_warns(self):
# Only one of the two required tags present is still insufficient.
reader = PydicomReader()
metadata = {"00200037": {"Value": [1, 0, 0, 0, 1, 0]}} # orientation only
with self.assertWarns(UserWarning):
affine = reader._get_affine(metadata)
np.testing.assert_array_equal(affine, np.eye(4))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add docstring per coding guidelines.

Google-style docstring should describe the test purpose, including what is being verified and expected behavior.

📝 Proposed docstring
 def test_partial_orientation_tags_warns(self):
+    """Verify UserWarning is emitted when only orientation tag is present.
+    
+    The affine should default to identity when position tag (0020,0032) is missing.
+    """
     # Only one of the two required tags present is still insufficient.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_partial_orientation_tags_warns(self):
# Only one of the two required tags present is still insufficient.
reader = PydicomReader()
metadata = {"00200037": {"Value": [1, 0, 0, 0, 1, 0]}} # orientation only
with self.assertWarns(UserWarning):
affine = reader._get_affine(metadata)
np.testing.assert_array_equal(affine, np.eye(4))
def test_partial_orientation_tags_warns(self):
"""Verify UserWarning is emitted when only orientation tag is present.
The affine should default to identity when position tag (0020,0032) is missing.
"""
# Only one of the two required tags present is still insufficient.
reader = PydicomReader()
metadata = {"00200037": {"Value": [1, 0, 0, 0, 1, 0]}} # orientation only
with self.assertWarns(UserWarning):
affine = reader._get_affine(metadata)
np.testing.assert_array_equal(affine, np.eye(4))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/data/test_pydicom_reader.py` around lines 34 - 40, The
test_partial_orientation_tags_warns method is missing a Google-style docstring.
Add a docstring immediately after the method definition that describes the test
purpose, explains what is being verified (that having only one of the two
required orientation tags results in a UserWarning), and documents the expected
behavior (that the affine matrix returned is the identity matrix). Follow
Google-style docstring conventions with a summary line and additional details as
needed.

Source: Coding guidelines

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PydicomReader should not just silently make up an affine matrix

1 participant