diff --git a/extensions/dicom-sr/src/OHIFCornerstoneSRViewport.js b/extensions/dicom-sr/src/OHIFCornerstoneSRViewport.js index 45eb4bf10..a228ea220 100644 --- a/extensions/dicom-sr/src/OHIFCornerstoneSRViewport.js +++ b/extensions/dicom-sr/src/OHIFCornerstoneSRViewport.js @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useContext, useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import cornerstoneTools from 'cornerstone-tools'; import cornerstone from 'cornerstone-core'; @@ -16,12 +16,15 @@ const globalImageIdSpecificToolStateManager = const { StackManager, guid } = OHIF.utils; +const MEASUREMENT_TRACKING_EXTENSION_ID = 'org.ohif.measurement-tracking'; + function OHIFCornerstoneSRViewport({ children, dataSource, displaySet, viewportIndex, servicesManager, + extensionManager, }) { const { DisplaySetService, MeasurementService } = servicesManager.services; const [viewportGrid, viewportGridService] = useViewportGrid(); @@ -31,9 +34,29 @@ function OHIFCornerstoneSRViewport({ const [activeDisplaySetData, setActiveDisplaySetData] = useState({}); const [element, setElement] = useState(null); const [isHydrated, setIsHydrated] = useState(displaySet.isHydrated); - const { viewports, activeViewportIndex } = viewportGrid; + // Optional hook into tracking extension, if present. + let trackedMeasurements; + let sendTrackedMeasurementsEvent; + + if ( + extensionManager.registeredExtensionIds.includes( + MEASUREMENT_TRACKING_EXTENSION_ID + ) + ) { + const contextModule = extensionManager.getModuleEntry( + 'org.ohif.measurement-tracking.contextModule.TrackedMeasurementsContext' + ); + + const useTrackedMeasurements = () => useContext(contextModule.context); + + [ + trackedMeasurements, + sendTrackedMeasurementsEvent, + ] = useTrackedMeasurements(); + } + const onElementEnabled = evt => { const eventData = evt.detail; const targetElement = eventData.element; @@ -207,6 +230,7 @@ function OHIFCornerstoneSRViewport({ SeriesInstanceUID, PixelSpacing, SeriesNumber, + displaySetInstanceUID, } = activeDisplaySetData; const onMeasurementChange = direction => { @@ -274,6 +298,8 @@ function OHIFCornerstoneSRViewport({ } }); + const imageIds = []; + Object.keys(hydratableMeasurementsInSR).forEach(toolType => { const toolDataForToolType = hydratableMeasurementsInSR[toolType]; @@ -300,6 +326,10 @@ function OHIFCornerstoneSRViewport({ data, toMeasurementSchema ); + + if (!imageIds.includes(imageId)) { + imageIds.push(imageId); + } }); }); @@ -309,8 +339,53 @@ function OHIFCornerstoneSRViewport({ // TODO -> Switch to cornerstone viewport. // TODO -> Tell measurement service to track the series on which the measurements were added. - // TODO -> set displaySet as inactive. + + // Deal with optional extensions + + if ( + extensionManager.registeredExtensionIds.includes( + MEASUREMENT_TRACKING_EXTENSION_ID + ) + ) { + // Set the series touched as tracked. + + let targetStudyInstanceUID; + const SeriesInstanceUIDs = []; + + for (let i = 0; i < imageIds.length; i++) { + const imageId = imageIds[0]; + const { + SeriesInstanceUID, + StudyInstanceUID, + } = cornerstone.metaData.get('instance', imageId); + + if (!SeriesInstanceUIDs.includes(SeriesInstanceUID)) { + SeriesInstanceUIDs.push(SeriesInstanceUID); + } + + if (!targetStudyInstanceUID) { + targetStudyInstanceUID = StudyInstanceUID; + } else if (targetStudyInstanceUID !== StudyInstanceUID) { + console.warn( + 'NO SUPPORT FOR SRs THAT HAVE MEASUREMENTS FROM MULTIPLE STUDIES.' + ); + } + } + + debugger; + + sendTrackedMeasurementsEvent('SET_TRACKED_SERIES', { + StudyInstanceUID: targetStudyInstanceUID, + SeriesInstanceUID: SeriesInstanceUIDs[0], + }); + } + debugger; + + viewportGridService.setDisplaysetForViewport({ + viewportIndex: activeViewportIndex, + displaySetInstanceUID: activeDisplaySetData.displaySetInstanceUID, + }); } return ( @@ -460,6 +535,7 @@ async function _getViewportAndActiveDisplaySetData( SeriesDescription: image0.SeriesDescription, SeriesInstanceUID: image0.SeriesInstanceUID, SeriesNumber: image0.SeriesNumber, + displaySetInstanceUID, }; return { viewportData, activeDisplaySetData }; diff --git a/extensions/dicom-sr/src/index.js b/extensions/dicom-sr/src/index.js index 5bf7ea5f4..879478388 100644 --- a/extensions/dicom-sr/src/index.js +++ b/extensions/dicom-sr/src/index.js @@ -29,6 +29,10 @@ export default { id: 'org.ohif.cornerstone', version: '3.0.0', }, + { + id: 'org.ohif.measurement-tracking', + version: '^0.0.1', + }, ], preRegistration({ servicesManager, configuration = {} }) { @@ -41,11 +45,12 @@ export default { * @param {object} [configuration={}] * @param {object|array} [configuration.csToolsConfig] - Passed directly to `initCornerstoneTools` */ - getViewportModule({ servicesManager }) { + getViewportModule({ servicesManager, extensionManager }) { const ExtendedOHIFCornerstoneSRViewport = props => { return ( ); diff --git a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js index 680fabf49..5ff597b9a 100644 --- a/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js +++ b/extensions/measurement-tracking/src/contexts/TrackedMeasurementsContext/measurementTrackingMachine.js @@ -15,6 +15,18 @@ const machineConfiguration = { entry: 'clearContext', on: { TRACK_SERIES: 'promptBeginTracking', + SET_TRACKED_SERIES: [ + { + target: 'tracking', + actions: ['setTrackedStudyAndSeries'], + cond: 'isNewStudy', + }, + { + target: 'tracking', + actions: ['addTrackedSeries'], + cond: 'isNewSeries', + }, + ], }, }, promptBeginTracking: { @@ -51,6 +63,7 @@ const machineConfiguration = { cond: 'isNewSeries', }, ], + UNTRACK_SERIES: [ { target: 'tracking', diff --git a/platform/core/src/services/MeasurementService/MeasurementService.js b/platform/core/src/services/MeasurementService/MeasurementService.js index dbaabfc63..b97c09c55 100644 --- a/platform/core/src/services/MeasurementService/MeasurementService.js +++ b/platform/core/src/services/MeasurementService/MeasurementService.js @@ -297,8 +297,6 @@ class MeasurementService { return; } - debugger; - const sourceInfo = this._getSourceInfo(source); if (!definition) { diff --git a/platform/viewer/src/components/ViewportGrid.jsx b/platform/viewer/src/components/ViewportGrid.jsx index e6384b82e..950b04ee7 100644 --- a/platform/viewer/src/components/ViewportGrid.jsx +++ b/platform/viewer/src/components/ViewportGrid.jsx @@ -28,13 +28,13 @@ function ViewerViewportGrid(props) { displaySets => { displaySets.sort((a, b) => { const isImageSet = x => x instanceof ImageSet; - return (isImageSet(a) === isImageSet(b)) ? 0 : isImageSet(a) ? -1 : 1; + return isImageSet(a) === isImageSet(b) ? 0 : isImageSet(a) ? -1 : 1; }); viewportGridService.setDisplaysetForViewport({ viewportIndex: 0, displaySetInstanceUID: displaySets[0].displaySetInstanceUID, }); - }, + } ); return () => {