Build WADO logic to fetch + build displaysets + generate imageIds based on prefs.

This commit is contained in:
James A. Petts 2020-05-12 15:00:27 +01:00
parent d5c83bf596
commit 289d3f5703
6 changed files with 164 additions and 15 deletions

View File

@ -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;
},
});
}

View File

@ -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
}
}

View File

@ -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}`;
}

View File

@ -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.
};

View File

@ -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);
}
}
};

View File

@ -16,6 +16,8 @@ export default function ModeRoute({
const dataSource = dataSources[0];
console.log(dataSource);
const { displaySetInstanceUids, setDisplaySetInstanceUids } = useContext(
ViewModelContext
);