OHIF-135: providing all data required by cornerstoneWADOImageLoader to wadors instances
This commit is contained in:
1 parent
3d99821117
commit
9ad0b670b3
7 files changed
+194
-106
No files matched your search
@@ -59,6 +59,10 @@ Viewerbase.updateAllViewports = updateAllViewports;
|
||||
import { sortStudy } from './lib/sortStudy';
|
||||
Viewerbase.sortStudy = sortStudy;
|
||||
|
||||
// updateMetaDataManager
|
||||
import { updateMetaDataManager } from './lib/updateMetaDataManager';
|
||||
Viewerbase.updateMetaDataManager = updateMetaDataManager;
|
||||
|
||||
// updateOrientationMarkers
|
||||
import { updateOrientationMarkers } from './lib/updateOrientationMarkers';
|
||||
Viewerbase.updateOrientationMarkers = updateOrientationMarkers;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
export class WadoRsMetaDataBuilder {
|
||||
constructor() {
|
||||
this.tags = {};
|
||||
}
|
||||
|
||||
addTag(tag, value, multi) {
|
||||
this.tags[tag] = {
|
||||
tag,
|
||||
value,
|
||||
multi
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const json = {};
|
||||
const keys = Object.keys(this.tags);
|
||||
|
||||
keys.forEach(key => {
|
||||
if (!this.tags.hasOwnProperty(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tag = this.tags[key];
|
||||
const multi = !!tag.multi;
|
||||
let value = tag.value;
|
||||
|
||||
if ((value == null) || ((value.length === 1) && (value[0] == null))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((typeof value === 'string') && multi) {
|
||||
value = value.split('\\');
|
||||
}
|
||||
|
||||
if (!_.isArray(value)) {
|
||||
value = [value];
|
||||
}
|
||||
|
||||
json[key] = {
|
||||
Value: value
|
||||
};
|
||||
});
|
||||
|
||||
return json;
|
||||
}
|
||||
}
|
||||
@@ -1,66 +1,6 @@
|
||||
import { OHIF } from 'meteor/ohif:core';
|
||||
import { _ } from 'meteor/underscore';
|
||||
|
||||
class ImageMetadataBuilder {
|
||||
constructor() {
|
||||
this.tags = {};
|
||||
}
|
||||
|
||||
addTag(tag, value, multi) {
|
||||
this.tags[tag] = {
|
||||
tag,
|
||||
value,
|
||||
multi
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
const json = {};
|
||||
const keys = Object.keys(this.tags);
|
||||
|
||||
keys.forEach(key => {
|
||||
if(!this.tags.hasOwnProperty(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tag = this.tags[key];
|
||||
const multi = !!tag.multi;
|
||||
let value = tag.value;
|
||||
|
||||
if((value == null) || ((value.length === 1) && (value[0] == null))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if((typeof value === 'string') && multi) {
|
||||
value = value.split('\\');
|
||||
}
|
||||
|
||||
if(!_.isArray(value)) {
|
||||
value = [value];
|
||||
}
|
||||
|
||||
json[key] = {
|
||||
Value: value
|
||||
};
|
||||
});
|
||||
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
||||
function formatWADORSImageUrl(wadorsuri, frame) {
|
||||
// We need to sum 1 because WADO-RS frame number is 1-based
|
||||
frame = (frame || 0) + 1;
|
||||
|
||||
// Replaces /frame/1 by /frame/{frame}
|
||||
// TODO: Maybe should be better to export the WADOProxy to be able to use it on client
|
||||
// Example: WADOProxy.convertURL(baseWadoRsUri + '/frame/' + frame)
|
||||
wadorsuri = wadorsuri.replace(/(%2Fframes%2F)(\d+)/, `$1${frame}`);
|
||||
|
||||
return Meteor.absoluteUrl(wadorsuri);
|
||||
}
|
||||
import { getWADORSImageUrl } from './getWADORSImageUrl';
|
||||
|
||||
/**
|
||||
* Obtain an imageId for Cornerstone based on the WADO-RS scheme
|
||||
@@ -69,51 +9,14 @@ function formatWADORSImageUrl(wadorsuri, frame) {
|
||||
* @returns {string} The imageId to be used by Cornerstone
|
||||
*/
|
||||
export function getWADORSImageId(instance, frame) {
|
||||
const uri = formatWADORSImageUrl(instance.wadorsuri, frame);
|
||||
const uri = getWADORSImageUrl(instance, frame);
|
||||
|
||||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
|
||||
const imageId = `wadors:${uri}`;
|
||||
|
||||
const imageMetadata = new ImageMetadataBuilder()
|
||||
.addTag('00080016', instance.sopClassUid)
|
||||
.addTag('00080018', instance.sopInstanceUid)
|
||||
.addTag('00180050', instance.sliceThickness)
|
||||
.addTag('00200013', instance.instanceNumber)
|
||||
.addTag('00200032', instance.imagePositionPatient, true)
|
||||
.addTag('00200037', instance.imageOrientationPatient, true)
|
||||
.addTag('00200052', instance.frameOfReferenceUID)
|
||||
.addTag('00201041', instance.sliceLocation)
|
||||
.addTag('00280002', instance.samplesPerPixel)
|
||||
.addTag('00280004', instance.photometricInterpretation)
|
||||
.addTag('00280006', instance.planarConfiguration)
|
||||
.addTag('00280010', instance.rows)
|
||||
.addTag('00280011', instance.columns)
|
||||
.addTag('00280030', instance.pixelSpacing, true)
|
||||
.addTag('00280034', instance.pixelAspectRatio, true)
|
||||
.addTag('00280100', instance.bitsAllocated)
|
||||
.addTag('00280101', instance.bitsStored)
|
||||
.addTag('00280102', instance.highBit)
|
||||
.addTag('00280103', instance.pixelRepresentation)
|
||||
.addTag('00280106', instance.smallestPixelValue)
|
||||
.addTag('00280107', instance.largestPixelValue)
|
||||
.addTag('00281050', instance.windowCenter, true)
|
||||
.addTag('00281051', instance.windowWidth, true)
|
||||
.addTag('00281052', instance.rescaleIntercept)
|
||||
.addTag('00281053', instance.rescaleSlope)
|
||||
.addTag('00281054', instance.rescaleType)
|
||||
.addTag('00281101', instance.redPaletteColorLookupTableDescriptor)
|
||||
.addTag('00281102', instance.greenPaletteColorLookupTableDescriptor)
|
||||
.addTag('00281103', instance.bluePaletteColorLookupTableDescriptor)
|
||||
.addTag('00281201', instance.redPaletteColorLookupTableData)
|
||||
.addTag('00281202', instance.greenPaletteColorLookupTableData)
|
||||
.addTag('00281203', instance.bluePaletteColorLookupTableData)
|
||||
.toJSON();
|
||||
|
||||
_.extend(imageMetadata, {
|
||||
uri: uri,
|
||||
instance: instance
|
||||
});
|
||||
|
||||
cornerstoneWADOImageLoader.wadors.metaDataManager.add(imageId, imageMetadata);
|
||||
|
||||
OHIF.log.info('WADO-RS ImageID: ' + imageId);
|
||||
|
||||
return imageId;
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
export function getWADORSImageUrl(instance, frame) {
|
||||
let wadorsuri = instance.wadorsuri;
|
||||
|
||||
if (!wadorsuri) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to sum 1 because WADO-RS frame number is 1-based
|
||||
frame = (frame || 0) + 1;
|
||||
|
||||
// Replaces /frame/1 by /frame/{frame}
|
||||
// TODO: Maybe should be better to export the WADOProxy to be able to use it on client
|
||||
// Example: WADOProxy.convertURL(baseWadoRsUri + '/frame/' + frame)
|
||||
wadorsuri = wadorsuri.replace(/(%2Fframes%2F)(\d+)/, `$1${frame}`);
|
||||
|
||||
return Meteor.absoluteUrl(wadorsuri);
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
import { _ } from 'meteor/underscore';
|
||||
import { getWADORSImageId } from './getWADORSImageId';
|
||||
import { WadoRsMetaDataBuilder } from './classes/metadata/WadoRsMetaDataBuilder';
|
||||
|
||||
function getRadiopharmaceuticalInfoMetaData(instance) {
|
||||
const radiopharmaceuticalInfo = instance.radiopharmaceuticalInfo;
|
||||
|
||||
if ((instance.modality !== 'PT') || !radiopharmaceuticalInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
return new WadoRsMetaDataBuilder()
|
||||
.addTag('00181072', radiopharmaceuticalInfo.radiopharmaceuticalStartTime)
|
||||
.addTag('00181074', radiopharmaceuticalInfo.radionuclideTotalDose)
|
||||
.addTag('00181075', radiopharmaceuticalInfo.radionuclideHalfLife)
|
||||
.toJSON();
|
||||
}
|
||||
|
||||
const getWadoRsInstanceMetaData = (study, series, instance) => {
|
||||
return new WadoRsMetaDataBuilder()
|
||||
.addTag('00080016', instance.sopClassUid)
|
||||
.addTag('00080018', instance.sopInstanceUid)
|
||||
.addTag('00080021', series.seriesDate)
|
||||
.addTag('00080031', series.seriesTime)
|
||||
.addTag('00080060', instance.modality)
|
||||
.addTag('00101010', study.patientAge)
|
||||
.addTag('00101020', study.patientSize)
|
||||
.addTag('00101030', study.patientWeight)
|
||||
.addTag('00180050', instance.sliceThickness)
|
||||
.addTag('0020000e', series.seriesInstanceUid)
|
||||
.addTag('00200011', series.seriesNumber)
|
||||
.addTag('0020000d', study.studyInstanceUid)
|
||||
.addTag('00200013', instance.instanceNumber)
|
||||
.addTag('00200032', instance.imagePositionPatient, true)
|
||||
.addTag('00200037', instance.imageOrientationPatient, true)
|
||||
.addTag('00200052', instance.frameOfReferenceUID)
|
||||
.addTag('00201041', instance.sliceLocation)
|
||||
.addTag('00280002', instance.samplesPerPixel)
|
||||
.addTag('00280004', instance.photometricInterpretation)
|
||||
.addTag('00280006', instance.planarConfiguration)
|
||||
.addTag('00280010', instance.rows)
|
||||
.addTag('00280011', instance.columns)
|
||||
.addTag('00280030', instance.pixelSpacing, true)
|
||||
.addTag('00280034', instance.pixelAspectRatio, true)
|
||||
.addTag('00280100', instance.bitsAllocated)
|
||||
.addTag('00280101', instance.bitsStored)
|
||||
.addTag('00280102', instance.highBit)
|
||||
.addTag('00280103', instance.pixelRepresentation)
|
||||
.addTag('00280106', instance.smallestPixelValue)
|
||||
.addTag('00280107', instance.largestPixelValue)
|
||||
.addTag('00281050', instance.windowCenter, true)
|
||||
.addTag('00281051', instance.windowWidth, true)
|
||||
.addTag('00281052', instance.rescaleIntercept)
|
||||
.addTag('00281053', instance.rescaleSlope)
|
||||
.addTag('00281054', instance.rescaleType)
|
||||
.addTag('00281101', instance.redPaletteColorLookupTableDescriptor)
|
||||
.addTag('00281102', instance.greenPaletteColorLookupTableDescriptor)
|
||||
.addTag('00281103', instance.bluePaletteColorLookupTableDescriptor)
|
||||
.addTag('00281201', instance.redPaletteColorLookupTableData)
|
||||
.addTag('00281202', instance.greenPaletteColorLookupTableData)
|
||||
.addTag('00281203', instance.bluePaletteColorLookupTableData)
|
||||
.addTag('00540016', getRadiopharmaceuticalInfoMetaData(instance))
|
||||
.toJSON();
|
||||
};
|
||||
|
||||
export function updateMetaDataManager(study) {
|
||||
study.seriesList.forEach(series => {
|
||||
series.instances.forEach(instance => {
|
||||
// Cache just images that are going to be loaded via WADO-RS
|
||||
if ((instance.imageRendering !== 'wadors') && (instance.thumbnailRendering !== 'wadors')) {
|
||||
OHIF.log.info(`Skiping cornerstone metaDataManager update (${imageId})`);
|
||||
return;
|
||||
}
|
||||
|
||||
const metaData = getWadoRsInstanceMetaData(study, series, instance);
|
||||
const numberOfFrames = instance.numberOfFrames || 1;
|
||||
|
||||
// We can share the same metaData with all frames because it doesn't have
|
||||
// any frame specific data, such as frameNumber, pixelData, offset, etc.
|
||||
// WADO-RS frame number is 1-based
|
||||
for (let frameNumber = 0; frameNumber < numberOfFrames; frameNumber++) {
|
||||
const imageId = getWADORSImageId(instance, frameNumber);
|
||||
cornerstoneWADOImageLoader.wadors.metaDataManager.add(imageId, metaData);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user