IDC2346: fix images sorting (#2358)

This commit is contained in:
Davide Punzo 2021-04-14 19:43:58 +02:00 committed by GitHub
parent 9bbdb35d88
commit 4bb36704ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 26 deletions

View File

@ -9,7 +9,7 @@ import { SeriesMetadata } from './SeriesMetadata';
import { api } from 'dicomweb-client'; import { api } from 'dicomweb-client';
// - createStacks // - createStacks
import { isImage } from '../../utils/isImage'; import { isImage } from '../../utils/isImage';
import isDisplaySetReconstructable from '../../utils/isDisplaySetReconstructable'; import { isDisplaySetReconstructable, isSpacingUniform } from '../../utils/isDisplaySetReconstructable';
import errorHandler from '../../errorHandler'; import errorHandler from '../../errorHandler';
import isLowPriorityModality from '../../utils/isLowPriorityModality'; import isLowPriorityModality from '../../utils/isLowPriorityModality';
@ -796,7 +796,7 @@ const makeDisplaySet = (series, instances) => {
isMultiFrame: isMultiFrame(instance), isMultiFrame: isMultiFrame(instance),
}); });
// Sort the images in this series if needed // Sort the images in this series by instanceNumber
const shallSort = true; //!OHIF.utils.ObjectPath.get(Meteor, 'settings.public.ui.sortSeriesByIncomingOrder'); const shallSort = true; //!OHIF.utils.ObjectPath.get(Meteor, 'settings.public.ui.sortSeriesByIncomingOrder');
if (shallSort) { if (shallSort) {
imageSet.sortBy((a, b) => { imageSet.sortBy((a, b) => {
@ -817,19 +817,29 @@ const makeDisplaySet = (series, instances) => {
const displayReconstructableInfo = isDisplaySetReconstructable(instances); const displayReconstructableInfo = isDisplaySetReconstructable(instances);
imageSet.isReconstructable = displayReconstructableInfo.value; imageSet.isReconstructable = displayReconstructableInfo.value;
let displaySpacingInfo = undefined;
if (shallSort && imageSet.isReconstructable) { if (shallSort && imageSet.isReconstructable) {
// sort images by image position
imageSet.sortByImagePositionPatient(); imageSet.sortByImagePositionPatient();
}
if (displayReconstructableInfo.missingFrames) { // check if the spacing is uniform and update isReconstructable
// TODO -> This is currently unused, but may be used for reconstructing const datasetIs4D = displayReconstructableInfo.warningIssues.find
// Volumes with gaps later on. (issue => issue === ReconstructionIssues.DATASET_4D);
imageSet.missingFrames = displayReconstructableInfo.missingFrames; displaySpacingInfo = isSpacingUniform(imageSet.images, datasetIs4D);
imageSet.isReconstructable = displaySpacingInfo.isUniform;
if (displaySpacingInfo.missingFrames) {
// TODO -> This is currently unused, but may be used for reconstructing
// Volumes with gaps later on.
imageSet.missingFrames = displaySpacingInfo.missingFrames;
}
} }
if (!imageSet.displayReconstructableInfo) { if (!imageSet.displayReconstructableInfo) {
// It is not reconstrabale Save type of warning // It is not reconstrabale Save type of warning
imageSet.warningIssues = displayReconstructableInfo.warningIssues; imageSet.warningIssues = displaySpacingInfo ?
displayReconstructableInfo.warningIssues.concat(displaySpacingInfo.warningIssues) :
displayReconstructableInfo.warningIssues;
} }
return imageSet; return imageSet;

View File

@ -4,11 +4,11 @@ import { ReconstructionIssues } from './../enums.js';
/** /**
* Checks if a series is reconstructable to a 3D volume. * Checks if a series is reconstructable to a 3D volume.
* *
* @param {Object[]} instances An array of `OHIFInstanceMetadata` objects. * @param {Object[]} An array of `OHIFInstanceMetadata` objects.
* *
* @returns {Object} reconstructable value, missingFrames and warningIssues. * @returns {Object} value, warningIssues.
*/ */
export default function isDisplaySetReconstructable(instances) { function isDisplaySetReconstructable(instances) {
if (!instances.length) { if (!instances.length) {
return { value: false }; return { value: false };
} }
@ -28,7 +28,7 @@ export default function isDisplaySetReconstructable(instances) {
} }
if (isMultiframe) { if (isMultiframe) {
return processMultiframe(instances[0]); return processMultiframe();
} else { } else {
return processSingleframe(instances); return processSingleframe(instances);
} }
@ -37,12 +37,10 @@ export default function isDisplaySetReconstructable(instances) {
/** /**
* Process reconstructable multiframes checks * Process reconstructable multiframes checks
* TODO: deal with multriframe checks! return false for now as can't reconstruct. * TODO: deal with multriframe checks! return false for now as can't reconstruct.
* * *
* @param {Object} instanceof `OHIFInstanceMetadata` objects. Currently not used. * @returns {Object} value and warningIssues.
*
* @returns {Object} reconstructable value and warningIssues.
*/ */
function processMultiframe(instance) { function processMultiframe() {
const warningIssues = [ReconstructionIssues.MULTIFRAMES]; const warningIssues = [ReconstructionIssues.MULTIFRAMES];
return { value: false, warningIssues }; return { value: false, warningIssues };
} }
@ -50,9 +48,9 @@ function processMultiframe(instance) {
/** /**
* Process reconstructable single frame checks * Process reconstructable single frame checks
* *
* @param {Object[]} instances An array of `OHIFInstanceMetadata` objects. * @param {Object[]} An array of `OHIFInstanceMetadata` objects.
* *
* @returns {Object} reconstructable value, missingFrames and warningIssues. * @returns {Object} value and warningIssues.
*/ */
function processSingleframe(instances) { function processSingleframe(instances) {
const n = instances.length; const n = instances.length;
@ -61,7 +59,6 @@ function processSingleframe(instances) {
const firstImageColumns = firstImage.Columns; const firstImageColumns = firstImage.Columns;
const firstImageSamplesPerPixel = firstImage.SamplesPerPixel; const firstImageSamplesPerPixel = firstImage.SamplesPerPixel;
const firstImageOrientationPatient = firstImage.ImageOrientationPatient; const firstImageOrientationPatient = firstImage.ImageOrientationPatient;
const firstImagePositionPatient = firstImage.ImagePositionPatient;
const warningIssues = []; const warningIssues = [];
// Can't reconstruct if we: // Can't reconstruct if we:
@ -91,11 +88,28 @@ function processSingleframe(instances) {
} }
// check if dataset is 4D // check if dataset is 4D
const datasetIs4D = _isDataset4D(instances); if (_isDataset4D(instances)) {
if (datasetIs4D) {
warningIssues.push(ReconstructionIssues.DATASET_4D); warningIssues.push(ReconstructionIssues.DATASET_4D);
} }
return { value: warningIssues.length === 0 ? true : false, warningIssues };
}
/**
* Check is the spacing is uniform.
* The input metadata array has to be ordered by image position.
*
* @param {Object[]} An array of `OHIFInstanceMetadata` objects.
* @param {boolean} is the dataset 4D.
*
* @returns {Object} isUniform, warningIssues and missingFrames
*/
function isSpacingUniform(instances, datasetIs4D) {
const n = instances.length;
const firstImage = instances[0].getData().metadata;
const firstImagePositionPatient = firstImage.ImagePositionPatient;
const warningIssues = [];
let missingFrames = 0; let missingFrames = 0;
// Check if frame spacing is approximately equal within a spacingTolerance. // Check if frame spacing is approximately equal within a spacingTolerance.
@ -150,11 +164,10 @@ function processSingleframe(instances) {
} }
} }
return { isUniform: warningIssues.length === 0 ? true : false, missingFrames, warningIssues };
return { value: warningIssues.length === 0 ? true : false, missingFrames, warningIssues };
} }
/** /**
* Check if 4D dataset. * Check if 4D dataset.
* *
@ -166,7 +179,7 @@ function processSingleframe(instances) {
* *
* @param {Object[]} instances An array of `OHIFInstanceMetadata` objects. * @param {Object[]} instances An array of `OHIFInstanceMetadata` objects.
* *
* @returns {boolean} reconstructable value. * @returns {boolean} dataset4D value.
*/ */
function _isDataset4D(instances) { function _isDataset4D(instances) {
const n = instances.length; const n = instances.length;
@ -258,3 +271,5 @@ function _getPerpendicularDistance(a, b) {
} }
const constructableModalities = ['MR', 'CT', 'PT', 'NM']; const constructableModalities = ['MR', 'CT', 'PT', 'NM'];
export {isDisplaySetReconstructable, isSpacingUniform};