From f3cecf129b16f8d24d239aa44fdff7f46e6ba683 Mon Sep 17 00:00:00 2001 From: Igor Octaviano Date: Thu, 3 Dec 2020 13:36:02 -0300 Subject: [PATCH] feat: Update approach to better handle rtdose instead of disabling panel Co-authored-by: Davide Punzo --- .../src/components/RTPanel/RTPanel.js | 168 +++++++++--------- extensions/dicom-rt/src/loadRTStruct.js | 10 +- .../viewer/src/connectedComponents/Viewer.js | 20 ++- 3 files changed, 105 insertions(+), 93 deletions(-) diff --git a/extensions/dicom-rt/src/components/RTPanel/RTPanel.js b/extensions/dicom-rt/src/components/RTPanel/RTPanel.js index 856c60d56..504089a04 100644 --- a/extensions/dicom-rt/src/components/RTPanel/RTPanel.js +++ b/extensions/dicom-rt/src/components/RTPanel/RTPanel.js @@ -1,4 +1,4 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import PropTypes from 'prop-types'; import cornerstoneTools from 'cornerstone-tools'; import cornerstone from 'cornerstone-core'; @@ -31,19 +31,20 @@ const refreshViewport = () => { * * @param {Object} props * @param {Array} props.studies - * @param {Array} props.viewports - viewportSpecificData + * @param {Array} props.getActiveViewport - get active viewport data * @param {number} props.activeIndex - activeViewportIndex * @param {number} props.isOpen - isOpen * @returns component */ const RTPanel = ({ studies, - viewports, activeIndex, isOpen, onContourItemClick, activeContexts = [], contexts = {}, + activeViewport, + getActiveViewport }) => { const isVTK = () => activeContexts.includes(contexts.VTK); const isCornerstone = () => activeContexts.includes(contexts.CORNERSTONE); @@ -54,11 +55,11 @@ const RTPanel = ({ referencedDisplaysets: [], sets: [], selectedSet: null, + isLocked: false }; const [state, setState] = useState(DEFAULT_STATE); const [showSettings, setShowSettings] = useState(false); - const activeViewport = viewports[activeIndex]; /* * TODO: Improve the way we notify parts of the app that depends on rts to be loaded. @@ -81,27 +82,32 @@ const RTPanel = ({ document.addEventListener('extensiondicomrtrtloaded', updateStructureSets); return () => { - document.removeEventListener( - 'extensiondicomrtrtloaded', - updateStructureSets - ); + document.removeEventListener('extensiondicomrtrtloaded', updateStructureSets); }; }, []); + useEffect(() => { + const studyMetadata = studyMetadataManager.get(activeViewport.StudyInstanceUID); + const referencedDisplaysets = studyMetadata.getDerivedDatasets({ + referencedSeriesInstanceUID: activeViewport.SeriesInstanceUID, + Modality: 'RTSTRUCT', + }); + setState(state => ({ ...state, isLocked: !referencedDisplaysets.length })); + }, [activeViewport]); + const updateStructureSets = () => { + const viewport = getActiveViewport(); const module = cornerstoneTools.getModule('rtstruct'); const StructureSets = module.state.StructureSets; if (StructureSets && StructureSets.length) { const viewportSets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid( - activeViewport.SeriesInstanceUID + viewport.SeriesInstanceUID ); - const studyMetadata = studyMetadataManager.get( - activeViewport.StudyInstanceUID - ); + const studyMetadata = studyMetadataManager.get(viewport.StudyInstanceUID); const referencedDisplaysets = studyMetadata.getDerivedDatasets({ - referencedSeriesInstanceUID: activeViewport.SeriesInstanceUID, + referencedSeriesInstanceUID: viewport.SeriesInstanceUID, Modality: 'RTSTRUCT', }); @@ -118,10 +124,6 @@ const RTPanel = ({ } }; - useEffect(() => { - updateStructureSets(); - }, [studies, viewports, activeIndex]); - useEffect(() => { setShowSettings(showSettings && !isOpen); }, [isOpen]); @@ -232,78 +234,80 @@ const RTPanel = ({

RT Structure Sets

- setShowSettings(true)} - /> + {!state.isLocked && ( + setShowSettings(true)} + /> + )}
- {!state.referencedDisplaysets.length && ( - - )} - {state.sets && - state.referencedDisplaysets.map(displaySet => { - const { SeriesInstanceUID, metadata, isLoaded } = displaySet; + {!state.isLocked && !state.referencedDisplaysets.length && } + {state.sets && state.referencedDisplaysets.map(displaySet => { + const { SeriesInstanceUID, metadata, isLoaded } = displaySet; - const module = cornerstoneTools.getModule('rtstruct'); - const sets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid( - viewports[activeIndex].SeriesInstanceUID - ); + const module = cornerstoneTools.getModule('rtstruct'); + const sets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid( + activeViewport.SeriesInstanceUID + ); - const loadedSet = sets.find( - set => set.SeriesInstanceUID === SeriesInstanceUID - ); - return ( - set.SeriesInstanceUID === SeriesInstanceUID + ); + + if (!loadedSet) return null; + + return ( + { + const module = cornerstoneTools.getModule('rtstruct'); + + if (newVisibility) { + module.setters.showStructureSet(loadedSet.SeriesInstanceUID); + } else { + module.setters.hideStructureSet(loadedSet.SeriesInstanceUID); } - onVisibilityChange={newVisibility => { + const sets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid( + activeViewport.SeriesInstanceUID + ); + setState(state => ({ ...state, sets })); + refreshViewport(); + }} + onExpandChange={async () => { + if (!isLoaded) { + await displaySet.load(activeViewport, studies); const module = cornerstoneTools.getModule('rtstruct'); - - if (newVisibility) { - module.setters.showStructureSet(loadedSet.SeriesInstanceUID); - } else { - module.setters.hideStructureSet(loadedSet.SeriesInstanceUID); - } const sets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid( - viewports[activeIndex].SeriesInstanceUID + activeViewport.SeriesInstanceUID ); - setState(state => ({ ...state, sets })); - refreshViewport(); - }} - onExpandChange={async () => { - if (!isLoaded) { - await displaySet.load(viewports[activeIndex], studies); - const module = cornerstoneTools.getModule('rtstruct'); - const sets = module.getters.structuresSetsWhichReferenceSeriesInstanceUid( - viewports[activeIndex].SeriesInstanceUID - ); - const selectedSet = sets.find( - set => set.SeriesInstanceUID === SeriesInstanceUID - ); - setState(state => ({ ...state, selectedSet, sets })); - } - }} - > - - - {isLoaded && - loadedSet.ROIContours.map(c => toContourItem(c, loadedSet))} - - - - ); - })} + const selectedSet = sets.find( + set => set.SeriesInstanceUID === SeriesInstanceUID + ); + setState(state => ({ ...state, selectedSet, sets })); + } + }} + > + + + {isLoaded && + loadedSet.ROIContours.map(c => toContourItem(c, loadedSet))} + + + + ); + })}
); }; diff --git a/extensions/dicom-rt/src/loadRTStruct.js b/extensions/dicom-rt/src/loadRTStruct.js index 59da0b71b..42fd24d5c 100644 --- a/extensions/dicom-rt/src/loadRTStruct.js +++ b/extensions/dicom-rt/src/loadRTStruct.js @@ -90,11 +90,11 @@ export default async function loadRTStruct( const sopInstanceUID = ContourImageSequence ? ContourImageSequence.ReferencedSOPInstanceUID : _getClosestSOPInstanceUID( - ContourData, - ContourGeometricType, - NumberOfContourPoints, - imageIdSopInstanceUidPairs - ); + ContourData, + ContourGeometricType, + NumberOfContourPoints, + imageIdSopInstanceUidPairs + ); const imageId = _getImageId(imageIdSopInstanceUidPairs, sopInstanceUID); const imageIdSpecificToolData = _getOrCreateImageIdSpecificToolData( toolState, diff --git a/platform/viewer/src/connectedComponents/Viewer.js b/platform/viewer/src/connectedComponents/Viewer.js index 08d70d741..4cf756737 100644 --- a/platform/viewer/src/connectedComponents/Viewer.js +++ b/platform/viewer/src/connectedComponents/Viewer.js @@ -83,6 +83,8 @@ class Viewer extends Component { disassociate: this.disassociateStudy, }, }); + + this._getActiveViewport = this._getActiveViewport.bind(this); } state = { @@ -214,6 +216,10 @@ class Viewer extends Component { } } + _getActiveViewport() { + return this.props.viewports[this.props.activeViewportIndex]; + } + render() { let VisiblePanelLeft, VisiblePanelRight; const panelExtensions = extensionManager.modules[MODULE_TYPES.PANEL]; @@ -314,11 +320,11 @@ class Viewer extends Component { activeIndex={this.props.activeViewportIndex} /> ) : ( - - )} + + )} @@ -341,6 +347,8 @@ class Viewer extends Component { viewports={this.props.viewports} studies={this.props.studies} activeIndex={this.props.activeViewportIndex} + activeViewport={this.props.viewports[this.props.activeViewportIndex]} + getActiveViewport={this._getActiveViewport} /> )} @@ -363,7 +371,7 @@ export default withDialog(Viewer); * @param {Study[]} studies * @param {DisplaySet[]} studies[].displaySets */ -const _mapStudiesToThumbnails = function(studies) { +const _mapStudiesToThumbnails = function (studies) { return studies.map(study => { const { StudyInstanceUID } = study;