@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
@@ -22,23 +22,19 @@ function init({ genomes }) {
22
22
  const q = req.query;
23
23
  try {
24
24
  const genome = genomes[q.genome];
25
- if (!genome)
26
- throw "invalid genome name";
25
+ if (!genome) throw "invalid genome name";
27
26
  const ds = genome.datasets?.[q.dslabel];
28
- if (!ds)
29
- throw "invalid ds";
27
+ if (!ds) throw "invalid ds";
30
28
  const result = await compute(q, ds);
31
29
  res.send(result);
32
30
  } catch (e) {
33
31
  res.send({ error: e?.message || e });
34
- if (e instanceof Error && e.stack)
35
- console.error(e);
32
+ if (e instanceof Error && e.stack) console.error(e);
36
33
  }
37
34
  };
38
35
  }
39
36
  async function compute(q, ds) {
40
- if (!q.featureTw.$id)
41
- throw "featureTw.$id missing";
37
+ if (!q.featureTw.$id) throw "featureTw.$id missing";
42
38
  if (!ds.cohort.correlationVolcano.feature.termTypes.includes(q.featureTw?.term.type))
43
39
  throw "unsupported featureTw.term.type";
44
40
  const data = await getData(
@@ -50,22 +46,18 @@ async function compute(q, ds) {
50
46
  },
51
47
  ds
52
48
  );
53
- if (data.error)
54
- throw data.error;
49
+ if (data.error) throw data.error;
55
50
  const vtid2array = /* @__PURE__ */ new Map();
56
51
  for (const tw of q.variableTwLst) {
57
52
  vtid2array.set(tw.$id, { id: tw.$id, v1: [], v2: [] });
58
53
  }
59
54
  for (const sid in data.samples) {
60
55
  const featureValue = data.samples[sid][q.featureTw.$id]?.value;
61
- if (!Number.isFinite(featureValue))
62
- continue;
56
+ if (!Number.isFinite(featureValue)) continue;
63
57
  for (const tw of q.variableTwLst) {
64
- if (!tw.$id)
65
- throw "variableTwLst[].$id missing";
58
+ if (!tw.$id) throw "variableTwLst[].$id missing";
66
59
  const variableValue = data.samples[sid][tw.$id]?.value;
67
- if (!Number.isFinite(variableValue))
68
- continue;
60
+ if (!Number.isFinite(variableValue)) continue;
69
61
  vtid2array.get(tw.$id).v1.push(featureValue);
70
62
  vtid2array.get(tw.$id).v2.push(variableValue);
71
63
  }
@@ -79,8 +71,7 @@ async function compute(q, ds) {
79
71
  acceptedVariables.push(v);
80
72
  }
81
73
  const result = { skippedVariables, variableItems: [] };
82
- if (!acceptedVariables.length)
83
- return result;
74
+ if (!acceptedVariables.length) return result;
84
75
  const input = {
85
76
  method: q.correlationMethod || "pearson",
86
77
  terms: acceptedVariables
@@ -105,34 +96,25 @@ async function compute(q, ds) {
105
96
  }
106
97
  function validate_correlationVolcano(ds) {
107
98
  const cv = ds.cohort.correlationVolcano;
108
- if (!cv)
109
- return;
110
- if (typeof cv.feature != "object")
111
- throw "cv.feature not obj";
112
- if (!Array.isArray(cv.feature.termTypes))
113
- throw "cv.feature.termTypes[] not array";
99
+ if (!cv) return;
100
+ if (typeof cv.feature != "object") throw "cv.feature not obj";
101
+ if (!Array.isArray(cv.feature.termTypes)) throw "cv.feature.termTypes[] not array";
114
102
  for (const t of cv.feature.termTypes) {
115
103
  if (t == "geneExpression") {
116
- if (!ds.queries?.geneExpression)
117
- throw "geneExpression cv.feature is not supported";
104
+ if (!ds.queries?.geneExpression) throw "geneExpression cv.feature is not supported";
118
105
  } else if (t == "ssGSEA") {
119
- if (!ds.queries?.ssGSEA)
120
- throw "ssGSEA cv.feature is not supported";
106
+ if (!ds.queries?.ssGSEA) throw "ssGSEA cv.feature is not supported";
121
107
  } else {
122
108
  throw "unknown cv.feature.termType";
123
109
  }
124
110
  }
125
- if (typeof cv.variables != "object")
126
- throw "cv.variables not obj";
111
+ if (typeof cv.variables != "object") throw "cv.variables not obj";
127
112
  if (cv.variables.type == "dictionaryTerm") {
128
- if (!Array.isArray(cv.variables.termIds))
129
- throw "cv.variables.termIds not array when type=dictionaryTerm";
113
+ if (!Array.isArray(cv.variables.termIds)) throw "cv.variables.termIds not array when type=dictionaryTerm";
130
114
  for (const id of cv.variables.termIds) {
131
115
  const t = ds.cohort.termdb.q.termjsonByOneid(id);
132
- if (!t)
133
- throw "cv.variables.termIds: unknown id: " + id;
134
- if (t.type != "integer" && t.type != "float")
135
- throw "cv.variables.termIds: not integer/float: " + id;
116
+ if (!t) throw "cv.variables.termIds: unknown id: " + id;
117
+ if (t.type != "integer" && t.type != "float") throw "cv.variables.termIds: not integer/float: " + id;
136
118
  }
137
119
  } else {
138
120
  throw "unknown cv.variables.type";
package/routes/dataset.js CHANGED
@@ -20,10 +20,8 @@ function init({ genomes }) {
20
20
  try {
21
21
  const q = req.query;
22
22
  const genome = genomes[q.genome];
23
- if (!genome)
24
- throw "unknown genome";
25
- if (!genome.datasets)
26
- throw "genomeobj.datasets{} missing";
23
+ if (!genome) throw "unknown genome";
24
+ if (!genome.datasets) throw "genomeobj.datasets{} missing";
27
25
  let ds;
28
26
  for (const k in genome.datasets) {
29
27
  if (k.toLowerCase() == q.dsname.toLowerCase()) {
@@ -31,8 +29,7 @@ function init({ genomes }) {
31
29
  break;
32
30
  }
33
31
  }
34
- if (!ds)
35
- throw "invalid dsname";
32
+ if (!ds) throw "invalid dsname";
36
33
  const copy = ds.isMds3 ? mds3_init.client_copy(ds) : ds.isMds ? mds_clientcopy(ds) : copy_legacyDataset(ds);
37
34
  return res.send({ ds: copy });
38
35
  } catch (e) {
@@ -72,8 +69,7 @@ function mds_clientcopy(ds) {
72
69
  const toclient = {};
73
70
  for (const k in ds.cohort.sampleAttribute.attributes) {
74
71
  const a = ds.cohort.sampleAttribute.attributes[k];
75
- if (!a.clientnoshow)
76
- toclient[k] = a;
72
+ if (!a.clientnoshow) toclient[k] = a;
77
73
  }
78
74
  ds2.sampleAttribute = { attributes: toclient };
79
75
  }
@@ -168,8 +164,7 @@ function mds_clientcopy(ds) {
168
164
  const lst = [];
169
165
  if (e.boxplotbysamplegroup.attributes)
170
166
  lst.push(e.boxplotbysamplegroup.attributes.map((i) => i.label).join(", "));
171
- for (const i of e.boxplotbysamplegroup.additionals)
172
- lst.push(i.label);
167
+ for (const i of e.boxplotbysamplegroup.additionals) lst.push(i.label);
173
168
  clientquery.checkexpressionrank.boxplotgroupers = lst;
174
169
  }
175
170
  }
@@ -222,8 +217,7 @@ function copy_legacyDataset(ds) {
222
217
  rep.lst = [];
223
218
  for (const e of at.lst) {
224
219
  const rep2 = {};
225
- for (const k2 in e)
226
- rep2[k2] = e[k2];
220
+ for (const k2 in e) rep2[k2] = e[k2];
227
221
  rep.lst.push(rep2);
228
222
  }
229
223
  } else {
@@ -0,0 +1,75 @@
1
+ import { deleteWSIAnnotationPayload } from "#types/checkers";
2
+ import { getDbConnection } from "#src/aiHistoDBConnection.ts";
3
+ import { runSQL } from "#src/runSQLHelpers.ts";
4
+ const api = {
5
+ endpoint: `deleteWSIAnnotation`,
6
+ methods: {
7
+ delete: {
8
+ ...deleteWSIAnnotationPayload,
9
+ init
10
+ }
11
+ }
12
+ };
13
+ function init({ genomes }) {
14
+ return async (req, res) => {
15
+ try {
16
+ const query = req.query;
17
+ if (!query.genome) throw new Error(".genome is required for deleteWSIAnnotation request.");
18
+ if (!query.dslabel) throw new Error(".dslabel is required for deleteWSIAnnotation request.");
19
+ if (!query.annotation) throw new Error(".annotation:{} is required for deleteWSIAnnotation request.");
20
+ if (!query.projectId) throw new Error(".projectId is required for deleteWSIAnnotation request.");
21
+ if (!query.wsimage) throw new Error(".wsimage is required for deleteWSIAnnotation request.");
22
+ const g = genomes[query.genome];
23
+ if (!g) throw new Error("invalid genome name");
24
+ const ds = g.datasets[query.dslabel];
25
+ if (!ds) throw new Error("invalid dataset name");
26
+ if (typeof ds.queries?.WSImages?.deleteAnnotation === "function") {
27
+ const result = await ds.queries.WSImages.deleteAnnotation(query);
28
+ if (result?.status === "error") {
29
+ return res.status(500).send(result);
30
+ }
31
+ }
32
+ res.status(200).send({ status: `Annotation = ${query.annotation.zoomCoordinates} deleted.` });
33
+ } catch (e) {
34
+ console.warn(e);
35
+ res.status(500).send({
36
+ status: "error",
37
+ error: e?.message || String(e)
38
+ });
39
+ }
40
+ };
41
+ }
42
+ async function validate_query_deleteWSIAnnotation(ds) {
43
+ if (!ds.queries?.WSImages?.db) return;
44
+ const connection = getDbConnection(ds);
45
+ if (!connection) {
46
+ return;
47
+ }
48
+ validateQuery(ds, connection);
49
+ }
50
+ function validateQuery(ds, connection) {
51
+ ds.queries.WSImages.deleteAnnotation = async (query) => {
52
+ const sql = `
53
+ DELETE FROM project_annotations
54
+ WHERE project_id = ?
55
+ AND coordinates = ?
56
+ AND image_id = (
57
+ SELECT id FROM project_images
58
+ WHERE project_id = ?
59
+ AND image_path = ?
60
+ )
61
+ `;
62
+ const params = [
63
+ query.projectId,
64
+ JSON.stringify(query.annotation.zoomCoordinates),
65
+ query.projectId,
66
+ query.wsimage
67
+ // this is the image_path
68
+ ];
69
+ return runSQL(connection, sql, params, "delete annotation");
70
+ };
71
+ }
72
+ export {
73
+ api,
74
+ validate_query_deleteWSIAnnotation
75
+ };
package/routes/dsdata.js CHANGED
@@ -24,13 +24,10 @@ function init({ genomes }) {
24
24
  return async function handle_dsdata(req, res) {
25
25
  try {
26
26
  const q = req.query;
27
- if (!genomes[q.genome])
28
- throw "invalid genome";
29
- if (!q.dsname)
30
- throw ".dsname missing";
27
+ if (!genomes[q.genome]) throw "invalid genome";
28
+ if (!q.dsname) throw ".dsname missing";
31
29
  const ds = genomes[q.genome].datasets[q.dsname];
32
- if (!ds)
33
- throw "invalid dsname";
30
+ if (!ds) throw "invalid dsname";
34
31
  const data = [];
35
32
  for (const query of ds.queries) {
36
33
  if (q.expressiononly && !query.isgeneexpression) {
@@ -56,16 +53,14 @@ function init({ genomes }) {
56
53
  }
57
54
  res.send({ data });
58
55
  } catch (e) {
59
- if (e.stack)
60
- console.log(e.stack);
56
+ if (e.stack) console.log(e.stack);
61
57
  res.send({ error: e.message || e });
62
58
  }
63
59
  };
64
60
  }
65
61
  function handle_dsdata_makequery(ds, query, req, genomes) {
66
62
  if (req.query.isoform) {
67
- if (genomes[req.query.genome].genomicNameRegexp.test(req.query.isoform))
68
- return;
63
+ if (genomes[req.query.genome].genomicNameRegexp.test(req.query.isoform)) return;
69
64
  }
70
65
  const [sqlstr, values] = query.makequery(req.query);
71
66
  if (!sqlstr) {
@@ -84,8 +79,7 @@ function handle_dsdata_makequery(ds, query, req, genomes) {
84
79
  result.isgeneexpression = true;
85
80
  result.config = query.config;
86
81
  for (const q2 of ds.queries) {
87
- if (!q2.dsblocktracklst)
88
- continue;
82
+ if (!q2.dsblocktracklst) continue;
89
83
  for (const tk of q2.dsblocktracklst) {
90
84
  if (tk.type == common.tkt.junction) {
91
85
  result.config.dsjunctiontk = tk;
@@ -109,8 +103,7 @@ function handle_dsdata_vcf(query, req) {
109
103
  ps.stderr.on("data", (i) => out2.push(i));
110
104
  ps.on("close", () => {
111
105
  const e = out2.join("").trim();
112
- if (e != "")
113
- reject("error querying vcf file");
106
+ if (e != "") reject("error querying vcf file");
114
107
  const tmp = out.join("").trim();
115
108
  resolve({
116
109
  lines: tmp == "" ? [] : tmp.split("\n"),
@@ -20,16 +20,12 @@ function init({ genomes }) {
20
20
  try {
21
21
  const q = req.query;
22
22
  const g = genomes[q.genome];
23
- if (!g)
24
- throw "invalid genome name";
23
+ if (!g) throw "invalid genome name";
25
24
  const ds = g.datasets[q.dslabel];
26
- if (!ds)
27
- throw "invalid dataset name";
25
+ if (!ds) throw "invalid dataset name";
28
26
  const sampleId = q.sampleId;
29
- if (!sampleId)
30
- throw "invalid sampleId";
31
- if (illegalpath(req.query.file))
32
- throw `illegalpath filepath`;
27
+ if (!sampleId) throw "invalid sampleId";
28
+ if (illegalpath(req.query.file)) throw `illegalpath filepath`;
33
29
  const filename = path.basename(q.file);
34
30
  const allowedExtensions = [".dzi", ".jpeg", ".png"];
35
31
  const extension = path.extname(filename);
@@ -24,11 +24,9 @@ function init({ genomes }) {
24
24
  return async (req, res) => {
25
25
  try {
26
26
  const g = genomes.hg38;
27
- if (!g)
28
- throw "hg38 missing";
27
+ if (!g) throw "hg38 missing";
29
28
  const ds = g.datasets?.GDC;
30
- if (!ds)
31
- throw "hg38 GDC missing";
29
+ if (!ds) throw "hg38 GDC missing";
32
30
  console.log("GRIN2 List Route Received:", JSON.stringify(req.query, null, 2));
33
31
  const result = {};
34
32
  if (req.query.mafOptions) {
@@ -49,15 +47,13 @@ function init({ genomes }) {
49
47
  }
50
48
  res.send(result);
51
49
  } catch (e) {
52
- if (e.stack)
53
- console.log(e.stack);
50
+ if (e.stack) console.log(e.stack);
54
51
  res.send({ status: "error", error: e.message || e });
55
52
  }
56
53
  };
57
54
  }
58
55
  async function listMafFiles(q, result, ds) {
59
- if (!q.mafOptions)
60
- return;
56
+ if (!q.mafOptions) return;
61
57
  if (!result.mafFiles) {
62
58
  throw new Error("result.mafFiles must be initialized before calling listMafFiles");
63
59
  }
@@ -88,22 +84,17 @@ async function listMafFiles(q, result, ds) {
88
84
  "cases.samples.tumor_descriptor"
89
85
  ].join(",")
90
86
  };
91
- if (case_filters.content.length)
92
- body.case_filters = case_filters;
87
+ if (case_filters.content.length) body.case_filters = case_filters;
93
88
  const response = await ky.post(joinUrl(host.rest, "files"), { timeout: false, headers, json: body });
94
- if (!response.ok)
95
- throw `HTTP Error: ${response.status} ${response.statusText}`;
89
+ if (!response.ok) throw `HTTP Error: ${response.status} ${response.statusText}`;
96
90
  const re = await response.json();
97
- if (!Number.isInteger(re.data?.pagination?.total))
98
- throw "re.data.pagination.total is not int";
99
- if (!Array.isArray(re.data?.hits))
100
- throw "re.data.hits[] not array";
91
+ if (!Number.isInteger(re.data?.pagination?.total)) throw "re.data.pagination.total is not int";
92
+ if (!Array.isArray(re.data?.hits)) throw "re.data.hits[] not array";
101
93
  const files = [];
102
94
  const filteredFiles = [];
103
95
  for (const h of re.data.hits) {
104
96
  const c = h.cases?.[0];
105
- if (!c)
106
- throw "h.cases[0] missing";
97
+ if (!c) throw "h.cases[0] missing";
107
98
  if (h.file_size >= maxFileSizeAllowed) {
108
99
  filteredFiles.push({
109
100
  fileId: h.id,
@@ -133,8 +124,7 @@ If you want to include it, please increase the maxFileSizeAllowed in the code.`
133
124
  }
134
125
  file.sample_types.push(tumor_descriptor + " " + tissue_type);
135
126
  }
136
- if (normalTypeName)
137
- file.sample_types.push(normalTypeName);
127
+ if (normalTypeName) file.sample_types.push(normalTypeName);
138
128
  }
139
129
  file.sample_types = [...new Set(file.sample_types)];
140
130
  files.push(file);
@@ -215,8 +205,7 @@ async function listCnvFiles(q, result, ds) {
215
205
  }
216
206
  }
217
207
  };
218
- if (case_filters.content.length)
219
- body.case_filters = case_filters;
208
+ if (case_filters.content.length) body.case_filters = case_filters;
220
209
  const { host, headers } = ds.getHostHeaders(q);
221
210
  try {
222
211
  const re = await ky.post(joinUrl(host.rest, "files"), { timeout: false, headers, json: body }).json();
@@ -232,11 +221,9 @@ async function listCnvFiles(q, result, ds) {
232
221
  if (h.data_format != "TXT") {
233
222
  continue;
234
223
  }
235
- if (!h.analysis?.workflow_type)
236
- throw "h.analysis.workflow_type missing";
224
+ if (!h.analysis?.workflow_type) throw "h.analysis.workflow_type missing";
237
225
  const c = h.cases?.[0];
238
- if (!c)
239
- throw "h.cases[0] missing";
226
+ if (!c) throw "h.cases[0] missing";
240
227
  if (h.data_type == "Allele-specific Copy Number Segment") {
241
228
  } else if (h.data_type == "Masked Copy Number Segment" || h.data_type == "Copy Number Segment" && h.analysis.workflow_type != "DNACopy") {
242
229
  const file = {
@@ -34,11 +34,9 @@ function init({ genomes }) {
34
34
  }
35
35
  async function runGrin2(genomes, req, res) {
36
36
  const g = genomes.hg38;
37
- if (!g)
38
- throw "hg38 missing";
37
+ if (!g) throw "hg38 missing";
39
38
  const ds = g.datasets.GDC;
40
- if (!ds)
41
- throw "hg38 GDC missing";
39
+ if (!ds) throw "hg38 GDC missing";
42
40
  const parsedRequest = req.query;
43
41
  const rustInput = {
44
42
  caseFiles: parsedRequest.caseFiles,
@@ -54,8 +52,7 @@ async function runGrin2(genomes, req, res) {
54
52
  };
55
53
  for (const c in g.majorchr) {
56
54
  if (ds.queries.singleSampleMutation?.discoPlot?.skipChrM) {
57
- if (c.toLowerCase() == "chrm")
58
- continue;
55
+ if (c.toLowerCase() == "chrm") continue;
59
56
  }
60
57
  rustInput.chromosomes.push(c);
61
58
  pyInput.chromosomelist[c] = g.majorchr[c];
package/routes/gdc.maf.js CHANGED
@@ -22,11 +22,9 @@ function init({ genomes }) {
22
22
  return async (req, res) => {
23
23
  try {
24
24
  const g = genomes.hg38;
25
- if (!g)
26
- throw "hg38 missing";
25
+ if (!g) throw "hg38 missing";
27
26
  const ds = g.datasets.GDC;
28
- if (!ds)
29
- throw "hg38 GDC missing";
27
+ if (!ds) throw "hg38 GDC missing";
30
28
  const payload = await listMafFiles(req.query, ds);
31
29
  res.send(payload);
32
30
  } catch (e) {
@@ -66,21 +64,16 @@ async function listMafFiles(q, ds) {
66
64
  "cases.samples.tumor_descriptor"
67
65
  ].join(",")
68
66
  };
69
- if (case_filters.content.length)
70
- body.case_filters = case_filters;
67
+ if (case_filters.content.length) body.case_filters = case_filters;
71
68
  const response = await ky.post(joinUrl(host.rest, "files"), { timeout: false, json: body });
72
- if (!response.ok)
73
- throw `HTTP Error: ${response.status} ${response.statusText}`;
69
+ if (!response.ok) throw `HTTP Error: ${response.status} ${response.statusText}`;
74
70
  const re = await response.json();
75
- if (!Number.isInteger(re.data?.pagination?.total))
76
- throw "re.data.pagination.total is not int";
77
- if (!Array.isArray(re.data?.hits))
78
- throw "re.data.hits[] not array";
71
+ if (!Number.isInteger(re.data?.pagination?.total)) throw "re.data.pagination.total is not int";
72
+ if (!Array.isArray(re.data?.hits)) throw "re.data.hits[] not array";
79
73
  const files = [];
80
74
  for (const h of re.data.hits) {
81
75
  const c = h.cases?.[0];
82
- if (!c)
83
- throw "h.cases[0] missing";
76
+ if (!c) throw "h.cases[0] missing";
84
77
  const file = {
85
78
  id: h.id,
86
79
  project_id: c.project.project_id,
@@ -98,8 +91,7 @@ async function listMafFiles(q, ds) {
98
91
  }
99
92
  file.sample_types.push(tumor_descriptor + " " + tissue_type);
100
93
  }
101
- if (normalTypeName)
102
- file.sample_types.push(normalTypeName);
94
+ if (normalTypeName) file.sample_types.push(normalTypeName);
103
95
  }
104
96
  file.sample_types = [...new Set(file.sample_types)];
105
97
  files.push(file);
@@ -22,15 +22,12 @@ function init({ genomes }) {
22
22
  try {
23
23
  const q = req.query;
24
24
  const g = genomes.hg38;
25
- if (!g)
26
- throw "hg38 missing";
25
+ if (!g) throw "hg38 missing";
27
26
  const ds = g.datasets.GDC;
28
- if (!ds)
29
- throw "hg38 GDC missing";
27
+ if (!ds) throw "hg38 GDC missing";
30
28
  await buildMaf(q, res, ds);
31
29
  } catch (e) {
32
- if (e.stack)
33
- console.log(e.stack);
30
+ if (e.stack) console.log(e.stack);
34
31
  res.send({ status: "error", error: e.message || e });
35
32
  }
36
33
  };
@@ -57,8 +54,7 @@ async function buildMaf(q, res, ds) {
57
54
  if (streams) {
58
55
  const { rustStream, endStream } = streams;
59
56
  res.on("close", () => {
60
- if (res.writableEnded)
61
- return;
57
+ if (res.writableEnded) return;
62
58
  try {
63
59
  console.log("\n-- forced res.end() ---\n");
64
60
  res.end();
@@ -74,8 +70,7 @@ async function buildMaf(q, res, ds) {
74
70
  rustStream.pipe(res, { end: false }).on("error", (e) => {
75
71
  console.log("rustStream.pipe().on(error)", e);
76
72
  }).on("end", () => {
77
- if (res.writableEnded)
78
- return;
73
+ if (res.writableEnded) return;
79
74
  console.log("rustStream.on(end), trigger res.end()");
80
75
  res.end();
81
76
  });
@@ -86,8 +81,7 @@ async function buildMaf(q, res, ds) {
86
81
  console.log("error calling stream_rust(gdcmaf)", e);
87
82
  }
88
83
  function emitJson(data, end = true) {
89
- if (res.writableEnded)
90
- return;
84
+ if (res.writableEnded) return;
91
85
  if (data) {
92
86
  res.write(`\r
93
87
  --${boundary}`);
@@ -100,13 +94,11 @@ async function buildMaf(q, res, ds) {
100
94
  --${boundary}--\r
101
95
  `);
102
96
  mayLog("rust gdcmaf", Date.now() - t0);
103
- if (end)
104
- res.end();
97
+ if (end) res.end();
105
98
  }
106
99
  }
107
100
  async function getFileLstUnderSizeLimit(lst, host) {
108
- if (lst.length == 0)
109
- throw "fileIdLst[] not array or blank";
101
+ if (lst.length == 0) throw "fileIdLst[] not array or blank";
110
102
  const body = {
111
103
  filters: {
112
104
  op: "in",
@@ -116,25 +108,19 @@ async function getFileLstUnderSizeLimit(lst, host) {
116
108
  fields: "file_size"
117
109
  };
118
110
  const response = await ky.post(joinUrl(host.rest, "files"), { timeout: false, json: body });
119
- if (!response.ok)
120
- throw `HTTP Error: ${response.status} ${response.statusText}`;
111
+ if (!response.ok) throw `HTTP Error: ${response.status} ${response.statusText}`;
121
112
  const re = await response.json();
122
- if (!Array.isArray(re.data?.hits))
123
- throw "re.data.hits[] not array";
113
+ if (!Array.isArray(re.data?.hits)) throw "re.data.hits[] not array";
124
114
  const out = [];
125
115
  let cumsize = 0;
126
116
  for (const h of re.data.hits) {
127
- if (cumsize >= maxTotalSizeCompressed)
128
- break;
129
- if (!h.id)
130
- throw ".id missing";
131
- if (!Number.isInteger(h.file_size))
132
- throw ".file_size not integer";
117
+ if (cumsize >= maxTotalSizeCompressed) break;
118
+ if (!h.id) throw ".id missing";
119
+ if (!Number.isInteger(h.file_size)) throw ".file_size not integer";
133
120
  cumsize += h.file_size;
134
121
  out.push(h.id);
135
122
  }
136
- if (out.length == 0)
137
- throw "no file available";
123
+ if (out.length == 0) throw "no file available";
138
124
  return out;
139
125
  }
140
126
  export {
@@ -20,19 +20,15 @@ const api = {
20
20
  function init({ genomes }) {
21
21
  return function(req, res) {
22
22
  try {
23
- if (!req.query.gene)
24
- throw ".gene missing";
23
+ if (!req.query.gene) throw ".gene missing";
25
24
  const genome = genomes[req.query.genome];
26
- if (!genome)
27
- throw "unknown genome";
28
- if (!genome.genedb.get_gene2canonicalisoform)
29
- throw "gene2canonicalisoform not supported on this genome";
25
+ if (!genome) throw "unknown genome";
26
+ if (!genome.genedb.get_gene2canonicalisoform) throw "gene2canonicalisoform not supported on this genome";
30
27
  const data = genome.genedb.get_gene2canonicalisoform.get(req.query.gene);
31
28
  res.send(data);
32
29
  } catch (e) {
33
30
  res.send({ error: e.message || e });
34
- if (e.stack)
35
- console.log(e.stack);
31
+ if (e.stack) console.log(e.stack);
36
32
  }
37
33
  };
38
34
  }
@@ -18,14 +18,12 @@ function init({ genomes }) {
18
18
  try {
19
19
  const q = req.query;
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 result = getResult(g, q);
24
23
  res.send(result);
25
24
  } catch (e) {
26
25
  res.send({ error: e.message || e });
27
- if (e.stack)
28
- console.log(e.stack);
26
+ if (e.stack) console.log(e.stack);
29
27
  }
30
28
  };
31
29
  }
@@ -26,13 +26,11 @@ function init({ genomes }) {
26
26
  const q = req.query;
27
27
  const results = await run_genesetEnrichment_analysis(q, genomes);
28
28
  if (!q.geneset_name) {
29
- if (typeof results != "object")
30
- throw "gsea result is not object";
29
+ if (typeof results != "object") throw "gsea result is not object";
31
30
  res.send(results);
32
31
  return;
33
32
  }
34
- if (typeof results != "string")
35
- throw "gsea result is not string";
33
+ if (typeof results != "string") throw "gsea result is not string";
36
34
  res.sendFile(results, (err) => {
37
35
  fs.unlink(results, () => {
38
36
  });
@@ -42,14 +40,12 @@ function init({ genomes }) {
42
40
  });
43
41
  } catch (e) {
44
42
  res.send({ status: "error", error: e.message || e });
45
- if (e.stack)
46
- console.log(e.stack);
43
+ if (e.stack) console.log(e.stack);
47
44
  }
48
45
  };
49
46
  }
50
47
  async function run_genesetEnrichment_analysis(q, genomes) {
51
- if (!genomes[q.genome].termdbs)
52
- throw "termdb database is not available for " + q.genome;
48
+ if (!genomes[q.genome].termdbs) throw "termdb database is not available for " + q.genome;
53
49
  const genesetenrichment_input = {
54
50
  genes: q.genes,
55
51
  fold_change: q.fold_change,
@@ -82,11 +78,9 @@ async function run_genesetEnrichment_analysis(q, genomes) {
82
78
  mayLog(line);
83
79
  }
84
80
  }
85
- if (data_found)
86
- return result;
81
+ if (data_found) return result;
87
82
  const image_file_name = path.join(cachedir_gsea, result.image_file);
88
- if (image_found)
89
- return image_file_name;
83
+ if (image_found) return image_file_name;
90
84
  throw "data or image not found in gsea output; this should not happen";
91
85
  } else if (q.method == "cerno") {
92
86
  const time1 = (/* @__PURE__ */ new Date()).valueOf();
@@ -26,8 +26,7 @@ function init({ genomes }) {
26
26
  };
27
27
  }
28
28
  async function run_genesetOverrepresentation_analysis(q, genomes) {
29
- if (!genomes[q.genome].termdbs)
30
- throw "termdb database is not available for " + q.genome;
29
+ if (!genomes[q.genome].termdbs) throw "termdb database is not available for " + q.genome;
31
30
  const gene_overrepresentation_input_type = {
32
31
  sample_genes: q.sample_genes,
33
32
  msigdb: genomes[q.genome].termdbs.msigdb.cohort.db.connection.name,