@sjcrh/proteinpaint-server 2.116.1-2 → 2.117.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.
@@ -194,7 +194,8 @@ var termdb_test_default = {
194
194
  },
195
195
  geneExpression: {
196
196
  src: "native",
197
- file: "files/hg38/TermdbTest/TermdbTest.fpkm.matrix.gz"
197
+ hdf5File: true,
198
+ file: "files/hg38/TermdbTest/TermdbTest.fpkm.matrix.h5"
198
199
  },
199
200
  topVariablyExpressedGenes: {
200
201
  src: "native"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjcrh/proteinpaint-server",
3
- "version": "2.116.1-2",
3
+ "version": "2.117.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",
@@ -66,9 +66,9 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@sjcrh/augen": "2.116.0",
69
- "@sjcrh/proteinpaint-rust": "2.116.0",
70
- "@sjcrh/proteinpaint-shared": "2.116.1-1",
71
- "@sjcrh/proteinpaint-types": "2.116.1-2",
69
+ "@sjcrh/proteinpaint-rust": "2.117.0",
70
+ "@sjcrh/proteinpaint-shared": "2.117.0",
71
+ "@sjcrh/proteinpaint-types": "2.117.0",
72
72
  "@types/express": "^5.0.0",
73
73
  "@types/express-session": "^1.18.1",
74
74
  "better-sqlite3": "^9.4.1",
@@ -12,6 +12,7 @@ import { TermTypes, NUMERIC_DICTIONARY_TERM } from "#shared/terms.js";
12
12
  import { getData } from "#src/termdb.matrix.js";
13
13
  import { termType2label } from "#shared/terms.js";
14
14
  import { mayLog } from "#src/helpers.ts";
15
+ import { formatElapsedTime } from "#shared/time.js";
15
16
  const api = {
16
17
  endpoint: "termdb/cluster",
17
18
  methods: {
@@ -102,7 +103,7 @@ async function getResult(q, ds, genome) {
102
103
  }
103
104
  const t = Date.now();
104
105
  const clustering = await doClustering(term2sample2value, q, Object.keys(bySampleId).length);
105
- mayLog("clustering done:", Date.now() - t, "ms");
106
+ mayLog("clustering done:", formatElapsedTime(Date.now() - t));
106
107
  const result = { clustering, byTermId, bySampleId };
107
108
  if (removedHierClusterTerms.length)
108
109
  result.removedHierClusterTerms = removedHierClusterTerms;
@@ -239,19 +240,19 @@ async function validateHDF5File(filePath) {
239
240
  };
240
241
  }
241
242
  }
242
- async function queryGeneExpression(hdf5_file, geneName) {
243
+ async function queryGeneExpression(hdf5_file, geneNames) {
243
244
  const jsonInput = JSON.stringify({
244
245
  hdf5_file,
245
- gene: geneName
246
+ gene: geneNames
246
247
  });
247
248
  try {
248
249
  const result = await run_rust("readHDF5", jsonInput);
249
- if (!result || Object.keys(result).length === 0) {
250
+ if (!result || result.length === 0) {
250
251
  throw new Error("Failed to retrieve expression data: Empty or missing response");
251
252
  }
252
253
  return result;
253
254
  } catch (error) {
254
- console.error(`Error querying gene expression for ${geneName}`);
255
+ console.error(`Error querying gene expression for ${geneNames}`);
255
256
  throw error;
256
257
  }
257
258
  }
@@ -294,13 +295,30 @@ async function validateNative(q, ds, genome) {
294
295
  }
295
296
  const term2sample2value = /* @__PURE__ */ new Map();
296
297
  const byTermId = {};
298
+ const geneNames = [];
297
299
  for (const geneTerm of param.terms) {
298
- if (!geneTerm.gene)
299
- continue;
300
- try {
301
- const geneQuery = await queryGeneExpression(q.file, geneTerm.gene);
302
- const geneData = JSON.parse(geneQuery);
303
- const samplesData = geneData.samples || {};
300
+ if (geneTerm.gene) {
301
+ geneNames.push(geneTerm.gene);
302
+ }
303
+ }
304
+ if (geneNames.length === 0) {
305
+ console.log("No genes to query");
306
+ return { term2sample2value, byTermId };
307
+ }
308
+ const time1 = Date.now();
309
+ try {
310
+ const geneData = JSON.parse(await queryGeneExpression(q.file, geneNames));
311
+ mayLog("Time taken to run gene query:", formatElapsedTime(Date.now() - time1));
312
+ const genesData = geneData.genes || { [geneNames[0]]: geneData };
313
+ for (const geneTerm of param.terms) {
314
+ if (!geneTerm.gene)
315
+ continue;
316
+ const geneResult = genesData[geneTerm.gene];
317
+ if (!geneResult) {
318
+ console.warn(`No data found for gene ${geneTerm.gene} in the response`);
319
+ continue;
320
+ }
321
+ const samplesData = geneResult.samples || {};
304
322
  const s2v = {};
305
323
  for (const [sampleName, value] of Object.entries(samplesData)) {
306
324
  const sampleId = ds.cohort.termdb.q.sampleName2id(sampleName);
@@ -308,16 +326,14 @@ async function validateNative(q, ds, genome) {
308
326
  continue;
309
327
  if (limitSamples && !limitSamples.has(sampleId))
310
328
  continue;
311
- s2v[sampleId] = Number(value);
329
+ s2v[sampleId] = value;
312
330
  }
313
- console.log(`Gene ${geneTerm.gene} has ${Object.keys(s2v).length} samples with data`);
314
331
  if (Object.keys(s2v).length) {
315
332
  term2sample2value.set(geneTerm.gene, s2v);
316
333
  }
317
- } catch (error) {
318
- console.warn(`Error processing gene ${geneTerm.gene}:`, error);
319
- continue;
320
334
  }
335
+ } catch (error) {
336
+ console.error(`Error processing batch gene query:`, error);
321
337
  }
322
338
  if (term2sample2value.size == 0) {
323
339
  throw "No data available for the input " + param.terms?.map((g) => g.gene).join(", ");
@@ -41,6 +41,7 @@ function make(q, req, res, ds, genome) {
41
41
  const c = {
42
42
  selectCohort: getSelectCohort(ds, req),
43
43
  supportedChartTypes: tdb.q?.getSupportedChartTypes(req),
44
+ hiddenTermIds: tdb.hiddenTermIds,
44
45
  renamedChartTypes: ds.cohort.renamedChartTypes,
45
46
  allowedTermTypes: getAllowedTermTypes(ds),
46
47
  termMatch2geneSet: tdb.termMatch2geneSet,
@@ -5,6 +5,8 @@ import { get_samples } from "#src/termdb.sql.js";
5
5
  import { makeFilter } from "#src/mds3.gdc.js";
6
6
  import { cachedFetch } from "#src/utils.js";
7
7
  import { joinUrl } from "#shared/joinUrl.js";
8
+ import { formatElapsedTime } from "#shared/time.js";
9
+ import { mayLog } from "#src/helpers.ts";
8
10
  const api = {
9
11
  endpoint: "termdb/topVariablyExpressedGenes",
10
12
  methods: {
@@ -35,8 +37,7 @@ function init({ genomes }) {
35
37
  result = {
36
38
  genes: await ds.queries.topVariablyExpressedGenes.getGenes(q)
37
39
  };
38
- if (serverconfig.debugmode)
39
- console.log("topVariablyExpressedGenes", Date.now() - t, "ms");
40
+ mayLog("topVariablyExpressedGenes", formatElapsedTime(Date.now() - t));
40
41
  } catch (e) {
41
42
  result = { status: e.status || 400, error: e.message || e };
42
43
  }