From 430330f7e384d503cb6fc695a7a9642ddfaac313 Mon Sep 17 00:00:00 2001 From: Ibrahim <93064150+IbrahimCSAE@users.noreply.github.com> Date: Wed, 5 Jun 2024 10:07:53 -0400 Subject: [PATCH] fix(hydration): Maintain the same slice that the user was on pre hydration in post hydration for SR and SEG. (#4200) --- .../src/commandsModule.ts | 4 +++ .../src/utils/hydrationUtils.ts | 11 +++++++ .../CornerstoneViewportService.ts | 4 +-- .../src/services/ViewportService/Viewport.ts | 1 + .../default/src/getHangingProtocolModule.js | 8 ++--- .../TrackedMeasurementsContext.tsx | 30 ++++++++++++++++++- .../measurementTrackingMachine.js | 4 +-- .../contextProviders/ViewportGridProvider.tsx | 8 +++++ 8 files changed, 60 insertions(+), 10 deletions(-) diff --git a/extensions/cornerstone-dicom-seg/src/commandsModule.ts b/extensions/cornerstone-dicom-seg/src/commandsModule.ts index b5155826a..ff451a0a4 100644 --- a/extensions/cornerstone-dicom-seg/src/commandsModule.ts +++ b/extensions/cornerstone-dicom-seg/src/commandsModule.ts @@ -48,6 +48,7 @@ const commandsModule = ({ displaySetService, viewportGridService, toolGroupService, + cornerstoneViewportService, } = servicesManager.services; const actions = { @@ -210,6 +211,8 @@ const commandsModule = ({ const referencedDisplaySet = displaySetService.getDisplaySetByUID( displaySet.referencedDisplaySetInstanceUID ); + const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId); + const initialSliceIndex = viewport.getSliceIndex(); updateViewportsForSegmentationRendering({ viewportId, @@ -229,6 +232,7 @@ const commandsModule = ({ segmentation.description = `S${referencedDisplaySet.SeriesNumber}: ${referencedDisplaySet.SeriesDescription}`; return segmentationId; }, + initialSliceIndex, }); }, /** diff --git a/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts b/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts index d87c6e109..6dd33c1b3 100644 --- a/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts +++ b/extensions/cornerstone-dicom-seg/src/utils/hydrationUtils.ts @@ -11,6 +11,7 @@ import { Enums, cache } from '@cornerstonejs/core'; * @param params.loadFn - Function to load the segmentation data. * @param params.servicesManager - The services manager. * @param params.displaySet - the display set. + * @param params.initialSliceIndex - The initial slice index. * * @returns Returns true upon successful update of viewports for segmentation rendering. */ @@ -19,11 +20,13 @@ async function updateViewportsForSegmentationRendering({ loadFn, servicesManager, displaySet, + initialSliceIndex = null, }: { viewportId: string; loadFn: () => Promise; servicesManager: AppTypes.ServicesManager; displaySet?: any; + initialSliceIndex?: number; }) { const { cornerstoneViewportService, segmentationService, viewportGridService } = servicesManager.services; @@ -61,6 +64,14 @@ async function updateViewportsForSegmentationRendering({ }; const viewportId = viewport.viewportId; + // maintain the prehydration slice on the target viewport only + if (viewportId === targetViewportId) { + viewport.viewportOptions.initialImageOptions = { + index: initialSliceIndex, + useOnce: true, + }; + } + const csViewport = cornerstoneViewportService.getCornerstoneViewport(viewportId); const prevCamera = csViewport.getCamera(); diff --git a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts index c5ae70cc2..8ad62cb2f 100644 --- a/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts +++ b/extensions/cornerstone/src/services/ViewportService/CornerstoneViewportService.ts @@ -1,5 +1,5 @@ import { PubSubService } from '@ohif/core'; -import * as OhifTypes from '@ohif/core/types'; +import { Types as OhifTypes } from '@ohif/core'; import { RenderingEngine, StackViewport, @@ -617,11 +617,9 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi imageIds?: string[] ): number { const initialImageOptions = viewportInfo.getInitialImageOptions(); - if (!initialImageOptions) { return; } - const { index, preset } = initialImageOptions; const viewportType = viewportInfo.getViewportType(); diff --git a/extensions/cornerstone/src/services/ViewportService/Viewport.ts b/extensions/cornerstone/src/services/ViewportService/Viewport.ts index 247b4d3bd..6245c69ff 100644 --- a/extensions/cornerstone/src/services/ViewportService/Viewport.ts +++ b/extensions/cornerstone/src/services/ViewportService/Viewport.ts @@ -16,6 +16,7 @@ import { SyncGroup } from '../SyncGroupService/SyncGroupService'; export type InitialImageOptions = { index?: number; preset?: JumpPresets; + useOnce?: boolean; }; export type ViewportOptions = { diff --git a/extensions/default/src/getHangingProtocolModule.js b/extensions/default/src/getHangingProtocolModule.js index 9c2af010b..f7fde44eb 100644 --- a/extensions/default/src/getHangingProtocolModule.js +++ b/extensions/default/src/getHangingProtocolModule.js @@ -120,10 +120,10 @@ function getHangingProtocolModule() { name: hpMammography.id, protocol: hpMammography, }, - // { - // name: hpScale.id, - // protocol: hpScale, - // }, + { + name: hpScale.id, + protocol: hpScale, + }, ]; } diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx index ef74b98c0..7e89712ee 100644 --- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx +++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/TrackedMeasurementsContext.tsx @@ -31,7 +31,12 @@ function TrackedMeasurementsContextProvider( const [viewportGrid, viewportGridService] = useViewportGrid(); const { activeViewportId, viewports } = viewportGrid; - const { measurementService, displaySetService, customizationService } = servicesManager.services; + const { + measurementService, + displaySetService, + customizationService, + cornerstoneViewportService, + } = servicesManager.services; const machineOptions = Object.assign({}, defaultOptions); machineOptions.actions = Object.assign({}, machineOptions.actions, { @@ -81,6 +86,29 @@ function TrackedMeasurementsContextProvider( }, }); }, + + jumpToSameImageInActiveViewport: (ctx, evt) => { + const { trackedStudy, trackedSeries, activeViewportId } = ctx; + const measurements = measurementService.getMeasurements(); + const trackedMeasurements = measurements.filter( + m => trackedStudy === m.referenceStudyUID && trackedSeries.includes(m.referenceSeriesUID) + ); + + const trackedMeasurement = trackedMeasurements[0]; + const referencedDisplaySetUID = trackedMeasurement.displaySetInstanceUID; + const viewport = cornerstoneViewportService.getCornerstoneViewport(activeViewportId); + const imageIndex = viewport.getCurrentImageIdIndex(); + + viewportGridService.setDisplaySetsForViewport({ + viewportId: activeViewportId, + displaySetInstanceUIDs: [referencedDisplaySetUID], + viewportOptions: { + initialImageOptions: { + index: imageIndex, + }, + }, + }); + }, showStructuredReportDisplaySetInActiveViewport: (ctx, evt) => { if (evt.data.createdDisplaySetInstanceUIDs.length > 0) { const StructuredReportDisplaySetInstanceUID = evt.data.createdDisplaySetInstanceUIDs[0]; diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js index fce9930d3..d53408e3c 100644 --- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js +++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js @@ -250,7 +250,7 @@ const machineConfiguration = { target: 'tracking', actions: [ 'setTrackedStudyAndMultipleSeries', - 'jumpToFirstMeasurementInActiveViewport', + 'jumpToSameImageInActiveViewport', 'setIsDirtyToClean', ], cond: 'shouldHydrateStructuredReport', @@ -274,7 +274,7 @@ const machineConfiguration = { target: 'tracking', actions: [ 'setTrackedStudyAndMultipleSeries', - 'jumpToFirstMeasurementInActiveViewport', + 'jumpToSameImageInActiveViewport', 'setIsDirtyToClean', ], }, diff --git a/platform/ui/src/contextProviders/ViewportGridProvider.tsx b/platform/ui/src/contextProviders/ViewportGridProvider.tsx index d82004c6d..9f1ae8155 100644 --- a/platform/ui/src/contextProviders/ViewportGridProvider.tsx +++ b/platform/ui/src/contextProviders/ViewportGridProvider.tsx @@ -160,6 +160,14 @@ export function ViewportGridProvider({ children, service }) { const previousViewport = viewports.get(viewportId); + // remove options that were meant for one time usage + if (previousViewport?.viewportOptions?.initialImageOptions) { + const { useOnce } = previousViewport.viewportOptions.initialImageOptions; + if (useOnce) { + previousViewport.viewportOptions.initialImageOptions = null; + } + } + // Use the newly provide viewportOptions and display set options // when provided, and otherwise fall back to the previous ones. // That allows for easy updates of just the display set.