diff --git a/extensions/default/src/DicomWebDataSource/index.js b/extensions/default/src/DicomWebDataSource/index.js index e331dc0d9..74f7aa44a 100644 --- a/extensions/default/src/DicomWebDataSource/index.js +++ b/extensions/default/src/DicomWebDataSource/index.js @@ -6,7 +6,15 @@ import { processResults, processSeriesResults, } from './qido.js'; -import { dicomMetadataStore, IWebApiDataSource, utils } from '@ohif/core'; +import { + dicomMetadataStore, + IWebApiDataSource, + utils, + displaySetManager, +} from '@ohif/core'; + +import { mapParams, search as qidoSearch, processResults } from './qido.js'; +import getImageId from './utils/getImageId'; import * as dcmjs from 'dcmjs'; import { retrieveStudyMetadata } from './retrieveStudyMetadata.js'; @@ -121,18 +129,46 @@ function createDicomWebApi(dicomWebConfig) { }); }); }); - - // TEMP use dummy data. - //const { naturalizeDataset } = dcmjs.data.DicomMetaDictionary; - //const instances = exampleInstances.map(naturalizeDataset); - - // TEMP - - //dicomMetadataStore.addInstances(instances); - //callback(instances); }, }, }, + getImageIdsForDisplaySet(displaySetInstanceUid) { + const displaySet = displaySetManager.getDisplaySetByUID( + displaySetInstanceUid + ); + + debugger; + + const images = displaySet.images; + + const imageIds = []; + + if (!images) { + return imageIds; + } + + displaySet.images.forEach(instance => { + const NumberOfFrames = instance.NumberOfFrames; + + if (NumberOfFrames > 1) { + for (let i = 0; i < NumberOfFrames; i++) { + const imageId = getImageId({ + instance, + frame: i, + config: dicomWebConfig, + }); + imageIds.push(imageId); + } + } else { + const imageId = getImageId({ instance, config: dicomWebConfig }); + imageIds.push(imageId); + } + }); + + debugger; + + return imageIds; + }, }); } diff --git a/extensions/default/src/DicomWebDataSource/utils/getImageId.js b/extensions/default/src/DicomWebDataSource/utils/getImageId.js new file mode 100644 index 000000000..0e7325eb0 --- /dev/null +++ b/extensions/default/src/DicomWebDataSource/utils/getImageId.js @@ -0,0 +1,51 @@ +import getWADORSImageId from './getWADORSImageId'; + +function buildInstanceWadoUrl(config, instance) { + const { StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID } = instance; + const params = []; + + params.push('requestType=WADO'); + params.push(`studyUID=${StudyInstanceUID}`); + params.push(`seriesUID=${SeriesInstanceUID}`); + params.push(`objectUID=${SOPInstanceUID}`); + params.push('contentType=application/dicom'); + params.push('transferSyntax=*'); + + const paramString = params.join('&'); + + return `${config.wadoUriRoot}?${paramString}`; +} + +/** + * Obtain an imageId for Cornerstone from an image instance + * + * @param instance + * @param frame + * @param thumbnail + * @returns {string} The imageId to be used by Cornerstone + */ +export default function getImageId({ + instance, + frame, + config, + thumbnail = false, +}) { + if (!instance) { + return; + } + + const renderingAttr = thumbnail ? 'thumbnailRendering' : 'imageRendering'; + + if (!config[renderingAttr] || config[renderingAttr] === 'wadouri') { + const wadouri = buildInstanceWadoUrl(config, instance); + + let imageId = 'dicomweb:' + wadouri; + if (frame !== undefined) { + imageId += '&frame=' + frame; + } + + return imageId; + } else { + return getWADORSImageId(instance, config, frame); // WADO-RS Retrieve Frame + } +} diff --git a/extensions/default/src/DicomWebDataSource/utils/getWADORSImageId.js b/extensions/default/src/DicomWebDataSource/utils/getWADORSImageId.js new file mode 100644 index 000000000..36058292f --- /dev/null +++ b/extensions/default/src/DicomWebDataSource/utils/getWADORSImageId.js @@ -0,0 +1,51 @@ +function buildInstanceWadoRsUri(instance, config) { + const { StudyInstanceUID, SeriesInstanceUID, SOPInstanceUID } = instance; + return `${config.wadoRoot}/studies/${StudyInstanceUID}/series/${SeriesInstanceUID}/instances/${SOPInstanceUID}`; +} + +function buildInstanceFrameWadoRsUri(instance, config, frame) { + const baseWadoRsUri = buildInstanceWadoRsUri(instance, config); + + frame = frame != null || 1; + + return `${baseWadoRsUri}/frames/${frame}`; +} + +// function getWADORSImageUrl(instance, frame) { +// const wadorsuri = buildInstanceFrameWadoRsUri(instance, config, frame); + +// if (!wadorsuri) { +// return; +// } + +// // Use null to obtain an imageId which represents the instance +// if (frame === null) { +// wadorsuri = wadorsuri.replace(/frames\/(\d+)/, ''); +// } else { +// // We need to sum 1 because WADO-RS frame number is 1-based +// frame = frame ? parseInt(frame) + 1 : 1; + +// // Replaces /frame/1 by /frame/{frame} +// wadorsuri = wadorsuri.replace(/frames\/(\d+)/, `frames/${frame}`); +// } + +// return wadorsuri; +// } + +/** + * Obtain an imageId for Cornerstone based on the WADO-RS scheme + * + * @param {object} instanceMetada metadata object (InstanceMetadata) + * @param {(string\|number)} [frame] the frame number + * @returns {string} The imageId to be used by Cornerstone + */ +export default function getWADORSImageId(instance, config, frame) { + //const uri = getWADORSImageUrl(instance, frame); + const uri = buildInstanceFrameWadoRsUri(instance, config, frame); + + if (!uri) { + return; + } + + return `wadors:${uri}`; +} diff --git a/platform/core/src/DataSources/IWebApiDataSource.js b/platform/core/src/DataSources/IWebApiDataSource.js index 580d4de04..487c8101d 100644 --- a/platform/core/src/DataSources/IWebApiDataSource.js +++ b/platform/core/src/DataSources/IWebApiDataSource.js @@ -10,7 +10,7 @@ import { dicomMetadataStore } from '@ohif/core'; * It's worth noting that a single implementation of this interface * can define different underlying sources for "read" and "write" operations. */ -function create({ query, retrieve }) { +function create({ query, retrieve, getImageIdsForDisplaySet }) { const defaultQuery = { studies: { /** @@ -38,8 +38,9 @@ function create({ query, retrieve }) { }; return { - query, - retrieve, + query: query || defaultQuery, + retrieve: retrieve || defaultRetrieve, + getImageIdsForDisplaySet, // then go get all series level metadata. // Store this in the DICOM MetadataStore. }; diff --git a/platform/core/src/displaySetManager.js b/platform/core/src/displaySetManager.js index 845ebe3b3..f006a6f25 100644 --- a/platform/core/src/displaySetManager.js +++ b/platform/core/src/displaySetManager.js @@ -39,6 +39,12 @@ class DisplaySetManager { ); } + getDisplaySetByUID(displaySetInstanceUid) { + return this.displaySets.find( + displaySet => displaySet.displaySetInstanceUid === displaySetInstanceUid + ); + } + makeDisplaySets = instances => { if (!instances || !instances.length) { throw new Error('No instances were provided.'); @@ -73,10 +79,12 @@ class DisplaySetManager { addedDisplaySetUids = this._addDisplaySets(displaySets); } - this.setDisplaySetInstanceUids([ + this.displaySetInstanceUids = [ ...addedDisplaySetUids, ...this.displaySetInstanceUids, - ]); + ]; + + this.setDisplaySetInstanceUids(this.displaySetInstanceUids); } } }; diff --git a/platform/viewer/src/routes/ModeRoute.js b/platform/viewer/src/routes/ModeRoute.js index dee08e0d7..5feacb448 100644 --- a/platform/viewer/src/routes/ModeRoute.js +++ b/platform/viewer/src/routes/ModeRoute.js @@ -16,6 +16,8 @@ export default function ModeRoute({ const dataSource = dataSources[0]; + console.log(dataSource); + const { displaySetInstanceUids, setDisplaySetInstanceUids } = useContext( ViewModelContext );