OHIF-20 Moving multi-frame related functionality to metaDataProvider / Created new library with parsing utilities.

This commit is contained in:
Emanuel F. Oliveira 2016-10-28 15:44:32 -02:00
parent 952f4d1a60
commit 1122594d2b
3 changed files with 110 additions and 5 deletions

View File

@ -213,15 +213,15 @@ function loadDisplaySetIntoViewport(data, templateData) {
cornerstoneTools.addToolState(element, 'stack', stack);
// Set the default CINE settings
var frameRate = 1000 / displaySet.images[0].frameTime;
var multiframeMetadata = instance.multiframeMetadata;
var cineToolData = {
loop: OHIF.viewer.cine.loop,
framesPerSecond: frameRate || OHIF.viewer.cine.framesPerSecond
framesPerSecond: multiframeMetadata.averageFrameRate || OHIF.viewer.cine.framesPerSecond
};
cornerstoneTools.addToolState(element, 'playClip', cineToolData);
// Autoplay datasets that have framerates set
if (frameRate) {
if (multiframeMetadata.isMultiframeImage && multiframeMetadata.averageFrameRate > 0) {
cornerstoneTools.playClip(element);
}
@ -386,7 +386,6 @@ function setDisplaySet(data, displaySetInstanceUid, templateData) {
var study = data.study;
if (!study || !study.displaySets) {
throw 'Study does not exist or has no display sets';
return;
}
study.displaySets.every(displaySet => {
@ -401,7 +400,6 @@ function setDisplaySet(data, displaySetInstanceUid, templateData) {
// If we didn't find anything, stop here
if (!data.displaySet) {
throw 'Display set not found in specified study!';
return;
}
// Otherwise, load pass the data object into loadSeriesIntoViewport

View File

@ -1,3 +1,5 @@
import {parsingUtils} from './parsingUtils'
var metaDataLookup = {};
/**
@ -102,6 +104,7 @@ updateMetaData = function(image) {
imageMetaData.instance.frameIncrementPointer = imageMetaData.instance.frameIncrementPointer || image.data.string('x00280009');
imageMetaData.instance.frameTime = imageMetaData.instance.frameTime || image.data.string('x00181063');
imageMetaData.instance.frameTimeVector = imageMetaData.instance.frameTimeVector || image.data.string('x00181065');
imageMetaData.instance.multiframeMetadata = getMultiframeModuleMetaData(image.data);
imageMetaData.imagePlane = imageMetaData.imagePlane || getImagePlane(imageMetaData.instance);
};
@ -150,6 +153,69 @@ function getImagePlane(instance) {
};
}
/**
* This function extracts miltiframe information from a dicomParser.DataSet object.
*
* @param dataSet {Object} An instance of dicomParser.DataSet object where multiframe information can be found.
* @return {Object} An object containing multiframe image metadata (frameIncrementPointer, frameTime, frameTimeVector, etc).
*/
getMultiframeModuleMetaData = function(dataSet) {
var numberOfFrames,
frameIncrementPointer,
frameTime,
frameTimeVector,
imageInfo = {
isMultiframeImage: false,
frameIncrementPointer: null,
numberOfFrames: 0,
frameTime: 0,
frameTimeVector: null,
averageFrameRate: 0 // backwards compatibility only... it might be useless in the future
};
if (parsingUtils.isValidDataSet(dataSet)) {
// (0028,0008) = Number of Frames
numberOfFrames = dataSet.intString('x00280008', -1);
if (numberOfFrames > 0) {
// set multi-frame image indicator
imageInfo.isMultiframeImage = true;
imageInfo.numberOfFrames = numberOfFrames;
// (0028,0009) = Frame Increment Pointer
frameIncrementPointer = parsingUtils.attributeTag(dataSet, 'x00280009') || '';
if (frameIncrementPointer === 'x00181065') {
// Frame Increment Pointer points to Frame Time Vector (0018,1065) field
frameTimeVector = parsingUtils.floatArray(dataSet, 'x00181065');
if (frameTimeVector instanceof Array && frameTimeVector.length > 0) {
imageInfo.frameIncrementPointer = 'frameTimeVector';
imageInfo.frameTimeVector = frameTimeVector;
frameTime = frameTimeVector.reduce((a, b) => a + b) / frameTimeVector.length;
imageInfo.averageFrameRate = 1000 / frameTime;
}
} else if (frameIncrementPointer === 'x00181063' || frameIncrementPointer === '') {
// Frame Increment Pointer points to Frame Time (0018,1063) field or is not defined (for addtional flexibility).
// Yet another value is possible for this field (5200,9230 for Multi-frame Functional Groups)
// but that case is currently not supported.
frameTime = dataSet.floatString('x00181063', -1);
if (frameTime > 0) {
imageInfo.frameIncrementPointer = 'frameTime';
imageInfo.frameTime = frameTime;
imageInfo.averageFrameRate = 1000 / frameTime;
}
}
}
}
return imageInfo;
};
/**
* Looks up metaData for Cornerstone Tools given a specified type and imageId
* A type may be, e.g. 'study', or 'patient', or 'imagePlane'. These types

View File

@ -0,0 +1,41 @@
import {dicomParser} from 'meteor/cornerstone';
export const parsingUtils = {
isValidDataSet: function(data) {
return (data instanceof dicomParser.DataSet);
},
attributeTag: function(data, tag) {
if (this.isValidDataSet(data) && tag in data.elements) {
let element = data.elements[tag];
if (element && element.length === 4) {
let parser = data.byteArrayParser.readUint16,
bytes = data.byteArray,
offset = element.dataOffset;
return 'x' + ('00000000' + (parser(bytes, offset) * 256 * 256 + parser(bytes, offset + 2)).toString(16)).substr(-8);
}
}
return null;
},
multiValue: function(data, tag, parser) {
if (this.isValidDataSet(data) && tag in data.elements) {
let element = data.elements[tag];
if (element && element.length > 0) {
let string = dicomParser.readFixedString(data.byteArray, element.dataOffset, element.length);
if (typeof string === 'string' && string.length > 0) {
if (typeof parser !== 'function') {
parser = null;
}
return string.split('\\').map(function(value) {
value = value.trim();
return parser !== null ? parser(value) : value;
});
}
}
}
return null;
},
floatArray: function(data, tag) {
return this.multiValue(data, tag, parseFloat);
}
};