@sjcrh/proteinpaint-server 2.178.0 → 2.178.1-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.boxplot.js +7 -7
- package/routes/termdb.chat2.js +16 -4
- package/routes/termdb.sampleScatter.js +8 -8
- package/routes/termdb.violin.js +17 -7
- package/src/app.js +270 -62
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-server",
|
|
3
|
-
"version": "2.178.0",
|
|
3
|
+
"version": "2.178.1-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",
|
|
@@ -65,8 +65,8 @@
|
|
|
65
65
|
"@sjcrh/proteinpaint-python": "2.178.0",
|
|
66
66
|
"@sjcrh/proteinpaint-r": "2.178.0",
|
|
67
67
|
"@sjcrh/proteinpaint-rust": "2.178.0",
|
|
68
|
-
"@sjcrh/proteinpaint-shared": "2.178.0",
|
|
69
|
-
"@sjcrh/proteinpaint-types": "2.178.0",
|
|
68
|
+
"@sjcrh/proteinpaint-shared": "2.178.1-0",
|
|
69
|
+
"@sjcrh/proteinpaint-types": "2.178.1-0",
|
|
70
70
|
"@types/express": "^5.0.0",
|
|
71
71
|
"@types/express-session": "^1.18.1",
|
|
72
72
|
"better-sqlite3": "^12.4.1",
|
package/routes/termdb.boxplot.js
CHANGED
|
@@ -22,14 +22,14 @@ const api = {
|
|
|
22
22
|
function init({ genomes }) {
|
|
23
23
|
return async (req, res) => {
|
|
24
24
|
const q = req.query;
|
|
25
|
-
const genome = genomes[q.genome];
|
|
26
|
-
if (!genome) throw new Error("invalid genome name");
|
|
27
|
-
const ds = genome.datasets?.[q.dslabel];
|
|
28
|
-
if (!ds) throw new Error("invalid ds");
|
|
29
|
-
const terms = [q.tw];
|
|
30
|
-
if (q.overlayTw) terms.push(q.overlayTw);
|
|
31
|
-
if (q.divideTw) terms.push(q.divideTw);
|
|
32
25
|
try {
|
|
26
|
+
const genome = genomes[q.genome];
|
|
27
|
+
if (!genome) throw new Error("invalid genome name");
|
|
28
|
+
const ds = genome.datasets?.[q.dslabel];
|
|
29
|
+
if (!ds) throw new Error("invalid dslabel");
|
|
30
|
+
const terms = [q.tw];
|
|
31
|
+
if (q.overlayTw) terms.push(q.overlayTw);
|
|
32
|
+
if (q.divideTw) terms.push(q.divideTw);
|
|
33
33
|
const data = await getData(
|
|
34
34
|
{ filter: q.filter, filter0: q.filter0, terms, __protected__: q.__protected__, __abortSignal: q.__abortSignal },
|
|
35
35
|
ds
|
package/routes/termdb.chat2.js
CHANGED
|
@@ -7,6 +7,7 @@ import { extract_DE_search_terms_from_query } from "./chat/DEagent.ts";
|
|
|
7
7
|
import { extract_summary_terms } from "./chat/summaryagent.ts";
|
|
8
8
|
import { extract_matrix_search_terms_from_query } from "./chat/matrixagent.ts";
|
|
9
9
|
import { extract_samplescatter_terms_from_query } from "./chat/samplescatteragent.ts";
|
|
10
|
+
import { extract_hiercluster_terms_from_query } from "./chat/hierclusteragent.ts";
|
|
10
11
|
import { parse_dataset_db, parse_geneset_db, getGenesetNames } from "./chat/utils.ts";
|
|
11
12
|
import serverconfig from "../src/serverconfig.js";
|
|
12
13
|
import { mayLog } from "#src/helpers.ts";
|
|
@@ -50,7 +51,6 @@ function init({ genomes }) {
|
|
|
50
51
|
const ai_output_json = await run_chat_pipeline(
|
|
51
52
|
q.prompt,
|
|
52
53
|
llm,
|
|
53
|
-
serverconfig.aiRoute,
|
|
54
54
|
dataset_json,
|
|
55
55
|
testing,
|
|
56
56
|
dataset_db,
|
|
@@ -65,7 +65,7 @@ function init({ genomes }) {
|
|
|
65
65
|
}
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
|
-
async function run_chat_pipeline(user_prompt, llm,
|
|
68
|
+
async function run_chat_pipeline(user_prompt, llm, dataset_json, testing, dataset_db, genedb, ds, genesetNames = []) {
|
|
69
69
|
const time1 = (/* @__PURE__ */ new Date()).valueOf();
|
|
70
70
|
const class_response = await classifyQuery(user_prompt, llm);
|
|
71
71
|
let ai_output_json;
|
|
@@ -84,9 +84,8 @@ async function run_chat_pipeline(user_prompt, llm, aiRoute, dataset_json, testin
|
|
|
84
84
|
}
|
|
85
85
|
} else if (class_response.type == "plot") {
|
|
86
86
|
const classResult = await classifyPlotType(user_prompt, llm);
|
|
87
|
-
mayLog("classResult:", classResult);
|
|
88
87
|
const dataset_db_output = await parse_dataset_db(dataset_db);
|
|
89
|
-
const genes_list =
|
|
88
|
+
const genes_list = await parse_geneset_db(genedb);
|
|
90
89
|
if (classResult == "summary") {
|
|
91
90
|
const time12 = (/* @__PURE__ */ new Date()).valueOf();
|
|
92
91
|
ai_output_json = await extract_summary_terms(
|
|
@@ -139,6 +138,19 @@ async function run_chat_pipeline(user_prompt, llm, aiRoute, dataset_json, testin
|
|
|
139
138
|
genesetNames
|
|
140
139
|
);
|
|
141
140
|
mayLog("Time taken for sampleScatter agent:", formatElapsedTime(Date.now() - time12));
|
|
141
|
+
} else if (classResult == "hiercluster") {
|
|
142
|
+
const time12 = (/* @__PURE__ */ new Date()).valueOf();
|
|
143
|
+
ai_output_json = await extract_hiercluster_terms_from_query(
|
|
144
|
+
user_prompt,
|
|
145
|
+
llm,
|
|
146
|
+
dataset_db_output,
|
|
147
|
+
dataset_json,
|
|
148
|
+
genes_list,
|
|
149
|
+
ds,
|
|
150
|
+
testing,
|
|
151
|
+
genesetNames
|
|
152
|
+
);
|
|
153
|
+
mayLog("Time taken for hierCluster agent:", formatElapsedTime(Date.now() - time12));
|
|
142
154
|
} else {
|
|
143
155
|
ai_output_json = { type: "text", text: "Unknown classification value" };
|
|
144
156
|
}
|
|
@@ -23,15 +23,15 @@ const api = {
|
|
|
23
23
|
const refColor = "#F5F5DC";
|
|
24
24
|
function init({ genomes }) {
|
|
25
25
|
return async function(req, res) {
|
|
26
|
-
const q = req.query;
|
|
27
|
-
if (!q.genome || !q.dslabel) {
|
|
28
|
-
throw new Error("Genome and dataset label are required for termdb/sampleScatter request.");
|
|
29
|
-
}
|
|
30
|
-
const g = genomes[q.genome];
|
|
31
|
-
const ds = g.datasets[q.dslabel];
|
|
32
|
-
if (q.singleCellPlot)
|
|
33
|
-
return getSingleCellScatter(req, res, ds);
|
|
34
26
|
try {
|
|
27
|
+
const q = req.query;
|
|
28
|
+
if (!q.genome || !q.dslabel) {
|
|
29
|
+
throw new Error("Genome and dataset label are required for termdb/sampleScatter request.");
|
|
30
|
+
}
|
|
31
|
+
const g = genomes[q.genome];
|
|
32
|
+
const ds = g.datasets[q.dslabel];
|
|
33
|
+
if (q.singleCellPlot)
|
|
34
|
+
return getSingleCellScatter(req, res, ds);
|
|
35
35
|
let refSamples = [], cohortSamples;
|
|
36
36
|
const terms = [];
|
|
37
37
|
if (q.colorTW) terms.push(q.colorTW);
|
package/routes/termdb.violin.js
CHANGED
|
@@ -190,9 +190,10 @@ async function createCanvasImg(q, result, ds) {
|
|
|
190
190
|
const chart = result.charts[k];
|
|
191
191
|
const plot2Values = {};
|
|
192
192
|
for (const plot of chart.plots) plot2Values[plot.label] = plot.values;
|
|
193
|
-
const densities = await getDensities(plot2Values);
|
|
194
|
-
let axisScale;
|
|
195
193
|
const useLog = q.unit == "log";
|
|
194
|
+
const logBase = ds.cohort.termdb.logscaleBase2 ? 2 : 10;
|
|
195
|
+
const densities = await getDensities(plot2Values, useLog, logBase);
|
|
196
|
+
let axisScale;
|
|
196
197
|
if (useLog) {
|
|
197
198
|
axisScale = scaleLog().base(ds.cohort.termdb.logscaleBase2 ? 2 : 10).domain([result.min, result.max]).range(isH ? [0, q.svgw] : [q.svgw, 0]);
|
|
198
199
|
} else {
|
|
@@ -241,8 +242,16 @@ async function getDensity(values) {
|
|
|
241
242
|
const result = await getDensities({ plot: values });
|
|
242
243
|
return result.plot;
|
|
243
244
|
}
|
|
244
|
-
async function getDensities(plot2Values) {
|
|
245
|
-
|
|
245
|
+
async function getDensities(plot2Values, useLog = false, logBase = 10) {
|
|
246
|
+
let transformedPlot2Values = {};
|
|
247
|
+
if (useLog) {
|
|
248
|
+
for (const plot in plot2Values) {
|
|
249
|
+
transformedPlot2Values[plot] = plot2Values[plot].filter((v) => v > 0).map((v) => Math.log(v) / Math.log(logBase));
|
|
250
|
+
}
|
|
251
|
+
} else {
|
|
252
|
+
transformedPlot2Values = plot2Values;
|
|
253
|
+
}
|
|
254
|
+
const plot2Density = JSON.parse(await run_R("density.R", JSON.stringify({ plot2Values: transformedPlot2Values })));
|
|
246
255
|
const densities = {};
|
|
247
256
|
for (const plot in plot2Density) {
|
|
248
257
|
const result = plot2Density[plot];
|
|
@@ -253,11 +262,12 @@ async function getDensities(plot2Values) {
|
|
|
253
262
|
let xMax = -Infinity;
|
|
254
263
|
for (const [i, x] of Object.entries(result.x)) {
|
|
255
264
|
const density2 = result.y[i];
|
|
256
|
-
|
|
257
|
-
|
|
265
|
+
const x0 = useLog ? Math.pow(logBase, x) : x;
|
|
266
|
+
xMin = Math.min(xMin, x0);
|
|
267
|
+
xMax = Math.max(xMax, x0);
|
|
258
268
|
densityMin = Math.min(densityMin, density2);
|
|
259
269
|
densityMax = Math.max(densityMax, density2);
|
|
260
|
-
bins.push({ x0
|
|
270
|
+
bins.push({ x0, density: density2 });
|
|
261
271
|
}
|
|
262
272
|
bins.unshift({ x0: xMin, density: densityMin });
|
|
263
273
|
bins.push({ x0: xMax, density: densityMin });
|