@gmod/tabix 1.5.14 → 1.6.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/CHANGELOG.md +9 -5
- package/README.md +182 -35
- package/dist/chunk.js +0 -1
- package/dist/chunk.js.map +1 -1
- package/dist/csi.d.ts +1 -1
- package/dist/csi.js +132 -128
- package/dist/csi.js.map +1 -1
- package/dist/indexFile.js +15 -41
- package/dist/indexFile.js.map +1 -1
- package/dist/tabix-bundle.js +2 -0
- package/dist/tabix-bundle.js.LICENSE.txt +8 -0
- package/dist/tabixIndexedFile.d.ts +49 -25
- package/dist/tabixIndexedFile.js +214 -195
- package/dist/tabixIndexedFile.js.map +1 -1
- package/dist/tbi.js +169 -173
- package/dist/tbi.js.map +1 -1
- package/dist/util.d.ts +7 -6
- package/dist/util.js +9 -19
- package/dist/util.js.map +1 -1
- package/dist/virtualOffset.d.ts +0 -1
- package/dist/virtualOffset.js +0 -13
- package/dist/virtualOffset.js.map +1 -1
- package/esm/chunk.js +0 -1
- package/esm/chunk.js.map +1 -1
- package/esm/csi.d.ts +1 -1
- package/esm/csi.js +4 -4
- package/esm/csi.js.map +1 -1
- package/esm/indexFile.js +1 -1
- package/esm/indexFile.js.map +1 -1
- package/esm/tabixIndexedFile.d.ts +49 -25
- package/esm/tabixIndexedFile.js +134 -90
- package/esm/tabixIndexedFile.js.map +1 -1
- package/esm/tbi.js +6 -5
- package/esm/tbi.js.map +1 -1
- package/esm/util.d.ts +7 -6
- package/esm/util.js +6 -5
- package/esm/util.js.map +1 -1
- package/esm/virtualOffset.d.ts +0 -1
- package/esm/virtualOffset.js +0 -13
- package/esm/virtualOffset.js.map +1 -1
- package/package.json +24 -19
- package/src/chunk.ts +0 -1
- package/src/csi.ts +6 -5
- package/src/indexFile.ts +1 -1
- package/src/tabixIndexedFile.ts +141 -106
- package/src/tbi.ts +7 -6
- package/src/util.ts +7 -6
- package/src/virtualOffset.ts +7 -21
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
# [1.6.0](https://github.com/GMOD/tabix-js/compare/v1.5.15...v1.6.0) (2024-11-30)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
### Reverts
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
## [1.5.15](https://github.com/GMOD/tabix-js/compare/v1.5.14...v1.5.15) (2024-08-30)
|
|
7
6
|
|
|
7
|
+
## [1.5.14](https://github.com/GMOD/tabix-js/compare/v1.5.13...v1.5.14) (2024-07-23)
|
|
8
|
+
|
|
9
|
+
### Reverts
|
|
8
10
|
|
|
11
|
+
- Revert "Bump to eslint 9"
|
|
12
|
+
([9bd49b1](https://github.com/GMOD/tabix-js/commit/9bd49b1132f632b0e7847d9b95cf3cb08c424360))
|
|
9
13
|
|
|
10
14
|
## [1.5.13](https://github.com/GMOD/tabix-js/compare/v1.5.12...v1.5.13) (2024-01-09)
|
|
11
15
|
|
|
@@ -13,8 +17,8 @@
|
|
|
13
17
|
|
|
14
18
|
## [1.5.12](https://github.com/GMOD/tabix-js/compare/v1.5.11...v1.5.12) (2024-01-09)
|
|
15
19
|
|
|
16
|
-
- Add missing abort signal to the @gmod/abortable-promise-cache fetch for tabix
|
|
17
|
-
(#143)
|
|
20
|
+
- Add missing abort signal to the @gmod/abortable-promise-cache fetch for tabix
|
|
21
|
+
chunks (#143)
|
|
18
22
|
|
|
19
23
|
## [1.5.11](https://github.com/GMOD/tabix-js/compare/v1.5.10...v1.5.11) (2023-07-10)
|
|
20
24
|
|
package/README.md
CHANGED
|
@@ -22,6 +22,15 @@ const { TabixIndexedFile } = require('@gmod/tabix')
|
|
|
22
22
|
import { TabixIndexedFile } from '@gmod/tabix'
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
### Single file bundle
|
|
26
|
+
|
|
27
|
+
You can use tabix-js without NPM also with the tabix-bundle.js. See the example
|
|
28
|
+
directory for usage with script tag [example/index.html](example/index.html)
|
|
29
|
+
|
|
30
|
+
```html
|
|
31
|
+
<script src="https://unpkg.com/@gmod/tabix/dist/tabix-bundle.js"></script>
|
|
32
|
+
```
|
|
33
|
+
|
|
25
34
|
### TabixIndexedFile constructor
|
|
26
35
|
|
|
27
36
|
Basic usage of TabixIndexedFile under node.js supplies a path and optionally a
|
|
@@ -38,10 +47,10 @@ const tbiIndexed = new TabixIndexedFile({
|
|
|
38
47
|
|
|
39
48
|
```
|
|
40
49
|
|
|
41
|
-
You can also use CSI indexes. Note also the usage of the renameRefSeqs
|
|
42
|
-
The renameRefSeqs callback makes it so that you can use
|
|
43
|
-
file.getLines('1',0,100,...) even when the file itself contains names like
|
|
44
|
-
'chr1' (can also do the reverse by customizing the renameRefSeqs callback)
|
|
50
|
+
You can also use CSI indexes. Note also the usage of the `renameRefSeqs`
|
|
51
|
+
callback. The `renameRefSeqs` callback makes it so that you can use
|
|
52
|
+
`file.getLines('1',0,100,...)` even when the file itself contains names like
|
|
53
|
+
'chr1' (can also do the reverse by customizing the `renameRefSeqs` callback)
|
|
45
54
|
|
|
46
55
|
```typescript
|
|
47
56
|
// can also open tabix files that have a .csi index
|
|
@@ -55,9 +64,15 @@ const csiIndexed = new TabixIndexedFile({
|
|
|
55
64
|
|
|
56
65
|
#### TabixIndexedFile constructor with remote files
|
|
57
66
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
```typescript
|
|
68
|
+
const remoteTbiIndexed = new TabixIndexedFile({
|
|
69
|
+
url: 'http://yourhost/file.vcf.gz',
|
|
70
|
+
tbiUrl: 'http://yourhost/file.vcf.gz.tbi', // can also be csiUrl
|
|
71
|
+
})
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
You can also alternatively supply a filehandle-like object with the
|
|
75
|
+
[generic-filehandle](https://github.com/GMOD/generic-filehandle): example
|
|
61
76
|
|
|
62
77
|
```typescript
|
|
63
78
|
// use a remote file or other filehandle, note RemoteFile comes from https://github.com/GMOD/generic-filehandle
|
|
@@ -68,9 +83,9 @@ const remoteTbiIndexed = new TabixIndexedFile({
|
|
|
68
83
|
})
|
|
69
84
|
```
|
|
70
85
|
|
|
71
|
-
This works in both the browser and in node.js, but note that in node.js you
|
|
72
|
-
to also supply a custom fetch function to the RemoteFile constructor e.g.
|
|
73
|
-
this
|
|
86
|
+
This works in both the browser and in node.js, but note that in node.js you may
|
|
87
|
+
have to also supply a custom fetch function to the RemoteFile constructor e.g.
|
|
88
|
+
like this
|
|
74
89
|
|
|
75
90
|
```typescript
|
|
76
91
|
// for node.js you have to manually supply a fetch function e.g. node-fetch to RemoteFile
|
|
@@ -102,8 +117,8 @@ await tbiIndexed.getLines('ctgA', 200, 300, function (line, fileOffset) {
|
|
|
102
117
|
After running this, your `lines` array would contain an array of lines from the
|
|
103
118
|
file that match your query range
|
|
104
119
|
|
|
105
|
-
You can also supply some extra arguments to getLines with this format, but
|
|
106
|
-
are sort of obscure and only used in some circumstances
|
|
120
|
+
You can also supply some extra arguments to `getLines` with this format, but
|
|
121
|
+
these are sort of obscure and only used in some circumstances
|
|
107
122
|
|
|
108
123
|
```typescript
|
|
109
124
|
const lines = []
|
|
@@ -124,8 +139,8 @@ Notes about the returned values of `getLines`:
|
|
|
124
139
|
- the callback is also called with a `fileOffset` that can be used to uniquely
|
|
125
140
|
identify lines based on their virtual file offset where the line is found in
|
|
126
141
|
the file
|
|
127
|
-
- if getLines is called with an undefined `end` parameter it gets all lines
|
|
128
|
-
start going to the end of the contig e.g.
|
|
142
|
+
- if `getLines` is called with an undefined `end` parameter it gets all lines
|
|
143
|
+
from start going to the end of the contig e.g.
|
|
129
144
|
|
|
130
145
|
```typescript
|
|
131
146
|
const lines = []
|
|
@@ -133,32 +148,164 @@ await tbiIndexed.getLines('ctgA', 0, undefined, line=>lines.push(line))`
|
|
|
133
148
|
console.log(lines)
|
|
134
149
|
```
|
|
135
150
|
|
|
136
|
-
|
|
151
|
+
## API (auto-generated)
|
|
152
|
+
|
|
153
|
+
### TabixIndexedFile
|
|
154
|
+
|
|
155
|
+
<!-- Generated by documentation.js. Update this documentation by updating the source code. -->
|
|
156
|
+
|
|
157
|
+
##### Table of Contents
|
|
158
|
+
|
|
159
|
+
- [constructor](#constructor)
|
|
160
|
+
- [Parameters](#parameters)
|
|
161
|
+
- [getLines](#getlines)
|
|
162
|
+
- [Parameters](#parameters-1)
|
|
163
|
+
- [getHeaderBuffer](#getheaderbuffer)
|
|
164
|
+
- [Parameters](#parameters-2)
|
|
165
|
+
- [getHeader](#getheader)
|
|
166
|
+
- [Parameters](#parameters-3)
|
|
167
|
+
- [getReferenceSequenceNames](#getreferencesequencenames)
|
|
168
|
+
- [Parameters](#parameters-4)
|
|
169
|
+
- [checkLine](#checkline)
|
|
170
|
+
- [Parameters](#parameters-5)
|
|
171
|
+
- [lineCount](#linecount)
|
|
172
|
+
- [Parameters](#parameters-6)
|
|
173
|
+
- [readChunk](#readchunk)
|
|
174
|
+
- [Parameters](#parameters-7)
|
|
175
|
+
|
|
176
|
+
#### constructor
|
|
177
|
+
|
|
178
|
+
##### Parameters
|
|
179
|
+
|
|
180
|
+
- `args`
|
|
181
|
+
**[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** 
|
|
182
|
+
|
|
183
|
+
- `args.path`
|
|
184
|
+
**[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** 
|
|
185
|
+
- `args.filehandle` **filehandle?** 
|
|
186
|
+
- `args.url`
|
|
187
|
+
**[url](https://developer.mozilla.org/docs/Web/API/URL/URL)?** 
|
|
188
|
+
- `args.tbiPath`
|
|
189
|
+
**[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** 
|
|
190
|
+
- `args.tbiUrl` **tbiUrl?** 
|
|
191
|
+
- `args.tbiFilehandle` **filehandle?** 
|
|
192
|
+
- `args.csiPath`
|
|
193
|
+
**[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)?** 
|
|
194
|
+
- `args.csiUrl` **csiUrl?** 
|
|
195
|
+
- `args.csiFilehandle` **filehandle?** 
|
|
196
|
+
- `args.yieldTime`
|
|
197
|
+
**[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)?**
|
|
198
|
+
yield to main thread after N milliseconds if reading features is taking a
|
|
199
|
+
long time to avoid hanging main thread (optional, default `500`)
|
|
200
|
+
- `args.renameRefSeqs`
|
|
201
|
+
**[function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function)?**
|
|
202
|
+
optional function with sig `string => string` to transform reference
|
|
203
|
+
sequence names for the purpose of indexing and querying. note that the data
|
|
204
|
+
that is returned is not altered, just the names of the reference sequences
|
|
205
|
+
that are used for querying. (optional, default `n=>n`)
|
|
206
|
+
- `args.chunkCacheSize` (optional, default `5*2**20`)
|
|
207
|
+
|
|
208
|
+
#### getLines
|
|
209
|
+
|
|
210
|
+
##### Parameters
|
|
211
|
+
|
|
212
|
+
- `refName`
|
|
213
|
+
**[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)**
|
|
214
|
+
name of the reference sequence
|
|
215
|
+
- `s`
|
|
216
|
+
**([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)
|
|
217
|
+
|
|
|
218
|
+
[undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** 
|
|
219
|
+
- `e`
|
|
220
|
+
**([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)
|
|
221
|
+
|
|
|
222
|
+
[undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** 
|
|
223
|
+
- `opts` **(GetLinesOpts | GetLinesCallback)** callback called for each line in
|
|
224
|
+
the region. can also pass a object param containing obj.lineCallback,
|
|
225
|
+
obj.signal, etc
|
|
226
|
+
- `start` start of the region (in 0-based half-open coordinates)
|
|
227
|
+
- `end` end of the region (in 0-based half-open coordinates)
|
|
228
|
+
|
|
229
|
+
Returns **any** promise that is resolved when the whole read is finished,
|
|
230
|
+
rejected on error
|
|
137
231
|
|
|
138
|
-
|
|
139
|
-
// get the approximate number of data lines in the
|
|
140
|
-
// file for the given reference sequence, excluding header, comment, and whitespace lines
|
|
141
|
-
// uses the extra bin from tabix
|
|
142
|
-
const numLines = await tbiIndexed.lineCount('ctgA')
|
|
143
|
-
// or const numLines = await tbiIndexed.lineCount('ctgA', { signal: aborter.signal })
|
|
144
|
-
```
|
|
232
|
+
#### getHeaderBuffer
|
|
145
233
|
|
|
146
|
-
|
|
234
|
+
get a buffer containing the "header" region of the file, which are the bytes up
|
|
235
|
+
to the first non-meta line
|
|
147
236
|
|
|
148
|
-
|
|
149
|
-
// get the "header text" string from the file, which is the first contiguous
|
|
150
|
-
// set of lines in the file that all start with a "meta" character (usually #)
|
|
151
|
-
const headerText = await tbiIndexed.getHeader()
|
|
152
|
-
// or const headerText = await tbiIndexed.getHeader({ signal: aborter.signal })
|
|
153
|
-
```
|
|
237
|
+
##### Parameters
|
|
154
238
|
|
|
155
|
-
|
|
239
|
+
- `opts` **Options** (optional, default `{}`)
|
|
156
240
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
241
|
+
#### getHeader
|
|
242
|
+
|
|
243
|
+
get a string containing the "header" region of the file, is the portion up to
|
|
244
|
+
the first non-meta line
|
|
245
|
+
|
|
246
|
+
##### Parameters
|
|
247
|
+
|
|
248
|
+
- `opts` **Options** (optional, default `{}`)
|
|
249
|
+
|
|
250
|
+
Returns
|
|
251
|
+
**[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)**
|
|
252
|
+
for a string
|
|
253
|
+
|
|
254
|
+
#### getReferenceSequenceNames
|
|
255
|
+
|
|
256
|
+
get an array of reference sequence names, in the order in which they occur in
|
|
257
|
+
the file. reference sequence renaming is not applied to these names.
|
|
258
|
+
|
|
259
|
+
##### Parameters
|
|
260
|
+
|
|
261
|
+
- `opts` **Options** (optional, default `{}`)
|
|
262
|
+
|
|
263
|
+
#### checkLine
|
|
264
|
+
|
|
265
|
+
##### Parameters
|
|
266
|
+
|
|
267
|
+
- `metadata`
|
|
268
|
+
**[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**
|
|
269
|
+
metadata object from the parsed index, containing columnNumbers, metaChar, and
|
|
270
|
+
format
|
|
271
|
+
- `regionRefName`
|
|
272
|
+
**[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
|
|
273
|
+
- `regionStart`
|
|
274
|
+
**[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)**
|
|
275
|
+
region start coordinate (0-based-half-open)
|
|
276
|
+
- `regionEnd`
|
|
277
|
+
**[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)**
|
|
278
|
+
region end coordinate (0-based-half-open)
|
|
279
|
+
- `line`
|
|
280
|
+
**[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
|
|
281
|
+
|
|
282
|
+
Returns
|
|
283
|
+
**[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)**
|
|
284
|
+
like `{startCoordinate, overlaps}`. overlaps is boolean, true if line is a data
|
|
285
|
+
line that overlaps the given region
|
|
286
|
+
|
|
287
|
+
#### lineCount
|
|
288
|
+
|
|
289
|
+
return the approximate number of data lines in the given reference sequence
|
|
290
|
+
|
|
291
|
+
##### Parameters
|
|
292
|
+
|
|
293
|
+
- `refName`
|
|
294
|
+
**[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
|
|
295
|
+
- `opts` **Options** (optional, default `{}`)
|
|
296
|
+
- `refSeq` reference sequence name
|
|
297
|
+
|
|
298
|
+
Returns **any** number of data lines present on that reference sequence
|
|
299
|
+
|
|
300
|
+
#### readChunk
|
|
301
|
+
|
|
302
|
+
read and uncompress the data in a chunk (composed of one or more contiguous
|
|
303
|
+
bgzip blocks) of the file
|
|
304
|
+
|
|
305
|
+
##### Parameters
|
|
306
|
+
|
|
307
|
+
- `c` **Chunk** 
|
|
308
|
+
- `opts` **Options** (optional, default `{}`)
|
|
162
309
|
|
|
163
310
|
## Academic Use
|
|
164
311
|
|
package/dist/chunk.js
CHANGED
|
@@ -9,7 +9,6 @@ class Chunk {
|
|
|
9
9
|
this._fetchedSize = fetchedSize;
|
|
10
10
|
}
|
|
11
11
|
toUniqueString() {
|
|
12
|
-
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
|
13
12
|
return `${this.minv}..${this.maxv} (bin ${this.bin}, fetchedSize ${this.fetchedSize()})`;
|
|
14
13
|
}
|
|
15
14
|
toString() {
|
package/dist/chunk.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk.js","sourceRoot":"","sources":["../src/chunk.ts"],"names":[],"mappings":";;AAEA,iDAAiD;AACjD,MAAqB,KAAK;IAMxB,YACE,IAAmB,EACnB,IAAmB,EACnB,GAAW,EACX,WAAW,GAAG,SAAS;QAEvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,YAAY,GAAG,WAAW,CAAA;IACjC,CAAC;IAED,cAAc;QACZ,
|
|
1
|
+
{"version":3,"file":"chunk.js","sourceRoot":"","sources":["../src/chunk.ts"],"names":[],"mappings":";;AAEA,iDAAiD;AACjD,MAAqB,KAAK;IAMxB,YACE,IAAmB,EACnB,IAAmB,EACnB,GAAW,EACX,WAAW,GAAG,SAAS;QAEvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,YAAY,GAAG,WAAW,CAAA;IACjC,CAAC;IAED,cAAc;QACZ,OAAO,GAAG,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,SAC/B,IAAI,CAAC,GACP,iBAAiB,IAAI,CAAC,WAAW,EAAE,GAAG,CAAA;IACxC,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,cAAc,EAAE,CAAA;IAC9B,CAAC;IAED,SAAS,CAAC,CAAQ;QAChB,OAAO,CACL,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;YAC3B,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CACjB,CAAA;IACH,CAAC;IAED,WAAW;QACT,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,YAAY,CAAA;QAC1B,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAA;IACtE,CAAC;CACF;AA1CD,wBA0CC"}
|
package/dist/csi.d.ts
CHANGED
|
@@ -85,5 +85,5 @@ export default class CSI extends IndexFile {
|
|
|
85
85
|
/**
|
|
86
86
|
* calculate the list of bins that may overlap with region [beg,end) (zero-based half-open)
|
|
87
87
|
*/
|
|
88
|
-
reg2bins(beg: number, end: number): number
|
|
88
|
+
reg2bins(beg: number, end: number): (readonly [number, number])[];
|
|
89
89
|
}
|
package/dist/csi.js
CHANGED
|
@@ -15,22 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
34
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
37
|
};
|
|
@@ -44,10 +45,10 @@ const indexFile_1 = __importDefault(require("./indexFile"));
|
|
|
44
45
|
const CSI1_MAGIC = 21582659; // CSI\1
|
|
45
46
|
const CSI2_MAGIC = 38359875; // CSI\2
|
|
46
47
|
function lshift(num, bits) {
|
|
47
|
-
return num *
|
|
48
|
+
return num * 2 ** bits;
|
|
48
49
|
}
|
|
49
50
|
function rshift(num, bits) {
|
|
50
|
-
return Math.floor(num /
|
|
51
|
+
return Math.floor(num / 2 ** bits);
|
|
51
52
|
}
|
|
52
53
|
class CSI extends indexFile_1.default {
|
|
53
54
|
constructor(args) {
|
|
@@ -56,23 +57,21 @@ class CSI extends indexFile_1.default {
|
|
|
56
57
|
this.depth = 0;
|
|
57
58
|
this.minShift = 0;
|
|
58
59
|
}
|
|
59
|
-
lineCount(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return -1;
|
|
64
|
-
}
|
|
65
|
-
const refId = indexData.refNameToId[refName];
|
|
66
|
-
const idx = indexData.indices[refId];
|
|
67
|
-
if (!idx) {
|
|
68
|
-
return -1;
|
|
69
|
-
}
|
|
70
|
-
const { stats } = indexData.indices[refId];
|
|
71
|
-
if (stats) {
|
|
72
|
-
return stats.lineCount;
|
|
73
|
-
}
|
|
60
|
+
async lineCount(refName, opts = {}) {
|
|
61
|
+
const indexData = await this.parse(opts);
|
|
62
|
+
const refId = indexData.refNameToId[refName];
|
|
63
|
+
if (refId === undefined) {
|
|
74
64
|
return -1;
|
|
75
|
-
}
|
|
65
|
+
}
|
|
66
|
+
const idx = indexData.indices[refId];
|
|
67
|
+
if (!idx) {
|
|
68
|
+
return -1;
|
|
69
|
+
}
|
|
70
|
+
const { stats } = indexData.indices[refId];
|
|
71
|
+
if (stats) {
|
|
72
|
+
return stats.lineCount;
|
|
73
|
+
}
|
|
74
|
+
return -1;
|
|
76
75
|
}
|
|
77
76
|
indexCov() {
|
|
78
77
|
throw new Error('CSI indexes do not support indexcov');
|
|
@@ -124,110 +123,115 @@ class CSI extends indexFile_1.default {
|
|
|
124
123
|
return { refNameToId, refIdToName };
|
|
125
124
|
}
|
|
126
125
|
// fetch and parse the index
|
|
127
|
-
_parse() {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
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
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
126
|
+
async _parse(opts = {}) {
|
|
127
|
+
const bytes = await (0, bgzf_filehandle_1.unzip)(await this.filehandle.readFile(opts));
|
|
128
|
+
// check TBI magic numbers
|
|
129
|
+
let csiVersion;
|
|
130
|
+
if (bytes.readUInt32LE(0) === CSI1_MAGIC) {
|
|
131
|
+
csiVersion = 1;
|
|
132
|
+
}
|
|
133
|
+
else if (bytes.readUInt32LE(0) === CSI2_MAGIC) {
|
|
134
|
+
csiVersion = 2;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
throw new Error('Not a CSI file');
|
|
138
|
+
// TODO: do we need to support big-endian CSI files?
|
|
139
|
+
}
|
|
140
|
+
this.minShift = bytes.readInt32LE(4);
|
|
141
|
+
this.depth = bytes.readInt32LE(8);
|
|
142
|
+
this.maxBinNumber = ((1 << ((this.depth + 1) * 3)) - 1) / 7;
|
|
143
|
+
const maxRefLength = 2 ** (this.minShift + this.depth * 3);
|
|
144
|
+
const auxLength = bytes.readInt32LE(12);
|
|
145
|
+
const aux = auxLength && auxLength >= 30
|
|
146
|
+
? this.parseAuxData(bytes, 16)
|
|
147
|
+
: {
|
|
148
|
+
refIdToName: [],
|
|
149
|
+
refNameToId: {},
|
|
150
|
+
metaChar: null,
|
|
151
|
+
columnNumbers: { ref: 0, start: 1, end: 2 },
|
|
152
|
+
coordinateType: 'zero-based-half-open',
|
|
153
|
+
format: 'generic',
|
|
154
|
+
};
|
|
155
|
+
const refCount = bytes.readInt32LE(16 + auxLength);
|
|
156
|
+
// read the indexes for each reference sequence
|
|
157
|
+
let firstDataLine;
|
|
158
|
+
let currOffset = 16 + auxLength + 4;
|
|
159
|
+
const indices = new Array(refCount).fill(0).map(() => {
|
|
160
|
+
// the binning index
|
|
161
|
+
const binCount = bytes.readInt32LE(currOffset);
|
|
162
|
+
currOffset += 4;
|
|
163
|
+
const binIndex = {};
|
|
164
|
+
let stats; // < provided by parsing a pseudo-bin, if present
|
|
165
|
+
for (let j = 0; j < binCount; j += 1) {
|
|
166
|
+
const bin = bytes.readUInt32LE(currOffset);
|
|
167
|
+
if (bin > this.maxBinNumber) {
|
|
168
|
+
// this is a fake bin that actually has stats information
|
|
169
|
+
// about the reference sequence in it
|
|
170
|
+
stats = this.parsePseudoBin(bytes, currOffset + 4);
|
|
171
|
+
currOffset += 4 + 8 + 4 + 16 + 16;
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
const loffset = (0, virtualOffset_1.fromBytes)(bytes, currOffset + 4);
|
|
175
|
+
firstDataLine = this._findFirstData(firstDataLine, loffset);
|
|
176
|
+
const chunkCount = bytes.readInt32LE(currOffset + 12);
|
|
177
|
+
currOffset += 16;
|
|
178
|
+
const chunks = new Array(chunkCount);
|
|
179
|
+
for (let k = 0; k < chunkCount; k += 1) {
|
|
180
|
+
const u = (0, virtualOffset_1.fromBytes)(bytes, currOffset);
|
|
181
|
+
const v = (0, virtualOffset_1.fromBytes)(bytes, currOffset + 8);
|
|
179
182
|
currOffset += 16;
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const u = (0, virtualOffset_1.fromBytes)(bytes, currOffset);
|
|
183
|
-
const v = (0, virtualOffset_1.fromBytes)(bytes, currOffset + 8);
|
|
184
|
-
currOffset += 16;
|
|
185
|
-
// this._findFirstData(data, u)
|
|
186
|
-
chunks[k] = new chunk_1.default(u, v, bin);
|
|
187
|
-
}
|
|
188
|
-
binIndex[bin] = chunks;
|
|
183
|
+
// this._findFirstData(data, u)
|
|
184
|
+
chunks[k] = new chunk_1.default(u, v, bin);
|
|
189
185
|
}
|
|
186
|
+
binIndex[bin] = chunks;
|
|
190
187
|
}
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
return Object.assign(Object.assign({}, aux), { csi: true, refCount, maxBlockSize: 1 << 16, firstDataLine,
|
|
194
|
-
csiVersion,
|
|
195
|
-
indices, depth: this.depth, maxBinNumber: this.maxBinNumber, maxRefLength });
|
|
188
|
+
}
|
|
189
|
+
return { binIndex, stats };
|
|
196
190
|
});
|
|
191
|
+
return {
|
|
192
|
+
...aux,
|
|
193
|
+
csi: true,
|
|
194
|
+
refCount,
|
|
195
|
+
maxBlockSize: 1 << 16,
|
|
196
|
+
firstDataLine,
|
|
197
|
+
csiVersion,
|
|
198
|
+
indices,
|
|
199
|
+
depth: this.depth,
|
|
200
|
+
maxBinNumber: this.maxBinNumber,
|
|
201
|
+
maxRefLength,
|
|
202
|
+
};
|
|
197
203
|
}
|
|
198
204
|
parsePseudoBin(bytes, offset) {
|
|
199
205
|
const lineCount = (0, util_1.longToNumber)(long_1.default.fromBytesLE(bytes.slice(offset + 28, offset + 36), true));
|
|
200
206
|
return { lineCount };
|
|
201
207
|
}
|
|
202
|
-
blocksForRange(
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
for (
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
chunks.push(new chunk_1.default(c.minv, c.maxv, bin));
|
|
225
|
-
}
|
|
208
|
+
async blocksForRange(refName, min, max, opts = {}) {
|
|
209
|
+
if (min < 0) {
|
|
210
|
+
min = 0;
|
|
211
|
+
}
|
|
212
|
+
const indexData = await this.parse(opts);
|
|
213
|
+
const refId = indexData.refNameToId[refName];
|
|
214
|
+
if (refId === undefined) {
|
|
215
|
+
return [];
|
|
216
|
+
}
|
|
217
|
+
const ba = indexData.indices[refId];
|
|
218
|
+
if (!ba) {
|
|
219
|
+
return [];
|
|
220
|
+
}
|
|
221
|
+
// const { linearIndex, binIndex } = indexes
|
|
222
|
+
const overlappingBins = this.reg2bins(min, max); // List of bin #s that overlap min, max
|
|
223
|
+
const chunks = [];
|
|
224
|
+
// Find chunks in overlapping bins. Leaf bins (< 4681) are not pruned
|
|
225
|
+
for (const [start, end] of overlappingBins) {
|
|
226
|
+
for (let bin = start; bin <= end; bin++) {
|
|
227
|
+
if (ba.binIndex[bin]) {
|
|
228
|
+
for (const c of ba.binIndex[bin]) {
|
|
229
|
+
chunks.push(new chunk_1.default(c.minv, c.maxv, bin));
|
|
226
230
|
}
|
|
227
231
|
}
|
|
228
232
|
}
|
|
229
|
-
|
|
230
|
-
|
|
233
|
+
}
|
|
234
|
+
return (0, util_1.optimizeChunks)(chunks, new virtualOffset_1.default(0, 0));
|
|
231
235
|
}
|
|
232
236
|
/**
|
|
233
237
|
* calculate the list of bins that may overlap with region [beg,end) (zero-based half-open)
|
|
@@ -237,8 +241,8 @@ class CSI extends indexFile_1.default {
|
|
|
237
241
|
if (beg < 1) {
|
|
238
242
|
beg = 1;
|
|
239
243
|
}
|
|
240
|
-
if (end >
|
|
241
|
-
end =
|
|
244
|
+
if (end > 2 ** 50) {
|
|
245
|
+
end = 2 ** 34;
|
|
242
246
|
} // 17 GiB ought to be enough for anybody
|
|
243
247
|
end -= 1;
|
|
244
248
|
let l = 0;
|