Allowing new target handling on max targets criteria
This commit is contained in:
parent
6e2dfacd3a
commit
ac2df0b3d0
@ -67,6 +67,7 @@ Template.trialOptionsModal.helpers({
|
|||||||
Template.trialOptionsModal.events({
|
Template.trialOptionsModal.events({
|
||||||
'change .js-trial'(event, instance) {
|
'change .js-trial'(event, instance) {
|
||||||
const form = instance.$('form').first().data('component');
|
const form = instance.$('form').first().data('component');
|
||||||
|
if (!form) return;
|
||||||
instance.selectedTrial.set(form.value().trialCriteria);
|
instance.selectedTrial.set(form.value().trialCriteria);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -41,12 +41,7 @@ Template.measurementTableView.helpers({
|
|||||||
const configuration = OHIF.measurements.MeasurementApi.getConfiguration();
|
const configuration = OHIF.measurements.MeasurementApi.getConfiguration();
|
||||||
const trialCriteriaType = OHIF.lesiontracker.TrialCriteriaTypes.findOne({ selected: true });
|
const trialCriteriaType = OHIF.lesiontracker.TrialCriteriaTypes.findOne({ selected: true });
|
||||||
const trialCriteriaTypeId = trialCriteriaType.id.toLowerCase();
|
const trialCriteriaTypeId = trialCriteriaType.id.toLowerCase();
|
||||||
const trialToolGroupMap = {
|
const toolGroupId = trialCriteriaTypeId === 'recist' ? 'nonTargets' : 'targets';
|
||||||
recist: 'nonTargets',
|
|
||||||
irrc: 'targets'
|
|
||||||
};
|
|
||||||
|
|
||||||
const toolGroupId = trialToolGroupMap[trialCriteriaTypeId];
|
|
||||||
const toolGroup = _.findWhere(configuration.measurementTools, { id: toolGroupId });
|
const toolGroup = _.findWhere(configuration.measurementTools, { id: toolGroupId });
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { _ } from 'meteor/underscore';
|
||||||
|
|
||||||
export class BaseCriterion {
|
export class BaseCriterion {
|
||||||
|
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
@ -16,4 +18,29 @@ export class BaseCriterion {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNewTargetNumbers(data) {
|
||||||
|
const { options } = this;
|
||||||
|
const baselineMeasurementNumbers = [];
|
||||||
|
const newTargetNumbers = new Set();
|
||||||
|
|
||||||
|
if (options.newTarget) {
|
||||||
|
_.each(data.targets, target => {
|
||||||
|
const { measurementNumber } = target.measurement;
|
||||||
|
if (target.timepoint.timepointType === 'baseline') {
|
||||||
|
baselineMeasurementNumbers.push(measurementNumber);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_.each(data.targets, target => {
|
||||||
|
const { measurementNumber } = target.measurement;
|
||||||
|
if (target.timepoint.timepointType === 'followup') {
|
||||||
|
if (!_.contains(baselineMeasurementNumbers, measurementNumber)) {
|
||||||
|
newTargetNumbers.add(measurementNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return newTargetNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { BaseCriterion } from './BaseCriterion';
|
|
||||||
import { _ } from 'meteor/underscore';
|
import { _ } from 'meteor/underscore';
|
||||||
|
import { BaseCriterion } from './BaseCriterion';
|
||||||
|
|
||||||
export const MaxTargetsSchema = {
|
export const MaxTargetsSchema = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
@ -8,26 +8,30 @@ export const MaxTargetsSchema = {
|
|||||||
label: 'Max targets allowed in study',
|
label: 'Max targets allowed in study',
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
minimum: 1
|
minimum: 1
|
||||||
|
},
|
||||||
|
newTarget: {
|
||||||
|
label: 'Flag to evaluate only new targets',
|
||||||
|
type: 'boolean'
|
||||||
|
},
|
||||||
|
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
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
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
|
|
||||||
},
|
|
||||||
required: ['limit']
|
required: ['limit']
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -35,6 +39,7 @@ export const MaxTargetsSchema = {
|
|||||||
* Check if the number of target measurements exceeded the limit allowed
|
* Check if the number of target measurements exceeded the limit allowed
|
||||||
* Options:
|
* Options:
|
||||||
* limit: Max targets allowed in study
|
* limit: Max targets allowed in study
|
||||||
|
* newTarget: Flag to evaluate only new targets (must be evaluated on both)
|
||||||
* locationIn: Filter to evaluate only measurements with the specified locations
|
* locationIn: Filter to evaluate only measurements with the specified locations
|
||||||
* locationNotIn: Filter to evaluate only measurements without the specified locations
|
* locationNotIn: Filter to evaluate only measurements without the specified locations
|
||||||
* message: Message to be displayed in case of nonconformity
|
* message: Message to be displayed in case of nonconformity
|
||||||
@ -47,17 +52,21 @@ export class MaxTargetsCriterion extends BaseCriterion {
|
|||||||
|
|
||||||
evaluate(data) {
|
evaluate(data) {
|
||||||
const { options } = this;
|
const { options } = this;
|
||||||
|
|
||||||
|
const newTargetNumbers = this.getNewTargetNumbers(data);
|
||||||
const measurementNumbers = [];
|
const measurementNumbers = [];
|
||||||
_.each(data.targets, target => {
|
_.each(data.targets, target => {
|
||||||
const { location } = target.measurement;
|
const { location, measurementNumber } = target.measurement;
|
||||||
|
if (options.newTarget && !newTargetNumbers.has(measurementNumber)) return;
|
||||||
if (options.locationIn && options.locationIn.indexOf(location) === -1) return;
|
if (options.locationIn && options.locationIn.indexOf(location) === -1) return;
|
||||||
if (options.locationNotIn && options.locationNotIn.indexOf(location) > -1) return;
|
if (options.locationNotIn && options.locationNotIn.indexOf(location) > -1) return;
|
||||||
measurementNumbers.push(target.measurement.measurementNumber);
|
measurementNumbers.push(measurementNumber);
|
||||||
});
|
});
|
||||||
|
|
||||||
let message = options.message;
|
let message;
|
||||||
if (!message && measurementNumbers.length > this.options.limit) {
|
if (measurementNumbers.length > this.options.limit) {
|
||||||
message = `The study should not have more than ${this.options.limit} targets.`;
|
const increment = options.newTarget ? 'new ' : '';
|
||||||
|
message = options.message || `The study should not have more than ${this.options.limit} ${increment}targets.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.generateResponse(message);
|
return this.generateResponse(message);
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { _ } from 'meteor/underscore';
|
||||||
import { BaseCriterion } from './BaseCriterion';
|
import { BaseCriterion } from './BaseCriterion';
|
||||||
|
|
||||||
export const MaxTargetsPerOrganSchema = {
|
export const MaxTargetsPerOrganSchema = {
|
||||||
@ -7,6 +8,10 @@ export const MaxTargetsPerOrganSchema = {
|
|||||||
label: 'Max targets allowed per organ',
|
label: 'Max targets allowed per organ',
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
minimum: 1
|
minimum: 1
|
||||||
|
},
|
||||||
|
newTarget: {
|
||||||
|
label: 'Flag to evaluate only new targets',
|
||||||
|
type: 'boolean'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
required: ['limit']
|
required: ['limit']
|
||||||
@ -17,6 +22,7 @@ export const MaxTargetsPerOrganSchema = {
|
|||||||
* Check if the number of target measurements per organ exceeded the limit allowed
|
* Check if the number of target measurements per organ exceeded the limit allowed
|
||||||
* Options:
|
* Options:
|
||||||
* limit: Max targets allowed in study
|
* limit: Max targets allowed in study
|
||||||
|
* newTarget: Flag to evaluate only new targets (must be evaluated on both)
|
||||||
*/
|
*/
|
||||||
export class MaxTargetsPerOrganCriterion extends BaseCriterion {
|
export class MaxTargetsPerOrganCriterion extends BaseCriterion {
|
||||||
|
|
||||||
@ -25,25 +31,31 @@ export class MaxTargetsPerOrganCriterion extends BaseCriterion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
evaluate(data) {
|
evaluate(data) {
|
||||||
|
const { options } = this;
|
||||||
const targetsPerOrgan = {};
|
const targetsPerOrgan = {};
|
||||||
let message;
|
|
||||||
let measurements = [];
|
let measurements = [];
|
||||||
|
|
||||||
for (let i = 0; i < data.targets.length; i++) {
|
const newTargetNumbers = this.getNewTargetNumbers(data);
|
||||||
const measurement = data.targets[i].measurement;
|
_.each(data.targets, target => {
|
||||||
|
const { measurement } = target;
|
||||||
const { location, measurementNumber } = measurement;
|
const { location, measurementNumber } = measurement;
|
||||||
if (!targetsPerOrgan[location]) {
|
if (!targetsPerOrgan[location]) {
|
||||||
targetsPerOrgan[location] = new Set();
|
targetsPerOrgan[location] = new Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
targetsPerOrgan[location].add(measurementNumber);
|
if (!options.newTarget || newTargetNumbers.has(measurementNumber)) {
|
||||||
if (targetsPerOrgan[location].size > this.options.limit) {
|
targetsPerOrgan[location].add(measurementNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetsPerOrgan[location].size > options.limit) {
|
||||||
measurements.push(measurement);
|
measurements.push(measurement);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
|
let message;
|
||||||
if (measurements.length) {
|
if (measurements.length) {
|
||||||
message = `Each organ should not have more than ${this.options.limit} targets.`;
|
const increment = options.newTarget ? 'new ' : '';
|
||||||
|
message = options.message || `Each organ should not have more than ${options.limit} ${increment}targets.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.generateResponse(message, measurements);
|
return this.generateResponse(message, measurements);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user