@sjcrh/proteinpaint-server 2.142.0 → 2.143.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.
Files changed (65) hide show
  1. package/dataset/protected.test.js +1 -2
  2. package/dataset/termdb.test.js +3 -2
  3. package/package.json +9 -8
  4. package/routes/aiProjectAdmin.js +46 -60
  5. package/routes/aiProjectSelectedWSImages.js +161 -0
  6. package/routes/brainImaging.js +9 -18
  7. package/routes/brainImagingSamples.js +2 -4
  8. package/routes/burden.js +13 -26
  9. package/routes/correlationVolcano.js +18 -36
  10. package/routes/dataset.js +6 -12
  11. package/routes/deleteWSIAnnotation.js +75 -0
  12. package/routes/dsdata.js +7 -14
  13. package/routes/dzimages.js +4 -8
  14. package/routes/gdc.grin2.list.js +13 -26
  15. package/routes/gdc.grin2.run.js +3 -6
  16. package/routes/gdc.maf.js +8 -16
  17. package/routes/gdc.mafBuild.js +14 -28
  18. package/routes/gene2canonicalisoform.js +4 -8
  19. package/routes/genelookup.js +2 -4
  20. package/routes/genesetEnrichment.js +6 -12
  21. package/routes/genesetOverrepresentation.js +1 -2
  22. package/routes/genomes.js +1 -2
  23. package/routes/grin2.js +13 -17
  24. package/routes/healthcheck.js +3 -6
  25. package/routes/hicdata.js +4 -8
  26. package/routes/hicgenome.js +4 -8
  27. package/routes/hicstat.js +2 -4
  28. package/routes/img.js +1 -2
  29. package/routes/isoformlst.js +6 -12
  30. package/routes/ntseq.js +4 -8
  31. package/routes/pdomain.js +5 -10
  32. package/routes/sampledzimages.js +2 -4
  33. package/routes/samplewsimages.js +3 -67
  34. package/routes/saveWSIAnnotation.js +100 -0
  35. package/routes/snp.js +9 -18
  36. package/routes/termdb.DE.js +23 -46
  37. package/routes/termdb.boxplot.js +84 -84
  38. package/routes/termdb.categories.js +9 -18
  39. package/routes/termdb.cluster.js +23 -46
  40. package/routes/termdb.cohort.summary.js +3 -6
  41. package/routes/termdb.cohorts.js +4 -8
  42. package/routes/termdb.config.js +32 -64
  43. package/routes/termdb.descrstats.js +6 -12
  44. package/routes/termdb.filterTermValues.js +4 -8
  45. package/routes/termdb.numericcategories.js +5 -10
  46. package/routes/termdb.percentile.js +6 -12
  47. package/routes/termdb.profileFormScores.js +12 -24
  48. package/routes/termdb.profileScores.js +7 -14
  49. package/routes/termdb.rootterm.js +4 -8
  50. package/routes/termdb.sampleImages.js +4 -8
  51. package/routes/termdb.singleSampleMutation.js +9 -18
  52. package/routes/termdb.singlecellDEgenes.js +4 -8
  53. package/routes/termdb.singlecellData.js +4 -8
  54. package/routes/termdb.singlecellSamples.js +28 -56
  55. package/routes/termdb.termchildren.js +5 -10
  56. package/routes/termdb.termsbyids.js +4 -8
  57. package/routes/termdb.topMutatedGenes.js +15 -30
  58. package/routes/termdb.topTermsByType.js +9 -18
  59. package/routes/termdb.topVariablyExpressedGenes.js +13 -26
  60. package/routes/termdb.violin.js +124 -135
  61. package/routes/tileserver.js +14 -15
  62. package/routes/wsimages.js +42 -46
  63. package/routes/wsisamples.js +3 -6
  64. package/src/app.js +4345 -6708
  65. package/routes/sampleWsiAiApi.js +0 -33
@@ -23,16 +23,13 @@ function init({ genomes }) {
23
23
  mayCopyFromCookie(q, req.cookies);
24
24
  try {
25
25
  const genome = genomes[q.genome];
26
- if (!genome)
27
- throw "invalid genome";
26
+ if (!genome) throw "invalid genome";
28
27
  const [ds] = get_ds_tdb(genome, q);
29
28
  return make(q, req, res, ds, genome);
30
29
  } catch (e) {
31
30
  res.send({ error: e.message || e });
32
- if (e.stack)
33
- console.log(e.stack);
34
- else
35
- console.log(e);
31
+ if (e.stack) console.log(e.stack);
32
+ else console.log(e);
36
33
  }
37
34
  };
