@sjcrh/proteinpaint-server 2.138.0 → 2.138.2

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.
@@ -4,7 +4,8 @@ function termdb_test_default() {
4
4
  isSupportedChartOverride: {
5
5
  runChart: () => true,
6
6
  frequencyChart: () => true,
7
- report: () => true
7
+ report: () => true,
8
+ summarizeMutationDiagnosis: () => true
8
9
  },
9
10
  cohort: {
10
11
  massNav: {
@@ -175,6 +176,9 @@ function termdb_test_default() {
175
176
  ]
176
177
  }
177
178
  }
179
+ },
180
+ defaultTw4correlationPlot: {
181
+ disease: { id: "diaggrp", q: {} }
178
182
  }
179
183
  },
180
184
  scatterplots: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjcrh/proteinpaint-server",
3
- "version": "2.138.0",
3
+ "version": "2.138.2",
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",
@@ -64,7 +64,7 @@
64
64
  "@sjcrh/proteinpaint-r": "2.137.2-0",
65
65
  "@sjcrh/proteinpaint-rust": "2.137.2-0",
66
66
  "@sjcrh/proteinpaint-shared": "2.137.3",
67
- "@sjcrh/proteinpaint-types": "2.138.0",
67
+ "@sjcrh/proteinpaint-types": "2.138.1",
68
68
  "@types/express": "^5.0.0",
69
69
  "@types/express-session": "^1.18.1",
70
70
  "better-sqlite3": "^9.4.1",
