import { MODULE_TYPES, utils, DICOMWeb } from '@ohif/core'; import loadRTStruct from './loadRTStruct'; import id from './id'; // TODO: Should probably use dcmjs for this const SOP_CLASS_UIDS = { DICOM_RT_STRUCT: '1.2.840.10008.5.1.4.1.1.481.3', }; const sopClassUIDs = Object.values(SOP_CLASS_UIDS); const OHIFDicomRTStructSopClassHandler = { id: 'OHIFDicomRTStructSopClassHandler', type: MODULE_TYPES.SOP_CLASS_HANDLER, sopClassUIDs, getDisplaySetFromSeries: function( series, study, dicomWebClient, authorizationHeaders ) { const instance = series.getFirstInstance(); const metadata = instance.getData().metadata; const { SeriesDate, SeriesTime, SeriesDescription, FrameOfReferenceUID, SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID, } = metadata; // TODO -> GET REFERENCED FRAME OF REFERENCE SEQUENCE. const rtStructDisplaySet = { Modality: 'RTSTRUCT', displaySetInstanceUID: utils.guid(), wadoRoot: study.getData().wadoRoot, wadoUri: instance.getData().wadouri, SOPInstanceUID, SeriesInstanceUID, StudyInstanceUID, FrameOfReferenceUID, authorizationHeaders, metadata, isDerived: true, referencedDisplaySetUID: null, // Assigned when loaded. labelmapIndex: null, // Assigned when loaded. isLoaded: false, SeriesDate, SeriesTime, SeriesDescription, }; if (!metadata.ReferencedSeriesSequence) { const ReferencedFrameOfReferenceSequence = metadata.ReferencedFrameOfReferenceSequence; if (ReferencedFrameOfReferenceSequence) { // TODO -> @dannyrb Do we augment metadata or add a (potentially large? fallback list in filterDerivedDisplaySets ) metadata.ReferencedSeriesSequence = _deriveReferencedSeriesSequenceFromFrameOfReferenceSequence( ReferencedFrameOfReferenceSequence ); } } rtStructDisplaySet.load = function(referencedDisplaySet, studies) { return loadRTStruct( rtStructDisplaySet, referencedDisplaySet, studies ).catch(error => { rtStructDisplaySet.isLoaded = false; throw new Error(error); }); }; return rtStructDisplaySet; }, }; function _deriveReferencedSeriesSequenceFromFrameOfReferenceSequence( ReferencedFrameOfReferenceSequence ) { const ReferencedSeriesSequence = []; _getSequenceAsArray(ReferencedFrameOfReferenceSequence).forEach( referencedFrameOfReference => { const { RTReferencedStudySequence } = referencedFrameOfReference; _getSequenceAsArray(RTReferencedStudySequence).forEach( rtReferencedStudy => { const { RTReferencedSeriesSequence } = rtReferencedStudy; _getSequenceAsArray(RTReferencedSeriesSequence).forEach( rtReferencedSeries => { const ReferencedInstanceSequence = []; const { ContourImageSequence, SeriesInstanceUID, } = rtReferencedSeries; _getSequenceAsArray(ContourImageSequence).forEach( contourImage => { ReferencedInstanceSequence.push({ ReferencedSOPInstanceUID: contourImage.ReferencedSOPInstanceUID, ReferencedSOPClassUID: contourImage.ReferencedSOPClassUID, }); } ); const referencedSeries = { SeriesInstanceUID, ReferencedInstanceSequence, }; ReferencedSeriesSequence.push(referencedSeries); } ); } ); } ); return ReferencedSeriesSequence; } function _getSequenceAsArray(sequence) { return Array.isArray(sequence) ? sequence : [sequence]; } function _getReferencedFrameOfReferenceSequence(instance) { const referencedFrameOfReferenceSequenceRaw = instance['30060010']; const referencedFrameOfReferenceSequence = []; if ( !referencedFrameOfReferenceSequenceRaw || !referencedFrameOfReferenceSequenceRaw.Value ) { return undefined; } referencedFrameOfReferenceSequenceRaw.Value.forEach( referencedFrameOfReferenceRaw => { const frameOfReferenceUID = DICOMWeb.getString( referencedFrameOfReferenceRaw['00200052'] ); const referencedFrameOfReference = { frameOfReferenceUID }; const RTReferencedStudySequenceRaw = referencedFrameOfReferenceRaw['30060012']; referencedFrameOfReferenceSequence.push(referencedFrameOfReference); if (RTReferencedStudySequenceRaw && RTReferencedStudySequenceRaw.Value) { referencedFrameOfReference.rtReferencedStudySequence = []; const { rtReferencedStudySequence } = referencedFrameOfReference; RTReferencedStudySequenceRaw.Value.forEach(rtReferencedStudyRaw => { const referencedSopClassUID = DICOMWeb.getString( rtReferencedStudyRaw['00081150'] ); const referencedSOPInstanceUID = DICOMWeb.getString( rtReferencedStudyRaw['00081155'] ); const rtReferencedStudy = { referencedSopClassUID, referencedSOPInstanceUID, rtReferencedSeriesSequence: [], }; rtReferencedStudySequence.push(rtReferencedStudy); const { rtReferencedSeriesSequence } = rtReferencedStudy; const rtReferencedSeriesSequenceRaw = rtReferencedStudyRaw['30060014']; rtReferencedSeriesSequenceRaw.Value.forEach(rtReferencedSeriesRaw => { const seriesInstanceUID = DICOMWeb.getString( rtReferencedSeriesRaw['0020000E'] ); const rtReferencedSeries = { seriesInstanceUID, contourImageSequence: [], }; rtReferencedSeriesSequence.push(rtReferencedSeries); const { contourImageSequence } = rtReferencedSeries; const contourImageSequenceRaw = rtReferencedSeriesRaw['30060016']; contourImageSequenceRaw.Value.forEach(contourImageRaw => { const referencedSOPClassUID = DICOMWeb.getString( contourImageRaw['00081150'] ); const referencedSOPInstanceUID = DICOMWeb.getString( contourImageRaw['00081155'] ); const referencedFrameNumber = DICOMWeb.getString( contourImageRaw['00081160'] ); const referencedSegmentNumber = DICOMWeb.getString( contourImageRaw['0062000B'] ); const contourImage = { referencedSOPClassUID, referencedSOPInstanceUID, referencedFrameNumber, referencedSegmentNumber, }; contourImageSequence.push(contourImage); }); }); }); } } ); return referencedFrameOfReferenceSequence; } export default OHIFDicomRTStructSopClassHandler;