@sjcrh/proteinpaint-server 2.145.0 → 2.145.1-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 +2 -2
- package/package.json +5 -5
- package/routes/termdb.DE.js +30 -10
- package/routes/termdb.boxplot.js +3 -3
- package/routes/termdb.cluster.js +28 -93
- package/src/app.js +78 -113
package/dataset/termdb.test.js
CHANGED
|
@@ -303,7 +303,6 @@ function termdb_test_default() {
|
|
|
303
303
|
geneExpression: {
|
|
304
304
|
src: "native",
|
|
305
305
|
file: "files/hg38/TermdbTest/rnaseq/TermdbTest.fpkm.matrix.new.h5",
|
|
306
|
-
newformat: true,
|
|
307
306
|
unit: "FPKM"
|
|
308
307
|
},
|
|
309
308
|
ssGSEA: {
|
|
@@ -314,7 +313,8 @@ function termdb_test_default() {
|
|
|
314
313
|
},
|
|
315
314
|
rnaseqGeneCount: {
|
|
316
315
|
storage_type: "HDF5",
|
|
317
|
-
|
|
316
|
+
newformat: true,
|
|
317
|
+
file: "files/hg38/TermdbTest/rnaseq/TermdbTest.geneCounts.new.h5"
|
|
318
318
|
},
|
|
319
319
|
singleCell: {
|
|
320
320
|
samples: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-server",
|
|
3
|
-
"version": "2.145.
|
|
3
|
+
"version": "2.145.1-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",
|
|
@@ -62,10 +62,10 @@
|
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"@sjcrh/augen": "2.143.0",
|
|
64
64
|
"@sjcrh/proteinpaint-python": "2.144.0",
|
|
65
|
-
"@sjcrh/proteinpaint-r": "2.
|
|
66
|
-
"@sjcrh/proteinpaint-rust": "2.145.0",
|
|
67
|
-
"@sjcrh/proteinpaint-shared": "2.
|
|
68
|
-
"@sjcrh/proteinpaint-types": "2.145.
|
|
65
|
+
"@sjcrh/proteinpaint-r": "2.145.1-0",
|
|
66
|
+
"@sjcrh/proteinpaint-rust": "2.145.1-0",
|
|
67
|
+
"@sjcrh/proteinpaint-shared": "2.145.1-0",
|
|
68
|
+
"@sjcrh/proteinpaint-types": "2.145.1-1",
|
|
69
69
|
"@types/express": "^5.0.0",
|
|
70
70
|
"@types/express-session": "^1.18.1",
|
|
71
71
|
"better-sqlite3": "^9.4.1",
|
package/routes/termdb.DE.js
CHANGED
|
@@ -204,7 +204,12 @@ async function run_DE(param, ds, term_results, term_results2) {
|
|
|
204
204
|
const sample_size_limit = 8;
|
|
205
205
|
if (group1names.length <= sample_size_limit && group2names.length <= sample_size_limit || param.method == "edgeR" || param.method == "limma") {
|
|
206
206
|
const time12 = (/* @__PURE__ */ new Date()).valueOf();
|
|
207
|
-
|
|
207
|
+
let result2;
|
|
208
|
+
if (q.newformat) {
|
|
209
|
+
result2 = JSON.parse(await run_R("edge_newh5.R", JSON.stringify(expression_input)));
|
|
210
|
+
} else {
|
|
211
|
+
result2 = JSON.parse(await run_R("edge.R", JSON.stringify(expression_input)));
|
|
212
|
+
}
|
|
208
213
|
mayLog("Time taken to run edgeR:", formatElapsedTime(Date.now() - time12));
|
|
209
214
|
param.method = "edgeR";
|
|
210
215
|
const ql_imagePath = path.join(serverconfig.cachedir, result2.edgeR_ql_image_name[0]);
|
|
@@ -254,15 +259,30 @@ async function validate_query_rnaseqGeneCount(ds) {
|
|
|
254
259
|
if (ds.queries.rnaseqGeneCount.storage_type == "text") {
|
|
255
260
|
samples = (await get_header_txt(q.file, null)).split(" ").slice(4);
|
|
256
261
|
} else if (ds.queries.rnaseqGeneCount.storage_type == "HDF5") {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
262
|
+
if (q.newformat) {
|
|
263
|
+
const get_samples_from_hdf5 = {
|
|
264
|
+
hdf5_file: q.file,
|
|
265
|
+
validate: true
|
|
266
|
+
};
|
|
267
|
+
const time1 = (/* @__PURE__ */ new Date()).valueOf();
|
|
268
|
+
const result = await run_rust("readH5", JSON.stringify(get_samples_from_hdf5));
|
|
269
|
+
const time2 = (/* @__PURE__ */ new Date()).valueOf();
|
|
270
|
+
mayLog("Time taken to query gene expression:", time2 - time1, "ms");
|
|
271
|
+
const vr = JSON.parse(result);
|
|
272
|
+
if (vr.status !== "success") throw vr.message;
|
|
273
|
+
if (!Array.isArray(vr.samples)) throw "HDF5 file has no samples, please check file.";
|
|
274
|
+
samples = vr.samples;
|
|
275
|
+
} else {
|
|
276
|
+
const get_samples_from_hdf5 = {
|
|
277
|
+
input_file: q.file,
|
|
278
|
+
data_type: "get_samples"
|
|
279
|
+
};
|
|
280
|
+
const time1 = (/* @__PURE__ */ new Date()).valueOf();
|
|
281
|
+
const result = await run_rust("DEanalysis", JSON.stringify(get_samples_from_hdf5));
|
|
282
|
+
const time2 = (/* @__PURE__ */ new Date()).valueOf();
|
|
283
|
+
mayLog("Time taken to query gene expression:", time2 - time1, "ms");
|
|
284
|
+
samples = result.split(",");
|
|
285
|
+
}
|
|
266
286
|
} else throw "unknown storage type:" + ds.queries.rnaseqGeneCount.storage_type;
|
|
267
287
|
q.allSampleSet = new Set(samples);
|
|
268
288
|
const unknownSamples = [];
|
package/routes/termdb.boxplot.js
CHANGED
|
@@ -140,7 +140,7 @@ function setUncomputableValues(values) {
|
|
|
140
140
|
function parseValues(q, data, sampleType, isLog, overlayTerm, divideTerm) {
|
|
141
141
|
const chart2plot2values = /* @__PURE__ */ new Map();
|
|
142
142
|
const uncomputableValues = {};
|
|
143
|
-
let absMin =
|
|
143
|
+
let absMin = Infinity, absMax = -Infinity;
|
|
144
144
|
for (const val of Object.values(data.samples)) {
|
|
145
145
|
const value = val[q.tw.$id];
|
|
146
146
|
if (!Number.isFinite(value?.value)) continue;
|
|
@@ -175,8 +175,8 @@ function parseValues(q, data, sampleType, isLog, overlayTerm, divideTerm) {
|
|
|
175
175
|
if (!plot2values.has(plot)) plot2values.set(plot, []);
|
|
176
176
|
const values = plot2values.get(plot);
|
|
177
177
|
values.push(value.value);
|
|
178
|
-
if (
|
|
179
|
-
if (
|
|
178
|
+
if (value.value < absMin) absMin = value.value;
|
|
179
|
+
if (value.value > absMax) absMax = value.value;
|
|
180
180
|
}
|
|
181
181
|
return { absMax, absMin, chart2plot2values, uncomputableValues };
|
|
182
182
|
}
|
package/routes/termdb.cluster.js
CHANGED
|
@@ -213,22 +213,6 @@ async function validate_query_geneExpression(ds, genome) {
|
|
|
213
213
|
}
|
|
214
214
|
throw "unknown queries.geneExpression.src";
|
|
215
215
|
}
|
|
216
|
-
async function queryGeneExpression(hdf5_file, geneNames) {
|
|
217
|
-
const jsonInput = JSON.stringify({
|
|
218
|
-
hdf5_file,
|
|
219
|
-
gene: geneNames
|
|
220
|
-
});
|
|
221
|
-
try {
|
|
222
|
-
const result = await run_rust("readHDF5", jsonInput);
|
|
223
|
-
if (!result || result.length === 0) {
|
|
224
|
-
throw new Error("Failed to retrieve expression data: Empty or missing response");
|
|
225
|
-
}
|
|
226
|
-
return result;
|
|
227
|
-
} catch (error) {
|
|
228
|
-
console.error(`Error querying gene expression for ${geneNames}`);
|
|
229
|
-
throw error;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
216
|
async function queryHDF5(hdf5_file, query) {
|
|
233
217
|
const jsonInput = JSON.stringify({
|
|
234
218
|
hdf5_file,
|
|
@@ -250,34 +234,16 @@ async function validateNative(q, ds) {
|
|
|
250
234
|
q.samples = [];
|
|
251
235
|
try {
|
|
252
236
|
await utils.file_is_readable(q.file);
|
|
253
|
-
|
|
254
|
-
if (q.newformat) {
|
|
255
|
-
tmp = await run_rust("readH5", JSON.stringify({ hdf5_file: q.file, validate: true }));
|
|
256
|
-
} else {
|
|
257
|
-
tmp = await run_rust("validateHDF5", JSON.stringify({ hdf5_file: q.file }));
|
|
258
|
-
}
|
|
237
|
+
const tmp = await run_rust("readH5", JSON.stringify({ hdf5_file: q.file, validate: true }));
|
|
259
238
|
const vr = JSON.parse(tmp);
|
|
260
239
|
if (vr.status !== "success") throw vr.message;
|
|
261
|
-
if (
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
q.samples.push(si);
|
|
267
|
-
}
|
|
268
|
-
console.log(`${ds.label}: geneExpression HDF5 file validated. Format: ${vr.format}, Samples:`, vr.samples.length);
|
|
269
|
-
} else {
|
|
270
|
-
if (!vr.sampleNames?.length) throw "HDF5 file has no samples, please check file.";
|
|
271
|
-
for (const sn of vr.sampleNames) {
|
|
272
|
-
const si = ds.cohort.termdb.q.sampleName2id(sn);
|
|
273
|
-
if (si == void 0) throw `unknown sample ${sn} from HDF5 ${q.file}`;
|
|
274
|
-
q.samples.push(si);
|
|
275
|
-
}
|
|
276
|
-
console.log(
|
|
277
|
-
`${ds.label}: geneExpression HDF5 file validated. Format: ${vr.format}, Samples:`,
|
|
278
|
-
vr.sampleNames.length
|
|
279
|
-
);
|
|
240
|
+
if (!vr.samples?.length) throw "HDF5 file has no samples, please check file.";
|
|
241
|
+
for (const sn of vr.samples) {
|
|
242
|
+
const si = ds.cohort.termdb.q.sampleName2id(sn);
|
|
243
|
+
if (si == void 0) throw `unknown sample ${sn} from HDF5 ${q.file}`;
|
|
244
|
+
q.samples.push(si);
|
|
280
245
|
}
|
|
246
|
+
console.log(`${ds.label}: geneExpression HDF5 file validated. Format: ${vr.format}, Samples:`, vr.samples.length);
|
|
281
247
|
} catch (error) {
|
|
282
248
|
throw `${ds.label}: Failed to validate geneExpression HDF5 file: ${error}`;
|
|
283
249
|
}
|
|
@@ -310,63 +276,32 @@ async function validateNative(q, ds) {
|
|
|
310
276
|
return { term2sample2value, byTermId };
|
|
311
277
|
}
|
|
312
278
|
const time1 = Date.now();
|
|
313
|
-
|
|
314
|
-
if (q.newformat) {
|
|
315
|
-
geneData = JSON.parse(await queryHDF5(q.file, geneNames));
|
|
316
|
-
} else {
|
|
317
|
-
geneData = JSON.parse(await queryGeneExpression(q.file, geneNames));
|
|
318
|
-
}
|
|
279
|
+
const geneData = JSON.parse(await queryHDF5(q.file, geneNames));
|
|
319
280
|
mayLog("Time taken to run gene query:", formatElapsedTime(Date.now() - time1));
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
continue;
|
|
329
|
-
}
|
|
330
|
-
const samplesData = geneResult.samples || {};
|
|
331
|
-
const s2v = {};
|
|
332
|
-
for (const sampleName in samplesData) {
|
|
333
|
-
const sampleId = ds.cohort.termdb.q.sampleName2id(sampleName);
|
|
334
|
-
if (!sampleId) continue;
|
|
335
|
-
if (limitSamples && !limitSamples.has(sampleId)) continue;
|
|
336
|
-
s2v[sampleId] = samplesData[sampleName];
|
|
337
|
-
}
|
|
338
|
-
if (Object.keys(s2v).length) {
|
|
339
|
-
term2sample2value.set(tw.$id, s2v);
|
|
340
|
-
}
|
|
281
|
+
const genesData = geneData.query_output || {};
|
|
282
|
+
if (!genesData) throw "No expression data returned from HDF5 query";
|
|
283
|
+
for (const tw of param.terms) {
|
|
284
|
+
if (!tw.term.gene) continue;
|
|
285
|
+
const geneResult = genesData[tw.term.gene];
|
|
286
|
+
if (!geneResult) {
|
|
287
|
+
console.warn(`No data found for gene ${tw.term.gene} in the response`);
|
|
288
|
+
continue;
|
|
341
289
|
}
|
|
342
|
-
|
|
343
|
-
|
|
290
|
+
const samplesData = geneResult.samples || {};
|
|
291
|
+
const s2v = {};
|
|
292
|
+
for (const sampleName in samplesData) {
|
|
293
|
+
const sampleId = ds.cohort.termdb.q.sampleName2id(sampleName);
|
|
294
|
+
if (!sampleId) continue;
|
|
295
|
+
if (limitSamples && !limitSamples.has(sampleId)) continue;
|
|
296
|
+
s2v[sampleId] = samplesData[sampleName];
|
|
344
297
|
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
for (const tw of param.terms) {
|
|
348
|
-
if (!tw.term.gene) continue;
|
|
349
|
-
const geneResult = genesData[tw.term.gene];
|
|
350
|
-
if (!geneResult) {
|
|
351
|
-
console.warn(`No data found for gene ${tw.term.gene} in the response`);
|
|
352
|
-
continue;
|
|
353
|
-
}
|
|
354
|
-
const samplesData = geneResult.samples || {};
|
|
355
|
-
const s2v = {};
|
|
356
|
-
for (const [sampleName, value] of Object.entries(samplesData)) {
|
|
357
|
-
const sampleId = ds.cohort.termdb.q.sampleName2id(sampleName);
|
|
358
|
-
if (!sampleId) continue;
|
|
359
|
-
if (limitSamples && !limitSamples.has(sampleId)) continue;
|
|
360
|
-
s2v[sampleId] = value;
|
|
361
|
-
}
|
|
362
|
-
if (Object.keys(s2v).length) {
|
|
363
|
-
term2sample2value.set(tw.$id, s2v);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
if (term2sample2value.size == 0) {
|
|
367
|
-
throw "No data available for the input " + param.terms?.map((tw) => tw.term.gene).join(", ");
|
|
298
|
+
if (Object.keys(s2v).length) {
|
|
299
|
+
term2sample2value.set(tw.$id, s2v);
|
|
368
300
|
}
|
|
369
301
|
}
|
|
302
|
+
if (term2sample2value.size == 0) {
|
|
303
|
+
throw "No data available for the input " + param.terms?.map((tw) => tw.term.gene).join(", ");
|
|
304
|
+
}
|
|
370
305
|
return { term2sample2value, byTermId, bySampleId };
|
|
371
306
|
};
|
|
372
307
|
}
|