feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
import { utils, Types as OhifTypes, DicomMetadataStore, classes, log } from '@ohif/core';
|
2025-05-05 22:35:05 +02:00
|
|
|
import i18n from '@ohif/i18n';
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
import { metaData, eventTarget, utilities as csUtils } from '@cornerstonejs/core';
|
2024-11-06 13:15:27 +01:00
|
|
|
import { CONSTANTS, segmentation as cstSegmentation } from '@cornerstonejs/tools';
|
2023-08-08 20:39:31 +02:00
|
|
|
import { adaptersSEG, Enums } from '@cornerstonejs/adapters';
|
2022-11-16 20:19:52 +01:00
|
|
|
|
|
|
|
|
import { SOPClassHandlerId } from './id';
|
2023-08-08 20:39:31 +02:00
|
|
|
import { dicomlabToRGB } from './utils/dicomlabToRGB';
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
import { getSegmentationParserType } from './utils/segmentationConfig';
|
|
|
|
|
import {
|
|
|
|
|
getFrameIndexFromImageId,
|
|
|
|
|
isLocalSchemeImageId,
|
|
|
|
|
stripFrameFromImageId,
|
|
|
|
|
} from './utils/segLocalImageIds';
|
2022-11-16 20:19:52 +01:00
|
|
|
|
2025-06-26 17:59:44 +02:00
|
|
|
const sopClassUids = ['1.2.840.10008.5.1.4.1.1.66.4', '1.2.840.10008.5.1.4.1.1.66.7'];
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
const LABELMAP_SEG_SOP_CLASS_UID = '1.2.840.10008.5.1.4.1.1.66.7';
|
2022-11-16 20:19:52 +01:00
|
|
|
|
2024-05-08 18:12:49 +02:00
|
|
|
const loadPromises = {};
|
2022-11-16 20:19:52 +01:00
|
|
|
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
const SEG_LOAD_LOG_PREFIX = '[SEG load]';
|
|
|
|
|
|
|
|
|
|
// Max number of SEG frames fetched/decoded concurrently by the segmentation
|
|
|
|
|
// loader. Hard-coded to 16 for now; intended to become configurable (and to
|
|
|
|
|
// pair with the full-instance prefetch capability) in a follow-up.
|
|
|
|
|
const SEG_FRAME_DECODE_CONCURRENCY = 16;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function _normalizeImageId(imageId: string | string[] | undefined): string | undefined {
|
|
|
|
|
if (imageId == null) {
|
|
|
|
|
return undefined;
|
|
|
|
|
}
|
|
|
|
|
return Array.isArray(imageId) ? imageId[0] : imageId;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Expands a WADO-RS frame imageId (…/frames/1) into one imageId per frame.
|
|
|
|
|
* Multiframe SEG is stored as separate /frames/N resources on the server.
|
|
|
|
|
*/
|
|
|
|
|
function getFrameImageIds(segImageId: string, numberOfFrames: number): string[] {
|
|
|
|
|
const frameMatch = segImageId.match(/(.*\/frames\/)(\d+)(.*)$/);
|
|
|
|
|
if (!frameMatch || numberOfFrames <= 1) {
|
|
|
|
|
return [segImageId];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const prefix = frameMatch[1];
|
|
|
|
|
const suffix = frameMatch[3] || '';
|
|
|
|
|
const frameImageIds: string[] = [];
|
|
|
|
|
|
|
|
|
|
for (let frameNumber = 1; frameNumber <= numberOfFrames; frameNumber++) {
|
|
|
|
|
frameImageIds.push(`${prefix}${frameNumber}${suffix}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return frameImageIds;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _getSegNumberOfFrames(instance: Record<string, unknown>): number {
|
|
|
|
|
const fromTag = Number(instance.NumberOfFrames);
|
|
|
|
|
if (fromTag > 0) {
|
|
|
|
|
return fromTag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const perFrame = instance.PerFrameFunctionalGroupsSequence;
|
|
|
|
|
if (Array.isArray(perFrame) && perFrame.length > 0) {
|
|
|
|
|
return perFrame.length;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _ensureSegImageIdMetadataRegistered(
|
|
|
|
|
imageId: string | undefined,
|
|
|
|
|
instance: Record<string, unknown>
|
|
|
|
|
): void {
|
|
|
|
|
if (!imageId) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const metadataProvider = classes.MetadataProvider;
|
|
|
|
|
|
|
|
|
|
const StudyInstanceUID = instance.StudyInstanceUID as string | undefined;
|
|
|
|
|
const SeriesInstanceUID = instance.SeriesInstanceUID as string | undefined;
|
|
|
|
|
const SOPInstanceUID = (instance.SOPInstanceUID || instance.SopInstanceUID) as
|
|
|
|
|
| string
|
|
|
|
|
| undefined;
|
|
|
|
|
|
|
|
|
|
if (!StudyInstanceUID || !SeriesInstanceUID || !SOPInstanceUID) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
metadataProvider.addImageIdToUIDs(imageId, {
|
|
|
|
|
StudyInstanceUID,
|
|
|
|
|
SeriesInstanceUID,
|
|
|
|
|
SOPInstanceUID,
|
|
|
|
|
frameNumber: getFrameIndexFromImageId(imageId),
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** Ensures metadataProvider.get('instance', imageId) resolves for frame-qualified local SEG ids. */
|
|
|
|
|
function _ensureSegInstanceMetadataAvailable(
|
|
|
|
|
imageId: string | undefined,
|
|
|
|
|
instance: Record<string, unknown>
|
|
|
|
|
): void {
|
|
|
|
|
if (!imageId) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_ensureSegImageIdMetadataRegistered(imageId, instance);
|
|
|
|
|
|
|
|
|
|
if (metaData.get('instance', imageId)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const StudyInstanceUID = instance.StudyInstanceUID as string | undefined;
|
|
|
|
|
const SeriesInstanceUID = instance.SeriesInstanceUID as string | undefined;
|
|
|
|
|
const SOPInstanceUID = (instance.SOPInstanceUID || instance.SopInstanceUID) as
|
|
|
|
|
| string
|
|
|
|
|
| undefined;
|
|
|
|
|
|
|
|
|
|
const storedInstance =
|
|
|
|
|
StudyInstanceUID && SeriesInstanceUID && SOPInstanceUID
|
|
|
|
|
? DicomMetadataStore.getInstance(StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID)
|
|
|
|
|
: undefined;
|
|
|
|
|
|
|
|
|
|
classes.MetadataProvider.addCustomMetadata(
|
|
|
|
|
imageId,
|
|
|
|
|
'instance',
|
|
|
|
|
storedInstance || instance
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _getSegDataSource(extensionManager, instance: Record<string, unknown>) {
|
|
|
|
|
const StudyInstanceUID = instance.StudyInstanceUID as string | undefined;
|
|
|
|
|
const SeriesInstanceUID = instance.SeriesInstanceUID as string | undefined;
|
|
|
|
|
const SOPInstanceUID = (instance.SOPInstanceUID || instance.SopInstanceUID) as
|
|
|
|
|
| string
|
|
|
|
|
| undefined;
|
|
|
|
|
|
|
|
|
|
let localUrl: string | undefined;
|
|
|
|
|
|
|
|
|
|
if (StudyInstanceUID && SeriesInstanceUID && SOPInstanceUID) {
|
|
|
|
|
const storedInstance = DicomMetadataStore.getInstance(
|
|
|
|
|
StudyInstanceUID,
|
|
|
|
|
SeriesInstanceUID,
|
|
|
|
|
SOPInstanceUID
|
|
|
|
|
);
|
|
|
|
|
localUrl = storedInstance?.url as string | undefined;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
localUrl = localUrl || (instance.url as string | undefined);
|
|
|
|
|
|
|
|
|
|
if (localUrl && isLocalSchemeImageId(localUrl)) {
|
|
|
|
|
const dicomLocal = extensionManager.getDataSources('dicomlocal');
|
|
|
|
|
|
|
|
|
|
if (dicomLocal?.[0]) {
|
|
|
|
|
return dicomLocal[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return extensionManager.getActiveDataSource()[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _getSegImageIdFromInstance(
|
|
|
|
|
instance: Record<string, unknown>,
|
|
|
|
|
dataSource: { getImageIdsForInstance?: (args: { instance: unknown; frame?: number }) => unknown }
|
|
|
|
|
): string | undefined {
|
|
|
|
|
const numberOfFrames = _getSegNumberOfFrames(instance);
|
|
|
|
|
const frame = numberOfFrames > 1 ? 1 : undefined;
|
|
|
|
|
|
|
|
|
|
return _normalizeImageId(
|
|
|
|
|
dataSource.getImageIdsForInstance?.({ instance, frame }) as string | string[] | undefined
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _resolveFrameImageIds(
|
|
|
|
|
segImageIdStr: string,
|
|
|
|
|
instance: Record<string, unknown>,
|
|
|
|
|
dataSource: { getImageIdsForInstance?: (args: { instance: unknown; frame?: number }) => unknown }
|
|
|
|
|
): string[] {
|
|
|
|
|
const numberOfFrames = _getSegNumberOfFrames(instance);
|
|
|
|
|
const fromFrameUrl = getFrameImageIds(segImageIdStr, numberOfFrames);
|
|
|
|
|
|
|
|
|
|
if (fromFrameUrl.length > 1) {
|
|
|
|
|
return fromFrameUrl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (numberOfFrames <= 1) {
|
|
|
|
|
return [segImageIdStr];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const frameImageIds: string[] = [];
|
|
|
|
|
|
|
|
|
|
for (let frame = 1; frame <= numberOfFrames; frame++) {
|
|
|
|
|
const frameImageId = _normalizeImageId(
|
|
|
|
|
dataSource.getImageIdsForInstance?.({ instance, frame }) as string | string[] | undefined
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (frameImageId) {
|
|
|
|
|
frameImageIds.push(frameImageId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return frameImageIds.length ? frameImageIds : [segImageIdStr];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _logSegImageIds({
|
|
|
|
|
segDisplaySet,
|
|
|
|
|
segImageIdStr,
|
|
|
|
|
frameImageIds,
|
|
|
|
|
referencedImageIds,
|
|
|
|
|
}: {
|
|
|
|
|
segDisplaySet: AppTypes.DisplaySet;
|
|
|
|
|
segImageIdStr: string;
|
|
|
|
|
frameImageIds: string[];
|
|
|
|
|
referencedImageIds: string[];
|
|
|
|
|
}) {
|
|
|
|
|
const instance = segDisplaySet.instance as Record<string, unknown>;
|
|
|
|
|
const numberOfFrames = Number(instance?.NumberOfFrames) || 1;
|
|
|
|
|
|
|
|
|
|
log.debug(SEG_LOAD_LOG_PREFIX, 'Loading SEG pixel data', {
|
|
|
|
|
SOPInstanceUID: segDisplaySet.SOPInstanceUID,
|
|
|
|
|
SeriesInstanceUID: segDisplaySet.SeriesInstanceUID,
|
|
|
|
|
SOPClassUID: segDisplaySet.SOPClassUID,
|
|
|
|
|
NumberOfFrames: numberOfFrames,
|
|
|
|
|
segmentCount: Object.keys(segDisplaySet.segments || {}).length,
|
|
|
|
|
referencedDisplaySetInstanceUID: segDisplaySet.referencedDisplaySetInstanceUID,
|
|
|
|
|
referencedImageIdCount: referencedImageIds.length,
|
|
|
|
|
referencedImageIds,
|
|
|
|
|
segImageIdForMetadata: segImageIdStr,
|
|
|
|
|
frameImageIds,
|
|
|
|
|
loadSegFramesIndividually: frameImageIds.length > 1,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-08 18:12:49 +02:00
|
|
|
function _getDisplaySetsFromSeries(
|
|
|
|
|
instances,
|
|
|
|
|
servicesManager: AppTypes.ServicesManager,
|
|
|
|
|
extensionManager
|
|
|
|
|
) {
|
2025-11-21 19:07:26 +01:00
|
|
|
utils.sortStudyInstances(instances);
|
|
|
|
|
|
|
|
|
|
// Choose the LAST instance in the list as the most recently created one.
|
|
|
|
|
const instance = instances[instances.length - 1];
|
2022-11-16 20:19:52 +01:00
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
StudyInstanceUID,
|
|
|
|
|
SeriesInstanceUID,
|
|
|
|
|
SOPInstanceUID,
|
2025-11-21 19:07:26 +01:00
|
|
|
SeriesDescription = '',
|
2022-11-16 20:19:52 +01:00
|
|
|
SeriesNumber,
|
|
|
|
|
SeriesDate,
|
2025-11-21 19:07:26 +01:00
|
|
|
StructureSetDate,
|
2022-11-16 20:19:52 +01:00
|
|
|
SOPClassUID,
|
2026-04-02 14:52:23 +02:00
|
|
|
FrameOfReferenceUID,
|
2022-11-16 20:19:52 +01:00
|
|
|
wadoRoot,
|
|
|
|
|
wadoUri,
|
|
|
|
|
wadoUriRoot,
|
2025-11-21 19:07:26 +01:00
|
|
|
imageId: predecessorImageId,
|
2022-11-16 20:19:52 +01:00
|
|
|
} = instance;
|
|
|
|
|
|
|
|
|
|
const displaySet = {
|
|
|
|
|
Modality: 'SEG',
|
|
|
|
|
loading: false,
|
2025-06-27 13:11:46 +02:00
|
|
|
isReconstructable: false,
|
2022-11-16 20:19:52 +01:00
|
|
|
displaySetInstanceUID: utils.guid(),
|
|
|
|
|
SeriesDescription,
|
|
|
|
|
SeriesNumber,
|
2025-11-21 19:07:26 +01:00
|
|
|
SeriesDate: SeriesDate || StructureSetDate || '',
|
2022-11-16 20:19:52 +01:00
|
|
|
SOPInstanceUID,
|
|
|
|
|
SeriesInstanceUID,
|
|
|
|
|
StudyInstanceUID,
|
|
|
|
|
SOPClassHandlerId,
|
|
|
|
|
SOPClassUID,
|
2026-04-06 18:03:28 +02:00
|
|
|
FrameOfReferenceUID,
|
2022-11-16 20:19:52 +01:00
|
|
|
referencedImages: null,
|
|
|
|
|
referencedSeriesInstanceUID: null,
|
|
|
|
|
referencedDisplaySetInstanceUID: null,
|
|
|
|
|
isDerivedDisplaySet: true,
|
|
|
|
|
isLoaded: false,
|
|
|
|
|
isHydrated: false,
|
|
|
|
|
segments: {},
|
|
|
|
|
sopClassUids,
|
|
|
|
|
instance,
|
2025-11-21 19:07:26 +01:00
|
|
|
predecessorImageId,
|
2023-04-25 23:25:10 +02:00
|
|
|
instances: [instance],
|
2022-11-16 20:19:52 +01:00
|
|
|
wadoRoot,
|
|
|
|
|
wadoUriRoot,
|
|
|
|
|
wadoUri,
|
feat(RT): add dicom RT support via volume viewports (#3310)
* feat: initial RT support
* make the segmentation service work with representation data
* feat: make segmentation service work with representations
* fix rtss vis
* fix: rt hydration
* fix the rendering of rt names
* fix imports
* refactor: Modify status and click handling for hydration of RTStructures
Modify status and click handling for hydration of RTStructures by renaming `onPillClick` to `onStatusClick` in `OHIFCornerstoneRTViewport.tsx` and `_getStatusComponent.tsx` files. Also, update initial segmentation configurations in `PanelSegmentation.tsx` and simplify configuration changes and values for segmentation service in `SegmentationService.ts`. Finally, remove console debug in `CornerstoneViewportService.ts`.
* wip for highlighting contours
* refactor rt displayset code
* review code update
* update cornerstone dependencies
* refactor: Update license year, version number, and minor code cleanup
This commit updates the license year in several files, updates the version number in package.json, and contains minor code cleanup in two files.
* add bulkdataURI retrieve for RT
* fix package version
* apply review comments
* apply review comments
* apply review comments
* feat(panels): refactor and streamline segmentation configuration and inputs
Rewrote state hooks and streamlined the configuration input for `PanelSegmentation` to be more verbose and reusable. Included several new input types, including the `InputRange` component which now shows a fixed floating value based on the step provided. The `SegmentationConfig` component now works with dynamic values controlled by `initialConfig`. These changes should improve function usability and make the code more maintainable going forward.
* fix various bugs
* fix contour delete by upgrade cs3d version
* feat(viewport, inputNumber, segmentationConfig, orthanc): Implement minimum and maximum values for input number components, and useBulkDataURI for Orthanc configuration. Compare measurement view planes with absolute viewport view planes in Cornerstone viewport.
* update yarn lock
2023-04-26 18:21:08 +02:00
|
|
|
isOverlayDisplaySet: true,
|
2025-05-05 22:35:05 +02:00
|
|
|
label: SeriesDescription || `${i18n.t('Series')} ${SeriesNumber} - ${i18n.t('SEG')}`,
|
2022-11-16 20:19:52 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const referencedSeriesSequence = instance.ReferencedSeriesSequence;
|
|
|
|
|
|
|
|
|
|
if (!referencedSeriesSequence) {
|
2023-10-03 16:11:32 +02:00
|
|
|
console.error('ReferencedSeriesSequence is missing for the SEG');
|
|
|
|
|
return;
|
2022-11-16 20:19:52 +01:00
|
|
|
}
|
|
|
|
|
|
2023-09-22 16:23:44 +02:00
|
|
|
const referencedSeries = referencedSeriesSequence[0] || referencedSeriesSequence;
|
2022-11-16 20:19:52 +01:00
|
|
|
|
2023-09-01 22:19:39 +02:00
|
|
|
displaySet.referencedImages = instance.ReferencedSeriesSequence.ReferencedInstanceSequence;
|
2022-11-16 20:19:52 +01:00
|
|
|
displaySet.referencedSeriesInstanceUID = referencedSeries.SeriesInstanceUID;
|
2024-11-06 13:15:27 +01:00
|
|
|
const { displaySetService } = servicesManager.services;
|
2025-11-21 19:07:26 +01:00
|
|
|
const referencedDisplaySets = displaySetService.getDisplaySetsForReferences(
|
|
|
|
|
instance.ReferencedSeriesSequence
|
2024-11-06 13:15:27 +01:00
|
|
|
);
|
2022-11-16 20:19:52 +01:00
|
|
|
|
2025-11-21 19:07:26 +01:00
|
|
|
if (referencedDisplaySets?.length > 1) {
|
|
|
|
|
console.warn(
|
|
|
|
|
'Segmentation does not currently handle references to multiple series, defaulting to first series'
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-06 13:15:27 +01:00
|
|
|
const referencedDisplaySet = referencedDisplaySets[0];
|
|
|
|
|
|
|
|
|
|
if (!referencedDisplaySet) {
|
|
|
|
|
// subscribe to display sets added which means at some point it will be available
|
|
|
|
|
const { unsubscribe } = displaySetService.subscribe(
|
|
|
|
|
displaySetService.EVENTS.DISPLAY_SETS_ADDED,
|
|
|
|
|
({ displaySetsAdded }) => {
|
|
|
|
|
// here we can also do a little bit of search, since sometimes DICOM SEG
|
|
|
|
|
// does not contain the referenced display set uid , and we can just
|
|
|
|
|
// see which of the display sets added is more similar and assign it
|
|
|
|
|
// to the referencedDisplaySet
|
|
|
|
|
const addedDisplaySet = displaySetsAdded[0];
|
|
|
|
|
if (addedDisplaySet.SeriesInstanceUID === displaySet.referencedSeriesInstanceUID) {
|
|
|
|
|
displaySet.referencedDisplaySetInstanceUID = addedDisplaySet.displaySetInstanceUID;
|
2025-06-27 13:11:46 +02:00
|
|
|
displaySet.isReconstructable = addedDisplaySet.isReconstructable;
|
2026-04-06 18:03:28 +02:00
|
|
|
displaySet.FrameOfReferenceUID = addedDisplaySet.FrameOfReferenceUID;
|
2024-11-06 13:15:27 +01:00
|
|
|
unsubscribe();
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-16 20:19:52 +01:00
|
|
|
);
|
2024-11-06 13:15:27 +01:00
|
|
|
} else {
|
2023-09-01 22:19:39 +02:00
|
|
|
displaySet.referencedDisplaySetInstanceUID = referencedDisplaySet.displaySetInstanceUID;
|
2025-06-27 13:11:46 +02:00
|
|
|
displaySet.isReconstructable = referencedDisplaySet.isReconstructable;
|
2026-04-06 18:03:28 +02:00
|
|
|
displaySet.FrameOfReferenceUID = referencedDisplaySet.FrameOfReferenceUID;
|
2024-11-06 13:15:27 +01:00
|
|
|
}
|
2022-11-16 20:19:52 +01:00
|
|
|
|
|
|
|
|
displaySet.load = async ({ headers }) =>
|
|
|
|
|
await _load(displaySet, servicesManager, extensionManager, headers);
|
|
|
|
|
|
|
|
|
|
return [displaySet];
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-08 18:12:49 +02:00
|
|
|
function _load(
|
|
|
|
|
segDisplaySet,
|
|
|
|
|
servicesManager: AppTypes.ServicesManager,
|
|
|
|
|
extensionManager,
|
|
|
|
|
headers
|
|
|
|
|
) {
|
2022-11-16 20:19:52 +01:00
|
|
|
const { SOPInstanceUID } = segDisplaySet;
|
feat(RT): add dicom RT support via volume viewports (#3310)
* feat: initial RT support
* make the segmentation service work with representation data
* feat: make segmentation service work with representations
* fix rtss vis
* fix: rt hydration
* fix the rendering of rt names
* fix imports
* refactor: Modify status and click handling for hydration of RTStructures
Modify status and click handling for hydration of RTStructures by renaming `onPillClick` to `onStatusClick` in `OHIFCornerstoneRTViewport.tsx` and `_getStatusComponent.tsx` files. Also, update initial segmentation configurations in `PanelSegmentation.tsx` and simplify configuration changes and values for segmentation service in `SegmentationService.ts`. Finally, remove console debug in `CornerstoneViewportService.ts`.
* wip for highlighting contours
* refactor rt displayset code
* review code update
* update cornerstone dependencies
* refactor: Update license year, version number, and minor code cleanup
This commit updates the license year in several files, updates the version number in package.json, and contains minor code cleanup in two files.
* add bulkdataURI retrieve for RT
* fix package version
* apply review comments
* apply review comments
* apply review comments
* feat(panels): refactor and streamline segmentation configuration and inputs
Rewrote state hooks and streamlined the configuration input for `PanelSegmentation` to be more verbose and reusable. Included several new input types, including the `InputRange` component which now shows a fixed floating value based on the step provided. The `SegmentationConfig` component now works with dynamic values controlled by `initialConfig`. These changes should improve function usability and make the code more maintainable going forward.
* fix various bugs
* fix contour delete by upgrade cs3d version
* feat(viewport, inputNumber, segmentationConfig, orthanc): Implement minimum and maximum values for input number components, and useBulkDataURI for Orthanc configuration. Compare measurement view planes with absolute viewport view planes in Cornerstone viewport.
* update yarn lock
2023-04-26 18:21:08 +02:00
|
|
|
const { segmentationService } = servicesManager.services;
|
|
|
|
|
|
2022-11-16 20:19:52 +01:00
|
|
|
if (
|
|
|
|
|
(segDisplaySet.loading || segDisplaySet.isLoaded) &&
|
feat(RT): add dicom RT support via volume viewports (#3310)
* feat: initial RT support
* make the segmentation service work with representation data
* feat: make segmentation service work with representations
* fix rtss vis
* fix: rt hydration
* fix the rendering of rt names
* fix imports
* refactor: Modify status and click handling for hydration of RTStructures
Modify status and click handling for hydration of RTStructures by renaming `onPillClick` to `onStatusClick` in `OHIFCornerstoneRTViewport.tsx` and `_getStatusComponent.tsx` files. Also, update initial segmentation configurations in `PanelSegmentation.tsx` and simplify configuration changes and values for segmentation service in `SegmentationService.ts`. Finally, remove console debug in `CornerstoneViewportService.ts`.
* wip for highlighting contours
* refactor rt displayset code
* review code update
* update cornerstone dependencies
* refactor: Update license year, version number, and minor code cleanup
This commit updates the license year in several files, updates the version number in package.json, and contains minor code cleanup in two files.
* add bulkdataURI retrieve for RT
* fix package version
* apply review comments
* apply review comments
* apply review comments
* feat(panels): refactor and streamline segmentation configuration and inputs
Rewrote state hooks and streamlined the configuration input for `PanelSegmentation` to be more verbose and reusable. Included several new input types, including the `InputRange` component which now shows a fixed floating value based on the step provided. The `SegmentationConfig` component now works with dynamic values controlled by `initialConfig`. These changes should improve function usability and make the code more maintainable going forward.
* fix various bugs
* fix contour delete by upgrade cs3d version
* feat(viewport, inputNumber, segmentationConfig, orthanc): Implement minimum and maximum values for input number components, and useBulkDataURI for Orthanc configuration. Compare measurement view planes with absolute viewport view planes in Cornerstone viewport.
* update yarn lock
2023-04-26 18:21:08 +02:00
|
|
|
loadPromises[SOPInstanceUID] &&
|
2024-11-06 13:15:27 +01:00
|
|
|
_segmentationExists(segDisplaySet)
|
2022-11-16 20:19:52 +01:00
|
|
|
) {
|
|
|
|
|
return loadPromises[SOPInstanceUID];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
segDisplaySet.loading = true;
|
|
|
|
|
|
|
|
|
|
// We don't want to fire multiple loads, so we'll wait for the first to finish
|
|
|
|
|
// and also return the same promise to any other callers.
|
|
|
|
|
loadPromises[SOPInstanceUID] = new Promise(async (resolve, reject) => {
|
2023-09-01 22:19:39 +02:00
|
|
|
if (!segDisplaySet.segments || Object.keys(segDisplaySet.segments).length === 0) {
|
2024-10-30 00:14:34 +01:00
|
|
|
try {
|
|
|
|
|
await _loadSegments({
|
|
|
|
|
extensionManager,
|
|
|
|
|
servicesManager,
|
|
|
|
|
segDisplaySet,
|
|
|
|
|
headers,
|
|
|
|
|
});
|
|
|
|
|
} catch (e) {
|
|
|
|
|
segDisplaySet.loading = false;
|
|
|
|
|
return reject(e);
|
|
|
|
|
}
|
2022-11-16 20:19:52 +01:00
|
|
|
}
|
|
|
|
|
|
feat(RT): add dicom RT support via volume viewports (#3310)
* feat: initial RT support
* make the segmentation service work with representation data
* feat: make segmentation service work with representations
* fix rtss vis
* fix: rt hydration
* fix the rendering of rt names
* fix imports
* refactor: Modify status and click handling for hydration of RTStructures
Modify status and click handling for hydration of RTStructures by renaming `onPillClick` to `onStatusClick` in `OHIFCornerstoneRTViewport.tsx` and `_getStatusComponent.tsx` files. Also, update initial segmentation configurations in `PanelSegmentation.tsx` and simplify configuration changes and values for segmentation service in `SegmentationService.ts`. Finally, remove console debug in `CornerstoneViewportService.ts`.
* wip for highlighting contours
* refactor rt displayset code
* review code update
* update cornerstone dependencies
* refactor: Update license year, version number, and minor code cleanup
This commit updates the license year in several files, updates the version number in package.json, and contains minor code cleanup in two files.
* add bulkdataURI retrieve for RT
* fix package version
* apply review comments
* apply review comments
* apply review comments
* feat(panels): refactor and streamline segmentation configuration and inputs
Rewrote state hooks and streamlined the configuration input for `PanelSegmentation` to be more verbose and reusable. Included several new input types, including the `InputRange` component which now shows a fixed floating value based on the step provided. The `SegmentationConfig` component now works with dynamic values controlled by `initialConfig`. These changes should improve function usability and make the code more maintainable going forward.
* fix various bugs
* fix contour delete by upgrade cs3d version
* feat(viewport, inputNumber, segmentationConfig, orthanc): Implement minimum and maximum values for input number components, and useBulkDataURI for Orthanc configuration. Compare measurement view planes with absolute viewport view planes in Cornerstone viewport.
* update yarn lock
2023-04-26 18:21:08 +02:00
|
|
|
segmentationService
|
2024-11-06 13:15:27 +01:00
|
|
|
.createSegmentationForSEGDisplaySet(segDisplaySet)
|
2022-11-16 20:19:52 +01:00
|
|
|
.then(() => {
|
|
|
|
|
segDisplaySet.loading = false;
|
|
|
|
|
resolve();
|
|
|
|
|
})
|
|
|
|
|
.catch(error => {
|
|
|
|
|
segDisplaySet.loading = false;
|
|
|
|
|
reject(error);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
// Expose the in-flight load promise so observers (e.g. the viewport service
|
|
|
|
|
// waiting to attach the representation) can react to a load failure without
|
|
|
|
|
// re-invoking load().
|
|
|
|
|
segDisplaySet.loadingPromise = loadPromises[SOPInstanceUID];
|
|
|
|
|
|
2022-11-16 20:19:52 +01:00
|
|
|
return loadPromises[SOPInstanceUID];
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-08 18:12:49 +02:00
|
|
|
async function _loadSegments({
|
|
|
|
|
extensionManager,
|
|
|
|
|
servicesManager,
|
|
|
|
|
segDisplaySet,
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
}: withAppTypes<{ segDisplaySet: AppTypes.DisplaySet }>) {
|
|
|
|
|
const { segmentationService, uiNotificationService, customizationService } =
|
|
|
|
|
servicesManager.services;
|
|
|
|
|
const instance = segDisplaySet.instance as Record<string, unknown>;
|
|
|
|
|
const dataSource = _getSegDataSource(extensionManager, instance);
|
|
|
|
|
const segImageIdStr = _getSegImageIdFromInstance(instance, dataSource);
|
|
|
|
|
|
|
|
|
|
if (!segImageIdStr) {
|
|
|
|
|
throw new Error(
|
|
|
|
|
'Could not get imageId for SEG instance (no local wadouri url and getImageIdsForInstance returned nothing).'
|
|
|
|
|
);
|
|
|
|
|
}
|
2022-11-16 20:19:52 +01:00
|
|
|
|
2024-11-06 13:15:27 +01:00
|
|
|
const referencedDisplaySet = servicesManager.services.displaySetService.getDisplaySetByUID(
|
|
|
|
|
segDisplaySet.referencedDisplaySetInstanceUID
|
|
|
|
|
);
|
2022-11-16 20:19:52 +01:00
|
|
|
|
2024-11-06 13:15:27 +01:00
|
|
|
if (!referencedDisplaySet) {
|
|
|
|
|
throw new Error('referencedDisplaySet is missing for SEG');
|
2022-11-16 20:19:52 +01:00
|
|
|
}
|
|
|
|
|
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
// Prefer cached stack imageIds (multiframe SEG fix #4890), then data source expansion.
|
2025-03-27 20:52:22 +01:00
|
|
|
let { imageIds } = referencedDisplaySet;
|
|
|
|
|
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
if (!imageIds?.length) {
|
|
|
|
|
imageIds = dataSource.getImageIdsForDisplaySet?.(referencedDisplaySet);
|
2025-03-27 20:52:22 +01:00
|
|
|
}
|
2022-11-16 20:19:52 +01:00
|
|
|
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
if (!imageIds?.length) {
|
|
|
|
|
imageIds = (referencedDisplaySet as { images?: { imageId: string }[] }).images?.map(
|
|
|
|
|
(img: { imageId: string }) => img.imageId
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!imageIds?.length) {
|
|
|
|
|
throw new Error('referencedDisplaySet has no imageIds');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(segDisplaySet as AppTypes.DisplaySet & { referencedImageIds?: string[] }).referencedImageIds =
|
|
|
|
|
imageIds;
|
|
|
|
|
|
|
|
|
|
if (!referencedDisplaySet.imageIds?.length) {
|
|
|
|
|
referencedDisplaySet.imageIds = imageIds;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const frameImageIds = _resolveFrameImageIds(
|
|
|
|
|
segImageIdStr,
|
|
|
|
|
segDisplaySet.instance as Record<string, unknown>,
|
|
|
|
|
dataSource
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const segImageIdForMetadata = isLocalSchemeImageId(segImageIdStr)
|
|
|
|
|
? stripFrameFromImageId(segImageIdStr)
|
|
|
|
|
: segImageIdStr;
|
|
|
|
|
|
|
|
|
|
_logSegImageIds({
|
|
|
|
|
segDisplaySet,
|
|
|
|
|
segImageIdStr: segImageIdForMetadata,
|
|
|
|
|
frameImageIds,
|
|
|
|
|
referencedImageIds: imageIds,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
_ensureSegInstanceMetadataAvailable(segImageIdForMetadata, instance);
|
|
|
|
|
frameImageIds.forEach(id => _ensureSegInstanceMetadataAvailable(id, instance));
|
|
|
|
|
|
2023-08-08 20:39:31 +02:00
|
|
|
const tolerance = 0.001;
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
const onProgress = evt => {
|
2023-08-08 20:39:31 +02:00
|
|
|
const { percentComplete } = evt.detail;
|
2023-09-01 22:19:39 +02:00
|
|
|
segmentationService._broadcastEvent(segmentationService.EVENTS.SEGMENT_LOADING_COMPLETE, {
|
|
|
|
|
percentComplete,
|
|
|
|
|
});
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
};
|
|
|
|
|
eventTarget.addEventListener(Enums.Events.SEGMENTATION_LOAD_PROGRESS, onProgress);
|
|
|
|
|
|
|
|
|
|
// Fetch the whole SEG instance as a single Part 10 object and register its
|
|
|
|
|
// per-frame compressed pixels into the Cornerstone3D frame registry, so the
|
|
|
|
|
// per-frame loads below are served locally instead of one network request
|
|
|
|
|
// per frame: SEG frames are so small and numerous that one bulk fetch beats
|
|
|
|
|
// hundreds of tiny requests. Enabled by default; per-frame loading is the
|
|
|
|
|
// exception (loadMultiframeAsPart10: false in the data source config, or the
|
|
|
|
|
// cornerstone.segmentation.loadMultiframeAsPart10 customization). The
|
|
|
|
|
// prefetch is awaited until it completes OR fails — deliberately no timeout:
|
|
|
|
|
// a failed/unsupported instance fetch resolves quickly and falls back to
|
|
|
|
|
// per-frame, while a slow large fetch is still the fastest way to all frames.
|
|
|
|
|
const loadMultiframeAsPart10 =
|
|
|
|
|
(dataSource?.getConfig?.()?.loadMultiframeAsPart10 as boolean | undefined) ??
|
|
|
|
|
(customizationService?.getCustomization?.(
|
|
|
|
|
'cornerstone.segmentation.loadMultiframeAsPart10'
|
|
|
|
|
) as boolean | undefined) ??
|
|
|
|
|
true;
|
|
|
|
|
|
|
|
|
|
let prefetch;
|
|
|
|
|
if (loadMultiframeAsPart10) {
|
|
|
|
|
prefetch = dataSource.retrieve?.prefetchInstanceFrames?.({
|
|
|
|
|
instance,
|
|
|
|
|
imageId: segImageIdForMetadata,
|
|
|
|
|
});
|
2022-11-16 20:19:52 +01:00
|
|
|
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
if (prefetch?.done) {
|
|
|
|
|
await prefetch.done;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let results;
|
|
|
|
|
try {
|
|
|
|
|
results = await adaptersSEG.Cornerstone3D.Segmentation.createFromDicomSegImageId(
|
|
|
|
|
imageIds,
|
|
|
|
|
segImageIdForMetadata,
|
|
|
|
|
{
|
|
|
|
|
metadataProvider: metaData,
|
|
|
|
|
tolerance,
|
|
|
|
|
parserType: getSegmentationParserType(
|
|
|
|
|
segDisplaySet.SOPClassUID,
|
|
|
|
|
customizationService
|
|
|
|
|
),
|
|
|
|
|
frameImageIds,
|
|
|
|
|
concurrency: SEG_FRAME_DECODE_CONCURRENCY,
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
} finally {
|
|
|
|
|
eventTarget.removeEventListener(Enums.Events.SEGMENTATION_LOAD_PROGRESS, onProgress);
|
|
|
|
|
prefetch?.cancel?.();
|
|
|
|
|
}
|
2022-11-16 20:19:52 +01:00
|
|
|
|
2023-12-13 21:03:09 +01:00
|
|
|
let usedRecommendedDisplayCIELabValue = true;
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
const resultsTyped = results as {
|
|
|
|
|
segMetadata: { data: { rgba?: number[]; RecommendedDisplayCIELabValue?: number[] }[] };
|
|
|
|
|
};
|
|
|
|
|
resultsTyped.segMetadata.data.forEach((data, i) => {
|
2023-08-08 20:39:31 +02:00
|
|
|
if (i > 0) {
|
2023-12-13 21:03:09 +01:00
|
|
|
data.rgba = data.RecommendedDisplayCIELabValue;
|
|
|
|
|
|
|
|
|
|
if (data.rgba) {
|
|
|
|
|
data.rgba = dicomlabToRGB(data.rgba);
|
|
|
|
|
} else {
|
|
|
|
|
usedRecommendedDisplayCIELabValue = false;
|
|
|
|
|
data.rgba = CONSTANTS.COLOR_LUT[i % CONSTANTS.COLOR_LUT.length];
|
|
|
|
|
}
|
2023-08-08 20:39:31 +02:00
|
|
|
}
|
2022-11-16 20:19:52 +01:00
|
|
|
});
|
|
|
|
|
|
2023-12-13 21:03:09 +01:00
|
|
|
if (!usedRecommendedDisplayCIELabValue) {
|
|
|
|
|
// Display a notification about the non-utilization of RecommendedDisplayCIELabValue
|
|
|
|
|
uiNotificationService.show({
|
|
|
|
|
title: 'DICOM SEG import',
|
|
|
|
|
message:
|
|
|
|
|
'RecommendedDisplayCIELabValue not found for one or more segments. The default color was used instead.',
|
|
|
|
|
type: 'warning',
|
|
|
|
|
duration: 5000,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-08-08 20:39:31 +02:00
|
|
|
Object.assign(segDisplaySet, results);
|
feat: Add support for labelmap seg images in any supported tsuid (also for compressed bitmap) (#5806)
* feat: Update to use pnpm (#6031) [simulated squash-merge]
* feat: load DICOM SEG images via imageLoader
* feat: load DICOM SEG images via imageLoader
* PR review fixes
* Test fragment of compressed multiframes
* fix: Removed dependencies incorrectly
* Update frame as a targetted change to avoid stripping remaining params
* lock
* Update test to agree with the missing representation branch
* test(contour): contour color change coverage (#6042)
* test(contour): contour interactions delete segment (#6069)
---------
Co-authored-by: Bill Wallace <wayfarer3130@gmail.com>
* chore(version): Update package versions to 3.13.0-beta.98 [skip ci]
* feat(testing): OHIF Test Agent Skills (#5993)
* chore(version): Update package versions to 3.13.0-beta.99 [skip ci]
* test(contour): Add the ContourSegmentToggleLock.spec.ts test file to test contour locking (#6072)
* chore(version): Update package versions to 3.13.0-beta.100 [skip ci]
* chore(testing): Flock lock for playwright tests; Pin node version for OHIF; add more workers (#6099)
* update Cypress apt deps for Ubuntu Noble (drop libgconf-2-4, libasound2→libasound2t64)
* chore(version): Update package versions to 3.13.0-beta.101 [skip ci]
* Debug fixes
* perf(seg): pass explicit frame decode concurrency (16) to SEG loader
Pass an explicit concurrency value (SEG_FRAME_DECODE_CONCURRENCY = 16) into
createFromDicomSegImageId rather than relying on the adapter default, so the
SEG frame fetch/decode parallelism is set at the call site and is ready to
become configurable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs(behaviours): add behaviours section + multiframe Part 10 prefetch proposal
Start a "Behaviours" docs section for documenting how the system and UI behave
end-to-end (observed behaviours, design proposals, and failure modes), with an
index README and a Docusaurus category.
First entry is the proposal for loading a multiframe SEG as a single Part 10
instance: prefetch the whole instance (gated by loadMultiframeAsPart10RaceTimeMs),
parse it with dcmjs (handling multipart/related vs raw DICOM), and register the
per-frame compressed pixels into the Cornerstone3D core image cache (the single
uniform frame registry) so the per-frame load path is served locally while the
standard decode path is unchanged. Best-effort: falls back to per-frame fetches
on any failure.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Pre-cache the image data using a full part10 file for performance
* Add customizations to specify type of segmentation save
* Add clearcache of the cacheData
* Bump @cornerstonejs/* pins 5.1.3 -> 5.4.10 to match libs/@cornerstonejs base
libs/@cornerstonejs (fix/use-imageLoader-for-seg) is based on the released
cs3d 5.4.10 (merge-base with origin/main is the 5.4.10 version bump), so pin
OHIF to that release. The local branch changes still reach the app via the
cs3d:link symlinks; these pins keep the lockfile/npm fallback aligned.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix seg OOM
* fix: file meta garbage element, bogus NumberOfFrames, unguarded source-map-loader
- dicomWriter: drop the naturalized meta.TransferSyntaxUID assignment that
dcmjs wrote as a garbage (0000,0000) element into every saved file's meta
group (download / clipboard / local wadouri blob / local store); keep the
hex 00020010 assignment, which is required for string-form _meta fallbacks.
- registerNaturalizedDatasetForLocalWadouri: keep the computed frame count
local so single-frame IODs (SR, RTSTRUCT) no longer gain a bogus
NumberOfFrames element in their serialized form.
- rsbuild.config: resolve source-map-loader opportunistically (it is not a
project dependency; the rule only serves the gitignored cs3d-link
workflow) so fresh clones no longer crash at config load.
- Regression tests for both writer fixes (mutation-checked).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* PR review comment fixes
* Update versions
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: diattamo <mmddiatta@gmail.com>
Co-authored-by: ohif-bot <danny.ri.brown+ohif-bot@gmail.com>
Co-authored-by: Joe Boccanfuso <109477394+jbocce@users.noreply.github.com>
2026-07-10 02:54:23 +02:00
|
|
|
|
|
|
|
|
const labelMapImageIds = (results as { labelMapImages?: { imageId: string }[][] })
|
|
|
|
|
.labelMapImages?.flat()
|
|
|
|
|
.map(image => image.imageId);
|
|
|
|
|
|
|
|
|
|
log.debug(SEG_LOAD_LOG_PREFIX, 'SEG parse complete', {
|
|
|
|
|
SOPInstanceUID: segDisplaySet.SOPInstanceUID,
|
|
|
|
|
labelMapImageCount: labelMapImageIds?.length ?? 0,
|
|
|
|
|
labelMapImageIds,
|
|
|
|
|
segmentIndices: Object.keys(segDisplaySet.segments || {}),
|
|
|
|
|
});
|
2023-08-08 20:39:31 +02:00
|
|
|
}
|
2022-11-16 20:19:52 +01:00
|
|
|
|
2024-11-06 13:15:27 +01:00
|
|
|
function _segmentationExists(segDisplaySet) {
|
|
|
|
|
return cstSegmentation.state.getSegmentation(segDisplaySet.displaySetInstanceUID);
|
2022-11-16 20:19:52 +01:00
|
|
|
}
|
|
|
|
|
|
2025-05-05 22:35:05 +02:00
|
|
|
function getSopClassHandlerModule(params: OhifTypes.Extensions.ExtensionParams) {
|
|
|
|
|
const { servicesManager, extensionManager } = params;
|
2022-11-16 20:19:52 +01:00
|
|
|
const getDisplaySetsFromSeries = instances => {
|
2023-09-01 22:19:39 +02:00
|
|
|
return _getDisplaySetsFromSeries(instances, servicesManager, extensionManager);
|
2022-11-16 20:19:52 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
{
|
|
|
|
|
name: 'dicom-seg',
|
|
|
|
|
sopClassUids,
|
|
|
|
|
getDisplaySetsFromSeries,
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default getSopClassHandlerModule;
|