@sjcrh/proteinpaint-server 2.173.0 → 2.174.1
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 +5 -5
- package/routes/grin2.js +173 -95
- package/routes/termdb.chat.js +410 -52
- package/routes/termdb.cluster.js +2 -1
- package/routes/termdb.config.js +1 -0
- package/routes/termdb.runChart.js +34 -28
- package/src/app.js +860 -333
- package/src/mds3.gdc.filter.js +58 -64
package/src/mds3.gdc.filter.js
CHANGED
|
@@ -6,35 +6,42 @@ f{}
|
|
|
6
6
|
returns a GDC filter object, or null if no filter
|
|
7
7
|
|
|
8
8
|
GDC filter: https://docs.gdc.cancer.gov/API/Users_Guide/Search_and_Retrieval/
|
|
9
|
-
|
|
10
|
-
TODO !!support nested filter!!
|
|
11
9
|
*/
|
|
12
|
-
export function filter2GDCfilter(f) {
|
|
10
|
+
export function filter2GDCfilter(f, level = 0) {
|
|
13
11
|
// gdc filter that will be returned
|
|
14
|
-
|
|
15
|
-
op: f.
|
|
12
|
+
let obj = {
|
|
13
|
+
op: f.join || 'and',
|
|
16
14
|
content: []
|
|
17
15
|
}
|
|
18
|
-
if (!Array.isArray(f.lst)) throw 'filter.lst[] not array'
|
|
16
|
+
if (!Array.isArray(f.lst)) throw new Error('filter.lst[] not array')
|
|
17
|
+
if (f.in === false) throw `negation of nested filters is not supported`
|
|
18
|
+
|
|
19
19
|
for (const item of f.lst) {
|
|
20
|
-
if (item.type != 'tvs')
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
if (item.type != 'tvs') {
|
|
21
|
+
const f = filter2GDCfilter(item, level + 1)
|
|
22
|
+
if (f) obj.content.push(f)
|
|
23
|
+
continue
|
|
24
|
+
}
|
|
25
|
+
if (!item.tvs) throw new Error('item.tvs missing')
|
|
26
|
+
if (!item.tvs.term) throw new Error('item.tvs.term missing')
|
|
23
27
|
if (dtTermTypes.has(item.tvs.term.type)) {
|
|
24
28
|
// geneVariant/dt term filtering will be performed during post-processing
|
|
25
29
|
// (see mayFilterByGeneVariant() in server/src/mds3.init.js)
|
|
26
30
|
continue
|
|
27
31
|
}
|
|
28
32
|
if (item.tvs.term.type == 'geneExpression') {
|
|
33
|
+
if (level > 0) throw new Error(`gene expression filters are only supported at the root level of a nested filter`)
|
|
29
34
|
// geneExpression term filtering will be performed during post-processing (see mayFilterByExpression() in server/src/mds3.gdc.js)
|
|
30
35
|
continue
|
|
31
36
|
}
|
|
32
37
|
if (item.tvs.term.type == 'survival') {
|
|
38
|
+
if (level > 0) throw new Error(`survival filters are only supported at the root level of a nested filter`)
|
|
33
39
|
// survival term filtering will be performed during post-processing (see mayFilterBySurvival() in server/src/mds3.gdc.js)
|
|
34
40
|
continue
|
|
35
41
|
}
|
|
36
42
|
|
|
37
|
-
|
|
43
|
+
// sometimes, numeric filters have a values entry
|
|
44
|
+
if (item.tvs.values && !item.tvs.ranges) {
|
|
38
45
|
// categorical
|
|
39
46
|
const f = {
|
|
40
47
|
op: item.tvs.isnot ? '!=' : 'in',
|
|
@@ -47,65 +54,24 @@ export function filter2GDCfilter(f) {
|
|
|
47
54
|
continue
|
|
48
55
|
}
|
|
49
56
|
if (item.tvs.ranges) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
obj.content.push({
|
|
60
|
-
op: range.startinclusive ? (item.tvs.isnot ? '<' : '>=') : item.tvs.isnot ? '<=' : '>',
|
|
61
|
-
content: { field: mayChangeCase2Cases(item.tvs.term), value: range.start }
|
|
62
|
-
})
|
|
63
|
-
continue
|
|
64
|
-
}
|
|
65
|
-
if (item.tvs.isnot) {
|
|
66
|
-
obj.content.push({
|
|
67
|
-
op: 'or',
|
|
68
|
-
content: [
|
|
69
|
-
{
|
|
70
|
-
op: 'and',
|
|
71
|
-
content: [
|
|
72
|
-
{
|
|
73
|
-
op: range.startinclusive ? '<' : '<=',
|
|
74
|
-
content: { field: mayChangeCase2Cases(item.tvs.term), value: range.start }
|
|
75
|
-
}
|
|
76
|
-
]
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
op: 'and',
|
|
80
|
-
content: [
|
|
81
|
-
{
|
|
82
|
-
op: range.stopinclusive ? '>' : '>=',
|
|
83
|
-
content: { field: mayChangeCase2Cases(item.tvs.term), value: range.stop }
|
|
84
|
-
}
|
|
85
|
-
]
|
|
86
|
-
}
|
|
87
|
-
]
|
|
88
|
-
})
|
|
89
|
-
} else {
|
|
90
|
-
obj.content.push({
|
|
91
|
-
op: 'and',
|
|
92
|
-
content: [
|
|
93
|
-
{
|
|
94
|
-
op: range.startinclusive ? '>=' : '>',
|
|
95
|
-
content: { field: mayChangeCase2Cases(item.tvs.term), value: range.start }
|
|
96
|
-
},
|
|
97
|
-
{
|
|
98
|
-
op: range.stopinclusive ? '<=' : '<',
|
|
99
|
-
content: { field: mayChangeCase2Cases(item.tvs.term), value: range.stop }
|
|
100
|
-
}
|
|
101
|
-
]
|
|
102
|
-
})
|
|
57
|
+
let f
|
|
58
|
+
if (!item.tvs.ranges.length) throw new Error('item.tvs.ranges[] is empty')
|
|
59
|
+
if (item.tvs.ranges.length == 1) {
|
|
60
|
+
const range = item.tvs.ranges[0]
|
|
61
|
+
f = range2GDCrange(range, item)
|
|
62
|
+
} else {
|
|
63
|
+
f = { op: 'or', content: [] }
|
|
64
|
+
for (const range of item.tvs.ranges) {
|
|
65
|
+
f.content.push(range2GDCrange(range, item))
|
|
103
66
|
}
|
|
104
67
|
}
|
|
68
|
+
//if (item.tvs.isnot) f = { op: '!=', content: f }
|
|
69
|
+
obj.content.push(f)
|
|
105
70
|
continue
|
|
106
71
|
}
|
|
107
|
-
throw 'unknown tvs structure when converting to gdc filter'
|
|
72
|
+
throw new Error('unknown tvs structure when converting to gdc filter')
|
|
108
73
|
}
|
|
74
|
+
if (!level) console.log(JSON.stringify(obj, null, ' '))
|
|
109
75
|
return obj.content.length ? obj : null
|
|
110
76
|
}
|
|
111
77
|
|
|
@@ -123,3 +89,31 @@ function mayChangeCase2Cases(t) {
|
|
|
123
89
|
if (l[0] == 'case') l[0] = 'cases'
|
|
124
90
|
return l.join('.')
|
|
125
91
|
}
|
|
92
|
+
|
|
93
|
+
function range2GDCrange(range, item) {
|
|
94
|
+
if (range.startunbounded) {
|
|
95
|
+
return {
|
|
96
|
+
op: range.stopinclusive ? (item.tvs.isnot ? '>' : '<=') : item.tvs.isnot ? '>=' : '<',
|
|
97
|
+
content: { field: mayChangeCase2Cases(item.tvs.term), value: range.stop }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (range.stopunbounded) {
|
|
101
|
+
return {
|
|
102
|
+
op: range.startinclusive ? (item.tvs.isnot ? '<' : '>=') : item.tvs.isnot ? '<=' : '>',
|
|
103
|
+
content: { field: mayChangeCase2Cases(item.tvs.term), value: range.start }
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
op: 'and',
|
|
108
|
+
content: [
|
|
109
|
+
{
|
|
110
|
+
op: range.startinclusive ? (item.tvs.isnot ? '<' : '>=') : item.tvs.isnot ? '>=' : '>',
|
|
111
|
+
content: { field: mayChangeCase2Cases(item.tvs.term), value: range.start }
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
op: range.stopinclusive ? (item.tvs.isnot ? '>' : '<=') : item.tvs.isnot ? '<=' : '<',
|
|
115
|
+
content: { field: mayChangeCase2Cases(item.tvs.term), value: range.stop }
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
}
|