@sjcrh/proteinpaint-server 2.67.1 → 2.68.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjcrh/proteinpaint-server",
3
- "version": "2.67.1",
3
+ "version": "2.68.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",
package/routes/snp.js CHANGED
@@ -97,6 +97,8 @@ function snp2hit(snp) {
97
97
  chromEnd: Number(fields[2]),
98
98
  name: fields[3],
99
99
  observed,
100
+ ref,
101
+ alt: alts,
100
102
  alleles: [ref, ...alts]
101
103
  };
102
104
  return hit;
@@ -1,6 +1,5 @@
1
1
  import { getOrderedLabels } from "#src/termdb.barchart.js";
2
2
  import { getData } from "#src/termdb.matrix.js";
3
- import { TermTypes } from "#shared/terms.js";
4
3
  const api = {
5
4
  endpoint: "termdb/categories",
6
5
  methods: {
@@ -19,7 +18,6 @@ const api = {
19
18
  genome: "hg38-test",
20
19
  dslabel: "TermdbTest",
21
20
  embedder: "localhost",
22
- getcategories: 1,
23
21
  term: { id: "diaggrp" },
24
22
  filter: {
25
23
  type: "tvslst",
@@ -79,6 +77,8 @@ function init({ genomes }) {
79
77
  };
80
78
  }
81
79
  async function trigger_getcategories(q, res, tdb, ds, genome) {
80
+ if (!q.tw.$id)
81
+ q.tw.$id = "_";
82
82
  const $id = q.tw.$id;
83
83
  const arg = {
84
84
  filter: q.filter,
@@ -92,7 +92,7 @@ async function trigger_getcategories(q, res, tdb, ds, genome) {
92
92
  if (data.error)
93
93
  throw data.error;
94
94
  const lst = [];
95
- if (q.tw.term.type == "geneVariant" && !q.tw.q.groupsetting.inuse) {
95
+ if (q.tw.term.type == "geneVariant" && !q.tw.q.groupsetting?.inuse) {
96
96
  const samples = data.samples;
97
97
  const dtClassMap = /* @__PURE__ */ new Map();
98
98
  if (ds.assayAvailability?.byDt) {
@@ -103,7 +103,7 @@ async function trigger_getcategories(q, res, tdb, ds, genome) {
103
103
  }
104
104
  }
105
105
  const sampleCountedFor = /* @__PURE__ */ new Set();
106
- for (const [sampleId, sampleData] of Object.entries(samples)) {
106
+ for (const sampleData of Object.values(samples)) {
107
107
  const key = $id;
108
108
  const values = sampleData[key].values;
109
109
  sampleCountedFor.clear();
@@ -171,34 +171,6 @@ async function trigger_getcategories(q, res, tdb, ds, genome) {
171
171
  orderedLabels
172
172
  });
173
173
  }
174
- function getDefaultQ(term, q) {
175
- if (term.type == "categorical")
176
- return {};
177
- if (term.type == "survival")
178
- return {};
179
- if (term.type == "integer" || term.type == "float")
180
- return term.bins.default;
181
- if (term.type == "condition") {
182
- return {
183
- mode: q.mode,
184
- breaks: q.breaks,
185
- bar_by_grade: q.bar_by_grade,
186
- /*Leave this here until bug with term1_q not passing to getCategories is figured out.
187
- Commented out b/c tvs condition tests fail.*/
188
- //bar_by_children: term.subconditions || q.bar_by_children,
189
- bar_by_children: q.bar_by_children,
190
- value_by_max_grade: q.value_by_max_grade,
191
- value_by_most_recent: q.value_by_most_recent,
192
- //value_by_computable_grade: term.subconditions || q.value_by_computable_grade
193
- value_by_computable_grade: q.value_by_computable_grade
194
- };
195
- }
196
- if (term.type == "geneVariant")
197
- return {};
198
- if (term.type == TermTypes.SINGLECELL_CELLTYPE)
199
- return {};
200
- throw "unknown term type";
201
- }
202
174
  export {
203
175
  api
204
176
  };
@@ -76,6 +76,8 @@ function make(q, res, ds, genome) {
76
76
  c.hasAncestry = tdb.hasAncestry;
77
77
  if (tdb.logscaleBase2)
78
78
  c.logscaleBase2 = tdb.logscaleBase2;
79
+ if (tdb.useCasesExcluded)
80
+ c.useCasesExcluded = tdb.useCasesExcluded;
79
81
  if (ds.assayAvailability)
80
82
  c.assayAvailability = ds.assayAvailability;
81
83
  if (ds.customTwQByType)
@@ -18,7 +18,7 @@ const api = {
18
18
  genome: "hg38-test",
19
19
  dslabel: "TermdbTest",
20
20
  embedder: "localhost",
21
- tid: "hrtavg",
21
+ tw: { term: { id: "hrtavg" }, q: { mode: "continuous" } },
22
22
  filter: {
23
23
  type: "tvslst",
24
24
  in: true,
@@ -54,45 +54,45 @@ const api = {
54
54
  function init({ genomes }) {
55
55
  return async (req, res) => {
56
56
  const q = req.query;
57
+ let result;
57
58
  try {
58
- const g = genomes[req.query.genome];
59
- if (!g)
59
+ const genome = genomes[req.query.genome];
60
+ if (!genome)
60
61
  throw "invalid genome name";
61
- const ds = g.datasets[req.query.dslabel];
62
+ const ds = genome.datasets[req.query.dslabel];
62
63
  if (!ds)
63
64
  throw "invalid dataset name";
64
65
  const tdb = ds.cohort.termdb;
65
66
  if (!tdb)
66
67
  throw "invalid termdb object";
67
- await trigger_getdescrstats(q, res, ds, g);
68
+ if (!q.tw.$id)
69
+ q.tw.$id = "_";
70
+ const data = await getData({ filter: q.filter, filter0: q.filter0, terms: [q.tw] }, ds, genome);
71
+ if (data.error)
72
+ throw data.error;
73
+ const values = [];
74
+ for (const key in data.samples) {
75
+ const sample = data.samples[key];
76
+ const value = sample[q.tw.$id].value;
77
+ if (q.tw.q.hiddenValues?.[value]) {
78
+ continue;
79
+ }
80
+ if (q.logScale) {
81
+ if (value === 0) {
82
+ continue;
83
+ }
84
+ }
85
+ values.push(Number(value));
86
+ }
87
+ result = Summarystats(values);
68
88
  } catch (e) {
69
- res.send({ error: e?.message || e });
70
89
  if (e instanceof Error && e.stack)
71
90
  console.log(e);
91
+ result = { error: e?.message || e };
72
92
  }
93
+ res.send(result);
73
94
  };
74
95
  }
75
- async function trigger_getdescrstats(q, res, ds, genome) {
76
- const terms = [q.tw];
77
- const data = await getData({ filter: q.filter, terms }, ds, genome);
78
- if (data.error)
79
- throw data.error;
80
- const values = [];
81
- for (const key in data.samples) {
82
- const sample = data.samples[key];
83
- const value = sample[q.tw.$id].value;
84
- if (q.tw.q.hiddenValues?.[value]) {
85
- continue;
86
- }
87
- if (q.settings?.violin?.unit === "log") {
88
- if (value === 0) {
89
- continue;
90
- }
91
- }
92
- values.push(parseFloat(value));
93
- }
94
- res.send(Summarystats(values));
95
- }
96
96
  export {
97
97
  api
98
98
  };
@@ -20,6 +20,7 @@ const api = {
20
20
  };
21
21
  function init({ genomes }) {
22
22
  return async (req, res) => {
23
+ let result;
23
24
  try {
24
25
  const q = req.query;
25
26
  const genome = genomes[q.genome];
@@ -31,13 +32,15 @@ function init({ genomes }) {
31
32
  if (!ds.queries?.topVariablyExpressedGenes)
32
33
  throw "not supported on dataset";
33
34
  const t = Date.now();
34
- const genes = await ds.queries.topVariablyExpressedGenes.getGenes(q);
35
+ result = {
36
+ genes: await ds.queries.topVariablyExpressedGenes.getGenes(q)
37
+ };
35
38
  if (serverconfig.debugmode)
36
39
  console.log("topVariablyExpressedGenes", Date.now() - t, "ms");
37
- res.send({ genes });
38
40
  } catch (e) {
39
- res.send({ status: "error", error: e.message || e });
41
+ result = { status: e.status || 400, error: e.message || e };
40
42
  }
43
+ res.send(result);
41
44
  };
42
45
  }
43
46
  function validate_query_TopVariablyExpressedGenes(ds, genome) {
@@ -87,7 +90,7 @@ async function computeGenes4nativeDs(q, ds, matrixFile, samples) {
87
90
  input_file: matrixFile,
88
91
  samples: samples.join(","),
89
92
  filter_extreme_values: true,
90
- num_genes: Number(q.maxGenes),
93
+ num_genes: q.maxGenes,
91
94
  param: "var"
92
95
  };
93
96
  const rust_output = await run_rust("topGeneByExpressionVariance", JSON.stringify(input_json));
@@ -146,24 +149,45 @@ function gdcValidateQuery(ds, genome) {
146
149
  const arg = {
147
150
  // add any to avoid tsc err
148
151
  case_filters: makeFilter(q),
149
- selection_size: Number(q.maxGenes)
152
+ selection_size: q.maxGenes,
153
+ min_median_log2_uqfpkm: q.min_median_log2_uqfpkm
150
154
  };
151
- arg.gene_ids = tempGetCGCgenes(genome);
155
+ if (q.geneSet) {
156
+ if (q.geneSet.type == "all") {
157
+ arg.gene_type = "protein_coding";
158
+ } else if (q.geneSet.type == "custom" || q.geneSet.type == "msigdb") {
159
+ if (!Array.isArray(q.geneSet.geneList))
160
+ throw "q.geneSet.geneList is not array";
161
+ arg.gene_ids = map2ensg(q.geneSet.geneList, genome);
162
+ if (arg.gene_ids.length == 0)
163
+ throw "no valid genes from custom gene set";
164
+ } else {
165
+ throw "unknown q.geneSet.type";
166
+ }
167
+ } else {
168
+ arg.gene_type = "protein_coding";
169
+ }
152
170
  return arg;
153
171
  }
154
172
  }
155
- function tempGetCGCgenes(genome) {
156
- const lst = [];
157
- for (const s of genome.geneset[0].lst) {
158
- const a = genome.genedb.getAliasByName.all(s);
159
- if (a) {
160
- for (const b of a) {
161
- if (b.alias.startsWith("ENSG"))
162
- lst.push(b.alias);
173
+ function map2ensg(lst, genome) {
174
+ const ensg = [];
175
+ for (const name of lst) {
176
+ if (name.startsWith("ENSG") && name.length == 15) {
177
+ ensg.push(name);
178
+ continue;
179
+ }
180
+ const tmp = genome.genedb.getAliasByName.all(name);
181
+ if (Array.isArray(tmp)) {
182
+ for (const a of tmp) {
183
+ if (a.alias.startsWith("ENSG")) {
184
+ ensg.push(a.alias);
185
+ break;
186
+ }
163
187
  }
164
188
  }
165
189
  }
166
- return lst;
190
+ return ensg;
167
191
  }
168
192
  export {
169
193
  api,
@@ -2,7 +2,7 @@ import { trigger_getViolinPlotData } from "#src/termdb.violin.js";
2
2
  const api = {
3
3
  endpoint: "termdb/violin",
4
4
  methods: {
5
- get: {
5
+ all: {
6
6
  init,
7
7
  request: {
8
8
  typeId: "getViolinRequest"
@@ -48,28 +48,27 @@ const api = {
48
48
  }
49
49
  }
50
50
  ]
51
- },
52
- post: {
53
- alternativeFor: "get",
54
- init
55
51
  }
56
52
  }
57
53
  };
58
54
  function init({ genomes }) {
59
55
  return async (req, res) => {
60
56
  const q = req.query;
57
+ let data;
61
58
  try {
62
- const g = genomes[req.query.genome];
63
- const ds = g.datasets[req.query.dslabel];
59
+ const g = genomes[q.genome];
64
60
  if (!g)
65
61
  throw "invalid genome name";
66
- const data = await trigger_getViolinPlotData(req.query, null, ds, g);
67
- res.send(data);
62
+ const ds = g.datasets?.[q.dslabel];
63
+ if (!ds)
64
+ throw "invalid ds";
65
+ data = await trigger_getViolinPlotData(q, null, ds, g);
68
66
  } catch (e) {
69
- res.send({ error: e?.message || e });
67
+ data = { error: e?.message || e };
70
68
  if (e instanceof Error && e.stack)
71
69
  console.log(e);
72
70
  }
71
+ res.send(data);
73
72
  };
74
73
  }
75
74
  export {