@sjcrh/proteinpaint-server 2.98.2-1 → 2.99.1-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.98.2-1",
3
+ "version": "2.99.1-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",
@@ -59,9 +59,9 @@
59
59
  },
60
60
  "dependencies": {
61
61
  "@sjcrh/augen": "2.87.0",
62
- "@sjcrh/proteinpaint-rust": "2.84.0",
63
- "@sjcrh/proteinpaint-shared": "2.98.0",
64
- "@sjcrh/proteinpaint-types": "2.98.2-1",
62
+ "@sjcrh/proteinpaint-rust": "2.99.0",
63
+ "@sjcrh/proteinpaint-shared": "2.99.0",
64
+ "@sjcrh/proteinpaint-types": "2.99.1-0",
65
65
  "better-sqlite3": "^9.4.1",
66
66
  "body-parser": "^1.15.2",
67
67
  "canvas": "~2.11.2",
@@ -70,16 +70,10 @@ async function compute(q, ds, genome) {
70
70
  terms: [...vtid2array.values()]
71
71
  };
72
72
  const time1 = Date.now();
73
- const r_output = await run_R(path.join(serverconfig.binpath, "utils", "corr.R"), JSON.stringify(input));
73
+ const output = {
74
+ terms: JSON.parse(await run_R(path.join(serverconfig.binpath, "utils", "corr.R"), JSON.stringify(input)))
75
+ };
74
76
  mayLog("Time taken to run correlation analysis:", Date.now() - time1);
75
- let json_result;
76
- for (const line of r_output.split("\n")) {
77
- if (line.startsWith("adjusted_p_values:")) {
78
- json_result = JSON.parse(line.replace("adjusted_p_values:", ""));
79
- } else {
80
- }
81
- }
82
- const output = { terms: json_result };
83
77
  const result = { variableItems: [] };
84
78
  for (const t of output.terms) {
85
79
  const t2 = {
package/routes/img.js ADDED
@@ -0,0 +1,46 @@
1
+ import { imgPayload } from "#types/checkers";
2
+ import path from "path";
3
+ import fs from "fs";
4
+ import * as utils from "../src/utils.js";
5
+ import imagesize from "image-size";
6
+ const api = {
7
+ endpoint: "img",
8
+ methods: {
9
+ get: {
10
+ ...imgPayload,
11
+ init
12
+ },
13
+ post: {
14
+ ...imgPayload,
15
+ init
16
+ }
17
+ }
18
+ };
19
+ function init() {
20
+ return async (req, res) => {
21
+ try {
22
+ sendImage(req, res);
23
+ } catch (e) {
24
+ res.send({ status: "error", error: e.message || e });
25
+ }
26
+ };
27
+ }
28
+ async function sendImage(req, res) {
29
+ const [e, file] = utils.fileurl(req, true);
30
+ try {
31
+ if (e)
32
+ throw "invalid image file";
33
+ const data = await fs.promises.readFile(file);
34
+ const ext = path.extname(file).substring(1);
35
+ const image = {
36
+ src: `data:image/${ext};base64,${Buffer.from(data).toString("base64")}`,
37
+ size: imagesize(file)
38
+ };
39
+ res.send({ ...image });
40
+ } catch (e2) {
41
+ res.send({ error: e2.message || e2 });
42
+ }
43
+ }
44
+ export {
45
+ api
46
+ };
@@ -4,6 +4,7 @@ import { run_rust } from "@sjcrh/proteinpaint-rust";
4
4
  import { getData } from "../src/termdb.matrix.js";
5
5
  import { get_ds_tdb } from "../src/termdb.js";
6
6
  import run_R from "../src/run_R.js";
7
+ import { mayLog } from "#src/helpers.ts";
7
8
  import serverconfig from "../src/serverconfig.js";
8
9
  const api = {
9
10
  endpoint: "DEanalysis",
@@ -120,27 +121,15 @@ async function run_DE(param, ds, term_results) {
120
121
  let result;
121
122
  if (group1names.length <= sample_size_limit && group2names.length <= sample_size_limit || param.method == "edgeR") {
122
123
  const time1 = (/* @__PURE__ */ new Date()).valueOf();
123
- const r_output = await run_R(path.join(serverconfig.binpath, "utils", "edge.R"), JSON.stringify(expression_input));
124
- const time2 = (/* @__PURE__ */ new Date()).valueOf();
125
- console.log("Time taken to run edgeR:", time2 - time1, "ms");
126
- for (const line of r_output.split("\n")) {
127
- if (line.startsWith("adjusted_p_values:")) {
128
- result = JSON.parse(line.replace("adjusted_p_values:", ""));
129
- } else {
130
- }
131
- }
124
+ result = JSON.parse(
125
+ await run_R(path.join(serverconfig.binpath, "utils", "edge.R"), JSON.stringify(expression_input))
126
+ );
127
+ mayLog("Time taken to run edgeR:", Date.now() - time1, "ms");
132
128
  param.method = "edgeR";
133
129
  } else {
134
130
  const time1 = (/* @__PURE__ */ new Date()).valueOf();
135
- const rust_output = await run_rust("DEanalysis", JSON.stringify(expression_input));
136
- const time2 = (/* @__PURE__ */ new Date()).valueOf();
137
- for (const line of rust_output.split("\n")) {
138
- if (line.startsWith("adjusted_p_values:")) {
139
- result = JSON.parse(line.replace("adjusted_p_values:", ""));
140
- } else {
141
- }
142
- }
143
- console.log("Time taken to run rust DE pipeline:", time2 - time1, "ms");
131
+ result = JSON.parse(await run_rust("DEanalysis", JSON.stringify(expression_input)));
132
+ mayLog("Time taken to run rust DE pipeline:", Date.now() - time1, "ms");
144
133
  param.method = "wilcoxon";
145
134
  }
146
135
  return { data: result, sample_size1, sample_size2, method: param.method };
@@ -219,6 +219,7 @@ function addNonDictionaryQueries(c, ds, genome) {
219
219
  sampleColumns: q.singleCell.samples.sampleColumns,
220
220
  experimentColumns: q.singleCell.samples.experimentColumns
221
221
  },
222
+ images: q.singleCell.images,
222
223
  data: {
223
224
  sameLegend: q.singleCell.data.sameLegend,
224
225
  refName: q.singleCell.data.refName,
@@ -1,7 +1,6 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import { read_file } from "#src/utils.js";
4
- import run_R from "#src/run_R.js";
3
+ import { read_file, file_is_readable } from "#src/utils.js";
5
4
  import { joinUrl, mayLog } from "#src/helpers.ts";
6
5
  import { run_rust } from "@sjcrh/proteinpaint-rust";
7
6
  import serverconfig from "#src/serverconfig.js";
@@ -77,6 +76,17 @@ async function validate_query_singleCell(ds, genome) {
77
76
  if (q.DEgenes) {
78
77
  validate_query_singleCell_DEgenes(ds);
79
78
  }
79
+ if (q.images) {
80
+ validateImages(q.images);
81
+ }
82
+ }
83
+ function validateImages(images) {
84
+ if (!images.folder)
85
+ throw "images.folder missing";
86
+ if (!images.label)
87
+ images.label = "Images";
88
+ if (!images.fileName)
89
+ throw "images.fileName missing";
80
90
  }
81
91
  async function validateSamplesNative(S, D, ds) {
82
92
  const samples = /* @__PURE__ */ new Map();
@@ -138,16 +148,7 @@ function validateDataNative(D, ds) {
138
148
  (q.sample.eID || q.sample.sID) + plot.fileSuffix
139
149
  );
140
150
  if (!file2Lines[tsvfile]) {
141
- try {
142
- await fs.promises.stat(tsvfile);
143
- } catch (e) {
144
- if (e.code == "ENOENT") {
145
- continue;
146
- }
147
- if (e.code == "EACCES")
148
- throw "cannot read file, permission denied";
149
- throw "failed to load sc data file";
150
- }
151
+ await file_is_readable(tsvfile);
151
152
  file2Lines[tsvfile] = (await read_file(tsvfile)).trim().split("\n");
152
153
  }
153
154
  const colorColumn = plot.colorColumns.find((c) => c.name == q.colorBy?.[plot.name]) || plot.colorColumns[0];
@@ -195,52 +196,28 @@ function validateDataNative(D, ds) {
195
196
  }
196
197
  function validateGeneExpressionNative(G) {
197
198
  G.sample2gene2expressionBins = {};
198
- if (G.storage_type == "RDS" || !G.storage_type) {
199
- G.get = async (q) => {
200
- const rdsfile = path.join(serverconfig.tpmasterdir, G.folder, (q.sample.eID || q.sample.sID) + ".rds");
201
- try {
202
- await fs.promises.stat(rdsfile);
203
- } catch (_) {
204
- return {};
205
- }
206
- let out;
207
- try {
208
- out = JSON.parse(
209
- await run_R(path.join(serverconfig.binpath, "utils", "getGeneFromMatrix.R"), null, [rdsfile, q.gene])
210
- );
211
- } catch (_) {
212
- return {};
213
- }
214
- return out;
215
- };
216
- } else if (G.storage_type == "HDF5") {
217
- G.get = async (q) => {
218
- const rdsfile = path.join(serverconfig.tpmasterdir, G.folder, (q.sample.eID || q.sample.sID) + ".h5");
219
- try {
220
- await fs.promises.stat(rdsfile);
221
- } catch (_) {
222
- return {};
223
- }
224
- const read_hdf5_input_type = { gene: q.gene, hdf5_file: rdsfile };
225
- let out;
226
- try {
227
- const time1 = (/* @__PURE__ */ new Date()).valueOf();
228
- const rust_output = await run_rust("readHDF5", JSON.stringify(read_hdf5_input_type));
229
- const time2 = (/* @__PURE__ */ new Date()).valueOf();
230
- console.log("Time taken to query HDF5 file:", time2 - time1, "ms");
231
- for (const line of rust_output.split("\n")) {
232
- if (line.startsWith("output_string:")) {
233
- out = JSON.parse(line.replace("output_string:", ""));
234
- } else {
235
- console.log(line);
236
- }
199
+ G.get = async (q) => {
200
+ const h5file = path.join(serverconfig.tpmasterdir, G.folder, (q.sample.eID || q.sample.sID) + ".h5");
201
+ await file_is_readable(h5file);
202
+ const read_hdf5_input_type = { gene: q.gene, hdf5_file: h5file };
203
+ let out;
204
+ try {
205
+ const time1 = Date.now();
206
+ const rust_output = await run_rust("readHDF5", JSON.stringify(read_hdf5_input_type));
207
+ mayLog("Time taken to query HDF5 file:", Date.now() - time1, "ms");
208
+ for (const line of rust_output.split("\n")) {
209
+ if (line.startsWith("output_string:")) {
210
+ out = JSON.parse(line.replace("output_string:", ""));
211
+ } else {
212
+ console.log(line);
237
213
  }
238
- } catch (_) {
239
- return {};
240
214
  }
241
- return out;
242
- };
243
- }
215
+ } catch (e) {
216
+ console.log(e);
217
+ throw "error reading h5 file: " + e;
218
+ }
219
+ return out;
220
+ };
244
221
  }
245
222
  function gdc_validateGeneExpression(G, ds, genome) {
246
223
  G.sample2gene2expressionBins = {};