@sjcrh/proteinpaint-server 2.44.0 → 2.46.1

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 (82) hide show
  1. package/dataset/clinvar.hg19.js +53 -52
  2. package/dataset/clinvar.hg38.js +74 -73
  3. package/dataset/clinvar.js +164 -47
  4. package/dataset/termdb.test.js +257 -0
  5. package/genome/CriGri.js +1859 -27
  6. package/genome/cgc.js +743 -7
  7. package/genome/danRer10.js +1108 -46
  8. package/genome/dm3.js +71 -44
  9. package/genome/dm6.js +1926 -45
  10. package/genome/galGal5.js +23522 -46
  11. package/genome/galGal6.js +512 -46
  12. package/genome/hg19.js +293 -198
  13. package/genome/hg38.js +472 -105
  14. package/genome/hg38.test.js +406 -40
  15. package/genome/hgvirus.js +45 -20
  16. package/genome/mm10.js +135 -67
  17. package/genome/mm9.js +116 -79
  18. package/genome/rn6.js +1002 -47
  19. package/package.json +31 -35
  20. package/routes/_template_.js +30 -0
  21. package/routes/burden.js +149 -0
  22. package/routes/dataset.js +266 -0
  23. package/routes/dsdata.js +127 -0
  24. package/routes/gdc.maf.js +120 -0
  25. package/routes/gdc.mafBuild.js +106 -0
  26. package/routes/gdc.topMutatedGenes.js +465 -0
  27. package/routes/gene2canonicalisoform.js +41 -0
  28. package/routes/genelookup.js +52 -0
  29. package/routes/genomes.js +144 -0
  30. package/routes/healthcheck.js +30 -0
  31. package/routes/hicdata.js +98 -0
  32. package/routes/hicstat.js +55 -0
  33. package/routes/isoformlst.js +57 -0
  34. package/routes/ntseq.js +43 -0
  35. package/routes/pdomain.js +61 -0
  36. package/routes/snp.js +107 -0
  37. package/routes/termdb.categories.js +209 -0
  38. package/routes/termdb.cluster.js +228 -0
  39. package/routes/termdb.cohort.summary.js +38 -0
  40. package/routes/termdb.cohorts.js +49 -0
  41. package/routes/termdb.config.js +202 -0
  42. package/routes/termdb.getdescrstats.js +102 -0
  43. package/routes/termdb.getnumericcategories.js +92 -0
  44. package/routes/termdb.getpercentile.js +108 -0
  45. package/routes/termdb.getrootterm.js +65 -0
  46. package/routes/termdb.gettermchildren.js +67 -0
  47. package/routes/termdb.singleSampleMutation.js +80 -0
  48. package/routes/termdb.singlecellData.js +46 -0
  49. package/routes/termdb.singlecellSamples.js +160 -0
  50. package/routes/termdb.termsbyids.js +59 -0
  51. package/routes/termdb.topVariablyExpressedGenes.js +171 -0
  52. package/routes/termdb.violin.js +77 -0
  53. package/src/app.js +41500 -0
  54. package/src/serverconfig.js +14 -8
  55. package/start.js +3 -3
  56. package/routes/README.md +0 -84
  57. package/routes/burden.ts +0 -143
  58. package/routes/gdc.maf.ts +0 -195
  59. package/routes/gdc.mafBuild.ts +0 -114
  60. package/routes/gdc.topMutatedGenes.ts +0 -586
  61. package/routes/genelookup.ts +0 -50
  62. package/routes/healthcheck.ts +0 -29
  63. package/routes/hicdata.ts +0 -111
  64. package/routes/hicstat.ts +0 -55
  65. package/routes/termdb.categories.ts +0 -245
  66. package/routes/termdb.cluster.ts +0 -248
  67. package/routes/termdb.getdescrstats.ts +0 -102
  68. package/routes/termdb.getnumericcategories.ts +0 -99
  69. package/routes/termdb.getpercentile.ts +0 -118
  70. package/routes/termdb.getrootterm.ts +0 -73
  71. package/routes/termdb.gettermchildren.ts +0 -82
  72. package/routes/termdb.singleSampleMutation.ts +0 -87
  73. package/routes/termdb.singlecellData.ts +0 -49
  74. package/routes/termdb.singlecellSamples.ts +0 -175
  75. package/routes/termdb.termsbyids.ts +0 -63
  76. package/routes/termdb.topVariablyExpressedGenes.ts +0 -214
  77. package/routes/termdb.violin.ts +0 -77
  78. package/server.js +0 -2
  79. package/server.js.map +0 -1
  80. package/shared/common.js +0 -1080
  81. package/shared/termdb.initbinconfig.js +0 -96
  82. package/shared/vcf.js +0 -629
