@sjcrh/proteinpaint-server 2.149.0 → 2.151.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/dataset/termdb.test.js +16 -1
- package/genome/hg38.js +2 -2
- package/package.json +5 -5
- package/routes/alphaGenome.js +41 -0
- package/routes/alphaGenomeTypes.js +36 -0
- package/routes/grin2.js +108 -8
- package/routes/termdb.DE.js +24 -9
- package/routes/termdb.chat.js +10 -2
- package/routes/termdb.config.js +3 -1
- package/src/app.js +557 -300
- package/src/mds3.gdc.filter.js +4 -0
package/dataset/termdb.test.js
CHANGED
|
@@ -281,7 +281,8 @@ function termdb_test_default() {
|
|
|
281
281
|
svfusion: {
|
|
282
282
|
byrange: {
|
|
283
283
|
file: "files/hg38/TermdbTest/TermdbTest_Fusion.gz"
|
|
284
|
-
}
|
|
284
|
+
},
|
|
285
|
+
dtLst: [2, 5]
|
|
285
286
|
},
|
|
286
287
|
cnv: {
|
|
287
288
|
file: "files/hg38/TermdbTest/TermdbTest_CNV_gene.gz"
|
|
@@ -367,6 +368,20 @@ function termdb_test_default() {
|
|
|
367
368
|
trackLst: {
|
|
368
369
|
jsonFile: "files/hg38/TermdbTest/trackLst/facet.json",
|
|
369
370
|
activeTracks: ["bw 1", "bed 1"]
|
|
371
|
+
},
|
|
372
|
+
chat: {},
|
|
373
|
+
alphaGenome: {
|
|
374
|
+
default: {
|
|
375
|
+
gene: "FLT3",
|
|
376
|
+
chromosome: "chr13",
|
|
377
|
+
position: 28034105,
|
|
378
|
+
reference: "A",
|
|
379
|
+
alternate: "AACTCCCATTTGAGATCATACC",
|
|
380
|
+
ontologyTerm: "EFO:0000572",
|
|
381
|
+
// lymphoblast
|
|
382
|
+
outputType: 4
|
|
383
|
+
//RNA SEQ
|
|
384
|
+
}
|
|
370
385
|
}
|
|
371
386
|
}
|
|
372
387
|
};
|
package/genome/hg38.js
CHANGED
|
@@ -55,8 +55,8 @@ var hg38_default = {
|
|
|
55
55
|
},
|
|
56
56
|
{
|
|
57
57
|
__isgene: true,
|
|
58
|
-
name: "GENCODE
|
|
59
|
-
file: "anno/gencode.
|
|
58
|
+
name: "GENCODE v48",
|
|
59
|
+
file: "anno/gencode.v48.hg38.gz",
|
|
60
60
|
translatecoding: true,
|
|
61
61
|
categories: {
|
|
62
62
|
coding: { color: "#004D99", label: "Coding gene" },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-server",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.151.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",
|
|
@@ -61,11 +61,11 @@
|
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@sjcrh/augen": "2.143.0",
|
|
64
|
-
"@sjcrh/proteinpaint-python": "2.
|
|
64
|
+
"@sjcrh/proteinpaint-python": "2.151.0",
|
|
65
65
|
"@sjcrh/proteinpaint-r": "2.149.0",
|
|
66
|
-
"@sjcrh/proteinpaint-rust": "2.
|
|
67
|
-
"@sjcrh/proteinpaint-shared": "2.
|
|
68
|
-
"@sjcrh/proteinpaint-types": "2.
|
|
66
|
+
"@sjcrh/proteinpaint-rust": "2.150.0",
|
|
67
|
+
"@sjcrh/proteinpaint-shared": "2.150.0",
|
|
68
|
+
"@sjcrh/proteinpaint-types": "2.150.0",
|
|
69
69
|
"@types/express": "^5.0.0",
|
|
70
70
|
"@types/express-session": "^1.18.1",
|
|
71
71
|
"better-sqlite3": "^9.4.1",
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { alphaGenomePayload } from "#types/checkers";
|
|
2
|
+
import { run_python } from "@sjcrh/proteinpaint-python";
|
|
3
|
+
import serverconfig from "#src/serverconfig.js";
|
|
4
|
+
const api = {
|
|
5
|
+
endpoint: "alphaGenome",
|
|
6
|
+
methods: {
|
|
7
|
+
get: {
|
|
8
|
+
...alphaGenomePayload,
|
|
9
|
+
init
|
|
10
|
+
},
|
|
11
|
+
post: {
|
|
12
|
+
...alphaGenomePayload,
|
|
13
|
+
init
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
function init() {
|
|
18
|
+
return async (req, res) => {
|
|
19
|
+
try {
|
|
20
|
+
const query = req.query;
|
|
21
|
+
const params = {
|
|
22
|
+
API_KEY: serverconfig.alphaGenome.API_KEY,
|
|
23
|
+
chromosome: query.chromosome,
|
|
24
|
+
position: query.position,
|
|
25
|
+
reference: query.reference,
|
|
26
|
+
alternate: query.alternate,
|
|
27
|
+
interval: query.interval
|
|
28
|
+
};
|
|
29
|
+
if (query.ontologyTerms) params["ontologyTerms"] = query.ontologyTerms;
|
|
30
|
+
if (query.outputType) params["outputType"] = Number(query.outputType);
|
|
31
|
+
const url = await run_python("alphaGenome.py", JSON.stringify(params));
|
|
32
|
+
res.send({ plotImage: url });
|
|
33
|
+
} catch (e) {
|
|
34
|
+
console.log(e);
|
|
35
|
+
res.status(404).send({ error: e });
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
api
|
|
41
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { alphaGenomeTypesPayload } from "#types/checkers";
|
|
2
|
+
import { run_python } from "@sjcrh/proteinpaint-python";
|
|
3
|
+
import serverconfig from "#src/serverconfig.js";
|
|
4
|
+
const api = {
|
|
5
|
+
endpoint: "AlphaGenomeTypes",
|
|
6
|
+
methods: {
|
|
7
|
+
get: {
|
|
8
|
+
...alphaGenomeTypesPayload,
|
|
9
|
+
init
|
|
10
|
+
},
|
|
11
|
+
post: {
|
|
12
|
+
...alphaGenomeTypesPayload,
|
|
13
|
+
init
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
function init() {
|
|
18
|
+
return async (req, res) => {
|
|
19
|
+
try {
|
|
20
|
+
const params = { API_KEY: serverconfig.alphaGenome.API_KEY };
|
|
21
|
+
const result = await run_python("AlphaGenomeTypes.py", JSON.stringify(params));
|
|
22
|
+
const { ontologyTerms, outputTypes, intervals } = JSON.parse(result);
|
|
23
|
+
res.send({
|
|
24
|
+
ontologyTerms: ontologyTerms.sort((a, b) => a.label.localeCompare(b.label)),
|
|
25
|
+
outputTypes,
|
|
26
|
+
intervals
|
|
27
|
+
});
|
|
28
|
+
} catch (e) {
|
|
29
|
+
console.log(e);
|
|
30
|
+
res.status(404).send({ error: e });
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
api
|
|
36
|
+
};
|
package/routes/grin2.js
CHANGED
|
@@ -5,7 +5,8 @@ import { run_python } from "@sjcrh/proteinpaint-python";
|
|
|
5
5
|
import { mayLog } from "#src/helpers.ts";
|
|
6
6
|
import { get_samples } from "#src/termdb.sql.js";
|
|
7
7
|
import { read_file, file_is_readable } from "#src/utils.js";
|
|
8
|
-
import { dtsnvindel, dtcnv, dtfusionrna } from "#shared/common.js";
|
|
8
|
+
import { dtsnvindel, dtcnv, dtfusionrna, dtsv } from "#shared/common.js";
|
|
9
|
+
import crypto from "crypto";
|
|
9
10
|
const MAX_LESIONS_PER_TYPE = 5e4;
|
|
10
11
|
const api = {
|
|
11
12
|
endpoint: "grin2",
|
|
@@ -41,6 +42,20 @@ function init({ genomes }) {
|
|
|
41
42
|
}
|
|
42
43
|
};
|
|
43
44
|
}
|
|
45
|
+
function generateCacheFileName() {
|
|
46
|
+
const randomHex = crypto.randomBytes(16).toString("hex");
|
|
47
|
+
const cacheFileName = `grin2_results_${randomHex}.txt`;
|
|
48
|
+
return path.join(serverconfig.cachedir, "grin2", cacheFileName);
|
|
49
|
+
}
|
|
50
|
+
function getAvailableDataTypes(request) {
|
|
51
|
+
const availableOptions = [];
|
|
52
|
+
for (const key in request) {
|
|
53
|
+
if (key.endsWith("Options")) {
|
|
54
|
+
availableOptions.push(key);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return availableOptions;
|
|
58
|
+
}
|
|
44
59
|
async function runGrin2(g, ds, request) {
|
|
45
60
|
const startTime = Date.now();
|
|
46
61
|
const samples = await get_samples(
|
|
@@ -76,7 +91,10 @@ async function runGrin2(g, ds, request) {
|
|
|
76
91
|
devicePixelRatio: request.devicePixelRatio,
|
|
77
92
|
pngDotRadius: request.pngDotRadius,
|
|
78
93
|
width: request.width,
|
|
79
|
-
height: request.height
|
|
94
|
+
height: request.height,
|
|
95
|
+
cacheFileName: generateCacheFileName(),
|
|
96
|
+
availableDataTypes: getAvailableDataTypes(request),
|
|
97
|
+
maxGenesToShow: request.maxGenesToShow
|
|
80
98
|
};
|
|
81
99
|
for (const c in g.majorchr) {
|
|
82
100
|
if (ds.queries.singleSampleMutation.discoPlot?.skipChrM) {
|
|
@@ -112,7 +130,8 @@ async function runGrin2(g, ds, request) {
|
|
|
112
130
|
grin2Time: grin2AnalysisTimeToPrint,
|
|
113
131
|
totalTime
|
|
114
132
|
},
|
|
115
|
-
processingSummary
|
|
133
|
+
processingSummary,
|
|
134
|
+
cacheFileName: resultData.cacheFileName
|
|
116
135
|
};
|
|
117
136
|
return response;
|
|
118
137
|
}
|
|
@@ -121,6 +140,7 @@ function getLesionTracker(req) {
|
|
|
121
140
|
if (req.snvindelOptions) currentTypes.push(dtsnvindel);
|
|
122
141
|
if (req.cnvOptions) currentTypes.push(dtcnv);
|
|
123
142
|
if (req.fusionOptions) currentTypes.push(dtfusionrna);
|
|
143
|
+
if (req.svOptions) currentTypes.push(dtsv);
|
|
124
144
|
const track = /* @__PURE__ */ new Map();
|
|
125
145
|
for (const t of currentTypes) track.set(t, { count: 0 });
|
|
126
146
|
return track;
|
|
@@ -188,6 +208,9 @@ async function processSampleData(samples, ds, request, tracker) {
|
|
|
188
208
|
case dtfusionrna:
|
|
189
209
|
label = "fusion";
|
|
190
210
|
break;
|
|
211
|
+
case dtsv:
|
|
212
|
+
label = "structural variant";
|
|
213
|
+
break;
|
|
191
214
|
default:
|
|
192
215
|
label = `type ${type}`;
|
|
193
216
|
break;
|
|
@@ -237,8 +260,43 @@ async function processSampleMlst(sampleName, mlst, request, tracker) {
|
|
|
237
260
|
}
|
|
238
261
|
const les = filterAndConvertFusion(sampleName, m, request.fusionOptions);
|
|
239
262
|
if (les && fusion) {
|
|
240
|
-
|
|
241
|
-
|
|
263
|
+
const lesionsToAdd = Array.isArray(les[0]) ? les.length : 1;
|
|
264
|
+
if (fusion.count + lesionsToAdd > MAX_LESIONS_PER_TYPE) {
|
|
265
|
+
break;
|
|
266
|
+
}
|
|
267
|
+
if (Array.isArray(les[0])) {
|
|
268
|
+
for (const lesion of les) {
|
|
269
|
+
sampleLesions.push(lesion);
|
|
270
|
+
fusion.count++;
|
|
271
|
+
}
|
|
272
|
+
} else {
|
|
273
|
+
sampleLesions.push(les);
|
|
274
|
+
fusion.count++;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
case dtsv: {
|
|
280
|
+
if (!request.svOptions) break;
|
|
281
|
+
const sv = tracker.get(dtsv);
|
|
282
|
+
if (sv && sv.count >= MAX_LESIONS_PER_TYPE) {
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
const les = filterAndConvertSV(sampleName, m, request.svOptions);
|
|
286
|
+
if (les && sv) {
|
|
287
|
+
const lesionsToAdd = Array.isArray(les[0]) ? les.length : 1;
|
|
288
|
+
if (sv.count + lesionsToAdd > MAX_LESIONS_PER_TYPE) {
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
if (Array.isArray(les[0])) {
|
|
292
|
+
for (const lesion of les) {
|
|
293
|
+
sampleLesions.push(lesion);
|
|
294
|
+
sv.count++;
|
|
295
|
+
}
|
|
296
|
+
} else {
|
|
297
|
+
sampleLesions.push(les);
|
|
298
|
+
sv.count++;
|
|
299
|
+
}
|
|
242
300
|
}
|
|
243
301
|
break;
|
|
244
302
|
}
|
|
@@ -258,7 +316,20 @@ function filterAndConvertSnvIndel(sampleName, entry, options) {
|
|
|
258
316
|
if (!Number.isInteger(entry.pos)) {
|
|
259
317
|
return null;
|
|
260
318
|
}
|
|
261
|
-
|
|
319
|
+
if (options.minAltAlleleCount !== void 0 && options.minAltAlleleCount > 0) {
|
|
320
|
+
if (!entry.altCount || entry.altCount < options.minAltAlleleCount) {
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if (options.minTotalDepth !== void 0 && options.minTotalDepth > 0) {
|
|
325
|
+
const totalDepth = (entry.refCount || 0) + (entry.altCount || 0);
|
|
326
|
+
if (totalDepth < options.minTotalDepth) {
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
const start = entry.pos;
|
|
331
|
+
const end = entry.pos;
|
|
332
|
+
return [sampleName, entry.chr, start, end, "mutation"];
|
|
262
333
|
}
|
|
263
334
|
function filterAndConvertCnv(sampleName, entry, options) {
|
|
264
335
|
if (!options || options.gainThreshold === void 0 || options.lossThreshold === void 0 || options.maxSegLength === void 0) {
|
|
@@ -277,10 +348,39 @@ function filterAndConvertCnv(sampleName, entry, options) {
|
|
|
277
348
|
const isLoss = entry.value <= options.lossThreshold;
|
|
278
349
|
if (!isGain && !isLoss) return null;
|
|
279
350
|
const lesionType = isGain ? "gain" : "loss";
|
|
280
|
-
|
|
351
|
+
const start = entry.start;
|
|
352
|
+
const end = entry.stop;
|
|
353
|
+
return [sampleName, entry.chr, start, end, lesionType];
|
|
281
354
|
}
|
|
282
355
|
function filterAndConvertFusion(sampleName, entry, _options) {
|
|
283
|
-
|
|
356
|
+
if (!entry.chrA || entry.posA === void 0) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
const startA = entry.posA;
|
|
360
|
+
const endA = entry.posA;
|
|
361
|
+
const lesionA = [sampleName, entry.chrA, startA, endA, "fusion"];
|
|
362
|
+
if (entry.chrB && entry.posB !== void 0) {
|
|
363
|
+
const startB = entry.posB;
|
|
364
|
+
const endB = entry.posB;
|
|
365
|
+
const lesionB = [sampleName, entry.chrB, startB, endB, "fusion"];
|
|
366
|
+
return [lesionA, lesionB];
|
|
367
|
+
}
|
|
368
|
+
return lesionA;
|
|
369
|
+
}
|
|
370
|
+
function filterAndConvertSV(sampleName, entry, _options) {
|
|
371
|
+
if (!entry.chrA || entry.posA === void 0) {
|
|
372
|
+
return null;
|
|
373
|
+
}
|
|
374
|
+
const startA = entry.posA;
|
|
375
|
+
const endA = entry.posA;
|
|
376
|
+
const lesionA = [sampleName, entry.chrA, startA, endA, "sv"];
|
|
377
|
+
if (entry.chrB && entry.posB !== void 0) {
|
|
378
|
+
const startB = entry.posB;
|
|
379
|
+
const endB = entry.posB;
|
|
380
|
+
const lesionB = [sampleName, entry.chrB, startB, endB, "sv"];
|
|
381
|
+
return [lesionA, lesionB];
|
|
382
|
+
}
|
|
383
|
+
return lesionA;
|
|
284
384
|
}
|
|
285
385
|
export {
|
|
286
386
|
api
|
package/routes/termdb.DE.js
CHANGED
|
@@ -166,17 +166,24 @@ async function run_DE(param, ds, term_results, term_results2) {
|
|
|
166
166
|
}
|
|
167
167
|
const sample_size1 = group1names.length;
|
|
168
168
|
const sample_size2 = group2names.length;
|
|
169
|
-
|
|
170
|
-
if (
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
169
|
+
const alerts = validateGroups(sample_size1, sample_size2, group1names, group2names);
|
|
170
|
+
if (param.preAnalysis) {
|
|
171
|
+
const group1Name = param.samplelst.groups[0].name;
|
|
172
|
+
const group2Name = param.samplelst.groups[1].name;
|
|
173
|
+
return {
|
|
174
|
+
data: {
|
|
175
|
+
[group1Name]: sample_size1,
|
|
176
|
+
[group2Name]: sample_size2,
|
|
177
|
+
...alerts.length ? { alert: alerts.join(" | ") } : {}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
174
180
|
}
|
|
175
|
-
|
|
176
|
-
const
|
|
181
|
+
if (alerts.length) throw alerts.join(" | ");
|
|
182
|
+
const cases_string = group2names.map((i) => i).join(",");
|
|
183
|
+
const controls_string = group1names.map((i) => i).join(",");
|
|
177
184
|
const expression_input = {
|
|
178
|
-
case:
|
|
179
|
-
control:
|
|
185
|
+
case: cases_string,
|
|
186
|
+
control: controls_string,
|
|
180
187
|
data_type: "do_DE",
|
|
181
188
|
input_file: q.file,
|
|
182
189
|
cachedir: serverconfig.cachedir,
|
|
@@ -236,6 +243,14 @@ async function run_DE(param, ds, term_results, term_results2) {
|
|
|
236
243
|
param.method = "wilcoxon";
|
|
237
244
|
return { data: result, sample_size1, sample_size2, method: param.method };
|
|
238
245
|
}
|
|
246
|
+
function validateGroups(sample_size1, sample_size2, group1names, group2names) {
|
|
247
|
+
const alerts = [];
|
|
248
|
+
if (sample_size1 < 1) alerts.push("sample size of group1 < 1");
|
|
249
|
+
if (sample_size2 < 1) alerts.push("sample size of group2 < 1");
|
|
250
|
+
const commonnames = group1names.filter((x) => group2names.includes(x));
|
|
251
|
+
if (commonnames.length) alerts.push(`Common elements found between both groups: ${commonnames.join(", ")}`);
|
|
252
|
+
return alerts;
|
|
253
|
+
}
|
|
239
254
|
async function readFileAndDelete(file, key, response) {
|
|
240
255
|
const plot = await fs.promises.readFile(file);
|
|
241
256
|
const plotBuffer = Buffer.from(plot).toString("base64");
|
package/routes/termdb.chat.js
CHANGED
|
@@ -23,6 +23,12 @@ function init({ genomes }) {
|
|
|
23
23
|
if (!g) throw "invalid genome";
|
|
24
24
|
const ds = g.datasets?.[q.dslabel];
|
|
25
25
|
if (!ds) throw "invalid dslabel";
|
|
26
|
+
console.log("serverconfig:", serverconfig);
|
|
27
|
+
const serverconfig_ds_entries = serverconfig.genomes.find((genome) => genome.name == q.genome).datasets.find((dslabel) => dslabel.name == ds.label);
|
|
28
|
+
console.log("serverconfig_ds_entries:", serverconfig_ds_entries);
|
|
29
|
+
if (!serverconfig_ds_entries.aifiles) {
|
|
30
|
+
throw "aifiles are missing for chatbot to work";
|
|
31
|
+
}
|
|
26
32
|
let apilink;
|
|
27
33
|
let comp_model_name;
|
|
28
34
|
let embedding_model_name;
|
|
@@ -41,11 +47,13 @@ function init({ genomes }) {
|
|
|
41
47
|
// Just hardcoding variables here, these will later be defined in more appropriate places
|
|
42
48
|
user_input: q.prompt,
|
|
43
49
|
apilink,
|
|
44
|
-
|
|
50
|
+
tpmasterdir: serverconfig.tpmasterdir,
|
|
45
51
|
comp_model_name,
|
|
46
52
|
embedding_model_name,
|
|
47
|
-
llm_backend_name: serverconfig.llm_backend
|
|
53
|
+
llm_backend_name: serverconfig.llm_backend,
|
|
48
54
|
// The type of backend (engine) used for running the embedding and completion model. Currently "SJ" and "Ollama" are supported
|
|
55
|
+
aifiles: serverconfig_ds_entries.aifiles,
|
|
56
|
+
binpath: serverconfig.binpath
|
|
49
57
|
};
|
|
50
58
|
const time1 = (/* @__PURE__ */ new Date()).valueOf();
|
|
51
59
|
const ai_output_data = await run_rust("aichatbot", JSON.stringify(chatbot_input));
|
package/routes/termdb.config.js
CHANGED
|
@@ -73,6 +73,7 @@ function make(q, req, res, ds, genome) {
|
|
|
73
73
|
if (tdb.excludedTermtypeByTarget) c.excludedTermtypeByTarget = tdb.excludedTermtypeByTarget;
|
|
74
74
|
if (tdb.survival) c.survival = tdb.survival;
|
|
75
75
|
if (tdb.regression) c.regression = tdb.regression;
|
|
76
|
+
if (tdb.uiLabels) c.uiLabels = tdb.uiLabels;
|
|
76
77
|
if (ds.assayAvailability) c.assayAvailability = ds.assayAvailability;
|
|
77
78
|
if (ds.cohort.correlationVolcano) c.correlationVolcano = ds.cohort.correlationVolcano;
|
|
78
79
|
addRestrictAncestries(c, tdb);
|
|
@@ -135,7 +136,7 @@ function addNonDictionaryQueries(c, ds, genome) {
|
|
|
135
136
|
if (q.snvindel.byisoform?.processTwsInOneQuery) q2.snvindel.byisoform = { processTwsInOneQuery: true };
|
|
136
137
|
}
|
|
137
138
|
if (q.svfusion) {
|
|
138
|
-
q2.svfusion = {};
|
|
139
|
+
q2.svfusion = { dtLst: q.svfusion.dtLst };
|
|
139
140
|
}
|
|
140
141
|
if (q.cnv) {
|
|
141
142
|
q2.cnv = {};
|
|
@@ -180,6 +181,7 @@ function addNonDictionaryQueries(c, ds, genome) {
|
|
|
180
181
|
if (q.chat) {
|
|
181
182
|
q2.chat = {};
|
|
182
183
|
}
|
|
184
|
+
if (q.alphaGenome) q2.alphaGenome = q.alphaGenome;
|
|
183
185
|
if (q.NIdata && serverconfig.features.showBrainImaging) {
|
|
184
186
|
q2.NIdata = {};
|
|
185
187
|
for (const k in q.NIdata) {
|