@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
package/routes/termdb.config.js
CHANGED
|
@@ -23,16 +23,13 @@ function init({ genomes }) {
|
|
|
23
23
|
mayCopyFromCookie(q, req.cookies);
|
|
24
24
|
try {
|
|
25
25
|
const genome = genomes[q.genome];
|
|
26
|
-
if (!genome)
|
|
27
|
-
throw "invalid genome";
|
|
26
|
+
if (!genome) throw "invalid genome";
|
|
28
27
|
const [ds] = get_ds_tdb(genome, q);
|
|
29
28
|
return make(q, req, res, ds, genome);
|
|
30
29
|
} catch (e) {
|
|
31
30
|
res.send({ error: e.message || e });
|
|
32
|
-
if (e.stack)
|
|
33
|
-
|
|
34
|
-
else
|
|
35
|
-
console.log(e);
|
|
31
|
+
if (e.stack) console.log(e.stack);
|
|
32
|
+
else console.log(e);
|
|
36
33
|
}
|
|
37
34
|
};
|
|
38
35
|
}
|
|
@@ -64,34 +61,20 @@ function make(q, req, res, ds, genome) {
|
|
|
64
61
|
defaultTw4correlationPlot: tdb.defaultTw4correlationPlot,
|
|
65
62
|
authFilter: req.query.filter
|
|
66
63
|
};
|
|
67
|
-
if (tdb.plotConfigByCohort)
|
|
68
|
-
|
|
69
|
-
if (tdb.
|
|
70
|
-
|
|
71
|
-
if (tdb.
|
|
72
|
-
|
|
73
|
-
if (tdb.
|
|
74
|
-
|
|
75
|
-
if (tdb.
|
|
76
|
-
|
|
77
|
-
if (tdb.
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
if (tdb.logscaleBase2)
|
|
82
|
-
c.logscaleBase2 = tdb.logscaleBase2;
|
|
83
|
-
if (tdb.useCasesExcluded)
|
|
84
|
-
c.useCasesExcluded = tdb.useCasesExcluded;
|
|
85
|
-
if (tdb.excludedTermtypeByTarget)
|
|
86
|
-
c.excludedTermtypeByTarget = tdb.excludedTermtypeByTarget;
|
|
87
|
-
if (tdb.survival)
|
|
88
|
-
c.survival = tdb.survival;
|
|
89
|
-
if (tdb.regression)
|
|
90
|
-
c.regression = tdb.regression;
|
|
91
|
-
if (ds.assayAvailability)
|
|
92
|
-
c.assayAvailability = ds.assayAvailability;
|
|
93
|
-
if (ds.cohort.correlationVolcano)
|
|
94
|
-
c.correlationVolcano = ds.cohort.correlationVolcano;
|
|
64
|
+
if (tdb.plotConfigByCohort) c.plotConfigByCohort = tdb.plotConfigByCohort;
|
|
65
|
+
if (tdb.multipleTestingCorrection) c.multipleTestingCorrection = tdb.multipleTestingCorrection;
|
|
66
|
+
if (tdb.helpPages) c.helpPages = tdb.helpPages;
|
|
67
|
+
if (tdb.minTimeSinceDx) c.minTimeSinceDx = tdb.minTimeSinceDx;
|
|
68
|
+
if (tdb.timeUnit) c.timeUnit = tdb.timeUnit;
|
|
69
|
+
if (tdb.cohortStartTimeMsg) c.cohortStartTimeMsg = tdb.cohortStartTimeMsg;
|
|
70
|
+
if (tdb.hasAncestry) c.hasAncestry = tdb.hasAncestry;
|
|
71
|
+
if (tdb.logscaleBase2) c.logscaleBase2 = tdb.logscaleBase2;
|
|
72
|
+
if (tdb.useCasesExcluded) c.useCasesExcluded = tdb.useCasesExcluded;
|
|
73
|
+
if (tdb.excludedTermtypeByTarget) c.excludedTermtypeByTarget = tdb.excludedTermtypeByTarget;
|
|
74
|
+
if (tdb.survival) c.survival = tdb.survival;
|
|
75
|
+
if (tdb.regression) c.regression = tdb.regression;
|
|
76
|
+
if (ds.assayAvailability) c.assayAvailability = ds.assayAvailability;
|
|
77
|
+
if (ds.cohort.correlationVolcano) c.correlationVolcano = ds.cohort.correlationVolcano;
|
|
95
78
|
addRestrictAncestries(c, tdb);
|
|
96
79
|
addScatterplots(c, ds);
|
|
97
80
|
addMatrixplots(c, ds);
|
|
@@ -99,21 +82,18 @@ function make(q, req, res, ds, genome) {
|
|
|
99
82
|
c.requiredAuth = authApi.getRequiredCredForDsEmbedder(q.dslabel, q.embedder);
|
|
100
83
|
const info = authApi.getNonsensitiveInfo(req);
|
|
101
84
|
c.clientAuthResult = info?.clientAuthResult || {};
|
|
102
|
-
if (tdb.displaySampleIds)
|
|
103
|
-
c.displaySampleIds = tdb.displaySampleIds(c.clientAuthResult);
|
|
85
|
+
if (tdb.displaySampleIds) c.displaySampleIds = tdb.displaySampleIds(c.clientAuthResult);
|
|
104
86
|
c.authFilter = req.query.filter;
|
|
105
87
|
res.send({ termdbConfig: c });
|
|
106
88
|
}
|
|
107
89
|
function addRestrictAncestries(c, tdb) {
|
|
108
|
-
if (!tdb.restrictAncestries)
|
|
109
|
-
return;
|
|
90
|
+
if (!tdb.restrictAncestries) return;
|
|
110
91
|
c.restrictAncestries = tdb.restrictAncestries.map((i) => {
|
|
111
92
|
return { name: i.name, tvs: i.tvs, PCcount: i.PCcount };
|
|
112
93
|
});
|
|
113
94
|
}
|
|
114
95
|
function addScatterplots(c, ds) {
|
|
115
|
-
if (!ds.cohort.scatterplots)
|
|
116
|
-
return;
|
|
96
|
+
if (!ds.cohort.scatterplots) return;
|
|
117
97
|
c.scatterplots = ds.cohort.scatterplots.plots.map((p) => {
|
|
118
98
|
return {
|
|
119
99
|
name: p.name,
|
|
@@ -130,16 +110,14 @@ function addScatterplots(c, ds) {
|
|
|
130
110
|
});
|
|
131
111
|
}
|
|
132
112
|
function addMatrixplots(c, ds) {
|
|
133
|
-
if (!ds.cohort.matrixplots)
|
|
134
|
-
return;
|
|
113
|
+
if (!ds.cohort.matrixplots) return;
|
|
135
114
|
c.matrixplots = ds.cohort.matrixplots.plots.map((p) => {
|
|
136
115
|
return { name: p.name };
|
|
137
116
|
});
|
|
138
117
|
}
|
|
139
118
|
function addNonDictionaryQueries(c, ds, genome) {
|
|
140
119
|
const q = ds.queries;
|
|
141
|
-
if (!q)
|
|
142
|
-
return;
|
|
120
|
+
if (!q) return;
|
|
143
121
|
c.queries = {
|
|
144
122
|
defaultCoord: q.defaultCoord || genome.defaultcoord,
|
|
145
123
|
gbRestrictMode: q.gbRestrictMode
|
|
@@ -154,8 +132,7 @@ function addNonDictionaryQueries(c, ds, genome) {
|
|
|
154
132
|
details: q.snvindel.details,
|
|
155
133
|
populations: q.snvindel.populations
|
|
156
134
|
};
|
|
157
|
-
if (q.snvindel.byisoform?.processTwsInOneQuery)
|
|
158
|
-
q2.snvindel.byisoform = { processTwsInOneQuery: true };
|
|
135
|
+
if (q.snvindel.byisoform?.processTwsInOneQuery) q2.snvindel.byisoform = { processTwsInOneQuery: true };
|
|
159
136
|
}
|
|
160
137
|
if (q.trackLst) {
|
|
161
138
|
q2.trackLst = q.trackLst;
|
|
@@ -177,16 +154,13 @@ function addNonDictionaryQueries(c, ds, genome) {
|
|
|
177
154
|
"gainColor",
|
|
178
155
|
"lossColor"
|
|
179
156
|
]) {
|
|
180
|
-
if (k in q.cnv)
|
|
181
|
-
q2.cnv[k] = q.cnv[k];
|
|
157
|
+
if (k in q.cnv) q2.cnv[k] = q.cnv[k];
|
|
182
158
|
}
|
|
183
159
|
}
|
|
184
160
|
if (q.geneCnv) {
|
|
185
161
|
}
|
|
186
|
-
if (q.topMutatedGenes)
|
|
187
|
-
|
|
188
|
-
if (q.topVariablyExpressedGenes)
|
|
189
|
-
q2.topVariablyExpressedGenes = q.topVariablyExpressedGenes;
|
|
162
|
+
if (q.topMutatedGenes) q2.topMutatedGenes = q.topMutatedGenes;
|
|
163
|
+
if (q.topVariablyExpressedGenes) q2.topVariablyExpressedGenes = q.topVariablyExpressedGenes;
|
|
190
164
|
if (q.singleSampleMutation) {
|
|
191
165
|
q2.singleSampleMutation = {
|
|
192
166
|
sample_id_key: q.singleSampleMutation.sample_id_key,
|
|
@@ -260,24 +234,18 @@ function addNonDictionaryQueries(c, ds, genome) {
|
|
|
260
234
|
function getAllowedTermTypes(ds) {
|
|
261
235
|
const typeSet = /* @__PURE__ */ new Set();
|
|
262
236
|
for (const r of ds.cohort.termdb.termtypeByCohort) {
|
|
263
|
-
if (r.termType)
|
|
264
|
-
typeSet.add(r.termType);
|
|
237
|
+
if (r.termType) typeSet.add(r.termType);
|
|
265
238
|
}
|
|
266
239
|
if (ds.cohort.termdb.allowedTermTypes) {
|
|
267
|
-
for (const t of ds.cohort.termdb.allowedTermTypes)
|
|
268
|
-
typeSet.add(t);
|
|
240
|
+
for (const t of ds.cohort.termdb.allowedTermTypes) typeSet.add(t);
|
|
269
241
|
}
|
|
270
|
-
if (ds.queries?.geneExpression)
|
|
271
|
-
|
|
272
|
-
if (ds.queries?.
|
|
273
|
-
typeSet.add(TermTypes.METABOLITE_INTENSITY);
|
|
274
|
-
if (ds.queries?.ssGSEA)
|
|
275
|
-
typeSet.add(TermTypes.SSGSEA);
|
|
242
|
+
if (ds.queries?.geneExpression) typeSet.add(TermTypes.GENE_EXPRESSION);
|
|
243
|
+
if (ds.queries?.metaboliteIntensity) typeSet.add(TermTypes.METABOLITE_INTENSITY);
|
|
244
|
+
if (ds.queries?.ssGSEA) typeSet.add(TermTypes.SSGSEA);
|
|
276
245
|
return [...typeSet];
|
|
277
246
|
}
|
|
278
247
|
function getSelectCohort(ds, req) {
|
|
279
|
-
if (!ds.cohort.termdb.selectCohort)
|
|
280
|
-
return;
|
|
248
|
+
if (!ds.cohort.termdb.selectCohort) return;
|
|
281
249
|
const copy = Object.assign({}, ds.cohort.termdb.selectCohort);
|
|
282
250
|
if (ds.cohort.termdb.selectCohort.descriptionByUser) {
|
|
283
251
|
copy.description = ds.cohort.termdb.selectCohort.descriptionByUser(authApi.getNonsensitiveInfo(req));
|
|
@@ -20,22 +20,17 @@ function init({ genomes }) {
|
|
|
20
20
|
let result;
|
|
21
21
|
try {
|
|
22
22
|
const genome = genomes[req.query.genome];
|
|
23
|
-
if (!genome)
|
|
24
|
-
throw "invalid genome name";
|
|
23
|
+
if (!genome) throw "invalid genome name";
|
|
25
24
|
const ds = genome.datasets[req.query.dslabel];
|
|
26
|
-
if (!ds)
|
|
27
|
-
throw "invalid dataset name";
|
|
25
|
+
if (!ds) throw "invalid dataset name";
|
|
28
26
|
const tdb = ds.cohort.termdb;
|
|
29
|
-
if (!tdb)
|
|
30
|
-
|
|
31
|
-
if (!q.tw.$id)
|
|
32
|
-
q.tw.$id = "_";
|
|
27
|
+
if (!tdb) throw "invalid termdb object";
|
|
28
|
+
if (!q.tw.$id) q.tw.$id = "_";
|
|
33
29
|
const data = await getData(
|
|
34
30
|
{ filter: q.filter, filter0: q.filter0, terms: [q.tw], __protected__: q.__protected__ },
|
|
35
31
|
ds
|
|
36
32
|
);
|
|
37
|
-
if (data.error)
|
|
38
|
-
throw data.error;
|
|
33
|
+
if (data.error) throw data.error;
|
|
39
34
|
const values = [];
|
|
40
35
|
for (const key in data.samples) {
|
|
41
36
|
const sample = data.samples[key];
|
|
@@ -60,8 +55,7 @@ function init({ genomes }) {
|
|
|
60
55
|
result = {};
|
|
61
56
|
}
|
|
62
57
|
} catch (e) {
|
|
63
|
-
if (e instanceof Error && e.stack)
|
|
64
|
-
console.log(e);
|
|
58
|
+
if (e instanceof Error && e.stack) console.log(e);
|
|
65
59
|
result = { error: e?.message || e };
|
|
66
60
|
}
|
|
67
61
|
res.send(result);
|
|
@@ -18,20 +18,17 @@ function init({ genomes }) {
|
|
|
18
18
|
return async (req, res) => {
|
|
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
23
|
res.send(await getFilters(req.query, ds));
|
|
25
24
|
} catch (e) {
|
|
26
|
-
if (e.stack)
|
|
27
|
-
console.log(e.stack);
|
|
25
|
+
if (e.stack) console.log(e.stack);
|
|
28
26
|
res.send({ status: "error", error: e.message || e });
|
|
29
27
|
}
|
|
30
28
|
};
|
|
31
29
|
}
|
|
32
30
|
async function getFilters(query, ds) {
|
|
33
|
-
if (!query.filterByUserSites)
|
|
34
|
-
authApi.mayAdjustFilter(query, ds, query.terms);
|
|
31
|
+
if (!query.filterByUserSites) authApi.mayAdjustFilter(query, ds, query.terms);
|
|
35
32
|
const samplesPerFilter = await getSamplesPerFilter(query, ds);
|
|
36
33
|
const filtersData = await getData(
|
|
37
34
|
{
|
|
@@ -60,8 +57,7 @@ function getList(samplesPerFilter, filtersData, tw, showAll) {
|
|
|
60
57
|
for (const value of values) {
|
|
61
58
|
const label = value.label.replace(/["']/g, "");
|
|
62
59
|
const disabled = !sampleValues.includes(value.key || value.label);
|
|
63
|
-
if (!showAll && disabled)
|
|
64
|
-
continue;
|
|
60
|
+
if (!showAll && disabled) continue;
|
|
65
61
|
filteredValues.push({ value: value.key || value.label, label, disabled });
|
|
66
62
|
}
|
|
67
63
|
filteredValues.unshift({ label: "", value: "" });
|
|
@@ -18,26 +18,21 @@ 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 result = await trigger_getnumericcategories(q, tdb, ds);
|
|
30
27
|
res.send(result);
|
|
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
|
}
|
|
38
34
|
async function trigger_getnumericcategories(q, tdb, ds) {
|
|
39
|
-
if (!q.tid)
|
|
40
|
-
throw ".tid missing";
|
|
35
|
+
if (!q.tid) throw ".tid missing";
|
|
41
36
|
const arg = {
|
|
42
37
|
ds,
|
|
43
38
|
term_id: q.tid,
|
|
@@ -20,29 +20,23 @@ function init({ genomes }) {
|
|
|
20
20
|
const q = req.query;
|
|
21
21
|
try {
|
|
22
22
|
const g = genomes[req.query.genome];
|
|
23
|
-
if (!g)
|
|
24
|
-
throw "invalid genome name";
|
|
23
|
+
if (!g) throw "invalid genome name";
|
|
25
24
|
const ds = g.datasets[req.query.dslabel];
|
|
26
|
-
if (!ds)
|
|
27
|
-
throw "invalid dataset name";
|
|
25
|
+
if (!ds) throw "invalid dataset name";
|
|
28
26
|
await trigger_getpercentile(q, res, ds);
|
|
29
27
|
} catch (e) {
|
|
30
28
|
res.send({ error: e instanceof Error ? e.message : e });
|
|
31
|
-
if (e instanceof Error && e.stack)
|
|
32
|
-
console.log(e);
|
|
29
|
+
if (e instanceof Error && e.stack) console.log(e);
|
|
33
30
|
}
|
|
34
31
|
};
|
|
35
32
|
}
|
|
36
33
|
async function trigger_getpercentile(q, res, ds) {
|
|
37
34
|
const term = q.term;
|
|
38
|
-
if (!term)
|
|
39
|
-
|
|
40
|
-
if (!isNumericTerm(term))
|
|
41
|
-
throw "not numeric term";
|
|
35
|
+
if (!term) throw "term is missing";
|
|
36
|
+
if (!isNumericTerm(term)) throw "not numeric term";
|
|
42
37
|
const tw = { $id: "_", term, q: { mode: "continuous" } };
|
|
43
38
|
const data = await getData({ filter: q.filter, filter0: q.filter0, terms: [tw], __protected__: q.__protected__ }, ds);
|
|
44
|
-
if (data.error)
|
|
45
|
-
throw data.error;
|
|
39
|
+
if (data.error) throw data.error;
|
|
46
40
|
const values = [];
|
|
47
41
|
for (const key in data.samples) {
|
|
48
42
|
const sample = data.samples[key];
|
|
@@ -17,8 +17,7 @@ function init({ genomes }) {
|
|
|
17
17
|
return async (req, res) => {
|
|
18
18
|
try {
|
|
19
19
|
const g = genomes[req.query.genome];
|
|
20
|
-
if (!g)
|
|
21
|
-
throw "invalid genome name";
|
|
20
|
+
if (!g) throw "invalid genome name";
|
|
22
21
|
const ds = g.datasets?.[req.query.dslabel];
|
|
23
22
|
const result = await getScoresDict(req.query, ds);
|
|
24
23
|
res.send(result);
|
|
@@ -29,11 +28,9 @@ function init({ genomes }) {
|
|
|
29
28
|
};
|
|
30
29
|
}
|
|
31
30
|
async function getScoresDict(query, ds) {
|
|
32
|
-
if (!query.filterByUserSites)
|
|
33
|
-
query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
|
|
31
|
+
if (!query.filterByUserSites) query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
|
|
34
32
|
const terms = [...query.scoreTerms, query.facilityTW];
|
|
35
|
-
if (query.scScoreTerms)
|
|
36
|
-
terms.push(...query.scScoreTerms);
|
|
33
|
+
if (query.scScoreTerms) terms.push(...query.scScoreTerms);
|
|
37
34
|
const data = await getData(
|
|
38
35
|
{
|
|
39
36
|
terms,
|
|
@@ -60,16 +57,12 @@ async function getScoresDict(query, ds) {
|
|
|
60
57
|
}
|
|
61
58
|
}
|
|
62
59
|
let sitesSelected = [];
|
|
63
|
-
if (query.site)
|
|
64
|
-
|
|
65
|
-
else
|
|
66
|
-
sitesSelected = [sites[0].value];
|
|
67
|
-
else
|
|
68
|
-
sitesSelected = query.sites;
|
|
60
|
+
if (query.site) sitesSelected = [query.site];
|
|
61
|
+
else if (!query.isAggregate) sitesSelected = [sites[0].value];
|
|
62
|
+
else sitesSelected = query.sites;
|
|
69
63
|
const sampleData = sitesSelected?.length == 1 ? data.samples[sitesSelected[0]] : null;
|
|
70
64
|
let samples = sampleData ? [sampleData] : Object.values(data.samples);
|
|
71
|
-
if (sitesSelected?.length > 0)
|
|
72
|
-
samples = samples.filter((s) => sitesSelected.includes(s.sample));
|
|
65
|
+
if (sitesSelected?.length > 0) samples = samples.filter((s) => sitesSelected.includes(s.sample));
|
|
73
66
|
const term2Score = {};
|
|
74
67
|
for (const d of query.scoreTerms) {
|
|
75
68
|
const getDictFunc = (sample) => getDict(d.$id, sample);
|
|
@@ -87,8 +80,7 @@ async function getScoresDict(query, ds) {
|
|
|
87
80
|
return { term2Score, sites, hospital, n: sampleData ? 1 : samples.length };
|
|
88
81
|
}
|
|
89
82
|
function getDict(key, sample) {
|
|
90
|
-
if (!sample[key])
|
|
91
|
-
return null;
|
|
83
|
+
if (!sample[key]) return null;
|
|
92
84
|
const termData = sample[key].value;
|
|
93
85
|
return JSON.parse(termData);
|
|
94
86
|
}
|
|
@@ -96,26 +88,22 @@ function getPercentsDict(getDictFunc, samples) {
|
|
|
96
88
|
const percentageDict = {};
|
|
97
89
|
for (const sample of samples) {
|
|
98
90
|
const percents = getDictFunc(sample);
|
|
99
|
-
if (!percents)
|
|
100
|
-
continue;
|
|
91
|
+
if (!percents) continue;
|
|
101
92
|
for (const key in percents) {
|
|
102
93
|
const value = percents[key];
|
|
103
|
-
if (!percentageDict[key])
|
|
104
|
-
percentageDict[key] = 0;
|
|
94
|
+
if (!percentageDict[key]) percentageDict[key] = 0;
|
|
105
95
|
percentageDict[key] += value;
|
|
106
96
|
}
|
|
107
97
|
}
|
|
108
98
|
return percentageDict;
|
|
109
99
|
}
|
|
110
100
|
function getSCPercentsDict(tw, samples) {
|
|
111
|
-
if (!tw)
|
|
112
|
-
throw "tw not defined";
|
|
101
|
+
if (!tw) throw "tw not defined";
|
|
113
102
|
const percentageDict = {};
|
|
114
103
|
for (const sample of samples) {
|
|
115
104
|
const twData = sample[tw.$id];
|
|
116
105
|
const key = twData?.value;
|
|
117
|
-
if (!percentageDict[key])
|
|
118
|
-
percentageDict[key] = 0;
|
|
106
|
+
if (!percentageDict[key]) percentageDict[key] = 0;
|
|
119
107
|
percentageDict[key] += 1;
|
|
120
108
|
}
|
|
121
109
|
return percentageDict;
|
|
@@ -17,8 +17,7 @@ function init({ genomes }) {
|
|
|
17
17
|
return async (req, res) => {
|
|
18
18
|
try {
|
|
19
19
|
const g = genomes[req.query.genome];
|
|
20
|
-
if (!g)
|
|
21
|
-
throw "invalid genome name";
|
|
20
|
+
if (!g) throw "invalid genome name";
|
|
22
21
|
const ds = g.datasets?.[req.query.dslabel];
|
|
23
22
|
const result = await getScores(req.query, ds);
|
|
24
23
|
res.send(result);
|
|
@@ -29,8 +28,7 @@ function init({ genomes }) {
|
|
|
29
28
|
};
|
|
30
29
|
}
|
|
31
30
|
async function getScores(query, ds) {
|
|
32
|
-
if (!query.filterByUserSites)
|
|
33
|
-
query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
|
|
31
|
+
if (!query.filterByUserSites) query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
|
|
34
32
|
const terms = [query.facilityTW];
|
|
35
33
|
for (const term of query.scoreTerms) {
|
|
36
34
|
terms.push(term.score);
|
|
@@ -61,16 +59,12 @@ async function getScores(query, ds) {
|
|
|
61
59
|
}
|
|
62
60
|
}
|
|
63
61
|
let sitesSelected = [];
|
|
64
|
-
if (query.site)
|
|
65
|
-
|
|
66
|
-
else
|
|
67
|
-
sitesSelected = [sites[0].value];
|
|
68
|
-
else
|
|
69
|
-
sitesSelected = query.sites;
|
|
62
|
+
if (query.site) sitesSelected = [query.site];
|
|
63
|
+
else if (!query.isAggregate) sitesSelected = [sites[0].value];
|
|
64
|
+
else sitesSelected = query.sites;
|
|
70
65
|
const sampleData = sitesSelected?.length == 1 ? data.samples[sitesSelected[0]] : null;
|
|
71
66
|
let samples = Object.values(data.samples);
|
|
72
|
-
if (sitesSelected?.length > 0)
|
|
73
|
-
samples = samples.filter((s) => sitesSelected.includes(s.sample));
|
|
67
|
+
if (sitesSelected?.length > 0) samples = samples.filter((s) => sitesSelected.includes(s.sample));
|
|
74
68
|
const term2Score = {};
|
|
75
69
|
for (const d of query.scoreTerms) {
|
|
76
70
|
term2Score[d.score.term.id] = getPercentage(d, samples, sampleData);
|
|
@@ -81,8 +75,7 @@ async function getScores(query, ds) {
|
|
|
81
75
|
return { term2Score, sites, hospital, n: sampleData ? 1 : samples.length };
|
|
82
76
|
}
|
|
83
77
|
function getPercentage(d, samples, sampleData) {
|
|
84
|
-
if (!d)
|
|
85
|
-
return null;
|
|
78
|
+
if (!d) return null;
|
|
86
79
|
const isAggregate = sampleData == null;
|
|
87
80
|
if (isAggregate) {
|
|
88
81
|
const scores = samples.filter((sample) => sample[d.score.$id]?.value).map((sample) => sample[d.score.$id].value / (sample[d.maxScore.$id]?.value || d.maxScore) * 100);
|
|
@@ -18,18 +18,14 @@ 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] = 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
|
await trigger_rootterm(req, q, res, tdb);
|
|
29
26
|
} catch (e) {
|
|
30
27
|
res.send({ error: e instanceof Error ? e.message : e });
|
|
31
|
-
if (e instanceof Error && e.stack)
|
|
32
|
-
console.log(e);
|
|
28
|
+
if (e instanceof Error && e.stack) console.log(e);
|
|
33
29
|
}
|
|
34
30
|
};
|
|
35
31
|
}
|
|
@@ -21,11 +21,9 @@ function init({ genomes }) {
|
|
|
21
21
|
const q = req.query;
|
|
22
22
|
const sampleId = q.sampleId;
|
|
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
|
-
throw "invalid dslabel";
|
|
26
|
+
if (!ds) throw "invalid dslabel";
|
|
29
27
|
const images = await ds.queries.images.getSampleImages({ sampleId });
|
|
30
28
|
res.send({ images });
|
|
31
29
|
} catch (e) {
|
|
@@ -35,8 +33,7 @@ function init({ genomes }) {
|
|
|
35
33
|
}
|
|
36
34
|
function validate_query_getSampleImages(ds) {
|
|
37
35
|
const q = ds.queries.images;
|
|
38
|
-
if (!q)
|
|
39
|
-
return;
|
|
36
|
+
if (!q) return;
|
|
40
37
|
nativeValidateQuery(ds);
|
|
41
38
|
}
|
|
42
39
|
function nativeValidateQuery(ds) {
|
|
@@ -52,8 +49,7 @@ async function getSampleImages(ds, folder, sampleId) {
|
|
|
52
49
|
const images = [];
|
|
53
50
|
for (const row of rows) {
|
|
54
51
|
const file = path.join(serverconfig.tpmasterdir, folder, row.fileName);
|
|
55
|
-
if (!fs.existsSync(file))
|
|
56
|
-
throw new Error(`File ${row.fileName} does not exist`);
|
|
52
|
+
if (!fs.existsSync(file)) throw new Error(`File ${row.fileName} does not exist`);
|
|
57
53
|
const data = await fs.promises.readFile(file);
|
|
58
54
|
images.push({
|
|
59
55
|
src: "data:image/jpeg;base64," + Buffer.from(data).toString("base64")
|
|
@@ -17,17 +17,13 @@ function init({ genomes }) {
|
|
|
17
17
|
let result;
|
|
18
18
|
try {
|
|
19
19
|
const g = genomes[q.genome];
|
|
20
|
-
if (!g)
|
|
21
|
-
throw "invalid genome name";
|
|
20
|
+
if (!g) throw "invalid genome name";
|
|
22
21
|
const ds = g.datasets[q.dslabel];
|
|
23
|
-
if (!ds)
|
|
24
|
-
|
|
25
|
-
if (!ds.queries?.singleSampleMutation)
|
|
26
|
-
throw "not supported on this dataset";
|
|
22
|
+
if (!ds) throw "invalid dataset name";
|
|
23
|
+
if (!ds.queries?.singleSampleMutation) throw "not supported on this dataset";
|
|
27
24
|
result = await ds.queries.singleSampleMutation.get(q);
|
|
28
25
|
} catch (e) {
|
|
29
|
-
if (e.stack)
|
|
30
|
-
console.log(e.stack);
|
|
26
|
+
if (e.stack) console.log(e.stack);
|
|
31
27
|
result = {
|
|
32
28
|
status: e.status || 400,
|
|
33
29
|
error: e.message || e
|
|
@@ -38,8 +34,7 @@ function init({ genomes }) {
|
|
|
38
34
|
}
|
|
39
35
|
async function validate_query_singleSampleMutation(ds, genome) {
|
|
40
36
|
const _q = ds.queries.singleSampleMutation;
|
|
41
|
-
if (!_q)
|
|
42
|
-
return;
|
|
37
|
+
if (!_q) return;
|
|
43
38
|
if (_q.src == "gdcapi") {
|
|
44
39
|
gdcValidate_query_singleSampleMutation(ds, genome);
|
|
45
40
|
} else if (_q.src == "native") {
|
|
@@ -48,8 +43,7 @@ async function validate_query_singleSampleMutation(ds, genome) {
|
|
|
48
43
|
{
|
|
49
44
|
const vt = typeof q.sample;
|
|
50
45
|
if (vt == "string") {
|
|
51
|
-
if (q.sample == "")
|
|
52
|
-
throw "sample is blank string";
|
|
46
|
+
if (q.sample == "") throw "sample is blank string";
|
|
53
47
|
sample = q.sample;
|
|
54
48
|
} else if (vt == "number") {
|
|
55
49
|
sample = q.sample.toString();
|
|
@@ -57,18 +51,15 @@ async function validate_query_singleSampleMutation(ds, genome) {
|
|
|
57
51
|
throw "sample value is not string or number";
|
|
58
52
|
}
|
|
59
53
|
}
|
|
60
|
-
if (illegalpath(sample))
|
|
61
|
-
throw "invalid sample name";
|
|
54
|
+
if (illegalpath(sample)) throw "invalid sample name";
|
|
62
55
|
const tmp = fileurl({
|
|
63
56
|
query: {
|
|
64
57
|
file: path.join(_q.folder, sample)
|
|
65
58
|
}
|
|
66
59
|
});
|
|
67
|
-
if (tmp[0])
|
|
68
|
-
throw tmp[0];
|
|
60
|
+
if (tmp[0]) throw tmp[0];
|
|
69
61
|
const file = tmp[1];
|
|
70
|
-
if (!file)
|
|
71
|
-
throw "no file returned";
|
|
62
|
+
if (!file) throw "no file returned";
|
|
72
63
|
await file_is_readable(file);
|
|
73
64
|
const data = await read_file(file);
|
|
74
65
|
return { mlst: JSON.parse(data) };
|
|
@@ -19,13 +19,10 @@ function init({ genomes }) {
|
|
|
19
19
|
let result;
|
|
20
20
|
try {
|
|
21
21
|
const g = genomes[q.genome];
|
|
22
|
-
if (!g)
|
|
23
|
-
throw "invalid genome name";
|
|
22
|
+
if (!g) throw "invalid genome name";
|
|
24
23
|
const ds = g.datasets[q.dslabel];
|
|
25
|
-
if (!ds)
|
|
26
|
-
|
|
27
|
-
if (!ds.queries?.singleCell?.DEgenes)
|
|
28
|
-
throw "not supported on this dataset";
|
|
24
|
+
if (!ds) throw "invalid dataset name";
|
|
25
|
+
if (!ds.queries?.singleCell?.DEgenes) throw "not supported on this dataset";
|
|
29
26
|
result = await ds.queries.singleCell.DEgenes.get(q);
|
|
30
27
|
if (!result || !result.genes || !result?.genes?.length) {
|
|
31
28
|
result = {
|
|
@@ -34,8 +31,7 @@ function init({ genomes }) {
|
|
|
34
31
|
};
|
|
35
32
|
}
|
|
36
33
|
} catch (e) {
|
|
37
|
-
if (e.stack)
|
|
38
|
-
console.log(e.stack);
|
|
34
|
+
if (e.stack) console.log(e.stack);
|
|
39
35
|
result = {
|
|
40
36
|
status: e.status || 400,
|
|
41
37
|
error: e.message || e
|
|
@@ -18,17 +18,13 @@ function init({ genomes }) {
|
|
|
18
18
|
let result;
|
|
19
19
|
try {
|
|
20
20
|
const g = genomes[q.genome];
|
|
21
|
-
if (!g)
|
|
22
|
-
throw "invalid genome name";
|
|
21
|
+
if (!g) throw "invalid genome name";
|
|
23
22
|
const ds = g.datasets[q.dslabel];
|
|
24
|
-
if (!ds)
|
|
25
|
-
|
|
26
|
-
if (!ds.queries?.singleCell)
|
|
27
|
-
throw "no singlecell data on this dataset";
|
|
23
|
+
if (!ds) throw "invalid dataset name";
|
|
24
|
+
if (!ds.queries?.singleCell) throw "no singlecell data on this dataset";
|
|
28
25
|
result = await ds.queries.singleCell.data.get(q);
|
|
29
26
|
} catch (e) {
|
|
30
|
-
if (e.stack)
|
|
31
|
-
console.log(e);
|
|
27
|
+
if (e.stack) console.log(e);
|
|
32
28
|
result = {
|
|
33
29
|
status: e.status || 400,
|
|
34
30
|
error: e.message || e
|