@sjcrh/proteinpaint-server 2.180.0 → 2.180.1
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/dataset/termdb.test.js +1 -1
- package/package.json +5 -5
- package/routes/termdb.categories.js +2 -15
- package/routes/termdb.chat2.js +29 -13
- package/routes/termdb.cluster.js +33 -43
- package/routes/termdb.config.js +22 -13
- package/routes/termdb.filterTermValues.js +2 -12
- package/src/app.js +357 -366
package/dataset/termdb.test.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-server",
|
|
3
|
-
"version": "2.180.
|
|
3
|
+
"version": "2.180.1",
|
|
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",
|
|
@@ -63,10 +63,10 @@
|
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@sjcrh/augen": "2.143.0",
|
|
65
65
|
"@sjcrh/proteinpaint-python": "2.179.0",
|
|
66
|
-
"@sjcrh/proteinpaint-r": "2.
|
|
67
|
-
"@sjcrh/proteinpaint-rust": "2.180.0",
|
|
68
|
-
"@sjcrh/proteinpaint-shared": "2.180.
|
|
69
|
-
"@sjcrh/proteinpaint-types": "2.180.
|
|
66
|
+
"@sjcrh/proteinpaint-r": "2.180.1-0",
|
|
67
|
+
"@sjcrh/proteinpaint-rust": "2.180.1-0",
|
|
68
|
+
"@sjcrh/proteinpaint-shared": "2.180.1",
|
|
69
|
+
"@sjcrh/proteinpaint-types": "2.180.1",
|
|
70
70
|
"@types/express": "^5.0.0",
|
|
71
71
|
"@types/express-session": "^1.18.1",
|
|
72
72
|
"better-sqlite3": "^12.4.1",
|
|
@@ -48,23 +48,11 @@ async function trigger_getcategories(q, res, tdb, ds) {
|
|
|
48
48
|
const data = await getData(arg, ds);
|
|
49
49
|
if (data.error) throw data.error;
|
|
50
50
|
const [lst, orderedLabels] = getCategories(data, q, ds, $id);
|
|
51
|
-
const allowedValues = tdb.getRestrictedValues?.(q.__protected__?.clientAuthResult, q.tw.term.id);
|
|
52
|
-
const filtered = filterCategoriesByAllowedValues(lst, orderedLabels, allowedValues);
|
|
53
51
|
res.send({
|
|
54
|
-
lst
|
|
55
|
-
orderedLabels
|
|
52
|
+
lst,
|
|
53
|
+
orderedLabels
|
|
56
54
|
});
|
|
57
55
|
}
|
|
58
|
-
function filterCategoriesByAllowedValues(lst, orderedLabels, allowedValues) {
|
|
59
|
-
if (!allowedValues) {
|
|
60
|
-
return { lst, orderedLabels };
|
|
61
|
-
}
|
|
62
|
-
const allowedValuesSet = new Set(allowedValues.map((v) => String(v)));
|
|
63
|
-
const filteredLst = lst.filter((item) => allowedValuesSet.has(String(item.key)));
|
|
64
|
-
const allowedLabels = new Set(filteredLst.map((item) => item.label));
|
|
65
|
-
const filteredOrderedLabels = orderedLabels.filter((label) => allowedLabels.has(label));
|
|
66
|
-
return { lst: filteredLst, orderedLabels: filteredOrderedLabels };
|
|
67
|
-
}
|
|
68
56
|
function getCategories(data, q, ds, $id) {
|
|
69
57
|
const lst = [];
|
|
70
58
|
if (q.tw.term.type == "geneVariant" && q.tw.q.type != "predefined-groupset" && q.tw.q.type != "custom-groupset") {
|
|
@@ -145,6 +133,5 @@ function getCategories(data, q, ds, $id) {
|
|
|
145
133
|
}
|
|
146
134
|
export {
|
|
147
135
|
api,
|
|
148
|
-
filterCategoriesByAllowedValues,
|
|
149
136
|
getCategories
|
|
150
137
|
};
|
package/routes/termdb.chat2.js
CHANGED
|
@@ -2,7 +2,6 @@ import { ChatPayload } from "#types/checkers";
|
|
|
2
2
|
import { classifyQuery } from "./chat/classify1.ts";
|
|
3
3
|
import { classifyNotPlot } from "./chat/classify2.ts";
|
|
4
4
|
import { classifyPlotType } from "./chat/plot.ts";
|
|
5
|
-
import { readJSONFile } from "./chat/utils.ts";
|
|
6
5
|
import { extract_DE_search_terms_from_query } from "./chat/DEagent.ts";
|
|
7
6
|
import { determineAmbiguousGenePrompt } from "./chat/ambiguousgeneagent.ts";
|
|
8
7
|
import { extract_summary_terms } from "./chat/summaryagent.ts";
|
|
@@ -14,6 +13,9 @@ import { extractGenesFromPrompt, parse_dataset_db, parse_geneset_db, getGenesetN
|
|
|
14
13
|
import serverconfig from "../src/serverconfig.js";
|
|
15
14
|
import { mayLog } from "#src/helpers.ts";
|
|
16
15
|
import { formatElapsedTime } from "#shared";
|
|
16
|
+
import path from "path";
|
|
17
|
+
import fs from "fs";
|
|
18
|
+
import { readJSONFile } from "./chat/utils.ts";
|
|
17
19
|
const api = {
|
|
18
20
|
endpoint: "termdb/chat2",
|
|
19
21
|
methods: {
|
|
@@ -35,8 +37,14 @@ function init({ genomes }) {
|
|
|
35
37
|
if (!g) throw "invalid genome";
|
|
36
38
|
const ds = g.datasets?.[q.dslabel];
|
|
37
39
|
if (!ds) throw "invalid dslabel";
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
const aiFilesDir = serverconfig.binpath + "/../../dataset/ai/" + q.dslabel;
|
|
41
|
+
let agentFiles = [];
|
|
42
|
+
try {
|
|
43
|
+
agentFiles = fs.readdirSync(aiFilesDir).filter((file) => file.endsWith(".json"));
|
|
44
|
+
} catch (err) {
|
|
45
|
+
if (err.code === "ENOENT") throw new Error(`Directory not found: ${aiFilesDir}`);
|
|
46
|
+
if (err.code === "ENOTDIR") throw new Error(`Path is not a directory: ${aiFilesDir}`);
|
|
47
|
+
throw err;
|
|
40
48
|
}
|
|
41
49
|
const llm = serverconfig.llm;
|
|
42
50
|
if (!llm) throw "serverconfig.llm is not configured";
|
|
@@ -45,18 +53,18 @@ function init({ genomes }) {
|
|
|
45
53
|
}
|
|
46
54
|
const dataset_db = serverconfig.tpmasterdir + "/" + ds.cohort.db.file;
|
|
47
55
|
const genedb = serverconfig.tpmasterdir + "/" + g.genedb.dbfile;
|
|
48
|
-
const dataset_json = await readJSONFile(ds?.queries?.chat?.aifiles);
|
|
49
56
|
const testing = false;
|
|
50
57
|
const genesetNames = getGenesetNames(g);
|
|
51
58
|
const ai_output_json = await run_chat_pipeline(
|
|
52
59
|
q.prompt,
|
|
53
60
|
llm,
|
|
54
|
-
dataset_json,
|
|
55
61
|
testing,
|
|
56
62
|
dataset_db,
|
|
57
63
|
genedb,
|
|
58
64
|
ds,
|
|
59
|
-
genesetNames
|
|
65
|
+
genesetNames,
|
|
66
|
+
agentFiles,
|
|
67
|
+
aiFilesDir
|
|
60
68
|
);
|
|
61
69
|
res.send(ai_output_json);
|
|
62
70
|
} catch (e) {
|
|
@@ -65,14 +73,17 @@ function init({ genomes }) {
|
|
|
65
73
|
}
|
|
66
74
|
};
|
|
67
75
|
}
|
|
68
|
-
async function run_chat_pipeline(user_prompt, llm,
|
|
76
|
+
async function run_chat_pipeline(user_prompt, llm, testing, dataset_db, genedb, ds, genesetNames = [], agentFiles, aiFilesDir) {
|
|
77
|
+
if (!fs.existsSync(path.join(aiFilesDir, "main.json")))
|
|
78
|
+
throw "Main data file is not specified for dataset:" + ds.label;
|
|
79
|
+
const dataset_json = await readJSONFile(path.join(aiFilesDir, "main.json"));
|
|
69
80
|
const time1 = (/* @__PURE__ */ new Date()).valueOf();
|
|
70
81
|
const class_response = await classifyQuery(user_prompt, llm);
|
|
71
82
|
let ai_output_json;
|
|
72
83
|
mayLog("Time taken for classification:", formatElapsedTime(Date.now() - time1));
|
|
73
84
|
if (class_response.type == "notplot") {
|
|
74
85
|
const time2 = (/* @__PURE__ */ new Date()).valueOf();
|
|
75
|
-
const notPlotResult = await classifyNotPlot(user_prompt, llm,
|
|
86
|
+
const notPlotResult = await classifyNotPlot(user_prompt, llm, agentFiles, aiFilesDir);
|
|
76
87
|
mayLog("Time taken for classify2:", formatElapsedTime(Date.now() - time2));
|
|
77
88
|
if (notPlotResult.type == "html") {
|
|
78
89
|
ai_output_json = notPlotResult;
|
|
@@ -127,7 +138,8 @@ async function run_chat_pipeline(user_prompt, llm, dataset_json, testing, datase
|
|
|
127
138
|
ds,
|
|
128
139
|
testing,
|
|
129
140
|
genesetNames,
|
|
130
|
-
geneFeatures
|
|
141
|
+
geneFeatures,
|
|
142
|
+
aiFilesDir
|
|
131
143
|
);
|
|
132
144
|
mayLog("Time taken for summary agent:", formatElapsedTime(Date.now() - time12));
|
|
133
145
|
} else if (classResult == "dge") {
|
|
@@ -138,7 +150,8 @@ async function run_chat_pipeline(user_prompt, llm, dataset_json, testing, datase
|
|
|
138
150
|
dataset_db_output,
|
|
139
151
|
dataset_json,
|
|
140
152
|
ds,
|
|
141
|
-
testing
|
|
153
|
+
testing,
|
|
154
|
+
aiFilesDir
|
|
142
155
|
);
|
|
143
156
|
mayLog("Time taken for DE agent:", formatElapsedTime(Date.now() - time12));
|
|
144
157
|
} else if (classResult == "survival") {
|
|
@@ -153,7 +166,8 @@ async function run_chat_pipeline(user_prompt, llm, dataset_json, testing, datase
|
|
|
153
166
|
ds,
|
|
154
167
|
testing,
|
|
155
168
|
genesetNames,
|
|
156
|
-
geneFeatures
|
|
169
|
+
geneFeatures,
|
|
170
|
+
aiFilesDir
|
|
157
171
|
);
|
|
158
172
|
mayLog("Time taken for matrix agent:", formatElapsedTime(Date.now() - time12));
|
|
159
173
|
} else if (classResult == "samplescatter") {
|
|
@@ -166,7 +180,8 @@ async function run_chat_pipeline(user_prompt, llm, dataset_json, testing, datase
|
|
|
166
180
|
ds,
|
|
167
181
|
testing,
|
|
168
182
|
genesetNames,
|
|
169
|
-
geneFeatures
|
|
183
|
+
geneFeatures,
|
|
184
|
+
aiFilesDir
|
|
170
185
|
);
|
|
171
186
|
mayLog("Time taken for sampleScatter agent:", formatElapsedTime(Date.now() - time12));
|
|
172
187
|
} else if (classResult == "hiercluster") {
|
|
@@ -179,7 +194,8 @@ async function run_chat_pipeline(user_prompt, llm, dataset_json, testing, datase
|
|
|
179
194
|
ds,
|
|
180
195
|
testing,
|
|
181
196
|
genesetNames,
|
|
182
|
-
geneFeatures
|
|
197
|
+
geneFeatures,
|
|
198
|
+
aiFilesDir
|
|
183
199
|
);
|
|
184
200
|
mayLog("Time taken for hierCluster agent:", formatElapsedTime(Date.now() - time12));
|
|
185
201
|
} else if (classResult == "lollipop") {
|
package/routes/termdb.cluster.js
CHANGED
|
@@ -7,8 +7,7 @@ import serverconfig from "#src/serverconfig.js";
|
|
|
7
7
|
import { gdc_validate_query_geneExpression } from "#src/mds3.gdc.js";
|
|
8
8
|
import { mayLimitSamples } from "#src/mds3.filter.js";
|
|
9
9
|
import { clusterMethodLst, distanceMethodLst } from "#shared/clustering.js";
|
|
10
|
-
import { TermTypes,
|
|
11
|
-
import { getData } from "#src/termdb.matrix.js";
|
|
10
|
+
import { TermTypes, PROTEOME_ABUNDANCE } from "#shared/terms.js";
|
|
12
11
|
import { termType2label } from "#shared/terms.js";
|
|
13
12
|
import { formatElapsedTime } from "#shared/time.js";
|
|
14
13
|
const api = {
|
|
@@ -35,16 +34,16 @@ function init({ genomes }) {
|
|
|
35
34
|
if (!ds) throw "invalid dataset name";
|
|
36
35
|
if (ds.label === "GDC" && !ds.__gdc?.doneCaching)
|
|
37
36
|
throw "The server has not finished caching the case IDs: try again in about 2 minutes.";
|
|
38
|
-
if ([TermTypes.GENE_EXPRESSION, TermTypes.METABOLITE_INTENSITY
|
|
39
|
-
if (!ds.queries?.[q.dataType]
|
|
40
|
-
throw `no ${q.dataType} data on this dataset`;
|
|
37
|
+
if ([TermTypes.GENE_EXPRESSION, TermTypes.METABOLITE_INTENSITY].includes(q.dataType)) {
|
|
38
|
+
if (!ds.queries?.[q.dataType]) throw `no ${q.dataType} data on this dataset`;
|
|
41
39
|
if (!q.terms) throw `missing gene list`;
|
|
42
40
|
if (!Array.isArray(q.terms)) throw `gene list is not an array`;
|
|
43
41
|
if (q.terms.length < 3)
|
|
44
42
|
throw `A minimum of three genes is required for clustering. Please refresh this page to clear this error.`;
|
|
45
43
|
result = await getResult(q, ds);
|
|
46
|
-
} else if (
|
|
47
|
-
|
|
44
|
+
} else if (PROTEOME_ABUNDANCE == q.dataType) {
|
|
45
|
+
const proteomeQuery = ds.queries?.proteome;
|
|
46
|
+
if (!proteomeQuery?.get) throw `no ${TermTypes.PROTEOME_ABUNDANCE} data getter on this dataset`;
|
|
48
47
|
if (!q.terms) throw `missing gene list`;
|
|
49
48
|
if (!Array.isArray(q.terms)) throw `gene list is not an array`;
|
|
50
49
|
if (q.terms.length < 3)
|
|
@@ -71,12 +70,9 @@ async function getResult(q, ds) {
|
|
|
71
70
|
_q.__abortSignal = q.__abortSignal;
|
|
72
71
|
}
|
|
73
72
|
let term2sample2value, byTermId, bySampleId, skippedSexChrGenes;
|
|
74
|
-
if (q.dataType ==
|
|
73
|
+
if (q.dataType == PROTEOME_ABUNDANCE) {
|
|
75
74
|
;
|
|
76
|
-
({ term2sample2value, byTermId, bySampleId } = await
|
|
77
|
-
} else if (q.dataType == TermTypes.WHOLE_PROTEOME_ABUNDANCE) {
|
|
78
|
-
;
|
|
79
|
-
({ term2sample2value, byTermId, bySampleId, skippedSexChrGenes } = await ds.queries.proteome.whole.get(_q, ds));
|
|
75
|
+
({ term2sample2value, byTermId, bySampleId, skippedSexChrGenes } = await ds.queries.proteome.get(_q));
|
|
80
76
|
} else {
|
|
81
77
|
;
|
|
82
78
|
({ term2sample2value, byTermId, bySampleId, skippedSexChrGenes } = await ds.queries[q.dataType].get(_q, ds));
|
|
@@ -113,28 +109,6 @@ async function getResult(q, ds) {
|
|
|
113
109
|
if (removedHierClusterTerms.length) result.removedHierClusterTerms = removedHierClusterTerms;
|
|
114
110
|
return result;
|
|
115
111
|
}
|
|
116
|
-
async function getNumericDictTermAnnotation(q, ds) {
|
|
117
|
-
const getDataArgs = {
|
|
118
|
-
// TODO: figure out when term is not a termwrapper
|
|
119
|
-
terms: q.terms.map((tw) => tw.term ? tw : { term: tw, q: { mode: "continuous" } }),
|
|
120
|
-
filter: q.filter,
|
|
121
|
-
filter0: q.filter0,
|
|
122
|
-
__protected__: q.__protected__
|
|
123
|
-
};
|
|
124
|
-
const data = await getData(getDataArgs, ds);
|
|
125
|
-
const term2sample2value = /* @__PURE__ */ new Map();
|
|
126
|
-
for (const [key, sampleData] of Object.entries(data.samples)) {
|
|
127
|
-
for (const [term, value] of Object.entries(sampleData)) {
|
|
128
|
-
if (term !== "sample") {
|
|
129
|
-
if (!term2sample2value.has(term)) {
|
|
130
|
-
term2sample2value.set(term, {});
|
|
131
|
-
}
|
|
132
|
-
term2sample2value.get(term)[key] = value.value;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
return { term2sample2value, byTermId: data.refs.byTermId, bySampleId: data.refs.bySampleId };
|
|
137
|
-
}
|
|
138
112
|
async function doClustering(data, q, numCases = 1e3) {
|
|
139
113
|
const sampleSet = /* @__PURE__ */ new Set();
|
|
140
114
|
let firstTerm = true;
|
|
@@ -227,13 +201,14 @@ async function validate_query_geneExpression(ds, genome) {
|
|
|
227
201
|
}
|
|
228
202
|
throw "unknown queries.geneExpression.src";
|
|
229
203
|
}
|
|
230
|
-
async function queryHDF5(hdf5_file, query) {
|
|
231
|
-
const
|
|
204
|
+
async function queryHDF5(hdf5_file, query, read_mode) {
|
|
205
|
+
const input = {
|
|
232
206
|
hdf5_file,
|
|
233
207
|
query
|
|
234
|
-
}
|
|
208
|
+
};
|
|
209
|
+
if (read_mode) input.read_mode = read_mode;
|
|
235
210
|
try {
|
|
236
|
-
const result = await run_rust("readH5",
|
|
211
|
+
const result = await run_rust("readH5", JSON.stringify(input));
|
|
237
212
|
if (!result || result.length === 0) {
|
|
238
213
|
throw new Error("Failed to retrieve expression data: Empty or missing response");
|
|
239
214
|
}
|
|
@@ -254,10 +229,16 @@ async function validateNative(q, ds) {
|
|
|
254
229
|
if (!vr.samples?.length) throw "HDF5 file has no samples, please check file.";
|
|
255
230
|
for (const sn of vr.samples) {
|
|
256
231
|
const si = ds.cohort.termdb.q.sampleName2id(sn);
|
|
257
|
-
if (si == void 0)
|
|
232
|
+
if (si == void 0) {
|
|
233
|
+
if (ds.cohort.db) {
|
|
234
|
+
throw `unknown sample ${sn} from HDF5 ${q.file}`;
|
|
235
|
+
} else {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
258
239
|
q.samples.push(si);
|
|
259
240
|
}
|
|
260
|
-
console.log(`${ds.label}: geneExpression HDF5 file validated. Format: ${vr.format}, Samples:`,
|
|
241
|
+
console.log(`${ds.label}: geneExpression HDF5 file validated. Format: ${vr.format}, Samples:`, q.samples.length);
|
|
261
242
|
} catch (error) {
|
|
262
243
|
throw `${ds.label}: Failed to validate geneExpression HDF5 file: ${error}`;
|
|
263
244
|
}
|
|
@@ -270,11 +251,19 @@ async function validateNative(q, ds) {
|
|
|
270
251
|
const samples = q.samples || [];
|
|
271
252
|
if (limitSamples) {
|
|
272
253
|
for (const sid of limitSamples) {
|
|
273
|
-
|
|
254
|
+
if (ds.cohort?.termdb?.q?.id2sampleRefs) {
|
|
255
|
+
bySampleId[sid] = ds.cohort.termdb.q.id2sampleRefs(sid);
|
|
256
|
+
} else {
|
|
257
|
+
bySampleId[sid] = { label: ds.cohort.termdb.q.id2sampleName(sid) };
|
|
258
|
+
}
|
|
274
259
|
}
|
|
275
260
|
} else {
|
|
276
261
|
for (const sid of samples) {
|
|
277
|
-
|
|
262
|
+
if (ds.cohort?.termdb?.q?.id2sampleRefs) {
|
|
263
|
+
bySampleId[sid] = ds.cohort.termdb.q.id2sampleRefs(sid);
|
|
264
|
+
} else {
|
|
265
|
+
bySampleId[sid] = { label: ds.cohort.termdb.q.id2sampleName(sid) };
|
|
266
|
+
}
|
|
278
267
|
}
|
|
279
268
|
}
|
|
280
269
|
const term2sample2value = /* @__PURE__ */ new Map();
|
|
@@ -290,7 +279,8 @@ async function validateNative(q, ds) {
|
|
|
290
279
|
return { term2sample2value, byTermId };
|
|
291
280
|
}
|
|
292
281
|
const time1 = Date.now();
|
|
293
|
-
const
|
|
282
|
+
const readMode = param.dslabel == "MMRF" ? "bulk" : null;
|
|
283
|
+
const geneData = JSON.parse(await queryHDF5(q.file, geneNames, readMode));
|
|
294
284
|
console.log("Time taken to run gene query:", formatElapsedTime(Date.now() - time1));
|
|
295
285
|
const genesData = geneData.query_output || {};
|
|
296
286
|
if (!genesData) throw "No expression data returned from HDF5 query";
|
package/routes/termdb.config.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
SINGLECELL_CELLTYPE,
|
|
7
7
|
GENE_EXPRESSION,
|
|
8
8
|
METABOLITE_INTENSITY,
|
|
9
|
-
|
|
9
|
+
PROTEOME_ABUNDANCE,
|
|
10
10
|
SINGLECELL_GENE_EXPRESSION,
|
|
11
11
|
DNA_METHYLATION,
|
|
12
12
|
SSGSEA
|
|
@@ -51,7 +51,6 @@ function make(q, req, res, ds, genome) {
|
|
|
51
51
|
dataDownloadCatch: tdb.dataDownloadCatch,
|
|
52
52
|
matrix: tdb.matrix,
|
|
53
53
|
hierCluster: tdb.hierCluster,
|
|
54
|
-
numericDictTermCluster: tdb.numericDictTermCluster,
|
|
55
54
|
mclass: tdb.mclass,
|
|
56
55
|
alwaysRefillCategoricalTermValues: tdb.alwaysRefillCategoricalTermValues,
|
|
57
56
|
isGeneSetTermdb: tdb.isGeneSetTermdb,
|
|
@@ -89,7 +88,6 @@ function make(q, req, res, ds, genome) {
|
|
|
89
88
|
if (tdb.maxAnnoTermsPerClientRequest) c.maxAnnoTermsPerClientRequest = tdb.maxAnnoTermsPerClientRequest;
|
|
90
89
|
addRestrictAncestries(c, tdb);
|
|
91
90
|
addMatrixplots(c, ds);
|
|
92
|
-
addMutationSignatureplots(c, ds);
|
|
93
91
|
addNonDictionaryQueries(c, ds, genome);
|
|
94
92
|
c.requiredAuth = authApi.getRequiredCredForDsEmbedder(q.dslabel, q.embedder);
|
|
95
93
|
const info = authApi.getNonsensitiveInfo(req);
|
|
@@ -132,15 +130,6 @@ function addMatrixplots(c, ds) {
|
|
|
132
130
|
return { name: p.name };
|
|
133
131
|
});
|
|
134
132
|
}
|
|
135
|
-
function addMutationSignatureplots(c, ds) {
|
|
136
|
-
const mutationSignatureplots = ds.cohort.termdb.termCollections?.find(
|
|
137
|
-
(tc) => tc.name == "Mutation Signature" && tc.type === "numeric"
|
|
138
|
-
)?.plots;
|
|
139
|
-
if (!mutationSignatureplots) return;
|
|
140
|
-
c.mutationSignatureplots = mutationSignatureplots.map((p) => {
|
|
141
|
-
return { name: p.name };
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
133
|
function addNonDictionaryQueries(c, ds, genome) {
|
|
145
134
|
const q = ds.queries;
|
|
146
135
|
if (!q) return;
|
|
@@ -198,6 +187,26 @@ function addNonDictionaryQueries(c, ds, genome) {
|
|
|
198
187
|
if (q.geneExpression) {
|
|
199
188
|
q2.geneExpression = { unit: q.geneExpression.unit };
|
|
200
189
|
}
|
|
190
|
+
if (q.proteome) {
|
|
191
|
+
q2.proteome = {};
|
|
192
|
+
if (q.proteome.assays) {
|
|
193
|
+
q2.proteome.assays = {};
|
|
194
|
+
for (const assay in q.proteome.assays) {
|
|
195
|
+
q2.proteome.assays[assay] = {};
|
|
196
|
+
if (q.proteome.assays[assay].cohorts) {
|
|
197
|
+
q2.proteome.assays[assay].cohorts = {};
|
|
198
|
+
for (const cohort in q.proteome.assays[assay].cohorts) {
|
|
199
|
+
q2.proteome.assays[assay].cohorts[cohort] = {};
|
|
200
|
+
if ("filter" in q.proteome.assays[assay].cohorts[cohort]) {
|
|
201
|
+
q2.proteome.assays[assay].cohorts[cohort].filter = JSON.parse(
|
|
202
|
+
JSON.stringify(q.proteome.assays[assay].cohorts[cohort].filter)
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
201
210
|
if (q.dnaMethylation) {
|
|
202
211
|
q2.dnaMethylation = { unit: q.dnaMethylation.unit };
|
|
203
212
|
if (q.dnaMethylation.promoter) {
|
|
@@ -284,7 +293,7 @@ function getAllowedTermTypes(ds) {
|
|
|
284
293
|
}
|
|
285
294
|
if (ds.queries?.geneExpression) typeSet.add(GENE_EXPRESSION);
|
|
286
295
|
if (ds.queries?.metaboliteIntensity) typeSet.add(METABOLITE_INTENSITY);
|
|
287
|
-
if (ds.queries?.proteome?.
|
|
296
|
+
if (ds.queries?.proteome?.assays) typeSet.add(PROTEOME_ABUNDANCE);
|
|
288
297
|
if (ds.queries?.ssGSEA) typeSet.add(SSGSEA);
|
|
289
298
|
if (ds.queries?.dnaMethylation) typeSet.add(DNA_METHYLATION);
|
|
290
299
|
if (ds.queries?.singleCell) {
|
|
@@ -40,20 +40,11 @@ async function getFilters(query, ds) {
|
|
|
40
40
|
);
|
|
41
41
|
const tw2List = {};
|
|
42
42
|
for (const tw of query.terms) {
|
|
43
|
-
|
|
44
|
-
const allowedValues = ds.cohort.termdb.getRestrictedValues?.(query.__protected__.clientAuthResult, tw.term.id);
|
|
45
|
-
values = filterByAllowedValues(values, allowedValues);
|
|
43
|
+
const values = getList(samplesPerFilter, filtersData, tw, query.showAll);
|
|
46
44
|
tw2List[tw.term.id] = values;
|
|
47
45
|
}
|
|
48
46
|
return { ...tw2List };
|
|
49
47
|
}
|
|
50
|
-
function filterByAllowedValues(values, allowedValues) {
|
|
51
|
-
if (!allowedValues) {
|
|
52
|
-
return values;
|
|
53
|
-
}
|
|
54
|
-
const allowedValuesSet = new Set(allowedValues.map((v) => String(v)));
|
|
55
|
-
return values.filter((v) => v.value === "" || allowedValuesSet.has(String(v.value)));
|
|
56
|
-
}
|
|
57
48
|
async function getSamplesPerFilter(q, ds) {
|
|
58
49
|
q.ds = ds;
|
|
59
50
|
const samples = {};
|
|
@@ -94,6 +85,5 @@ function getList(samplesPerFilter, filtersData, tw, showAll) {
|
|
|
94
85
|
return filteredValues;
|
|
95
86
|
}
|
|
96
87
|
export {
|
|
97
|
-
api
|
|
98
|
-
filterByAllowedValues
|
|
88
|
+
api
|
|
99
89
|
};
|