ohif-viewer/platform/core
Alireza 70421225d7
fix(pt): resolve Philips PET private SUV bulkdata before scaling (#6096)
* fix(pt): resolve Philips PET private SUV bulkdata before scaling

When a DICOMweb server delivers the Philips PET private tags SUVScaleFactor
(7053,1000) / ActivityConcentrationScaleFactor (7053,1009) as bulkdata, dcmjs
naturalization leaves them as { BulkDataURI } objects. These were fed verbatim
to calculate-suv, which treats the object as a valid value and silently
corrupts the SUV scaling factors.

Resolve these scalar private tags to numbers during ingestion - in both the
lazy (async) and non-lazy (sync) DICOMweb metadata paths, before INSTANCES_ADDED
fires - by decoding the bulkdata (VR-aware: DS/IS text or little-endian FL/FD).
Harden getPTImageIdInstanceMetadata to coerce values to finite numbers (reusing
@ohif/core utils.toNumber) and reject unresolved bulkdata objects so they can
never reach calculate-suv. Share the bulkdata-attach helper between both
metadata paths. Adds unit tests for the bulkdata decoder/resolver and for
getPTImageIdInstanceMetadata.

* refactor(bulkdata): move PET bulkdata resolution to a generic core tag registry

Generalize resolvePETPrivateScalarBulkData into a datasource-agnostic
utils.resolveBulkDataTags in @ohif/core, backed by a static tag registry
seeded with the Philips PET SUV/activity-concentration scalar tags and
extensible via registerResolvedBulkDataTags.

* fix(bulkdata): strip NUL padding and refresh qido auth before resolution

Address review feedback:
- decodeText now strips NUL (0x00) padding, which String.trim() leaves
  intact, so NUL-padded DS/IS values no longer decode as NaN. Adds a
  regression test.
- refresh qidoDicomWebClient.headers before resolveBulkDataTags in both
  series-metadata paths; retrieveBulkData is bound to qidoDicomWebClient,
  matching every other qido op in this file.

* fix(dicomweb): await deferred metadata storage

* fix(dicomweb): support single-part bulkdata responses
2026-07-11 12:16:32 -04:00
..
.webpack feat: Update to use pnpm (#6031) 2026-06-12 16:04:56 -04:00
src fix(pt): resolve Philips PET private SUV bulkdata before scaling (#6096) 2026-07-11 12:16:32 -04:00
.all-contributorsrc chore(prettier): full repo linting and code reformatting once and for all (#3627) 2023-09-01 16:19:39 -04:00
babel.config.js chore(prettier): full repo linting and code reformatting once and for all (#3627) 2023-09-01 16:19:39 -04:00
CHANGELOG.md chore(version): Update package versions to 3.13.0-beta.89 [skip ci] 2026-06-10 00:29:36 +00:00
jest.config.js feat: customization service append and customize functionality should run once (#4238) 2024-06-19 16:31:59 -04:00
LICENSE Chore/kill yalc with fire (#629) 2019-08-13 15:36:46 -04:00
package.json feat(next): native Generic Viewport migration (useNextViewports) (#6101) 2026-07-11 12:13:54 -04:00
README.md fix(security): For bun, enforce frozen lockfile. For yarn, strongly suggest using frozen lockfile. (#5508) 2025-10-24 16:48:35 -04:00

@ohif/core

@ohif/core is a collection of useful functions and classes for building web-based medical imaging applications. This library helps power OHIF's zero-footprint DICOM viewer.


NPM version NPM downloads All Contributors MIT License

Why?

This library offers pre-packaged solutions for features common to Web-based medical imaging viewers. For example:

  • Hotkeys
  • DICOM Web
  • Hanging Protocols
  • Managing a study's measurements
  • Managing a study's DICOM metadata
  • A flexible pattern for extensions
  • And many others

It does this while remaining decoupled from any particular view library or rendering logic. While we use it to power our React Viewer, it can be used with Vue, React, Vanilla JS, or any number of other frameworks.

Getting Started

The documentation for this library is sparse. The best way to get started is to look at its top level exports, and explore the source code of features that interest you. If you want to see how we use this library, you can check out our viewer implementation.

Install

This library is pre- v1.0. All releases until a v1.0 have the possibility of introducing breaking changes. Please depend on an "exact" version in your projects to prevent issues caused by loose versioning.

// with npm
npm i @ohif/core --save-exact

// with yarn
yarn add @ohif/core --exact

Usage

Usage is dependent on the feature(s) you want to leverage. The bulk of @ohif/core's features are "pure" and can be imported and used in place.

Example: retrieving study metadata from a server

import { studies } from '@ohif/core';

const studiesMetadata = await studies.retrieveStudiesMetadata(
  server, // Object
  studyInstanceUIDs, // Array
  seriesInstanceUIDs // Array (optional)
);

Contributing

It is notoriously difficult to setup multiple dependent repositories for end-to-end testing and development. That's why we recommend writing and running unit tests when adding and modifying features for this library. This allows us to program in isolation without a complex setup, and has the added benefit of producing well-tested business logic.

  1. Clone this repository
  2. Navigate to the project directory, and yarn install --frozen-lockfile
  3. To begin making changes, yarn run dev
  4. To commit changes, run yarn run cm

When creating tests, place the test file "next to" the file you're testing. For example:

// File
index.js;

// Test for file
index.test.js;

As you add and modify code, jest will watch for uncommitted changes and run your tests, reporting the results to your terminal. Make a pull request with your changes to master, and a core team member will review your work. If you have any questions, please don't hesitate to reach out via a GitHub issue.

Contributors

Thanks goes to these wonderful people (emoji key):

Erik Ziegler
Erik Ziegler

💻
Evren Ozkan
Evren Ozkan

💻
Gustavo André Lelis
Gustavo André Lelis

💻
Danny Brown
Danny Brown

💻
allcontributors[bot]
allcontributors[bot]

📖
Ivan Aksamentov
Ivan Aksamentov

💻 ⚠️

This project follows the all-contributors specification. Contributions of any kind welcome!

License

MIT © OHIF