@gmod/bam 7.6.2 → 7.7.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/dist/bai.d.ts +6 -3
- package/dist/bai.js +32 -16
- package/dist/bai.js.map +1 -1
- package/dist/bamFile.d.ts +3 -3
- package/dist/bamFile.js +39 -12
- package/dist/bamFile.js.map +1 -1
- package/dist/chunk.d.ts +0 -1
- package/dist/chunk.js +0 -5
- package/dist/chunk.js.map +1 -1
- package/dist/csi.d.ts +0 -2
- package/dist/csi.js +4 -11
- package/dist/csi.js.map +1 -1
- package/dist/indexFile.d.ts +2 -3
- package/dist/indexFile.js.map +1 -1
- package/dist/sam.js +8 -3
- package/dist/sam.js.map +1 -1
- package/dist/util.d.ts +3 -3
- package/dist/util.js +21 -5
- package/dist/util.js.map +1 -1
- package/dist/virtualOffset.d.ts +8 -3
- package/dist/virtualOffset.js +0 -3
- package/dist/virtualOffset.js.map +1 -1
- package/esm/bai.d.ts +6 -3
- package/esm/bai.js +32 -16
- package/esm/bai.js.map +1 -1
- package/esm/bamFile.d.ts +3 -3
- package/esm/bamFile.js +39 -12
- package/esm/bamFile.js.map +1 -1
- package/esm/chunk.d.ts +0 -1
- package/esm/chunk.js +0 -5
- package/esm/chunk.js.map +1 -1
- package/esm/csi.d.ts +0 -2
- package/esm/csi.js +4 -11
- package/esm/csi.js.map +1 -1
- package/esm/indexFile.d.ts +2 -3
- package/esm/indexFile.js.map +1 -1
- package/esm/sam.js +8 -3
- package/esm/sam.js.map +1 -1
- package/esm/util.d.ts +3 -3
- package/esm/util.js +21 -5
- package/esm/util.js.map +1 -1
- package/esm/virtualOffset.d.ts +8 -3
- package/esm/virtualOffset.js +0 -3
- package/esm/virtualOffset.js.map +1 -1
- package/package.json +1 -1
- package/src/bai.ts +42 -20
- package/src/bamFile.ts +38 -11
- package/src/chunk.ts +0 -8
- package/src/csi.ts +4 -10
- package/src/indexFile.ts +2 -3
- package/src/sam.ts +8 -3
- package/src/util.ts +28 -8
- package/src/virtualOffset.ts +9 -8
- package/dist/long.d.ts +0 -1
- package/dist/long.js +0 -17
- package/dist/long.js.map +0 -1
- package/esm/long.d.ts +0 -1
- package/esm/long.js +0 -14
- package/esm/long.js.map +0 -1
- package/src/long.ts +0 -16
package/esm/util.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Chunk from './chunk.ts';
|
|
2
2
|
import { VirtualOffset } from './virtualOffset.ts';
|
|
3
|
-
import type {
|
|
3
|
+
import type { OffsetCoords } from './virtualOffset.ts';
|
|
4
4
|
export interface BamOpts {
|
|
5
5
|
viewAsPairs?: boolean;
|
|
6
6
|
pairAcrossChr?: boolean;
|
|
@@ -25,11 +25,11 @@ export interface BaseOpts {
|
|
|
25
25
|
*/
|
|
26
26
|
onProgress?: (bytesDownloaded: number, totalBytes?: number) => void;
|
|
27
27
|
}
|
|
28
|
-
export declare function optimizeChunks(chunks: Chunk[], lowest?:
|
|
28
|
+
export declare function optimizeChunks(chunks: Chunk[], lowest?: OffsetCoords): Chunk[];
|
|
29
29
|
export declare function parsePseudoBin(bytes: Uint8Array, offset: number): {
|
|
30
30
|
lineCount: number;
|
|
31
31
|
};
|
|
32
|
-
export declare function clampChunkEnds(chunks: Chunk[], extraBoundaries?: number
|
|
32
|
+
export declare function clampChunkEnds(chunks: Chunk[], extraBoundaries?: ArrayLike<number>): void;
|
|
33
33
|
export declare function parseRefSeqs(uncba: Uint8Array, start: number, renameRefSeq: (s: string) => string): {
|
|
34
34
|
chrToIndex: Record<string, number>;
|
|
35
35
|
indexToChr: {
|
package/esm/util.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import Chunk from "./chunk.js";
|
|
2
|
-
import { longFromBytesToUnsigned } from "./long.js";
|
|
3
2
|
import { VirtualOffset } from "./virtualOffset.js";
|
|
4
3
|
export function optimizeChunks(chunks, lowest) {
|
|
5
4
|
const n = chunks.length;
|
|
@@ -60,9 +59,20 @@ export function optimizeChunks(chunks, lowest) {
|
|
|
60
59
|
}
|
|
61
60
|
return mergedChunks;
|
|
62
61
|
}
|
|
62
|
+
// The pseudo-bin's mapped-record count, a little-endian uint64. Read as two
|
|
63
|
+
// 32-bit halves rather than via BigInt: exact up to Number.MAX_SAFE_INTEGER,
|
|
64
|
+
// which is far past any real record count, and allocates nothing.
|
|
63
65
|
export function parsePseudoBin(bytes, offset) {
|
|
66
|
+
const low = bytes[offset] |
|
|
67
|
+
(bytes[offset + 1] << 8) |
|
|
68
|
+
(bytes[offset + 2] << 16) |
|
|
69
|
+
(bytes[offset + 3] << 24);
|
|
70
|
+
const high = bytes[offset + 4] |
|
|
71
|
+
(bytes[offset + 5] << 8) |
|
|
72
|
+
(bytes[offset + 6] << 16) |
|
|
73
|
+
(bytes[offset + 7] << 24);
|
|
64
74
|
return {
|
|
65
|
-
lineCount:
|
|
75
|
+
lineCount: (high >>> 0) * 2 ** 32 + (low >>> 0),
|
|
66
76
|
};
|
|
67
77
|
}
|
|
68
78
|
// Tighten each chunk's endPosition (default: a full max-size BGZF block past
|
|
@@ -73,11 +83,17 @@ export function parsePseudoBin(bytes, offset) {
|
|
|
73
83
|
// least the true block end, so the clamped fetch still contains the whole block.
|
|
74
84
|
// Shrinks both the byte estimate and the actual fetch with no extra I/O.
|
|
75
85
|
export function clampChunkEnds(chunks, extraBoundaries = []) {
|
|
76
|
-
|
|
86
|
+
// Float64Array rather than number[]: `extraBoundaries` is the linear index,
|
|
87
|
+
// which runs to tens of thousands of entries on a human-sized reference, and
|
|
88
|
+
// this is the only place they get copied.
|
|
89
|
+
const boundaries = new Float64Array(extraBoundaries.length + chunks.length * 2);
|
|
90
|
+
boundaries.set(extraBoundaries);
|
|
91
|
+
let n = extraBoundaries.length;
|
|
77
92
|
for (const c of chunks) {
|
|
78
|
-
boundaries
|
|
93
|
+
boundaries[n++] = c.minv.blockPosition;
|
|
94
|
+
boundaries[n++] = c.maxv.blockPosition;
|
|
79
95
|
}
|
|
80
|
-
boundaries.sort(
|
|
96
|
+
boundaries.sort();
|
|
81
97
|
for (const c of chunks) {
|
|
82
98
|
const max = c.maxv.blockPosition;
|
|
83
99
|
// first boundary strictly greater than max
|
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,
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/esm/virtualOffset.d.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The two coordinates a virtual offset packs, without the `blockPos:dataPos`
|
|
3
|
+
* string form. What every consumer that only compares positions needs — the
|
|
4
|
+
* BAI linear index stores these as raw numbers and materializes no object.
|
|
5
|
+
*/
|
|
6
|
+
export interface OffsetCoords {
|
|
2
7
|
blockPosition: number;
|
|
3
8
|
dataPosition: number;
|
|
9
|
+
}
|
|
10
|
+
export interface Offset extends OffsetCoords {
|
|
4
11
|
toString(): string;
|
|
5
|
-
compareTo(arg: Offset): number;
|
|
6
12
|
}
|
|
7
13
|
export declare class VirtualOffset {
|
|
8
14
|
blockPosition: number;
|
|
9
15
|
dataPosition: number;
|
|
10
16
|
constructor(blockPosition: number, dataPosition: number);
|
|
11
17
|
toString(): string;
|
|
12
|
-
compareTo(b: VirtualOffset): number;
|
|
13
18
|
}
|
|
14
19
|
export declare function fromBytes(bytes: Uint8Array, offset?: number): VirtualOffset;
|
package/esm/virtualOffset.js
CHANGED
|
@@ -8,9 +8,6 @@ export class VirtualOffset {
|
|
|
8
8
|
toString() {
|
|
9
9
|
return `${this.blockPosition}:${this.dataPosition}`;
|
|
10
10
|
}
|
|
11
|
-
compareTo(b) {
|
|
12
|
-
return (this.blockPosition - b.blockPosition || this.dataPosition - b.dataPosition);
|
|
13
|
-
}
|
|
14
11
|
}
|
|
15
12
|
export function fromBytes(bytes, offset = 0) {
|
|
16
13
|
return new VirtualOffset(bytes[offset + 7] * 0x10000000000 +
|
package/esm/virtualOffset.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualOffset.js","sourceRoot":"","sources":["../src/virtualOffset.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"virtualOffset.js","sourceRoot":"","sources":["../src/virtualOffset.ts"],"names":[],"mappings":"AAcA,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;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
|
@@ -7,8 +7,17 @@ import type { ParsedIndexBase, RefIndex } from './indexFile.ts'
|
|
|
7
7
|
import type { BaseOpts } from './util.ts'
|
|
8
8
|
import type { VirtualOffset } from './virtualOffset.ts'
|
|
9
9
|
|
|
10
|
+
// The linear index as two parallel Float64Arrays rather than an array of
|
|
11
|
+
// VirtualOffset objects. A human-sized reference has one entry per 16kb window
|
|
12
|
+
// — ~15k for chr1 — and an object apiece costs roughly an order of magnitude
|
|
13
|
+
// more memory than the packed form, retained for as long as memoizeByRefId
|
|
14
|
+
// holds the reference. Both consumers want the raw numbers anyway: indexCov and
|
|
15
|
+
// clampChunkEnds read blockPosition only, and getLowestChunk builds the one
|
|
16
|
+
// VirtualOffset a query actually needs. Same shape as bgzf-filehandle's
|
|
17
|
+
// GziIndex, for the same reason.
|
|
10
18
|
interface BaiRefIndex extends RefIndex {
|
|
11
|
-
|
|
19
|
+
linearBlockPositions: Float64Array
|
|
20
|
+
linearDataPositions: Float64Array
|
|
12
21
|
}
|
|
13
22
|
|
|
14
23
|
interface BaiParsed extends ParsedIndexBase<BaiRefIndex> {
|
|
@@ -142,19 +151,27 @@ export default class BAI extends IndexFile<BaiParsed> {
|
|
|
142
151
|
|
|
143
152
|
const linearCount = dataView.getInt32(curr, true)
|
|
144
153
|
curr += 4
|
|
145
|
-
const
|
|
154
|
+
const linearBlockPositions = new Float64Array(linearCount)
|
|
155
|
+
const linearDataPositions = new Float64Array(linearCount)
|
|
146
156
|
for (let j = 0; j < linearCount; j++) {
|
|
147
|
-
|
|
157
|
+
// a virtual offset is a 48-bit block position in the high bytes and a
|
|
158
|
+
// 16-bit data position in the low two
|
|
159
|
+
linearBlockPositions[j] =
|
|
160
|
+
bytes[curr + 7]! * 0x10000000000 +
|
|
161
|
+
bytes[curr + 6]! * 0x100000000 +
|
|
162
|
+
bytes[curr + 5]! * 0x1000000 +
|
|
163
|
+
bytes[curr + 4]! * 0x10000 +
|
|
164
|
+
bytes[curr + 3]! * 0x100 +
|
|
165
|
+
bytes[curr + 2]!
|
|
166
|
+
linearDataPositions[j] = (bytes[curr + 1]! << 8) | bytes[curr]!
|
|
148
167
|
curr += 8
|
|
149
168
|
}
|
|
150
169
|
|
|
151
|
-
clampChunkEnds(
|
|
152
|
-
Object.values(binIndex).flat(),
|
|
153
|
-
linearIndex.map(v => v.blockPosition),
|
|
154
|
-
)
|
|
170
|
+
clampChunkEnds(Object.values(binIndex).flat(), linearBlockPositions)
|
|
155
171
|
return {
|
|
156
172
|
binIndex,
|
|
157
|
-
|
|
173
|
+
linearBlockPositions,
|
|
174
|
+
linearDataPositions,
|
|
158
175
|
stats,
|
|
159
176
|
}
|
|
160
177
|
}
|
|
@@ -162,7 +179,6 @@ export default class BAI extends IndexFile<BaiParsed> {
|
|
|
162
179
|
return {
|
|
163
180
|
bai: true,
|
|
164
181
|
firstDataLine,
|
|
165
|
-
maxBlockSize: 1 << 16,
|
|
166
182
|
indices: memoizeByRefId(getIndices),
|
|
167
183
|
refCount,
|
|
168
184
|
}
|
|
@@ -182,17 +198,18 @@ export default class BAI extends IndexFile<BaiParsed> {
|
|
|
182
198
|
if (!seqIdx) {
|
|
183
199
|
return []
|
|
184
200
|
}
|
|
185
|
-
const {
|
|
186
|
-
|
|
201
|
+
const { linearBlockPositions, stats } = seqIdx
|
|
202
|
+
const nintv = linearBlockPositions.length
|
|
203
|
+
if (nintv === 0) {
|
|
187
204
|
return []
|
|
188
205
|
}
|
|
189
|
-
const e = end === undefined ? (
|
|
206
|
+
const e = end === undefined ? (nintv - 1) * v : roundUp(end, v)
|
|
190
207
|
const s = start === undefined ? 0 : roundDown(start, v)
|
|
191
208
|
const depths: IndexCovEntry[] = range
|
|
192
209
|
? new Array((e - s) / v)
|
|
193
|
-
: new Array(
|
|
194
|
-
const totalSize =
|
|
195
|
-
if (e > (
|
|
210
|
+
: new Array(nintv - 1)
|
|
211
|
+
const totalSize = linearBlockPositions[nintv - 1]!
|
|
212
|
+
if (e > (nintv - 1) * v) {
|
|
196
213
|
throw new Error('query outside of range of linear index')
|
|
197
214
|
}
|
|
198
215
|
// Scale the block-delta into a read count as we go, rather than building the
|
|
@@ -200,9 +217,9 @@ export default class BAI extends IndexFile<BaiParsed> {
|
|
|
200
217
|
// multiply-then-divide order: hoisting lineCount/totalSize into a factor
|
|
201
218
|
// reassociates the arithmetic and shifts scores by an ulp.
|
|
202
219
|
const lineCount = stats?.lineCount ?? 0
|
|
203
|
-
let currentPos =
|
|
220
|
+
let currentPos = linearBlockPositions[s / v]!
|
|
204
221
|
for (let i = s / v, j = 0; i < e / v; i++, j++) {
|
|
205
|
-
const nextPos =
|
|
222
|
+
const nextPos = linearBlockPositions[i + 1]!
|
|
206
223
|
depths[j] = {
|
|
207
224
|
score: ((nextPos - currentPos) * lineCount) / totalSize,
|
|
208
225
|
start: i * v,
|
|
@@ -221,8 +238,13 @@ export default class BAI extends IndexFile<BaiParsed> {
|
|
|
221
238
|
// contain alignments in the region. Linear index entries are monotonically
|
|
222
239
|
// non-decreasing, so the first entry at minLin is the minimum.
|
|
223
240
|
protected getLowestChunk(refIndex: BaiRefIndex, min: number) {
|
|
224
|
-
const {
|
|
225
|
-
const
|
|
226
|
-
return
|
|
241
|
+
const { linearBlockPositions, linearDataPositions } = refIndex
|
|
242
|
+
const i = Math.min(min >> BAI_LINEAR_SHIFT, linearBlockPositions.length - 1)
|
|
243
|
+
return i < 0
|
|
244
|
+
? undefined
|
|
245
|
+
: {
|
|
246
|
+
blockPosition: linearBlockPositions[i]!,
|
|
247
|
+
dataPosition: linearDataPositions[i]!,
|
|
248
|
+
}
|
|
227
249
|
}
|
|
228
250
|
}
|
package/src/bamFile.ts
CHANGED
|
@@ -232,7 +232,14 @@ export default class BamFile<T extends BamRecordLike = BAMFeature> {
|
|
|
232
232
|
|
|
233
233
|
async getHeaderPre(opts: BaseOpts = {}) {
|
|
234
234
|
if (!this.index) {
|
|
235
|
-
|
|
235
|
+
// Only reachable via `new BamFile({htsget: true})` used directly rather
|
|
236
|
+
// than through HtsgetFile, which overrides this. Throwing rather than
|
|
237
|
+
// returning undefined keeps `| undefined` off getHeader()'s public type,
|
|
238
|
+
// and makes that misuse loud instead of silently answering every query
|
|
239
|
+
// with zero records (getSeqId would find no chrToIndex).
|
|
240
|
+
throw new Error(
|
|
241
|
+
'no index to read a header from: use HtsgetFile for htsget sources',
|
|
242
|
+
)
|
|
236
243
|
}
|
|
237
244
|
const indexData = await this.index.parse(opts)
|
|
238
245
|
|
|
@@ -512,13 +519,26 @@ export default class BamFile<T extends BamRecordLike = BAMFeature> {
|
|
|
512
519
|
const chunks = res[i]!
|
|
513
520
|
for (let j = 0, jl = chunks.length; j < jl; j++) {
|
|
514
521
|
const m = chunks[j]!
|
|
515
|
-
|
|
522
|
+
// Key on the virtual-offset span — the same key _cachedChunkFeatures
|
|
523
|
+
// uses. Chunk.toString() also folds in `bin` and fetchedSize(), which
|
|
524
|
+
// keeps two chunks covering an identical span apart here even though
|
|
525
|
+
// the cache below collapses them, so their records came back twice.
|
|
526
|
+
map.set(chunkCacheKey(m), m)
|
|
516
527
|
}
|
|
517
528
|
}
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
529
|
+
const mateChunks = [...map.values()]
|
|
530
|
+
|
|
531
|
+
// Bounded for the reason ADR 0008 bounds the main query path: a viewAsPairs
|
|
532
|
+
// query over a busy region resolves to many distinct mate chunks, and an
|
|
533
|
+
// unbounded fan-out inflates every one of them at once. Same inline pool
|
|
534
|
+
// shape as _fetchChunkFeatures — ADR 0009 measured extracting a shared
|
|
535
|
+
// mapConcurrent helper at ~11% on the hot path, so it stays inline.
|
|
536
|
+
const mateFeatLists = new Array<T[]>(mateChunks.length)
|
|
537
|
+
let next = 0
|
|
538
|
+
const readNext = async () => {
|
|
539
|
+
while (next < mateChunks.length) {
|
|
540
|
+
const ci = next++
|
|
541
|
+
const features = await this._cachedChunkFeatures(mateChunks[ci]!, opts)
|
|
522
542
|
const mateRecs = [] as T[]
|
|
523
543
|
for (let i = 0, l = features.length; i < l; i++) {
|
|
524
544
|
const feature = features[i]!
|
|
@@ -529,9 +549,11 @@ export default class BamFile<T extends BamRecordLike = BAMFeature> {
|
|
|
529
549
|
mateRecs.push(feature)
|
|
530
550
|
}
|
|
531
551
|
}
|
|
532
|
-
|
|
533
|
-
}
|
|
534
|
-
|
|
552
|
+
mateFeatLists[ci] = mateRecs
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
const workers = Math.min(MAX_CONCURRENT_CHUNK_READS, mateChunks.length)
|
|
556
|
+
await Promise.all(Array.from({ length: workers }, () => readNext()))
|
|
535
557
|
return mateFeatLists.flat()
|
|
536
558
|
}
|
|
537
559
|
|
|
@@ -559,10 +581,15 @@ export default class BamFile<T extends BamRecordLike = BAMFeature> {
|
|
|
559
581
|
}
|
|
560
582
|
}
|
|
561
583
|
|
|
584
|
+
// cpositions/dpositions are `ArrayLike`, not `number[]`, because the wasm
|
|
585
|
+
// decompressor produces them as Float64Arrays — @gmod/bgzf-filehandle spreads
|
|
586
|
+
// them into plain arrays on the way out, and this signature is what lets that
|
|
587
|
+
// copy be dropped there without a change here. Only indexed reads and
|
|
588
|
+
// `.length` are used below either way.
|
|
562
589
|
readBamFeatures(
|
|
563
590
|
ba: Uint8Array,
|
|
564
|
-
cpositions: number
|
|
565
|
-
dpositions: number
|
|
591
|
+
cpositions: ArrayLike<number>,
|
|
592
|
+
dpositions: ArrayLike<number>,
|
|
566
593
|
chunk: Chunk,
|
|
567
594
|
) {
|
|
568
595
|
let blockStart = 0
|
package/src/chunk.ts
CHANGED
|
@@ -29,14 +29,6 @@ export default class Chunk {
|
|
|
29
29
|
}, fetchedSize ${this.fetchedSize()})`
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
compareTo(b: Chunk) {
|
|
33
|
-
return (
|
|
34
|
-
this.minv.compareTo(b.minv) ||
|
|
35
|
-
this.maxv.compareTo(b.maxv) ||
|
|
36
|
-
this.bin - b.bin
|
|
37
|
-
)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
32
|
fetchedSize() {
|
|
41
33
|
return this.endPosition - this.minv.blockPosition
|
|
42
34
|
}
|
package/src/csi.ts
CHANGED
|
@@ -83,16 +83,12 @@ export default class CSI extends IndexFile {
|
|
|
83
83
|
bytes.byteOffset,
|
|
84
84
|
bytes.byteLength,
|
|
85
85
|
)
|
|
86
|
-
|
|
86
|
+
// CSI\1 and CSI\2 are parsed identically here — v2 only adds fields this
|
|
87
|
+
// reader doesn't consume — so the version is validated, not retained.
|
|
87
88
|
const magic = dataView.getUint32(0, true)
|
|
88
|
-
|
|
89
|
-
if (magic === CSI1_MAGIC) {
|
|
90
|
-
csiVersion = 1
|
|
91
|
-
} else if (magic === CSI2_MAGIC) {
|
|
92
|
-
csiVersion = 2
|
|
93
|
-
} else {
|
|
94
|
-
throw new Error(`Not a CSI file ${magic}`)
|
|
89
|
+
if (magic !== CSI1_MAGIC && magic !== CSI2_MAGIC) {
|
|
95
90
|
// TODO: do we need to support big-endian CSI files?
|
|
91
|
+
throw new Error(`Not a CSI file ${magic}`)
|
|
96
92
|
}
|
|
97
93
|
|
|
98
94
|
this.minShift = dataView.getInt32(4, true)
|
|
@@ -170,12 +166,10 @@ export default class CSI extends IndexFile {
|
|
|
170
166
|
}
|
|
171
167
|
|
|
172
168
|
return {
|
|
173
|
-
csiVersion,
|
|
174
169
|
firstDataLine,
|
|
175
170
|
indices: memoizeByRefId(getIndices),
|
|
176
171
|
refCount,
|
|
177
172
|
csi: true,
|
|
178
|
-
maxBlockSize: 1 << 16,
|
|
179
173
|
...aux,
|
|
180
174
|
}
|
|
181
175
|
}
|
package/src/indexFile.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { optimizeChunks } from './util.ts'
|
|
|
4
4
|
|
|
5
5
|
import type Chunk from './chunk.ts'
|
|
6
6
|
import type { BaseOpts } from './util.ts'
|
|
7
|
-
import type {
|
|
7
|
+
import type { OffsetCoords, VirtualOffset } from './virtualOffset.ts'
|
|
8
8
|
import type { GenericFilehandle } from 'generic-filehandle2'
|
|
9
9
|
|
|
10
10
|
export interface Region {
|
|
@@ -21,7 +21,6 @@ export interface RefIndex {
|
|
|
21
21
|
export interface ParsedIndexBase<R extends RefIndex = RefIndex> {
|
|
22
22
|
firstDataLine: VirtualOffset | undefined
|
|
23
23
|
refCount: number
|
|
24
|
-
maxBlockSize: number
|
|
25
24
|
indices: (refId: number) => R | undefined
|
|
26
25
|
}
|
|
27
26
|
|
|
@@ -84,7 +83,7 @@ export default abstract class IndexFile<
|
|
|
84
83
|
protected abstract getLowestChunk(
|
|
85
84
|
refIndex: RefIndex,
|
|
86
85
|
min: number,
|
|
87
|
-
):
|
|
86
|
+
): OffsetCoords | undefined
|
|
88
87
|
|
|
89
88
|
async blocksForRange(
|
|
90
89
|
refId: number,
|
package/src/sam.ts
CHANGED
|
@@ -8,9 +8,14 @@ export function parseHeaderText(text: string) {
|
|
|
8
8
|
tag: tag.slice(1),
|
|
9
9
|
data: fields.map(f => {
|
|
10
10
|
const r = f.indexOf(':')
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
// A field with no colon is not a TAG:VALUE pair — @CO lines are free
|
|
12
|
+
// text, one comment per line (`samtools view -H c2#pad.3.0.cram`).
|
|
13
|
+
// Without this branch `slice(0, -1)` silently drops the comment's last
|
|
14
|
+
// character into the tag. Same shape @gmod/cram's parseHeaderText
|
|
15
|
+
// returns, so both feed a consumer's header parser identically.
|
|
16
|
+
return r === -1
|
|
17
|
+
? { tag: f, value: '' }
|
|
18
|
+
: { tag: f.slice(0, r), value: f.slice(r + 1) }
|
|
14
19
|
}),
|
|
15
20
|
})
|
|
16
21
|
}
|
package/src/util.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import Chunk from './chunk.ts'
|
|
2
|
-
import { longFromBytesToUnsigned } from './long.ts'
|
|
3
2
|
import { VirtualOffset } from './virtualOffset.ts'
|
|
4
3
|
|
|
5
|
-
import type {
|
|
4
|
+
import type { OffsetCoords } from './virtualOffset.ts'
|
|
6
5
|
|
|
7
6
|
export interface BamOpts {
|
|
8
7
|
viewAsPairs?: boolean
|
|
@@ -30,7 +29,7 @@ export interface BaseOpts {
|
|
|
30
29
|
onProgress?: (bytesDownloaded: number, totalBytes?: number) => void
|
|
31
30
|
}
|
|
32
31
|
|
|
33
|
-
export function optimizeChunks(chunks: Chunk[], lowest?:
|
|
32
|
+
export function optimizeChunks(chunks: Chunk[], lowest?: OffsetCoords) {
|
|
34
33
|
const n = chunks.length
|
|
35
34
|
if (n === 0) {
|
|
36
35
|
return chunks
|
|
@@ -102,9 +101,22 @@ export function optimizeChunks(chunks: Chunk[], lowest?: Offset) {
|
|
|
102
101
|
return mergedChunks
|
|
103
102
|
}
|
|
104
103
|
|
|
104
|
+
// The pseudo-bin's mapped-record count, a little-endian uint64. Read as two
|
|
105
|
+
// 32-bit halves rather than via BigInt: exact up to Number.MAX_SAFE_INTEGER,
|
|
106
|
+
// which is far past any real record count, and allocates nothing.
|
|
105
107
|
export function parsePseudoBin(bytes: Uint8Array, offset: number) {
|
|
108
|
+
const low =
|
|
109
|
+
bytes[offset]! |
|
|
110
|
+
(bytes[offset + 1]! << 8) |
|
|
111
|
+
(bytes[offset + 2]! << 16) |
|
|
112
|
+
(bytes[offset + 3]! << 24)
|
|
113
|
+
const high =
|
|
114
|
+
bytes[offset + 4]! |
|
|
115
|
+
(bytes[offset + 5]! << 8) |
|
|
116
|
+
(bytes[offset + 6]! << 16) |
|
|
117
|
+
(bytes[offset + 7]! << 24)
|
|
106
118
|
return {
|
|
107
|
-
lineCount:
|
|
119
|
+
lineCount: (high >>> 0) * 2 ** 32 + (low >>> 0),
|
|
108
120
|
}
|
|
109
121
|
}
|
|
110
122
|
|
|
@@ -117,13 +129,21 @@ export function parsePseudoBin(bytes: Uint8Array, offset: number) {
|
|
|
117
129
|
// Shrinks both the byte estimate and the actual fetch with no extra I/O.
|
|
118
130
|
export function clampChunkEnds(
|
|
119
131
|
chunks: Chunk[],
|
|
120
|
-
extraBoundaries: number
|
|
132
|
+
extraBoundaries: ArrayLike<number> = [],
|
|
121
133
|
) {
|
|
122
|
-
|
|
134
|
+
// Float64Array rather than number[]: `extraBoundaries` is the linear index,
|
|
135
|
+
// which runs to tens of thousands of entries on a human-sized reference, and
|
|
136
|
+
// this is the only place they get copied.
|
|
137
|
+
const boundaries = new Float64Array(
|
|
138
|
+
extraBoundaries.length + chunks.length * 2,
|
|
139
|
+
)
|
|
140
|
+
boundaries.set(extraBoundaries)
|
|
141
|
+
let n = extraBoundaries.length
|
|
123
142
|
for (const c of chunks) {
|
|
124
|
-
boundaries
|
|
143
|
+
boundaries[n++] = c.minv.blockPosition
|
|
144
|
+
boundaries[n++] = c.maxv.blockPosition
|
|
125
145
|
}
|
|
126
|
-
boundaries.sort(
|
|
146
|
+
boundaries.sort()
|
|
127
147
|
|
|
128
148
|
for (const c of chunks) {
|
|
129
149
|
const max = c.maxv.blockPosition
|
package/src/virtualOffset.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* The two coordinates a virtual offset packs, without the `blockPos:dataPos`
|
|
3
|
+
* string form. What every consumer that only compares positions needs — the
|
|
4
|
+
* BAI linear index stores these as raw numbers and materializes no object.
|
|
5
|
+
*/
|
|
6
|
+
export interface OffsetCoords {
|
|
2
7
|
blockPosition: number
|
|
3
8
|
dataPosition: number
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface Offset extends OffsetCoords {
|
|
4
12
|
toString(): string
|
|
5
|
-
compareTo(arg: Offset): number
|
|
6
13
|
}
|
|
7
14
|
|
|
8
15
|
export class VirtualOffset {
|
|
@@ -16,12 +23,6 @@ export class VirtualOffset {
|
|
|
16
23
|
toString() {
|
|
17
24
|
return `${this.blockPosition}:${this.dataPosition}`
|
|
18
25
|
}
|
|
19
|
-
|
|
20
|
-
compareTo(b: VirtualOffset) {
|
|
21
|
-
return (
|
|
22
|
-
this.blockPosition - b.blockPosition || this.dataPosition - b.dataPosition
|
|
23
|
-
)
|
|
24
|
-
}
|
|
25
26
|
}
|
|
26
27
|
export function fromBytes(bytes: Uint8Array, offset = 0) {
|
|
27
28
|
return new VirtualOffset(
|
package/dist/long.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function longFromBytesToUnsigned(source: Uint8Array, i?: number): number;
|
package/dist/long.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.longFromBytesToUnsigned = longFromBytesToUnsigned;
|
|
4
|
-
const TWO_PWR_32_DBL = 2 ** 32;
|
|
5
|
-
// avoids dependency on long.js
|
|
6
|
-
function longFromBytesToUnsigned(source, i = 0) {
|
|
7
|
-
const low = source[i] |
|
|
8
|
-
(source[i + 1] << 8) |
|
|
9
|
-
(source[i + 2] << 16) |
|
|
10
|
-
(source[i + 3] << 24);
|
|
11
|
-
const high = source[i + 4] |
|
|
12
|
-
(source[i + 5] << 8) |
|
|
13
|
-
(source[i + 6] << 16) |
|
|
14
|
-
(source[i + 7] << 24);
|
|
15
|
-
return (high >>> 0) * TWO_PWR_32_DBL + (low >>> 0);
|
|
16
|
-
}
|
|
17
|
-
//# sourceMappingURL=long.js.map
|
package/dist/long.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"long.js","sourceRoot":"","sources":["../src/long.ts"],"names":[],"mappings":";;AAGA,0DAYC;AAfD,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,CAAA;AAE9B,+BAA+B;AAC/B,SAAgB,uBAAuB,CAAC,MAAkB,EAAE,CAAC,GAAG,CAAC;IAC/D,MAAM,GAAG,GACP,MAAM,CAAC,CAAC,CAAE;QACV,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC;QACrB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC;QACtB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC,CAAA;IACxB,MAAM,IAAI,GACR,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE;QACd,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC;QACrB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC;QACtB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC,CAAA;IACxB,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,cAAc,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAA;AACpD,CAAC"}
|
package/esm/long.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function longFromBytesToUnsigned(source: Uint8Array, i?: number): number;
|
package/esm/long.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
const TWO_PWR_32_DBL = 2 ** 32;
|
|
2
|
-
// avoids dependency on long.js
|
|
3
|
-
export function longFromBytesToUnsigned(source, i = 0) {
|
|
4
|
-
const low = source[i] |
|
|
5
|
-
(source[i + 1] << 8) |
|
|
6
|
-
(source[i + 2] << 16) |
|
|
7
|
-
(source[i + 3] << 24);
|
|
8
|
-
const high = source[i + 4] |
|
|
9
|
-
(source[i + 5] << 8) |
|
|
10
|
-
(source[i + 6] << 16) |
|
|
11
|
-
(source[i + 7] << 24);
|
|
12
|
-
return (high >>> 0) * TWO_PWR_32_DBL + (low >>> 0);
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=long.js.map
|
package/esm/long.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"long.js","sourceRoot":"","sources":["../src/long.ts"],"names":[],"mappings":"AAAA,MAAM,cAAc,GAAG,CAAC,IAAI,EAAE,CAAA;AAE9B,+BAA+B;AAC/B,MAAM,UAAU,uBAAuB,CAAC,MAAkB,EAAE,CAAC,GAAG,CAAC;IAC/D,MAAM,GAAG,GACP,MAAM,CAAC,CAAC,CAAE;QACV,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC;QACrB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC;QACtB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC,CAAA;IACxB,MAAM,IAAI,GACR,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE;QACd,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,CAAC,CAAC;QACrB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC;QACtB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAE,IAAI,EAAE,CAAC,CAAA;IACxB,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,GAAG,cAAc,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAA;AACpD,CAAC"}
|
package/src/long.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const TWO_PWR_32_DBL = 2 ** 32
|
|
2
|
-
|
|
3
|
-
// avoids dependency on long.js
|
|
4
|
-
export function longFromBytesToUnsigned(source: Uint8Array, i = 0) {
|
|
5
|
-
const low =
|
|
6
|
-
source[i]! |
|
|
7
|
-
(source[i + 1]! << 8) |
|
|
8
|
-
(source[i + 2]! << 16) |
|
|
9
|
-
(source[i + 3]! << 24)
|
|
10
|
-
const high =
|
|
11
|
-
source[i + 4]! |
|
|
12
|
-
(source[i + 5]! << 8) |
|
|
13
|
-
(source[i + 6]! << 16) |
|
|
14
|
-
(source[i + 7]! << 24)
|
|
15
|
-
return (high >>> 0) * TWO_PWR_32_DBL + (low >>> 0)
|
|
16
|
-
}
|