@gmod/bam 7.3.2 → 7.3.4
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/dist/bai.js +1 -0
- package/dist/bai.js.map +1 -1
- package/dist/chunk.d.ts +2 -2
- package/dist/chunk.js +8 -7
- package/dist/chunk.js.map +1 -1
- package/dist/csi.js +1 -0
- package/dist/csi.js.map +1 -1
- package/dist/long.d.ts +0 -2
- package/dist/long.js +2 -4
- package/dist/long.js.map +1 -1
- package/dist/record.d.ts +1 -1
- package/dist/record.js +93 -143
- package/dist/record.js.map +1 -1
- package/dist/util.d.ts +1 -0
- package/dist/util.js +34 -1
- package/dist/util.js.map +1 -1
- package/dist/virtualOffset.d.ts +1 -1
- package/dist/virtualOffset.js +1 -4
- package/dist/virtualOffset.js.map +1 -1
- package/esm/bai.js +2 -1
- package/esm/bai.js.map +1 -1
- package/esm/chunk.d.ts +2 -2
- package/esm/chunk.js +8 -7
- package/esm/chunk.js.map +1 -1
- package/esm/csi.js +2 -1
- package/esm/csi.js.map +1 -1
- package/esm/long.d.ts +0 -2
- package/esm/long.js +1 -2
- package/esm/long.js.map +1 -1
- package/esm/record.d.ts +1 -1
- package/esm/record.js +93 -143
- package/esm/record.js.map +1 -1
- package/esm/util.d.ts +1 -0
- package/esm/util.js +33 -1
- package/esm/util.js.map +1 -1
- package/esm/virtualOffset.d.ts +1 -1
- package/esm/virtualOffset.js +1 -4
- package/esm/virtualOffset.js.map +1 -1
- package/package.json +1 -1
- package/src/bai.ts +5 -1
- package/src/chunk.ts +20 -9
- package/src/csi.ts +7 -1
- package/src/long.ts +1 -2
- package/src/record.ts +116 -150
- package/src/util.ts +34 -0
- package/src/virtualOffset.ts +1 -5
package/esm/util.js
CHANGED
|
@@ -47,7 +47,7 @@ export function optimizeChunks(chunks, lowest) {
|
|
|
47
47
|
const cmp = chunkMaxBlock - lastMaxBlock ||
|
|
48
48
|
chunk.maxv.dataPosition - lastChunk.maxv.dataPosition;
|
|
49
49
|
if (cmp > 0) {
|
|
50
|
-
mergedChunks[mergedChunks.length - 1] = new Chunk(lastChunk.minv, chunk.maxv, lastChunk.bin);
|
|
50
|
+
mergedChunks[mergedChunks.length - 1] = new Chunk(lastChunk.minv, chunk.maxv, lastChunk.bin, chunk.endPosition);
|
|
51
51
|
lastMaxBlock = chunkMaxBlock;
|
|
52
52
|
}
|
|
53
53
|
}
|
|
@@ -64,6 +64,38 @@ export function parsePseudoBin(bytes, offset) {
|
|
|
64
64
|
lineCount: longFromBytesToUnsigned(bytes, offset),
|
|
65
65
|
};
|
|
66
66
|
}
|
|
67
|
+
// Tighten each chunk's endPosition (default: a full max-size BGZF block past
|
|
68
|
+
// maxv) down to the next known block boundary. Every chunk min/maxv blockPosition
|
|
69
|
+
// and every extraBoundary (e.g. linear-index entries) is a real BGZF block start;
|
|
70
|
+
// since blocks don't overlap, the first boundary strictly greater than a chunk's
|
|
71
|
+
// maxv.blockPosition is an upper bound on where that final block ends — always at
|
|
72
|
+
// least the true block end, so the clamped fetch still contains the whole block.
|
|
73
|
+
// Shrinks both the byte estimate and the actual fetch with no extra I/O.
|
|
74
|
+
export function clampChunkEnds(chunks, extraBoundaries = []) {
|
|
75
|
+
const boundaries = [...extraBoundaries];
|
|
76
|
+
for (const c of chunks) {
|
|
77
|
+
boundaries.push(c.minv.blockPosition, c.maxv.blockPosition);
|
|
78
|
+
}
|
|
79
|
+
boundaries.sort((a, b) => a - b);
|
|
80
|
+
for (const c of chunks) {
|
|
81
|
+
const max = c.maxv.blockPosition;
|
|
82
|
+
// first boundary strictly greater than max
|
|
83
|
+
let lo = 0;
|
|
84
|
+
let hi = boundaries.length;
|
|
85
|
+
while (lo < hi) {
|
|
86
|
+
const mid = (lo + hi) >>> 1;
|
|
87
|
+
if (boundaries[mid] > max) {
|
|
88
|
+
hi = mid;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
lo = mid + 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (lo < boundaries.length) {
|
|
95
|
+
c.endPosition = Math.min(c.endPosition, boundaries[lo]);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
67
99
|
// Parse the BAM reference-sequence table (SAMv1.pdf §4.2). Returns undefined
|
|
68
100
|
// if `uncba` doesn't yet contain the full table — caller fetches more bytes
|
|
69
101
|
// and retries.
|
package/esm/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAA;AA0CnD,MAAM,UAAU,cAAc,CAAC,MAAe,EAAE,MAAe;IAC7D,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,CAAA;IACvB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACZ,OAAO,MAAM,CAAA;IACf,CAAC;IAED,0DAA0D;IAC1D,IAAI,QAAiB,CAAA;IACrB,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,WAAW,GAAG,MAAM,CAAC,aAAa,CAAA;QACxC,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,CAAA;QACtC,QAAQ,GAAG,EAAE,CAAA;QACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAE,CAAA;YACxB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAA;YACvB,MAAM,GAAG,GACP,IAAI,CAAC,aAAa,GAAG,WAAW,IAAI,IAAI,CAAC,YAAY,GAAG,UAAU,CAAA;YACpE,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACZ,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACtB,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,QAAQ,CAAA;QACjB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,MAAM,CAAA;IACnB,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE;QACvB,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAA;QACzD,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,CAAA;IACtE,CAAC,CAAC,CAAA;IAEF,yEAAyE;IACzE,uEAAuE;IACvE,MAAM,YAAY,GAAY,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,CAAA;IAC5C,IAAI,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,aAAa,CAAA;IAClD,IAAI,YAAY,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,aAAa,CAAA;IAElD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAA;QAC1B,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAA;QAC9C,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAA;QAC9C,oEAAoE;QACpE,yEAAyE;QACzE,IACE,aAAa,GAAG,YAAY,GAAG,KAAK;YACpC,aAAa,GAAG,YAAY,GAAG,OAAO,EACtC,CAAC;YACD,MAAM,SAAS,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAE,CAAA;YACxD,MAAM,GAAG,GACP,aAAa,GAAG,YAAY;gBAC5B,KAAK,CAAC,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC,IAAI,CAAC,YAAY,CAAA;YACvD,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;gBACZ,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,IAAI,KAAK,CAC/C,SAAS,CAAC,IAAI,EACd,KAAK,CAAC,IAAI,EACV,SAAS,CAAC,GAAG,
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/esm/virtualOffset.d.ts
CHANGED
|
@@ -11,4 +11,4 @@ export declare class VirtualOffset {
|
|
|
11
11
|
toString(): string;
|
|
12
12
|
compareTo(b: VirtualOffset): number;
|
|
13
13
|
}
|
|
14
|
-
export declare function fromBytes(bytes: Uint8Array, offset?: number
|
|
14
|
+
export declare function fromBytes(bytes: Uint8Array, offset?: number): VirtualOffset;
|
package/esm/virtualOffset.js
CHANGED
|
@@ -12,10 +12,7 @@ export class VirtualOffset {
|
|
|
12
12
|
return (this.blockPosition - b.blockPosition || this.dataPosition - b.dataPosition);
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
export function fromBytes(bytes, offset = 0
|
|
16
|
-
if (bigendian) {
|
|
17
|
-
throw new Error('big-endian virtual file offsets not implemented');
|
|
18
|
-
}
|
|
15
|
+
export function fromBytes(bytes, offset = 0) {
|
|
19
16
|
return new VirtualOffset(bytes[offset + 7] * 0x10000000000 +
|
|
20
17
|
bytes[offset + 6] * 0x100000000 +
|
|
21
18
|
bytes[offset + 5] * 0x1000000 +
|
package/esm/virtualOffset.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualOffset.js","sourceRoot":"","sources":["../src/virtualOffset.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,aAAa;IACjB,aAAa,CAAQ;IACrB,YAAY,CAAQ;IAC3B,YAAY,aAAqB,EAAE,YAAoB;QACrD,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA,CAAC,wCAAwC;QAC3E,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA,CAAC,sCAAsC;IACzE,CAAC;IAED,QAAQ;QACN,OAAO,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,EAAE,CAAA;IACrD,CAAC;IAED,SAAS,CAAC,CAAgB;QACxB,OAAO,CACL,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAC3E,CAAA;IACH,CAAC;CACF;AACD,MAAM,UAAU,SAAS,CAAC,KAAiB,EAAE,MAAM,GAAG,CAAC
|
|
1
|
+
{"version":3,"file":"virtualOffset.js","sourceRoot":"","sources":["../src/virtualOffset.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,aAAa;IACjB,aAAa,CAAQ;IACrB,YAAY,CAAQ;IAC3B,YAAY,aAAqB,EAAE,YAAoB;QACrD,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA,CAAC,wCAAwC;QAC3E,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA,CAAC,sCAAsC;IACzE,CAAC;IAED,QAAQ;QACN,OAAO,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,EAAE,CAAA;IACrD,CAAC;IAED,SAAS,CAAC,CAAgB;QACxB,OAAO,CACL,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,IAAI,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,YAAY,CAC3E,CAAA;IACH,CAAC;CACF;AACD,MAAM,UAAU,SAAS,CAAC,KAAiB,EAAE,MAAM,GAAG,CAAC;IACrD,OAAO,IAAI,aAAa,CACtB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,GAAG,aAAa;QAChC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,GAAG,WAAW;QAChC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,GAAG,SAAS;QAC9B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,GAAG,OAAO;QAC5B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,GAAG,KAAK;QAC1B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,EACpB,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAE,CAC3C,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
package/src/bai.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Chunk from './chunk.ts'
|
|
2
2
|
import IndexFile, { memoizeByRefId } from './indexFile.ts'
|
|
3
|
-
import { findFirstData, parsePseudoBin } from './util.ts'
|
|
3
|
+
import { clampChunkEnds, findFirstData, parsePseudoBin } from './util.ts'
|
|
4
4
|
import { fromBytes } from './virtualOffset.ts'
|
|
5
5
|
|
|
6
6
|
import type { ParsedIndexBase, RefIndex } from './indexFile.ts'
|
|
@@ -146,6 +146,10 @@ export default class BAI extends IndexFile<BaiParsed> {
|
|
|
146
146
|
curr += 8
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
clampChunkEnds(
|
|
150
|
+
Object.values(binIndex).flat(),
|
|
151
|
+
linearIndex.map(v => v.blockPosition),
|
|
152
|
+
)
|
|
149
153
|
return {
|
|
150
154
|
binIndex,
|
|
151
155
|
linearIndex,
|
package/src/chunk.ts
CHANGED
|
@@ -2,12 +2,26 @@ import type { Offset } from './virtualOffset.ts'
|
|
|
2
2
|
|
|
3
3
|
// little class representing a chunk in the index
|
|
4
4
|
export default class Chunk {
|
|
5
|
+
public minv: Offset
|
|
6
|
+
public maxv: Offset
|
|
7
|
+
public bin: number
|
|
8
|
+
// Absolute byte offset where the fetch for this chunk ends. The compressed
|
|
9
|
+
// size of the final BGZF block (the one at maxv.blockPosition) is unknown
|
|
10
|
+
// from the index, so this defaults to a full max-size block past maxv. It can
|
|
11
|
+
// be tightened to the next known block boundary via clampChunkEnds.
|
|
12
|
+
public endPosition: number
|
|
13
|
+
|
|
5
14
|
constructor(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
) {
|
|
15
|
+
minv: Offset,
|
|
16
|
+
maxv: Offset,
|
|
17
|
+
bin: number,
|
|
18
|
+
endPosition = maxv.blockPosition + (1 << 16),
|
|
19
|
+
) {
|
|
20
|
+
this.minv = minv
|
|
21
|
+
this.maxv = maxv
|
|
22
|
+
this.bin = bin
|
|
23
|
+
this.endPosition = endPosition
|
|
24
|
+
}
|
|
11
25
|
|
|
12
26
|
toString() {
|
|
13
27
|
return `${this.minv.toString()}..${this.maxv.toString()} (bin ${
|
|
@@ -24,9 +38,6 @@ export default class Chunk {
|
|
|
24
38
|
}
|
|
25
39
|
|
|
26
40
|
fetchedSize() {
|
|
27
|
-
|
|
28
|
-
return this._fetchedSize
|
|
29
|
-
}
|
|
30
|
-
return this.maxv.blockPosition + (1 << 16) - this.minv.blockPosition
|
|
41
|
+
return this.endPosition - this.minv.blockPosition
|
|
31
42
|
}
|
|
32
43
|
}
|
package/src/csi.ts
CHANGED
|
@@ -2,7 +2,12 @@ import { unzip } from '@gmod/bgzf-filehandle'
|
|
|
2
2
|
|
|
3
3
|
import Chunk from './chunk.ts'
|
|
4
4
|
import IndexFile, { memoizeByRefId } from './indexFile.ts'
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
clampChunkEnds,
|
|
7
|
+
findFirstData,
|
|
8
|
+
parseNameBytes,
|
|
9
|
+
parsePseudoBin,
|
|
10
|
+
} from './util.ts'
|
|
6
11
|
import { VirtualOffset, fromBytes } from './virtualOffset.ts'
|
|
7
12
|
|
|
8
13
|
import type { BaseOpts } from './util.ts'
|
|
@@ -150,6 +155,7 @@ export default class CSI extends IndexFile {
|
|
|
150
155
|
}
|
|
151
156
|
}
|
|
152
157
|
|
|
158
|
+
clampChunkEnds(Object.values(binIndex).flat())
|
|
153
159
|
return {
|
|
154
160
|
binIndex,
|
|
155
161
|
stats: pseudoBinStats,
|
package/src/long.ts
CHANGED
package/src/record.ts
CHANGED
|
@@ -127,6 +127,97 @@ function bArrayByteLength(Btype: number, limit: number) {
|
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
+
// Cursor position just past a tag's value — i.e. the start of the next tag —
|
|
131
|
+
// given the value starts at `p`. For null-terminated Z/H this steps over the
|
|
132
|
+
// terminator. Returns 0 for an unknown type, whose value width is unknowable so
|
|
133
|
+
// the caller must stop. Shared by _findTag and _computeTags so the two loops
|
|
134
|
+
// can't drift in how they walk the tag layout. (0 is an impossible real end:
|
|
135
|
+
// `p` is always past the fixed record prefix.)
|
|
136
|
+
function tagValueEnd(
|
|
137
|
+
ba: Uint8Array,
|
|
138
|
+
dataView: DataView,
|
|
139
|
+
type: number,
|
|
140
|
+
p: number,
|
|
141
|
+
blockEnd: number,
|
|
142
|
+
) {
|
|
143
|
+
switch (type) {
|
|
144
|
+
case 0x41: // 'A'
|
|
145
|
+
case 0x63: // 'c'
|
|
146
|
+
case 0x43: // 'C'
|
|
147
|
+
return p + 1
|
|
148
|
+
case 0x73: // 's'
|
|
149
|
+
case 0x53: // 'S'
|
|
150
|
+
return p + 2
|
|
151
|
+
case 0x69: // 'i'
|
|
152
|
+
case 0x49: // 'I'
|
|
153
|
+
case 0x66: {
|
|
154
|
+
// 'f'
|
|
155
|
+
return p + 4
|
|
156
|
+
}
|
|
157
|
+
case 0x5a: // 'Z'
|
|
158
|
+
case 0x48: {
|
|
159
|
+
// 'H'
|
|
160
|
+
let q = p
|
|
161
|
+
while (q < blockEnd && ba[q] !== 0) {
|
|
162
|
+
q++
|
|
163
|
+
}
|
|
164
|
+
return q + 1 // step past the null terminator
|
|
165
|
+
}
|
|
166
|
+
case 0x42: {
|
|
167
|
+
// 'B'
|
|
168
|
+
const Btype = ba[p]!
|
|
169
|
+
const limit = dataView.getInt32(p + 1, true)
|
|
170
|
+
return p + 5 + bArrayByteLength(Btype, limit)
|
|
171
|
+
}
|
|
172
|
+
default:
|
|
173
|
+
console.error('Unknown BAM tag type', type)
|
|
174
|
+
return 0
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Decode the value of a tag of `type` whose bytes start at `p`; `end` is the
|
|
179
|
+
// next-tag cursor from tagValueEnd (used only to bound Z/H strings, whose bytes
|
|
180
|
+
// run up to the null terminator at end-1). When `raw`, Z/H return the undecoded
|
|
181
|
+
// byte subarray. Assumes `type` is a known scalar/string/B type.
|
|
182
|
+
function decodeTagValue(
|
|
183
|
+
ba: Uint8Array,
|
|
184
|
+
dataView: DataView,
|
|
185
|
+
type: number,
|
|
186
|
+
p: number,
|
|
187
|
+
end: number,
|
|
188
|
+
raw: boolean,
|
|
189
|
+
): unknown {
|
|
190
|
+
switch (type) {
|
|
191
|
+
case 0x41: // 'A'
|
|
192
|
+
return String.fromCharCode(ba[p]!)
|
|
193
|
+
case 0x69: // 'i'
|
|
194
|
+
return dataView.getInt32(p, true)
|
|
195
|
+
case 0x49: // 'I'
|
|
196
|
+
return dataView.getUint32(p, true)
|
|
197
|
+
case 0x63: // 'c'
|
|
198
|
+
return dataView.getInt8(p)
|
|
199
|
+
case 0x43: // 'C'
|
|
200
|
+
return dataView.getUint8(p)
|
|
201
|
+
case 0x73: // 's'
|
|
202
|
+
return dataView.getInt16(p, true)
|
|
203
|
+
case 0x53: // 'S'
|
|
204
|
+
return dataView.getUint16(p, true)
|
|
205
|
+
case 0x66: // 'f'
|
|
206
|
+
return dataView.getFloat32(p, true)
|
|
207
|
+
case 0x5a: // 'Z'
|
|
208
|
+
case 0x48: // 'H'
|
|
209
|
+
return raw
|
|
210
|
+
? ba.subarray(p, end - 1)
|
|
211
|
+
: textDecoder.decode(ba.subarray(p, end - 1))
|
|
212
|
+
default: {
|
|
213
|
+
// 'B'
|
|
214
|
+
const Btype = ba[p]!
|
|
215
|
+
const limit = dataView.getInt32(p + 1, true)
|
|
216
|
+
return decodeBArrayTag(ba, dataView, p + 5, Btype, limit)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
130
221
|
export default class BamRecord {
|
|
131
222
|
public fileOffset: number
|
|
132
223
|
private _byteArray: Uint8Array
|
|
@@ -261,172 +352,47 @@ export default class BamRecord {
|
|
|
261
352
|
private _findTag(tagName: string, raw: boolean) {
|
|
262
353
|
const tag1 = tagName.charCodeAt(0)
|
|
263
354
|
const tag2 = tagName.charCodeAt(1)
|
|
264
|
-
|
|
265
|
-
let p = this.tagsStart
|
|
266
|
-
|
|
267
355
|
const blockEnd = this._end
|
|
268
356
|
const ba = this._byteArray
|
|
357
|
+
let p = this.tagsStart
|
|
269
358
|
while (p < blockEnd) {
|
|
270
|
-
const
|
|
271
|
-
const
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
if (isMatch) {
|
|
280
|
-
return String.fromCharCode(ba[p]!)
|
|
281
|
-
}
|
|
282
|
-
p += 1
|
|
283
|
-
break
|
|
284
|
-
case 0x69: // 'i'
|
|
285
|
-
if (isMatch) {
|
|
286
|
-
return this._dataView.getInt32(p, true)
|
|
287
|
-
}
|
|
288
|
-
p += 4
|
|
289
|
-
break
|
|
290
|
-
case 0x49: // 'I'
|
|
291
|
-
if (isMatch) {
|
|
292
|
-
return this._dataView.getUint32(p, true)
|
|
293
|
-
}
|
|
294
|
-
p += 4
|
|
295
|
-
break
|
|
296
|
-
case 0x63: // 'c'
|
|
297
|
-
if (isMatch) {
|
|
298
|
-
return this._dataView.getInt8(p)
|
|
299
|
-
}
|
|
300
|
-
p += 1
|
|
301
|
-
break
|
|
302
|
-
case 0x43: // 'C'
|
|
303
|
-
if (isMatch) {
|
|
304
|
-
return this._dataView.getUint8(p)
|
|
305
|
-
}
|
|
306
|
-
p += 1
|
|
307
|
-
break
|
|
308
|
-
case 0x73: // 's'
|
|
309
|
-
if (isMatch) {
|
|
310
|
-
return this._dataView.getInt16(p, true)
|
|
311
|
-
}
|
|
312
|
-
p += 2
|
|
313
|
-
break
|
|
314
|
-
case 0x53: // 'S'
|
|
315
|
-
if (isMatch) {
|
|
316
|
-
return this._dataView.getUint16(p, true)
|
|
317
|
-
}
|
|
318
|
-
p += 2
|
|
319
|
-
break
|
|
320
|
-
case 0x66: // 'f'
|
|
321
|
-
if (isMatch) {
|
|
322
|
-
return this._dataView.getFloat32(p, true)
|
|
323
|
-
}
|
|
324
|
-
p += 4
|
|
325
|
-
break
|
|
326
|
-
case 0x5a: // 'Z'
|
|
327
|
-
case 0x48: {
|
|
328
|
-
// 'H'
|
|
329
|
-
const start = p
|
|
330
|
-
while (p < blockEnd && ba[p] !== 0) {
|
|
331
|
-
p++
|
|
332
|
-
}
|
|
333
|
-
if (isMatch) {
|
|
334
|
-
return raw
|
|
335
|
-
? ba.subarray(start, p)
|
|
336
|
-
: textDecoder.decode(ba.subarray(start, p))
|
|
337
|
-
}
|
|
338
|
-
p++ // advance past null terminator
|
|
339
|
-
break
|
|
340
|
-
}
|
|
341
|
-
case 0x42: {
|
|
342
|
-
// 'B'
|
|
343
|
-
const Btype = ba[p++]!
|
|
344
|
-
const limit = this._dataView.getInt32(p, true)
|
|
345
|
-
p += 4
|
|
346
|
-
if (isMatch) {
|
|
347
|
-
return decodeBArrayTag(ba, this._dataView, p, Btype, limit)
|
|
348
|
-
}
|
|
349
|
-
p += bArrayByteLength(Btype, limit)
|
|
350
|
-
break
|
|
351
|
-
}
|
|
352
|
-
default:
|
|
353
|
-
if (type !== undefined) {
|
|
354
|
-
console.error('Unknown BAM tag type', type)
|
|
355
|
-
}
|
|
356
|
-
break
|
|
359
|
+
const isMatch = ba[p] === tag1 && ba[p + 1] === tag2
|
|
360
|
+
const type = ba[p + 2]!
|
|
361
|
+
const valueStart = p + 3
|
|
362
|
+
const end = tagValueEnd(ba, this._dataView, type, valueStart, blockEnd)
|
|
363
|
+
if (end === 0) {
|
|
364
|
+
break // unknown type: can't compute how far to advance
|
|
365
|
+
}
|
|
366
|
+
if (isMatch) {
|
|
367
|
+
return decodeTagValue(ba, this._dataView, type, valueStart, end, raw)
|
|
357
368
|
}
|
|
369
|
+
p = end
|
|
358
370
|
}
|
|
359
371
|
return undefined
|
|
360
372
|
}
|
|
361
373
|
|
|
362
374
|
private _computeTags() {
|
|
363
|
-
let p = this.tagsStart
|
|
364
|
-
|
|
365
375
|
const blockEnd = this._end
|
|
366
376
|
const ba = this._byteArray
|
|
367
377
|
const tags: Record<string, unknown> = {}
|
|
378
|
+
let p = this.tagsStart
|
|
368
379
|
while (p < blockEnd) {
|
|
369
380
|
const tag = String.fromCharCode(ba[p]!, ba[p + 1]!)
|
|
370
381
|
const type = ba[p + 2]!
|
|
371
|
-
p
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
tags[tag] = String.fromCharCode(ba[p]!)
|
|
376
|
-
p += 1
|
|
377
|
-
break
|
|
378
|
-
case 0x69: // 'i'
|
|
379
|
-
tags[tag] = this._dataView.getInt32(p, true)
|
|
380
|
-
p += 4
|
|
381
|
-
break
|
|
382
|
-
case 0x49: // 'I'
|
|
383
|
-
tags[tag] = this._dataView.getUint32(p, true)
|
|
384
|
-
p += 4
|
|
385
|
-
break
|
|
386
|
-
case 0x63: // 'c'
|
|
387
|
-
tags[tag] = this._dataView.getInt8(p)
|
|
388
|
-
p += 1
|
|
389
|
-
break
|
|
390
|
-
case 0x43: // 'C'
|
|
391
|
-
tags[tag] = this._dataView.getUint8(p)
|
|
392
|
-
p += 1
|
|
393
|
-
break
|
|
394
|
-
case 0x73: // 's'
|
|
395
|
-
tags[tag] = this._dataView.getInt16(p, true)
|
|
396
|
-
p += 2
|
|
397
|
-
break
|
|
398
|
-
case 0x53: // 'S'
|
|
399
|
-
tags[tag] = this._dataView.getUint16(p, true)
|
|
400
|
-
p += 2
|
|
401
|
-
break
|
|
402
|
-
case 0x66: // 'f'
|
|
403
|
-
tags[tag] = this._dataView.getFloat32(p, true)
|
|
404
|
-
p += 4
|
|
405
|
-
break
|
|
406
|
-
case 0x5a: // 'Z'
|
|
407
|
-
case 0x48: {
|
|
408
|
-
// 'H'
|
|
409
|
-
const start = p
|
|
410
|
-
while (p < blockEnd && ba[p] !== 0) {
|
|
411
|
-
p++
|
|
412
|
-
}
|
|
413
|
-
tags[tag] = textDecoder.decode(ba.subarray(start, p))
|
|
414
|
-
p++ // advance past null terminator
|
|
415
|
-
break
|
|
416
|
-
}
|
|
417
|
-
case 0x42: {
|
|
418
|
-
// 'B'
|
|
419
|
-
const Btype = ba[p++]!
|
|
420
|
-
const limit = this._dataView.getInt32(p, true)
|
|
421
|
-
p += 4
|
|
422
|
-
tags[tag] = decodeBArrayTag(ba, this._dataView, p, Btype, limit)
|
|
423
|
-
p += bArrayByteLength(Btype, limit)
|
|
424
|
-
break
|
|
425
|
-
}
|
|
426
|
-
default:
|
|
427
|
-
console.error('Unknown BAM tag type', type)
|
|
428
|
-
break
|
|
382
|
+
const valueStart = p + 3
|
|
383
|
+
const end = tagValueEnd(ba, this._dataView, type, valueStart, blockEnd)
|
|
384
|
+
if (end === 0) {
|
|
385
|
+
break // unknown type: can't compute how far to advance
|
|
429
386
|
}
|
|
387
|
+
tags[tag] = decodeTagValue(
|
|
388
|
+
ba,
|
|
389
|
+
this._dataView,
|
|
390
|
+
type,
|
|
391
|
+
valueStart,
|
|
392
|
+
end,
|
|
393
|
+
false,
|
|
394
|
+
)
|
|
395
|
+
p = end
|
|
430
396
|
}
|
|
431
397
|
return tags
|
|
432
398
|
}
|
package/src/util.ts
CHANGED
|
@@ -99,6 +99,7 @@ export function optimizeChunks(chunks: Chunk[], lowest?: Offset) {
|
|
|
99
99
|
lastChunk.minv,
|
|
100
100
|
chunk.maxv,
|
|
101
101
|
lastChunk.bin,
|
|
102
|
+
chunk.endPosition,
|
|
102
103
|
)
|
|
103
104
|
lastMaxBlock = chunkMaxBlock
|
|
104
105
|
}
|
|
@@ -118,6 +119,39 @@ export function parsePseudoBin(bytes: Uint8Array, offset: number) {
|
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
// Tighten each chunk's endPosition (default: a full max-size BGZF block past
|
|
123
|
+
// maxv) down to the next known block boundary. Every chunk min/maxv blockPosition
|
|
124
|
+
// and every extraBoundary (e.g. linear-index entries) is a real BGZF block start;
|
|
125
|
+
// since blocks don't overlap, the first boundary strictly greater than a chunk's
|
|
126
|
+
// maxv.blockPosition is an upper bound on where that final block ends — always at
|
|
127
|
+
// least the true block end, so the clamped fetch still contains the whole block.
|
|
128
|
+
// Shrinks both the byte estimate and the actual fetch with no extra I/O.
|
|
129
|
+
export function clampChunkEnds(chunks: Chunk[], extraBoundaries: number[] = []) {
|
|
130
|
+
const boundaries = [...extraBoundaries]
|
|
131
|
+
for (const c of chunks) {
|
|
132
|
+
boundaries.push(c.minv.blockPosition, c.maxv.blockPosition)
|
|
133
|
+
}
|
|
134
|
+
boundaries.sort((a, b) => a - b)
|
|
135
|
+
|
|
136
|
+
for (const c of chunks) {
|
|
137
|
+
const max = c.maxv.blockPosition
|
|
138
|
+
// first boundary strictly greater than max
|
|
139
|
+
let lo = 0
|
|
140
|
+
let hi = boundaries.length
|
|
141
|
+
while (lo < hi) {
|
|
142
|
+
const mid = (lo + hi) >>> 1
|
|
143
|
+
if (boundaries[mid]! > max) {
|
|
144
|
+
hi = mid
|
|
145
|
+
} else {
|
|
146
|
+
lo = mid + 1
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (lo < boundaries.length) {
|
|
150
|
+
c.endPosition = Math.min(c.endPosition, boundaries[lo]!)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
121
155
|
// Parse the BAM reference-sequence table (SAMv1.pdf §4.2). Returns undefined
|
|
122
156
|
// if `uncba` doesn't yet contain the full table — caller fetches more bytes
|
|
123
157
|
// and retries.
|
package/src/virtualOffset.ts
CHANGED
|
@@ -23,11 +23,7 @@ export class VirtualOffset {
|
|
|
23
23
|
)
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
|
-
export function fromBytes(bytes: Uint8Array, offset = 0
|
|
27
|
-
if (bigendian) {
|
|
28
|
-
throw new Error('big-endian virtual file offsets not implemented')
|
|
29
|
-
}
|
|
30
|
-
|
|
26
|
+
export function fromBytes(bytes: Uint8Array, offset = 0) {
|
|
31
27
|
return new VirtualOffset(
|
|
32
28
|
bytes[offset + 7]! * 0x10000000000 +
|
|
33
29
|
bytes[offset + 6]! * 0x100000000 +
|