@gmod/tabix 3.5.3 → 3.5.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/README.md +12 -0
- package/dist/csi.d.ts +5 -9
- package/dist/csi.js +17 -54
- package/dist/csi.js.map +1 -1
- package/dist/indexFile.d.ts +43 -6
- package/dist/indexFile.js +48 -0
- package/dist/indexFile.js.map +1 -1
- package/dist/tabix-bundle.js +1 -1
- package/dist/tabixIndexedFile.d.ts +42 -7
- package/dist/tabixIndexedFile.js +104 -27
- package/dist/tabixIndexedFile.js.map +1 -1
- package/dist/tbi.d.ts +14 -2
- package/dist/tbi.js +36 -58
- package/dist/tbi.js.map +1 -1
- package/esm/csi.d.ts +5 -9
- package/esm/csi.js +18 -55
- package/esm/csi.js.map +1 -1
- package/esm/indexFile.d.ts +43 -6
- package/esm/indexFile.js +48 -0
- package/esm/indexFile.js.map +1 -1
- package/esm/tabixIndexedFile.d.ts +42 -7
- package/esm/tabixIndexedFile.js +104 -27
- package/esm/tabixIndexedFile.js.map +1 -1
- package/esm/tbi.d.ts +14 -2
- package/esm/tbi.js +37 -59
- package/esm/tbi.js.map +1 -1
- package/package.json +2 -2
- package/src/csi.ts +26 -74
- package/src/indexFile.ts +86 -8
- package/src/tabixIndexedFile.ts +120 -44
- package/src/tbi.ts +48 -82
package/README.md
CHANGED
|
@@ -148,6 +148,18 @@ Separate from `getHeader` because htslib treats the two differently: a line is
|
|
|
148
148
|
not data when the index's skip count covers it **or** it starts with the meta
|
|
149
149
|
character, but `tabix -H` prints only the latter.
|
|
150
150
|
|
|
151
|
+
### `getHeaderLines(opts?): Promise<string[]>`
|
|
152
|
+
|
|
153
|
+
Returns the file's header lines however the file keeps them: the commented block
|
|
154
|
+
when there is one, and otherwise the rows the index counted. Empty lines are
|
|
155
|
+
dropped.
|
|
156
|
+
|
|
157
|
+
This is usually the one you want. Reading `getHeader` alone cannot tell a file
|
|
158
|
+
that has no header from one whose header is not commented — both come back as
|
|
159
|
+
the empty string — so callers fall back to an assumed column layout and quietly
|
|
160
|
+
mis-name columns. Both forms are parsed from a single read of the file's leading
|
|
161
|
+
blocks, which is also shared with `getHeader` and `getSkippedLines`.
|
|
162
|
+
|
|
151
163
|
### `getReferenceSequenceNames(opts?): Promise<string[]>`
|
|
152
164
|
|
|
153
165
|
Returns reference sequence names in index order.
|
package/dist/csi.d.ts
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import Chunk from './chunk.ts';
|
|
2
1
|
import IndexFile from './indexFile.ts';
|
|
3
|
-
import type { Options, RefIndex } from './indexFile.ts';
|
|
2
|
+
import type { IndexData, Options, RefIndex } from './indexFile.ts';
|
|
4
3
|
import type VirtualOffset from './virtualOffset.ts';
|
|
5
4
|
export default class CSI extends IndexFile {
|
|
6
|
-
private maxBinNumber;
|
|
7
|
-
private depth;
|
|
8
|
-
private minShift;
|
|
9
5
|
/** @internal */
|
|
10
6
|
_parse(opts?: Options): Promise<{
|
|
11
7
|
csi: boolean;
|
|
@@ -14,6 +10,7 @@ export default class CSI extends IndexFile {
|
|
|
14
10
|
firstDataLine: VirtualOffset | undefined;
|
|
15
11
|
csiVersion: number;
|
|
16
12
|
indices: (refId: number) => RefIndex | undefined;
|
|
13
|
+
minShift: number;
|
|
17
14
|
depth: number;
|
|
18
15
|
maxBinNumber: number;
|
|
19
16
|
maxRefLength: number;
|
|
@@ -35,6 +32,7 @@ export default class CSI extends IndexFile {
|
|
|
35
32
|
firstDataLine: VirtualOffset | undefined;
|
|
36
33
|
csiVersion: number;
|
|
37
34
|
indices: (refId: number) => RefIndex | undefined;
|
|
35
|
+
minShift: number;
|
|
38
36
|
depth: number;
|
|
39
37
|
maxBinNumber: number;
|
|
40
38
|
maxRefLength: number;
|
|
@@ -49,7 +47,6 @@ export default class CSI extends IndexFile {
|
|
|
49
47
|
coordinateType: string;
|
|
50
48
|
format: string;
|
|
51
49
|
}>;
|
|
52
|
-
blocksForRange(refName: string, min: number, max: number, opts?: Options): Promise<Chunk[]>;
|
|
53
50
|
/**
|
|
54
51
|
* CSI's equivalent of the BAI/TBI linear index: the loffset of the deepest
|
|
55
52
|
* indexed bin covering `beg` is the earliest virtual offset any record
|
|
@@ -57,7 +54,6 @@ export default class CSI extends IndexFile {
|
|
|
57
54
|
* Walks leaf -> previous sibling -> parent until an indexed bin is found.
|
|
58
55
|
* SYNC: htslib hts_itr_query min_off computation
|
|
59
56
|
*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
reg2bins(beg: number, end: number): (readonly [number, number])[];
|
|
57
|
+
protected lowestOffset(ref: RefIndex, beg: number, { minShift, depth }: IndexData): VirtualOffset | undefined;
|
|
58
|
+
protected reg2bins(beg: number, end: number, { minShift, depth, maxBinNumber }: IndexData): (readonly [number, number])[];
|
|
63
59
|
}
|
package/dist/csi.js
CHANGED
|
@@ -3,7 +3,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
|
|
7
6
|
const chunk_ts_1 = __importDefault(require("./chunk.js"));
|
|
8
7
|
const indexFile_ts_1 = __importDefault(require("./indexFile.js"));
|
|
9
8
|
const util_ts_1 = require("./util.js");
|
|
@@ -19,17 +18,9 @@ function rshift(num, bits) {
|
|
|
19
18
|
return Math.floor(num / 2 ** bits);
|
|
20
19
|
}
|
|
21
20
|
class CSI extends indexFile_ts_1.default {
|
|
22
|
-
maxBinNumber = 0;
|
|
23
|
-
depth = 0;
|
|
24
|
-
minShift = 0;
|
|
25
21
|
/** @internal */
|
|
26
22
|
async _parse(opts = {}) {
|
|
27
|
-
const
|
|
28
|
-
signal: opts.signal,
|
|
29
|
-
onProgress: opts.onProgress,
|
|
30
|
-
});
|
|
31
|
-
const bytes = (await (0, bgzf_filehandle_1.unzip)(buf));
|
|
32
|
-
const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
23
|
+
const { bytes, dataView } = await this.readIndexBytes(opts);
|
|
33
24
|
const magic = dataView.getUint32(0, true);
|
|
34
25
|
let csiVersion;
|
|
35
26
|
if (magic === CSI1_MAGIC) {
|
|
@@ -41,11 +32,10 @@ class CSI extends indexFile_ts_1.default {
|
|
|
41
32
|
else {
|
|
42
33
|
throw new Error(`Not a CSI file (magic=${magic})`);
|
|
43
34
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
const maxRefLength = 2 ** (this.minShift + this.depth * 3);
|
|
35
|
+
const minShift = dataView.getInt32(4, true);
|
|
36
|
+
const depth = dataView.getInt32(8, true);
|
|
37
|
+
const maxBinNumber = ((1 << ((depth + 1) * 3)) - 1) / 7;
|
|
38
|
+
const maxRefLength = 2 ** (minShift + depth * 3);
|
|
49
39
|
const auxLength = dataView.getInt32(12, true);
|
|
50
40
|
const aux = auxLength >= 30
|
|
51
41
|
? (0, util_ts_1.parseAuxData)(bytes, 16)
|
|
@@ -123,40 +113,12 @@ class CSI extends indexFile_ts_1.default {
|
|
|
123
113
|
firstDataLine,
|
|
124
114
|
csiVersion,
|
|
125
115
|
indices: (0, util_ts_1.memoizeByRefId)(getIndices),
|
|
126
|
-
|
|
116
|
+
minShift,
|
|
117
|
+
depth,
|
|
127
118
|
maxBinNumber,
|
|
128
119
|
maxRefLength,
|
|
129
120
|
};
|
|
130
121
|
}
|
|
131
|
-
async blocksForRange(refName, min, max, opts = {}) {
|
|
132
|
-
if (min < 0) {
|
|
133
|
-
min = 0;
|
|
134
|
-
}
|
|
135
|
-
const indexData = await this.parse(opts);
|
|
136
|
-
const refId = indexData.refNameToId[refName];
|
|
137
|
-
if (refId === undefined) {
|
|
138
|
-
return [];
|
|
139
|
-
}
|
|
140
|
-
const ba = indexData.indices(refId);
|
|
141
|
-
if (!ba) {
|
|
142
|
-
return [];
|
|
143
|
-
}
|
|
144
|
-
// List of bin #s that overlap min, max
|
|
145
|
-
const overlappingBins = this.reg2bins(min, max);
|
|
146
|
-
const chunks = [];
|
|
147
|
-
// Find chunks in overlapping bins. Leaf bins (< 4681) are not pruned
|
|
148
|
-
for (const [start, end] of overlappingBins) {
|
|
149
|
-
for (let bin = start; bin <= end; bin++) {
|
|
150
|
-
const binChunks = ba.binIndex[bin];
|
|
151
|
-
if (binChunks) {
|
|
152
|
-
for (const c of binChunks) {
|
|
153
|
-
chunks.push(c);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
return (0, util_ts_1.optimizeChunks)(chunks, this.minOffset(ba.loffsets, min));
|
|
159
|
-
}
|
|
160
122
|
/**
|
|
161
123
|
* CSI's equivalent of the BAI/TBI linear index: the loffset of the deepest
|
|
162
124
|
* indexed bin covering `beg` is the earliest virtual offset any record
|
|
@@ -164,11 +126,12 @@ class CSI extends indexFile_ts_1.default {
|
|
|
164
126
|
* Walks leaf -> previous sibling -> parent until an indexed bin is found.
|
|
165
127
|
* SYNC: htslib hts_itr_query min_off computation
|
|
166
128
|
*/
|
|
167
|
-
|
|
129
|
+
lowestOffset(ref, beg, { minShift, depth }) {
|
|
130
|
+
const { loffsets } = ref;
|
|
168
131
|
let found;
|
|
169
132
|
if (loffsets) {
|
|
170
133
|
// first bin of the deepest level, i.e. (8**depth - 1) / 7
|
|
171
|
-
let bin = (lshift(1, 3 *
|
|
134
|
+
let bin = (lshift(1, 3 * depth) - 1) / 7 + rshift(Math.max(beg, 0), minShift);
|
|
172
135
|
while (found === undefined && bin > 0) {
|
|
173
136
|
found = loffsets[bin];
|
|
174
137
|
if (found === undefined) {
|
|
@@ -181,22 +144,22 @@ class CSI extends indexFile_ts_1.default {
|
|
|
181
144
|
}
|
|
182
145
|
return found;
|
|
183
146
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const maxPos = 2 ** (
|
|
147
|
+
reg2bins(beg, end, { minShift, depth, maxBinNumber }) {
|
|
148
|
+
beg = Math.max(beg, 0);
|
|
149
|
+
const maxPos = 2 ** (minShift + depth * 3);
|
|
187
150
|
if (end > maxPos) {
|
|
188
151
|
end = maxPos;
|
|
189
152
|
}
|
|
190
153
|
end -= 1;
|
|
191
154
|
let l = 0;
|
|
192
155
|
let t = 0;
|
|
193
|
-
let s =
|
|
156
|
+
let s = minShift + depth * 3;
|
|
194
157
|
const bins = [];
|
|
195
|
-
for (; l <=
|
|
158
|
+
for (; l <= depth; s -= 3, t += lshift(1, l * 3), l += 1) {
|
|
196
159
|
const b = t + rshift(beg, s);
|
|
197
160
|
const e = t + rshift(end, s);
|
|
198
|
-
if (e - b + bins.length >
|
|
199
|
-
throw new Error(`query ${beg}-${end} is too large for current binning scheme (shift ${
|
|
161
|
+
if (e - b + bins.length > maxBinNumber) {
|
|
162
|
+
throw new Error(`query ${beg}-${end} is too large for current binning scheme (shift ${minShift}, depth ${depth}), try a smaller query or a coarser index binning scheme`);
|
|
200
163
|
}
|
|
201
164
|
bins.push([b, e]);
|
|
202
165
|
}
|
package/dist/csi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csi.js","sourceRoot":"","sources":["../src/csi.ts"],"names":[],"mappings":";;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"csi.js","sourceRoot":"","sources":["../src/csi.ts"],"names":[],"mappings":"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"}
|
package/dist/indexFile.d.ts
CHANGED
|
@@ -33,13 +33,19 @@ export interface IndexData {
|
|
|
33
33
|
indices: (refId: number) => RefIndex | undefined;
|
|
34
34
|
maxRefLength: number;
|
|
35
35
|
skipLines?: number;
|
|
36
|
-
maxBinNumber?: number;
|
|
37
36
|
maxBlockSize: number;
|
|
38
37
|
firstDataLine?: VirtualOffset;
|
|
39
38
|
refCount?: number;
|
|
40
39
|
csi?: boolean;
|
|
41
40
|
csiVersion?: number;
|
|
42
|
-
|
|
41
|
+
/**
|
|
42
|
+
* The binning scheme. TBI reports these too, though its own are fixed by the
|
|
43
|
+
* format (minShift 14, depth 5) rather than read from the file: they are the
|
|
44
|
+
* same scheme, and CSI exists to let a file choose other values for them.
|
|
45
|
+
*/
|
|
46
|
+
minShift: number;
|
|
47
|
+
depth: number;
|
|
48
|
+
maxBinNumber: number;
|
|
43
49
|
}
|
|
44
50
|
export default abstract class IndexFile {
|
|
45
51
|
filehandle: GenericFilehandle;
|
|
@@ -48,6 +54,25 @@ export default abstract class IndexFile {
|
|
|
48
54
|
filehandle: GenericFilehandle;
|
|
49
55
|
});
|
|
50
56
|
protected abstract _parse(opts: Options): Promise<IndexData>;
|
|
57
|
+
/**
|
|
58
|
+
* The bins that may overlap [beg, end), as one inclusive [first, last] range
|
|
59
|
+
* per level of the binning scheme.
|
|
60
|
+
*/
|
|
61
|
+
protected abstract reg2bins(beg: number, end: number, indexData: IndexData): (readonly [number, number])[];
|
|
62
|
+
/**
|
|
63
|
+
* The earliest virtual offset any record overlapping `beg` can have, so that
|
|
64
|
+
* chunks ending at or before it can be dropped. TBI reads it off the linear
|
|
65
|
+
* index; CSI, which has none, off the bins' loffsets.
|
|
66
|
+
*/
|
|
67
|
+
protected abstract lowestOffset(ref: RefIndex, beg: number, indexData: IndexData): VirtualOffset | undefined;
|
|
68
|
+
/**
|
|
69
|
+
* The whole index file, decompressed, with a DataView over it. Both .tbi and
|
|
70
|
+
* .csi are bgzf-compressed and read whole, so both parsers start here.
|
|
71
|
+
*/
|
|
72
|
+
protected readIndexBytes(opts: Options): Promise<{
|
|
73
|
+
bytes: Uint8Array<ArrayBufferLike>;
|
|
74
|
+
dataView: DataView<ArrayBufferLike>;
|
|
75
|
+
}>;
|
|
51
76
|
/** @internal */
|
|
52
77
|
lineCount(refName: string, opts?: Options): Promise<number>;
|
|
53
78
|
/** @internal */
|
|
@@ -64,16 +89,28 @@ export default abstract class IndexFile {
|
|
|
64
89
|
format: string;
|
|
65
90
|
maxRefLength: number;
|
|
66
91
|
skipLines?: number;
|
|
67
|
-
maxBinNumber?: number;
|
|
68
92
|
maxBlockSize: number;
|
|
69
93
|
firstDataLine?: VirtualOffset;
|
|
70
94
|
refCount?: number;
|
|
71
95
|
csi?: boolean;
|
|
72
96
|
csiVersion?: number;
|
|
73
|
-
|
|
97
|
+
/**
|
|
98
|
+
* The binning scheme. TBI reports these too, though its own are fixed by the
|
|
99
|
+
* format (minShift 14, depth 5) rather than read from the file: they are the
|
|
100
|
+
* same scheme, and CSI exists to let a file choose other values for them.
|
|
101
|
+
*/
|
|
102
|
+
minShift: number;
|
|
103
|
+
depth: number;
|
|
104
|
+
maxBinNumber: number;
|
|
74
105
|
}>;
|
|
75
|
-
/**
|
|
76
|
-
|
|
106
|
+
/**
|
|
107
|
+
* The chunks of the data file that may hold records overlapping the region.
|
|
108
|
+
* The two index formats differ only in their binning scheme and in where
|
|
109
|
+
* they keep the pruning floor, which is what the two hooks above supply.
|
|
110
|
+
*
|
|
111
|
+
* @internal
|
|
112
|
+
*/
|
|
113
|
+
blocksForRange(refName: string, min: number, max: number, opts?: Options): Promise<Chunk[]>;
|
|
77
114
|
/** @internal */
|
|
78
115
|
parse(opts?: Options): Promise<IndexData>;
|
|
79
116
|
/** @internal */
|
package/dist/indexFile.js
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const bgzf_filehandle_1 = require("@gmod/bgzf-filehandle");
|
|
4
|
+
const util_ts_1 = require("./util.js");
|
|
3
5
|
class IndexFile {
|
|
4
6
|
filehandle;
|
|
5
7
|
parseP;
|
|
6
8
|
constructor({ filehandle }) {
|
|
7
9
|
this.filehandle = filehandle;
|
|
8
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* The whole index file, decompressed, with a DataView over it. Both .tbi and
|
|
13
|
+
* .csi are bgzf-compressed and read whole, so both parsers start here.
|
|
14
|
+
*/
|
|
15
|
+
async readIndexBytes(opts) {
|
|
16
|
+
const buf = await this.filehandle.readFile({
|
|
17
|
+
signal: opts.signal,
|
|
18
|
+
onProgress: opts.onProgress,
|
|
19
|
+
});
|
|
20
|
+
const bytes = await (0, bgzf_filehandle_1.unzip)(buf);
|
|
21
|
+
return {
|
|
22
|
+
bytes,
|
|
23
|
+
dataView: new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
9
26
|
/** @internal */
|
|
10
27
|
async lineCount(refName, opts = {}) {
|
|
11
28
|
const indexData = await this.parse(opts);
|
|
@@ -20,6 +37,37 @@ class IndexFile {
|
|
|
20
37
|
const { indices: _indices, ...rest } = await this.parse(opts);
|
|
21
38
|
return rest;
|
|
22
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* The chunks of the data file that may hold records overlapping the region.
|
|
42
|
+
* The two index formats differ only in their binning scheme and in where
|
|
43
|
+
* they keep the pruning floor, which is what the two hooks above supply.
|
|
44
|
+
*
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
async blocksForRange(refName, min, max, opts = {}) {
|
|
48
|
+
const indexData = await this.parse(opts);
|
|
49
|
+
const refId = indexData.refNameToId[refName];
|
|
50
|
+
if (refId === undefined) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
const ba = indexData.indices(refId);
|
|
54
|
+
if (!ba) {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
// Find chunks in overlapping bins. Leaf bins are not pruned.
|
|
58
|
+
const chunks = [];
|
|
59
|
+
for (const [start, end] of this.reg2bins(min, max, indexData)) {
|
|
60
|
+
for (let bin = start; bin <= end; bin++) {
|
|
61
|
+
const binChunks = ba.binIndex[bin];
|
|
62
|
+
if (binChunks) {
|
|
63
|
+
for (const c of binChunks) {
|
|
64
|
+
chunks.push(c);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return (0, util_ts_1.optimizeChunks)(chunks, this.lowestOffset(ba, min, indexData));
|
|
70
|
+
}
|
|
23
71
|
/** @internal */
|
|
24
72
|
async parse(opts = {}) {
|
|
25
73
|
this.parseP ??= this._parse(opts).catch((error) => {
|
package/dist/indexFile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexFile.js","sourceRoot":"","sources":["../src/indexFile.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"indexFile.js","sourceRoot":"","sources":["../src/indexFile.ts"],"names":[],"mappings":"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"}
|