fix(multiframe): metadata handling of NM studies and loading order (#4554)

This commit is contained in:
Alireza authored and GitHub committed 2024-11-28 13:22:40 -05:00
1 parent 6729534a1a
commit 7624ccb5e4
57 files changed
+482 -662

No files matched your search

+4 -4
View File
@@ -38,7 +38,7 @@
"@cornerstonejs/codec-libjpeg-turbo-8bit": "^1.2.2",
"@cornerstonejs/codec-openjpeg": "^1.2.4",
"@cornerstonejs/codec-openjph": "^2.4.5",
"@cornerstonejs/dicom-image-loader": "^2.2.13",
"@cornerstonejs/dicom-image-loader": "^2.2.20",
"@icr/polyseg-wasm": "^0.4.0",
"@ohif/core": "3.10.0-beta.10",
"@ohif/ui": "3.10.0-beta.10",
@@ -55,9 +55,9 @@
},
"dependencies": {
"@babel/runtime": "^7.20.13",
"@cornerstonejs/adapters": "^2.2.13",
"@cornerstonejs/core": "^2.2.13",
"@cornerstonejs/tools": "^2.2.13",
"@cornerstonejs/adapters": "^2.2.20",
"@cornerstonejs/core": "^2.2.20",
"@cornerstonejs/tools": "^2.2.20",
"@icr/polyseg-wasm": "^0.4.0",
"@kitware/vtk.js": "32.1.1",
"html2canvas": "^1.4.1",
+1 -1
View File
@@ -45,7 +45,7 @@ import {
useSegmentationPresentationStore,
useSynchronizersStore,
} from './stores';
import { useToggleOneUpViewportGridStore } from '../../default/src/stores/useToggleOneUpViewportGridStore';
import { useToggleOneUpViewportGridStore } from '@ohif/extension-default';
import { useActiveViewportSegmentationRepresentations } from './hooks/useActiveViewportSegmentationRepresentations';
import { useMeasurements } from './hooks/useMeasurements';
import getPanelModule from './getPanelModule';
+38 -3
View File
@@ -38,6 +38,7 @@ import { SegmentationRepresentations } from '@cornerstonejs/tools/enums';
import { useLutPresentationStore } from './stores/useLutPresentationStore';
import { usePositionPresentationStore } from './stores/usePositionPresentationStore';
import { useSegmentationPresentationStore } from './stores/useSegmentationPresentationStore';
import { imageRetrieveMetadataProvider } from '@cornerstonejs/core/utilities';
const { registerColormap } = csUtilities.colormap;
@@ -135,9 +136,21 @@ export default async function init({
cornerstoneStreamingDynamicImageVolumeLoader
);
hangingProtocolService.registerImageLoadStrategy('interleaveCenter', interleaveCenterLoader);
hangingProtocolService.registerImageLoadStrategy('interleaveTopToBottom', interleaveTopToBottom);
hangingProtocolService.registerImageLoadStrategy('nth', nthLoader);
// Register strategies using the wrapper
const imageLoadStrategies = {
interleaveCenter: interleaveCenterLoader,
interleaveTopToBottom: interleaveTopToBottom,
nth: nthLoader,
};
Object.entries(imageLoadStrategies).forEach(([name, strategyFn]) => {
hangingProtocolService.registerImageLoadStrategy(
name,
createMetadataWrappedStrategy(strategyFn)
);
});
// ... existing code ...
// add metadata providers
metaData.addProvider(
@@ -296,6 +309,28 @@ function initializeWebWorkerProgressHandler(uiNotificationService) {
});
}
/**
* Creates a wrapped image load strategy with metadata handling
* @param strategyFn - The image loading strategy function to wrap
* @returns A wrapped strategy function that handles metadata configuration
*/
const createMetadataWrappedStrategy = (strategyFn: (args: any) => any) => {
return (args: any) => {
const clonedConfig = imageRetrieveMetadataProvider.clone();
imageRetrieveMetadataProvider.clear();
try {
const result = strategyFn(args);
return result;
} finally {
// Ensure metadata is always restored, even if there's an error
setTimeout(() => {
imageRetrieveMetadataProvider.restore(clonedConfig);
}, 10);
}
};
};
function CPUModal() {
return (
<div>
@@ -59,10 +59,10 @@ const initMeasurementService = (
'Crosshairs',
Length.matchingCriteria,
() => {
console.warn('Crosshairs mapping not implemented.');
return null;
},
() => {
console.warn('Crosshairs mapping not implemented.');
return null;
}
);
@@ -1058,6 +1058,11 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
// Store the current position presentations for each viewport.
viewports.forEach(({ id: viewportId }) => {
const presentation = this._getPositionPresentation(viewportId);
// During a resize, the slice index should remain unchanged. This is a temporary fix for
// a larger issue regarding the definition of slice index with slab thickness.
// We need to revisit this to make it more robust and understandable.
delete presentation.viewReference.sliceIndex;
this.beforeResizePositionPresentations.set(viewportId, presentation);
});
@@ -1066,10 +1071,12 @@ class CornerstoneViewportService extends PubSubService implements IViewportServi
renderingEngine.resize(isImmediate);
renderingEngine.render();
// Reset the camera for viewports that should reset their camera on resize,
// Reset the camera for all viewports using position presentation to maintain relative size/position
// which means only those viewports that have a zoom level of 1.
this.beforeResizePositionPresentations.forEach((positionPresentation, viewportId) => {
this.setPresentations(viewportId, { positionPresentation });
this.setPresentations(viewportId, {
positionPresentation,
});
});
// Resize and render the rendering engine again.
@@ -108,7 +108,7 @@ export default function interleaveTopToBottom({
volumes.forEach(volume => {
const requests = volume.getImageLoadRequests();
if (!requests.length || !requests[0] || !requests[0].imageId) {
if (!requests?.[0]?.imageId) {
return;
}