129 lines
4.9 KiB
JavaScript
129 lines
4.9 KiB
JavaScript
import { Meteor } from 'meteor/meteor';
|
|
import { isImage } from './isImage';
|
|
import { OHIF } from 'ohif-core';
|
|
|
|
const isMultiFrame = instance => {
|
|
// NumberOfFrames (0028,0008)
|
|
return instance.getRawValue('x00280008') > 1;
|
|
};
|
|
|
|
const makeDisplaySet = (series, instances) => {
|
|
const instance = instances[0];
|
|
|
|
const { ImageSet } = OHIF.classes;
|
|
const imageSet = new ImageSet(instances);
|
|
const seriesData = series.getData();
|
|
|
|
// set appropriate attributes to image set...
|
|
imageSet.setAttributes({
|
|
displaySetInstanceUid: imageSet.uid, // create a local alias for the imageSet UID
|
|
seriesDate: seriesData.seriesDate,
|
|
seriesTime: seriesData.seriesTime,
|
|
seriesInstanceUid: series.getSeriesInstanceUID(),
|
|
seriesNumber: instance.getRawValue('x00200011'),
|
|
seriesDescription: instance.getRawValue('x0008103e'),
|
|
numImageFrames: instances.length,
|
|
frameRate: instance.getRawValue('x00181063'),
|
|
modality: instance.getRawValue('x00080060'),
|
|
isMultiFrame: isMultiFrame(instance)
|
|
});
|
|
|
|
// Sort the images in this series if needed
|
|
const shallSort = !OHIF.utils.ObjectPath.get(Meteor, 'settings.public.ui.sortSeriesByIncomingOrder');
|
|
if (shallSort) {
|
|
imageSet.sortBy((a, b) => {
|
|
// Sort by InstanceNumber (0020,0013)
|
|
return (parseInt(a.getRawValue('x00200013', 0)) || 0) - (parseInt(b.getRawValue('x00200013', 0)) || 0);
|
|
});
|
|
}
|
|
|
|
// Include the first image instance number (after sorted)
|
|
imageSet.setAttribute('instanceNumber', imageSet.getImage(0).getRawValue('x00200013'));
|
|
|
|
return imageSet;
|
|
};
|
|
|
|
const isSingleImageModality = modality => {
|
|
return (modality === 'CR' ||
|
|
modality === 'MG' ||
|
|
modality === 'DX');
|
|
};
|
|
|
|
/**
|
|
* Creates a set of series to be placed in the Study Metadata
|
|
* The series that appear in the Study Metadata must represent
|
|
* imaging modalities.
|
|
*
|
|
* Furthermore, for drag/drop functionality,
|
|
* it is easiest if the stack objects also contain information about
|
|
* which study they are linked to.
|
|
*
|
|
* @param study The study instance metadata to be used
|
|
* @returns {Array} An array of series to be placed in the Study Metadata
|
|
*/
|
|
const createStacks = study => {
|
|
// Define an empty array of display sets
|
|
const displaySets = [];
|
|
|
|
if (!study || !study.getSeriesCount()) {
|
|
return displaySets;
|
|
}
|
|
|
|
// Loop through the series (SeriesMetadata)
|
|
study.forEachSeries(series => {
|
|
// If the series has no instances, skip it
|
|
if (!series.getInstanceCount()) {
|
|
return;
|
|
}
|
|
|
|
// Search through the instances (InstanceMedatada object) of this series
|
|
// Split Multi-frame instances and Single-image modalities
|
|
// into their own specific display sets. Place the rest of each
|
|
// series into another display set.
|
|
const stackableInstances = [];
|
|
series.forEachInstance(instance => {
|
|
// All imaging modalities must have a valid value for sopClassUid (x00080016) or rows (x00280010)
|
|
if (!isImage(instance.getRawValue('x00080016')) && !instance.getRawValue('x00280010')) {
|
|
return;
|
|
}
|
|
|
|
let displaySet;
|
|
if (isMultiFrame(instance)) {
|
|
displaySet = makeDisplaySet(series, [ instance ]);
|
|
displaySet.setAttributes({
|
|
isClip: true,
|
|
studyInstanceUid: study.getStudyInstanceUID(), // Include the study instance Uid for drag/drop purposes
|
|
numImageFrames: instance.getRawValue('x00280008'), // Override the default value of instances.length
|
|
instanceNumber: instance.getRawValue('x00200013'), // Include the instance number
|
|
acquisitionDatetime: instance.getRawValue('x0008002a') // Include the acquisition datetime
|
|
});
|
|
displaySets.push(displaySet);
|
|
} else if (isSingleImageModality(instance.modality)) {
|
|
displaySet = makeDisplaySet(series, [ instance ]);
|
|
displaySet.setAttributes({
|
|
studyInstanceUid: study.getStudyInstanceUID(), // Include the study instance Uid
|
|
instanceNumber: instance.getRawValue('x00200013'), // Include the instance number
|
|
acquisitionDatetime: instance.getRawValue('x0008002a') // Include the acquisition datetime
|
|
});
|
|
displaySets.push(displaySet);
|
|
} else {
|
|
stackableInstances.push(instance);
|
|
}
|
|
});
|
|
|
|
if (stackableInstances.length) {
|
|
const displaySet = makeDisplaySet(series, stackableInstances);
|
|
displaySet.setAttribute('studyInstanceUid', study.getStudyInstanceUID());
|
|
displaySets.push(displaySet);
|
|
}
|
|
});
|
|
|
|
return displaySets;
|
|
};
|
|
|
|
/**
|
|
* Expose "createStacks"...
|
|
*/
|
|
|
|
export { createStacks };
|