@sjcrh/proteinpaint-server 2.117.0 → 2.118.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.117.0",
3
+ "version": "2.118.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",
@@ -66,8 +66,9 @@
66
66
  },
67
67
  "dependencies": {
68
68
  "@sjcrh/augen": "2.116.0",
69
+ "@sjcrh/proteinpaint-python": "2.118.0",
69
70
  "@sjcrh/proteinpaint-rust": "2.117.0",
70
- "@sjcrh/proteinpaint-shared": "2.117.0",
71
+ "@sjcrh/proteinpaint-shared": "2.118.0",
71
72
  "@sjcrh/proteinpaint-types": "2.117.0",
72
73
  "@types/express": "^5.0.0",
73
74
  "@types/express-session": "^1.18.1",
@@ -1,10 +1,10 @@
1
1
  import path from "path";
2
2
  import serverconfig from "#src/serverconfig.js";
3
3
  import { brainImagingPayload } from "#types/checkers";
4
- import { spawn } from "child_process";
5
4
  import { getData } from "../src/termdb.matrix.js";
6
5
  import { isNumericTerm } from "@sjcrh/proteinpaint-shared/terms.js";
7
6
  import { getColors } from "#shared/common.js";
7
+ import { run_python } from "@sjcrh/proteinpaint-python";
8
8
  const api = {
9
9
  endpoint: "brainImaging",
10
10
  methods: {
@@ -124,7 +124,20 @@ async function getBrainImage(query, genomes, plane, index) {
124
124
  if (!legend[category])
125
125
  legend[category] = { color: filesByCat[category].color, maxLength };
126
126
  }
127
- const url = await generateBrainImage(refFile, plane, index, maxLength, JSON.stringify(filesByCat));
127
+ const arg = {
128
+ refFile,
129
+ plane,
130
+ index,
131
+ maxLength,
132
+ filesByCat: JSON.stringify(filesByCat)
133
+ };
134
+ let url;
135
+ try {
136
+ url = await run_python("plotBrainImaging.py", JSON.stringify(arg));
137
+ } catch (error) {
138
+ const errmsg = "Error running Python script:" + error;
139
+ throw new Error(errmsg);
140
+ }
128
141
  brainImageDict[dcategory] = { url, catNum };
129
142
  }
130
143
  if (query.legendFilter) {
@@ -141,30 +154,6 @@ async function getBrainImage(query, genomes, plane, index) {
141
154
  throw "no reference or sample files";
142
155
  }
143
156
  }
144
- async function generateBrainImage(refFile, plane, index, maxLength, filesJson) {
145
- return new Promise((resolve, reject) => {
146
- const cmd = [`${serverconfig.binpath}/utils/plotBrainImaging.py`, refFile, plane, index, maxLength, filesJson];
147
- const ps = spawn(serverconfig.python, cmd);
148
- const imgData = [];
149
- ps.stdout.on("data", (data) => {
150
- imgData.push(data);
151
- });
152
- ps.stderr.on("data", (data) => {
153
- console.error(`stderr: ${data}`);
154
- reject(new Error(`Python script filed: ${data}`));
155
- });
156
- ps.on("close", (code) => {
157
- if (code === 0) {
158
- const imageBuffer = Buffer.concat(imgData);
159
- const base64Data = imageBuffer.toString("base64");
160
- const imgUrl = `data:image/png;base64,${base64Data}`;
161
- resolve(imgUrl);
162
- } else {
163
- reject(new Error(`Python script exited with code ${code}`));
164
- }
165
- });
166
- });
167
- }
168
157
  export {
169
158
  api
170
159
  };
@@ -1,7 +1,6 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
3
  import serverconfig from "#src/serverconfig.js";
4
- import { spawn } from "child_process";
5
4
  const api = {
6
5
  endpoint: "brainImagingSamples",
7
6
  methods: {
@@ -62,59 +61,6 @@ async function getBrainImageSamples(query, genomes) {
62
61
  throw "no reference or sample files";
63
62
  }
64
63
  }
65
- async function validate_query_NIdata(ds) {
66
- const q = ds.queries.NIdata;
67
- if (!q || !serverconfig.features?.showBrainImaging)
68
- return;
69
- for (const key in q) {
70
- if (q[key].referenceFile && q[key].samples) {
71
- q[key].get = async (sampleName, l, f, t) => {
72
- const refFile = path.join(serverconfig.tpmasterdir, q[key].referenceFile);
73
- const sampleFile = path.join(serverconfig.tpmasterdir, q[key].samples, sampleName);
74
- try {
75
- await fs.promises.stat(sampleFile);
76
- } catch (e) {
77
- if (e.code == "EACCES")
78
- throw "cannot read file, permission denied";
79
- if (e.code == "ENOENT")
80
- throw "no data for this sample";
81
- throw "failed to load data";
82
- }
83
- return new Promise((resolve, reject) => {
84
- const ps = spawn(serverconfig.python, [
85
- `${serverconfig.binpath}/utils/plotBrainImaging.py`,
86
- refFile,
87
- sampleFile,
88
- l,
89
- f,
90
- t
91
- ]);
92
- const imgData = [];
93
- ps.stdout.on("data", (data) => {
94
- imgData.push(data);
95
- });
96
- ps.stderr.on("data", (data) => {
97
- console.error(`stderr: ${data}`);
98
- reject(new Error(`Python script filed: ${data}`));
99
- });
100
- ps.on("close", (code) => {
101
- if (code === 0) {
102
- const imageBuffer = Buffer.concat(imgData);
103
- const base64Data = imageBuffer.toString("base64");
104
- const imgUrl = `data:image/png;base64,${base64Data}`;
105
- resolve(imgUrl);
106
- } else {
107
- reject(new Error(`Python script exited with code ${code}`));
108
- }
109
- });
110
- });
111
- };
112
- } else {
113
- throw "no reference or sample files";
114
- }
115
- }
116
- }
117
64
  export {
118
- api,
119
- validate_query_NIdata
65
+ api
120
66
  };
@@ -1,9 +1,8 @@
1
1
  import { genesetEnrichmentPayload } from "#types/checkers";
2
2
  import fs from "fs";
3
3
  import path from "path";
4
- import { spawn } from "child_process";
5
- import { Readable } from "stream";
6
4
  import serverconfig from "#src/serverconfig.js";
5
+ import { run_python } from "@sjcrh/proteinpaint-python";
7
6
  const api = {
8
7
  endpoint: "genesetEnrichment",
9
8
  methods: {
@@ -60,11 +59,7 @@ async function run_genesetEnrichment_analysis(q, genomes) {
60
59
  genedb: path.join(serverconfig.tpmasterdir, genomes[q.genome].genedb.dbfile),
61
60
  filter_non_coding_genes: q.filter_non_coding_genes
62
61
  };
63
- const gsea_output = await run_gsea(
64
- `${serverconfig.binpath}/utils/gsea.py`,
65
- "/" + JSON.stringify(genesetenrichment_input)
66
- // "/" is needed for python to accept the bracket "{" as a bracket
67
- );
62
+ const gsea_output = await run_python("gsea.py", "/" + JSON.stringify(genesetenrichment_input));
68
63
  let result;
69
64
  let data_found = false;
70
65
  let image_found = false;
@@ -88,55 +83,6 @@ async function run_genesetEnrichment_analysis(q, genomes) {
88
83
  throw ``;
89
84
  }
90
85
  }
91
- async function run_gsea(path2, data) {
92
- try {
93
- await fs.promises.stat(path2);
94
- } catch (_) {
95
- throw `${path2} does not exist`;
96
- }
97
- return new Promise((resolve, reject) => {
98
- const _stdout = [];
99
- const _stderr = [];
100
- const sp = spawn(serverconfig.python, [path2]);
101
- if (data) {
102
- try {
103
- const input = data.endsWith("\n") ? data : data + "\n";
104
- Readable.from(input).pipe(sp.stdin);
105
- } catch (e) {
106
- sp.kill();
107
- let errmsg = e;
108
- const stderr = _stderr.join("").trim();
109
- if (stderr)
110
- errmsg += `
111
- python stderr: ${stderr}`;
112
- reject(errmsg);
113
- }
114
- }
115
- sp.stdout.on("data", (data2) => _stdout.push(data2));
116
- sp.stderr.on("data", (data2) => _stderr.push(data2));
117
- sp.on("error", (err) => reject(err));
118
- sp.on("close", (code) => {
119
- const stdout = _stdout.join("").trim();
120
- const stderr = _stderr.join("").trim();
121
- if (code !== 0) {
122
- let errmsg = `python process exited with non-zero status code=${code}`;
123
- if (stdout)
124
- errmsg += `
125
- python stdout: ${stdout}`;
126
- if (stderr)
127
- errmsg += `
128
- python stderr: ${stderr}`;
129
- reject(errmsg);
130
- }
131
- if (stderr) {
132
- const errmsg = `python process emitted standard error
133
- python stderr: ${stderr}`;
134
- reject(errmsg);
135
- }
136
- resolve(stdout);
137
- });
138
- });
139
- }
140
86
  export {
141
87
  api
142
88
  };