@@ -62,7 +62,7 @@ async function getBrainImage(query, genomes, plane, index) {
62
62
  if (overlayTW)
63
63
  terms.push(overlayTW);
64
64
  const selectedSampleNames = query.selectedSampleFileNames.map((s) => s.split(".nii")[0]);
65
- const data = await getData({ terms }, ds, q.genome);
65
+ const data = await getData({ terms }, ds);
66
66
  const divideByCat = {};
67
67
  const uniqueOverlayTwCats = /* @__PURE__ */ new Set();
68
68
  for (const sampleName of selectedSampleNames) {
@@ -29,7 +29,7 @@ function init({ genomes }) {
29
29
  const ds = genome.datasets?.[q.dslabel];
30
30
  if (!ds)
31
31
  throw "invalid ds";
32
- const result = await compute(q, ds, genome);
32
+ const result = await compute(q, ds);
33
33
  res.send(result);
34
34
  } catch (e) {
35
35
  res.send({ error: e?.message || e });
@@ -38,16 +38,16 @@ function init({ genomes }) {
38
38
  }
39
39
  };
40
40
  }
41
- async function compute(q, ds, genome) {
41
+ async function compute(q, ds) {
42
42
  const terms = [q.featureTw, ...q.variableTwLst];
43
43
  const data = await getData(
44
44
  {
45
45
  filter: q.filter,
46
46
  filter0: q.filter0,
47
- terms
47
+ terms,
48
+ __protected__: q.__protected__
48
49
  },
49
- ds,
50
- genome
50
+ ds
51
51
  );
52
52
  if (data.error)
53
53
  throw data.error;
@@ -21,34 +21,14 @@ function init({ genomes }) {
21
21
  if (!g)
22
22
  throw "invalid genome name";
23
23
  const ds = g.datasets?.[req.query.dslabel];
24
- getFilters(req.query, ds, g, res);
24
+ getFilters(req.query, ds, res);
25
25
  } catch (e) {
26
26
  console.log(e);
27
27
  res.send({ status: "error", error: e.message || e });
28
28
  }
29
29
  };
30
30
  }
31
- function getList(samplesPerFilter, filtersData, tw) {
32
- const values = Object.values(tw.term.values);
33
- values.sort((v1, v2) => v1.label.localeCompare(v2.label));
34
- const twSamples = samplesPerFilter[tw.term.id];
35
- const data = [];
36
- for (const sample of twSamples) {
37
- data.push(filtersData.samples[sample]);
38
- }
39
- const annotations = data.filter((s) => s != void 0).map((sample) => sample[tw.$id]?.value);
40
- const sampleValues = Array.from(new Set(annotations));
41
- const filteredValues = [];
42
- for (const value of values) {
43
- const label = value.label.replace(/["']/g, "");
44
- const disabled = !sampleValues.includes(value.key || value.label);
45
- filteredValues.push({ value: value.key || value.label, label, disabled });
46
- }
47
- filteredValues.unshift({ label: "", value: "" });
48
- filteredValues.sort((a, b) => a.label.localeCompare(b.label));
49
- return filteredValues;
50
- }
51
- async function getFilters(query, ds, genome, res) {
31
+ async function getFilters(query, ds, res) {
52
32
  if (!query.filterByUserSites)
53
33
  authApi.mayAdjustFilter(query, ds, query.terms);
54
34
  try {
@@ -58,12 +38,11 @@ async function getFilters(query, ds, genome, res) {
58
38
  terms: query.terms,
59
39
  __protected__: query.__protected__
60
40
  },
61
- ds,
62
- genome
41
+ ds
63
42
  );
64
43
  const tw2List = {};
65
44
  for (const tw of query.terms) {
66
- tw2List[tw.term.id] = getList(samplesPerFilter, filtersData, tw);
45
+ tw2List[tw.term.id] = getList(samplesPerFilter, filtersData, tw, query.showAll);
67
46
  }
68
47
  res.send({ ...tw2List });
69
48
  } catch (e) {
@@ -71,6 +50,28 @@ async function getFilters(query, ds, genome, res) {
71
50
  res.send({ error: e.message || e });
72
51
  }
73
52
  }
53
+ function getList(samplesPerFilter, filtersData, tw, showAll) {
54
+ const values = Object.values(tw.term.values);
55
+ values.sort((v1, v2) => v1.label.localeCompare(v2.label));
56
+ const twSamples = samplesPerFilter[tw.term.id];
57
+ const data = [];
58
+ for (const sample of twSamples) {
59
+ data.push(filtersData.samples[sample]);
60
+ }
61
+ const annotations = data.filter((s) => s != void 0).map((sample) => sample[tw.$id]?.value);
62
+ const sampleValues = Array.from(new Set(annotations));
63
+ const filteredValues = [];
64
+ for (const value of values) {
65
+ const label = value.label.replace(/["']/g, "");
66
+ const disabled = !sampleValues.includes(value.key || value.label);
67
+ if (!showAll && disabled)
68
+ continue;
69
+ filteredValues.push({ value: value.key || value.label, label, disabled });
70
+ }
71
+ filteredValues.unshift({ label: "", value: "" });
72
+ filteredValues.sort((a, b) => a.label.localeCompare(b.label));
73
+ return filteredValues;
74
+ }
74
75
  export {
75
76
  api
76
77
  };
@@ -20,7 +20,7 @@ function init({ genomes }) {
20
20
  if (!g)
21
21
  throw "invalid genome name";
22
22
  const ds = g.datasets?.[req.query.dslabel];
23
- const result = await getScoresDict(req.query, ds, g);
23
+ const result = await getScoresDict(req.query, ds);
24
24
  res.send(result);
25
25
  } catch (e) {
26
26
  console.log(e);
@@ -28,7 +28,7 @@ function init({ genomes }) {
28
28
  }
29
29
  };
30
30
  }
31
- async function getScoresDict(query, ds, genome) {
31
+ async function getScoresDict(query, ds) {
32
32
  if (!query.filterByUserSites)
33
33
  query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
34
34
  const terms = [...query.scoreTerms, query.facilityTW];
@@ -41,8 +41,7 @@ async function getScoresDict(query, ds, genome) {
41
41
  //if isRadarFacility and site is specified, do not apply the filter
42
42
  __protected__: query.__protected__
43
43
  },
44
- ds,
45
- genome
44
+ ds
46
45
  );
47
46
  const lst = Object.values(data.samples);
48
47
  let sites = lst.map((s) => {
@@ -20,7 +20,7 @@ function init({ genomes }) {
20
20
  if (!g)
21
21
  throw "invalid genome name";
22
22
  const ds = g.datasets?.[req.query.dslabel];
23
- const result = await getScores(req.query, ds, g);
23
+ const result = await getScores(req.query, ds);
24
24
  res.send(result);
25
25
  } catch (e) {
26
26
  console.log(e);
@@ -28,7 +28,7 @@ function init({ genomes }) {
28
28
  }
29
29
  };
30
30
  }
31
- async function getScores(query, ds, genome) {
31
+ async function getScores(query, ds) {
32
32
  if (!query.filterByUserSites)
33
33
  query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
34
34
  const terms = [query.facilityTW];
@@ -45,8 +45,7 @@ async function getScores(query, ds, genome) {
45
45
  //if site is specified, do not apply the filter that is for the aggregation
46
46
  __protected__: query.__protected__
47
47
  },
48
- ds,
49
- genome
48
+ ds
50
49
  );
51
50
  const lst = Object.values(data.samples);
52
51
  let sites = lst.map((s) => {
@@ -40,8 +40,7 @@ function init({ genomes }) {
40
40
  filter0: q.filter0,
41
41
  terms
42
42
  },
43
- ds,
44
- genome
43
+ ds
45
44
  );
46
45
  if (term_results.error)
47
46
  throw term_results.error;
@@ -55,8 +54,7 @@ function init({ genomes }) {
55
54
  filter0: q.filter0,
56
55
  terms: terms2
57
56
  },
58
- ds,
59
- genome
57
+ ds
60
58
  );
61
59
  if (term_results2.error)
62
60
  throw term_results2.error;
@@ -31,15 +31,7 @@ function init({ genomes }) {
31
31
  const terms = [q.tw];
32
32
  if (q.overlayTw)
33
33
  terms.push(q.overlayTw);
34
- const data = await getData(
35
- {
36
- filter: q.filter,
37
- filter0: q.filter0,
38
- terms
39
- },
40
- ds,
41
- genome
42
- );
34
+ const data = await getData({ filter: q.filter, filter0: q.filter0, terms, __protected__: q.__protected__ }, ds);
43
35
  if (data.error)
44
36
  throw data.error;
45
37
  const sampleType = `All ${data.sampleType?.plural_name || "samples"}`;
@@ -27,7 +27,7 @@ function init({ genomes }) {
27
27
  const tdb = ds.cohort.termdb;
28
28
  if (!tdb)
29
29
  throw "invalid termdb object";
30
- await trigger_getcategories(q, res, tdb, ds, g);
30
+ await trigger_getcategories(q, res, tdb, ds);
31
31
  } catch (e) {
32
32
  res.send({ error: e?.message || e });
33
33
  if (e instanceof Error && e.stack)
@@ -35,7 +35,7 @@ function init({ genomes }) {
35
35
  }
36
36
  };
37
37
  }
38
- async function trigger_getcategories(q, res, tdb, ds, genome) {
38
+ async function trigger_getcategories(q, res, tdb, ds) {
39
39
  if (!q.tw.$id)
40
40
  q.tw.$id = "_";
41
41
  const $id = q.tw.$id;
@@ -49,7 +49,7 @@ async function trigger_getcategories(q, res, tdb, ds, genome) {
49
49
  // optional, from mds3 mayAddGetCategoryArgs()
50
50
  __protected__: q.__protected__
51
51
  };
52
- const data = await getData(arg, ds, genome);
52
+ const data = await getData(arg, ds);
53
53
  if (data.error)
54
54
  throw data.error;
55
55
  const [lst, orderedLabels] = getCategories(data, q, ds, $id);
@@ -47,7 +47,7 @@ function init({ genomes }) {
47
47
  throw `gene list is not an array`;
48
48
  if (q.terms.length < 3)
49
49
  throw `A minimum of three genes is required for clustering. Please refresh this page to clear this error.`;
50
- result = await getResult(q, ds, g);
50
+ result = await getResult(q, ds);
51
51
  } else {
52
52
  throw "unknown q.dataType " + q.dataType;
53
53
  }
@@ -62,7 +62,7 @@ function init({ genomes }) {
62
62
  res.send(result);
63
63
  };
64
64
  }
65
- async function getResult(q, ds, genome) {
65
+ async function getResult(q, ds) {
66
66
  let _q = q;
67
67
  if (q.dataType == TermTypes.GENE_EXPRESSION) {
68
68
  _q = JSON.parse(JSON.stringify(q));
@@ -71,7 +71,7 @@ async function getResult(q, ds, genome) {
71
71
  let term2sample2value, byTermId, bySampleId, skippedSexChrGenes;
72
72
  if (q.dataType == NUMERIC_DICTIONARY_TERM) {
73
73
  ;
74
- ({ term2sample2value, byTermId, bySampleId } = await getNumericDictTermAnnotation(q, ds, genome));
74
+ ({ term2sample2value, byTermId, bySampleId } = await getNumericDictTermAnnotation(q, ds));
75
75
  } else {
76
76
  ;
77
77
  ({ term2sample2value, byTermId, bySampleId, skippedSexChrGenes } = await ds.queries[q.dataType].get(_q));
@@ -108,12 +108,14 @@ async function getResult(q, ds, genome) {
108
108
  result.removedHierClusterTerms = removedHierClusterTerms;
109
109
  return result;
110
110
  }
111
- async function getNumericDictTermAnnotation(q, ds, genome) {
111
+ async function getNumericDictTermAnnotation(q, ds) {
112
112
  const getDataArgs = {
113
+ terms: q.terms.map((term) => ({ term, q: { mode: "continuous" } })),
113
114
  filter: q.filter,
114
- terms: q.terms.map((term) => ({ term, q: { mode: "continuous" } }))
115
+ filter0: q.filter0,
116
+ __protected__: q.__protected__
115
117
  };
116
- const data = await getData(getDataArgs, ds, genome);
118
+ const data = await getData(getDataArgs, ds);
117
119
  const term2sample2value = /* @__PURE__ */ new Map();
118
120
  for (const [key, sampleData] of Object.entries(data.samples)) {
119
121
  for (const [term, value] of Object.entries(sampleData)) {
@@ -32,15 +32,18 @@ function init({ genomes }) {
32
32
  q.tw.$id = "_";
33
33
  const data = await getData(
34
34
  { filter: q.filter, filter0: q.filter0, terms: [q.tw], __protected__: q.__protected__ },
35
- ds,
36
- genome
35
+ ds
37
36
  );
38
37
  if (data.error)
39
38
  throw data.error;
40
39
  const values = [];
41
40
  for (const key in data.samples) {
42
41
  const sample = data.samples[key];
43
- const value = sample[q.tw.$id].value;
42
+ const v = sample[q.tw.$id];
43
+ if (!v && v !== 0) {
44
+ continue;
45
+ }
46
+ const value = v.value;
44
47
  if (q.tw.q.hiddenValues?.[value]) {
45
48
  continue;
46
49
  }
@@ -32,7 +32,7 @@ function init({ genomes }) {
32
32
  const ds = g.datasets?.[q.dslabel];
33
33
  if (!ds)
34
34
  throw "invalid ds";
35
- data = await trigger_getViolinPlotData(q, ds, g);
35
+ data = await trigger_getViolinPlotData(q, ds);
36
36
  } catch (e) {
37
37
  data = { error: e?.message || e };
38
38
  if (e instanceof Error && e.stack)
@@ -41,7 +41,7 @@ function init({ genomes }) {
41
41
  res.send(data);
42
42
  };
43
43
  }
44
- async function trigger_getViolinPlotData(q, ds, genome) {
44
+ async function trigger_getViolinPlotData(q, ds) {
45
45
  if (typeof q.tw?.term != "object" || typeof q.tw?.q != "object")
46
46
  throw "q.tw not of {term,q}";
47
47
  const term = q.tw.term;
@@ -53,9 +53,14 @@ async function trigger_getViolinPlotData(q, ds, genome) {
53
53
  if (q.divideTw)
54
54
  terms.push(q.divideTw);
55
55
  const data = await getData(
56
- { terms, filter: q.filter, filter0: q.filter0, currentGeneNames: q.currentGeneNames },
57
- ds,
58
- genome
56
+ {
57
+ terms,
58
+ filter: q.filter,
59
+ filter0: q.filter0,
60
+ currentGeneNames: q.currentGeneNames,
61
+ __protected__: q.__protected__
62
+ },
63
+ ds
59
64
  );
60
65
  const sampleType = `All ${data.sampleType?.plural_name || "samples"}`;
61
66
  if (data.error)