Skip to content
This repository was archived by the owner on Aug 15, 2019. It is now read-only.

Commit a90cf4a

Browse files
igoroctavianodannyrb
authored andcommitted
feat(Criteria): Add is nodal option to criterias (#51)
1 parent ece884d commit a90cf4a

File tree

3 files changed

+53
-8
lines changed

3 files changed

+53
-8
lines changed

src/measurements/conformance/criteria/MaxTargets.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ export const MaxTargetsSchema = {
3232
minItems: 1,
3333
uniqueItems: true,
3434
},
35+
isNodal: {
36+
label: 'Filter to evaluate only nodal or extranodal measurements',
37+
type: 'boolean'
38+
},
39+
message: {
40+
label: 'Message to be displayed in case of nonconformity',
41+
type: 'string',
42+
}
3543
},
3644
required: ['limit'],
3745
};
@@ -43,6 +51,7 @@ export const MaxTargetsSchema = {
4351
* newTarget: Flag to evaluate only new targets (must be evaluated on both)
4452
* locationIn: Filter to evaluate only measurements with the specified locations
4553
* locationNotIn: Filter to evaluate only measurements without the specified locations
54+
* isNodal: Filter to evaluate only nodal or extranodal measurements
4655
* message: Message to be displayed in case of nonconformity
4756
*/
4857
export class MaxTargetsCriterion extends BaseCriterion {
@@ -56,24 +65,39 @@ export class MaxTargetsCriterion extends BaseCriterion {
5665
const newTargetNumbers = this.getNewTargetNumbers(data);
5766
const measurementNumbers = [];
5867
data.targets.forEach(target => {
59-
const { location, measurementNumber, isSplitLesion } = target.measurement;
60-
if (isSplitLesion) return;
61-
if (options.newTarget && !newTargetNumbers.has(measurementNumber)) return;
68+
const { location, measurementNumber, isSplitLesion, isNodal } = target.measurement;
69+
70+
if (isSplitLesion)
71+
return;
72+
73+
if (typeof isNodal === 'boolean' && typeof options.isNodal === 'boolean' && options.isNodal !== isNodal)
74+
return;
75+
76+
if (options.newTarget && !newTargetNumbers.has(measurementNumber))
77+
return;
78+
6279
if (options.locationIn && options.locationIn.indexOf(location) === -1)
6380
return;
81+
6482
if (options.locationNotIn && options.locationNotIn.indexOf(location) > -1)
6583
return;
84+
6685
measurementNumbers.push(measurementNumber);
6786
});
6887

88+
let lesionType = '';
89+
if (typeof options.isNodal === 'boolean') {
90+
lesionType = options.isNodal ? 'nodal ' : 'extranodal ';
91+
}
92+
6993
let message;
7094
if (measurementNumbers.length > options.limit) {
7195
const increment = options.newTarget ? 'new ' : '';
7296
const plural = options.limit === 1 ? '' : 's';
7397
const amount = options.limit === 0 ? '' : `more than ${options.limit}`;
7498
message =
7599
options.message ||
76-
`The study should not have ${amount} ${increment}target${plural}.`;
100+
`The study should not have ${amount} ${increment}${lesionType}target${plural}.`;
77101
}
78102

79103
return this.generateResponse(message);

src/measurements/conformance/criteria/MaxTargetsPerOrgan.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ export const MaxTargetsPerOrganSchema = {
1212
label: 'Flag to evaluate only new targets',
1313
type: 'boolean',
1414
},
15+
isNodal: {
16+
label: 'Filter to evaluate only nodal or extranodal measurements',
17+
type: 'boolean'
18+
},
19+
message: {
20+
label: 'Message to be displayed in case of nonconformity',
21+
type: 'string',
22+
}
1523
},
1624
required: ['limit'],
1725
};
@@ -22,6 +30,8 @@ export const MaxTargetsPerOrganSchema = {
2230
* Options:
2331
* limit: Max targets allowed in study
2432
* newTarget: Flag to evaluate only new targets (must be evaluated on both)
33+
* isNodal: Filter to evaluate only nodal or extranodal measurements
34+
* message: Message to be displayed in case of nonconformity
2535
*/
2636
export class MaxTargetsPerOrganCriterion extends BaseCriterion {
2737
constructor(...props) {
@@ -36,9 +46,13 @@ export class MaxTargetsPerOrganCriterion extends BaseCriterion {
3646
const newTargetNumbers = this.getNewTargetNumbers(data);
3747
data.targets.forEach(target => {
3848
const { measurement } = target;
39-
const { location, measurementNumber, isSplitLesion } = measurement;
49+
const { location, measurementNumber, isSplitLesion, isNodal } = measurement;
50+
51+
if (isSplitLesion)
52+
return;
4053

41-
if (isSplitLesion) return;
54+
if (typeof isNodal === 'boolean' && typeof options.isNodal === 'boolean' && options.isNodal !== isNodal)
55+
return;
4256

4357
if (!targetsPerOrgan[location]) {
4458
targetsPerOrgan[location] = new Set();
@@ -59,7 +73,7 @@ export class MaxTargetsPerOrganCriterion extends BaseCriterion {
5973
message =
6074
options.message ||
6175
`Each organ should not have more than ${
62-
options.limit
76+
options.limit
6377
} ${increment}targets.`;
6478
}
6579

src/measurements/conformance/criteria/MeasurementsLength.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ export const MeasurementsLengthSchema = {
6363
minItems: 1,
6464
uniqueItems: true,
6565
},
66+
isNodal: {
67+
label: 'Filter to evaluate only nodal or extranodal measurements',
68+
type: 'boolean'
69+
},
6670
message: {
6771
label: 'Message to be displayed in case of nonconformity',
6872
type: 'string',
@@ -89,6 +93,7 @@ export const MeasurementsLengthSchema = {
8993
* modalityNotIn: Filter to evaluate only measurements without the specified modalities
9094
* locationIn: Filter to evaluate only measurements with the specified locations
9195
* locationNotIn: Filter to evaluate only measurements without the specified locations
96+
* isNodal: Filter to evaluate only nodal or extranodal measurements
9297
* message: Message to be displayed in case of nonconformity
9398
*/
9499
export class MeasurementsLengthCriterion extends BaseCriterion {
@@ -107,7 +112,7 @@ export class MeasurementsLengthCriterion extends BaseCriterion {
107112
const { metadata, measurement } = item;
108113
const { location } = measurement;
109114

110-
let { longestDiameter, shortestDiameter } = measurement;
115+
let { longestDiameter, shortestDiameter, isNodal } = measurement;
111116
if (measurement.childToolsCount) {
112117
const child = measurement.bidirectional;
113118
longestDiameter = (child && child.longestDiameter) || 0;
@@ -118,6 +123,8 @@ export class MeasurementsLengthCriterion extends BaseCriterion {
118123
const modality = (metadata.getRawValue('x00080060') || '').toUpperCase();
119124

120125
// Stop here if the measurement does not match the modality and location filters
126+
if (typeof isNodal === 'boolean' && typeof options.isNodal === 'boolean' && options.isNodal !== isNodal)
127+
return;
121128
if (options.locationIn && options.locationIn.indexOf(location) === -1)
122129
return;
123130
if (options.modalityIn && options.modalityIn.indexOf(modality) === -1)

0 commit comments

Comments
 (0)