@gmod/bam 1.1.18 → 2.0.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/CHANGELOG.md +66 -25
- package/README.md +95 -57
- package/dist/bai.d.ts +34 -15
- package/dist/bai.js +87 -91
- package/dist/bai.js.map +1 -1
- package/dist/bamFile.d.ts +33 -27
- package/dist/bamFile.js +132 -130
- package/dist/bamFile.js.map +1 -1
- package/dist/chunk.d.ts +4 -8
- package/dist/chunk.js +2 -8
- package/dist/chunk.js.map +1 -1
- package/dist/csi.d.ts +74 -10
- package/dist/csi.js +78 -90
- package/dist/csi.js.map +1 -1
- package/dist/htsget.d.ts +5 -8
- package/dist/htsget.js +75 -49
- package/dist/htsget.js.map +1 -1
- package/dist/index.d.ts +5 -6
- package/dist/index.js +11 -11
- package/dist/index.js.map +1 -1
- package/dist/indexFile.d.ts +0 -6
- package/dist/indexFile.js +0 -35
- package/dist/indexFile.js.map +1 -1
- package/dist/nullIndex.d.ts +7 -0
- package/dist/nullIndex.js +33 -0
- package/dist/nullIndex.js.map +1 -0
- package/dist/record.d.ts +2 -2
- package/dist/record.js +34 -25
- package/dist/record.js.map +1 -1
- package/dist/sam.js +11 -7
- package/dist/sam.js.map +1 -1
- package/dist/util.d.ts +13 -1
- package/dist/util.js +47 -15
- package/dist/util.js.map +1 -1
- package/dist/virtualOffset.js.map +1 -1
- package/esm/bai.d.ts +34 -15
- package/esm/bai.js +86 -91
- package/esm/bai.js.map +1 -1
- package/esm/bamFile.d.ts +33 -27
- package/esm/bamFile.js +124 -120
- package/esm/bamFile.js.map +1 -1
- package/esm/chunk.d.ts +4 -8
- package/esm/chunk.js +2 -8
- package/esm/chunk.js.map +1 -1
- package/esm/csi.d.ts +74 -10
- package/esm/csi.js +85 -93
- package/esm/csi.js.map +1 -1
- package/esm/htsget.d.ts +5 -8
- package/esm/htsget.js +68 -43
- package/esm/htsget.js.map +1 -1
- package/esm/index.d.ts +5 -6
- package/esm/index.js +5 -6
- package/esm/index.js.map +1 -1
- package/esm/indexFile.d.ts +0 -6
- package/esm/indexFile.js +0 -22
- package/esm/indexFile.js.map +1 -1
- package/esm/nullIndex.d.ts +7 -0
- package/esm/nullIndex.js +16 -0
- package/esm/nullIndex.js.map +1 -0
- package/esm/record.d.ts +2 -2
- package/esm/record.js +34 -25
- package/esm/record.js.map +1 -1
- package/esm/sam.js +11 -7
- package/esm/sam.js.map +1 -1
- package/esm/util.d.ts +13 -1
- package/esm/util.js +40 -14
- package/esm/util.js.map +1 -1
- package/esm/virtualOffset.js.map +1 -1
- package/package.json +19 -21
- package/src/bai.ts +99 -102
- package/src/bamFile.ts +174 -198
- package/src/chunk.ts +6 -20
- package/src/csi.ts +102 -111
- package/src/htsget.ts +81 -61
- package/src/index.ts +5 -7
- package/src/indexFile.ts +0 -27
- package/src/nullIndex.ts +18 -0
- package/src/record.ts +34 -25
- package/src/sam.ts +11 -7
- package/src/util.ts +54 -13
- package/src/declare.d.ts +0 -2
package/src/record.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2
1
|
import Constants from './constants'
|
|
3
2
|
|
|
4
3
|
const SEQRET_DECODER = '=ACMGRSVTWYHKDBN'.split('')
|
|
@@ -83,11 +82,11 @@ export default class BamRecord {
|
|
|
83
82
|
}
|
|
84
83
|
tags = tags.concat(this._tagList || [])
|
|
85
84
|
|
|
86
|
-
Object.keys(this.data)
|
|
85
|
+
for (const k of Object.keys(this.data)) {
|
|
87
86
|
if (k[0] !== '_' && k !== 'next_seq_id') {
|
|
88
87
|
tags.push(k)
|
|
89
88
|
}
|
|
90
|
-
}
|
|
89
|
+
}
|
|
91
90
|
|
|
92
91
|
const seen: { [key: string]: boolean } = {}
|
|
93
92
|
return tags.filter(t => {
|
|
@@ -107,7 +106,7 @@ export default class BamRecord {
|
|
|
107
106
|
}
|
|
108
107
|
|
|
109
108
|
parent() {
|
|
110
|
-
return
|
|
109
|
+
return
|
|
111
110
|
}
|
|
112
111
|
|
|
113
112
|
children() {
|
|
@@ -137,7 +136,7 @@ export default class BamRecord {
|
|
|
137
136
|
|
|
138
137
|
qualRaw() {
|
|
139
138
|
if (this.isSegmentUnmapped()) {
|
|
140
|
-
return
|
|
139
|
+
return
|
|
141
140
|
}
|
|
142
141
|
|
|
143
142
|
const { start, byteArray } = this.bytes
|
|
@@ -157,7 +156,7 @@ export default class BamRecord {
|
|
|
157
156
|
|
|
158
157
|
multi_segment_next_segment_strand() {
|
|
159
158
|
if (this.isMateUnmapped()) {
|
|
160
|
-
return
|
|
159
|
+
return
|
|
161
160
|
}
|
|
162
161
|
return this.isMateReverseComplemented() ? -1 : 1
|
|
163
162
|
}
|
|
@@ -181,7 +180,7 @@ export default class BamRecord {
|
|
|
181
180
|
// called, we already know that we have no such tag, because
|
|
182
181
|
// it would already have been cached.
|
|
183
182
|
if (this._allTagsParsed) {
|
|
184
|
-
return
|
|
183
|
+
return
|
|
185
184
|
}
|
|
186
185
|
|
|
187
186
|
const { byteArray, start } = this.bytes
|
|
@@ -204,40 +203,48 @@ export default class BamRecord {
|
|
|
204
203
|
|
|
205
204
|
let value
|
|
206
205
|
switch (type) {
|
|
207
|
-
case 'A':
|
|
206
|
+
case 'A': {
|
|
208
207
|
value = String.fromCharCode(byteArray[p])
|
|
209
208
|
p += 1
|
|
210
209
|
break
|
|
211
|
-
|
|
210
|
+
}
|
|
211
|
+
case 'i': {
|
|
212
212
|
value = byteArray.readInt32LE(p)
|
|
213
213
|
p += 4
|
|
214
214
|
break
|
|
215
|
-
|
|
215
|
+
}
|
|
216
|
+
case 'I': {
|
|
216
217
|
value = byteArray.readUInt32LE(p)
|
|
217
218
|
p += 4
|
|
218
219
|
break
|
|
219
|
-
|
|
220
|
+
}
|
|
221
|
+
case 'c': {
|
|
220
222
|
value = byteArray.readInt8(p)
|
|
221
223
|
p += 1
|
|
222
224
|
break
|
|
223
|
-
|
|
225
|
+
}
|
|
226
|
+
case 'C': {
|
|
224
227
|
value = byteArray.readUInt8(p)
|
|
225
228
|
p += 1
|
|
226
229
|
break
|
|
227
|
-
|
|
230
|
+
}
|
|
231
|
+
case 's': {
|
|
228
232
|
value = byteArray.readInt16LE(p)
|
|
229
233
|
p += 2
|
|
230
234
|
break
|
|
231
|
-
|
|
235
|
+
}
|
|
236
|
+
case 'S': {
|
|
232
237
|
value = byteArray.readUInt16LE(p)
|
|
233
238
|
p += 2
|
|
234
239
|
break
|
|
235
|
-
|
|
240
|
+
}
|
|
241
|
+
case 'f': {
|
|
236
242
|
value = byteArray.readFloatLE(p)
|
|
237
243
|
p += 4
|
|
238
244
|
break
|
|
245
|
+
}
|
|
239
246
|
case 'Z':
|
|
240
|
-
case 'H':
|
|
247
|
+
case 'H': {
|
|
241
248
|
value = ''
|
|
242
249
|
while (p <= blockEnd) {
|
|
243
250
|
const cc = byteArray[p++]
|
|
@@ -248,6 +255,7 @@ export default class BamRecord {
|
|
|
248
255
|
}
|
|
249
256
|
}
|
|
250
257
|
break
|
|
258
|
+
}
|
|
251
259
|
case 'B': {
|
|
252
260
|
value = ''
|
|
253
261
|
const cc = byteArray[p++]
|
|
@@ -339,10 +347,11 @@ export default class BamRecord {
|
|
|
339
347
|
}
|
|
340
348
|
break
|
|
341
349
|
}
|
|
342
|
-
default:
|
|
350
|
+
default: {
|
|
343
351
|
console.warn(`Unknown BAM tag type '${type}', tags may be incomplete`)
|
|
344
352
|
value = undefined
|
|
345
|
-
p = blockEnd
|
|
353
|
+
p = blockEnd
|
|
354
|
+
} // stop parsing tags
|
|
346
355
|
}
|
|
347
356
|
|
|
348
357
|
this._tagOffset = p
|
|
@@ -355,7 +364,7 @@ export default class BamRecord {
|
|
|
355
364
|
this.data[lcTag] = value
|
|
356
365
|
}
|
|
357
366
|
this._allTagsParsed = true
|
|
358
|
-
return
|
|
367
|
+
return
|
|
359
368
|
}
|
|
360
369
|
|
|
361
370
|
_parseAllTags() {
|
|
@@ -368,7 +377,7 @@ export default class BamRecord {
|
|
|
368
377
|
cigar
|
|
369
378
|
.match(/\d+\D/g)
|
|
370
379
|
//@ts-ignore
|
|
371
|
-
.map(op => [op.match(/\D/)[0].toUpperCase(), parseInt(op, 10)])
|
|
380
|
+
.map(op => [op.match(/\D/)[0].toUpperCase(), Number.parseInt(op, 10)])
|
|
372
381
|
)
|
|
373
382
|
}
|
|
374
383
|
|
|
@@ -436,7 +445,7 @@ export default class BamRecord {
|
|
|
436
445
|
|
|
437
446
|
cigar() {
|
|
438
447
|
if (this.isSegmentUnmapped()) {
|
|
439
|
-
return
|
|
448
|
+
return
|
|
440
449
|
}
|
|
441
450
|
|
|
442
451
|
const { byteArray, start } = this.bytes
|
|
@@ -568,7 +577,7 @@ export default class BamRecord {
|
|
|
568
577
|
}
|
|
569
578
|
return tmp.join('')
|
|
570
579
|
}
|
|
571
|
-
return
|
|
580
|
+
return ''
|
|
572
581
|
}
|
|
573
582
|
|
|
574
583
|
_bin_mq_nl() {
|
|
@@ -597,13 +606,13 @@ export default class BamRecord {
|
|
|
597
606
|
|
|
598
607
|
toJSON() {
|
|
599
608
|
const data: { [key: string]: any } = {}
|
|
600
|
-
Object.keys(this)
|
|
609
|
+
for (const k of Object.keys(this)) {
|
|
601
610
|
if (k.charAt(0) === '_' || k === 'bytes') {
|
|
602
|
-
|
|
611
|
+
continue
|
|
603
612
|
}
|
|
604
613
|
//@ts-ignore
|
|
605
614
|
data[k] = this[k]
|
|
606
|
-
}
|
|
615
|
+
}
|
|
607
616
|
|
|
608
617
|
return data
|
|
609
618
|
}
|
package/src/sam.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
export function parseHeaderText(text: string) {
|
|
2
2
|
const lines = text.split(/\r?\n/)
|
|
3
3
|
const data: { tag: string; data: { tag: string; value: string }[] }[] = []
|
|
4
|
-
|
|
4
|
+
for (const line of lines) {
|
|
5
5
|
const [tag, ...fields] = line.split(/\t/)
|
|
6
|
-
const parsedFields = fields.map(f => {
|
|
7
|
-
const [fieldTag, value] = f.split(':', 2)
|
|
8
|
-
return { tag: fieldTag, value }
|
|
9
|
-
})
|
|
10
6
|
if (tag) {
|
|
11
|
-
data.push({
|
|
7
|
+
data.push({
|
|
8
|
+
tag: tag.slice(1),
|
|
9
|
+
data: fields.map(f => {
|
|
10
|
+
const r = f.indexOf(':')
|
|
11
|
+
const fieldTag = f.slice(0, r)
|
|
12
|
+
const value = f.slice(r + 1)
|
|
13
|
+
return { tag: fieldTag, value }
|
|
14
|
+
}),
|
|
15
|
+
})
|
|
12
16
|
}
|
|
13
|
-
}
|
|
17
|
+
}
|
|
14
18
|
return data
|
|
15
19
|
}
|
package/src/util.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import Long from 'long'
|
|
1
2
|
import Chunk from './chunk'
|
|
2
3
|
import VirtualOffset from './virtualOffset'
|
|
3
4
|
|
|
@@ -33,13 +34,13 @@ export function checkAbortSignal(signal?: AbortSignal) {
|
|
|
33
34
|
|
|
34
35
|
if (signal.aborted) {
|
|
35
36
|
// console.log('bam aborted!')
|
|
36
|
-
if (typeof DOMException
|
|
37
|
-
throw new DOMException('aborted', 'AbortError')
|
|
38
|
-
} else {
|
|
37
|
+
if (typeof DOMException === 'undefined') {
|
|
39
38
|
const e = new Error('aborted')
|
|
40
39
|
//@ts-ignore
|
|
41
40
|
e.code = 'ERR_ABORTED'
|
|
42
41
|
throw e
|
|
42
|
+
} else {
|
|
43
|
+
throw new DOMException('aborted', 'AbortError')
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
}
|
|
@@ -77,9 +78,9 @@ export function makeOpts(obj: AbortSignal | BaseOpts = {}): BaseOpts {
|
|
|
77
78
|
return 'aborted' in obj ? ({ signal: obj } as BaseOpts) : (obj as BaseOpts)
|
|
78
79
|
}
|
|
79
80
|
|
|
80
|
-
export function optimizeChunks(chunks: Chunk[], lowest
|
|
81
|
+
export function optimizeChunks(chunks: Chunk[], lowest?: VirtualOffset) {
|
|
81
82
|
const mergedChunks: Chunk[] = []
|
|
82
|
-
let lastChunk: Chunk |
|
|
83
|
+
let lastChunk: Chunk | undefined
|
|
83
84
|
|
|
84
85
|
if (chunks.length === 0) {
|
|
85
86
|
return chunks
|
|
@@ -87,16 +88,12 @@ export function optimizeChunks(chunks: Chunk[], lowest: VirtualOffset) {
|
|
|
87
88
|
|
|
88
89
|
chunks.sort((c0, c1) => {
|
|
89
90
|
const dif = c0.minv.blockPosition - c1.minv.blockPosition
|
|
90
|
-
|
|
91
|
-
return dif
|
|
92
|
-
} else {
|
|
93
|
-
return c0.minv.dataPosition - c1.minv.dataPosition
|
|
94
|
-
}
|
|
91
|
+
return dif === 0 ? c0.minv.dataPosition - c1.minv.dataPosition : dif
|
|
95
92
|
})
|
|
96
93
|
|
|
97
|
-
|
|
94
|
+
for (const chunk of chunks) {
|
|
98
95
|
if (!lowest || chunk.maxv.compareTo(lowest) > 0) {
|
|
99
|
-
if (lastChunk ===
|
|
96
|
+
if (lastChunk === undefined) {
|
|
100
97
|
mergedChunks.push(chunk)
|
|
101
98
|
lastChunk = chunk
|
|
102
99
|
} else {
|
|
@@ -110,7 +107,51 @@ export function optimizeChunks(chunks: Chunk[], lowest: VirtualOffset) {
|
|
|
110
107
|
}
|
|
111
108
|
}
|
|
112
109
|
}
|
|
113
|
-
}
|
|
110
|
+
}
|
|
114
111
|
|
|
115
112
|
return mergedChunks
|
|
116
113
|
}
|
|
114
|
+
|
|
115
|
+
export function parsePseudoBin(bytes: Buffer, offset: number) {
|
|
116
|
+
const lineCount = longToNumber(
|
|
117
|
+
Long.fromBytesLE(
|
|
118
|
+
Array.prototype.slice.call(bytes, offset, offset + 8),
|
|
119
|
+
true,
|
|
120
|
+
),
|
|
121
|
+
)
|
|
122
|
+
return { lineCount }
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function findFirstData(
|
|
126
|
+
firstDataLine: VirtualOffset | undefined,
|
|
127
|
+
virtualOffset: VirtualOffset,
|
|
128
|
+
) {
|
|
129
|
+
return firstDataLine
|
|
130
|
+
? firstDataLine.compareTo(virtualOffset) > 0
|
|
131
|
+
? virtualOffset
|
|
132
|
+
: firstDataLine
|
|
133
|
+
: virtualOffset
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function parseNameBytes(
|
|
137
|
+
namesBytes: Buffer,
|
|
138
|
+
renameRefSeq: (arg: string) => string = s => s,
|
|
139
|
+
) {
|
|
140
|
+
let currRefId = 0
|
|
141
|
+
let currNameStart = 0
|
|
142
|
+
const refIdToName = []
|
|
143
|
+
const refNameToId: { [key: string]: number } = {}
|
|
144
|
+
for (let i = 0; i < namesBytes.length; i += 1) {
|
|
145
|
+
if (!namesBytes[i]) {
|
|
146
|
+
if (currNameStart < i) {
|
|
147
|
+
let refName = namesBytes.toString('utf8', currNameStart, i)
|
|
148
|
+
refName = renameRefSeq(refName)
|
|
149
|
+
refIdToName[currRefId] = refName
|
|
150
|
+
refNameToId[refName] = currRefId
|
|
151
|
+
}
|
|
152
|
+
currNameStart = i + 1
|
|
153
|
+
currRefId += 1
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return { refNameToId, refIdToName }
|
|
157
|
+
}
|
package/src/declare.d.ts
DELETED