@sjcrh/proteinpaint-server 2.103.0 → 2.105.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.103.0",
3
+ "version": "2.105.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",
@@ -61,7 +61,7 @@
61
61
  "@sjcrh/augen": "2.87.0",
62
62
  "@sjcrh/proteinpaint-rust": "2.99.0",
63
63
  "@sjcrh/proteinpaint-shared": "2.99.1",
64
- "@sjcrh/proteinpaint-types": "2.102.0",
64
+ "@sjcrh/proteinpaint-types": "2.105.0",
65
65
  "@types/express": "^5.0.0",
66
66
  "@types/express-session": "^1.18.1",
67
67
  "better-sqlite3": "^9.4.1",
package/routes/gdc.maf.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { gdcMafPayload } from "#types/checkers";
2
- import path from "path";
3
- import got from "got";
2
+ import ky from "ky";
3
+ import { joinUrl } from "#shared/joinUrl.js";
4
4
  import serverconfig from "#src/serverconfig.js";
5
5
  const maxFileNumber = 1e3;
6
6
  const allowedWorkflowType = "Aliquot Ensemble Somatic Variant Merging and Masking";
@@ -49,8 +49,8 @@ async function listMafFiles(q, ds) {
49
49
  if (q.filter0) {
50
50
  case_filters.content.push(q.filter0);
51
51
  }
52
- const { host, headers } = ds.getHostHeaders(q);
53
- const data = {
52
+ const { host } = ds.getHostHeaders(q);
53
+ const body = {
54
54
  filters,
55
55
  size: maxFileNumber,
56
56
  fields: [
@@ -62,19 +62,16 @@ async function listMafFiles(q, ds) {
62
62
  // case uuid for making case url link to portal
63
63
  "cases.submitter_id",
64
64
  // used when listing all cases & files
65
- "cases.samples.sample_type"
66
- // may add diagnosis and primary site
65
+ "cases.samples.tissue_type",
66
+ "cases.samples.tumor_descriptor"
67
67
  ].join(",")
68
68
  };
69
69
  if (case_filters.content.length)
70
- data.case_filters = case_filters;
71
- const response = await got.post(path.join(host.rest, "files"), { headers, body: JSON.stringify(data) });
72
- let re;
73
- try {
74
- re = JSON.parse(response.body);
75
- } catch (_) {
76
- throw "invalid JSON from " + api.endpoint;
77
- }
70
+ body.case_filters = case_filters;
71
+ 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}`;
74
+ const re = await response.json();
78
75
  if (!Number.isInteger(re.data?.pagination?.total))
79
76
  throw "re.data.pagination.total is not int";
80
77
  if (!Array.isArray(re.data?.hits))
@@ -89,10 +86,20 @@ async function listMafFiles(q, ds) {
89
86
  project_id: c.project.project_id,
90
87
  file_size: h.file_size,
91
88
  case_submitter_id: c.submitter_id,
92
- case_uuid: c.case_id
89
+ case_uuid: c.case_id,
90
+ sample_types: []
93
91
  };
94
92
  if (c.samples) {
95
- file.sample_types = c.samples.map((i) => i.sample_type).sort();
93
+ let normalTypeName;
94
+ for (const { tumor_descriptor, tissue_type } of c.samples) {
95
+ if (tissue_type == "Normal") {
96
+ normalTypeName = (tumor_descriptor == "Not Applicable" ? "" : tumor_descriptor + " ") + tissue_type;
97
+ continue;
98
+ }
99
+ file.sample_types.push(tumor_descriptor + " " + tissue_type);
100
+ }
101
+ if (normalTypeName)
102
+ file.sample_types.push(normalTypeName);
96
103
  }
97
104
  files.push(file);
98
105
  }
@@ -1,9 +1,9 @@
1
- import got from "got";
2
- import path from "path";
1
+ import ky from "ky";
2
+ import { joinUrl } from "#shared/joinUrl.js";
3
3
  import { run_rust_stream } from "@sjcrh/proteinpaint-rust";
4
- import serverconfig from "#src/serverconfig.js";
5
4
  import { gdcMafPayload } from "#types/checkers";
6
5
  import { maxTotalSizeCompressed } from "./gdc.maf.ts";
6
+ import { mayLog } from "#src/helpers.ts";
7
7
  const api = {
8
8
  endpoint: "gdc/mafBuild",
9
9
  methods: {
@@ -37,17 +37,13 @@ function init({ genomes }) {
37
37
  }
38
38
  async function buildMaf(q, res, ds) {
39
39
  const t0 = Date.now();
40
- const { host, headers } = ds.getHostHeaders(q);
41
- const fileLst2 = await getFileLstUnderSizeLimit(q.fileIdLst, host, headers);
42
- if (serverconfig.debugmode)
43
- console.log(
44
- `${fileLst2.length} out of ${q.fileIdLst.length} input MAF files accepted by size limit`,
45
- Date.now() - t0
46
- );
40
+ const { host } = ds.getHostHeaders(q);
41
+ const fileLst2 = await getFileLstUnderSizeLimit(q.fileIdLst, host);
42
+ mayLog(`${fileLst2.length} out of ${q.fileIdLst.length} input MAF files accepted by size limit`, Date.now() - t0);
47
43
  const arg = {
48
44
  fileIdLst: fileLst2,
49
45
  columns: q.columns,
50
- host: path.join(host.rest, "data")
46
+ host: joinUrl(host.rest, "data")
51
47
  // must use the /data/ endpoint from current host
52
48
  };
53
49
  const rustStream = run_rust_stream("gdcmaf", JSON.stringify(arg));
@@ -55,8 +51,7 @@ async function buildMaf(q, res, ds) {
55
51
  res.setHeader("Content-Disposition", "attachment; filename=cohort.maf.gz");
56
52
  rustStream.pipe(res);
57
53
  rustStream.on("end", () => {
58
- if (serverconfig.debugmode)
59
- console.log("rust gdcmaf", Date.now() - t0);
54
+ mayLog("rust gdcmaf", Date.now() - t0);
60
55
  res.end();
61
56
  });
62
57
  rustStream.on("error", (err) => {
@@ -65,10 +60,10 @@ async function buildMaf(q, res, ds) {
65
60
  res.end("Internal Server Error");
66
61
  });
67
62
  }
68
- async function getFileLstUnderSizeLimit(lst, host, headers) {
63
+ async function getFileLstUnderSizeLimit(lst, host) {
69
64
  if (lst.length == 0)
70
65
  throw "fileIdLst[] not array or blank";
71
- const data = {
66
+ const body = {
72
67
  filters: {
73
68
  op: "in",
74
69
  content: { field: "file_id", value: lst }
@@ -76,13 +71,10 @@ async function getFileLstUnderSizeLimit(lst, host, headers) {
76
71
  size: 1e4,
77
72
  fields: "file_size"
78
73
  };
79
- const response = await got.post(path.join(host.rest, "files"), { headers, body: JSON.stringify(data) });
80
- let re;
81
- try {
82
- re = JSON.parse(response.body);
83
- } catch (_) {
84
- throw "invalid json from getFileLstUnderSizeLimit";
85
- }
74
+ const response = await ky.post(joinUrl(host.rest, "files"), { timeout: false, json: body });
75
+ if (!response.ok)
76
+ throw `HTTP Error: ${response.status} ${response.statusText}`;
77
+ const re = await response.json();
86
78
  if (!Array.isArray(re.data?.hits))
87
79
  throw "re.data.hits[] not array";
88
80
  const out = [];
@@ -120,6 +120,9 @@ async function run_DE(param, ds, term_results) {
120
120
  const sample_size_limit = 8;
121
121
  let result;
122
122
  if (group1names.length <= sample_size_limit && group2names.length <= sample_size_limit || param.method == "edgeR") {
123
+ if (param.method == "edgeR") {
124
+ expression_input.VarGenes = param.VarGenes;
125
+ }
123
126
  const time1 = (/* @__PURE__ */ new Date()).valueOf();
124
127
  result = JSON.parse(
125
128
  await run_R(path.join(serverconfig.binpath, "utils", "edge.R"), JSON.stringify(expression_input))
@@ -215,9 +215,9 @@ function addNonDictionaryQueries(c, ds, genome) {
215
215
  if (q.singleCell) {
216
216
  q2.singleCell = {
217
217
  samples: {
218
- firstColumnName: q.singleCell.samples.firstColumnName,
219
218
  sampleColumns: q.singleCell.samples.sampleColumns,
220
- experimentColumns: q.singleCell.samples.experimentColumns
219
+ experimentColumns: q.singleCell.samples.experimentColumns,
220
+ extraSampleTabLabel: q.singleCell.samples.extraSampleTabLabel
221
221
  },
222
222
  images: q.singleCell.images,
223
223
  data: {