@sjcrh/proteinpaint-server 2.137.2 → 2.137.3
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 +3 -3
- package/routes/filterTermValues.js +5 -1
- package/routes/grin2.js +1 -1
- package/routes/profileFormScores.js +12 -6
- package/routes/profileScores.js +4 -1
- package/routes/termdb.categories.js +2 -1
- package/routes/termdb.config.js +3 -2
- package/routes/termdb.descrstats.js +5 -1
- package/routes/termdb.topMutatedGenes.js +1 -1
- package/routes/termdb.topTermsByType.js +1 -1
- package/routes/termdb.topVariablyExpressedGenes.js +1 -1
- package/src/app.js +311 -194
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-server",
|
|
3
|
-
"version": "2.137.
|
|
3
|
+
"version": "2.137.3",
|
|
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",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"@sjcrh/proteinpaint-python": "2.135.2-0",
|
|
64
64
|
"@sjcrh/proteinpaint-r": "2.137.2-0",
|
|
65
65
|
"@sjcrh/proteinpaint-rust": "2.137.2-0",
|
|
66
|
-
"@sjcrh/proteinpaint-shared": "2.137.
|
|
67
|
-
"@sjcrh/proteinpaint-types": "2.137.
|
|
66
|
+
"@sjcrh/proteinpaint-shared": "2.137.3",
|
|
67
|
+
"@sjcrh/proteinpaint-types": "2.137.3",
|
|
68
68
|
"@types/express": "^5.0.0",
|
|
69
69
|
"@types/express-session": "^1.18.1",
|
|
70
70
|
"better-sqlite3": "^9.4.1",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { FilterTermValuesPayload } from "#types/checkers";
|
|
2
2
|
import { getData, getSamplesPerFilter } from "../src/termdb.matrix.js";
|
|
3
|
+
import { authApi } from "../src/auth.js";
|
|
3
4
|
const api = {
|
|
4
5
|
endpoint: "filterTermValues",
|
|
5
6
|
methods: {
|
|
@@ -48,11 +49,14 @@ function getList(samplesPerFilter, filtersData, tw) {
|
|
|
48
49
|
return filteredValues;
|
|
49
50
|
}
|
|
50
51
|
async function getFilters(query, ds, genome, res) {
|
|
52
|
+
if (!query.filterByUserSites)
|
|
53
|
+
authApi.mayAdjustFilter(query, ds, query.terms);
|
|
51
54
|
try {
|
|
52
55
|
const samplesPerFilter = await getSamplesPerFilter(query, ds);
|
|
53
56
|
const filtersData = await getData(
|
|
54
57
|
{
|
|
55
|
-
terms: query.terms
|
|
58
|
+
terms: query.terms,
|
|
59
|
+
__protected__: query.__protected__
|
|
56
60
|
},
|
|
57
61
|
ds,
|
|
58
62
|
genome
|
package/routes/grin2.js
CHANGED
|
@@ -47,7 +47,7 @@ async function runGrin2(g, ds, request) {
|
|
|
47
47
|
const startTime = Date.now();
|
|
48
48
|
mayLog("[GRIN2] Getting samples from cohort filter...");
|
|
49
49
|
const samples = await get_samples(
|
|
50
|
-
request
|
|
50
|
+
request,
|
|
51
51
|
ds,
|
|
52
52
|
true
|
|
53
53
|
// must set to true to return sample name to be able to access file. FIXME this can let names revealed to grin2 client, may need to apply access control
|
|
@@ -29,14 +29,17 @@ function init({ genomes }) {
|
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
async function getScoresDict(query, ds, genome) {
|
|
32
|
+
if (!query.filterByUserSites)
|
|
33
|
+
query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
|
|
32
34
|
const terms = [...query.scoreTerms, query.facilityTW];
|
|
33
35
|
if (query.scScoreTerms)
|
|
34
36
|
terms.push(...query.scScoreTerms);
|
|
35
37
|
const data = await getData(
|
|
36
38
|
{
|
|
37
39
|
terms,
|
|
38
|
-
filter: query.site || !query.isAggregate ? void 0 : query.filter
|
|
40
|
+
filter: query.site || !query.isAggregate ? void 0 : query.filter,
|
|
39
41
|
//if isRadarFacility and site is specified, do not apply the filter
|
|
42
|
+
__protected__: query.__protected__
|
|
40
43
|
},
|
|
41
44
|
ds,
|
|
42
45
|
genome
|
|
@@ -48,6 +51,9 @@ async function getScoresDict(query, ds, genome) {
|
|
|
48
51
|
sites = lst.map((s) => {
|
|
49
52
|
return { label: data.refs.bySampleId[s.sample].label, value: s.sample };
|
|
50
53
|
});
|
|
54
|
+
if (query.userSites) {
|
|
55
|
+
sites = sites.filter((s) => query.userSites.includes(s.label));
|
|
56
|
+
}
|
|
51
57
|
let sitesSelected = [];
|
|
52
58
|
if (query.site)
|
|
53
59
|
sitesSelected = [query.site];
|
|
@@ -56,18 +62,18 @@ async function getScoresDict(query, ds, genome) {
|
|
|
56
62
|
else
|
|
57
63
|
sitesSelected = query.sites;
|
|
58
64
|
const sampleData = sitesSelected?.length == 1 ? data.samples[sitesSelected[0]] : null;
|
|
59
|
-
|
|
65
|
+
let samples = sampleData ? [sampleData] : Object.values(data.samples);
|
|
66
|
+
if (sitesSelected?.length > 0)
|
|
67
|
+
samples = samples.filter((s) => sitesSelected.includes(s.sample));
|
|
60
68
|
const term2Score = {};
|
|
61
69
|
for (const d of query.scoreTerms) {
|
|
62
|
-
const samples2 = sampleData ? [sampleData] : Object.values(data.samples);
|
|
63
70
|
const getDictFunc = (sample) => getDict(d.$id, sample);
|
|
64
|
-
const percents = getPercentsDict(getDictFunc,
|
|
71
|
+
const percents = getPercentsDict(getDictFunc, samples);
|
|
65
72
|
term2Score[d.term.id] = percents;
|
|
66
73
|
}
|
|
67
74
|
if (query.scScoreTerms)
|
|
68
75
|
for (const d of query.scScoreTerms) {
|
|
69
|
-
const
|
|
70
|
-
const percents = getSCPercentsDict(d, samples2);
|
|
76
|
+
const percents = getSCPercentsDict(d, samples);
|
|
71
77
|
term2Score[d.term.id] = percents;
|
|
72
78
|
}
|
|
73
79
|
const facilityValue = sampleData?.[query.facilityTW.$id];
|
package/routes/profileScores.js
CHANGED
|
@@ -29,6 +29,8 @@ function init({ genomes }) {
|
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
async function getScores(query, ds, genome) {
|
|
32
|
+
if (!query.filterByUserSites)
|
|
33
|
+
query.__protected__.ignoredTermIds.push(query.facilityTW.term.id);
|
|
32
34
|
const terms = [query.facilityTW];
|
|
33
35
|
for (const term of query.scoreTerms) {
|
|
34
36
|
terms.push(term.score);
|
|
@@ -39,8 +41,9 @@ async function getScores(query, ds, genome) {
|
|
|
39
41
|
const data = await getData(
|
|
40
42
|
{
|
|
41
43
|
terms,
|
|
42
|
-
filter: query.site || !query.isAggregate ? void 0 : query.filter
|
|
44
|
+
filter: query.site || !query.isAggregate ? void 0 : query.filter,
|
|
43
45
|
//if site is specified, do not apply the filter that is for the aggregation
|
|
46
|
+
__protected__: query.__protected__
|
|
44
47
|
},
|
|
45
48
|
ds,
|
|
46
49
|
genome
|
|
@@ -45,8 +45,9 @@ async function trigger_getcategories(q, res, tdb, ds, genome) {
|
|
|
45
45
|
terms: [q.tw],
|
|
46
46
|
currentGeneNames: q.currentGeneNames,
|
|
47
47
|
// optional, from mds3 mayAddGetCategoryArgs()
|
|
48
|
-
rglst: q.rglst
|
|
48
|
+
rglst: q.rglst,
|
|
49
49
|
// optional, from mds3 mayAddGetCategoryArgs()
|
|
50
|
+
__protected__: q.__protected__
|
|
50
51
|
};
|
|
51
52
|
const data = await getData(arg, ds, genome);
|
|
52
53
|
if (data.error)
|
package/routes/termdb.config.js
CHANGED
|
@@ -62,7 +62,8 @@ function make(q, req, res, ds, genome) {
|
|
|
62
62
|
defaultChartType: ds.cohort.defaultChartType,
|
|
63
63
|
invalidTokenErrorHandling: tdb.invalidTokenErrorHandling,
|
|
64
64
|
colorMap: tdb.colorMap,
|
|
65
|
-
defaultTw4correlationPlot: tdb.defaultTw4correlationPlot
|
|
65
|
+
defaultTw4correlationPlot: tdb.defaultTw4correlationPlot,
|
|
66
|
+
authFilter: req.query.filter
|
|
66
67
|
};
|
|
67
68
|
if (tdb.plotConfigByCohort)
|
|
68
69
|
c.plotConfigByCohort = tdb.plotConfigByCohort;
|
|
@@ -92,7 +93,6 @@ function make(q, req, res, ds, genome) {
|
|
|
92
93
|
c.assayAvailability = ds.assayAvailability;
|
|
93
94
|
if (ds.cohort.correlationVolcano)
|
|
94
95
|
c.correlationVolcano = ds.cohort.correlationVolcano;
|
|
95
|
-
c.requiredAuth = authApi.getRequiredCredForDsEmbedder(q.dslabel, q.embedder);
|
|
96
96
|
addRestrictAncestries(c, tdb);
|
|
97
97
|
addScatterplots(c, ds);
|
|
98
98
|
addMatrixplots(c, ds);
|
|
@@ -102,6 +102,7 @@ function make(q, req, res, ds, genome) {
|
|
|
102
102
|
c.clientAuthResult = info?.clientAuthResult || {};
|
|
103
103
|
if (tdb.displaySampleIds)
|
|
104
104
|
c.displaySampleIds = tdb.displaySampleIds(c.clientAuthResult);
|
|
105
|
+
c.authFilter = req.query.filter;
|
|
105
106
|
res.send({ termdbConfig: c });
|
|
106
107
|
}
|
|
107
108
|
function addRestrictAncestries(c, tdb) {
|
|
@@ -30,7 +30,11 @@ function init({ genomes }) {
|
|
|
30
30
|
throw "invalid termdb object";
|
|
31
31
|
if (!q.tw.$id)
|
|
32
32
|
q.tw.$id = "_";
|
|
33
|
-
const data = await getData(
|
|
33
|
+
const data = await getData(
|
|
34
|
+
{ filter: q.filter, filter0: q.filter0, terms: [q.tw], __protected__: q.__protected__ },
|
|
35
|
+
ds,
|
|
36
|
+
genome
|
|
37
|
+
);
|
|
34
38
|
if (data.error)
|
|
35
39
|
throw data.error;
|
|
36
40
|
const values = [];
|
|
@@ -93,7 +93,7 @@ function validate_query_getTopMutatedGenes(ds) {
|
|
|
93
93
|
q.get = async (param) => {
|
|
94
94
|
let sampleStatement = "";
|
|
95
95
|
if (param.filter) {
|
|
96
|
-
const lst = await get_samples(param
|
|
96
|
+
const lst = await get_samples(param, ds);
|
|
97
97
|
if (lst.length == 0)
|
|
98
98
|
throw "empty sample filter";
|
|
99
99
|
sampleStatement = `WHERE sample IN (${lst.map((i) => i.id).join(",")})`;
|
|
@@ -56,7 +56,7 @@ function nativeValidateQuery(ds, type) {
|
|
|
56
56
|
const typeQuery = ds.queries[type];
|
|
57
57
|
const samples = [];
|
|
58
58
|
if (q.filter) {
|
|
59
|
-
const sidlst = await get_samples(q
|
|
59
|
+
const sidlst = await get_samples(q, ds);
|
|
60
60
|
for (const i of sidlst) {
|
|
61
61
|
if (typeQuery.samples.includes(i.id)) {
|
|
62
62
|
const n = ds.cohort.termdb.q.id2sampleName(i.id);
|
|
@@ -66,7 +66,7 @@ function nativeValidateQuery(ds) {
|
|
|
66
66
|
ds.queries.topVariablyExpressedGenes.getGenes = async (q) => {
|
|
67
67
|
const samples = [];
|
|
68
68
|
if (q.filter) {
|
|
69
|
-
const sidlst = await get_samples(q
|
|
69
|
+
const sidlst = await get_samples(q, ds);
|
|
70
70
|
for (const i of sidlst) {
|
|
71
71
|
if (gE.samples.includes(i.id)) {
|
|
72
72
|
const n = ds.cohort.termdb.q.id2sampleName(i.id);
|