@sjcrh/proteinpaint-server 2.74.2 → 2.75.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.
@@ -83,6 +83,15 @@ var termdb_test_default = {
83
83
  }
84
84
  },
85
85
  termid2totalsize2: {}
86
+ // about: {
87
+ // tab: {
88
+ // order: 4,
89
+ // topLabel: 'test',
90
+ // midLabel: 'test about',
91
+ // btmLabel: 'test'
92
+ // },
93
+ // html: 'Test'
94
+ // }
86
95
  },
87
96
  scatterplots: {
88
97
  plots: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjcrh/proteinpaint-server",
3
- "version": "2.74.2",
3
+ "version": "2.75.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",
@@ -62,7 +62,7 @@
62
62
  },
63
63
  "dependencies": {
64
64
  "@sjcrh/augen": "2.46.0",
65
- "@sjcrh/proteinpaint-rust": "2.74.0",
65
+ "@sjcrh/proteinpaint-rust": "2.75.0",
66
66
  "better-sqlite3": "^9.4.1",
67
67
  "body-parser": "^1.15.2",
68
68
  "canvas": "~2.11.2",
@@ -0,0 +1,99 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import serverconfig from "#src/serverconfig.js";
4
+ import { spawn } from "child_process";
5
+ const api = {
6
+ endpoint: "brainImaging",
7
+ methods: {
8
+ get: {
9
+ init,
10
+ request: {
11
+ typeId: "GetBrainImagingRequest"
12
+ },
13
+ response: {
14
+ typeId: "GetBrainImagingResponse"
15
+ }
16
+ }
17
+ }
18
+ };
19
+ function init({ genomes }) {
20
+ return async (req, res) => {
21
+ try {
22
+ const query = req.query;
23
+ const g = genomes[query.genome];
24
+ if (!g)
25
+ throw "invalid genome name";
26
+ const ds = g.datasets[query.dslabel];
27
+ if (!ds)
28
+ throw "invalid dataset name";
29
+ const brainImage = await getBrainImage(query, genomes);
30
+ res.send({ brainImage });
31
+ } catch (e) {
32
+ console.log(e);
33
+ res.status(404).send("Sample brain image not found");
34
+ }
35
+ };
36
+ }
37
+ async function getBrainImage(query, genomes) {
38
+ const ds = genomes[query.genome].datasets[query.dslabel];
39
+ const q = ds.queries.NIdata;
40
+ const key = query.refKey;
41
+ if (q[key].referenceFile && q[key].samples) {
42
+ const refFile = path.join(serverconfig.tpmasterdir, q[key].referenceFile);
43
+ const dirPath = path.join(serverconfig.tpmasterdir, q[key].samples);
44
+ const files = fs.readdirSync(dirPath).filter((file) => file.endsWith(".nii") && fs.statSync(path.join(dirPath, file)).isFile());
45
+ if (query.samplesOnly) {
46
+ const sampleNames = files.map((name) => name.split(".nii")[0]);
47
+ if (q[key].sampleColumns) {
48
+ const samples = {};
49
+ for (const s of sampleNames) {
50
+ const annoForOneS = { sample: s };
51
+ const sid = ds.cohort.termdb.q.sampleName2id(s);
52
+ for (const term of q[key].sampleColumns) {
53
+ const v = ds.cohort.termdb.q.getSample2value(term.termid, sid);
54
+ if (v[0]) {
55
+ annoForOneS[term.termid] = v[0].value;
56
+ }
57
+ }
58
+ samples[s] = annoForOneS;
59
+ }
60
+ return Object.values(samples);
61
+ }
62
+ return sampleNames;
63
+ }
64
+ return new Promise((resolve, reject) => {
65
+ const filePaths = query.selectedSampleFileNames.map((file) => path.join(dirPath, file));
66
+ const ps = spawn("python3", [
67
+ `${serverconfig.binpath}/../python/src/plotBrainImaging.py`,
68
+ refFile,
69
+ query.l,
70
+ query.f,
71
+ query.t,
72
+ ...filePaths
73
+ ]);
74
+ const imgData = [];
75
+ ps.stdout.on("data", (data) => {
76
+ imgData.push(data);
77
+ });
78
+ ps.stderr.on("data", (data) => {
79
+ console.error(`stderr: ${data}`);
80
+ reject(new Error(`Python script filed: ${data}`));
81
+ });
82
+ ps.on("close", (code) => {
83
+ if (code === 0) {
84
+ const imageBuffer = Buffer.concat(imgData);
85
+ const base64Data = imageBuffer.toString("base64");
86
+ const imgUrl = `data:image/png;base64,${base64Data}`;
87
+ resolve(imgUrl);
88
+ } else {
89
+ reject(new Error(`Python script exited with code ${code}`));
90
+ }
91
+ });
92
+ });
93
+ } else {
94
+ throw "no reference or sample files";
95
+ }
96
+ }
97
+ export {
98
+ api
99
+ };
@@ -1,6 +1,3 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import serverconfig from "#src/serverconfig.js";
4
1
  const api = {
5
2
  endpoint: "samplewsimages",
6
3
  methods: {
@@ -30,22 +27,42 @@ function init({ genomes }) {
30
27
  if (!ds)
31
28
  throw "invalid dataset name";
32
29
  const sampleId = query.sample_id;
33
- const sampleWSImagesPath = path.join(
34
- `${serverconfig.tpmasterdir}/${ds.queries.WSImages.imageBySampleFolder}`,
35
- sampleId
36
- );
37
- const sampleWSImages = await getWSImages(sampleWSImagesPath);
38
- res.send({ sampleWSImages });
30
+ const images = await ds.queries.WSImages.getWSImages({ sampleId });
31
+ res.send({ sampleWSImages: images });
39
32
  } catch (e) {
40
33
  console.log(e);
41
34
  res.status(404).send("Sample images not found");
42
35
  }
43
36
  };
44
37
  }
45
- async function getWSImages(sampleImagesPath) {
46
- const files = await fs.promises.readdir(sampleImagesPath);
47
- return files.filter((file) => [".svs", ".mrxs", ".scn", ".ndpi", ".tiff"].includes(path.extname(file)));
38
+ function validate_query_getSampleWSImages(ds, genome) {
39
+ const q = ds.queries.WSImages;
40
+ if (!q)
41
+ return;
42
+ nativeValidateQuery(ds);
43
+ }
44
+ function nativeValidateQuery(ds) {
45
+ ds.queries.WSImages.getWSImages = async (q) => {
46
+ return await getWSImages(ds, q.sampleId);
47
+ };
48
+ }
49
+ async function getWSImages(ds, sampleName) {
50
+ const sql = `SELECT wsimages.filename as filename, wsimages.metadata as metadata
51
+ FROM wsimages
52
+ INNER JOIN sampleidmap
53
+ ON wsimages.sample = sampleidmap.id
54
+ WHERE sampleidmap.name = ?`;
55
+ const rows = ds.cohort.db.connection.prepare(sql).all(sampleName);
56
+ const images = [];
57
+ for (const row of rows) {
58
+ images.push({
59
+ filename: row.filename,
60
+ metadata: row.metadata
61
+ });
62
+ }
63
+ return images;
48
64
  }
49
65
  export {
50
- api
66
+ api,
67
+ validate_query_getSampleWSImages
51
68
  };
@@ -23,7 +23,7 @@ function init({ genomes }) {
23
23
  if (!genome)
24
24
  throw "invalid genome";
25
25
  const [ds] = get_ds_tdb(genome, q);
26
- res.send({ count: ds.cohort.termdb.q.getcohortsamplecount(q.cohort) });
26
+ res.send({ count: ds.cohort.termdb.q.getCohortSampleCount(q.cohort) });
27
27
  } catch (e) {
28
28
  res.send({ error: e.message || e });
29
29
  if (e.stack)
@@ -62,6 +62,8 @@ function make(q, res, ds, genome) {
62
62
  c.chartConfigByType = tdb.chartConfigByType;
63
63
  if (tdb.multipleTestingCorrection)
64
64
  c.multipleTestingCorrection = tdb.multipleTestingCorrection;
65
+ if (tdb.neuroOncRegression)
66
+ c.neuroOncRegression = tdb.neuroOncRegression;
65
67
  if (tdb.helpPages)
66
68
  c.helpPages = tdb.helpPages;
67
69
  if (tdb.minTimeSinceDx)
@@ -80,6 +82,8 @@ function make(q, res, ds, genome) {
80
82
  c.useCasesExcluded = tdb.useCasesExcluded;
81
83
  if (tdb.excludedTermtypeByTarget)
82
84
  c.excludedTermtypeByTarget = tdb.excludedTermtypeByTarget;
85
+ if (tdb.about)
86
+ c.about = tdb.about;
83
87
  if (ds.assayAvailability)
84
88
  c.assayAvailability = ds.assayAvailability;
85
89
  if (ds.customTwQByType)