Skip to content

Commit 8dae5e0

Browse files
Merge pull request #38 from bcgsc/feature/KBDEV-1399-clinicaltrial-statement-display
Feature/kbdev 1399 clinicaltrial statement display
2 parents 6ca5607 + 23e4b08 commit 8dae5e0

File tree

3 files changed

+135
-71
lines changed

3 files changed

+135
-71
lines changed

src/sentenceTemplates.ts

Lines changed: 78 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const TEMPLATE_KEYS = {
99
conditions: '{conditions}',
1010
subject: '{subject}',
1111
evidence: '{evidence}',
12+
evidenceSourceId: '{evidenceSourceId}',
1213
relevance: '{relevance}',
1314
evidenceLevel: '{evidenceLevel}',
1415
preclinicalWarning: '{preclinicalWarning}',
@@ -35,21 +36,24 @@ const DEFAULT_TEMPLATE = `Given ${
3536
* - evidences
3637
* - evidence levels
3738
*
38-
* @param {string} template string
39-
* @param {object} record statement record
40-
* @param {object} [keys=TEMPLATE_KEYS] template key-value pairs
39+
* @param {boolean} [opt.evidenceSourceId=false] whether evidenceSourceId is used instead of evidence
40+
* @param {object} [opt.keys=TEMPLATE_KEYS] template key-value pairs
41+
* @param {object} opt.ecord statement record
42+
* @param {string} opt.template string
4143
*
4244
* @returns the updated template string
4345
*/
44-
const addEvidence = (
45-
template: string,
46-
record: StatementRecord,
46+
const addEvidence = ({
47+
evidenceSourceId = false,
4748
keys = TEMPLATE_KEYS,
48-
) => {
49+
record,
50+
template,
51+
}) => {
4952
// remove preexisting evidence info, if any, e.g. from default template
5053
let updated = template
5154
.replace(` (${keys.evidenceLevel})`, '')
5255
.replace(` (${keys.evidence})`, '')
56+
.replace(` (${keys.evidenceSourceId})`, '')
5357
.replace(` ${keys.preclinicalWarning}`, '');
5458

5559
// preclinical warning
@@ -69,7 +73,11 @@ const addEvidence = (
6973
}
7074

7175
// evidences
72-
updated += ` (${keys.evidence})`;
76+
if (evidenceSourceId) {
77+
updated += ` (${keys.evidenceSourceId})`;
78+
} else {
79+
updated += ` (${keys.evidence})`;
80+
}
7381

7482
// evidence levels
7583
if (record.evidenceLevel) {
@@ -102,49 +110,49 @@ const chooseDefaultTemplate = (record: StatementRecord, keys = TEMPLATE_KEYS) =>
102110
: '';
103111

104112
if (hasDisease && hasVariant && relevance === 'recurrent') {
105-
return addEvidence(
106-
`${multiVariant}${keys.variant} is ${keys.relevance} in ${keys.disease}`,
113+
return addEvidence({
114+
template: `${multiVariant}${keys.variant} is ${keys.relevance} in ${keys.disease}`,
107115
record,
108-
);
116+
});
109117
}
110118
if (
111119
subjectType === 'disease'
112120
&& hasVariant
113121
) {
114122
if (relevance === 'diagnostic indicator') {
115-
return addEvidence(
116-
`${multiVariant}${keys.variant} is ${vowel || 'a'} ${keys.relevance} of ${keys.subject}`,
123+
return addEvidence({
124+
template: `${multiVariant}${keys.variant} is ${vowel || 'a'} ${keys.relevance} of ${keys.subject}`,
117125
record,
118-
);
126+
});
119127
}
120128
if (relevance.includes('diagnos')) {
121-
return addEvidence(
122-
`${multiVariant}${keys.variant} ${keys.relevance} of ${keys.subject}`,
129+
return addEvidence({
130+
template: `${multiVariant}${keys.variant} ${keys.relevance} of ${keys.subject}`,
123131
record,
124-
);
132+
});
125133
}
126134
if (relevance.includes('predisposing')) {
127-
return addEvidence(
128-
`${multiVariant}${keys.variant} is ${keys.relevance} to ${keys.subject}`,
135+
return addEvidence({
136+
template: `${multiVariant}${keys.variant} is ${keys.relevance} to ${keys.subject}`,
129137
record,
130-
);
138+
});
131139
}
132140
if (relevance === 'mutation hotspot') {
133-
return addEvidence(
134-
`${keys.variant} is ${vowel || 'a'} ${keys.relevance} in ${keys.subject}`,
141+
return addEvidence({
142+
template: `${keys.variant} is ${vowel || 'a'} ${keys.relevance} in ${keys.subject}`,
135143
record,
136-
);
144+
});
137145
}
138146
if (relevance === 'tumourigenesis') {
139-
return addEvidence(
140-
`${multiVariant}${keys.variant} contributes to ${keys.relevance} of ${keys.subject}`,
147+
return addEvidence({
148+
template: `${multiVariant}${keys.variant} contributes to ${keys.relevance} of ${keys.subject}`,
141149
record,
142-
);
150+
});
143151
}
144-
return addEvidence(
145-
`${multiVariant}${keys.variant} is ${keys.relevance} in ${keys.subject}`,
152+
return addEvidence({
153+
template: `${multiVariant}${keys.variant} is ${keys.relevance} in ${keys.subject}`,
146154
record,
147-
);
155+
});
148156
}
149157

150158
if (subjectType === 'feature' || subjectType.endsWith('variant')) {
@@ -153,15 +161,15 @@ const chooseDefaultTemplate = (record: StatementRecord, keys = TEMPLATE_KEYS) =>
153161

154162
if (isFunctional && hasVariant) {
155163
if (!hasDisease) {
156-
return addEvidence(
157-
`${keys.variant} results in ${keys.relevance} of ${keys.subject}`,
164+
return addEvidence({
165+
template: `${keys.variant} results in ${keys.relevance} of ${keys.subject}`,
158166
record,
159-
);
167+
});
160168
}
161-
return addEvidence(
162-
`${keys.variant} results in ${keys.relevance} of ${keys.subject} in ${keys.disease}`,
169+
return addEvidence({
170+
template: `${keys.variant} results in ${keys.relevance} of ${keys.subject} in ${keys.disease}`,
163171
record,
164-
);
172+
});
165173
}
166174
let article = '';
167175

@@ -172,28 +180,28 @@ const chooseDefaultTemplate = (record: StatementRecord, keys = TEMPLATE_KEYS) =>
172180
}
173181

174182
if (!hasDisease) {
175-
return addEvidence(
176-
`${keys.subject} is ${article}${keys.relevance}`,
183+
return addEvidence({
184+
template: `${keys.subject} is ${article}${keys.relevance}`,
177185
record,
178-
);
186+
});
179187
}
180-
return addEvidence(
181-
`${keys.subject} is ${article}${keys.relevance} in ${keys.disease}`,
188+
return addEvidence({
189+
template: `${keys.subject} is ${article}${keys.relevance} in ${keys.disease}`,
182190
record,
183-
);
191+
});
184192
}
185193

186194
if (subjectType === 'therapy' && hasVariant) {
187195
if (hasDisease) {
188-
return addEvidence(
189-
`${multiVariant}${keys.variant} is associated with ${keys.relevance} to ${keys.subject} in ${keys.disease}`,
196+
return addEvidence({
197+
template: `${multiVariant}${keys.variant} is associated with ${keys.relevance} to ${keys.subject} in ${keys.disease}`,
190198
record,
191-
);
199+
});
192200
}
193-
return addEvidence(
194-
`${multiVariant}${keys.variant} is associated with ${keys.relevance} to ${keys.subject}`,
201+
return addEvidence({
202+
template: `${multiVariant}${keys.variant} is associated with ${keys.relevance} to ${keys.subject}`,
195203
record,
196-
);
204+
});
197205
}
198206

199207
// prognostic statements
@@ -209,40 +217,42 @@ const chooseDefaultTemplate = (record: StatementRecord, keys = TEMPLATE_KEYS) =>
209217
if (hasDisease) {
210218
template += ` in ${keys.disease}`;
211219
}
212-
return addEvidence(
220+
return addEvidence({
213221
template,
214222
record,
215-
);
223+
});
216224
}
217225
}
218226

219227
// eligibility to clinical trials statements
220228
if (hasVariant && relevance === 'eligibility' && subjectType === 'clinicaltrial') {
221229
if (hasDisease) {
222-
return addEvidence(
223-
`Patients with ${multiVariant}${keys.variant} in ${keys.disease} are eligible for ${keys.subject}`,
230+
return addEvidence({
231+
template: `Patients with ${multiVariant}${keys.variant} in ${keys.disease} are eligible for ${keys.subject}`,
224232
record,
225-
);
233+
evidenceSourceId: true,
234+
});
226235
}
227-
return addEvidence(
228-
`Patients with ${multiVariant}${keys.variant} are eligible for ${keys.subject}`,
236+
return addEvidence({
237+
template: `Patients with ${multiVariant}${keys.variant} are eligible for ${keys.subject}`,
229238
record,
230-
);
239+
evidenceSourceId: true,
240+
});
231241
}
232242

233243
// default for a single conditions class statement
234244
if (conditionTypes.length === 1) {
235-
return addEvidence(
236-
`${keys.subject} is ${keys.relevance}`,
245+
return addEvidence({
246+
template: `${keys.subject} is ${keys.relevance}`,
237247
record,
238-
);
248+
});
239249
}
240250

241251
// default
242-
return addEvidence(
243-
DEFAULT_TEMPLATE,
252+
return addEvidence({
253+
template: DEFAULT_TEMPLATE,
244254
record,
245-
);
255+
});
246256
};
247257

248258
/**
@@ -349,6 +359,13 @@ const generateStatementSentence = (
349359
substitutions[keys.evidence] = naturalListJoin(words);
350360
}
351361

362+
// add the evidence's sourceId (for clinical trials eligibility; KBDEV-1399)
363+
if (replacementsFound.includes(keys.evidenceSourceId) && record.evidence && record.evidence.length) {
364+
const words = record.evidence.map((e) => previewFunc({ ...e, displayName: e.sourceId }));
365+
highlighted.push(...words);
366+
substitutions[keys.evidenceSourceId] = naturalListJoin(words);
367+
}
368+
352369
// add the evidence level
353370
if (
354371
replacementsFound.includes(keys.evidenceLevel)

test/sentenceTemplates.test.ts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -289,16 +289,16 @@ describe('generateStatementSentence', () => {
289289

290290
test('patient with variant in diesase is eligible for trial', () => {
291291
const key = 'subject:ClinicalTrial|conditions:CategoryVariant;ClinicalTrial;Disease|relevance:eligibility';
292-
const result = 'Patients with CD274 increased rna expression in osteosarcoma [DOID:3347] are eligible for NCT02879162';
292+
const result = 'Patients with CD274 increased rna expression in osteosarcoma [DOID:3347] are eligible for NCT02879162 (NCT02879162)';
293293
const { content } = generateStatementSentence(previewFunction, examples[key]);
294-
expect(content.replace(' ({evidence})', '')).toEqual(result);
294+
expect(content).toEqual(result);
295295
});
296296

297297
test('patient with variant is eligible for trial', () => {
298298
const key = 'subject:ClinicalTrial|conditions:ClinicalTrial;PositionalVariant|relevance:eligibility';
299299
const { content } = generateStatementSentence(previewFunction, examples[key]);
300-
const result = 'Patients with ERBB2:p.L755S are eligible for NCT02155621';
301-
expect(content.replace(' ({evidence})', '')).toEqual(result);
300+
const result = 'Patients with ERBB2:p.L755S are eligible for NCT02155621 (NCT02155621 and NCT02155622)';
301+
expect(content).toEqual(result);
302302
});
303303

304304
test('partial content', () => {
@@ -340,24 +340,49 @@ describe('generateStatementSentence', () => {
340340

341341
describe('addEvidence', () => {
342342
test('evidence', () => {
343-
const updatedTemplate = addEvidence(DEFAULT_TEMPLATE, examples['evidence']);
343+
const updatedTemplate = addEvidence({
344+
template: DEFAULT_TEMPLATE,
345+
record: examples.evidence,
346+
});
344347
const expected = 'Given {conditions}, {relevance} applies to {subject} ({evidence})'
345348
expect(updatedTemplate).toEqual(expected);
346349
});
350+
351+
test('evidenceSourceId', () => {
352+
const updatedTemplate = addEvidence({
353+
template: DEFAULT_TEMPLATE,
354+
record: examples.evidence, // works just fine as example's data for evidenceSourceId
355+
evidenceSourceId: true,
356+
});
357+
const expected = 'Given {conditions}, {relevance} applies to {subject} ({evidenceSourceId})'
358+
expect(updatedTemplate).toEqual(expected);
359+
});
360+
347361
test('evidenceLevel', () => {
348-
const updatedTemplate = addEvidence(DEFAULT_TEMPLATE, examples['evidenceLevel']);
362+
const updatedTemplate = addEvidence({
363+
template: DEFAULT_TEMPLATE,
364+
record: examples.evidenceLevel,
365+
});
349366
const expected = 'Given {conditions}, {relevance} applies to {subject} ({evidence}) ({evidenceLevel})'
350367
expect(updatedTemplate).toEqual(expected);
351368
});
369+
352370
test('preclinical warning', () => {
353-
const updatedTemplate = addEvidence(DEFAULT_TEMPLATE, examples['preclinicalWarning']);
371+
const updatedTemplate = addEvidence({
372+
template: DEFAULT_TEMPLATE,
373+
record: examples.preclinicalWarning,
374+
});
354375
const expected = 'Given {conditions}, {relevance} applies to {subject} {preclinicalWarning} ({evidence}) ({evidenceLevel})'
355376
expect(updatedTemplate).toEqual(expected);
356377
});
378+
357379
test('remove preexisting evidence info', () => {
358-
const template = '... {preclinicalWarning} ({evidence}) ({evidenceLevel})'
359-
const updatedTemplate = addEvidence(template, examples['evidence']);
380+
const template = '... {preclinicalWarning} ({evidence}) ({evidenceSourceId}) ({evidenceLevel})'
381+
const updatedTemplate = addEvidence({
382+
template,
383+
record: examples.evidence,
384+
});
360385
const expected = '... ({evidence})'
361386
expect(updatedTemplate).toEqual(expected);
362387
});
363-
});
388+
});

test/testData/statementExamples.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,20 @@
871871
"@rid": "#109:0"
872872
}
873873
],
874+
"evidence": [
875+
{
876+
"@rid": "#123:45",
877+
"@class": "Publication",
878+
"displayName": "pmid:12345678",
879+
"sourceId": "NCT02155621"
880+
},
881+
{
882+
"@rid": "#123:46",
883+
"@class": "Publication",
884+
"displayName": "pmid:12345679",
885+
"sourceId": "NCT02155622"
886+
}
887+
],
874888
"subject": {
875889
"displayName": "NCT02155621",
876890
"@class": "ClinicalTrial",
@@ -1761,6 +1775,14 @@
17611775
"@rid": "#110:6"
17621776
}
17631777
],
1778+
"evidence": [
1779+
{
1780+
"@rid": "#123:45",
1781+
"@class": "Publication",
1782+
"displayName": "pmid:12345678",
1783+
"sourceId": "NCT02879162"
1784+
}
1785+
],
17641786
"subject": {
17651787
"displayName": "NCT02879162",
17661788
"@class": "ClinicalTrial",

0 commit comments

Comments
 (0)