@sjcrh/proteinpaint-server 2.82.0 → 2.83.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/package.json +3 -3
- package/routes/termdb.cluster.js +33 -6
- package/routes/termdb.config.js +1 -0
- package/src/app.js +166 -91
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.83.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "a genomics visualization tool for exploring a cohort's genotype and phenotype data",
|
|
6
6
|
"main": "src/app.js",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@babel/preset-env": "^7.9.6",
|
|
44
44
|
"@babel/preset-typescript": "^7.21.4",
|
|
45
45
|
"@babel/register": "^7.14.5",
|
|
46
|
-
"@sjcrh/proteinpaint-types": "2.
|
|
46
|
+
"@sjcrh/proteinpaint-types": "2.83.0",
|
|
47
47
|
"@types/node": "^20.11.24",
|
|
48
48
|
"@types/tough-cookie": "^4.0.5",
|
|
49
49
|
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@sjcrh/augen": "2.46.0",
|
|
66
66
|
"@sjcrh/proteinpaint-rust": "2.81.5",
|
|
67
|
-
"@sjcrh/proteinpaint-shared": "2.
|
|
67
|
+
"@sjcrh/proteinpaint-shared": "2.83.0",
|
|
68
68
|
"better-sqlite3": "^9.4.1",
|
|
69
69
|
"body-parser": "^1.15.2",
|
|
70
70
|
"canvas": "~2.11.2",
|
package/routes/termdb.cluster.js
CHANGED
|
@@ -6,7 +6,8 @@ import { gdc_validate_query_geneExpression } from "#src/mds3.gdc.js";
|
|
|
6
6
|
import { mayLimitSamples } from "#src/mds3.filter.js";
|
|
7
7
|
import { clusterMethodLst, distanceMethodLst } from "#shared/clustering.js";
|
|
8
8
|
import { getResult as getResultGene } from "#src/gene.js";
|
|
9
|
-
import { TermTypes } from "#shared/terms.js";
|
|
9
|
+
import { TermTypes, NUMERIC_DICTIONARY_TERM } from "#shared/terms.js";
|
|
10
|
+
import { getData } from "#src/termdb.matrix.js";
|
|
10
11
|
const api = {
|
|
11
12
|
endpoint: "termdb/cluster",
|
|
12
13
|
methods: {
|
|
@@ -34,8 +35,8 @@ function init({ genomes }) {
|
|
|
34
35
|
throw "invalid dataset name";
|
|
35
36
|
if (ds.__gdc && !ds.__gdc.doneCaching)
|
|
36
37
|
throw "The server has not finished caching the case IDs: try again in about 2 minutes.";
|
|
37
|
-
if (
|
|
38
|
-
if (!ds.queries?.[q.dataType])
|
|
38
|
+
if ([TermTypes.GENE_EXPRESSION, TermTypes.METABOLITE_INTENSITY, NUMERIC_DICTIONARY_TERM].includes(q.dataType)) {
|
|
39
|
+
if (!ds.queries?.[q.dataType] && q.dataType !== NUMERIC_DICTIONARY_TERM)
|
|
39
40
|
throw `no ${q.dataType} data on this dataset`;
|
|
40
41
|
if (!q.terms)
|
|
41
42
|
throw `missing gene list`;
|
|
@@ -43,7 +44,7 @@ function init({ genomes }) {
|
|
|
43
44
|
throw `gene list is not an array`;
|
|
44
45
|
if (q.terms.length < 3)
|
|
45
46
|
throw `A minimum of three genes is required for clustering. Please refresh this page to clear this error.`;
|
|
46
|
-
result = await getResult(q, ds);
|
|
47
|
+
result = await getResult(q, ds, g);
|
|
47
48
|
} else {
|
|
48
49
|
throw "unknown q.dataType " + q.dataType;
|
|
49
50
|
}
|
|
@@ -58,13 +59,20 @@ function init({ genomes }) {
|
|
|
58
59
|
res.send(result);
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
|
-
async function getResult(q, ds) {
|
|
62
|
+
async function getResult(q, ds, genome) {
|
|
62
63
|
let _q = q;
|
|
63
64
|
if (q.dataType == TermTypes.GENE_EXPRESSION) {
|
|
64
65
|
_q = JSON.parse(JSON.stringify(q));
|
|
65
66
|
_q.forClusteringAnalysis = true;
|
|
66
67
|
}
|
|
67
|
-
|
|
68
|
+
let term2sample2value, byTermId, bySampleId;
|
|
69
|
+
if (q.dataType == NUMERIC_DICTIONARY_TERM) {
|
|
70
|
+
;
|
|
71
|
+
({ term2sample2value, byTermId, bySampleId } = await getNumericDictTermAnnotation(q, ds, genome));
|
|
72
|
+
} else {
|
|
73
|
+
;
|
|
74
|
+
({ term2sample2value, byTermId, bySampleId } = await ds.queries[q.dataType].get(_q));
|
|
75
|
+
}
|
|
68
76
|
if (term2sample2value.size == 0)
|
|
69
77
|
throw "no data";
|
|
70
78
|
if (term2sample2value.size == 1) {
|
|
@@ -77,6 +85,25 @@ async function getResult(q, ds) {
|
|
|
77
85
|
console.log("clustering done:", Date.now() - t, "ms");
|
|
78
86
|
return { clustering, byTermId, bySampleId };
|
|
79
87
|
}
|
|
88
|
+
async function getNumericDictTermAnnotation(q, ds, genome) {
|
|
89
|
+
const getDataArgs = {
|
|
90
|
+
filter: q.filter,
|
|
91
|
+
terms: q.terms.map((term) => ({ term, q: { mode: "continuous" } }))
|
|
92
|
+
};
|
|
93
|
+
const data = await getData(getDataArgs, ds, genome);
|
|
94
|
+
const term2sample2value = /* @__PURE__ */ new Map();
|
|
95
|
+
for (const [key, sampleData] of Object.entries(data.samples)) {
|
|
96
|
+
for (const [term, value] of Object.entries(sampleData)) {
|
|
97
|
+
if (term !== "sample") {
|
|
98
|
+
if (!term2sample2value.has(term)) {
|
|
99
|
+
term2sample2value.set(term, {});
|
|
100
|
+
}
|
|
101
|
+
term2sample2value.get(term)[key] = value.value;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return { term2sample2value, byTermId: data.refs.byTermId, bySampleId: data.refs.bySampleId };
|
|
106
|
+
}
|
|
80
107
|
async function doClustering(data, q, numCases = 1e3) {
|
|
81
108
|
const sampleSet = /* @__PURE__ */ new Set();
|
|
82
109
|
for (const o of data.values()) {
|
package/routes/termdb.config.js
CHANGED
|
@@ -52,6 +52,7 @@ function make(q, res, ds, genome) {
|
|
|
52
52
|
dataDownloadCatch: tdb.dataDownloadCatch,
|
|
53
53
|
matrix: tdb.matrix,
|
|
54
54
|
hierCluster: tdb.hierCluster,
|
|
55
|
+
numericDictTermCluster: tdb.numericDictTermCluster,
|
|
55
56
|
mclass: tdb.mclass,
|
|
56
57
|
alwaysRefillCategoricalTermValues: tdb.alwaysRefillCategoricalTermValues,
|
|
57
58
|
isGeneSetTermdb: tdb.isGeneSetTermdb,
|