@sjcrh/proteinpaint-server 2.114.0 → 2.115.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 +6 -5
- package/routes/correlationVolcano.js +4 -1
- package/routes/samplewsimages.js +23 -35
- package/routes/termdb.topMutatedGenes.js +51 -0
- package/routes/wsisamples.js +74 -0
- package/src/app.js +501 -611
- package/src/serverconfig.js +1 -1
- package/routes/gdc.topMutatedGenes.js +0 -275
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.115.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",
|
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
"start": "tsx watch . /start.js",
|
|
20
20
|
"test:unit": "tsx emitImports.js unit > serverTests.js && c8 tsx serverTests.js && rm -rf ./cache",
|
|
21
21
|
"precombined:coverage": "tsx emitImports.js unit > serverTests.js",
|
|
22
|
-
"combined:coverage": "
|
|
22
|
+
"combined:coverage": "coverageKey=test c8 --all --src=proteinpaint/server --experimental-monocart -r=v8 -r=html -r=json -r=markdown-summary -r=markdown-details -o=./.coverage tsx ./coverage.js & ",
|
|
23
23
|
"postcombined:coverage": "rm -rf ./cache",
|
|
24
|
+
"spec:coverage": "tsx test/relevant.js",
|
|
24
25
|
"getconf": "../build/getConfigProp.js",
|
|
25
26
|
"doc": "../augen/build.sh routes shared/types/routes shared/checkers ../public/docs/server",
|
|
26
27
|
"mjs": "esbuild \"$DIR/*.ts\" --platform=node --outdir=\"$DIR\" --format=esm",
|
|
@@ -64,10 +65,10 @@
|
|
|
64
65
|
"typescript": "^5.6.3"
|
|
65
66
|
},
|
|
66
67
|
"dependencies": {
|
|
67
|
-
"@sjcrh/augen": "2.
|
|
68
|
+
"@sjcrh/augen": "2.115.0",
|
|
68
69
|
"@sjcrh/proteinpaint-rust": "2.114.0",
|
|
69
|
-
"@sjcrh/proteinpaint-shared": "2.
|
|
70
|
-
"@sjcrh/proteinpaint-types": "2.
|
|
70
|
+
"@sjcrh/proteinpaint-shared": "2.115.0",
|
|
71
|
+
"@sjcrh/proteinpaint-types": "2.115.0",
|
|
71
72
|
"@types/express": "^5.0.0",
|
|
72
73
|
"@types/express-session": "^1.18.1",
|
|
73
74
|
"better-sqlite3": "^9.4.1",
|
|
@@ -5,6 +5,7 @@ import serverconfig from "../src/serverconfig.js";
|
|
|
5
5
|
import { mayLog } from "#src/helpers.ts";
|
|
6
6
|
import path from "path";
|
|
7
7
|
import { getStdDev } from "#shared/descriptive.stats.js";
|
|
8
|
+
import { formatElapsedTime } from "#shared/time.js";
|
|
8
9
|
const minArrayLength = 3;
|
|
9
10
|
const minSD = 0.05;
|
|
10
11
|
const api = {
|
|
@@ -92,7 +93,9 @@ async function compute(q, ds, genome) {
|
|
|
92
93
|
const output = {
|
|
93
94
|
terms: JSON.parse(await run_R(path.join(serverconfig.binpath, "utils", "corr.R"), JSON.stringify(input)))
|
|
94
95
|
};
|
|
95
|
-
|
|
96
|
+
const elapsedMs = Date.now() - time1;
|
|
97
|
+
const formattedTime = formatElapsedTime(elapsedMs);
|
|
98
|
+
mayLog("Time taken to run correlation analysis:", formattedTime);
|
|
96
99
|
for (const t of output.terms) {
|
|
97
100
|
const t2 = {
|
|
98
101
|
tw$id: t.id,
|
package/routes/samplewsimages.js
CHANGED
|
@@ -23,18 +23,7 @@ function init({ genomes }) {
|
|
|
23
23
|
if (!ds)
|
|
24
24
|
throw "invalid dataset name";
|
|
25
25
|
const sampleId = query.sample_id;
|
|
26
|
-
|
|
27
|
-
const images2 = [];
|
|
28
|
-
if (ds.queries.WSImages.sources) {
|
|
29
|
-
images2.push({
|
|
30
|
-
filename: sampleId + "_fsspec.json",
|
|
31
|
-
metadata: ""
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
res.send({ sampleWSImages: images2 });
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const images = await ds.queries.WSImages.getWSImages({ sampleId });
|
|
26
|
+
const images = await ds.queries.WSImages.getWSImages(sampleId);
|
|
38
27
|
res.send({ sampleWSImages: images });
|
|
39
28
|
} catch (e) {
|
|
40
29
|
console.log(e);
|
|
@@ -42,32 +31,31 @@ function init({ genomes }) {
|
|
|
42
31
|
}
|
|
43
32
|
};
|
|
44
33
|
}
|
|
45
|
-
function validate_query_getSampleWSImages(ds) {
|
|
46
|
-
|
|
47
|
-
if (!q)
|
|
34
|
+
async function validate_query_getSampleWSImages(ds) {
|
|
35
|
+
if (!ds.queries?.WSImages)
|
|
48
36
|
return;
|
|
49
|
-
|
|
37
|
+
validateQuery(ds);
|
|
50
38
|
}
|
|
51
|
-
function
|
|
52
|
-
ds.queries.WSImages.getWSImages
|
|
53
|
-
return
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
async function getWSImages(ds, sampleName) {
|
|
57
|
-
const sql = `SELECT wsimages.filename as filename, wsimages.metadata as metadata
|
|
58
|
-
FROM wsimages
|
|
59
|
-
INNER JOIN sampleidmap
|
|
60
|
-
ON wsimages.sample = sampleidmap.id
|
|
61
|
-
WHERE sampleidmap.name = ?`;
|
|
62
|
-
const rows = ds.cohort.db.connection.prepare(sql).all(sampleName);
|
|
63
|
-
const images = [];
|
|
64
|
-
for (const row of rows) {
|
|
65
|
-
images.push({
|
|
66
|
-
filename: row.filename,
|
|
67
|
-
metadata: row.metadata
|
|
68
|
-
});
|
|
39
|
+
function validateQuery(ds) {
|
|
40
|
+
if (typeof ds.queries.WSImages.getWSImages == "function") {
|
|
41
|
+
return;
|
|
69
42
|
}
|
|
70
|
-
|
|
43
|
+
ds.queries.WSImages.getWSImages = async (sampleName) => {
|
|
44
|
+
const sql = `SELECT wsimages.filename as filename, wsimages.metadata as metadata
|
|
45
|
+
FROM wsimages
|
|
46
|
+
INNER JOIN sampleidmap
|
|
47
|
+
ON wsimages.sample = sampleidmap.id
|
|
48
|
+
WHERE sampleidmap.name = ?`;
|
|
49
|
+
const rows = ds.cohort.db.connection.prepare(sql).all(sampleName);
|
|
50
|
+
const images = [];
|
|
51
|
+
for (const row of rows) {
|
|
52
|
+
images.push({
|
|
53
|
+
filename: row.filename,
|
|
54
|
+
metadata: row.metadata
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return images;
|
|
58
|
+
};
|
|
71
59
|
}
|
|
72
60
|
export {
|
|
73
61
|
api,
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { topMutatedGenePayload } from "#types/checkers";
|
|
2
|
+
const api = {
|
|
3
|
+
endpoint: "termdb/topMutatedGenes",
|
|
4
|
+
methods: {
|
|
5
|
+
get: {
|
|
6
|
+
init,
|
|
7
|
+
...topMutatedGenePayload
|
|
8
|
+
},
|
|
9
|
+
post: {
|
|
10
|
+
init,
|
|
11
|
+
...topMutatedGenePayload
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
function init({ genomes }) {
|
|
16
|
+
return async (req, res) => {
|
|
17
|
+
try {
|
|
18
|
+
const q = req.query;
|
|
19
|
+
const g = genomes[q.genome];
|
|
20
|
+
if (!g)
|
|
21
|
+
throw "genome missing";
|
|
22
|
+
const ds = g.datasets?.[q.dslabel];
|
|
23
|
+
if (!ds)
|
|
24
|
+
throw "ds missing";
|
|
25
|
+
if (!ds.queries?.topMutatedGenes)
|
|
26
|
+
throw "not supported by ds";
|
|
27
|
+
const genes = await ds.queries.topMutatedGenes.get(q);
|
|
28
|
+
const payload = { genes };
|
|
29
|
+
res.send(payload);
|
|
30
|
+
} catch (e) {
|
|
31
|
+
res.send({ status: "error", error: e.message || e });
|
|
32
|
+
if (e.stack)
|
|
33
|
+
console.log(e.stack);
|
|
34
|
+
else
|
|
35
|
+
console.trace(e);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function validate_query_getTopMutatedGenes(ds, genome) {
|
|
40
|
+
const q = ds.queries?.topMutatedGenes;
|
|
41
|
+
if (!q)
|
|
42
|
+
return;
|
|
43
|
+
if (typeof q.get == "function")
|
|
44
|
+
return;
|
|
45
|
+
q.get = async (param) => {
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export {
|
|
49
|
+
api,
|
|
50
|
+
validate_query_getTopMutatedGenes
|
|
51
|
+
};
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { wsiSamplesPayload } from "#types/checkers";
|
|
2
|
+
const routePath = "wsisamples";
|
|
3
|
+
const api = {
|
|
4
|
+
endpoint: `${routePath}`,
|
|
5
|
+
methods: {
|
|
6
|
+
get: {
|
|
7
|
+
...wsiSamplesPayload,
|
|
8
|
+
init
|
|
9
|
+
},
|
|
10
|
+
post: {
|
|
11
|
+
...wsiSamplesPayload,
|
|
12
|
+
init
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
function init({ genomes }) {
|
|
17
|
+
return async (req, res) => {
|
|
18
|
+
try {
|
|
19
|
+
const query = req.query;
|
|
20
|
+
const g = genomes[query.genome];
|
|
21
|
+
if (!g)
|
|
22
|
+
throw new Error("Invalid genome name");
|
|
23
|
+
const ds = g.datasets[query.dslabel];
|
|
24
|
+
if (!ds)
|
|
25
|
+
throw "Invalid dslabel";
|
|
26
|
+
const images = await ds.queries.WSImages.getSamples();
|
|
27
|
+
const payload = {
|
|
28
|
+
samples: images
|
|
29
|
+
};
|
|
30
|
+
res.status(200).json(payload);
|
|
31
|
+
} catch (e) {
|
|
32
|
+
console.warn(e);
|
|
33
|
+
res.status(500).send({
|
|
34
|
+
status: "error",
|
|
35
|
+
error: e.message || e
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
async function validate_query_getWSISamples(ds) {
|
|
41
|
+
const q = ds.queries?.WSImages;
|
|
42
|
+
if (!q)
|
|
43
|
+
return;
|
|
44
|
+
validateQuery(ds);
|
|
45
|
+
}
|
|
46
|
+
function validateQuery(ds) {
|
|
47
|
+
if (typeof ds.queries.WSImages.getSamples == "function") {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
ds.queries.WSImages.getSamples = async () => {
|
|
51
|
+
const sql = `SELECT wsimages.sample as sample, wsimages.filename as filename, wsimages.metadata as metadata, sampleidmap.name as sampleName
|
|
52
|
+
FROM wsimages
|
|
53
|
+
INNER JOIN sampleidmap
|
|
54
|
+
ON wsimages.sample = sampleidmap.id`;
|
|
55
|
+
try {
|
|
56
|
+
const rows = ds.cohort.db.connection.prepare(sql).all();
|
|
57
|
+
const sampleMap = {};
|
|
58
|
+
for (const row of rows) {
|
|
59
|
+
if (!sampleMap[row.sample]) {
|
|
60
|
+
sampleMap[row.sample] = { sampleId: row.sampleName, wsimages: [] };
|
|
61
|
+
}
|
|
62
|
+
sampleMap[row.sample].wsimages.push(row.filename);
|
|
63
|
+
}
|
|
64
|
+
return Object.values(sampleMap);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error("Error fetching samples:", error);
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export {
|
|
72
|
+
api,
|
|
73
|
+
validate_query_getWSISamples
|
|
74
|
+
};
|