@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 CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "@sjcrh/proteinpaint-shared",
3
- "version": "2.178.0",
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
- sampleAnno[anno{}] array of sample annotations
3
- anno.sample
4
- - string or number sample name
5
-
6
- anno.s || anno.data
7
- - the annotation object {[key1]: value1, ...}
8
-
9
- filter: nested filter structure as used in the termdbapp, see docs
10
- */
11
- export function getFilteredSamples(sampleAnno, filter) {
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
- given a value from a sample's anno of a term, return true if a value matches the filter
27
- */
28
- export function sample_match_termvaluesetting(row, filter, _term = null, sample = null) {
29
- const lst = filter.type == 'tvslst' ? filter.lst : [filter]
30
- let numberofmatchedterms = 0
31
-
32
- /* for AND, require all terms to match */
33
- for (const item of lst) {
34
- if (item.type == 'tvslst') {
35
- if (sample_match_termvaluesetting(row, item, _term, sample)) {
36
- numberofmatchedterms++
37
- }
38
- } else {
39
- const itemCopy = JSON.parse(JSON.stringify(item))
40
- const t = itemCopy.tvs
41
-
42
- if (_term && t.term) {
43
- if (!(_term.name == t.term.name && _term.type == t.term.type)) {
44
- // for an filter from "this.config.legendValueFilter", if the filter is not for the tw
45
- // (not the same type and name), ignore the filter.
46
- numberofmatchedterms++
47
- continue
48
- }
49
- }
50
-
51
- let samplevalue
52
- if (_term && !t.term) {
53
- if (t.term$type && t.term$type !== _term.type) {
54
- //when the filter is not for the term being tested, ignore the filter
55
- numberofmatchedterms++
56
- continue
57
- }
58
- t.term = _term
59
- samplevalue = typeof row === 'object' && t.term.id in row ? row[t.term.id] : row //'tumorWES'
60
- } else if (sample && t.term.$id) {
61
- samplevalue = sample[t.term.$id].value
62
- } else {
63
- samplevalue = t.term.id in row ? row[t.term.id] : row
64
- }
65
- setDatasetAnnotations(itemCopy)
66
- let thistermmatch
67
-
68
- if (t.term.type == 'categorical') {
69
- if (samplevalue === undefined) continue // this sample has no anno for this term, do not count
70
- thistermmatch = t.valueset.has(samplevalue)
71
- } else if (t.term.type == 'integer' || t.term.type == 'float') {
72
- if (samplevalue === undefined) continue // this sample has no anno for this term, do not count
73
- for (const range of t.ranges) {
74
- if ('value' in range) {
75
- thistermmatch = samplevalue === range.value // || ""+samplevalue == range.value || samplevalue == ""+range.value //; if (thistermmatch) console.log(i++)
76
- if (thistermmatch) break
77
- } else if (samplevalue == range.name) {
78
- thistermmatch = true
79
- break
80
- } else {
81
- // actual range
82
- if (t.term.values) {
83
- const v = t.term.values[samplevalue.toString()]
84
- if (v && v.uncomputable) {
85
- continue
86
- }
87
- }
88
- let left, right
89
- if (range.startunbounded) {
90
- left = true
91
- } else if ('start' in range) {
92
- if (range.startinclusive) {
93
- left = samplevalue >= range.start
94
- } else {
95
- left = samplevalue > range.start
96
- }
97
- }
98
- if (range.stopunbounded) {
99
- right = true
100
- } else if ('stop' in range) {
101
- if (range.stopinclusive) {
102
- right = samplevalue <= range.stop
103
- } else {
104
- right = samplevalue < range.stop
105
- }
106
- }
107
- thistermmatch = left && right
108
- }
109
- if (thistermmatch) break
110
- }
111
- } else if (t.term.type == 'condition') {
112
- const key = getPrecomputedKey(t)
113
- const anno = samplevalue && samplevalue[key]
114
- if (anno) {
115
- thistermmatch = Array.isArray(anno)
116
- ? t.values.find(d => anno.includes(d.key))
117
- : t.values.find(d => d.key == anno)
118
- }
119
- } else if (t.term.type == 'geneVariant') {
120
- /*
121
- samplevalue.values here can be an array or only one of the entries
122
- [
123
- { dt: 1, class: 'WT', _SAMPLEID_: 21, origin: 'germline' },
124
- { dt: 1, class: 'WT', _SAMPLEID_: 21, origin: 'somatic' },
125
- { dt: 2, class: 'Blank', _SAMPLEID_: 21 },
126
- { dt: 4, class: 'WT', _SAMPLEID_: 21 }
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
- export function setDatasetAnnotations(item, ds = null) {
171
- if (item.type == 'tvslst') {
172
- for (const subitem of item.lst) {
173
- setDatasetAnnotations(subitem, ds)
174
- }
175
- } else {
176
- if (ds && typeof ds.setAnnoByTermId == 'function') {
177
- ds.setAnnoByTermId(item.tvs.term.id)
178
- }
179
- if (item.tvs.term.type == 'categorical') {
180
- item.tvs.valueset = new Set(item.tvs.values.map(i => i.key))
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
- const precomputedKey =
187
- q.bar_by_children && q.value_by_max_grade
188
- ? 'childrenAtMaxGrade'
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
- /* join a list of filters into the first filter with "and", return joined filter
205
- to be used by caller app to join hidden filters into a visible filter
206
-
207
- lst:[]
208
- a list of filters
209
- the function returns a (modified) copy of the first filter, and will not modify it
210
- rest of the array will be joined to the first one under "and"
211
- */
212
- export function filterJoin(lst) {
213
- if (!lst || lst.length == 0) return
214
- let f = JSON.parse(JSON.stringify(lst[0]))
215
- if (lst.length == 1) return f
216
- // more than 1 item, will join
217
- if (f.lst.length < 2) {
218
- if (f.join !== '') throw 'filter.join must be an empty string "" when filter.lst.length < 2'
219
- f.join = 'and'
220
- } else if (f.join == 'or') {
221
- // f is "or", wrap it with another root layer of "and"
222
- f = {
223
- type: 'tvslst',
224
- join: 'and',
225
- in: true,
226
- lst: [f]
227
- }
228
- } else if (f.join != 'and') {
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
- export function getWrappedTvslst(lst = [], join = '', $id = null) {
247
- const filter = {
248
- type: 'tvslst',
249
- in: true,
250
- join,
251
- lst
252
- }
253
- if ($id !== null && filter.$id !== undefined) filter.$id = $id
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
+ };
@@ -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
- TermTypes.SINGLECELL_GENE_EXPRESSION,
24
- TermTypes.SINGLECELL_CELLTYPE,
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
- } else if (usecase?.vocab?.type == 'singleCell') {
118
- /** TODO: Revisit this approach. Seems chaotic. */
119
- if (term.type && term.type.startsWith('singleCell')) {
120
- if (term.plot && term.plot == usecase.vocab?.config.name) {
121
- uses.add('plot')
122
- }
123
- }
124
- } else {
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 == TermTypes.CATEGORICAL instead of type == 'categorical'
53
+ // eg: type == CATEGORICAL instead of type == 'categorical'
33
54
  export const TermTypes = {
34
- GENE_VARIANT: 'geneVariant',
35
- GENE_EXPRESSION: 'geneExpression',
36
- SSGSEA: 'ssGSEA',
37
- DNA_METHYLATION: 'dnaMethylation',
38
- CATEGORICAL: 'categorical',
39
- INTEGER: 'integer',
40
- FLOAT: 'float',
41
- SNP: 'snp',
42
- SNP_LIST: 'snplst',
43
- SNP_LOCUS: 'snplocus',
44
- CONDITION: 'condition',
45
- SURVIVAL: 'survival',
46
- SAMPLELST: 'samplelst',
47
- METABOLITE_INTENSITY: 'metaboliteIntensity',
48
- WHOLE_PROTEOME_ABUNDANCE: 'wholeProteomeAbundance',
49
- SINGLECELL_GENE_EXPRESSION: 'singleCellGeneExpression',
50
- SINGLECELL_CELLTYPE: 'singleCellCellType',
51
- MULTIVALUE: 'multivalue',
52
- DATE: 'date',
53
- TERM_COLLECTION: 'termCollection'
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
- [TermTypes.GENE_EXPRESSION]: dtgeneexpression,
64
- [TermTypes.SSGSEA]: dtssgsea,
65
- [TermTypes.DNA_METHYLATION]: dtdnamethylation,
66
- [TermTypes.METABOLITE_INTENSITY]: dtmetaboliteintensity,
67
- [TermTypes.WHOLE_PROTEOME_ABUNDANCE]: dtwholeproteomeabundance
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
- [TermTypes.CATEGORICAL]: TermTypeGroups.DICTIONARY_VARIABLES,
73
- [TermTypes.CONDITION]: TermTypeGroups.DICTIONARY_VARIABLES,
74
- [TermTypes.FLOAT]: TermTypeGroups.DICTIONARY_VARIABLES,
75
- [TermTypes.INTEGER]: TermTypeGroups.DICTIONARY_VARIABLES,
76
- [TermTypes.SAMPLELST]: TermTypeGroups.DICTIONARY_VARIABLES,
77
- [TermTypes.SURVIVAL]: TermTypeGroups.DICTIONARY_VARIABLES,
78
- [TermTypes.GENE_VARIANT]: TermTypeGroups.MUTATION_CNV_FUSION,
79
- [TermTypes.SNP]: TermTypeGroups.SNP,
80
- [TermTypes.SNP_LIST]: TermTypeGroups.SNP_LIST,
81
- [TermTypes.SNP_LOCUS]: TermTypeGroups.SNP_LOCUS,
82
- [TermTypes.GENE_EXPRESSION]: TermTypeGroups.GENE_EXPRESSION,
83
- [TermTypes.SSGSEA]: TermTypeGroups.SSGSEA,
84
- [TermTypes.DNA_METHYLATION]: TermTypeGroups.DNA_METHYLATION,
85
- [TermTypes.METABOLITE_INTENSITY]: TermTypeGroups.METABOLITE_INTENSITY,
86
- [TermTypes.WHOLE_PROTEOME_ABUNDANCE]: TermTypeGroups.WHOLE_PROTEOME_ABUNDANCE,
87
- [TermTypes.TERM_COLLECTION]: TermTypeGroups.TERM_COLLECTION,
88
- [TermTypes.SINGLECELL_CELLTYPE]: TermTypeGroups.SINGLECELL_CELLTYPE,
89
- [TermTypes.SINGLECELL_GENE_EXPRESSION]: TermTypeGroups.SINGLECELL_GENE_EXPRESSION
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
- TermTypes.SNP,
94
- TermTypes.SNP_LIST,
95
- TermTypes.SNP_LOCUS,
96
- TermTypes.GENE_EXPRESSION,
97
- TermTypes.SSGSEA,
98
- TermTypes.DNA_METHYLATION,
99
- TermTypes.GENE_VARIANT,
100
- TermTypes.METABOLITE_INTENSITY,
101
- TermTypes.WHOLE_PROTEOME_ABUNDANCE,
102
- TermTypes.SINGLECELL_GENE_EXPRESSION,
103
- TermTypes.SINGLECELL_CELLTYPE
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
- TermTypes.INTEGER,
111
- TermTypes.FLOAT,
112
- TermTypes.GENE_EXPRESSION,
113
- TermTypes.SSGSEA,
114
- TermTypes.DNA_METHYLATION,
115
- TermTypes.METABOLITE_INTENSITY,
116
- TermTypes.WHOLE_PROTEOME_ABUNDANCE,
117
- TermTypes.SINGLECELL_GENE_EXPRESSION,
118
- TermTypes.DATE
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([TermTypes.INTEGER, TermTypes.FLOAT, TermTypes.DATE])
146
+ export const annoNumericTypes = new Set([INTEGER, FLOAT, DATE])
124
147
 
125
- const categoricalTypes = new Set([TermTypes.CATEGORICAL, TermTypes.SNP])
148
+ const categoricalTypes = new Set([CATEGORICAL, SNP])
126
149
 
127
- const singleSampleTerms = new Set([TermTypes.SINGLECELL_CELLTYPE, TermTypes.SINGLECELL_GENE_EXPRESSION])
150
+ const singleCellTerms = new Set([SINGLECELL_CELLTYPE, SINGLECELL_GENE_EXPRESSION])
128
151
 
129
- export function isSingleSampleTerm(term) {
152
+ export function isSingleCellTerm(term) {
130
153
  if (!term) return false
131
- return singleSampleTerms.has(term.type)
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 != TermTypes.SAMPLELST) return t1.id === t2.id
178
+ if (isDictionaryType(t1.type) && isDictionaryType(t2.type) && t1.type != SAMPLELST) return t1.id === t2.id
156
179
  switch (t1.type) {
157
- case TermTypes.GENE_EXPRESSION:
180
+ case GENE_EXPRESSION:
158
181
  return t1.gene == t2.gene
159
- case TermTypes.SSGSEA:
182
+ case SSGSEA:
160
183
  return t1.id == t2.id
161
- case TermTypes.DNA_METHYLATION:
184
+ case DNA_METHYLATION:
162
185
  return t1.chr == t2.chr && t1.start == t2.start && t1.stop == t2.stop
163
- case TermTypes.METABOLITE_INTENSITY:
164
- case TermTypes.WHOLE_PROTEOME_ABUNDANCE:
186
+ case METABOLITE_INTENSITY:
187
+ case WHOLE_PROTEOME_ABUNDANCE:
165
188
  return t1.name == t2.name
166
- case TermTypes.GENE_VARIANT:
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 TermTypes.SNP_LIST:
171
- // case TermTypes.SNP_LOCUS:
172
- // case TermTypes.SAMPLELST:
193
+ // case SNP_LIST:
194
+ // case SNP_LOCUS:
195
+ // case SAMPLELST:
173
196
 
174
197
  default:
175
198
  return false