@@ -0,0 +1,80 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { read_file } from "#src/utils.js";
4
+ import serverconfig from "#src/serverconfig.js";
5
+ import { gdcValidate_query_singleSampleMutation } from "#src/mds3.gdc.js";
6
+ const api = {
7
+ endpoint: "termdb/singleSampleMutation",
8
+ methods: {
9
+ get: {
10
+ init,
11
+ request: {
12
+ typeId: "TermdbSingleSampleMutationRequest"
13
+ },
14
+ response: {
15
+ typeId: "TermdbSingleSampleMutationResponse"
16
+ }
17
+ }
18
+ }
19
+ };
20
+ function init({ genomes }) {
21
+ return async (req, res) => {
22
+ const q = req.query;
23
+ let result;
24
+ try {
25
+ const g = genomes[q.genome];
26
+ if (!g)
27
+ throw "invalid genome name";
28
+ const ds = g.datasets[q.dslabel];
29
+ if (!ds)
30
+ throw "invalid dataset name";
31
+ if (!ds.queries?.singleSampleMutation)
32
+ throw "not supported on this dataset";
33
+ result = await ds.queries.singleSampleMutation.get(q);
34
+ } catch (e) {
35
+ if (e.stack)
36
+ console.log(e.stack);
37
+ result = {
38
+ status: e.status || 400,
39
+ error: e.message || e
40
+ };
41
+ }
42
+ res.send(result);
43
+ };
44
+ }
45
+ async function validate_query_singleSampleMutation(ds, genome) {
46
+ const _q = ds.queries.singleSampleMutation;
47
+ if (!_q)
48
+ return;
49
+ if (_q.src == "gdcapi") {
50
+ gdcValidate_query_singleSampleMutation(ds, genome);
51
+ } else if (_q.src == "native") {
52
+ _q.get = async (q) => {
53
+ let fileName = q.sample;
54
+ if (ds.cohort?.termdb?.q?.sampleName2id) {
55
+ fileName = ds.cohort.termdb.q.sampleName2id(q.sample);
56
+ if (fileName == void 0) {
57
+ return [];
58
+ }
59
+ }
60
+ const file = path.join(serverconfig.tpmasterdir, _q.folder, fileName.toString());
61
+ try {
62
+ await fs.promises.stat(file);
63
+ } catch (e) {
64
+ if (e.code == "EACCES")
65
+ throw "cannot read file, permission denied";
66
+ if (e.code == "ENOENT")
67
+ throw "no data for this sample";
68
+ throw "failed to load data";
69
+ }
70
+ const data = await read_file(file);
71
+ return { mlst: JSON.parse(data) };
72
+ };
73
+ } else {
74
+ throw "unknown singleSampleMutation.src";
75
+ }
76
+ }
77
+ export {
78
+ api,
79
+ validate_query_singleSampleMutation
80
+ };
@@ -0,0 +1,46 @@
1
+ const api = {
2
+ endpoint: "termdb/singlecellData",
3
+ methods: {
4
+ get: {
5
+ init,
6
+ request: {
7
+ typeId: "TermdbSinglecellDataRequest"
8
+ },
9
+ response: {
10
+ typeId: "TermdbSinglecellDataResponse"
11
+ }
12
+ },
13
+ post: {
14
+ alternativeFor: "get",
15
+ init
16
+ }
17
+ }
18
+ };
19
+ function init({ genomes }) {
20
+ return async (req, res) => {
21
+ const q = req.query;
22
+ let result;
23
+ try {
24
+ const g = genomes[q.genome];
25
+ if (!g)
26
+ throw "invalid genome name";
27
+ const ds = g.datasets[q.dslabel];
28
+ if (!ds)
29
+ throw "invalid dataset name";
30
+ if (!ds.queries?.singleCell)
31
+ throw "no singlecell data on this dataset";
32
+ result = await ds.queries.singleCell.data.get(q);
33
+ } catch (e) {
34
+ if (e.stack)
35
+ console.log(e);
36
+ result = {
37
+ status: e.status || 400,
38
+ error: e.message || e
39
+ };
40
+ }
41
+ res.send(result);
42
+ };
43
+ }
44
+ export {
45
+ api
46
+ };
@@ -0,0 +1,160 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { read_file } from "#src/utils.js";
4
+ import serverconfig from "#src/serverconfig.js";
5
+ import { gdc_validate_query_singleCell_samples, gdc_validate_query_singleCell_data } from "#src/mds3.gdc.js";
6
+ const api = {
7
+ endpoint: "termdb/singlecellSamples",
8
+ methods: {
9
+ get: {
10
+ init,
11
+ request: {
12
+ typeId: "TermdbSinglecellsamplesRequest"
13
+ },
14
+ response: {
15
+ typeId: "TermdbSinglecellsamplesResponse"
16
+ }
17
+ },
18
+ post: {
19
+ alternativeFor: "get",
20
+ init
21
+ }
22
+ }
23
+ };
24
+ function init({ genomes }) {
25
+ return async (req, res) => {
26
+ const q = req.query;
27
+ let result;
28
+ try {
29
+ const g = genomes[q.genome];
30
+ if (!g)
31
+ throw "invalid genome name";
32
+ const ds = g.datasets[q.dslabel];
33
+ if (!ds)
34
+ throw "invalid dataset name";
35
+ if (!ds.queries?.singleCell)
36
+ throw "no singlecell data on this dataset";
37
+ result = await ds.queries.singleCell.samples.get(q);
38
+ } catch (e) {
39
+ if (e.stack)
40
+ console.log(e.stack);
41
+ result = {
42
+ status: e.status || 400,
43
+ error: e.message || e
44
+ };
45
+ }
46
+ res.send(result);
47
+ };
48
+ }
49
+ async function validate_query_singleCell(ds, genome) {
50
+ const q = ds.queries.singleCell;
51
+ if (!q)
52
+ return;
53
+ if (q.samples.src == "gdcapi") {
54
+ gdc_validate_query_singleCell_samples(ds, genome);
55
+ } else if (q.samples.src == "native") {
56
+ getSamplesNative(q.samples, ds);
57
+ } else {
58
+ throw "unknown singleCell.samples.src";
59
+ }
60
+ if (q.data.src == "gdcapi") {
61
+ gdc_validate_query_singleCell_data(ds, genome);
62
+ } else if (q.data.src == "native") {
63
+ getDataNative(q.data, ds);
64
+ } else {
65
+ throw "unknown singleCell.data.src";
66
+ }
67
+ }
68
+ async function getSamplesNative(S, ds) {
69
+ const isSamples = ds.cohort.termdb.q.getAllValues4term(S.isSampleTerm);
70
+ if (isSamples.size == 0)
71
+ throw "no samples found that are identified by isSampleTerm";
72
+ const samples = [];
73
+ for (const sampleid of isSamples.keys()) {
74
+ if (isSamples.get(sampleid) == "1")
75
+ samples.push({
76
+ sample: ds.cohort.termdb.q.id2sampleName(sampleid),
77
+ // string name for display
78
+ sampleid
79
+ // temporarily kept to assign term value to each sample
80
+ });
81
+ }
82
+ if (S.sampleColumns) {
83
+ for (const term of S.sampleColumns) {
84
+ const s2v = ds.cohort.termdb.q.getAllValues4term(term.termid);
85
+ for (const s of samples) {
86
+ if (s2v.has(s.sampleid))
87
+ s[term.termid] = s2v.get(s.sampleid);
88
+ }
89
+ }
90
+ }
91
+ for (const s of samples)
92
+ delete s.sampleid;
93
+ S.get = () => {
94
+ return { samples };
95
+ };
96
+ }
97
+ function getDataNative(D, ds) {
98
+ const nameSet = /* @__PURE__ */ new Set();
99
+ for (const plot of D.plots) {
100
+ if (nameSet.has(plot.name))
101
+ throw "duplicate plot.name";
102
+ nameSet.add(plot.name);
103
+ }
104
+ const _terms = [];
105
+ for (const tid of D.termIds) {
106
+ const t = ds.cohort.termdb.q.termjsonByOneid(tid);
107
+ if (!t)
108
+ throw "invalid term id from queries.singleCell.data.termIds[]";
109
+ _terms.push(t);
110
+ }
111
+ D.get = async (q) => {
112
+ try {
113
+ const tid2cellvalue = {};
114
+ for (const tid of D.termIds)
115
+ tid2cellvalue[tid] = {};
116
+ const plots = [];
117
+ for (const plot of D.plots) {
118
+ const tsvfile = path.join(serverconfig.tpmasterdir, plot.folder, q.sample + plot.fileSuffix);
119
+ try {
120
+ await fs.promises.stat(tsvfile);
121
+ } catch (e) {
122
+ if (e.code == "ENOENT") {
123
+ continue;
124
+ }
125
+ if (e.code == "EACCES")
126
+ throw "cannot read file, permission denied";
127
+ throw "failed to load sc data file";
128
+ }
129
+ const lines = (await read_file(tsvfile)).trim().split("\n");
130
+ const cells = [];
131
+ for (let i = 1; i < lines.length; i++) {
132
+ const l = lines[i].split(" ");
133
+ const cellId = l[0], x = Number(l[plot.coordsColumns.x]), y = Number(l[plot.coordsColumns.y]);
134
+ const category = l[plot.colorColumn?.index] || "";
135
+ if (!cellId)
136
+ throw "cell id missing";
137
+ if (!Number.isFinite(x) || !Number.isFinite(y))
138
+ throw "x/y not number";
139
+ cells.push({ cellId, x, y, category });
140
+ for (const tid of D.termIds) {
141
+ tid2cellvalue[tid][cellId] = l[1];
142
+ }
143
+ }
144
+ plots.push({ name: plot.name, cells, colorBy: plot.colorColumn?.name, colorMap: plot.colorColumn?.colorMap });
145
+ }
146
+ if (plots.length == 0) {
147
+ return { nodata: true };
148
+ }
149
+ return { plots, terms: _terms, tid2cellvalue };
150
+ } catch (e) {
151
+ if (e.stack)
152
+ console.log(e.stack);
153
+ return { error: e.message || e };
154
+ }
155
+ };
156
+ }
157
+ export {
158
+ api,
159
+ validate_query_singleCell
160
+ };
@@ -0,0 +1,59 @@
1
+ import { copy_term } from "#src/termdb.js";
2
+ const api = {
3
+ endpoint: "termdb/termsbyids",
4
+ methods: {
5
+ get: {
6
+ init,
7
+ request: {
8
+ typeId: "gettermsbyidsRequest"
9
+ },
10
+ response: {
11
+ typeId: "gettermsbyidsResponse"
12
+ }
13
+ },
14
+ post: {
15
+ alternativeFor: "get",
16
+ init
17
+ }
18
+ }
19
+ };
20
+ function init({ genomes }) {
21
+ return async (req, res) => {
22
+ const q = req.query;
23
+ try {
24
+ const g = genomes[req.query.genome];
25
+ if (!g)
26
+ throw "invalid genome name";
27
+ const ds = g.datasets[req.query.dslabel];
28
+ if (!ds)
29
+ throw "invalid dataset name";
30
+ const tdb = ds.cohort.termdb;
31
+ if (!tdb)
32
+ throw "invalid termdb object";
33
+ await trigger_gettermsbyid(q, res, tdb);
34
+ } catch (e) {
35
+ res.send({ error: e?.message || e });
36
+ if (e instanceof Error && e.stack)
37
+ console.log(e);
38
+ }
39
+ };
40
+ }
41
+ async function trigger_gettermsbyid(q, res, tdb) {
42
+ const terms = {};
43
+ for (const id of q.ids) {
44
+ const term = tdb.q.termjsonByOneid(id);
45
+ if (term) {
46
+ if (term.type == "categorical" && !term.values && !term.groupsetting?.inuse) {
47
+ term.values = {};
48
+ term.samplecount = {};
49
+ }
50
+ }
51
+ terms[id] = term ? copy_term(term) : void 0;
52
+ }
53
+ res.send({
54
+ terms
55
+ });
56
+ }
57
+ export {
58
+ api
59
+ };
@@ -0,0 +1,171 @@
1
+ import { gdcGetCasesWithExressionDataFromCohort } from "../src/mds3.gdc.js";
2
+ import path from "path";
3
+ import { run_rust } from "@sjcrh/proteinpaint-rust";
4
+ import got from "got";
5
+ import serverconfig from "#src/serverconfig.js";
6
+ import { get_samples } from "#src/termdb.sql.js";
7
+ const api = {
8
+ endpoint: "termdb/topVariablyExpressedGenes",
9
+ methods: {
10
+ all: {
11
+ init,
12
+ request: {
13
+ typeId: "TermdbTopVariablyExpressedGenesRequest"
14
+ },
15
+ response: {
16
+ typeId: "TermdbTopVariablyExpressedGenesResponse"
17
+ }
18
+ }
19
+ }
20
+ };
21
+ function init({ genomes }) {
22
+ return async (req, res) => {
23
+ try {
24
+ const q = req.query;
25
+ const genome = genomes[q.genome];
26
+ if (!genome)
27
+ throw "invalid genome";
28
+ const ds = genome.datasets?.[q.dslabel];
29
+ if (!ds)
30
+ throw "invalid dslabel";
31
+ if (!ds.queries?.topVariablyExpressedGenes)
32
+ throw "not supported on dataset";
33
+ const t = Date.now();
34
+ const genes = await ds.queries.topVariablyExpressedGenes.getGenes(q);
35
+ if (serverconfig.debugmode)
36
+ console.log("topVariablyExpressedGenes", Date.now() - t, "ms");
37
+ res.send({ genes });
38
+ } catch (e) {
39
+ res.send({ status: "error", error: e.message || e });
40
+ }
41
+ };
42
+ }
43
+ function validate_query_TopVariablyExpressedGenes(ds, genome) {
44
+ const q = ds.queries.topVariablyExpressedGenes;
45
+ if (!q)
46
+ return;
47
+ if (q.src == "gdcapi") {
48
+ gdcValidateQuery(ds, genome);
49
+ } else if (q.src == "native") {
50
+ nativeValidateQuery(ds, genome);
51
+ } else {
52
+ throw "unknown topVariablyExpressedGenes.src";
53
+ }
54
+ }
55
+ function nativeValidateQuery(ds, genome) {
56
+ const gE = ds.queries.geneExpression;
57
+ if (!gE)
58
+ throw "topVariablyExpressedGenes query given but geneExpression missing";
59
+ if (gE.src != "native")
60
+ throw "topVariablyExpressedGenes is native but geneExpression.src is not native";
61
+ ds.queries.topVariablyExpressedGenes.getGenes = async (q) => {
62
+ const samples = [];
63
+ if (q.filter) {
64
+ const sidlst = await get_samples(q.filter, ds);
65
+ for (const i of sidlst) {
66
+ if (gE.samples.includes(i.id)) {
67
+ const n = ds.cohort.termdb.q.id2sampleName(i.id);
68
+ if (!n)
69
+ throw "sample id cannot convert to string name";
70
+ samples.push(n);
71
+ }
72
+ }
73
+ } else {
74
+ for (const i of gE.samples) {
75
+ const n = ds.cohort.termdb.q.id2sampleName(i.id);
76
+ if (!n)
77
+ throw "sample id cannot convert to string name";
78
+ samples.push(n);
79
+ }
80
+ }
81
+ const genes = await computeGenes4nativeDs(q, ds, gE.file, samples);
82
+ return genes;
83
+ };
84
+ }
85
+ async function computeGenes4nativeDs(q, ds, matrixFile, samples) {
86
+ const input_json = {
87
+ input_file: matrixFile,
88
+ samples: samples.join(","),
89
+ filter_extreme_values: true,
90
+ num_genes: Number(q.maxGenes),
91
+ param: "var"
92
+ };
93
+ const rust_output = await run_rust("topGeneByExpressionVariance", JSON.stringify(input_json));
94
+ const rust_output_list = rust_output.split("\n");
95
+ let output_json;
96
+ for (const item of rust_output_list) {
97
+ if (item.includes("output_json:")) {
98
+ output_json = JSON.parse(item.replace("output_json:", ""));
99
+ } else {
100
+ console.log(item);
101
+ }
102
+ }
103
+ const varGenes = output_json.map((i) => i.gene_symbol);
104
+ return varGenes;
105
+ }
106
+ function gdcValidateQuery(ds, genome) {
107
+ ds.queries.topVariablyExpressedGenes.getGenes = async (q) => {
108
+ if (serverconfig.features.gdcGenes) {
109
+ console.log("!!GDC!! using serverconfig.features.gdcGenes[]");
110
+ return serverconfig.features.gdcGenes;
111
+ }
112
+ if (!ds.__gdc.doneCaching)
113
+ throw "The server has not finished caching the case IDs: try again in ~2 minutes";
114
+ const caseLst = await gdcGetCasesWithExressionDataFromCohort(q, ds);
115
+ if (caseLst.length == 0) {
116
+ return [];
117
+ }
118
+ const { host, headers } = ds.getHostHeaders(q);
119
+ const url = path.join(host.geneExp, "/gene_expression/gene_selection");
120
+ try {
121
+ const response = await got.post(url, {
122
+ headers,
123
+ body: JSON.stringify(getGeneSelectionArg(q, caseLst))
124
+ });
125
+ const re = JSON.parse(response.body);
126
+ const genes = [];
127
+ if (!Array.isArray(re.gene_selection))
128
+ throw "re.gene_selection[] is not array";
129
+ for (const i of re.gene_selection) {
130
+ if (i.gene_id && typeof i.gene_id == "string") {
131
+ const t = genome.genedb.getNameByAlias.get(i.gene_id);
132
+ if (t)
133
+ genes.push(t.name);
134
+ } else if (i.symbol && typeof i.symbol == "string") {
135
+ genes.push(i.symbol);
136
+ } else {
137
+ throw "one of re.gene_selection[] is missing both gene_id and symbol";
138
+ }
139
+ }
140
+ return genes;
141
+ } catch (e) {
142
+ console.log(e.stack || e);
143
+ throw e;
144
+ }
145
+ };
146
+ function getGeneSelectionArg(q, caseLst) {
147
+ return {
148
+ case_ids: caseLst,
149
+ //.slice(0, 20),
150
+ gene_ids: tempGetCGCgenes(genome),
151
+ selection_size: Number(q.maxGenes)
152
+ };
153
+ }
154
+ }
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);
163
+ }
164
+ }
165
+ }
166
+ return lst;
167
+ }
168
+ export {
169
+ api,
170
+ validate_query_TopVariablyExpressedGenes
171
+ };
@@ -0,0 +1,77 @@
1
+ import { trigger_getViolinPlotData } from "#src/termdb.violin.js";
2
+ const api = {
3
+ endpoint: "termdb/violin",
4
+ methods: {
5
+ get: {
6
+ init,
7
+ request: {
8
+ typeId: "getViolinRequest"
9
+ },
10
+ response: {
11
+ typeId: "getViolinResponse"
12
+ },
13
+ examples: [
14
+ {
15
+ request: {
16
+ body: {
17
+ genome: "hg38-test",
18
+ dslabel: "TermdbTest",
19
+ embedder: "localhost",
20
+ devicePixelRatio: 2.200000047683716,
21
+ maxThickness: 150,
22
+ screenThickness: 1218,
23
+ filter: {
24
+ type: "tvslst",
25
+ in: true,
26
+ join: "",
27
+ lst: [
28
+ {
29
+ tag: "cohortFilter",
30
+ type: "tvs",
31
+ tvs: { term: { id: "subcohort", type: "categorical" }, values: [{ key: "ABC", label: "ABC" }] }
32
+ }
33
+ ]
34
+ },
35
+ svgw: 227.27272234672367,
36
+ orientation: "horizontal",
37
+ datasymbol: "bean",
38
+ radius: 5,
39
+ strokeWidth: 0.2,
40
+ axisHeight: 60,
41
+ rightMargin: 50,
42
+ unit: "abs",
43
+ termid: "agedx"
44
+ }
45
+ },
46
+ response: {
47
+ header: { status: 200 }
48
+ }
49
+ }
50
+ ]
51
+ },
52
+ post: {
53
+ alternativeFor: "get",
54
+ init
55
+ }
56
+ }
57
+ };
58
+ function init({ genomes }) {
59
+ return async (req, res) => {
60
+ const q = req.query;
61
+ try {
62
+ const g = genomes[req.query.genome];
63
+ const ds = g.datasets[req.query.dslabel];
64
+ if (!g)
65
+ throw "invalid genome name";
66
+ const data = await trigger_getViolinPlotData(req.query, null, ds, g);
67
+ res.send(data);
68
+ } catch (e) {
69
+ res.send({ error: e?.message || e });
70
+ if (e instanceof Error && e.stack)
71
+ console.log(e);
72
+ }
73
+ };
74
+ }
75
+ export {
76
+ api
77
+ };