@sjcrh/proteinpaint-shared 2.180.0 → 2.180.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 +2 -2
- package/src/bulk.cnv.js +30 -30
- package/src/bulk.del.js +48 -48
- package/src/bulk.itd.js +48 -48
- package/src/bulk.js +31 -31
- package/src/bulk.snv.js +109 -72
- package/src/bulk.sv.js +78 -78
- package/src/bulk.svjson.js +33 -31
- package/src/bulk.trunc.js +53 -47
- package/src/clustering.js +27 -27
- package/src/common.js +665 -558
- package/src/compute.percentile.js +3 -1
- package/src/fetch-helpers.js +67 -42
- package/src/fileSize.js +4 -4
- package/src/filter.js +207 -179
- package/src/hash.js +8 -5
- package/src/helpers.js +17 -9
- package/src/index.js +24 -24
- package/src/mds3tk.js +14 -12
- package/src/roundValue.js +5 -4
- package/src/termdb.bins.js +151 -84
- package/src/termdb.initbinconfig.js +46 -18
- package/src/termdb.usecase.js +125 -116
- package/src/terms.js +281 -266
- package/src/tree.js +4 -4
- package/src/vcf.ann.js +9 -9
- package/src/vcf.csq.js +8 -8
- package/src/vcf.info.js +3 -3
- package/src/vcf.js +99 -74
- package/src/vcf.type.js +8 -2
package/src/filter.js
CHANGED
|
@@ -1,193 +1,221 @@
|
|
|
1
1
|
function getFilteredSamples(sampleAnno, filter) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
|
12
12
|
}
|
|
13
|
-
function sample_match_termvaluesetting(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
13
|
+
function sample_match_termvaluesetting(
|
|
14
|
+
row,
|
|
15
|
+
filter,
|
|
16
|
+
_term = null,
|
|
17
|
+
sample = null
|
|
18
|
+
) {
|
|
19
|
+
const lst = filter.type == "tvslst" ? filter.lst : [filter]
|
|
20
|
+
let numberofmatchedterms = 0
|
|
21
|
+
for (const item of lst) {
|
|
22
|
+
if ("type" in item && item.type == "tvslst") {
|
|
23
|
+
if (sample_match_termvaluesetting(row, item, _term, sample)) {
|
|
24
|
+
numberofmatchedterms++
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
const itemCopy = JSON.parse(JSON.stringify(item))
|
|
28
|
+
const t = itemCopy.tvs
|
|
29
|
+
if (_term && t.term) {
|
|
30
|
+
if (!(_term.name == t.term.name && _term.type == t.term.type)) {
|
|
31
|
+
numberofmatchedterms++
|
|
32
|
+
continue
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
let samplevalue
|
|
36
|
+
if (_term && !t.term) {
|
|
37
|
+
if (t.term$type && t.term$type !== _term.type) {
|
|
38
|
+
numberofmatchedterms++
|
|
39
|
+
continue
|
|
40
|
+
}
|
|
41
|
+
t.term = _term
|
|
42
|
+
samplevalue =
|
|
43
|
+
typeof row === "object" && t.term.id in row ? row[t.term.id] : row
|
|
44
|
+
} else if (sample && t.term.$id) {
|
|
45
|
+
samplevalue = sample[t.term.$id].value
|
|
46
|
+
} else {
|
|
47
|
+
samplevalue = t.term.id in row ? row[t.term.id] : row
|
|
48
|
+
}
|
|
49
|
+
setDatasetAnnotations(itemCopy)
|
|
50
|
+
let thistermmatch
|
|
51
|
+
if (t.term.type == "categorical") {
|
|
52
|
+
if (samplevalue === void 0) continue
|
|
53
|
+
thistermmatch = t.valueset.has(samplevalue)
|
|
54
|
+
} else if (t.term.type == "integer" || t.term.type == "float") {
|
|
55
|
+
if (samplevalue === void 0) continue
|
|
56
|
+
for (const range of t.ranges) {
|
|
57
|
+
if ("value" in range) {
|
|
58
|
+
thistermmatch = samplevalue === range.value
|
|
59
|
+
if (thistermmatch) break
|
|
60
|
+
} else if (samplevalue == range.name) {
|
|
61
|
+
thistermmatch = true
|
|
62
|
+
break
|
|
63
|
+
} else {
|
|
64
|
+
if (t.term.values) {
|
|
65
|
+
const v = t.term.values[samplevalue.toString()]
|
|
66
|
+
if (v && v.uncomputable) {
|
|
67
|
+
continue
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
let left, right
|
|
71
|
+
if (range.startunbounded) {
|
|
72
|
+
left = true
|
|
73
|
+
} else if ("start" in range) {
|
|
74
|
+
if (range.startinclusive) {
|
|
75
|
+
left = samplevalue >= range.start
|
|
76
|
+
} else {
|
|
77
|
+
left = samplevalue > range.start
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (range.stopunbounded) {
|
|
81
|
+
right = true
|
|
82
|
+
} else if ("stop" in range) {
|
|
83
|
+
if (range.stopinclusive) {
|
|
84
|
+
right = samplevalue <= range.stop
|
|
85
|
+
} else {
|
|
86
|
+
right = samplevalue < range.stop
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
thistermmatch = left && right
|
|
90
|
+
}
|
|
91
|
+
if (thistermmatch) break
|
|
92
|
+
}
|
|
93
|
+
} else if (t.term.type == "condition") {
|
|
94
|
+
const key = getPrecomputedKey(t)
|
|
95
|
+
const anno = samplevalue && samplevalue[key]
|
|
96
|
+
if (anno) {
|
|
97
|
+
thistermmatch = Array.isArray(anno)
|
|
98
|
+
? t.values.find((d) => anno.includes(d.key))
|
|
99
|
+
: t.values.find((d) => d.key == anno)
|
|
100
|
+
}
|
|
101
|
+
} else if (t.term.type == "geneVariant") {
|
|
102
|
+
const svalues = samplevalue.values || [samplevalue]
|
|
103
|
+
for (const sv of svalues) {
|
|
104
|
+
thistermmatch =
|
|
105
|
+
t.values.find(
|
|
106
|
+
(v) =>
|
|
107
|
+
v.dt == sv.dt &&
|
|
108
|
+
(!v.origin || sv.origin == v.origin) &&
|
|
109
|
+
(!v.mclasslst || v.mclasslst.includes(sv.class))
|
|
110
|
+
) && true
|
|
111
|
+
if (thistermmatch) break
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
throw "unknown term type [sample_match_termvaluesetting() shared/utils/src/filter.ts]"
|
|
115
|
+
}
|
|
116
|
+
if (t.isnot) {
|
|
117
|
+
thistermmatch = !thistermmatch
|
|
118
|
+
}
|
|
119
|
+
if (thistermmatch) numberofmatchedterms++
|
|
120
|
+
}
|
|
121
|
+
if (filter.join == "or") {
|
|
122
|
+
if (numberofmatchedterms && filter.in) return true
|
|
123
|
+
if (!numberofmatchedterms && !filter.in) return true
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (!("in" in filter)) filter.in = true
|
|
127
|
+
return filter.in == (numberofmatchedterms == lst.length)
|
|
116
128
|
}
|
|
117
129
|
function setDatasetAnnotations(item, ds = null) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
if (item.type == "tvslst") {
|
|
131
|
+
for (const subitem of item.lst) {
|
|
132
|
+
setDatasetAnnotations(subitem, ds)
|
|
133
|
+
}
|
|
134
|
+
} else {
|
|
135
|
+
if (ds && typeof ds.setAnnoByTermId == "function") {
|
|
136
|
+
ds.setAnnoByTermId(item.tvs.term.id)
|
|
137
|
+
}
|
|
138
|
+
if (item.tvs.term.type == "categorical") {
|
|
139
|
+
const tvsAny = item.tvs
|
|
140
|
+
tvsAny.valueset = new Set(tvsAny.values.map((i) => i.key))
|
|
141
|
+
}
|
|
142
|
+
}
|
|
131
143
|
}
|
|
132
144
|
function getPrecomputedKey(q) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
145
|
+
const precomputedKey =
|
|
146
|
+
q.bar_by_children && q.value_by_max_grade
|
|
147
|
+
? "childrenAtMaxGrade"
|
|
148
|
+
: q.bar_by_children && q.value_by_most_recent
|
|
149
|
+
? "childrenAtMostRecent"
|
|
150
|
+
: q.bar_by_children && q.value_by_computable_grade
|
|
151
|
+
? "children"
|
|
152
|
+
: q.bar_by_grade && q.value_by_max_grade
|
|
153
|
+
? "maxGrade"
|
|
154
|
+
: q.bar_by_grade && q.value_by_most_recent
|
|
155
|
+
? "mostRecentGrades"
|
|
156
|
+
: q.bar_by_grade && q.value_by_computable_grade
|
|
157
|
+
? "computableGrades"
|
|
158
|
+
: ""
|
|
159
|
+
if (!precomputedKey) throw `unknown condition term bar_by_* and/or value_by_*`
|
|
160
|
+
return precomputedKey
|
|
136
161
|
}
|
|
137
162
|
function filterJoin(lst) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
+
if (!lst || lst.length == 0) return
|
|
164
|
+
let f = JSON.parse(JSON.stringify(lst[0]))
|
|
165
|
+
if (lst.length == 1) return f
|
|
166
|
+
if (f.lst.length < 2) {
|
|
167
|
+
if (f.join !== "")
|
|
168
|
+
throw 'filter.join must be an empty string "" when filter.lst.length < 2'
|
|
169
|
+
f.join = "and"
|
|
170
|
+
} else if (f.join == "or") {
|
|
171
|
+
f = {
|
|
172
|
+
type: "tvslst",
|
|
173
|
+
join: "and",
|
|
174
|
+
in: true,
|
|
175
|
+
lst: [f],
|
|
176
|
+
}
|
|
177
|
+
} else if (f.join != "and") {
|
|
178
|
+
throw 'filter.join must be either "and" or "or" when .lst length > 1'
|
|
179
|
+
}
|
|
180
|
+
for (let i = 1; i < lst.length; i++) {
|
|
181
|
+
const f2 = JSON.parse(JSON.stringify(lst[i]))
|
|
182
|
+
if (f2.join == "or") f.lst.push(f2)
|
|
183
|
+
else f.lst.push(...f2.lst)
|
|
184
|
+
}
|
|
185
|
+
if (f.lst.length == 1 && f.lst[0].type == "tvs") {
|
|
186
|
+
f.join = ""
|
|
187
|
+
}
|
|
188
|
+
return f
|
|
163
189
|
}
|
|
164
190
|
function getWrappedTvslst(lst = [], join = "", $id = null) {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
191
|
+
const filter = {
|
|
192
|
+
type: "tvslst",
|
|
193
|
+
in: true,
|
|
194
|
+
join,
|
|
195
|
+
lst,
|
|
196
|
+
}
|
|
197
|
+
if ($id !== null) filter.$id = $id
|
|
198
|
+
return filter
|
|
173
199
|
}
|
|
174
200
|
function validateTermCollectionTvs(lst1, lst2) {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
201
|
+
if (!Array.isArray(lst1)) throw new Error("numerator not array")
|
|
202
|
+
if (!Array.isArray(lst2)) throw new Error("denominator not array")
|
|
203
|
+
if (lst1.length == 0) throw new Error("numerator empty")
|
|
204
|
+
if (lst2.length == 0) throw new Error("denominator empty")
|
|
205
|
+
if (lst1.length > lst2.length)
|
|
206
|
+
throw new Error("numerator longer than denominator")
|
|
207
|
+
for (const s of lst1) {
|
|
208
|
+
if (typeof s != "string") throw new Error("one of numerator not string")
|
|
209
|
+
if (!s) throw new Error("empty string in numerator")
|
|
210
|
+
if (!lst2.includes(s))
|
|
211
|
+
throw new Error("one of numerator not in denominator")
|
|
212
|
+
}
|
|
185
213
|
}
|
|
186
214
|
export {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
215
|
+
filterJoin,
|
|
216
|
+
getFilteredSamples,
|
|
217
|
+
getWrappedTvslst,
|
|
218
|
+
sample_match_termvaluesetting,
|
|
219
|
+
setDatasetAnnotations,
|
|
220
|
+
validateTermCollectionTvs,
|
|
221
|
+
}
|
package/src/hash.js
CHANGED
|
@@ -2,17 +2,20 @@ const encoder = new TextEncoder()
|
|
|
2
2
|
|
|
3
3
|
export async function hash(message) {
|
|
4
4
|
const msgUint8 = encoder.encode(message) // encode as (utf-8) Uint8Array
|
|
5
|
-
const hashBuffer = await crypto.subtle.digest(
|
|
5
|
+
const hashBuffer = await crypto.subtle.digest("SHA-1", msgUint8) // hash the message
|
|
6
6
|
const hashArray = Array.from(new Uint8Array(hashBuffer)) // convert buffer to byte array
|
|
7
|
-
const hashHex = hashArray.map(b => b.toString(16).padStart(2,
|
|
8
|
-
return hexToBase64(hashHex).replace(
|
|
7
|
+
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("") // convert bytes to hex string
|
|
8
|
+
return hexToBase64(hashHex).replace("=", "-") // shorten from 40 to 28 chars
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
function hexToBase64(hexStr) {
|
|
12
12
|
return btoa(
|
|
13
13
|
[...hexStr].reduce(
|
|
14
|
-
(acc, _, i) =>
|
|
15
|
-
|
|
14
|
+
(acc, _, i) =>
|
|
15
|
+
(acc += !((i - 1) & 1)
|
|
16
|
+
? String.fromCharCode(parseInt(hexStr.substring(i - 1, i + 1), 16))
|
|
17
|
+
: ""),
|
|
18
|
+
""
|
|
16
19
|
)
|
|
17
20
|
)
|
|
18
21
|
}
|
package/src/helpers.js
CHANGED
|
@@ -9,14 +9,14 @@ this is a helper file with a collection of functions to be used in backend and c
|
|
|
9
9
|
|
|
10
10
|
// checks whether given argument n is Numeric, with option to cast from string
|
|
11
11
|
export function isNumeric(n) {
|
|
12
|
-
const v = typeof n !=
|
|
12
|
+
const v = typeof n != "string" || n === "" ? n : Number(n)
|
|
13
13
|
const f = parseFloat(n)
|
|
14
14
|
return !isNaN(f) && Number.isFinite(v) && v === f
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
// like isNumeric but does not cast from string
|
|
18
18
|
export function isStrictNumeric(n) {
|
|
19
|
-
return typeof n ===
|
|
19
|
+
return typeof n === "number" && Number.isFinite(n)
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// converts a value from a unit to another unit
|
|
@@ -26,24 +26,32 @@ export function convertUnits(v, fromUnit, toUnit, scaleFactor, compact) {
|
|
|
26
26
|
if (scaleFactor >= 1) {
|
|
27
27
|
const toUnitV = Math.floor(v * scaleFactor)
|
|
28
28
|
if (compact) return `${toUnitV}${toUnit.charAt(0)}`
|
|
29
|
-
return `${toUnitV} ${toUnitV > 1 ? toUnit +
|
|
29
|
+
return `${toUnitV} ${toUnitV > 1 ? toUnit + "s" : ""}`
|
|
30
30
|
}
|
|
31
31
|
const toUnitV = Math.floor(v * scaleFactor)
|
|
32
32
|
const fromUnitV = Math.ceil(v % (1 / scaleFactor))
|
|
33
33
|
|
|
34
34
|
if (fromUnitV == 0) {
|
|
35
35
|
if (compact) return `${toUnitV}${toUnit.charAt(0)}`
|
|
36
|
-
return `${toUnitV} ${toUnitV > 1 ? toUnit +
|
|
36
|
+
return `${toUnitV} ${toUnitV > 1 ? toUnit + "s" : ""}`
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
if (compact)
|
|
40
|
-
|
|
39
|
+
if (compact)
|
|
40
|
+
return `${toUnitV}${toUnit.charAt(0)}${fromUnitV}${fromUnit.charAt(0)}`
|
|
41
|
+
return `${toUnitV} ${toUnitV > 1 ? toUnit + "s" : toUnit} ${fromUnitV} ${
|
|
42
|
+
fromUnitV > 1 ? fromUnit + "s" : fromUnit
|
|
43
|
+
}`
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
export function deepEqual(x, y) {
|
|
44
47
|
if (x === y) {
|
|
45
48
|
return true
|
|
46
|
-
} else if (
|
|
49
|
+
} else if (
|
|
50
|
+
typeof x == "object" &&
|
|
51
|
+
x != null &&
|
|
52
|
+
typeof y == "object" &&
|
|
53
|
+
y != null
|
|
54
|
+
) {
|
|
47
55
|
if (Object.keys(x).length != Object.keys(y).length) {
|
|
48
56
|
return false
|
|
49
57
|
}
|
|
@@ -63,13 +71,13 @@ export function deepFreeze(obj) {
|
|
|
63
71
|
Object.freeze(obj)
|
|
64
72
|
// not using for..in loop, in order to not descend into inherited props/methods
|
|
65
73
|
for (const value of Object.values(obj)) {
|
|
66
|
-
if (value !== null && typeof value ==
|
|
74
|
+
if (value !== null && typeof value == "object") deepFreeze(value)
|
|
67
75
|
}
|
|
68
76
|
return obj
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
export class CustomError extends Error {
|
|
72
|
-
level =
|
|
80
|
+
level = "" // '' | 'warn'
|
|
73
81
|
|
|
74
82
|
constructor(message, opts = {}) {
|
|
75
83
|
super(message)
|
package/src/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
// please list in alphanumeric order
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
8
|
-
export * from
|
|
9
|
-
export * from
|
|
10
|
-
export * from
|
|
11
|
-
export * from
|
|
12
|
-
export * from
|
|
13
|
-
export * from
|
|
14
|
-
export * from
|
|
15
|
-
export * from
|
|
16
|
-
export * from
|
|
17
|
-
export * from
|
|
18
|
-
export * from
|
|
19
|
-
export * from
|
|
2
|
+
export * from "./bulk.js"
|
|
3
|
+
export * from "./clustering.js"
|
|
4
|
+
export * from "./common.js"
|
|
5
|
+
export * from "./compute.percentile.js"
|
|
6
|
+
export * from "./fetch-helpers.js"
|
|
7
|
+
export * from "./fileSize.js"
|
|
8
|
+
export * from "./filter.js"
|
|
9
|
+
export * from "./hash.js"
|
|
10
|
+
export * from "./helpers.js"
|
|
11
|
+
export * from "./joinUrl.js"
|
|
12
|
+
export * from "./mds3tk.js"
|
|
13
|
+
export * from "./roundValue.js"
|
|
14
|
+
export * from "./termdb.bins.js"
|
|
15
|
+
export * from "./termdb.initbinconfig.js"
|
|
16
|
+
export * from "./termdb.usecase.js"
|
|
17
|
+
export * from "./terms.js"
|
|
18
|
+
export * from "./time.js"
|
|
19
|
+
export * from "./tree.js"
|
|
20
20
|
// do `npm run esm` to generate .js file from .ts file
|
|
21
|
-
export * from
|
|
22
|
-
export * from
|
|
23
|
-
export * from
|
|
24
|
-
export * from
|
|
25
|
-
export * from
|
|
26
|
-
export * from
|
|
21
|
+
export * from "./urljson.js"
|
|
22
|
+
export * from "./vcf.ann.js"
|
|
23
|
+
export * from "./vcf.csq.js"
|
|
24
|
+
export * from "./vcf.info.js"
|
|
25
|
+
export * from "./vcf.js"
|
|
26
|
+
export * from "./vcf.type.js"
|
package/src/mds3tk.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { dtcnv, dtsnvindel, dtsv, dtfusionrna } from
|
|
1
|
+
import { dtcnv, dtsnvindel, dtsv, dtfusionrna } from "./common.js"
|
|
2
2
|
|
|
3
3
|
// this script should contain mds3 track-related stuff shared between client and backend
|
|
4
4
|
|
|
@@ -15,7 +15,7 @@ svfusion: dt + chr + pos + strand + pairlstidx + mname
|
|
|
15
15
|
|
|
16
16
|
the separator must avoid conflicting with characters from gene names, and can be changed based on needs
|
|
17
17
|
*/
|
|
18
|
-
export const ssmIdFieldsSeparator =
|
|
18
|
+
export const ssmIdFieldsSeparator = "__"
|
|
19
19
|
|
|
20
20
|
/*
|
|
21
21
|
input: array of mixture of ssm, svfusion and cnv
|
|
@@ -59,7 +59,7 @@ export function guessSsmid(ssmid) {
|
|
|
59
59
|
if (l.length == 4) {
|
|
60
60
|
const [chr, tmp, ref, alt] = l
|
|
61
61
|
const pos = Number(tmp)
|
|
62
|
-
if (Number.isNaN(pos)) throw
|
|
62
|
+
if (Number.isNaN(pos)) throw "ssmid snvindel pos not integer"
|
|
63
63
|
return { dt: dtsnvindel, l: [chr, pos, ref, alt] }
|
|
64
64
|
}
|
|
65
65
|
if (l.length == 5) {
|
|
@@ -67,32 +67,34 @@ export function guessSsmid(ssmid) {
|
|
|
67
67
|
const [chr, _start, _stop, _class, _value] = l
|
|
68
68
|
const start = Number(_start),
|
|
69
69
|
stop = Number(_stop),
|
|
70
|
-
value = _value ==
|
|
71
|
-
if (Number.isNaN(start) || Number.isNaN(stop))
|
|
70
|
+
value = _value == "" ? null : Number(_value)
|
|
71
|
+
if (Number.isNaN(start) || Number.isNaN(stop))
|
|
72
|
+
throw "ssmid cnv start/stop not integer"
|
|
72
73
|
return { dt: dtcnv, l: [chr, start, stop, _class, value] }
|
|
73
74
|
}
|
|
74
75
|
if (l.length == 6) {
|
|
75
|
-
if (l[3] ==
|
|
76
|
+
if (l[3] == "+" || l[3] == "-") {
|
|
76
77
|
// sv/fusion
|
|
77
78
|
const [_dt, chr, _pos, strand, _pi, _mname] = l
|
|
78
79
|
|
|
79
80
|
// mname is encoded in case it contains comma (and is same as ssmIdFieldsSeparator)
|
|
80
81
|
const mname = decodeURIComponent(_mname)
|
|
81
82
|
const dt = Number(_dt)
|
|
82
|
-
if (dt != dtsv && dt != dtfusionrna) throw
|
|
83
|
+
if (dt != dtsv && dt != dtfusionrna) throw "ssmid dt not sv/fusion"
|
|
83
84
|
const pos = Number(_pos)
|
|
84
|
-
if (Number.isNaN(pos)) throw
|
|
85
|
+
if (Number.isNaN(pos)) throw "ssmid svfusion position not integer"
|
|
85
86
|
const pairlstIdx = Number(_pi)
|
|
86
|
-
if (Number.isNaN(pairlstIdx)) throw
|
|
87
|
+
if (Number.isNaN(pairlstIdx)) throw "ssmid pairlstIdx not integer"
|
|
87
88
|
return { dt, l: [dt, chr, pos, strand, pairlstIdx, mname] }
|
|
88
89
|
}
|
|
89
90
|
// cnv with sample
|
|
90
91
|
const [chr, _start, _stop, _class, _value, sample] = l
|
|
91
92
|
const start = Number(_start),
|
|
92
93
|
stop = Number(_stop),
|
|
93
|
-
value = _value ==
|
|
94
|
-
if (Number.isNaN(start) || Number.isNaN(stop))
|
|
94
|
+
value = _value == "" ? null : Number(_value) // if cnv not using value, must avoid `Number('')=0`
|
|
95
|
+
if (Number.isNaN(start) || Number.isNaN(stop))
|
|
96
|
+
throw "ssmid cnv start/stop not integer"
|
|
95
97
|
return { dt: dtcnv, l: [chr, start, stop, _class, value, sample] }
|
|
96
98
|
}
|
|
97
|
-
throw
|
|
99
|
+
throw "unknown ssmid"
|
|
98
100
|
}
|