@sjcrh/proteinpaint-server 2.104.0 → 2.106.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/gdc.maf.js +23 -16
- package/routes/gdc.mafBuild.js +14 -22
- package/routes/genesetEnrichment.js +1 -0
- package/routes/termdb.DE.js +3 -0
- package/routes/termdb.config.js +0 -1
- package/src/app.js +170 -157
- package/utils/edge.R +52 -9
- package/utils/gsea.py +129 -118
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.106.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",
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@sjcrh/augen": "2.87.0",
|
|
62
62
|
"@sjcrh/proteinpaint-rust": "2.99.0",
|
|
63
|
-
"@sjcrh/proteinpaint-shared": "2.
|
|
64
|
-
"@sjcrh/proteinpaint-types": "2.
|
|
63
|
+
"@sjcrh/proteinpaint-shared": "2.106.0",
|
|
64
|
+
"@sjcrh/proteinpaint-types": "2.106.0",
|
|
65
65
|
"@types/express": "^5.0.0",
|
|
66
66
|
"@types/express-session": "^1.18.1",
|
|
67
67
|
"better-sqlite3": "^9.4.1",
|
package/routes/gdc.maf.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { gdcMafPayload } from "#types/checkers";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import ky from "ky";
|
|
3
|
+
import { joinUrl } from "#shared/joinUrl.js";
|
|
4
4
|
import serverconfig from "#src/serverconfig.js";
|
|
5
5
|
const maxFileNumber = 1e3;
|
|
6
6
|
const allowedWorkflowType = "Aliquot Ensemble Somatic Variant Merging and Masking";
|
|
@@ -49,8 +49,8 @@ async function listMafFiles(q, ds) {
|
|
|
49
49
|
if (q.filter0) {
|
|
50
50
|
case_filters.content.push(q.filter0);
|
|
51
51
|
}
|
|
52
|
-
const { host
|
|
53
|
-
const
|
|
52
|
+
const { host } = ds.getHostHeaders(q);
|
|
53
|
+
const body = {
|
|
54
54
|
filters,
|
|
55
55
|
size: maxFileNumber,
|
|
56
56
|
fields: [
|
|
@@ -62,19 +62,16 @@ async function listMafFiles(q, ds) {
|
|
|
62
62
|
// case uuid for making case url link to portal
|
|
63
63
|
"cases.submitter_id",
|
|
64
64
|
// used when listing all cases & files
|
|
65
|
-
"cases.samples.
|
|
66
|
-
|
|
65
|
+
"cases.samples.tissue_type",
|
|
66
|
+
"cases.samples.tumor_descriptor"
|
|
67
67
|
].join(",")
|
|
68
68
|
};
|
|
69
69
|
if (case_filters.content.length)
|
|
70
|
-
|
|
71
|
-
const response = await
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
} catch (_) {
|
|
76
|
-
throw "invalid JSON from " + api.endpoint;
|
|
77
|
-
}
|
|
70
|
+
body.case_filters = case_filters;
|
|
71
|
+
const response = await ky.post(joinUrl(host.rest, "files"), { timeout: false, json: body });
|
|
72
|
+
if (!response.ok)
|
|
73
|
+
throw `HTTP Error: ${response.status} ${response.statusText}`;
|
|
74
|
+
const re = await response.json();
|
|
78
75
|
if (!Number.isInteger(re.data?.pagination?.total))
|
|
79
76
|
throw "re.data.pagination.total is not int";
|
|
80
77
|
if (!Array.isArray(re.data?.hits))
|
|
@@ -89,10 +86,20 @@ async function listMafFiles(q, ds) {
|
|
|
89
86
|
project_id: c.project.project_id,
|
|
90
87
|
file_size: h.file_size,
|
|
91
88
|
case_submitter_id: c.submitter_id,
|
|
92
|
-
case_uuid: c.case_id
|
|
89
|
+
case_uuid: c.case_id,
|
|
90
|
+
sample_types: []
|
|
93
91
|
};
|
|
94
92
|
if (c.samples) {
|
|
95
|
-
|
|
93
|
+
let normalTypeName;
|
|
94
|
+
for (const { tumor_descriptor, tissue_type } of c.samples) {
|
|
95
|
+
if (tissue_type == "Normal") {
|
|
96
|
+
normalTypeName = (tumor_descriptor == "Not Applicable" ? "" : tumor_descriptor + " ") + tissue_type;
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
file.sample_types.push(tumor_descriptor + " " + tissue_type);
|
|
100
|
+
}
|
|
101
|
+
if (normalTypeName)
|
|
102
|
+
file.sample_types.push(normalTypeName);
|
|
96
103
|
}
|
|
97
104
|
files.push(file);
|
|
98
105
|
}
|
package/routes/gdc.mafBuild.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import ky from "ky";
|
|
2
|
+
import { joinUrl } from "#shared/joinUrl.js";
|
|
3
3
|
import { run_rust_stream } from "@sjcrh/proteinpaint-rust";
|
|
4
|
-
import serverconfig from "#src/serverconfig.js";
|
|
5
4
|
import { gdcMafPayload } from "#types/checkers";
|
|
6
5
|
import { maxTotalSizeCompressed } from "./gdc.maf.ts";
|
|
6
|
+
import { mayLog } from "#src/helpers.ts";
|
|
7
7
|
const api = {
|
|
8
8
|
endpoint: "gdc/mafBuild",
|
|
9
9
|
methods: {
|
|
@@ -37,17 +37,13 @@ function init({ genomes }) {
|
|
|
37
37
|
}
|
|
38
38
|
async function buildMaf(q, res, ds) {
|
|
39
39
|
const t0 = Date.now();
|
|
40
|
-
const { host
|
|
41
|
-
const fileLst2 = await getFileLstUnderSizeLimit(q.fileIdLst, host
|
|
42
|
-
|
|
43
|
-
console.log(
|
|
44
|
-
`${fileLst2.length} out of ${q.fileIdLst.length} input MAF files accepted by size limit`,
|
|
45
|
-
Date.now() - t0
|
|
46
|
-
);
|
|
40
|
+
const { host } = ds.getHostHeaders(q);
|
|
41
|
+
const fileLst2 = await getFileLstUnderSizeLimit(q.fileIdLst, host);
|
|
42
|
+
mayLog(`${fileLst2.length} out of ${q.fileIdLst.length} input MAF files accepted by size limit`, Date.now() - t0);
|
|
47
43
|
const arg = {
|
|
48
44
|
fileIdLst: fileLst2,
|
|
49
45
|
columns: q.columns,
|
|
50
|
-
host:
|
|
46
|
+
host: joinUrl(host.rest, "data")
|
|
51
47
|
// must use the /data/ endpoint from current host
|
|
52
48
|
};
|
|
53
49
|
const rustStream = run_rust_stream("gdcmaf", JSON.stringify(arg));
|
|
@@ -55,8 +51,7 @@ async function buildMaf(q, res, ds) {
|
|
|
55
51
|
res.setHeader("Content-Disposition", "attachment; filename=cohort.maf.gz");
|
|
56
52
|
rustStream.pipe(res);
|
|
57
53
|
rustStream.on("end", () => {
|
|
58
|
-
|
|
59
|
-
console.log("rust gdcmaf", Date.now() - t0);
|
|
54
|
+
mayLog("rust gdcmaf", Date.now() - t0);
|
|
60
55
|
res.end();
|
|
61
56
|
});
|
|
62
57
|
rustStream.on("error", (err) => {
|
|
@@ -65,10 +60,10 @@ async function buildMaf(q, res, ds) {
|
|
|
65
60
|
res.end("Internal Server Error");
|
|
66
61
|
});
|
|
67
62
|
}
|
|
68
|
-
async function getFileLstUnderSizeLimit(lst, host
|
|
63
|
+
async function getFileLstUnderSizeLimit(lst, host) {
|
|
69
64
|
if (lst.length == 0)
|
|
70
65
|
throw "fileIdLst[] not array or blank";
|
|
71
|
-
const
|
|
66
|
+
const body = {
|
|
72
67
|
filters: {
|
|
73
68
|
op: "in",
|
|
74
69
|
content: { field: "file_id", value: lst }
|
|
@@ -76,13 +71,10 @@ async function getFileLstUnderSizeLimit(lst, host, headers) {
|
|
|
76
71
|
size: 1e4,
|
|
77
72
|
fields: "file_size"
|
|
78
73
|
};
|
|
79
|
-
const response = await
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
} catch (_) {
|
|
84
|
-
throw "invalid json from getFileLstUnderSizeLimit";
|
|
85
|
-
}
|
|
74
|
+
const response = await ky.post(joinUrl(host.rest, "files"), { timeout: false, json: body });
|
|
75
|
+
if (!response.ok)
|
|
76
|
+
throw `HTTP Error: ${response.status} ${response.statusText}`;
|
|
77
|
+
const re = await response.json();
|
|
86
78
|
if (!Array.isArray(re.data?.hits))
|
|
87
79
|
throw "re.data.hits[] not array";
|
|
88
80
|
const out = [];
|
|
@@ -56,6 +56,7 @@ async function run_genesetEnrichment_analysis(q, genomes) {
|
|
|
56
56
|
cachedir: serverconfig.cachedir,
|
|
57
57
|
geneset_name: q.geneset_name,
|
|
58
58
|
pickle_file: q.pickle_file,
|
|
59
|
+
num_permutations: q.num_permutations,
|
|
59
60
|
genedb: path.join(serverconfig.tpmasterdir, genomes[q.genome].genedb.dbfile),
|
|
60
61
|
filter_non_coding_genes: q.filter_non_coding_genes
|
|
61
62
|
};
|
package/routes/termdb.DE.js
CHANGED
|
@@ -120,6 +120,9 @@ async function run_DE(param, ds, term_results) {
|
|
|
120
120
|
const sample_size_limit = 8;
|
|
121
121
|
let result;
|
|
122
122
|
if (group1names.length <= sample_size_limit && group2names.length <= sample_size_limit || param.method == "edgeR") {
|
|
123
|
+
if (param.method == "edgeR") {
|
|
124
|
+
expression_input.VarGenes = param.VarGenes;
|
|
125
|
+
}
|
|
123
126
|
const time1 = (/* @__PURE__ */ new Date()).valueOf();
|
|
124
127
|
result = JSON.parse(
|
|
125
128
|
await run_R(path.join(serverconfig.binpath, "utils", "edge.R"), JSON.stringify(expression_input))
|
package/routes/termdb.config.js
CHANGED
|
@@ -215,7 +215,6 @@ function addNonDictionaryQueries(c, ds, genome) {
|
|
|
215
215
|
if (q.singleCell) {
|
|
216
216
|
q2.singleCell = {
|
|
217
217
|
samples: {
|
|
218
|
-
firstColumnName: q.singleCell.samples.firstColumnName,
|
|
219
218
|
sampleColumns: q.singleCell.samples.sampleColumns,
|
|
220
219
|
experimentColumns: q.singleCell.samples.experimentColumns,
|
|
221
220
|
extraSampleTabLabel: q.singleCell.samples.extraSampleTabLabel
|