-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
212 lines (192 loc) · 8.07 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
import fs from "fs";
const {reviver} = require("./utilities");
const diseaseLookupText = fs.readFileSync("./data/diseaseLookup.json", {encoding: "utf-8"});
const targetLookupText = fs.readFileSync("./data/targetLookup.json", {encoding: "utf-8"});
const ligandLookupText = fs.readFileSync("./data/ligandLookup.json", {encoding: "utf-8"});
const diseaseLookup = JSON.parse(diseaseLookupText, reviver);
const targetLookup = JSON.parse(targetLookupText, reviver);
const ligandLookup = JSON.parse(ligandLookupText, reviver);
const diseaseArray = Array.from(diseaseLookup.values());
exports.handler = async (event: any) => {
let responseValue = [];
const params = event.queryStringParameters;
if (!params) {
return {
statusCode: 400,
body: 'No query provided.'
};
}
if (params.target) {
responseValue = getAndProcessData(params.target, targetLookup, formatDiseaseEntity);
addCitations(responseValue);
addStyle(responseValue, 'table');
} else if (params.disease) {
responseValue = getAndProcessData(params.disease, diseaseLookup, formatTargetEntity);
addCitations(responseValue);
addStyle(responseValue, 'card');
} else if (params.allTargets) {
responseValue = getAllData(targetLookup, formatDiseaseEntity);
} else if (params.allDiseases) {
responseValue = getAllData(diseaseLookup, formatTargetEntity);
}
return {
statusCode: 200,
body: JSON.stringify(responseValue)
};
};
function addCitations(responseValue: any[]) {
responseValue.forEach((resp: any) => {
if (resp && resp.predictions && resp.predictions.length > 0) {
addCitation(resp);
}
});
}
function addStyle(responseValue: any[], style: string) {
responseValue.forEach((resp: any) => {
if (resp && resp.predictions && resp.predictions.length > 0) {
resp.style = style;
}
})
}
const getAllData = function (lookupTable: any, extractMethod: any): any[] {
const response: any = [];
lookupTable.forEach((val: any, key: string) => {
response.push({
entity: key,
predictions: extractPredictions(val, extractMethod, false)
})
});
return response;
}
const getAndProcessData = function (entity: string, lookupTable: any, transform: any): any[] {
let entities: string | string[] = entity.split(',');
const response: any = [];
if (!Array.isArray(entities)) {
entities = [entities];
}
entities.forEach((oneEntity: any) => {
const rawData = lookupTable.get(oneEntity);
if (rawData) {
const val = JSON.parse(JSON.stringify(rawData));
response.push({predictions: extractPredictions(val, transform)});
}
});
return response;
}
const extractPredictions = function (response: any, predictionFormatFunction: any, includeConfidence = true) : any {
const predictions: any[] = [];
response.predictions.forEach((pred: any) => {
predictions.push(predictionFormatFunction(pred, includeConfidence));
});
return predictions;
}
const transformDiseasePredictions = function (response: any): void {
return response;
}
const transformLigandPredictions = function (response: any): void {
}
function findMeshID(pred: any) {
for (let disease of diseaseLookup) {
if (disease[1].source_name === pred.disease) {
return disease[0];
}
}
console.log(pred.disease);
return null;
}
function formatTargetEntity(pred: any, includeConfidence = true): any {
const ret: any = {
"@type": "Prediction",
name: "Predicted Kinase",
value: {
"@context": "https://schema.org",
"@type": "Protein",
name: pred.target
}
}
if (includeConfidence) {
ret.confidence = {
"@context": "https://schema.org",
"@type": "QuantitativeValue",
value: pred.probability,
alternateName: 'probability',
description: 'Measure of the relevance of inhibiting a particular protein kinase for a specific cancer',
maxValue: 1,
minValue: 0
};
}
return ret;
}
function formatDiseaseEntity(pred: any, includeConfidence = true): any {
const mesh_id = findMeshID(pred);
const ret: any = {
"@type": "Prediction",
name: "Predicted Cancer",
value: {
"@context": "https://schema.org",
"@type": "MedicalCondition",
name: pred.disease,
alternateName: "MESH:" + mesh_id
}
};
if (includeConfidence) {
ret.confidence = {
"@context": "https://schema.org",
"@type": "QuantitativeValue",
value: pred.probability,
alternateName: 'probability',
description: 'Measure of the relevance of inhibiting a particular protein kinase for a specific cancer',
maxValue: 1,
minValue: 0
}
}
return ret;
}
const transformPredictions = function(response: any, formatFunction: any): void {
let predictions: any = [];
response.predictions.forEach((pred: any) => {
predictions.push(formatFunction(pred));
});
response.predictions = predictions;
}
const addCitation = function (response: any): void {
response.citation = {
'@context': 'http://schema.org',
'@type': 'ScholarlyArticle',
name: 'Supervised learning with word embeddings derived from PubMed captures latent knowledge about protein kinases and cancer',
abstract: 'Inhibiting protein kinases (PKs) that cause cancers has been an important topic in cancer therapy for years. So far, almost 8% of >530 PKs have been targeted by FDA-approved medications, and around 150 protein kinase inhibitors (PKIs) have been tested in clinical trials. We present an approach based on natural language processing and machine learning to investigate the relations between PKs and cancers, predicting PKs whose inhibition would be efficacious to treat a certain cancer. Our approach represents PKs and cancers as semantically meaningful 100-dimensional vectors based on word and concept neighborhoods in PubMed abstracts. We use information about phase I-IV trials in ClinicalTrials.gov to construct a training set for random forest classification. Our results with historical data show that associations between PKs and specific cancers can be predicted years in advance with good accuracy. Our tool can be used to predict the relevance of inhibiting PKs for specific cancers and to support the design of well-focused clinical trials to discover novel PKIs for cancer therapy.',
url: 'https://pubmed.ncbi.nlm.nih.gov/34888523/',
author: [
{'@type': 'Person', name: 'Vida Ravanmehr'},
{'@type': 'Person', name: 'Hannah Blau'},
{'@type': 'Person', name: 'Luca Cappelletti'},
{'@type': 'Person', name: 'Tommaso Fontana'},
{'@type': 'Person', name: 'Leigh Carmody'},
{'@type': 'Person', name: 'Ben Coleman'},
{'@type': 'Person', name: 'Joshy George'},
{'@type': 'Person', name: 'Justin Reese'},
{'@type': 'Person', name: 'Marcin Joachimiak'},
{'@type': 'Person', name: 'Giovanni Bocci'},
{'@type': 'Person', name: 'Peter Hansen'},
{'@type': 'Person', name: 'Carol Bult'},
{'@type': 'Person', name: 'Jens Rueter'},
{'@type': 'Person', name: 'Elena Casiraghi'},
{'@type': 'Person', name: 'Giorgio Valentini'},
{'@type': 'Person', name: 'Christopher Mungall'},
{'@type': 'Person', name: 'Tudor I Oprea'},
{'@type': 'Person', name: 'Peter N Robinson'},
],
datePublished: '2021 Dec 8',
publisher: {
'@type': 'Organization',
name: 'NAR Genomics and Bioinformatics',
url: 'https://academic.oup.com/nargab'
},
identifier: {
'@type': 'PropertyValue',
name: 'PMID',
value: 34888523
},
creditText: 'Ravanmehr et al.'
}
}