@sjcrh/proteinpaint-server 2.142.0 → 2.143.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dataset/protected.test.js +1 -2
- package/dataset/termdb.test.js +3 -2
- package/package.json +9 -8
- package/routes/aiProjectAdmin.js +46 -60
- package/routes/aiProjectSelectedWSImages.js +161 -0
- package/routes/brainImaging.js +9 -18
- package/routes/brainImagingSamples.js +2 -4
- package/routes/burden.js +13 -26
- package/routes/correlationVolcano.js +18 -36
- package/routes/dataset.js +6 -12
- package/routes/deleteWSIAnnotation.js +75 -0
- package/routes/dsdata.js +7 -14
- package/routes/dzimages.js +4 -8
- package/routes/gdc.grin2.list.js +13 -26
- package/routes/gdc.grin2.run.js +3 -6
- package/routes/gdc.maf.js +8 -16
- package/routes/gdc.mafBuild.js +14 -28
- package/routes/gene2canonicalisoform.js +4 -8
- package/routes/genelookup.js +2 -4
- package/routes/genesetEnrichment.js +6 -12
- package/routes/genesetOverrepresentation.js +1 -2
- package/routes/genomes.js +1 -2
- package/routes/grin2.js +13 -17
- package/routes/healthcheck.js +3 -6
- package/routes/hicdata.js +4 -8
- package/routes/hicgenome.js +4 -8
- package/routes/hicstat.js +2 -4
- package/routes/img.js +1 -2
- package/routes/isoformlst.js +6 -12
- package/routes/ntseq.js +4 -8
- package/routes/pdomain.js +5 -10
- package/routes/sampledzimages.js +2 -4
- package/routes/samplewsimages.js +3 -67
- package/routes/saveWSIAnnotation.js +100 -0
- package/routes/snp.js +9 -18
- package/routes/termdb.DE.js +23 -46
- package/routes/termdb.boxplot.js +84 -84
- package/routes/termdb.categories.js +9 -18
- package/routes/termdb.cluster.js +23 -46
- package/routes/termdb.cohort.summary.js +3 -6
- package/routes/termdb.cohorts.js +4 -8
- package/routes/termdb.config.js +32 -64
- package/routes/termdb.descrstats.js +6 -12
- package/routes/termdb.filterTermValues.js +4 -8
- package/routes/termdb.numericcategories.js +5 -10
- package/routes/termdb.percentile.js +6 -12
- package/routes/termdb.profileFormScores.js +12 -24
- package/routes/termdb.profileScores.js +7 -14
- package/routes/termdb.rootterm.js +4 -8
- package/routes/termdb.sampleImages.js +4 -8
- package/routes/termdb.singleSampleMutation.js +9 -18
- package/routes/termdb.singlecellDEgenes.js +4 -8
- package/routes/termdb.singlecellData.js +4 -8
- package/routes/termdb.singlecellSamples.js +28 -56
- package/routes/termdb.termchildren.js +5 -10
- package/routes/termdb.termsbyids.js +4 -8
- package/routes/termdb.topMutatedGenes.js +15 -30
- package/routes/termdb.topTermsByType.js +9 -18
- package/routes/termdb.topVariablyExpressedGenes.js +13 -26
- package/routes/termdb.violin.js +124 -135
- package/routes/tileserver.js +14 -15
- package/routes/wsimages.js +42 -46
- package/routes/wsisamples.js +3 -6
- package/src/app.js +4345 -6708
- package/routes/sampleWsiAiApi.js +0 -33
|
@@ -28,17 +28,13 @@ function init({ genomes }) {
|
|
|
28
28
|
let result;
|
|
29
29
|
try {
|
|
30
30
|
const g = genomes[q.genome];
|
|
31
|
-
if (!g)
|
|
32
|
-
throw "invalid genome name";
|
|
31
|
+
if (!g) throw "invalid genome name";
|
|
33
32
|
const ds = g.datasets[q.dslabel];
|
|
34
|
-
if (!ds)
|
|
35
|
-
|
|
36
|
-
if (!ds.queries?.singleCell)
|
|
37
|
-
throw "no singlecell data on this dataset";
|
|
33
|
+
if (!ds) throw "invalid dataset name";
|
|
34
|
+
if (!ds.queries?.singleCell) throw "no singlecell data on this dataset";
|
|
38
35
|
result = await ds.queries.singleCell.samples.get(q);
|
|
39
36
|
} catch (e) {
|
|
40
|
-
if (e.stack)
|
|
41
|
-
console.log(e.stack);
|
|
37
|
+
if (e.stack) console.log(e.stack);
|
|
42
38
|
result = {
|
|
43
39
|
status: e.status || 400,
|
|
44
40
|
error: e.message || e
|
|
@@ -49,16 +45,13 @@ function init({ genomes }) {
|
|
|
49
45
|
}
|
|
50
46
|
async function validate_query_singleCell(ds, genome) {
|
|
51
47
|
const q = ds.queries.singleCell;
|
|
52
|
-
if (!q)
|
|
53
|
-
|
|
54
|
-
if (typeof q.samples != "object")
|
|
55
|
-
throw "singleCell.samples{} not object";
|
|
48
|
+
if (!q) return;
|
|
49
|
+
if (typeof q.samples != "object") throw "singleCell.samples{} not object";
|
|
56
50
|
if (typeof q.samples.get == "function") {
|
|
57
51
|
} else {
|
|
58
52
|
await validateSamplesNative(q.samples, q.data, ds);
|
|
59
53
|
}
|
|
60
|
-
if (typeof q.data != "object")
|
|
61
|
-
throw "singleCell.data{} not object";
|
|
54
|
+
if (typeof q.data != "object") throw "singleCell.data{} not object";
|
|
62
55
|
if (q.data.src == "gdcapi") {
|
|
63
56
|
gdc_validate_query_singleCell_data(ds, genome);
|
|
64
57
|
} else if (q.data.src == "native") {
|
|
@@ -67,8 +60,7 @@ async function validate_query_singleCell(ds, genome) {
|
|
|
67
60
|
throw "unknown singleCell.data.src";
|
|
68
61
|
}
|
|
69
62
|
if (q.geneExpression) {
|
|
70
|
-
if (typeof q.geneExpression != "object")
|
|
71
|
-
throw "singleCell.geneExpression not object";
|
|
63
|
+
if (typeof q.geneExpression != "object") throw "singleCell.geneExpression not object";
|
|
72
64
|
if (q.geneExpression.src == "native") {
|
|
73
65
|
validateGeneExpressionNative(q.geneExpression);
|
|
74
66
|
} else if (q.geneExpression.src == "gdcapi") {
|
|
@@ -78,23 +70,18 @@ async function validate_query_singleCell(ds, genome) {
|
|
|
78
70
|
}
|
|
79
71
|
}
|
|
80
72
|
if (q.DEgenes) {
|
|
81
|
-
if (typeof q.DEgenes != "object")
|
|
82
|
-
throw "singleCell.DEgenes not object";
|
|
73
|
+
if (typeof q.DEgenes != "object") throw "singleCell.DEgenes not object";
|
|
83
74
|
validate_query_singleCell_DEgenes(ds);
|
|
84
75
|
}
|
|
85
76
|
if (q.images) {
|
|
86
|
-
if (typeof q.images != "object")
|
|
87
|
-
throw "singleCell.images not object";
|
|
77
|
+
if (typeof q.images != "object") throw "singleCell.images not object";
|
|
88
78
|
validateImages(q.images);
|
|
89
79
|
}
|
|
90
80
|
}
|
|
91
81
|
function validateImages(images) {
|
|
92
|
-
if (!images.folder)
|
|
93
|
-
|
|
94
|
-
if (!images.
|
|
95
|
-
images.label = "Images";
|
|
96
|
-
if (!images.fileName)
|
|
97
|
-
throw "images.fileName missing";
|
|
82
|
+
if (!images.folder) throw "images.folder missing";
|
|
83
|
+
if (!images.label) images.label = "Images";
|
|
84
|
+
if (!images.fileName) throw "images.fileName missing";
|
|
98
85
|
}
|
|
99
86
|
async function validateSamplesNative(S, D, ds) {
|
|
100
87
|
const samples = /* @__PURE__ */ new Map();
|
|
@@ -106,23 +93,19 @@ async function validateSamplesNative(S, D, ds) {
|
|
|
106
93
|
throw `singlecell.sample file name ${fn} does not end with required suffix ${plot.fileSuffix}`;
|
|
107
94
|
sampleName = fn.split(plot.fileSuffix)[0];
|
|
108
95
|
}
|
|
109
|
-
if (!sampleName)
|
|
110
|
-
throw `singlecell.sample: cannot derive sample name from file name ${fn}`;
|
|
96
|
+
if (!sampleName) throw `singlecell.sample: cannot derive sample name from file name ${fn}`;
|
|
111
97
|
const sid = ds.cohort.termdb.q.sampleName2id(sampleName);
|
|
112
|
-
if (sid == void 0)
|
|
113
|
-
throw `singlecell.sample: unknown sample name ${sampleName}`;
|
|
98
|
+
if (sid == void 0) throw `singlecell.sample: unknown sample name ${sampleName}`;
|
|
114
99
|
samples.set(sid, { sample: sampleName });
|
|
115
100
|
}
|
|
116
101
|
}
|
|
117
102
|
if (S.sampleColumns) {
|
|
118
103
|
for (const { termid } of S.sampleColumns) {
|
|
119
104
|
const term = ds.cohort.termdb.q.termjsonByOneid(termid);
|
|
120
|
-
if (!term)
|
|
121
|
-
throw "unknown termid from singlecell.samples.sampleColumns[]";
|
|
105
|
+
if (!term) throw "unknown termid from singlecell.samples.sampleColumns[]";
|
|
122
106
|
const s2v = ds.cohort.termdb.q.getAllValues4term(termid);
|
|
123
107
|
for (const [sid, v] of s2v.entries()) {
|
|
124
|
-
if (!samples.has(sid))
|
|
125
|
-
continue;
|
|
108
|
+
if (!samples.has(sid)) continue;
|
|
126
109
|
samples.get(sid)[termid] = term.values?.[v]?.label || v;
|
|
127
110
|
}
|
|
128
111
|
}
|
|
@@ -134,11 +117,9 @@ async function validateSamplesNative(S, D, ds) {
|
|
|
134
117
|
function validateDataNative(D, ds) {
|
|
135
118
|
const nameSet = /* @__PURE__ */ new Set();
|
|
136
119
|
for (const plot of D.plots) {
|
|
137
|
-
if (nameSet.has(plot.name))
|
|
138
|
-
throw "duplicate plot.name";
|
|
120
|
+
if (nameSet.has(plot.name)) throw "duplicate plot.name";
|
|
139
121
|
nameSet.add(plot.name);
|
|
140
|
-
if (!plot.folder)
|
|
141
|
-
throw "plot.folder missing";
|
|
122
|
+
if (!plot.folder) throw "plot.folder missing";
|
|
142
123
|
}
|
|
143
124
|
const file2Lines = {};
|
|
144
125
|
D.get = async (q) => {
|
|
@@ -148,8 +129,7 @@ function validateDataNative(D, ds) {
|
|
|
148
129
|
geneExpMap = await ds.queries.singleCell.geneExpression.get({ sample: q.sample, gene: q.gene });
|
|
149
130
|
}
|
|
150
131
|
for (const plot of D.plots) {
|
|
151
|
-
if (!q.plots.includes(plot.name))
|
|
152
|
-
continue;
|
|
132
|
+
if (!q.plots.includes(plot.name)) continue;
|
|
153
133
|
const tsvfile = path.join(serverconfig.tpmasterdir, plot.folder, (q.sample.eID || q.sample.sID) + plot.fileSuffix);
|
|
154
134
|
if (!file2Lines[tsvfile]) {
|
|
155
135
|
await file_is_readable(tsvfile);
|
|
@@ -172,10 +152,8 @@ function validateDataNative(D, ds) {
|
|
|
172
152
|
for (const l of file2Lines[tsvfile]) {
|
|
173
153
|
const cellId = l[0], x = Number(l[plot.coordsColumns.x]), y = Number(l[plot.coordsColumns.y]);
|
|
174
154
|
const category = l[colorColumn?.index] || "";
|
|
175
|
-
if (!cellId)
|
|
176
|
-
|
|
177
|
-
if (!Number.isFinite(x) || !Number.isFinite(y))
|
|
178
|
-
throw "x/y not number";
|
|
155
|
+
if (!cellId) throw "cell id missing";
|
|
156
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) throw "x/y not number";
|
|
179
157
|
const cell = { cellId, x, y, category };
|
|
180
158
|
if (geneExpMap) {
|
|
181
159
|
if (geneExpMap[cellId] !== void 0) {
|
|
@@ -184,8 +162,7 @@ function validateDataNative(D, ds) {
|
|
|
184
162
|
} else {
|
|
185
163
|
noExpCells.push(cell);
|
|
186
164
|
}
|
|
187
|
-
} else
|
|
188
|
-
noExpCells.push(cell);
|
|
165
|
+
} else noExpCells.push(cell);
|
|
189
166
|
}
|
|
190
167
|
plots.push({
|
|
191
168
|
name: plot.name,
|
|
@@ -223,8 +200,7 @@ function validateGeneExpressionNative(G) {
|
|
|
223
200
|
} catch (e) {
|
|
224
201
|
if (typeof e == "string") {
|
|
225
202
|
const geneNotFound = `Gene '${q.gene}' not found in the HDF5 file`;
|
|
226
|
-
if (e.includes(geneNotFound))
|
|
227
|
-
throw "No expression data for this gene";
|
|
203
|
+
if (e.includes(geneNotFound)) throw "No expression data for this gene";
|
|
228
204
|
}
|
|
229
205
|
console.log(e);
|
|
230
206
|
throw "error reading h5 file: " + e;
|
|
@@ -241,12 +217,10 @@ function gdc_validateGeneExpression(G, ds, genome) {
|
|
|
241
217
|
throw "GDC scRNA file mapping is not cached";
|
|
242
218
|
}
|
|
243
219
|
const hdf5id = ds.__gdc.scrnaAnalysis2hdf5.get(fileid);
|
|
244
|
-
if (!hdf5id)
|
|
245
|
-
throw "cannot map eID to hdf5 id";
|
|
220
|
+
if (!hdf5id) throw "cannot map eID to hdf5 id";
|
|
246
221
|
const aliasLst = genome.genedb.getAliasByName.all(q.gene);
|
|
247
222
|
const gencodeId = aliasLst.find((a) => a?.alias.toUpperCase().startsWith("ENSG"))?.alias;
|
|
248
|
-
if (!gencodeId)
|
|
249
|
-
throw "cannot map gene symbol to GENCODE";
|
|
223
|
+
if (!gencodeId) throw "cannot map gene symbol to GENCODE";
|
|
250
224
|
const body = {
|
|
251
225
|
gene_ids: [gencodeId],
|
|
252
226
|
file_id: hdf5id
|
|
@@ -254,8 +228,7 @@ function gdc_validateGeneExpression(G, ds, genome) {
|
|
|
254
228
|
const { host } = ds.getHostHeaders(q);
|
|
255
229
|
const t = Date.now();
|
|
256
230
|
const response = await ky.post(joinUrl(host.rest, "scrna_seq/gene_expression"), { timeout: false, json: body });
|
|
257
|
-
if (!response.ok)
|
|
258
|
-
throw `HTTP Error: ${response.status} ${response.statusText}`;
|
|
231
|
+
if (!response.ok) throw `HTTP Error: ${response.status} ${response.statusText}`;
|
|
259
232
|
const out = await response.json();
|
|
260
233
|
mayLog("gdc scrna gene exp", q.gene, Date.now() - t);
|
|
261
234
|
const result = out.data[0].cells;
|
|
@@ -265,8 +238,7 @@ function gdc_validateGeneExpression(G, ds, genome) {
|
|
|
265
238
|
}
|
|
266
239
|
return data;
|
|
267
240
|
} catch (e) {
|
|
268
|
-
if (e.stack)
|
|
269
|
-
console.log(e.stack);
|
|
241
|
+
if (e.stack) console.log(e.stack);
|
|
270
242
|
return { error: "GDC scRNAseq gene expression request failed with error: " + (e.message || e) };
|
|
271
243
|
}
|
|
272
244
|
};
|
|
@@ -18,25 +18,20 @@ function init({ genomes }) {
|
|
|
18
18
|
const q = req.query;
|
|
19
19
|
try {
|
|
20
20
|
const g = genomes[req.query.genome];
|
|
21
|
-
if (!g)
|
|
22
|
-
throw "invalid genome name";
|
|
21
|
+
if (!g) throw "invalid genome name";
|
|
23
22
|
const [ds, tdb] = await get_ds_tdb(g, q);
|
|
24
|
-
if (!ds)
|
|
25
|
-
|
|
26
|
-
if (!tdb)
|
|
27
|
-
throw "invalid termdb object";
|
|
23
|
+
if (!ds) throw "invalid dataset name";
|
|
24
|
+
if (!tdb) throw "invalid termdb object";
|
|
28
25
|
const result = await trigger_children(req, q, tdb);
|
|
29
26
|
res.send(result);
|
|
30
27
|
} catch (e) {
|
|
31
28
|
res.send({ error: e instanceof Error ? e.message : e });
|
|
32
|
-
if (e instanceof Error && e.stack)
|
|
33
|
-
console.log(e);
|
|
29
|
+
if (e instanceof Error && e.stack) console.log(e);
|
|
34
30
|
}
|
|
35
31
|
};
|
|
36
32
|
}
|
|
37
33
|
async function trigger_children(req, q, tdb) {
|
|
38
|
-
if (!q.tid)
|
|
39
|
-
throw "no parent term id";
|
|
34
|
+
if (!q.tid) throw "no parent term id";
|
|
40
35
|
const cohortValues = q.cohortValues ? q.cohortValues : "";
|
|
41
36
|
const treeFilter = q.treeFilter ? q.treeFilter : "";
|
|
42
37
|
const terms = await tdb.q.getTermChildren(req, q.tid, cohortValues, treeFilter);
|
|
@@ -18,20 +18,16 @@ function init({ genomes }) {
|
|
|
18
18
|
const q = req.query;
|
|
19
19
|
try {
|
|
20
20
|
const g = genomes[req.query.genome];
|
|
21
|
-
if (!g)
|
|
22
|
-
throw "invalid genome name";
|
|
21
|
+
if (!g) throw "invalid genome name";
|
|
23
22
|
const ds = g.datasets[req.query.dslabel];
|
|
24
|
-
if (!ds)
|
|
25
|
-
throw "invalid dataset name";
|
|
23
|
+
if (!ds) throw "invalid dataset name";
|
|
26
24
|
const tdb = ds.cohort.termdb;
|
|
27
|
-
if (!tdb)
|
|
28
|
-
throw "invalid termdb object";
|
|
25
|
+
if (!tdb) throw "invalid termdb object";
|
|
29
26
|
const results = await trigger_gettermsbyid(q, tdb);
|
|
30
27
|
res.send(results);
|
|
31
28
|
} catch (e) {
|
|
32
29
|
res.send({ error: e instanceof Error ? e.message : e });
|
|
33
|
-
if (e instanceof Error && e.stack)
|
|
34
|
-
console.log(e);
|
|
30
|
+
if (e instanceof Error && e.stack) console.log(e);
|
|
35
31
|
}
|
|
36
32
|
};
|
|
37
33
|
}
|
|
@@ -19,31 +19,24 @@ function init({ genomes }) {
|
|
|
19
19
|
try {
|
|
20
20
|
const q = req.query;
|
|
21
21
|
const g = genomes[q.genome];
|
|
22
|
-
if (!g)
|
|
23
|
-
throw "genome missing";
|
|
22
|
+
if (!g) throw "genome missing";
|
|
24
23
|
const ds = g.datasets?.[q.dslabel];
|
|
25
|
-
if (!ds)
|
|
26
|
-
|
|
27
|
-
if (!ds.queries?.topMutatedGenes)
|
|
28
|
-
throw "not supported by ds";
|
|
24
|
+
if (!ds) throw "ds missing";
|
|
25
|
+
if (!ds.queries?.topMutatedGenes) throw "not supported by ds";
|
|
29
26
|
const genes = await ds.queries.topMutatedGenes.get(q);
|
|
30
27
|
const payload = { genes };
|
|
31
28
|
res.send(payload);
|
|
32
29
|
} catch (e) {
|
|
33
30
|
res.send({ status: "error", error: e.message || e });
|
|
34
|
-
if (e.stack)
|
|
35
|
-
|
|
36
|
-
else
|
|
37
|
-
console.trace(e);
|
|
31
|
+
if (e.stack) console.log(e.stack);
|
|
32
|
+
else console.trace(e);
|
|
38
33
|
}
|
|
39
34
|
};
|
|
40
35
|
}
|
|
41
36
|
function validate_query_getTopMutatedGenes(ds) {
|
|
42
37
|
const q = ds.queries?.topMutatedGenes;
|
|
43
|
-
if (!q)
|
|
44
|
-
|
|
45
|
-
if (typeof q.get == "function")
|
|
46
|
-
return;
|
|
38
|
+
if (!q) return;
|
|
39
|
+
if (typeof q.get == "function") return;
|
|
47
40
|
if (!q.arguments) {
|
|
48
41
|
q.arguments = [];
|
|
49
42
|
q.arguments.push({ id: "maxGenes", label: "Gene Count", type: "number", value: 50 });
|
|
@@ -94,28 +87,20 @@ function validate_query_getTopMutatedGenes(ds) {
|
|
|
94
87
|
let sampleStatement = "";
|
|
95
88
|
if (param.filter) {
|
|
96
89
|
const lst = await get_samples(param, ds);
|
|
97
|
-
if (lst.length == 0)
|
|
98
|
-
throw "empty sample filter";
|
|
90
|
+
if (lst.length == 0) throw "empty sample filter";
|
|
99
91
|
sampleStatement = `WHERE sample IN (${lst.map((i) => i.id).join(",")})`;
|
|
100
92
|
}
|
|
101
93
|
const fields = [];
|
|
102
|
-
if (param.snv_mfndi)
|
|
103
|
-
|
|
104
|
-
if (param.
|
|
105
|
-
|
|
106
|
-
if (param.
|
|
107
|
-
|
|
108
|
-
if (param.snv_s)
|
|
109
|
-
fields.push("snv_s");
|
|
110
|
-
if (param.sv)
|
|
111
|
-
fields.push("sv");
|
|
112
|
-
if (param.fusion)
|
|
113
|
-
fields.push("fusion");
|
|
94
|
+
if (param.snv_mfndi) fields.push("snv_mfndi");
|
|
95
|
+
if (param.snv_splice) fields.push("snv_splice");
|
|
96
|
+
if (param.snv_utr) fields.push("snv_utr");
|
|
97
|
+
if (param.snv_s) fields.push("snv_s");
|
|
98
|
+
if (param.sv) fields.push("sv");
|
|
99
|
+
if (param.fusion) fields.push("fusion");
|
|
114
100
|
if (param.cnv == 1 && param.cnv_ms?.type && param.cnv_logratio?.type) {
|
|
115
101
|
fields.push(param.cnv_ms.type + param.cnv_logratio.type);
|
|
116
102
|
}
|
|
117
|
-
if (!fields.length)
|
|
118
|
-
throw "no fields";
|
|
103
|
+
if (!fields.length) throw "no fields";
|
|
119
104
|
const query = `WITH
|
|
120
105
|
filtered AS (
|
|
121
106
|
SELECT genesymbol, ${fields.join("+")} AS total FROM genesamplemutationcount
|
|
@@ -21,13 +21,10 @@ function init({ genomes }) {
|
|
|
21
21
|
const q = req.query;
|
|
22
22
|
const type = q.type;
|
|
23
23
|
const genome = genomes[q.genome];
|
|
24
|
-
if (!genome)
|
|
25
|
-
throw "invalid genome";
|
|
24
|
+
if (!genome) throw "invalid genome";
|
|
26
25
|
const ds = genome.datasets?.[q.dslabel];
|
|
27
|
-
if (!ds)
|
|
28
|
-
|
|
29
|
-
if (!ds.queries[type])
|
|
30
|
-
throw "not supported on dataset";
|
|
26
|
+
if (!ds) throw "invalid dslabel";
|
|
27
|
+
if (!ds.queries[type]) throw "not supported on dataset";
|
|
31
28
|
const terms = await ds.queries[type].getTopTerms(q);
|
|
32
29
|
res.send({ terms });
|
|
33
30
|
} catch (e) {
|
|
@@ -40,14 +37,10 @@ function validate_query_getTopTermsByType(ds, genome) {
|
|
|
40
37
|
for (const type of types) {
|
|
41
38
|
if (ds.queries[type]) {
|
|
42
39
|
const q = ds.queries[type];
|
|
43
|
-
if (!q)
|
|
44
|
-
|
|
45
|
-
if (q.src == "
|
|
46
|
-
|
|
47
|
-
else if (q.src == "native")
|
|
48
|
-
nativeValidateQuery(ds, type);
|
|
49
|
-
else
|
|
50
|
-
throw "unknown topVariablyExpressedGenes.src";
|
|
40
|
+
if (!q) return;
|
|
41
|
+
if (q.src == "gdcapi") gdcValidateQuery(ds, genome, type);
|
|
42
|
+
else if (q.src == "native") nativeValidateQuery(ds, type);
|
|
43
|
+
else throw "unknown topVariablyExpressedGenes.src";
|
|
51
44
|
}
|
|
52
45
|
}
|
|
53
46
|
}
|
|
@@ -60,16 +53,14 @@ function nativeValidateQuery(ds, type) {
|
|
|
60
53
|
for (const i of sidlst) {
|
|
61
54
|
if (typeQuery.samples.includes(i.id)) {
|
|
62
55
|
const n = ds.cohort.termdb.q.id2sampleName(i.id);
|
|
63
|
-
if (!n)
|
|
64
|
-
throw "sample id cannot convert to string name";
|
|
56
|
+
if (!n) throw "sample id cannot convert to string name";
|
|
65
57
|
samples.push(n);
|
|
66
58
|
}
|
|
67
59
|
}
|
|
68
60
|
} else {
|
|
69
61
|
for (const i of typeQuery.samples) {
|
|
70
62
|
const n = ds.cohort.termdb.q.id2sampleName(i.id);
|
|
71
|
-
if (!n)
|
|
72
|
-
throw "sample id cannot convert to string name";
|
|
63
|
+
if (!n) throw "sample id cannot convert to string name";
|
|
73
64
|
samples.push(n);
|
|
74
65
|
}
|
|
75
66
|
}
|
|
@@ -26,13 +26,10 @@ function init({ genomes }) {
|
|
|
26
26
|
try {
|
|
27
27
|
const q = req.query;
|
|
28
28
|
const genome = genomes[q.genome];
|
|
29
|
-
if (!genome)
|
|
30
|
-
throw "invalid genome";
|
|
29
|
+
if (!genome) throw "invalid genome";
|
|
31
30
|
const ds = genome.datasets?.[q.dslabel];
|
|
32
|
-
if (!ds)
|
|
33
|
-
|
|
34
|
-
if (!ds.queries?.topVariablyExpressedGenes)
|
|
35
|
-
throw "not supported on dataset";
|
|
31
|
+
if (!ds) throw "invalid dslabel";
|
|
32
|
+
if (!ds.queries?.topVariablyExpressedGenes) throw "not supported on dataset";
|
|
36
33
|
const t = Date.now();
|
|
37
34
|
result = {
|
|
38
35
|
genes: await ds.queries.topVariablyExpressedGenes.getGenes(q)
|
|
@@ -46,8 +43,7 @@ function init({ genomes }) {
|
|
|
46
43
|
}
|
|
47
44
|
function validate_query_TopVariablyExpressedGenes(ds, genome) {
|
|
48
45
|
const q = ds.queries.topVariablyExpressedGenes;
|
|
49
|
-
if (!q)
|
|
50
|
-
return;
|
|
46
|
+
if (!q) return;
|
|
51
47
|
if (q.src == "gdcapi") {
|
|
52
48
|
gdcValidateQuery(ds, genome);
|
|
53
49
|
} else if (q.src == "native") {
|
|
@@ -58,10 +54,8 @@ function validate_query_TopVariablyExpressedGenes(ds, genome) {
|
|
|
58
54
|
}
|
|
59
55
|
function nativeValidateQuery(ds) {
|
|
60
56
|
const gE = ds.queries.geneExpression;
|
|
61
|
-
if (!gE)
|
|
62
|
-
|
|
63
|
-
if (gE.src != "native")
|
|
64
|
-
throw "topVariablyExpressedGenes is native but geneExpression.src is not native";
|
|
57
|
+
if (!gE) throw "topVariablyExpressedGenes query given but geneExpression missing";
|
|
58
|
+
if (gE.src != "native") throw "topVariablyExpressedGenes is native but geneExpression.src is not native";
|
|
65
59
|
addTopVEarg(ds.queries.topVariablyExpressedGenes);
|
|
66
60
|
ds.queries.topVariablyExpressedGenes.getGenes = async (q) => {
|
|
67
61
|
const samples = [];
|
|
@@ -70,16 +64,14 @@ function nativeValidateQuery(ds) {
|
|
|
70
64
|
for (const i of sidlst) {
|
|
71
65
|
if (gE.samples.includes(i.id)) {
|
|
72
66
|
const n = ds.cohort.termdb.q.id2sampleName(i.id);
|
|
73
|
-
if (!n)
|
|
74
|
-
throw "sample id cannot convert to string name";
|
|
67
|
+
if (!n) throw "sample id cannot convert to string name";
|
|
75
68
|
samples.push(n);
|
|
76
69
|
}
|
|
77
70
|
}
|
|
78
71
|
} else {
|
|
79
72
|
for (const i of gE.samples) {
|
|
80
73
|
const n = ds.cohort.termdb.q.id2sampleName(i.id);
|
|
81
|
-
if (!n)
|
|
82
|
-
throw "sample id cannot convert to string name";
|
|
74
|
+
if (!n) throw "sample id cannot convert to string name";
|
|
83
75
|
samples.push(n);
|
|
84
76
|
}
|
|
85
77
|
}
|
|
@@ -135,11 +127,9 @@ function addTopVEarg(q) {
|
|
|
135
127
|
];
|
|
136
128
|
if (q.arguments) {
|
|
137
129
|
for (const a of q.arguments) {
|
|
138
|
-
if (!a.id)
|
|
139
|
-
throw "missing id of topVE.arguments[]";
|
|
130
|
+
if (!a.id) throw "missing id of topVE.arguments[]";
|
|
140
131
|
const item = arglst.find((i) => i.id == a.id);
|
|
141
|
-
if (!item)
|
|
142
|
-
throw "unknown id of topVE.arguments[]";
|
|
132
|
+
if (!item) throw "unknown id of topVE.arguments[]";
|
|
143
133
|
Object.assign(item, a);
|
|
144
134
|
}
|
|
145
135
|
}
|
|
@@ -209,8 +199,7 @@ function gdcValidateQuery(ds, genome) {
|
|
|
209
199
|
for (const i of re.gene_selection) {
|
|
210
200
|
if (i.gene_id && typeof i.gene_id == "string") {
|
|
211
201
|
const t = genome.genedb.getNameByAlias.get(i.gene_id);
|
|
212
|
-
if (t)
|
|
213
|
-
genes.push(t.name);
|
|
202
|
+
if (t) genes.push(t.name);
|
|
214
203
|
} else if (i.symbol && typeof i.symbol == "string") {
|
|
215
204
|
genes.push(i.symbol);
|
|
216
205
|
} else {
|
|
@@ -234,11 +223,9 @@ function gdcValidateQuery(ds, genome) {
|
|
|
234
223
|
if (q.geneSet.type == "all") {
|
|
235
224
|
arg.gene_type = "protein_coding";
|
|
236
225
|
} else if (q.geneSet.type == "custom" || q.geneSet.type == "msigdb") {
|
|
237
|
-
if (!Array.isArray(q.geneSet.geneList))
|
|
238
|
-
throw "q.geneSet.geneList is not array";
|
|
226
|
+
if (!Array.isArray(q.geneSet.geneList)) throw "q.geneSet.geneList is not array";
|
|
239
227
|
arg.gene_ids = map2ensg(q.geneSet.geneList, genome);
|
|
240
|
-
if (arg.gene_ids.length == 0)
|
|
241
|
-
throw "no valid genes from custom gene set";
|
|
228
|
+
if (arg.gene_ids.length == 0) throw "no valid genes from custom gene set";
|
|
242
229
|
} else {
|
|
243
230
|
throw "unknown q.geneSet.type";
|
|
244
231
|
}
|