@gmod/bbi 2.0.3 → 2.0.5
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 +11 -1
- package/README.md +1 -1
- package/dist/bbi.js +160 -268
- package/dist/bbi.js.map +1 -1
- package/dist/bigbed.js +146 -259
- package/dist/bigbed.js.map +1 -1
- package/dist/bigint-polyfill/polyfill.js +1 -1
- package/dist/bigint-polyfill/polyfill.js.map +1 -1
- package/dist/bigint-polyfill/pure.js +11 -11
- package/dist/bigint-polyfill/pure.js.map +1 -1
- package/dist/bigwig.js +21 -75
- package/dist/bigwig.js.map +1 -1
- package/dist/blockView.js +207 -303
- package/dist/blockView.js.map +1 -1
- package/dist/range.js +49 -50
- package/dist/range.js.map +1 -1
- package/dist/unzip-pako.js +1 -1
- package/dist/unzip-pako.js.map +1 -1
- package/dist/unzip.js +1 -1
- package/dist/unzip.js.map +1 -1
- package/dist/util.js +14 -66
- package/dist/util.js.map +1 -1
- package/esm/bbi.js +4 -3
- package/esm/bbi.js.map +1 -1
- package/esm/blockView.js +2 -3
- package/esm/blockView.js.map +1 -1
- package/package.json +13 -13
- package/src/bbi.ts +5 -3
- package/src/blockView.ts +14 -4
package/dist/blockView.js
CHANGED
|
@@ -1,15 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
14
3
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
15
4
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -19,55 +8,27 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
19
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
20
9
|
});
|
|
21
10
|
};
|
|
22
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
23
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
24
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
25
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
26
|
-
function step(op) {
|
|
27
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
28
|
-
while (_) try {
|
|
29
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
30
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
31
|
-
switch (op[0]) {
|
|
32
|
-
case 0: case 1: t = op; break;
|
|
33
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
34
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
35
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
36
|
-
default:
|
|
37
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
38
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
39
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
40
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
41
|
-
if (t[2]) _.ops.pop();
|
|
42
|
-
_.trys.pop(); continue;
|
|
43
|
-
}
|
|
44
|
-
op = body.call(thisArg, _);
|
|
45
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
46
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
50
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
51
13
|
};
|
|
52
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
15
|
exports.BlockView = void 0;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
16
|
+
const binary_parser_1 = require("binary-parser");
|
|
17
|
+
const abortable_promise_cache_1 = __importDefault(require("abortable-promise-cache"));
|
|
18
|
+
const quick_lru_1 = __importDefault(require("quick-lru"));
|
|
57
19
|
// locals
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
20
|
+
const range_1 = __importDefault(require("./range"));
|
|
21
|
+
const unzip_1 = require("./unzip");
|
|
22
|
+
const util_1 = require("./util");
|
|
23
|
+
const BIG_WIG_TYPE_GRAPH = 1;
|
|
24
|
+
const BIG_WIG_TYPE_VSTEP = 2;
|
|
25
|
+
const BIG_WIG_TYPE_FSTEP = 3;
|
|
64
26
|
function coordFilter(s1, e1, s2, e2) {
|
|
65
27
|
return s1 < e2 && e1 >= s2;
|
|
66
28
|
}
|
|
67
29
|
function getParsers(isBigEndian) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
var summaryParser = new binary_parser_1.Parser()
|
|
30
|
+
const le = isBigEndian ? 'big' : 'little';
|
|
31
|
+
const summaryParser = new binary_parser_1.Parser()
|
|
71
32
|
.endianess(le)
|
|
72
33
|
.uint32('chromId')
|
|
73
34
|
.uint32('start')
|
|
@@ -78,7 +39,7 @@ function getParsers(isBigEndian) {
|
|
|
78
39
|
.floatle('sumData')
|
|
79
40
|
.floatle('sumSqData')
|
|
80
41
|
.saveOffset('offset');
|
|
81
|
-
|
|
42
|
+
const leafParser = new binary_parser_1.Parser()
|
|
82
43
|
.endianess(le)
|
|
83
44
|
.uint8('isLeaf')
|
|
84
45
|
.skip(1)
|
|
@@ -111,7 +72,7 @@ function getParsers(isBigEndian) {
|
|
|
111
72
|
}),
|
|
112
73
|
},
|
|
113
74
|
});
|
|
114
|
-
|
|
75
|
+
const bigBedParser = new binary_parser_1.Parser()
|
|
115
76
|
.endianess(le)
|
|
116
77
|
.uint32('chromId')
|
|
117
78
|
.int32('start')
|
|
@@ -120,7 +81,7 @@ function getParsers(isBigEndian) {
|
|
|
120
81
|
zeroTerminated: true,
|
|
121
82
|
})
|
|
122
83
|
.saveOffset('offset');
|
|
123
|
-
|
|
84
|
+
const bigWigParser = new binary_parser_1.Parser()
|
|
124
85
|
.endianess(le)
|
|
125
86
|
.skip(4)
|
|
126
87
|
.int32('blockStart')
|
|
@@ -132,16 +93,16 @@ function getParsers(isBigEndian) {
|
|
|
132
93
|
.uint16('itemCount')
|
|
133
94
|
.choice({
|
|
134
95
|
tag: 'blockType',
|
|
135
|
-
choices:
|
|
136
|
-
|
|
96
|
+
choices: {
|
|
97
|
+
[BIG_WIG_TYPE_FSTEP]: new binary_parser_1.Parser().array('items', {
|
|
137
98
|
length: 'itemCount',
|
|
138
99
|
type: new binary_parser_1.Parser().floatle('score'),
|
|
139
100
|
}),
|
|
140
|
-
|
|
101
|
+
[BIG_WIG_TYPE_VSTEP]: new binary_parser_1.Parser().array('items', {
|
|
141
102
|
length: 'itemCount',
|
|
142
103
|
type: new binary_parser_1.Parser().endianess(le).int32('start').floatle('score'),
|
|
143
104
|
}),
|
|
144
|
-
|
|
105
|
+
[BIG_WIG_TYPE_GRAPH]: new binary_parser_1.Parser().array('items', {
|
|
145
106
|
length: 'itemCount',
|
|
146
107
|
type: new binary_parser_1.Parser()
|
|
147
108
|
.endianess(le)
|
|
@@ -149,13 +110,13 @@ function getParsers(isBigEndian) {
|
|
|
149
110
|
.int32('end')
|
|
150
111
|
.floatle('score'),
|
|
151
112
|
}),
|
|
152
|
-
|
|
113
|
+
},
|
|
153
114
|
});
|
|
154
115
|
return {
|
|
155
|
-
bigWigParser
|
|
156
|
-
bigBedParser
|
|
157
|
-
summaryParser
|
|
158
|
-
leafParser
|
|
116
|
+
bigWigParser,
|
|
117
|
+
bigBedParser,
|
|
118
|
+
summaryParser,
|
|
119
|
+
leafParser,
|
|
159
120
|
};
|
|
160
121
|
}
|
|
161
122
|
/**
|
|
@@ -165,9 +126,8 @@ function getParsers(isBigEndian) {
|
|
|
165
126
|
* Explorer by Thomas Down.
|
|
166
127
|
* @constructs
|
|
167
128
|
*/
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
var _this = this;
|
|
129
|
+
class BlockView {
|
|
130
|
+
constructor(bbi, refsByName, cirTreeOffset, isBigEndian, isCompressed, blockType) {
|
|
171
131
|
this.bbi = bbi;
|
|
172
132
|
this.refsByName = refsByName;
|
|
173
133
|
this.cirTreeOffset = cirTreeOffset;
|
|
@@ -176,160 +136,131 @@ var BlockView = /** @class */ (function () {
|
|
|
176
136
|
this.blockType = blockType;
|
|
177
137
|
this.featureCache = new abortable_promise_cache_1.default({
|
|
178
138
|
cache: new quick_lru_1.default({ maxSize: 1000 }),
|
|
179
|
-
fill:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
len = Number(requestData.length);
|
|
185
|
-
off = Number(requestData.offset);
|
|
186
|
-
return [4 /*yield*/, this.bbi.read(Buffer.alloc(len), 0, len, off, {
|
|
187
|
-
signal: signal,
|
|
188
|
-
})];
|
|
189
|
-
case 1:
|
|
190
|
-
buffer = (_a.sent()).buffer;
|
|
191
|
-
return [2 /*return*/, buffer];
|
|
192
|
-
}
|
|
139
|
+
fill: (requestData, signal) => __awaiter(this, void 0, void 0, function* () {
|
|
140
|
+
const len = Number(requestData.length);
|
|
141
|
+
const off = Number(requestData.offset);
|
|
142
|
+
const { buffer } = yield this.bbi.read(Buffer.alloc(len), 0, len, off, {
|
|
143
|
+
signal,
|
|
193
144
|
});
|
|
194
|
-
|
|
145
|
+
return buffer;
|
|
146
|
+
}),
|
|
195
147
|
});
|
|
196
148
|
if (!(cirTreeOffset >= 0)) {
|
|
197
149
|
throw new Error('invalid cirTreeOffset!');
|
|
198
150
|
}
|
|
199
|
-
|
|
151
|
+
const parsers = getParsers(isBigEndian);
|
|
200
152
|
this.leafParser = parsers.leafParser;
|
|
201
153
|
this.bigBedParser = parsers.bigBedParser;
|
|
202
154
|
}
|
|
203
|
-
|
|
204
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
155
|
+
readWigData(chrName, start, end, observer, opts) {
|
|
156
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
157
|
+
try {
|
|
158
|
+
const { refsByName, bbi, cirTreeOffset, isBigEndian } = this;
|
|
159
|
+
const chrId = refsByName[chrName];
|
|
160
|
+
if (chrId === undefined) {
|
|
161
|
+
observer.complete();
|
|
162
|
+
}
|
|
163
|
+
const request = { chrId, start, end };
|
|
164
|
+
if (!this.cirTreePromise) {
|
|
165
|
+
this.cirTreePromise = bbi.read(Buffer.alloc(48), 0, 48, Number(cirTreeOffset), opts);
|
|
166
|
+
}
|
|
167
|
+
const { buffer } = yield this.cirTreePromise;
|
|
168
|
+
const cirBlockSize = isBigEndian
|
|
169
|
+
? buffer.readUInt32BE(4)
|
|
170
|
+
: buffer.readUInt32LE(4);
|
|
171
|
+
let blocksToFetch = [];
|
|
172
|
+
let outstanding = 0;
|
|
173
|
+
const cirFobRecur2 = (cirBlockData, offset, level) => {
|
|
174
|
+
try {
|
|
175
|
+
const data = cirBlockData.subarray(offset);
|
|
176
|
+
const p = this.leafParser.parse(data);
|
|
177
|
+
if (p.blocksToFetch) {
|
|
178
|
+
blocksToFetch = blocksToFetch.concat(p.blocksToFetch
|
|
179
|
+
.filter(filterFeats)
|
|
180
|
+
.map((l) => ({
|
|
181
|
+
offset: l.blockOffset,
|
|
182
|
+
length: l.blockSize,
|
|
183
|
+
})));
|
|
220
184
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
blocksToFetch_1 = [];
|
|
228
|
-
outstanding_1 = 0;
|
|
229
|
-
cirFobRecur2_1 = function (cirBlockData, offset, level) {
|
|
230
|
-
try {
|
|
231
|
-
var data = cirBlockData.subarray(offset);
|
|
232
|
-
var p = _this.leafParser.parse(data);
|
|
233
|
-
if (p.blocksToFetch) {
|
|
234
|
-
blocksToFetch_1 = blocksToFetch_1.concat(p.blocksToFetch
|
|
235
|
-
.filter(filterFeats_1)
|
|
236
|
-
.map(function (l) { return ({
|
|
237
|
-
offset: l.blockOffset,
|
|
238
|
-
length: l.blockSize,
|
|
239
|
-
}); }));
|
|
240
|
-
}
|
|
241
|
-
if (p.recurOffsets) {
|
|
242
|
-
var recurOffsets = p.recurOffsets
|
|
243
|
-
.filter(filterFeats_1)
|
|
244
|
-
.map(function (l) { return Number(l.blockOffset); });
|
|
245
|
-
if (recurOffsets.length > 0) {
|
|
246
|
-
cirFobRecur_1(recurOffsets, level + 1);
|
|
247
|
-
}
|
|
248
|
-
}
|
|
185
|
+
if (p.recurOffsets) {
|
|
186
|
+
const recurOffsets = p.recurOffsets
|
|
187
|
+
.filter(filterFeats)
|
|
188
|
+
.map(l => Number(l.blockOffset));
|
|
189
|
+
if (recurOffsets.length > 0) {
|
|
190
|
+
cirFobRecur(recurOffsets, level + 1);
|
|
249
191
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
cirFobRecur2_1(resultBuffer, off[i] - offset, level);
|
|
273
|
-
outstanding_1 -= 1;
|
|
274
|
-
if (outstanding_1 === 0) {
|
|
275
|
-
this.readFeatures(observer, blocksToFetch_1, __assign(__assign({}, opts), { request: request_1 }));
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
return [3 /*break*/, 3];
|
|
280
|
-
case 2:
|
|
281
|
-
e_2 = _a.sent();
|
|
282
|
-
observer.error(e_2);
|
|
283
|
-
return [3 /*break*/, 3];
|
|
284
|
-
case 3: return [2 /*return*/];
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
}); };
|
|
288
|
-
cirFobRecur_1 = function (offset, level) {
|
|
289
|
-
try {
|
|
290
|
-
outstanding_1 += offset.length;
|
|
291
|
-
var maxCirBlockSpan = 4 + Number(cirBlockSize_1) * 32; // Upper bound on size, based on a completely full leaf node.
|
|
292
|
-
var spans = new range_1.default(offset[0], offset[0] + maxCirBlockSpan);
|
|
293
|
-
for (var i = 1; i < offset.length; i += 1) {
|
|
294
|
-
var blockSpan = new range_1.default(offset[i], offset[i] + maxCirBlockSpan);
|
|
295
|
-
spans = spans.union(blockSpan);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
catch (e) {
|
|
195
|
+
observer.error(e);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
const filterFeats = (b) => {
|
|
199
|
+
const { startChrom, startBase, endChrom, endBase } = b;
|
|
200
|
+
return ((startChrom < chrId || (startChrom === chrId && startBase <= end)) &&
|
|
201
|
+
(endChrom > chrId || (endChrom === chrId && endBase >= start)));
|
|
202
|
+
};
|
|
203
|
+
const cirFobStartFetch = (off, fr, level) => __awaiter(this, void 0, void 0, function* () {
|
|
204
|
+
try {
|
|
205
|
+
const length = fr.max() - fr.min();
|
|
206
|
+
const offset = fr.min();
|
|
207
|
+
const resultBuffer = yield this.featureCache.get(`${length}_${offset}`, { length, offset }, opts.signal);
|
|
208
|
+
for (let i = 0; i < off.length; i += 1) {
|
|
209
|
+
if (fr.contains(off[i])) {
|
|
210
|
+
cirFobRecur2(resultBuffer, off[i] - offset, level);
|
|
211
|
+
outstanding -= 1;
|
|
212
|
+
if (outstanding === 0) {
|
|
213
|
+
this.readFeatures(observer, blocksToFetch, Object.assign(Object.assign({}, opts), { request }));
|
|
296
214
|
}
|
|
297
|
-
spans.getRanges().map(function (fr) { return cirFobStartFetch_1(offset, fr, level); });
|
|
298
|
-
}
|
|
299
|
-
catch (e) {
|
|
300
|
-
observer.error(e);
|
|
301
215
|
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch (e) {
|
|
219
|
+
observer.error(e);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
const cirFobRecur = (offset, level) => {
|
|
223
|
+
try {
|
|
224
|
+
outstanding += offset.length;
|
|
225
|
+
const maxCirBlockSpan = 4 + Number(cirBlockSize) * 32; // Upper bound on size, based on a completely full leaf node.
|
|
226
|
+
let spans = new range_1.default(offset[0], offset[0] + maxCirBlockSpan);
|
|
227
|
+
for (let i = 1; i < offset.length; i += 1) {
|
|
228
|
+
const blockSpan = new range_1.default(offset[i], offset[i] + maxCirBlockSpan);
|
|
229
|
+
spans = spans.union(blockSpan);
|
|
230
|
+
}
|
|
231
|
+
spans.getRanges().map(fr => cirFobStartFetch(offset, fr, level));
|
|
232
|
+
}
|
|
233
|
+
catch (e) {
|
|
234
|
+
observer.error(e);
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
return cirFobRecur([Number(cirTreeOffset) + 48], 1);
|
|
238
|
+
}
|
|
239
|
+
catch (e) {
|
|
240
|
+
observer.error(e);
|
|
241
|
+
}
|
|
311
242
|
});
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
243
|
+
}
|
|
244
|
+
parseSummaryBlock(buffer, startOffset, request) {
|
|
245
|
+
const features = [];
|
|
246
|
+
let offset = startOffset;
|
|
247
|
+
const dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.length);
|
|
317
248
|
while (offset < buffer.byteLength) {
|
|
318
249
|
// this was extracted from looking at the runtime code generated by
|
|
319
250
|
// binary-parser
|
|
320
|
-
|
|
251
|
+
const chromId = dataView.getUint32(offset, true);
|
|
321
252
|
offset += 4;
|
|
322
|
-
|
|
253
|
+
const start = dataView.getUint32(offset, true);
|
|
323
254
|
offset += 4;
|
|
324
|
-
|
|
255
|
+
const end = dataView.getUint32(offset, true);
|
|
325
256
|
offset += 4;
|
|
326
|
-
|
|
257
|
+
const validCnt = dataView.getUint32(offset, true);
|
|
327
258
|
offset += 4;
|
|
328
|
-
|
|
259
|
+
const minScore = dataView.getFloat32(offset, true);
|
|
329
260
|
offset += 4;
|
|
330
|
-
|
|
261
|
+
const maxScore = dataView.getFloat32(offset, true);
|
|
331
262
|
offset += 4;
|
|
332
|
-
|
|
263
|
+
const sumData = dataView.getFloat32(offset, true);
|
|
333
264
|
offset += 4;
|
|
334
265
|
// unused
|
|
335
266
|
// const sumSqData = dataView.getFloat32(offset, true)
|
|
@@ -339,148 +270,121 @@ var BlockView = /** @class */ (function () {
|
|
|
339
270
|
coordFilter(start, end, request.start, request.end)
|
|
340
271
|
: true) {
|
|
341
272
|
features.push({
|
|
342
|
-
start
|
|
343
|
-
end
|
|
344
|
-
maxScore
|
|
345
|
-
minScore
|
|
273
|
+
start,
|
|
274
|
+
end,
|
|
275
|
+
maxScore,
|
|
276
|
+
minScore,
|
|
346
277
|
summary: true,
|
|
347
278
|
score: sumData / (validCnt || 1),
|
|
348
279
|
});
|
|
349
280
|
}
|
|
350
281
|
}
|
|
351
282
|
return features;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
283
|
+
}
|
|
284
|
+
parseBigBedBlock(data, startOffset, offset, request) {
|
|
285
|
+
const items = [];
|
|
286
|
+
let currOffset = startOffset;
|
|
356
287
|
while (currOffset < data.byteLength) {
|
|
357
|
-
|
|
358
|
-
items.push(
|
|
288
|
+
const res = this.bigBedParser.parse(data.subarray(currOffset));
|
|
289
|
+
items.push(Object.assign(Object.assign({}, res), { uniqueId: `bb-${offset + currOffset}` }));
|
|
359
290
|
currOffset += res.offset;
|
|
360
291
|
}
|
|
361
292
|
return request
|
|
362
|
-
? items.filter(
|
|
363
|
-
return coordFilter(f.start, f.end, request.start, request.end);
|
|
364
|
-
})
|
|
293
|
+
? items.filter((f) => coordFilter(f.start, f.end, request.start, request.end))
|
|
365
294
|
: items;
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
295
|
+
}
|
|
296
|
+
parseBigWigBlock(buffer, startOffset, request) {
|
|
297
|
+
const b = buffer.subarray(startOffset);
|
|
298
|
+
const dataView = new DataView(b.buffer, b.byteOffset, b.length);
|
|
299
|
+
let offset = 0;
|
|
371
300
|
offset += 4;
|
|
372
|
-
|
|
301
|
+
const blockStart = dataView.getInt32(offset, true);
|
|
373
302
|
offset += 8;
|
|
374
|
-
|
|
303
|
+
const itemStep = dataView.getUint32(offset, true);
|
|
375
304
|
offset += 4;
|
|
376
|
-
|
|
305
|
+
const itemSpan = dataView.getUint32(offset, true);
|
|
377
306
|
offset += 4;
|
|
378
|
-
|
|
307
|
+
const blockType = dataView.getUint8(offset);
|
|
379
308
|
offset += 2;
|
|
380
|
-
|
|
309
|
+
const itemCount = dataView.getUint16(offset, true);
|
|
381
310
|
offset += 2;
|
|
382
|
-
|
|
311
|
+
const items = new Array(itemCount);
|
|
383
312
|
switch (blockType) {
|
|
384
313
|
case 1:
|
|
385
|
-
for (
|
|
386
|
-
|
|
314
|
+
for (let i = 0; i < itemCount; i++) {
|
|
315
|
+
const start = dataView.getInt32(offset, true);
|
|
387
316
|
offset += 4;
|
|
388
|
-
|
|
317
|
+
const end = dataView.getInt32(offset, true);
|
|
389
318
|
offset += 4;
|
|
390
|
-
|
|
319
|
+
const score = dataView.getFloat32(offset, true);
|
|
391
320
|
offset += 4;
|
|
392
|
-
items[i] = { start
|
|
321
|
+
items[i] = { start, end, score };
|
|
393
322
|
}
|
|
394
323
|
break;
|
|
395
324
|
case 2:
|
|
396
|
-
for (
|
|
397
|
-
|
|
325
|
+
for (let i = 0; i < itemCount; i++) {
|
|
326
|
+
const start = dataView.getInt32(offset, true);
|
|
398
327
|
offset += 4;
|
|
399
|
-
|
|
328
|
+
const score = dataView.getFloat32(offset, true);
|
|
400
329
|
offset += 4;
|
|
401
|
-
items[i] = { score
|
|
330
|
+
items[i] = { score, start, end: start + itemSpan };
|
|
402
331
|
}
|
|
403
332
|
break;
|
|
404
333
|
case 3:
|
|
405
|
-
for (
|
|
406
|
-
|
|
334
|
+
for (let i = 0; i < itemCount; i++) {
|
|
335
|
+
const score = dataView.getFloat32(offset, true);
|
|
407
336
|
offset += 4;
|
|
408
|
-
|
|
409
|
-
items[i] = { score
|
|
337
|
+
const start = blockStart + i * itemStep;
|
|
338
|
+
items[i] = { score, start, end: start + itemSpan };
|
|
410
339
|
}
|
|
411
340
|
break;
|
|
412
341
|
}
|
|
413
342
|
return request
|
|
414
|
-
? items.filter(
|
|
415
|
-
return coordFilter(f.start, f.end, request.start, request.end);
|
|
416
|
-
})
|
|
343
|
+
? items.filter((f) => coordFilter(f.start, f.end, request.start, request.end))
|
|
417
344
|
: items;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
(0, util_1.checkAbortSignal)(
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
case 'bigbed':
|
|
460
|
-
observer.next(_this.parseBigBedBlock(resultData, blockOffset, Number(block.offset) * (1 << 8), request_2));
|
|
461
|
-
break;
|
|
462
|
-
default:
|
|
463
|
-
console.warn("Don't know what to do with ".concat(blockType_1));
|
|
464
|
-
}
|
|
465
|
-
});
|
|
466
|
-
return [2 /*return*/];
|
|
467
|
-
}
|
|
468
|
-
});
|
|
469
|
-
}); }))];
|
|
470
|
-
case 1:
|
|
471
|
-
_b.sent();
|
|
472
|
-
observer.complete();
|
|
473
|
-
return [3 /*break*/, 3];
|
|
474
|
-
case 2:
|
|
475
|
-
e_3 = _b.sent();
|
|
476
|
-
observer.error(e_3);
|
|
477
|
-
return [3 /*break*/, 3];
|
|
478
|
-
case 3: return [2 /*return*/];
|
|
479
|
-
}
|
|
480
|
-
});
|
|
345
|
+
}
|
|
346
|
+
readFeatures(observer, blocks, opts = {}) {
|
|
347
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
348
|
+
try {
|
|
349
|
+
const { blockType, isCompressed } = this;
|
|
350
|
+
const { signal, request } = opts;
|
|
351
|
+
const blockGroupsToFetch = (0, util_1.groupBlocks)(blocks);
|
|
352
|
+
(0, util_1.checkAbortSignal)(signal);
|
|
353
|
+
yield Promise.all(blockGroupsToFetch.map((blockGroup) => __awaiter(this, void 0, void 0, function* () {
|
|
354
|
+
(0, util_1.checkAbortSignal)(signal);
|
|
355
|
+
const { length, offset } = blockGroup;
|
|
356
|
+
const data = yield this.featureCache.get(`${length}_${offset}`, blockGroup, signal);
|
|
357
|
+
blockGroup.blocks.forEach(block => {
|
|
358
|
+
(0, util_1.checkAbortSignal)(signal);
|
|
359
|
+
let blockOffset = Number(block.offset) - Number(blockGroup.offset);
|
|
360
|
+
let resultData = data;
|
|
361
|
+
if (isCompressed) {
|
|
362
|
+
resultData = (0, unzip_1.unzip)(data.subarray(blockOffset));
|
|
363
|
+
blockOffset = 0;
|
|
364
|
+
}
|
|
365
|
+
(0, util_1.checkAbortSignal)(signal);
|
|
366
|
+
switch (blockType) {
|
|
367
|
+
case 'summary':
|
|
368
|
+
observer.next(this.parseSummaryBlock(resultData, blockOffset, request));
|
|
369
|
+
break;
|
|
370
|
+
case 'bigwig':
|
|
371
|
+
observer.next(this.parseBigWigBlock(resultData, blockOffset, request));
|
|
372
|
+
break;
|
|
373
|
+
case 'bigbed':
|
|
374
|
+
observer.next(this.parseBigBedBlock(resultData, blockOffset, Number(block.offset) * (1 << 8), request));
|
|
375
|
+
break;
|
|
376
|
+
default:
|
|
377
|
+
console.warn(`Don't know what to do with ${blockType}`);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
})));
|
|
381
|
+
observer.complete();
|
|
382
|
+
}
|
|
383
|
+
catch (e) {
|
|
384
|
+
observer.error(e);
|
|
385
|
+
}
|
|
481
386
|
});
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
}());
|
|
387
|
+
}
|
|
388
|
+
}
|
|
485
389
|
exports.BlockView = BlockView;
|
|
486
390
|
//# sourceMappingURL=blockView.js.map
|