Skip to content

fix(adapters): load co-planar SEGs whose ImageOrientationPatient is DICOM strings#2816

Merged
sedghi merged 1 commit into
mainfrom
fix/seg-orientation-string-iop
Jul 17, 2026
Merged

fix(adapters): load co-planar SEGs whose ImageOrientationPatient is DICOM strings#2816
sedghi merged 1 commit into
mainfrom
fix/seg-orientation-string-iop

Conversation

@sedghi

@sedghi sedghi commented Jul 17, 2026

Copy link
Copy Markdown
Member

Problem

Loading a DICOM SEG that is perfectly in-plane with its source series fails with:

Segmentations orthogonal to the acquisition plane of the source data are not yet supported.

Reproducible against a DICOMweb source (e.g. Orthanc): create a SEG on an axial series, store it, reload — the SEG is rejected as "orthogonal" even though its ImageOrientationPatient is identical to the source.

Root cause

checkOrientation decides in-plane vs perpendicular with utilities.isEqual(iop, sourceCosines, tolerance), which is type-strict. The source cosines are numeric (parsed from the image's imagePlaneModule), but the SEG's ImageOrientationPatient arrives from DICOMweb JSON metadata as DS strings (["1","0","0","0","1","0"]).

  • isEqual(["1","0",…], [1,0,…], 1e-3)false → not in-plane, even though the values are numerically identical.
  • It then falls through to checkIfPerpendicular, which uses arithmetic (string-coercing) and returns true for the parallel row/column cosines → the SEG is classified Perpendicular and rejected.

So a co-planar SEG is misclassified purely due to a string-vs-number mismatch.

Fix

Coerce ImageOrientationPatient to numbers before comparison:

  • helpers/checkOrientation.ts — coerce the SEG's IOP in the shared helper (also protects the legacy Segmentation_4X path).
  • Cornerstone3D/Segmentation/labelmapImagesFromBuffer.ts — normalize the shared and per-frame PlaneOrientationSequence.ImageOrientationPatient in prepareSegMultiframeMetadata, so the subsequent per-frame alignment (alignPixelDataWithSourceData) also sees numbers.

Test

Adds packages/adapters/test/checkOrientation.jest.js covering:

  • numeric co-planar IOP → Planar
  • string co-planar IOP → Planar (the regression; was Perpendicular)
  • genuinely perpendicular IOP → Perpendicular (coercion must not mask real perpendicular SEGs)
  • per-frame IOP fallback (no shared group) with string values → Planar

All pass; the string case fails without the fix.

Summary by CodeRabbit

  • Bug Fixes
    • Improved handling of DICOM orientation metadata provided as text values.
    • Fixed segmentation orientation detection so co-planar and perpendicular segmentations are classified correctly.
    • Added support for orientation data supplied in shared or per-frame metadata.

…ICOM strings

DICOMweb JSON metadata delivers ImageOrientationPatient as DS strings, while the
source cosines used to build validOrientations are numeric. The orientation
check uses a type-strict equality (utilities.isEqual), so a SEG that is
perfectly in-plane with its source was misclassified as perpendicular and
rejected with "Segmentations orthogonal to the acquisition plane of the source
data are not yet supported."

Coerce ImageOrientationPatient to numbers in checkOrientation and when preparing
the SEG multiframe metadata (shared + per-frame functional groups), so a
string-vs-number mismatch never defeats the comparison. Adds a checkOrientation
unit test covering the numeric, string, genuinely-perpendicular, and
per-frame-fallback cases.
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The adapter now converts DICOMweb-derived ImageOrientationPatient values to numbers during metadata preparation and orientation checks. Tests cover shared and per-frame orientations, planar and perpendicular classifications, and string-valued direction cosines.

Changes

Segmentation orientation normalization

Layer / File(s) Summary
Normalize orientation metadata
packages/adapters/src/adapters/Cornerstone3D/Segmentation/labelmapImagesFromBuffer.ts, packages/adapters/src/adapters/helpers/checkOrientation.ts
Shared and per-frame ImageOrientationPatient arrays are coerced to numeric values before orientation comparisons.
Validate orientation classification
packages/adapters/test/checkOrientation.jest.js
Tests cover numeric and string-valued planar orientations, perpendicular classifications, and per-frame fallback behavior.

Estimated code review effort: 3 (Moderate) | ~15–30 minutes

Suggested reviewers: wayfarer3130

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the issue, fix, and tests, but it omits the required checklist and tested-environment sections. Add the template’s checklist and tested-environment fields, and align the description to the required Context, Changes & Results, and Testing sections.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is specific, accurate, and follows the repo’s semantic-release style.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/seg-orientation-string-iop

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
packages/adapters/src/adapters/helpers/checkOrientation.ts (1)

22-24: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Use optional chaining to prevent runtime errors.

If a frame is missing the PlaneOrientationSequence, this direct access will throw a TypeError. Consider using optional chaining, which provides resilience against malformed metadata and aligns with how this sequence is safely accessed in other areas of the codebase.

💡 Proposed refactor
   const iopRaw =
     sharedImageOrientationPatient ||
-    PerFrameFunctionalGroups.PlaneOrientationSequence.ImageOrientationPatient;
+    PerFrameFunctionalGroups?.PlaneOrientationSequence?.ImageOrientationPatient;
🤖 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 `@packages/adapters/src/adapters/helpers/checkOrientation.ts` around lines 22 -
24, Update the iopRaw assignment in checkOrientation to use optional chaining
when accessing PlaneOrientationSequence and ImageOrientationPatient, while
preserving the existing sharedImageOrientationPatient fallback.
🤖 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.

Nitpick comments:
In `@packages/adapters/src/adapters/helpers/checkOrientation.ts`:
- Around line 22-24: Update the iopRaw assignment in checkOrientation to use
optional chaining when accessing PlaneOrientationSequence and
ImageOrientationPatient, while preserving the existing
sharedImageOrientationPatient fallback.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6bf669c3-138c-4eb9-b733-4f951adbc254

📥 Commits

Reviewing files that changed from the base of the PR and between a0bb6c5 and 768c8c9.

📒 Files selected for processing (3)
  • packages/adapters/src/adapters/Cornerstone3D/Segmentation/labelmapImagesFromBuffer.ts
  • packages/adapters/src/adapters/helpers/checkOrientation.ts
  • packages/adapters/test/checkOrientation.jest.js

@sedghi
sedghi merged commit 057707e into main Jul 17, 2026
17 checks passed
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.

1 participant