38
35
  }
@@ -64,34 +61,20 @@ function make(q, req, res, ds, genome) {
64
61
  defaultTw4correlationPlot: tdb.defaultTw4correlationPlot,
65
62
  authFilter: req.query.filter
66
63
  };
67
- if (tdb.plotConfigByCohort)
68
- c.plotConfigByCohort = tdb.plotConfigByCohort;
69
- if (tdb.multipleTestingCorrection)
70
- c.multipleTestingCorrection = tdb.multipleTestingCorrection;
71
- if (tdb.helpPages)
72
- c.helpPages = tdb.helpPages;
73
- if (tdb.minTimeSinceDx)
74
- c.minTimeSinceDx = tdb.minTimeSinceDx;
75
- if (tdb.timeUnit)
76
- c.timeUnit = tdb.timeUnit;
77
- if (tdb.cohortStartTimeMsg)
78
- c.cohortStartTimeMsg = tdb.cohortStartTimeMsg;
79
- if (tdb.hasAncestry)
80
- c.hasAncestry = tdb.hasAncestry;
81
- if (tdb.logscaleBase2)
82
- c.logscaleBase2 = tdb.logscaleBase2;
83
- if (tdb.useCasesExcluded)
84
- c.useCasesExcluded = tdb.useCasesExcluded;
85
- if (tdb.excludedTermtypeByTarget)
86
- c.excludedTermtypeByTarget = tdb.excludedTermtypeByTarget;
87
- if (tdb.survival)
88
- c.survival = tdb.survival;
89
- if (tdb.regression)
90
- c.regression = tdb.regression;
91
- if (ds.assayAvailability)
92
- c.assayAvailability = ds.assayAvailability;
93
- if (ds.cohort.correlationVolcano)
94
- c.correlationVolcano = ds.cohort.correlationVolcano;
64
+ if (tdb.plotConfigByCohort) c.plotConfigByCohort = tdb.plotConfigByCohort;
65
+ if (tdb.multipleTestingCorrection) c.multipleTestingCorrection = tdb.multipleTestingCorrection;
66
+ if (tdb.helpPages) c.helpPages = tdb.helpPages;
67
+ if (tdb.minTimeSinceDx) c.minTimeSinceDx = tdb.minTimeSinceDx;
68
+ if (tdb.timeUnit) c.timeUnit = tdb.timeUnit;
69
+ if (tdb.cohortStartTimeMsg) c.cohortStartTimeMsg = tdb.cohortStartTimeMsg;
70
+ if (tdb.hasAncestry) c.hasAncestry = tdb.hasAncestry;
71
+ if (tdb.logscaleBase2) c.logscaleBase2 = tdb.logscaleBase2;
72
+ if (tdb.useCasesExcluded) c.useCasesExcluded = tdb.useCasesExcluded;
73
+ if (tdb.excludedTermtypeByTarget) c.excludedTermtypeByTarget = tdb.excludedTermtypeByTarget;
74
+ if (tdb.survival) c.survival = tdb.survival;
75
+ if (tdb.regression) c.regression = tdb.regression;
76
+ if (ds.assayAvailability) c.assayAvailability = ds.assayAvailability;
77
+ if (ds.cohort.correlationVolcano) c.correlationVolcano = ds.cohort.correlationVolcano;
95
78
  addRestrictAncestries(c, tdb);
96
79
  addScatterplots(c, ds);
97
80
  addMatrixplots(c, ds);
@@ -99,21 +82,18 @@ function make(q, req, res, ds, genome) {
99
82
  c.requiredAuth = authApi.getRequiredCredForDsEmbedder(q.dslabel, q.embedder);
100
83
  const info = authApi.getNonsensitiveInfo(req);
101
84
  c.clientAuthResult = info?.clientAuthResult || {};
102
- if (tdb.displaySampleIds)
103
- c.displaySampleIds = tdb.displaySampleIds(c.clientAuthResult);
85
+ if (tdb.displaySampleIds) c.displaySampleIds = tdb.displaySampleIds(c.clientAuthResult);
104
86
  c.authFilter = req.query.filter;
105
87
  res.send({ termdbConfig: c });
106
88
  }
