ohif-viewer/Packages/ohif-measurements/client/conformance/criteria/MeasurementsLength.js
2017-01-18 11:01:52 -02:00

141 lines
5.0 KiB
JavaScript

import { BaseCriterion } from './BaseCriterion';
export const MeasurementsLengthSchema = {
properties: {
longAxis: {
label: 'Minimum length of long axis',
type: 'number',
minimum: 0
},
shortAxis: {
label: 'Minimum length of short axis',
type: 'number',
minimum: 0
},
longAxisSliceThicknessMultiplier: {
label: 'Length of long axis multiplier',
type: 'number',
minimum: 0
},
shortAxisSliceThicknessMultiplier: {
label: 'Length of short axis multiplier',
type: 'number',
minimum: 0
},
modalityIn: {
label: 'Filter to evaluate only measurements with the specified modalities',
type: 'array',
items: {
type: 'string'
},
minItems: 1,
uniqueItems: true
},
modalityNotIn: {
label: 'Filter to evaluate only measurements without the specified modalities',
type: 'array',
items: {
type: 'string'
},
minItems: 1,
uniqueItems: true
},
locationIn: {
label: 'Filter to evaluate only measurements with the specified locations',
type: 'array',
items: {
type: 'string'
},
minItems: 1,
uniqueItems: true
},
locationNotIn: {
label: 'Filter to evaluate only measurements without the specified locations',
type: 'array',
items: {
type: 'string'
},
minItems: 1,
uniqueItems: true
},
message: {
label: 'Message to be displayed in case of nonconformity',
type: 'string'
}
},
oneOf: [
{ required: ['message', 'longAxis'] },
{ required: ['message', 'shortAxis'] },
{ required: ['message', 'longAxisSliceThicknessMultiplier'] },
{ required: ['message', 'shortAxisSliceThicknessMultiplier'] }
]
};
/*
* MeasurementsLengthCriterion
* Check the measurements of all bidirectional tools based on
* short axis, long axis, modalities, location and slice thickness
* Options:
* longAxis: Minimum length of long axis
* shortAxis: Minimum length of short axis
* longAxisSliceThicknessMultiplier: Length of long axis multiplier
* shortAxisSliceThicknessMultiplier: Length of short axis multiplier
* modalityIn: Filter to evaluate only measurements with the specified modalities
* modalityNotIn: Filter to evaluate only measurements without the specified modalities
* locationIn: Filter to evaluate only measurements with the specified locations
* locationNotIn: Filter to evaluate only measurements without the specified locations
* message: Message to be displayed in case of nonconformity
*/
export class MeasurementsLengthCriterion extends BaseCriterion {
constructor(options) {
super(options);
}
evaluate(data) {
let message;
let measurements = [];
const { options } = this;
const longMultiplier = options.longAxisSliceThicknessMultiplier;
const shortMultiplier = options.shortAxisSliceThicknessMultiplier;
data.targets.forEach(item => {
const { measurement, metadata } = item;
const { location, longestDiameter, shortestDiameter } = measurement;
const { sliceThickness } = metadata;
const modality = metadata.modality.toUpperCase();
// Stop here if the measurement does not match the modality and location filters
if (options.locationIn && options.locationIn.indexOf(location) === -1) return;
if (options.modalityIn && options.modalityIn.indexOf(modality) === -1) return;
if (options.locationNotIn && options.locationNotIn.indexOf(location) > -1) return;
if (options.modalityNotIn && options.modalityNotIn.indexOf(modality) > -1) return;
// Check the measurement length
const failed = (
(options.longAxis && longestDiameter < options.longAxis) ||
(options.shortAxis && shortestDiameter < options.shortAxis) || (
longMultiplier && !isNaN(sliceThickness) &&
longestDiameter < (longMultiplier * sliceThickness)
) || (
shortMultiplier && !isNaN(sliceThickness) &&
shortestDiameter < (shortMultiplier * sliceThickness)
)
);
// Mark this measurement as invalid if some of the checks have failed
if (failed) {
measurements.push(measurement);
}
});
// Use the options' message if some measurement is invalid
if (measurements.length) {
message = options.message;
}
return this.generateResponse(message, measurements);
}
}