@sjcrh/proteinpaint-server 2.81.5-0 → 2.81.6
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/genesetOverrepresentation.js +1 -0
- package/routes/termdb.DE.js +4 -1
- package/routes/termdb.boxplot.js +123 -0
- package/routes/termdb.config.js +3 -3
- package/routes/termdb.topVariablyExpressedGenes.js +2 -2
- package/src/app.js +1097 -786
- package/utils/edge.R +56 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-server",
|
|
3
|
-
"version": "2.81.
|
|
3
|
+
"version": "2.81.6",
|
|
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.81.
|
|
46
|
+
"@sjcrh/proteinpaint-types": "2.81.5",
|
|
47
47
|
"@types/node": "^20.11.24",
|
|
48
48
|
"@types/tough-cookie": "^4.0.5",
|
|
49
49
|
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@sjcrh/augen": "2.46.0",
|
|
66
|
-
"@sjcrh/proteinpaint-rust": "2.
|
|
66
|
+
"@sjcrh/proteinpaint-rust": "2.81.5",
|
|
67
67
|
"@sjcrh/proteinpaint-shared": "2.79.4",
|
|
68
68
|
"better-sqlite3": "^9.4.1",
|
|
69
69
|
"body-parser": "^1.15.2",
|
|
@@ -37,6 +37,7 @@ async function run_genesetOverrepresentation_analysis(q, genomes) {
|
|
|
37
37
|
sample_genes: q.sample_genes,
|
|
38
38
|
msigdb: genomes[q.genome].termdbs.msigdb.cohort.db.connection.name,
|
|
39
39
|
gene_set_group: q.geneSetGroup,
|
|
40
|
+
filter_non_coding_genes: q.filter_non_coding_genes,
|
|
40
41
|
genedb: path.join(serverconfig.tpmasterdir, genomes[q.genome].genedb.dbfile)
|
|
41
42
|
};
|
|
42
43
|
if (q.background_genes) {
|
package/routes/termdb.DE.js
CHANGED
|
@@ -43,6 +43,7 @@ async function run_DE(param, ds) {
|
|
|
43
43
|
throw "samplelst.groups[0].values.length<1";
|
|
44
44
|
if (param.samplelst.groups[1].values?.length < 1)
|
|
45
45
|
throw "samplelst.groups[1].values.length<1";
|
|
46
|
+
param.storage_type = ds.queries.rnaseqGeneCount.storage_type;
|
|
46
47
|
const q = ds.queries.rnaseqGeneCount;
|
|
47
48
|
if (!q)
|
|
48
49
|
return;
|
|
@@ -83,9 +84,11 @@ async function run_DE(param, ds) {
|
|
|
83
84
|
const expression_input = {
|
|
84
85
|
case: cases_string,
|
|
85
86
|
control: controls_string,
|
|
87
|
+
data_type: "do_DE",
|
|
86
88
|
input_file: q.file,
|
|
87
89
|
min_count: param.min_count,
|
|
88
|
-
min_total_count: param.min_total_count
|
|
90
|
+
min_total_count: param.min_total_count,
|
|
91
|
+
storage_type: param.storage_type
|
|
89
92
|
};
|
|
90
93
|
const sample_size_limit = 8;
|
|
91
94
|
let result;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { getData } from "../src/termdb.matrix.js";
|
|
2
|
+
import { boxplot_getvalue } from "../src/utils.js";
|
|
3
|
+
import { sortKey2values } from "../src/termdb.violin.js";
|
|
4
|
+
const api = {
|
|
5
|
+
endpoint: "termdb/boxplot",
|
|
6
|
+
methods: {
|
|
7
|
+
all: {
|
|
8
|
+
init,
|
|
9
|
+
request: {
|
|
10
|
+
typeId: "BoxplotRequest"
|
|
11
|
+
},
|
|
12
|
+
response: {
|
|
13
|
+
typeId: "BoxplotResponse"
|
|
14
|
+
},
|
|
15
|
+
examples: []
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
function init({ genomes }) {
|
|
20
|
+
return async (req, res) => {
|
|
21
|
+
const q = req.query;
|
|
22
|
+
try {
|
|
23
|
+
const genome = genomes[q.genome];
|
|
24
|
+
if (!genome)
|
|
25
|
+
throw "invalid genome name";
|
|
26
|
+
const ds = genome.datasets?.[q.dslabel];
|
|
27
|
+
if (!ds)
|
|
28
|
+
throw "invalid ds";
|
|
29
|
+
const terms = [q.tw];
|
|
30
|
+
if (q.divideTw)
|
|
31
|
+
terms.push(q.divideTw);
|
|
32
|
+
const data = await getData(
|
|
33
|
+
{
|
|
34
|
+
filter: q.filter,
|
|
35
|
+
filter0: q.filter0,
|
|
36
|
+
terms
|
|
37
|
+
},
|
|
38
|
+
ds,
|
|
39
|
+
genome
|
|
40
|
+
);
|
|
41
|
+
if (data.error)
|
|
42
|
+
throw data.error;
|
|
43
|
+
const sampleType = `All ${data.sampleType?.plural_name || "samples"}`;
|
|
44
|
+
const key2values = /* @__PURE__ */ new Map();
|
|
45
|
+
const overlayTerm = q.divideTw;
|
|
46
|
+
for (const [key, val] of Object.entries(data.samples)) {
|
|
47
|
+
const value = val[q.tw.$id];
|
|
48
|
+
if (!Number.isFinite(value?.value))
|
|
49
|
+
continue;
|
|
50
|
+
if (overlayTerm) {
|
|
51
|
+
if (!val[overlayTerm?.$id])
|
|
52
|
+
continue;
|
|
53
|
+
const value2 = val[overlayTerm.$id];
|
|
54
|
+
if (!key2values.has(value2.key))
|
|
55
|
+
key2values.set(value2.key, []);
|
|
56
|
+
key2values.get(value2.key).push(value.value);
|
|
57
|
+
} else {
|
|
58
|
+
if (!key2values.has(sampleType))
|
|
59
|
+
key2values.set(sampleType, []);
|
|
60
|
+
key2values.get(sampleType).push(value.value);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const plots = [];
|
|
64
|
+
let absMin, absMax, maxLabelLgth;
|
|
65
|
+
for (const [key, values] of sortKey2values(data, key2values, overlayTerm)) {
|
|
66
|
+
const sortedValues = values.sort((a, b) => a - b);
|
|
67
|
+
if (!absMin || sortedValues[0] < absMin)
|
|
68
|
+
absMin = sortedValues[0];
|
|
69
|
+
if (!absMax || sortedValues[sortedValues.length - 1] > absMax)
|
|
70
|
+
absMax = sortedValues[sortedValues.length - 1];
|
|
71
|
+
const vs = sortedValues.map((v) => {
|
|
72
|
+
const value = { value: v };
|
|
73
|
+
return value;
|
|
74
|
+
});
|
|
75
|
+
if (overlayTerm) {
|
|
76
|
+
let label = overlayTerm?.term?.values?.[key]?.label || key;
|
|
77
|
+
label = `${label}, n=${values.length}`;
|
|
78
|
+
if (!maxLabelLgth || label.length > maxLabelLgth.length)
|
|
79
|
+
maxLabelLgth = label.length;
|
|
80
|
+
const plot = {
|
|
81
|
+
// label,
|
|
82
|
+
// values,
|
|
83
|
+
seriesId: key,
|
|
84
|
+
color: overlayTerm?.term?.values?.[key]?.color || null,
|
|
85
|
+
boxplot: boxplot_getvalue(vs),
|
|
86
|
+
//Need sd and mean?
|
|
87
|
+
// plotValueCount: values.length,
|
|
88
|
+
min: sortedValues[0],
|
|
89
|
+
max: sortedValues[sortedValues.length - 1]
|
|
90
|
+
};
|
|
91
|
+
plot.boxplot.label = label;
|
|
92
|
+
plots.push(plot);
|
|
93
|
+
} else {
|
|
94
|
+
const label = `${sampleType}, n=${values.length}`;
|
|
95
|
+
if (!maxLabelLgth || label.length > maxLabelLgth.length)
|
|
96
|
+
maxLabelLgth = label.length;
|
|
97
|
+
const plot = {
|
|
98
|
+
// label,
|
|
99
|
+
// values,
|
|
100
|
+
// plotValueCount: values.length,
|
|
101
|
+
boxplot: boxplot_getvalue(vs),
|
|
102
|
+
min: sortedValues[0],
|
|
103
|
+
max: sortedValues[sortedValues.length - 1]
|
|
104
|
+
};
|
|
105
|
+
plot.boxplot.label = label;
|
|
106
|
+
plots.push(plot);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
data.plots = plots;
|
|
110
|
+
data.absMin = absMin;
|
|
111
|
+
data.absMax = absMax;
|
|
112
|
+
data.maxLabelLgth = maxLabelLgth;
|
|
113
|
+
res.send(data);
|
|
114
|
+
} catch (e) {
|
|
115
|
+
res.send({ error: e?.message || e });
|
|
116
|
+
if (e instanceof Error && e.stack)
|
|
117
|
+
console.log(e);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
export {
|
|
122
|
+
api
|
|
123
|
+
};
|
package/routes/termdb.config.js
CHANGED
|
@@ -64,8 +64,8 @@ function make(q, res, ds, genome) {
|
|
|
64
64
|
hasSampleAncestry: ds.cohort.termdb.hasSampleAncestry,
|
|
65
65
|
defaultChartType: ds.cohort.defaultChartType
|
|
66
66
|
};
|
|
67
|
-
if (tdb.
|
|
68
|
-
c.
|
|
67
|
+
if (tdb.plotConfigByCohort)
|
|
68
|
+
c.plotConfigByCohort = tdb.plotConfigByCohort;
|
|
69
69
|
if (tdb.multipleTestingCorrection)
|
|
70
70
|
c.multipleTestingCorrection = tdb.multipleTestingCorrection;
|
|
71
71
|
if (tdb.neuroOncRegression)
|
|
@@ -222,7 +222,7 @@ function addNonDictionaryQueries(c, ds, genome) {
|
|
|
222
222
|
width: q.singleCell.data.width,
|
|
223
223
|
height: q.singleCell.data.height,
|
|
224
224
|
plots: q.singleCell.data.plots.map((p) => {
|
|
225
|
-
return { name: p.name, colorColumns: p.colorColumns.map((c2) => c2.name) };
|
|
225
|
+
return { name: p.name, colorColumns: p.colorColumns.map((c2) => c2.name), selected: p.selected };
|
|
226
226
|
})
|
|
227
227
|
}
|
|
228
228
|
};
|
|
@@ -3,6 +3,7 @@ import serverconfig from "#src/serverconfig.js";
|
|
|
3
3
|
import { get_samples } from "#src/termdb.sql.js";
|
|
4
4
|
import { makeFilter } from "#src/mds3.gdc.js";
|
|
5
5
|
import { cachedFetch } from "#src/utils.js";
|
|
6
|
+
import { joinUrl } from "#src/helpers.ts";
|
|
6
7
|
const api = {
|
|
7
8
|
endpoint: "termdb/topVariablyExpressedGenes",
|
|
8
9
|
methods: {
|
|
@@ -181,10 +182,9 @@ function gdcValidateQuery(ds, genome) {
|
|
|
181
182
|
throw "The server has not finished caching the case IDs: try again in about 2 minutes.";
|
|
182
183
|
}
|
|
183
184
|
const { host, headers } = ds.getHostHeaders(q);
|
|
184
|
-
const url = `${host.geneExp}/gene_expression/gene_selection`;
|
|
185
185
|
try {
|
|
186
186
|
const response = await cachedFetch(
|
|
187
|
-
|
|
187
|
+
joinUrl(host.geneExp, "/gene_expression/gene_selection"),
|
|
188
188
|
{
|
|
189
189
|
method: "POST",
|
|
190
190
|
headers,
|