107
89
  function addRestrictAncestries(c, tdb) {
108
- if (!tdb.restrictAncestries)
109
- return;
90
+ if (!tdb.restrictAncestries) return;
110
91
  c.restrictAncestries = tdb.restrictAncestries.map((i) => {
111
92
  return { name: i.name, tvs: i.tvs, PCcount: i.PCcount };
112
93
  });
113
94
  }
114
95
  function addScatterplots(c, ds) {
115
- if (!ds.cohort.scatterplots)
116
- return;
96
+ if (!ds.cohort.scatterplots) return;
117
97
  c.scatterplots = ds.cohort.scatterplots.plots.map((p) => {
118
98
  return {
119
99
  name: p.name,
@@ -130,16 +110,14 @@ function addScatterplots(c, ds) {
130
110
  });
131
111
  }
132
112
  function addMatrixplots(c, ds) {
133
- if (!ds.cohort.matrixplots)
134
- return;
113
+ if (!ds.cohort.matrixplots) return;
135
114
  c.matrixplots = ds.cohort.matrixplots.plots.map((p) => {
136
115
  return { name: p.name };
137
116
  });
138
117
  }
139
118
  function addNonDictionaryQueries(c, ds, genome) {
140
119
  const q = ds.queries;
141
- if (!q)
142
- return;
120
+ if (!q) return;
143
121
  c.queries = {
144
122
  defaultCoord: q.defaultCoord || genome.defaultcoord,
145
123
  gbRestrictMode: q.gbRestrictMode
@@ -154,8 +132,7 @@ function addNonDictionaryQueries(c, ds, genome) {
154
132
  details: q.snvindel.details,
155
133
  populations: q.snvindel.populations
156
134
  };
157
- if (q.snvindel.byisoform?.processTwsInOneQuery)
158
- q2.snvindel.byisoform = { processTwsInOneQuery: true };
135
+ if (q.snvindel.byisoform?.processTwsInOneQuery) q2.snvindel.byisoform = { processTwsInOneQuery: true };
159
136
  }
160
137
  if (q.trackLst) {
161
138
  q2.trackLst = q.trackLst;
@@ -177,16 +154,13 @@ function addNonDictionaryQueries(c, ds, genome) {
177
154
  "gainColor",
178
155
  "lossColor"
179
156
  ]) {
180
- if (k in q.cnv)
181
- q2.cnv[k] = q.cnv[k];
157
+ if (k in q.cnv) q2.cnv[k] = q.cnv[k];
182
158
  }
183
159
  }
184
160
  if (q.geneCnv) {
185
161
  }
186
- if (q.topMutatedGenes)
187
- q2.topMutatedGenes = q.topMutatedGenes;
188
- if (q.topVariablyExpressedGenes)
189
- q2.topVariablyExpressedGenes = q.topVariablyExpressedGenes;
162
+ if (q.topMutatedGenes) q2.topMutatedGenes = q.topMutatedGenes;
163
+ if (q.topVariablyExpressedGenes) q2.topVariablyExpressedGenes = q.topVariablyExpressedGenes;
190
164
  if (q.singleSampleMutation) {
191
165
  q2.singleSampleMutation = {
192
166
  sample_id_key: q.singleSampleMutation.sample_id_key,
@@ -260,24 +234,18 @@ function addNonDictionaryQueries(c, ds, genome) {
260
234
  function getAllowedTermTypes(ds) {
261
235
  const typeSet = /* @__PURE__ */ new Set();
262
236
  for (const r of ds.cohort.termdb.termtypeByCohort) {
263
- if (r.termType)
264
- typeSet.add(r.termType);
237
+ if (r.termType) typeSet.add(r.termType);
265
238
  }
266
239
  if (ds.cohort.termdb.allowedTermTypes) {
267
- for (const t of ds.cohort.termdb.allowedTermTypes)
268
- typeSet.add(t);
240
+ for (const t of ds.cohort.termdb.allowedTermTypes) typeSet.add(t);
269
241
  }
270
- if (ds.queries?.geneExpression)
271
- typeSet.add(TermTypes.GENE_EXPRESSION);
272
- if (ds.queries?.metaboliteIntensity)
273
- typeSet.add(TermTypes.METABOLITE_INTENSITY);
274
- if (ds.queries?.ssGSEA)
275
- typeSet.add(TermTypes.SSGSEA);
242
+ if (ds.queries?.geneExpression) typeSet.add(TermTypes.GENE_EXPRESSION);
243
+ if (ds.queries?.metaboliteIntensity) typeSet.add(TermTypes.METABOLITE_INTENSITY);
244
+ if (ds.queries?.ssGSEA) typeSet.add(TermTypes.SSGSEA);
276
245
  return [...typeSet];
277
246
  }
278
247
  function getSelectCohort(ds, req) {
279
- if (!ds.cohort.termdb.selectCohort)
280
- return;
248
+ if (!ds.cohort.termdb.selectCohort) return;
281
249
  const copy = Object.assign({}, ds.cohort.termdb.selectCohort);
282
250
  if (ds.cohort.termdb.selectCohort.descriptionByUser) {
283
251
  copy.description = ds.cohort.termdb.selectCohort.descriptionByUser(authApi.getNonsensitiveInfo(req));
@@ -20,22 +20,17 @@ function init({ genomes }) {
20
20
  let result;
21
21
  try {
22
22
  const genome = genomes[req.query.genome];
23
- if (!genome)
24
- throw "invalid genome name";
23
+ if (!genome) throw "invalid genome name";
25
24
  const ds = genome.datasets[req.query.dslabel];
26
- if (!ds)
27
- throw "invalid dataset name";
25
+ if (!ds) throw "invalid dataset name";
28
26
  const tdb = ds.cohort.termdb;
29
- if (!tdb)
30
- throw "invalid termdb object";
31
- if (!q.tw.$id)
32
- q.tw.$id = "_";
27
+ if (!tdb) throw "invalid termdb object";
28
+ if (!q.tw.$id) q.tw.$id = "_";
33
29
  const data = await getData(
34
30
  { filter: q.filter, filter0: q.filter0, terms: [q.tw], __protected__: q.__protected__ },
35
31
  ds
36
32
  );
37
- if (data.error)
38
- throw data.error;
33
+ if (data.error) throw data.error;
39
34
  const values = [];
40
35
  for (const key in data.samples) {
41
36
  const sample = data.samples[key];
@@ -60,8 +55,7 @@ function init({ genomes }) {
60
55
  result = {};
61
56
  }
62
57
  } catch (e) {
63
- if (e instanceof Error && e.stack)
64
- console.log(e);
58
+ if (e instanceof Error && e.stack) console.log(e);
65
59
  result = { error: e?.message || e };
66
60
  }
67
61
  res.send(result);
@@ -18,20 +18,17 @@ function init({ genomes }) {
18
18
  return async (req, res) => {
19
19
  try {
20
20
  const g = genomes[req.query.genome];
21
- if (!g)
22
- throw "invalid genome name";
21
+ if (!g) throw "invalid genome name";
23
22
  const ds = g.datasets?.[req.query.dslabel];
24
23
  res.send(await getFilters(req.query, ds));
25
24
  } catch (e) {
26
- if (e.stack)
27
- console.log(e.stack);
25
+ if (e.stack) console.log(e.stack);
28
26
  res.send({ status: "error", error: e.message || e });
29
27
  }
30
28
  };
31
29
  }
32
30
  async function getFilters(query, ds) {
33
- if (!query.filterByUserSites)
34
- authApi.mayAdjustFilter(query, ds, query.terms);
31
+ if (!query.filterByUserSites) authApi.mayAdjustFilter(query, ds, query.terms);
35
32
  const samplesPerFilter = await getSamplesPerFilter(query, ds);
36
33
  const filtersData = await getData(
37
34
  {
@@ -60,8 +57,7 @@ function getList(samplesPerFilter, filtersData, tw, showAll) {
60
57
  for (const value of values) {
61
58
  const label = value.label.replace(/["']/g, "");
62
59
  const disabled = !sampleValues.includes(value.key || value.label);
63
- if (!showAll && disabled)
64
- continue;
60
+ if (!showAll && disabled) continue;
65
61
  filteredValues.push({ value: value.key || value.label, label, disabled });
66
62
  }
67
63
  filteredValues.unshift({ label: "", value: "" });
@@ -18,26 +18,21 @@ function init({ genomes }) {
18
18
  const q = req.query;
19
19
  try {
20
20
  const g = genomes[req.query.genome];
21
- if (!g)
22
- throw "invalid genome name";
21
+ if (!g) throw "invalid genome name";
23
22
  const ds = g.datasets[req.query.dslabel];
24
- if (!ds)
25
- throw "invalid dataset name";
23
+ if (!ds) throw "invalid dataset name";
26
24
  const tdb = ds.cohort.termdb;
27
- if (!tdb)
28
- throw "invalid termdb object";
25
+ if (!tdb) throw "invalid termdb object";
29
26
  const result = await trigger_getnumericcategories(q, tdb, ds);
30
27
  res.send(result);
31
28
  } catch (e) {
32
29
  res.send({ error: e instanceof Error ? e.message : e });
33
- if (e instanceof Error && e.stack)
34
- console.log(e);
30
+ if (e instanceof Error && e.stack) console.log(e);
35
31
  }
36
32
  };
37
33
  }
38
34
  async function trigger_getnumericcategories(q, tdb, ds) {
39
- if (!q.tid)
40
- throw ".tid missing";
35
+ if (!q.tid) throw ".tid missing";
41
36
  const arg = {
42
37
  ds,
43
38
  term_id: q.tid,
@@ -20,29 +20,23 @@ function init({ genomes }) {
20
20
  const q = req.query;
21
21
  try {
22
22
  const g = genomes[req.query.genome];
23
- if (!g)
24
- throw "invalid genome name";
23
+ if (!g) throw "invalid genome name";
25
24
  const ds = g.datasets[req.query.dslabel];
26
- if (!ds)
27
- throw "invalid dataset name";
25
+ if (!ds) throw "invalid dataset name";
28
26
  await trigger_getpercentile(q, res, ds);
29
27
  } catch (e) {
30
28
  res.send({ error: e instanceof Error ? e.message : e });
31
- if (e instanceof Error && e.stack)
32
- console.log(e);
29
+ if (e instanceof Error && e.stack) console.log(e);
33
30
  }
34
31
  };
35
32
  }
36
33
  async function trigger_getpercentile(q, res, ds) {
37
34
  const term = q.term;
38
- if (!term)
39
- throw "term is missing";
40
- if (!isNumericTerm(term))
41
- throw "not numeric term";
35
+ if (!term) throw "term is missing";
36
+ if (!isNumericTerm(term)) throw "not numeric term";
42
37
  const tw = { $id: "_", term, q: { mode: "continuous" } };
43
38
  const data = await getData({ filter: q.filter, filter0: q.filter0, terms: [tw], __protected__: q.__protected__ }, ds);
44
- if (data.error)
45
- throw data.error;
39
+ if (data.error) throw data.error;
46
40
  const values = [];
47
41
  for (const key in data.samples) {
48
42
  const sample = data.samples[key];
@@ -17,8 +17,7 @@ function init({ genomes }) {
17
17
  return async (req, res) => {
18
18
  try {
19
19
  const g = genomes[req.query.genome];
20
- if (!g)
21
- throw "invalid genome name";
20
+ if (!g) throw "invalid genome name";
22
21
  const ds = g.datasets?.[req.query.dslabel];
23
22
  const result = await getScoresDict(req.query, ds);
24
23
  res.send(result);
@@ -29,11 +28,9 @@ function init({ genomes }) {
29
28
  };
30
29
  }
31
30
  async function getScoresDict(query, ds) {
32
- if (!query.filterByUserSites)
33
- query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
31
+ if (!query.filterByUserSites) query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
34
32
  const terms = [...query.scoreTerms, query.facilityTW];
35
- if (query.scScoreTerms)
36
- terms.push(...query.scScoreTerms);
33
+ if (query.scScoreTerms) terms.push(...query.scScoreTerms);
37
34
  const data = await getData(
38
35
  {
39
36
  terms,
@@ -60,16 +57,12 @@ async function getScoresDict(query, ds) {
60
57
  }
61
58
  }
62
59
  let sitesSelected = [];
63
- if (query.site)
64
- sitesSelected = [query.site];
65
- else if (!query.isAggregate)
66
- sitesSelected = [sites[0].value];
67
- else
68
- sitesSelected = query.sites;
60
+ if (query.site) sitesSelected = [query.site];
61
+ else if (!query.isAggregate) sitesSelected = [sites[0].value];
62
+ else sitesSelected = query.sites;
69
63
  const sampleData = sitesSelected?.length == 1 ? data.samples[sitesSelected[0]] : null;
70
64
  let samples = sampleData ? [sampleData] : Object.values(data.samples);
71
- if (sitesSelected?.length > 0)
72
- samples = samples.filter((s) => sitesSelected.includes(s.sample));
65
+ if (sitesSelected?.length > 0) samples = samples.filter((s) => sitesSelected.includes(s.sample));
73
66
  const term2Score = {};
74
67
  for (const d of query.scoreTerms) {
75
68
  const getDictFunc = (sample) => getDict(d.$id, sample);
@@ -87,8 +80,7 @@ async function getScoresDict(query, ds) {
87
80
  return { term2Score, sites, hospital, n: sampleData ? 1 : samples.length };
88
81
  }
89
82
  function getDict(key, sample) {
90
- if (!sample[key])
91
- return null;
83
+ if (!sample[key]) return null;
92
84
  const termData = sample[key].value;
93
85
  return JSON.parse(termData);
94
86
  }
@@ -96,26 +88,22 @@ function getPercentsDict(getDictFunc, samples) {
96
88
  const percentageDict = {};
97
89
  for (const sample of samples) {
98
90
  const percents = getDictFunc(sample);
99
- if (!percents)
100
- continue;
91
+ if (!percents) continue;
101
92
  for (const key in percents) {
102
93
  const value = percents[key];
103
- if (!percentageDict[key])
104
- percentageDict[key] = 0;
94
+ if (!percentageDict[key]) percentageDict[key] = 0;
105
95
  percentageDict[key] += value;
106
96
  }
107
97
  }
108
98
  return percentageDict;
109
99
  }
110
100
  function getSCPercentsDict(tw, samples) {
111
- if (!tw)
112
- throw "tw not defined";
101
+ if (!tw) throw "tw not defined";
113
102
  const percentageDict = {};
114
103
  for (const sample of samples) {
115
104
  const twData = sample[tw.$id];
116
105
  const key = twData?.value;
117
- if (!percentageDict[key])
118
- percentageDict[key] = 0;
106
+ if (!percentageDict[key]) percentageDict[key] = 0;
119
107
  percentageDict[key] += 1;
120
108
  }
121
109
  return percentageDict;
@@ -17,8 +17,7 @@ function init({ genomes }) {
17
17
  return async (req, res) => {
18
18
  try {
19
19
  const g = genomes[req.query.genome];
20
- if (!g)
21
- throw "invalid genome name";
20
+ if (!g) throw "invalid genome name";
22
21
  const ds = g.datasets?.[req.query.dslabel];
23
22
  const result = await getScores(req.query, ds);
24
23
  res.send(result);
@@ -29,8 +28,7 @@ function init({ genomes }) {
29
28
  };
30
29
  }
31
30
  async function getScores(query, ds) {
32
- if (!query.filterByUserSites)
33
- query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
31
+ if (!query.filterByUserSites) query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
34
32
  const terms = [query.facilityTW];
35
33
  for (const term of query.scoreTerms) {
36
34
  terms.push(term.score);
@@ -61,16 +59,12 @@ async function getScores(query, ds) {
61
59
  }
62
60
  }
63
61
  let sitesSelected = [];
64
- if (query.site)
65
- sitesSelected = [query.site];
66
- else if (!query.isAggregate)
67
- sitesSelected = [sites[0].value];
68
- else
69
- sitesSelected = query.sites;
62
+ if (query.site) sitesSelected = [query.site];
63
+ else if (!query.isAggregate) sitesSelected = [sites[0].value];
64
+ else sitesSelected = query.sites;
70
65
  const sampleData = sitesSelected?.length == 1 ? data.samples[sitesSelected[0]] : null;
71
66
  let samples = Object.values(data.samples);
72
- if (sitesSelected?.length > 0)
73
- samples = samples.filter((s) => sitesSelected.includes(s.sample));
67
+ if (sitesSelected?.length > 0) samples = samples.filter((s) => sitesSelected.includes(s.sample));
74
68
  const term2Score = {};
75
69
  for (const d of query.scoreTerms) {
76
70
  term2Score[d.score.term.id] = getPercentage(d, samples, sampleData);
@@ -81,8 +75,7 @@ async function getScores(query, ds) {
81
75
  return { term2Score, sites, hospital, n: sampleData ? 1 : samples.length };
82
76
  }
83
77
  function getPercentage(d, samples, sampleData) {
84
- if (!d)
85
- return null;
78
+ if (!d) return null;
86
79
  const isAggregate = sampleData == null;
87
80
  if (isAggregate) {
88
81
  const scores = samples.filter((sample) => sample[d.score.$id]?.value).map((sample) => sample[d.score.$id].value / (sample[d.maxScore.$id]?.value || d.maxScore) * 100);
@@ -18,18 +18,14 @@ function init({ genomes }) {
18
18
  const q = req.query;
19
19
  try {
20
20
  const g = genomes[req.query.genome];
21
- if (!g)
22
- throw "invalid genome name";
21
+ if (!g) throw "invalid genome name";
23
22
  const [ds, tdb] = get_ds_tdb(g, q);
24
- if (!ds)
25
- throw "invalid dataset name";
26
- if (!tdb)
27
- throw "invalid termdb object";
23
+ if (!ds) throw "invalid dataset name";
24
+ if (!tdb) throw "invalid termdb object";
28
25
  await trigger_rootterm(req, q, res, tdb);
29
26
  } catch (e) {
30
27
  res.send({ error: e instanceof Error ? e.message : e });
31
- if (e instanceof Error && e.stack)
32
- console.log(e);
28
+ if (e instanceof Error && e.stack) console.log(e);
33
29
  }
34
30
  };
35
31
  }
@@ -21,11 +21,9 @@ function init({ genomes }) {
21
21
  const q = req.query;
22
22
  const sampleId = q.sampleId;
23
23
  const genome = genomes[q.genome];
24
- if (!genome)
25
- throw "invalid genome";
24
+ if (!genome) throw "invalid genome";
26
25
  const ds = genome.datasets?.[q.dslabel];
27
- if (!ds)
28
- throw "invalid dslabel";
26
+ if (!ds) throw "invalid dslabel";
29
27
  const images = await ds.queries.images.getSampleImages({ sampleId });
30
28
  res.send({ images });
31
29
  } catch (e) {
@@ -35,8 +33,7 @@ function init({ genomes }) {
35
33
  }
36
34
  function validate_query_getSampleImages(ds) {
37
35
  const q = ds.queries.images;
38
- if (!q)
39
- return;
36
+ if (!q) return;
40
37
  nativeValidateQuery(ds);
41
38
  }
42
39
  function nativeValidateQuery(ds) {
@@ -52,8 +49,7 @@ async function getSampleImages(ds, folder, sampleId) {
52
49
  const images = [];
53
50
  for (const row of rows) {
54
51
  const file = path.join(serverconfig.tpmasterdir, folder, row.fileName);
55
- if (!fs.existsSync(file))
56
- throw new Error(`File ${row.fileName} does not exist`);
52
+ if (!fs.existsSync(file)) throw new Error(`File ${row.fileName} does not exist`);
57
53
  const data = await fs.promises.readFile(file);
58
54
  images.push({
59
55
  src: "data:image/jpeg;base64," + Buffer.from(data).toString("base64")
@@ -17,17 +17,13 @@ function init({ genomes }) {
17
17
  let result;
18
18
  try {
19
19
  const g = genomes[q.genome];
20
- if (!g)
21
- throw "invalid genome name";
20
+ if (!g) throw "invalid genome name";
22
21
  const ds = g.datasets[q.dslabel];
23
- if (!ds)
24
- throw "invalid dataset name";
25
- if (!ds.queries?.singleSampleMutation)
26
- throw "not supported on this dataset";
22
+ if (!ds) throw "invalid dataset name";
23
+ if (!ds.queries?.singleSampleMutation) throw "not supported on this dataset";
27
24
  result = await ds.queries.singleSampleMutation.get(q);
28
25
  } catch (e) {
29
- if (e.stack)
30
- console.log(e.stack);
26
+ if (e.stack) console.log(e.stack);
31
27
  result = {
32
28
  status: e.status || 400,
33
29
  error: e.message || e
@@ -38,8 +34,7 @@ function init({ genomes }) {
38
34
  }
39
35
  async function validate_query_singleSampleMutation(ds, genome) {
40
36
  const _q = ds.queries.singleSampleMutation;
41
- if (!_q)
42
- return;
37
+ if (!_q) return;
43
38
  if (_q.src == "gdcapi") {
44
39
  gdcValidate_query_singleSampleMutation(ds, genome);
45
40
  } else if (_q.src == "native") {
@@ -48,8 +43,7 @@ async function validate_query_singleSampleMutation(ds, genome) {
48
43
  {
49
44
  const vt = typeof q.sample;
50
45
  if (vt == "string") {
51
- if (q.sample == "")
52
- throw "sample is blank string";
46
+ if (q.sample == "") throw "sample is blank string";
53
47
  sample = q.sample;
54
48
  } else if (vt == "number") {
55
49
  sample = q.sample.toString();
@@ -57,18 +51,15 @@ async function validate_query_singleSampleMutation(ds, genome) {
57
51
  throw "sample value is not string or number";
58
52
  }
59
53
  }
60
- if (illegalpath(sample))
61
- throw "invalid sample name";
54
+ if (illegalpath(sample)) throw "invalid sample name";
62
55
  const tmp = fileurl({
63
56
  query: {
64
57
  file: path.join(_q.folder, sample)
65
58
  }
66
59
  });
67
- if (tmp[0])
68
- throw tmp[0];
60
+ if (tmp[0]) throw tmp[0];
69
61
  const file = tmp[1];
70
- if (!file)
71
- throw "no file returned";
62
+ if (!file) throw "no file returned";
72
63
  await file_is_readable(file);
73
64
  const data = await read_file(file);
74
65
  return { mlst: JSON.parse(data) };
@@ -19,13 +19,10 @@ function init({ genomes }) {
19
19
  let result;
20
20
  try {
21
21
  const g = genomes[q.genome];
22
- if (!g)
23
- throw "invalid genome name";
22
+ if (!g) throw "invalid genome name";
24
23
  const ds = g.datasets[q.dslabel];
25
- if (!ds)
26
- throw "invalid dataset name";
27
- if (!ds.queries?.singleCell?.DEgenes)
28
- throw "not supported on this dataset";
24
+ if (!ds) throw "invalid dataset name";
25
+ if (!ds.queries?.singleCell?.DEgenes) throw "not supported on this dataset";
29
26
  result = await ds.queries.singleCell.DEgenes.get(q);
30
27
  if (!result || !result.genes || !result?.genes?.length) {
31
28
  result = {
@@ -34,8 +31,7 @@ function init({ genomes }) {
34
31
  };
35
32
  }
36
33
  } catch (e) {
37
- if (e.stack)
38
- console.log(e.stack);
34
+ if (e.stack) console.log(e.stack);
39
35
  result = {
40
36
  status: e.status || 400,
41
37
  error: e.message || e
@@ -18,17 +18,13 @@ function init({ genomes }) {
18
18
  let result;
19
19
  try {
20
20
  const g = genomes[q.genome];
21
- if (!g)
22
- throw "invalid genome name";
21
+ if (!g) throw "invalid genome name";
23
22
  const ds = g.datasets[q.dslabel];
24
- if (!ds)
25
- throw "invalid dataset name";
26
- if (!ds.queries?.singleCell)
27
- throw "no singlecell data on this dataset";
23
+ if (!ds) throw "invalid dataset name";
24
+ if (!ds.queries?.singleCell) throw "no singlecell data on this dataset";
28
25
  result = await ds.queries.singleCell.data.get(q);
29
26
  } catch (e) {
30
- if (e.stack)
31
- console.log(e);
27
+ if (e.stack) console.log(e);
32
28
  result = {
33
29
  status: e.status || 400,
34
30
  error: e.message || e