Skip to content

fix(nifti): pass through DICOM metadata for NIfTI-backed display sets#5970

Open
nutzlastfan wants to merge 3 commits into
OHIF:masterfrom
nutzlastfan:fix/nifti-pass-through-dicom-metadata
Open

fix(nifti): pass through DICOM metadata for NIfTI-backed display sets#5970
nutzlastfan wants to merge 3 commits into
OHIF:masterfrom
nutzlastfan:fix/nifti-pass-through-dicom-metadata

Conversation

@nutzlastfan
Copy link
Copy Markdown

@nutzlastfan nutzlastfan commented Apr 20, 2026

Context

This is a small preparatory upstream PR for a downstream NIfTI workflow.

In the downstream integration, a NIfTI-backed display set can carry DICOM-derived metadata that should be preserved for VOI / series registration instead of falling back to generic defaults.

Changes

  • add @cornerstonejs/nifti-volume-loader to the default extension package
  • if a downstream data source exposes a configured NIfTI URL for a series, pass through DICOM-derived metadata alongside the NIfTI load request

Important Note

This PR is intentionally opened as a draft because the effect depends on paired loader-side support in Cornerstone3D / @cornerstonejs/nifti-volume-loader.

Today, upstream OHIF does not yet have a full built-in NIfTI path in this area, so this branch is best viewed as a minimal handoff hook for discussion rather than as a complete end-user feature.

Why Open It Anyway

The downstream fix request specifically needs an upstream anchor in OHIF/Viewers, but I want to be explicit that the real behavior change also needs the corresponding Cornerstone3D-side implementation and review.

Verification

Code-level port only in this environment. I could not run the full local test / build toolchain from this checkout.

Greptile Summary

This preparatory draft PR adds a NIfTI pass-through hook to the default extension's SOP-class handler: when a data source exposes a niftiPrivateTagName config, the resolved NIfTI URL and associated DICOM metadata are attached to the display set as a lazy loadImageIds callback. The dynamic import and re-thrown errors reflect improvements from prior review rounds; the full behavior still depends on paired loader-side support in @cornerstonejs/nifti-volume-loader.

Confidence Score: 4/5

Safe to iterate on as a draft; one minor correctness nit around isReconstructable should be addressed before promoting to a non-draft.

All prior P1 concerns have been resolved (dynamic import, error propagation, config read from active data source). The one remaining finding is a P2 edge case where an empty NIfTI result incorrectly leaves isReconstructable: true.

extensions/default/src/getSopClassHandlerModule.js — specifically the isReconstructable assignment inside loadImageIds.

Important Files Changed

Filename Overview
extensions/default/src/getSopClassHandlerModule.js Adds NIfTI URL resolution and a lazy loadImageIds callback; previous P1 concerns (static import, silent errors, stale config) are all addressed in this version. One remaining minor issue: isReconstructable is forced to true even when the loader returns an empty image-ID array.
extensions/default/package.json Adds @cornerstonejs/nifti-volume-loader at 4.21.7 as a hard dependency; version is consistent with other Cornerstone packages in the project and the package is already tracked by cs3d-set-version.mjs.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/default/src/getSopClassHandlerModule.js
Line: 180-184

Comment:
**`isReconstructable: true` set unconditionally on empty result**

`isReconstructable` is forced to `true` regardless of what `createNiftiImageIdsAndCacheMetadata` actually returns. If the loader resolves with an empty array (`loadedImageIds.length === 0`), the display set will advertise 0 frames but still claim to be reconstructable, which can confuse the volume-loading path downstream.

```suggestion
          imageSet.setAttributes({
            imageIds: loadedImageIds,
            numImageFrames: Array.isArray(loadedImageIds) ? loadedImageIds.length : 0,
            isReconstructable: Array.isArray(loadedImageIds) && loadedImageIds.length > 0,
          });
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (3): Last reviewed commit: "fix(nifti): resolve datasource config at..." | Re-trigger Greptile

@netlify
Copy link
Copy Markdown

netlify Bot commented Apr 20, 2026

Deploy Preview for ohif-dev canceled.

Name Link
🔨 Latest commit 08902ec
🔍 Latest deploy log https://app.netlify.com/projects/ohif-dev/deploys/69e5e9d300b1ef0008dcd5c9

@nutzlastfan nutzlastfan marked this pull request as ready for review April 20, 2026 06:41
Comment thread extensions/default/src/getSopClassHandlerModule.js Outdated
Comment thread extensions/default/src/getSopClassHandlerModule.js
Comment thread extensions/default/src/getSopClassHandlerModule.js
Comment thread extensions/default/src/getSopClassHandlerModule.js Outdated
Copy link
Copy Markdown
Author

Tracked down the regression from downstream testing: the NIfTI datasource config was being resolved once at module initialization time. In our deployed app that could leave niftiPrivateTagName / niftiBaseUrl empty, so OHIF silently fell back to the regular DICOM stack path and loaded individual instances instead of the NIfTI volume. This follow-up commit resolves the datasource config when building each display set again, which restores the working behavior without widening the PR scope.

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