@sjcrh/proteinpaint-shared 2.178.0 → 2.179.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 +5 -1
- package/src/filter.js +186 -248
- package/src/termdb.usecase.js +14 -11
- package/src/terms.js +102 -79
package/package.json
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sjcrh/proteinpaint-shared",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.179.0",
|
|
4
4
|
"description": "ProteinPaint code that is shared between server and client-side workspaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
7
|
+
"imports": {
|
|
8
|
+
"#types": "@sjcrh/proteinpaint-types",
|
|
9
|
+
"#types/*": "@sjcrh/proteinpaint-types/*"
|
|
10
|
+
},
|
|
7
11
|
"exports": {
|
|
8
12
|
".": "./src/index.js",
|
|
9
13
|
"./*.ts": "./src/*.ts_SHOULD_BE_js",
|
package/src/filter.js
CHANGED
|
@@ -1,255 +1,193 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
setDatasetAnnotations(filter)
|
|
13
|
-
|
|
14
|
-
const samples = new Set()
|
|
15
|
-
for (const anno of sampleAnno) {
|
|
16
|
-
if (samples.has(anno.sample)) continue
|
|
17
|
-
const data = anno.s || anno.data
|
|
18
|
-
if (data && sample_match_termvaluesetting(data, filter)) {
|
|
19
|
-
samples.add(anno.sample)
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
return samples // return as a Set, or maybe as an array later
|
|
1
|
+
function getFilteredSamples(sampleAnno, filter) {
|
|
2
|
+
setDatasetAnnotations(filter);
|
|
3
|
+
const samples = /* @__PURE__ */ new Set();
|
|
4
|
+
for (const anno of sampleAnno) {
|
|
5
|
+
if (samples.has(anno.sample)) continue;
|
|
6
|
+
const data = anno.s || anno.data;
|
|
7
|
+
if (data && sample_match_termvaluesetting(data, filter)) {
|
|
8
|
+
samples.add(anno.sample);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
return samples;
|
|
23
12
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
]
|
|
128
|
-
*/
|
|
129
|
-
/* tvs.values is an array that stores classes (for each available dt) that have/haven't been crossed out by the user at this round of edit-and-apply, e.g.
|
|
130
|
-
[
|
|
131
|
-
{dt: 1, mclassLst: ['WT'], mclassExcludeLst: ['Blank'], origin: 'germline'}
|
|
132
|
-
{dt: 1, mclassLst: ['Blank', 'WT', 'M'], mclassExcludeLst:[], origin:'somatic'},
|
|
133
|
-
{dt: 2, mclassLst: ['Blank', 'WT'], mclassExcludeLst:[]}
|
|
134
|
-
{dt: 4, mclassLst: ['WT', 'CNV_loss'], mclassExcludeLst:[]}
|
|
135
|
-
]
|
|
136
|
-
*/
|
|
137
|
-
const svalues = samplevalue.values || [samplevalue]
|
|
138
|
-
for (const sv of svalues) {
|
|
139
|
-
thistermmatch =
|
|
140
|
-
t.values.find(
|
|
141
|
-
v =>
|
|
142
|
-
v.dt == sv.dt &&
|
|
143
|
-
(!v.origin || sv.origin == v.origin) &&
|
|
144
|
-
(!v.mclasslst || v.mclasslst.includes(sv.class))
|
|
145
|
-
) && true //; console.log(114, t.values[0].dt, samplevalue.dt, thistermmatch)
|
|
146
|
-
}
|
|
147
|
-
} else {
|
|
148
|
-
throw 'unknown term type [sample_match_termvaluesetting() shared/utils/src/filter.js]'
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (t.isnot) {
|
|
152
|
-
thistermmatch = !thistermmatch
|
|
153
|
-
}
|
|
154
|
-
if (thistermmatch) numberofmatchedterms++
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// if one tvslst is matched with an "or" (Set UNION), then sample is okay
|
|
158
|
-
if (filter.join == 'or') {
|
|
159
|
-
if (numberofmatchedterms && filter.in) return true
|
|
160
|
-
if (!numberofmatchedterms && !filter.in) return true
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
// for join="and" (Set intersection)
|
|
164
|
-
if (!('in' in filter)) filter.in = true
|
|
165
|
-
return filter.in == (numberofmatchedterms == lst.length)
|
|
166
|
-
// if (filter.in && numberofmatchedterms == lst.length) return true
|
|
167
|
-
// if (!filter.in && numberofmatchedterms != lst.length) return true
|
|
13
|
+
function sample_match_termvaluesetting(row, filter, _term = null, sample = null) {
|
|
14
|
+
const lst = filter.type == "tvslst" ? filter.lst : [filter];
|
|
15
|
+
let numberofmatchedterms = 0;
|
|
16
|
+
for (const item of lst) {
|
|
17
|
+
if ("type" in item && item.type == "tvslst") {
|
|
18
|
+
if (sample_match_termvaluesetting(row, item, _term, sample)) {
|
|
19
|
+
numberofmatchedterms++;
|
|
20
|
+
}
|
|
21
|
+
} else {
|
|
22
|
+
const itemCopy = JSON.parse(JSON.stringify(item));
|
|
23
|
+
const t = itemCopy.tvs;
|
|
24
|
+
if (_term && t.term) {
|
|
25
|
+
if (!(_term.name == t.term.name && _term.type == t.term.type)) {
|
|
26
|
+
numberofmatchedterms++;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
let samplevalue;
|
|
31
|
+
if (_term && !t.term) {
|
|
32
|
+
if (t.term$type && t.term$type !== _term.type) {
|
|
33
|
+
numberofmatchedterms++;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
t.term = _term;
|
|
37
|
+
samplevalue = typeof row === "object" && t.term.id in row ? row[t.term.id] : row;
|
|
38
|
+
} else if (sample && t.term.$id) {
|
|
39
|
+
samplevalue = sample[t.term.$id].value;
|
|
40
|
+
} else {
|
|
41
|
+
samplevalue = t.term.id in row ? row[t.term.id] : row;
|
|
42
|
+
}
|
|
43
|
+
setDatasetAnnotations(itemCopy);
|
|
44
|
+
let thistermmatch;
|
|
45
|
+
if (t.term.type == "categorical") {
|
|
46
|
+
if (samplevalue === void 0) continue;
|
|
47
|
+
thistermmatch = t.valueset.has(samplevalue);
|
|
48
|
+
} else if (t.term.type == "integer" || t.term.type == "float") {
|
|
49
|
+
if (samplevalue === void 0) continue;
|
|
50
|
+
for (const range of t.ranges) {
|
|
51
|
+
if ("value" in range) {
|
|
52
|
+
thistermmatch = samplevalue === range.value;
|
|
53
|
+
if (thistermmatch) break;
|
|
54
|
+
} else if (samplevalue == range.name) {
|
|
55
|
+
thistermmatch = true;
|
|
56
|
+
break;
|
|
57
|
+
} else {
|
|
58
|
+
if (t.term.values) {
|
|
59
|
+
const v = t.term.values[samplevalue.toString()];
|
|
60
|
+
if (v && v.uncomputable) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
let left, right;
|
|
65
|
+
if (range.startunbounded) {
|
|
66
|
+
left = true;
|
|
67
|
+
} else if ("start" in range) {
|
|
68
|
+
if (range.startinclusive) {
|
|
69
|
+
left = samplevalue >= range.start;
|
|
70
|
+
} else {
|
|
71
|
+
left = samplevalue > range.start;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (range.stopunbounded) {
|
|
75
|
+
right = true;
|
|
76
|
+
} else if ("stop" in range) {
|
|
77
|
+
if (range.stopinclusive) {
|
|
78
|
+
right = samplevalue <= range.stop;
|
|
79
|
+
} else {
|
|
80
|
+
right = samplevalue < range.stop;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
thistermmatch = left && right;
|
|
84
|
+
}
|
|
85
|
+
if (thistermmatch) break;
|
|
86
|
+
}
|
|
87
|
+
} else if (t.term.type == "condition") {
|
|
88
|
+
const key = getPrecomputedKey(t);
|
|
89
|
+
const anno = samplevalue && samplevalue[key];
|
|
90
|
+
if (anno) {
|
|
91
|
+
thistermmatch = Array.isArray(anno) ? t.values.find((d) => anno.includes(d.key)) : t.values.find((d) => d.key == anno);
|
|
92
|
+
}
|
|
93
|
+
} else if (t.term.type == "geneVariant") {
|
|
94
|
+
const svalues = samplevalue.values || [samplevalue];
|
|
95
|
+
for (const sv of svalues) {
|
|
96
|
+
thistermmatch = t.values.find(
|
|
97
|
+
(v) => v.dt == sv.dt && (!v.origin || sv.origin == v.origin) && (!v.mclasslst || v.mclasslst.includes(sv.class))
|
|
98
|
+
) && true;
|
|
99
|
+
if (thistermmatch) break;
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
throw "unknown term type [sample_match_termvaluesetting() shared/utils/src/filter.ts]";
|
|
103
|
+
}
|
|
104
|
+
if (t.isnot) {
|
|
105
|
+
thistermmatch = !thistermmatch;
|
|
106
|
+
}
|
|
107
|
+
if (thistermmatch) numberofmatchedterms++;
|
|
108
|
+
}
|
|
109
|
+
if (filter.join == "or") {
|
|
110
|
+
if (numberofmatchedterms && filter.in) return true;
|
|
111
|
+
if (!numberofmatchedterms && !filter.in) return true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (!("in" in filter)) filter.in = true;
|
|
115
|
+
return filter.in == (numberofmatchedterms == lst.length);
|
|
168
116
|
}
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
117
|
+
function setDatasetAnnotations(item, ds = null) {
|
|
118
|
+
if (item.type == "tvslst") {
|
|
119
|
+
for (const subitem of item.lst) {
|
|
120
|
+
setDatasetAnnotations(subitem, ds);
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
if (ds && typeof ds.setAnnoByTermId == "function") {
|
|
124
|
+
ds.setAnnoByTermId(item.tvs.term.id);
|
|
125
|
+
}
|
|
126
|
+
if (item.tvs.term.type == "categorical") {
|
|
127
|
+
const tvsAny = item.tvs;
|
|
128
|
+
tvsAny.valueset = new Set(tvsAny.values.map((i) => i.key));
|
|
129
|
+
}
|
|
130
|
+
}
|
|
183
131
|
}
|
|
184
|
-
|
|
185
132
|
function getPrecomputedKey(q) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
: q.bar_by_children && q.value_by_most_recent
|
|
190
|
-
? 'childrenAtMostRecent'
|
|
191
|
-
: q.bar_by_children && q.value_by_computable_grade
|
|
192
|
-
? 'children'
|
|
193
|
-
: q.bar_by_grade && q.value_by_max_grade
|
|
194
|
-
? 'maxGrade'
|
|
195
|
-
: q.bar_by_grade && q.value_by_most_recent
|
|
196
|
-
? 'mostRecentGrades'
|
|
197
|
-
: q.bar_by_grade && q.value_by_computable_grade
|
|
198
|
-
? 'computableGrades'
|
|
199
|
-
: ''
|
|
200
|
-
if (!precomputedKey) throw `unknown condition term bar_by_* and/or value_by_*`
|
|
201
|
-
return precomputedKey
|
|
133
|
+
const precomputedKey = q.bar_by_children && q.value_by_max_grade ? "childrenAtMaxGrade" : q.bar_by_children && q.value_by_most_recent ? "childrenAtMostRecent" : q.bar_by_children && q.value_by_computable_grade ? "children" : q.bar_by_grade && q.value_by_max_grade ? "maxGrade" : q.bar_by_grade && q.value_by_most_recent ? "mostRecentGrades" : q.bar_by_grade && q.value_by_computable_grade ? "computableGrades" : "";
|
|
134
|
+
if (!precomputedKey) throw `unknown condition term bar_by_* and/or value_by_*`;
|
|
135
|
+
return precomputedKey;
|
|
202
136
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
lst
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
throw 'filter.join must be either "and" or "or" when .lst length > 1'
|
|
230
|
-
}
|
|
231
|
-
// now, f.join should be "and"
|
|
232
|
-
// if the argument lst[0].join == "and",
|
|
233
|
-
// then the f.in boolean value is reused
|
|
234
|
-
for (let i = 1; i < lst.length; i++) {
|
|
235
|
-
const f2 = JSON.parse(JSON.stringify(lst[i]))
|
|
236
|
-
if (f2.join == 'or') f.lst.push(f2)
|
|
237
|
-
else f.lst.push(...f2.lst)
|
|
238
|
-
}
|
|
239
|
-
// if f ends up single-tvs item (from joining single tvs to empty filter), need to set join to '' per filter spec
|
|
240
|
-
if (f.lst.length == 1 && f.lst[0].type == 'tvs') {
|
|
241
|
-
f.join = ''
|
|
242
|
-
}
|
|
243
|
-
return f
|
|
137
|
+
function filterJoin(lst) {
|
|
138
|
+
if (!lst || lst.length == 0) return;
|
|
139
|
+
let f = JSON.parse(JSON.stringify(lst[0]));
|
|
140
|
+
if (lst.length == 1) return f;
|
|
141
|
+
if (f.lst.length < 2) {
|
|
142
|
+
if (f.join !== "") throw 'filter.join must be an empty string "" when filter.lst.length < 2';
|
|
143
|
+
f.join = "and";
|
|
144
|
+
} else if (f.join == "or") {
|
|
145
|
+
f = {
|
|
146
|
+
type: "tvslst",
|
|
147
|
+
join: "and",
|
|
148
|
+
in: true,
|
|
149
|
+
lst: [f]
|
|
150
|
+
};
|
|
151
|
+
} else if (f.join != "and") {
|
|
152
|
+
throw 'filter.join must be either "and" or "or" when .lst length > 1';
|
|
153
|
+
}
|
|
154
|
+
for (let i = 1; i < lst.length; i++) {
|
|
155
|
+
const f2 = JSON.parse(JSON.stringify(lst[i]));
|
|
156
|
+
if (f2.join == "or") f.lst.push(f2);
|
|
157
|
+
else f.lst.push(...f2.lst);
|
|
158
|
+
}
|
|
159
|
+
if (f.lst.length == 1 && f.lst[0].type == "tvs") {
|
|
160
|
+
f.join = "";
|
|
161
|
+
}
|
|
162
|
+
return f;
|
|
244
163
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
return filter
|
|
164
|
+
function getWrappedTvslst(lst = [], join = "", $id = null) {
|
|
165
|
+
const filter = {
|
|
166
|
+
type: "tvslst",
|
|
167
|
+
in: true,
|
|
168
|
+
join,
|
|
169
|
+
lst
|
|
170
|
+
};
|
|
171
|
+
if ($id !== null) filter.$id = $id;
|
|
172
|
+
return filter;
|
|
255
173
|
}
|
|
174
|
+
function validateTermCollectionTvs(lst1, lst2) {
|
|
175
|
+
if (!Array.isArray(lst1)) throw new Error("numerator not array");
|
|
176
|
+
if (!Array.isArray(lst2)) throw new Error("denominator not array");
|
|
177
|
+
if (lst1.length == 0) throw new Error("numerator empty");
|
|
178
|
+
if (lst2.length == 0) throw new Error("denominator empty");
|
|
179
|
+
if (lst1.length > lst2.length) throw new Error("numerator longer than denominator");
|
|
180
|
+
for (const s of lst1) {
|
|
181
|
+
if (typeof s != "string") throw new Error("one of numerator not string");
|
|
182
|
+
if (!s) throw new Error("empty string in numerator");
|
|
183
|
+
if (!lst2.includes(s)) throw new Error("one of numerator not in denominator");
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
export {
|
|
187
|
+
filterJoin,
|
|
188
|
+
getFilteredSamples,
|
|
189
|
+
getWrappedTvslst,
|
|
190
|
+
sample_match_termvaluesetting,
|
|
191
|
+
setDatasetAnnotations,
|
|
192
|
+
validateTermCollectionTvs
|
|
193
|
+
};
|
package/src/termdb.usecase.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TermTypes, isNumericTerm } from './terms.js'
|
|
1
|
+
import { TermTypes, isNumericTerm, SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION } from './terms.js'
|
|
2
2
|
|
|
3
3
|
export const graphableTypes = new Set([
|
|
4
4
|
'categorical',
|
|
@@ -20,8 +20,8 @@ export const graphableTypes = new Set([
|
|
|
20
20
|
TermTypes.DNA_METHYLATION,
|
|
21
21
|
TermTypes.METABOLITE_INTENSITY,
|
|
22
22
|
TermTypes.WHOLE_PROTEOME_ABUNDANCE,
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
SINGLECELL_GENE_EXPRESSION,
|
|
24
|
+
SINGLECELL_CELLTYPE,
|
|
25
25
|
TermTypes.SNP,
|
|
26
26
|
TermTypes.TERM_COLLECTION
|
|
27
27
|
])
|
|
@@ -114,14 +114,17 @@ export function isUsableTerm(term, _usecase, termdbConfig, ds) {
|
|
|
114
114
|
uses.add('plot')
|
|
115
115
|
}
|
|
116
116
|
if (hasNumericChild(child_types)) uses.add('branch')
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
117
|
+
}
|
|
118
|
+
// Commenting out for now. May need later for another single
|
|
119
|
+
// cell term. Revisit logic at that time.
|
|
120
|
+
// else if (usecase?.specialCase?.type == 'singleCell') {
|
|
121
|
+
// if (term.type && term.type.startsWith('singleCell')) {
|
|
122
|
+
// if (term.plot && term.plot == usecase.specialCase?.config.name) {
|
|
123
|
+
// uses.add('plot')
|
|
124
|
+
// }
|
|
125
|
+
// }
|
|
126
|
+
// }
|
|
127
|
+
else {
|
|
125
128
|
if (graphableTypes.has(term.type)) uses.add('plot')
|
|
126
129
|
if (!term.isleaf) uses.add('branch')
|
|
127
130
|
}
|
package/src/terms.js
CHANGED
|
@@ -28,29 +28,50 @@ export const NumericModes = {
|
|
|
28
28
|
discrete: 'discrete'
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export const CATEGORICAL = 'categorical'
|
|
32
|
+
export const CONDITION = 'condition'
|
|
33
|
+
export const DATE = 'date'
|
|
34
|
+
export const DNA_METHYLATION = 'dnaMethylation'
|
|
35
|
+
export const FLOAT = 'float'
|
|
36
|
+
export const GENE_VARIANT = 'geneVariant'
|
|
37
|
+
export const GENE_EXPRESSION = 'geneExpression'
|
|
38
|
+
export const INTEGER = 'integer'
|
|
39
|
+
export const METABOLITE_INTENSITY = 'metaboliteIntensity'
|
|
40
|
+
export const MULTIVALUE = 'multivalue'
|
|
41
|
+
export const SAMPLELST = 'samplelst'
|
|
42
|
+
export const SINGLECELL_CELLTYPE = 'singleCellCellType'
|
|
43
|
+
export const SINGLECELL_GENE_EXPRESSION = 'singleCellGeneExpression'
|
|
44
|
+
export const SNP = 'snp'
|
|
45
|
+
export const SNP_LIST = 'snplst'
|
|
46
|
+
export const SNP_LOCUS = 'snplocus'
|
|
47
|
+
export const SSGSEA = 'ssGSEA'
|
|
48
|
+
export const SURVIVAL = 'survival'
|
|
49
|
+
export const TERM_COLLECTION = 'termCollection'
|
|
50
|
+
export const WHOLE_PROTEOME_ABUNDANCE = 'wholeProteomeAbundance'
|
|
51
|
+
|
|
31
52
|
//Term types should be used gradually using these constants instead of hardcoding the values,
|
|
32
|
-
// eg: type ==
|
|
53
|
+
// eg: type == CATEGORICAL instead of type == 'categorical'
|
|
33
54
|
export const TermTypes = {
|
|
34
|
-
GENE_VARIANT
|
|
35
|
-
GENE_EXPRESSION
|
|
36
|
-
SSGSEA
|
|
37
|
-
DNA_METHYLATION
|
|
38
|
-
CATEGORICAL
|
|
39
|
-
INTEGER
|
|
40
|
-
FLOAT
|
|
41
|
-
SNP
|
|
42
|
-
SNP_LIST
|
|
43
|
-
SNP_LOCUS
|
|
44
|
-
CONDITION
|
|
45
|
-
SURVIVAL
|
|
46
|
-
SAMPLELST
|
|
47
|
-
METABOLITE_INTENSITY
|
|
48
|
-
WHOLE_PROTEOME_ABUNDANCE
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
MULTIVALUE
|
|
52
|
-
DATE
|
|
53
|
-
TERM_COLLECTION
|
|
55
|
+
GENE_VARIANT,
|
|
56
|
+
GENE_EXPRESSION,
|
|
57
|
+
SSGSEA,
|
|
58
|
+
DNA_METHYLATION,
|
|
59
|
+
CATEGORICAL,
|
|
60
|
+
INTEGER,
|
|
61
|
+
FLOAT,
|
|
62
|
+
SNP,
|
|
63
|
+
SNP_LIST,
|
|
64
|
+
SNP_LOCUS,
|
|
65
|
+
CONDITION,
|
|
66
|
+
SURVIVAL,
|
|
67
|
+
SAMPLELST,
|
|
68
|
+
METABOLITE_INTENSITY,
|
|
69
|
+
WHOLE_PROTEOME_ABUNDANCE,
|
|
70
|
+
SINGLECELL_CELLTYPE,
|
|
71
|
+
SINGLECELL_GENE_EXPRESSION,
|
|
72
|
+
MULTIVALUE,
|
|
73
|
+
DATE,
|
|
74
|
+
TERM_COLLECTION
|
|
54
75
|
}
|
|
55
76
|
export const dtTermTypes = new Set(dtTerms.map(t => t.type))
|
|
56
77
|
for (const dtTermType of dtTermTypes) {
|
|
@@ -60,75 +81,77 @@ for (const dtTermType of dtTermTypes) {
|
|
|
60
81
|
export const NUMERIC_DICTIONARY_TERM = 'numericDictTerm'
|
|
61
82
|
|
|
62
83
|
export const TermTypes2Dt = {
|
|
63
|
-
[
|
|
64
|
-
[
|
|
65
|
-
[
|
|
66
|
-
[
|
|
67
|
-
[
|
|
84
|
+
[GENE_EXPRESSION]: dtgeneexpression,
|
|
85
|
+
[SSGSEA]: dtssgsea,
|
|
86
|
+
[DNA_METHYLATION]: dtdnamethylation,
|
|
87
|
+
[METABOLITE_INTENSITY]: dtmetaboliteintensity,
|
|
88
|
+
[WHOLE_PROTEOME_ABUNDANCE]: dtwholeproteomeabundance
|
|
68
89
|
}
|
|
69
90
|
|
|
70
91
|
// maps term type to group (as is shown as toggles in search ui)
|
|
71
92
|
export const typeGroup = {
|
|
72
|
-
[
|
|
73
|
-
[
|
|
74
|
-
[
|
|
75
|
-
[
|
|
76
|
-
[
|
|
77
|
-
[
|
|
78
|
-
[
|
|
79
|
-
[
|
|
80
|
-
[
|
|
81
|
-
[
|
|
82
|
-
[
|
|
83
|
-
[
|
|
84
|
-
[
|
|
85
|
-
[
|
|
86
|
-
[
|
|
87
|
-
[
|
|
88
|
-
[
|
|
89
|
-
[
|
|
93
|
+
[CATEGORICAL]: TermTypeGroups.DICTIONARY_VARIABLES,
|
|
94
|
+
[CONDITION]: TermTypeGroups.DICTIONARY_VARIABLES,
|
|
95
|
+
[FLOAT]: TermTypeGroups.DICTIONARY_VARIABLES,
|
|
96
|
+
[INTEGER]: TermTypeGroups.DICTIONARY_VARIABLES,
|
|
97
|
+
[SAMPLELST]: TermTypeGroups.DICTIONARY_VARIABLES,
|
|
98
|
+
[SURVIVAL]: TermTypeGroups.DICTIONARY_VARIABLES,
|
|
99
|
+
[DATE]: TermTypeGroups.DICTIONARY_VARIABLES,
|
|
100
|
+
[GENE_VARIANT]: TermTypeGroups.MUTATION_CNV_FUSION,
|
|
101
|
+
[SNP]: TermTypeGroups.SNP,
|
|
102
|
+
[SNP_LIST]: TermTypeGroups.SNP_LIST,
|
|
103
|
+
[SNP_LOCUS]: TermTypeGroups.SNP_LOCUS,
|
|
104
|
+
[GENE_EXPRESSION]: TermTypeGroups.GENE_EXPRESSION,
|
|
105
|
+
[SSGSEA]: TermTypeGroups.SSGSEA,
|
|
106
|
+
[DNA_METHYLATION]: TermTypeGroups.DNA_METHYLATION,
|
|
107
|
+
[METABOLITE_INTENSITY]: TermTypeGroups.METABOLITE_INTENSITY,
|
|
108
|
+
[WHOLE_PROTEOME_ABUNDANCE]: TermTypeGroups.WHOLE_PROTEOME_ABUNDANCE,
|
|
109
|
+
[TERM_COLLECTION]: TermTypeGroups.TERM_COLLECTION,
|
|
110
|
+
[SINGLECELL_CELLTYPE]: TermTypeGroups.SINGLECELL_CELLTYPE,
|
|
111
|
+
[SINGLECELL_GENE_EXPRESSION]: TermTypeGroups.SINGLECELL_GENE_EXPRESSION
|
|
90
112
|
}
|
|
91
113
|
|
|
92
114
|
const nonDictTypes = new Set([
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
115
|
+
SNP,
|
|
116
|
+
SNP_LIST,
|
|
117
|
+
SNP_LOCUS,
|
|
118
|
+
GENE_EXPRESSION,
|
|
119
|
+
SSGSEA,
|
|
120
|
+
DNA_METHYLATION,
|
|
121
|
+
GENE_VARIANT,
|
|
122
|
+
METABOLITE_INTENSITY,
|
|
123
|
+
WHOLE_PROTEOME_ABUNDANCE,
|
|
124
|
+
SINGLECELL_CELLTYPE,
|
|
125
|
+
SINGLECELL_GENE_EXPRESSION
|
|
104
126
|
])
|
|
127
|
+
|
|
105
128
|
for (const dtTermType of dtTermTypes) {
|
|
106
129
|
nonDictTypes.add(TermTypes[dtTermType.toUpperCase()])
|
|
107
130
|
}
|
|
108
131
|
|
|
109
132
|
export const numericTypes = new Set([
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
133
|
+
INTEGER,
|
|
134
|
+
FLOAT,
|
|
135
|
+
GENE_EXPRESSION,
|
|
136
|
+
SSGSEA,
|
|
137
|
+
DNA_METHYLATION,
|
|
138
|
+
METABOLITE_INTENSITY,
|
|
139
|
+
WHOLE_PROTEOME_ABUNDANCE,
|
|
140
|
+
SINGLECELL_GENE_EXPRESSION,
|
|
141
|
+
DATE
|
|
119
142
|
])
|
|
120
143
|
|
|
121
144
|
// available termdb numeric table names used as anno_<term.type>,
|
|
122
145
|
// for example anno_integer, anno_float, anno_date
|
|
123
|
-
export const annoNumericTypes = new Set([
|
|
146
|
+
export const annoNumericTypes = new Set([INTEGER, FLOAT, DATE])
|
|
124
147
|
|
|
125
|
-
const categoricalTypes = new Set([
|
|
148
|
+
const categoricalTypes = new Set([CATEGORICAL, SNP])
|
|
126
149
|
|
|
127
|
-
const
|
|
150
|
+
const singleCellTerms = new Set([SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION])
|
|
128
151
|
|
|
129
|
-
export function
|
|
152
|
+
export function isSingleCellTerm(term) {
|
|
130
153
|
if (!term) return false
|
|
131
|
-
return
|
|
154
|
+
return singleCellTerms.has(term.type)
|
|
132
155
|
}
|
|
133
156
|
export function isNumericTerm(term) {
|
|
134
157
|
if (!term) return false
|
|
@@ -152,24 +175,24 @@ export function equals(t1, t2) {
|
|
|
152
175
|
if (!t1) throw new Error('First term is not defined ')
|
|
153
176
|
if (!t2) throw new Error('Second term is not defined ')
|
|
154
177
|
if (t1.type !== t2.type) return false //term types are different
|
|
155
|
-
if (isDictionaryType(t1.type) && isDictionaryType(t2.type) && t1.type !=
|
|
178
|
+
if (isDictionaryType(t1.type) && isDictionaryType(t2.type) && t1.type != SAMPLELST) return t1.id === t2.id
|
|
156
179
|
switch (t1.type) {
|
|
157
|
-
case
|
|
180
|
+
case GENE_EXPRESSION:
|
|
158
181
|
return t1.gene == t2.gene
|
|
159
|
-
case
|
|
182
|
+
case SSGSEA:
|
|
160
183
|
return t1.id == t2.id
|
|
161
|
-
case
|
|
184
|
+
case DNA_METHYLATION:
|
|
162
185
|
return t1.chr == t2.chr && t1.start == t2.start && t1.stop == t2.stop
|
|
163
|
-
case
|
|
164
|
-
case
|
|
186
|
+
case METABOLITE_INTENSITY:
|
|
187
|
+
case WHOLE_PROTEOME_ABUNDANCE:
|
|
165
188
|
return t1.name == t2.name
|
|
166
|
-
case
|
|
189
|
+
case GENE_VARIANT:
|
|
167
190
|
return t1.gene == t2.gene || (t1.chr == t2.chr && t1.start == t2.start && t1.stop == t2.stop)
|
|
168
191
|
|
|
169
192
|
// TO DO: Add more cases
|
|
170
|
-
// case
|
|
171
|
-
// case
|
|
172
|
-
// case
|
|
193
|
+
// case SNP_LIST:
|
|
194
|
+
// case SNP_LOCUS:
|
|
195
|
+
// case SAMPLELST:
|
|
173
196
|
|
|
174
197
|
default:
|
|
175
198
|
return false
|