Comparing version 1.0.14 to 1.0.15
@@ -0,1 +1,9 @@ | ||
## [1.0.15](https://github.com/GMOD/bam-js/compare/v1.0.14...v1.0.15) (2019-04-04) | ||
- Added check for too large of chromosomes in the bai bins | ||
- Added aborting support (thanks @rbuels) | ||
- Refactored index file class | ||
<a name="1.0.14"></a> | ||
@@ -2,0 +10,0 @@ ## [1.0.14](https://github.com/GMOD/bam-js/compare/v1.0.13...v1.0.14) (2019-01-04) |
422
dist/bai.js
@@ -1,133 +0,36 @@ | ||
'use strict'; | ||
var _regenerator = require('babel-runtime/regenerator'); | ||
var _regenerator2 = _interopRequireDefault(_regenerator); | ||
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); | ||
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); | ||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | ||
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var Long = require('long'); | ||
"use strict";var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));var Long = require('long'); | ||
var VirtualOffset = require('./virtualOffset'); | ||
var Chunk = require('./chunk'); | ||
var IndexFile = require('./indexFile'); | ||
var BAI_MAGIC = 21578050; // BAI\1 | ||
var _require = require('./util'),longToNumber = _require.longToNumber,abortBreakPoint = _require.abortBreakPoint;var | ||
var _require = require('./util'), | ||
longToNumber = _require.longToNumber; | ||
BAI = /*#__PURE__*/function (_IndexFile) {(0, _inherits2.default)(BAI, _IndexFile);function BAI() {(0, _classCallCheck2.default)(this, BAI);return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BAI).apply(this, arguments));}(0, _createClass2.default)(BAI, [{ key: "parsePseudoBin", value: function parsePseudoBin( | ||
bytes, offset) { | ||
var lineCount = longToNumber( | ||
Long.fromBytesLE(bytes.slice(offset + 16, offset + 24), true)); | ||
var BAI = function () { | ||
/** | ||
* @param {filehandle} filehandle | ||
* @param {function} [renameRefSeqs] | ||
*/ | ||
function BAI(_ref) { | ||
var filehandle = _ref.filehandle, | ||
_ref$renameRefSeqs = _ref.renameRefSeqs, | ||
renameRefSeqs = _ref$renameRefSeqs === undefined ? function (n) { | ||
return n; | ||
} : _ref$renameRefSeqs; | ||
(0, _classCallCheck3.default)(this, BAI); | ||
this.filehandle = filehandle; | ||
this.renameRefSeq = renameRefSeqs; | ||
} | ||
(0, _createClass3.default)(BAI, [{ | ||
key: '_findFirstData', | ||
value: function _findFirstData(data, virtualOffset) { | ||
var currentFdl = data.firstDataLine; | ||
if (currentFdl) { | ||
data.firstDataLine = currentFdl.compareTo(virtualOffset) > 0 ? virtualOffset : currentFdl; | ||
} else { | ||
data.firstDataLine = virtualOffset; | ||
} | ||
} | ||
}, { | ||
key: 'parsePseudoBin', | ||
value: function parsePseudoBin(bytes, offset) { | ||
var lineCount = longToNumber(Long.fromBytesLE(bytes.slice(offset + 20, offset + 28), true)); | ||
return { lineCount: lineCount }; | ||
} | ||
}, { | ||
key: 'lineCount', | ||
value: function () { | ||
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(refId) { | ||
var index, ret; | ||
return _regenerator2.default.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.next = 2; | ||
return this.parse(); | ||
} }, { key: "lineCount", value: function () {var _lineCount = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee( | ||
case 2: | ||
_context.t0 = refId; | ||
index = _context.sent.indices[_context.t0]; | ||
refId) {var index, ret;return _regenerator.default.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:_context.next = 2;return ( | ||
this.parse());case 2:_context.t0 = refId;index = _context.sent.indices[_context.t0];if ( | ||
index) {_context.next = 6;break;}return _context.abrupt("return", | ||
-1);case 6: | ||
if (index) { | ||
_context.next = 6; | ||
break; | ||
} | ||
ret = index.stats || {};return _context.abrupt("return", | ||
ret.lineCount === undefined ? -1 : ret.lineCount);case 8:case "end":return _context.stop();}}}, _callee, this);}));function lineCount(_x) {return _lineCount.apply(this, arguments);}return lineCount;}() | ||
return _context.abrupt('return', -1); | ||
case 6: | ||
ret = index.stats || {}; | ||
return _context.abrupt('return', ret.lineCount === undefined ? -1 : ret.lineCount); | ||
case 8: | ||
case 'end': | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, this); | ||
})); | ||
function lineCount(_x) { | ||
return _ref2.apply(this, arguments); | ||
} | ||
return lineCount; | ||
}() | ||
// memoize | ||
// fetch and parse the index | ||
}, { key: "_parse", value: function () {var _parse2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(abortSignal) {var data, bytes, depth, binLimit, currOffset, i, binCount, stats, binIndex, j, bin, chunkCount, chunks, k, u, v, nintv;return _regenerator.default.wrap(function _callee2$(_context2) {while (1) {switch (_context2.prev = _context2.next) {case 0: | ||
data = { bai: true, maxBlockSize: 1 << 16 };_context2.next = 3;return ( | ||
this.filehandle.readFile(abortSignal));case 3:bytes = _context2.sent;if (!( | ||
}, { | ||
key: 'parse', | ||
value: function () { | ||
var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() { | ||
var data, bytes, depth, binLimit, currOffset, i, binCount, stats, binIndex, j, bin, chunkCount, chunks, k, u, v, nintv; | ||
return _regenerator2.default.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
data = { bai: true, maxBlockSize: 1 << 16 }; | ||
_context2.next = 3; | ||
return this.filehandle.readFile(); | ||
case 3: | ||
bytes = _context2.sent; | ||
bytes.readUInt32LE(0) !== BAI_MAGIC)) {_context2.next = 6;break;}throw ( | ||
new Error('Not a BAI file'));case 6: | ||
if (!(bytes.readUInt32LE(0) !== BAI_MAGIC)) { | ||
_context2.next = 6; | ||
break; | ||
} | ||
throw new Error('Not a BAI file'); | ||
case 6: | ||
data.refCount = bytes.readInt32LE(4); | ||
@@ -138,110 +41,68 @@ depth = 5; | ||
// read the indexes for each reference sequence | ||
data.indices = new Array(data.refCount); | ||
currOffset = 8; | ||
i = 0;case 12:if (!(i < data.refCount)) {_context2.next = 49;break;}_context2.next = 15;return ( | ||
abortBreakPoint(abortSignal));case 15: | ||
for (i = 0; i < data.refCount; i += 1) { | ||
// the binning index | ||
binCount = bytes.readInt32LE(currOffset); | ||
stats = void 0; | ||
// the binning index | ||
binCount = bytes.readInt32LE(currOffset); | ||
stats = void 0; | ||
currOffset += 4; | ||
binIndex = {}; | ||
j = 0;case 20:if (!(j < binCount)) {_context2.next = 41;break;} | ||
bin = bytes.readUInt32LE(currOffset); | ||
currOffset += 4;if (!( | ||
bin === binLimit + 1)) {_context2.next = 29;break;} | ||
currOffset += 4; | ||
stats = this.parsePseudoBin(bytes, currOffset); | ||
currOffset += 32;_context2.next = 38;break;case 29:if (!( | ||
bin > binLimit + 1)) {_context2.next = 33;break;}throw ( | ||
new Error('bai index contains too many bins, please use CSI'));case 33: | ||
currOffset += 4; | ||
binIndex = {}; | ||
chunkCount = bytes.readInt32LE(currOffset); | ||
currOffset += 4; | ||
chunks = new Array(chunkCount); | ||
for (k = 0; k < chunkCount; k += 1) { | ||
u = VirtualOffset.fromBytes(bytes, currOffset); | ||
v = VirtualOffset.fromBytes(bytes, currOffset + 8); | ||
currOffset += 16; | ||
this._findFirstData(data, u); | ||
chunks[k] = new Chunk(u, v, bin); | ||
} | ||
binIndex[bin] = chunks;case 38:j += 1;_context2.next = 20;break;case 41: | ||
for (j = 0; j < binCount; j += 1) { | ||
bin = bytes.readUInt32LE(currOffset); | ||
if (bin > binLimit) { | ||
stats = this.parsePseudoBin(bytes, currOffset + 4); | ||
} | ||
chunkCount = bytes.readInt32LE(currOffset + 4); | ||
currOffset += 8; | ||
chunks = new Array(chunkCount); | ||
for (k = 0; k < chunkCount; k += 1) { | ||
u = VirtualOffset.fromBytes(bytes, currOffset); | ||
v = VirtualOffset.fromBytes(bytes, currOffset + 8); | ||
currOffset += 16; | ||
this._findFirstData(data, u); | ||
chunks[k] = new Chunk(u, v, bin); | ||
} | ||
binIndex[bin] = chunks; | ||
} | ||
nintv = bytes.readInt32LE(currOffset); | ||
currOffset += 4; | ||
// as we're going through the linear index, figure out | ||
// the smallest virtual offset in the indexes, which | ||
// tells us where the BAM header ends | ||
if (nintv) { | ||
this._findFirstData(bytes, VirtualOffset.fromBytes(bytes, currOffset)); | ||
} | ||
currOffset += nintv * 8; | ||
data.indices[i] = { binIndex: binIndex, stats: stats }; | ||
nintv = bytes.readInt32LE(currOffset); | ||
currOffset += 4; | ||
// as we're going through the linear index, figure out | ||
// the smallest virtual offset in the indexes, which | ||
// tells us where the BAM header ends | ||
if (nintv) { | ||
this._findFirstData(bytes, VirtualOffset.fromBytes(bytes, currOffset)); | ||
} | ||
return _context2.abrupt('return', data); | ||
currOffset += nintv * 8; | ||
case 13: | ||
case 'end': | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2, this); | ||
})); | ||
data.indices[i] = { binIndex: binIndex, stats: stats };case 46:i += 1;_context2.next = 12;break;case 49:return _context2.abrupt("return", | ||
function parse() { | ||
return _ref3.apply(this, arguments); | ||
} | ||
return parse; | ||
}() | ||
}, { | ||
key: 'blocksForRange', | ||
value: function () { | ||
var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(refId, beg, end) { | ||
var indexData, indexes, binIndex, bins, l, numOffsets, i, off, _i, chunks, j, _i2, _i3, _i4; | ||
data);case 50:case "end":return _context2.stop();}}}, _callee2, this);}));function _parse(_x2) {return _parse2.apply(this, arguments);}return _parse;}() }, { key: "blocksForRange", value: function () {var _blocksForRange = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3( | ||
return _regenerator2.default.wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (beg < 0) beg = 0; | ||
_context3.next = 3; | ||
return this.parse(); | ||
refId, beg, end) {var indexData, indexes, binIndex, bins, l, numOffsets, i, off, _i, chunks, j, _i2, _i3, _i4;return _regenerator.default.wrap(function _callee3$(_context3) {while (1) {switch (_context3.prev = _context3.next) {case 0: | ||
if (beg < 0) beg = 0;_context3.next = 3;return ( | ||
case 3: | ||
indexData = _context3.sent; | ||
this.parse());case 3:indexData = _context3.sent;if ( | ||
indexData) {_context3.next = 6;break;}return _context3.abrupt("return", []);case 6: | ||
indexes = indexData.indices[refId];if ( | ||
indexes) {_context3.next = 9;break;}return _context3.abrupt("return", []);case 9: | ||
if (indexData) { | ||
_context3.next = 6; | ||
break; | ||
} | ||
binIndex = indexes.binIndex; | ||
return _context3.abrupt('return', []); | ||
bins = this.reg2bins(beg, end); | ||
case 6: | ||
indexes = indexData.indices[refId]; | ||
if (indexes) { | ||
_context3.next = 9; | ||
break; | ||
} | ||
return _context3.abrupt('return', []); | ||
case 9: | ||
binIndex = indexes.binIndex; | ||
bins = this.reg2bins(beg, end); | ||
l = void 0; | ||
numOffsets = 0; | ||
for (i = 0; i < bins.length; i += 1) { | ||
@@ -251,37 +112,25 @@ if (binIndex[bins[i]]) { | ||
} | ||
} | ||
}if (!( | ||
if (!(numOffsets === 0)) { | ||
_context3.next = 16; | ||
break; | ||
} | ||
numOffsets === 0)) {_context3.next = 15;break;}return _context3.abrupt("return", []);case 15: | ||
return _context3.abrupt('return', []); | ||
case 16: | ||
off = []; | ||
numOffsets = 0; | ||
for (_i = 0; _i < bins.length; _i += 1) { | ||
chunks = binIndex[bins[_i]]; | ||
if (chunks) | ||
for (j = 0; j < chunks.length; j += 1) { | ||
off[numOffsets] = new Chunk( | ||
chunks[j].minv, | ||
chunks[j].maxv, | ||
chunks[j].bin); | ||
if (chunks) for (j = 0; j < chunks.length; j += 1) { | ||
off[numOffsets] = new Chunk(chunks[j].minv, chunks[j].maxv, chunks[j].bin); | ||
numOffsets += 1; | ||
} | ||
} | ||
}if ( | ||
if (off.length) { | ||
_context3.next = 21; | ||
break; | ||
} | ||
off.length) {_context3.next = 20;break;}return _context3.abrupt("return", []);case 20: | ||
return _context3.abrupt('return', []); | ||
off = off.sort(function (a, b) {return a.compareTo(b);}); | ||
case 21: | ||
off = off.sort(function (a, b) { | ||
return a.compareTo(b); | ||
}); | ||
// resolve completely contained adjacent blocks | ||
@@ -300,7 +149,10 @@ l = 0; | ||
for (_i3 = 1; _i3 < numOffsets; _i3 += 1) { | ||
if (off[_i3 - 1].maxv.compareTo(off[_i3].minv) >= 0) off[_i3 - 1].maxv = off[_i3].minv; | ||
} // merge adjacent blocks | ||
if (off[_i3 - 1].maxv.compareTo(off[_i3].minv) >= 0) | ||
off[_i3 - 1].maxv = off[_i3].minv;} | ||
// merge adjacent blocks | ||
l = 0; | ||
for (_i4 = 1; _i4 < numOffsets; _i4 += 1) { | ||
if (off[l].maxv.blockPosition === off[_i4].minv.blockPosition) off[l].maxv = off[_i4].maxv;else { | ||
if (off[l].maxv.blockPosition === off[_i4].minv.blockPosition) | ||
off[l].maxv = off[_i4].maxv;else | ||
{ | ||
l += 1; | ||
@@ -311,108 +163,24 @@ off[l].minv = off[_i4].minv; | ||
} | ||
numOffsets = l + 1; | ||
numOffsets = l + 1;return _context3.abrupt("return", | ||
return _context3.abrupt('return', off.slice(0, numOffsets)); | ||
off.slice(0, numOffsets));case 29:case "end":return _context3.stop();}}}, _callee3, this);}));function blocksForRange(_x3, _x4, _x5) {return _blocksForRange.apply(this, arguments);}return blocksForRange;}() | ||
case 30: | ||
case 'end': | ||
return _context3.stop(); | ||
} | ||
} | ||
}, _callee3, this); | ||
})); | ||
function blocksForRange(_x2, _x3, _x4) { | ||
return _ref4.apply(this, arguments); | ||
} | ||
return blocksForRange; | ||
}() | ||
/** | ||
* @param {number} seqId | ||
* @returns {Promise} true if the index contains entries for | ||
* the given reference sequence ID, false otherwise | ||
*/ | ||
}, { | ||
key: 'hasRefSeq', | ||
value: function () { | ||
var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(seqId) { | ||
return _regenerator2.default.wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
_context4.next = 2; | ||
return this.parse(); | ||
case 2: | ||
_context4.t1 = seqId; | ||
_context4.t0 = _context4.sent.indices[_context4.t1]; | ||
if (_context4.t0) { | ||
_context4.next = 6; | ||
break; | ||
} | ||
_context4.t0 = {}; | ||
case 6: | ||
return _context4.abrupt('return', !!_context4.t0.binIndex); | ||
case 7: | ||
case 'end': | ||
return _context4.stop(); | ||
} | ||
} | ||
}, _callee4, this); | ||
})); | ||
function hasRefSeq(_x5) { | ||
return _ref5.apply(this, arguments); | ||
} | ||
return hasRefSeq; | ||
}() | ||
/** | ||
* calculate the list of bins that may overlap with region [beg,end) (zero-based half-open) | ||
* @returns {Array[number]} | ||
*/ | ||
}, { | ||
key: 'reg2bins', | ||
value: function reg2bins(beg, end) { | ||
* calculate the list of bins that may overlap with region [beg,end) (zero-based half-open) | ||
* @returns {Array[number]} | ||
*/ }, { key: "reg2bins", value: function reg2bins( | ||
beg, end) { | ||
var list = [0]; | ||
end -= 1; | ||
for (var k = 1 + (beg >> 26); k <= 1 + (end >> 26); k += 1) { | ||
list.push(k); | ||
}for (var _k = 9 + (beg >> 23); _k <= 9 + (end >> 23); _k += 1) { | ||
list.push(_k); | ||
}for (var _k2 = 73 + (beg >> 20); _k2 <= 73 + (end >> 20); _k2 += 1) { | ||
list.push(_k2); | ||
}for (var _k3 = 585 + (beg >> 17); _k3 <= 585 + (end >> 17); _k3 += 1) { | ||
list.push(_k3); | ||
}for (var _k4 = 4681 + (beg >> 14); _k4 <= 4681 + (end >> 14); _k4 += 1) { | ||
list.push(_k4); | ||
}return list; | ||
} | ||
}]); | ||
return BAI; | ||
}(); | ||
for (var k = 1 + (beg >> 26); k <= 1 + (end >> 26); k += 1) {list.push(k);} | ||
for (var _k = 9 + (beg >> 23); _k <= 9 + (end >> 23); _k += 1) {list.push(_k);} | ||
for (var _k2 = 73 + (beg >> 20); _k2 <= 73 + (end >> 20); _k2 += 1) {list.push(_k2);} | ||
for (var _k3 = 585 + (beg >> 17); _k3 <= 585 + (end >> 17); _k3 += 1) {list.push(_k3);} | ||
for (var _k4 = 4681 + (beg >> 14); _k4 <= 4681 + (end >> 14); _k4 += 1) { | ||
list.push(_k4);} | ||
return list; | ||
} }]);return BAI;}(IndexFile); | ||
// this is the stupidest possible memoization, ignores arguments. | ||
function tinyMemoize(_class, methodName) { | ||
var method = _class.prototype[methodName]; | ||
if (!method) throw new Error('no method ' + methodName + ' found in class ' + _class.name); | ||
var memoAttrName = '_memo_' + methodName; | ||
_class.prototype[methodName] = function _tinyMemoized() { | ||
if (!(memoAttrName in this)) this[memoAttrName] = method.call(this); | ||
return this[memoAttrName]; | ||
}; | ||
} | ||
// memoize index.parse() | ||
tinyMemoize(BAI, 'parse'); | ||
module.exports = BAI; |
@@ -1,78 +0,36 @@ | ||
'use strict'; | ||
"use strict";var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));var _abortablePromiseCache = _interopRequireDefault(require("abortable-promise-cache"));var _require = | ||
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray'); | ||
require('@gmod/bgzf-filehandle'),unzip = _require.unzip; | ||
var LRU = require('quick-lru'); | ||
var BAI = require('./bai'); | ||
var CSI = require('./csi'); | ||
var LocalFile = require('./localFile'); | ||
var BAMFeature = require('./record');var _require2 = | ||
require('./sam'),parseHeaderText = _require2.parseHeaderText;var _require3 = | ||
require('./util'),abortBreakPoint = _require3.abortBreakPoint,checkAbortSignal = _require3.checkAbortSignal; | ||
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); | ||
var BAM_MAGIC = 21840194; | ||
var _entries = require('babel-runtime/core-js/object/entries'); | ||
var blockLen = 1 << 16;var | ||
var _entries2 = _interopRequireDefault(_entries); | ||
BamFile = /*#__PURE__*/function () { | ||
/** | ||
* @param {object} args | ||
* @param {string} [args.bamPath] | ||
* @param {FileHandle} [args.bamFilehandle] | ||
* @param {string} [args.baiPath] | ||
* @param {FileHandle} [args.baiFilehandle] | ||
*/ | ||
function BamFile(_ref) | ||
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray'); | ||
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2); | ||
var _promise = require('babel-runtime/core-js/promise'); | ||
var _promise2 = _interopRequireDefault(_promise); | ||
var _regenerator = require('babel-runtime/regenerator'); | ||
var _regenerator2 = _interopRequireDefault(_regenerator); | ||
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); | ||
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); | ||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | ||
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var _require = require('@gmod/bgzf-filehandle'), | ||
unzip = _require.unzip; | ||
var LRU = require('quick-lru'); | ||
var BAI = require('./bai'); | ||
var CSI = require('./csi'); | ||
var LocalFile = require('./localFile'); | ||
var BAMFeature = require('./record'); | ||
var _require2 = require('./sam'), | ||
parseHeaderText = _require2.parseHeaderText; | ||
var BAM_MAGIC = 21840194; | ||
var blockLen = 1 << 16; | ||
var BamFile = function () { | ||
/** | ||
* @param {object} args | ||
* @param {string} [args.bamPath] | ||
* @param {FileHandle} [args.bamFilehandle] | ||
* @param {string} [args.baiPath] | ||
* @param {FileHandle} [args.baiFilehandle] | ||
*/ | ||
function BamFile(_ref) { | ||
var bamFilehandle = _ref.bamFilehandle, | ||
bamPath = _ref.bamPath, | ||
baiPath = _ref.baiPath, | ||
baiFilehandle = _ref.baiFilehandle, | ||
csiPath = _ref.csiPath, | ||
csiFilehandle = _ref.csiFilehandle, | ||
cacheSize = _ref.cacheSize, | ||
fetchSizeLimit = _ref.fetchSizeLimit, | ||
chunkSizeLimit = _ref.chunkSizeLimit, | ||
_ref$renameRefSeqs = _ref.renameRefSeqs, | ||
renameRefSeqs = _ref$renameRefSeqs === undefined ? function (n) { | ||
return n; | ||
} : _ref$renameRefSeqs; | ||
(0, _classCallCheck3.default)(this, BamFile); | ||
{var bamFilehandle = _ref.bamFilehandle,bamPath = _ref.bamPath,baiPath = _ref.baiPath,baiFilehandle = _ref.baiFilehandle,csiPath = _ref.csiPath,csiFilehandle = _ref.csiFilehandle,cacheSize = _ref.cacheSize,fetchSizeLimit = _ref.fetchSizeLimit,chunkSizeLimit = _ref.chunkSizeLimit,_ref$renameRefSeqs = _ref.renameRefSeqs,renameRefSeqs = _ref$renameRefSeqs === void 0 ? function (n) {return n;} : _ref$renameRefSeqs;(0, _classCallCheck2.default)(this, BamFile); | ||
this.renameRefSeq = renameRefSeqs; | ||
@@ -90,4 +48,4 @@ | ||
this.index = new CSI({ | ||
filehandle: new LocalFile(csiPath) | ||
}); | ||
filehandle: new LocalFile(csiPath) }); | ||
} else if (baiFilehandle) { | ||
@@ -98,54 +56,34 @@ this.index = new BAI({ filehandle: baiFilehandle }); | ||
} else { | ||
this.index = new BAI({ filehandle: new LocalFile(bamPath + '.bai') }); | ||
this.index = new BAI({ filehandle: new LocalFile("".concat(bamPath, ".bai")) }); | ||
} | ||
this.featureCache = new LRU({ | ||
maxSize: cacheSize !== undefined ? cacheSize : 20000, | ||
length: function length(featureArray) { | ||
return featureArray.length; | ||
} | ||
}); | ||
this.featureCache = new _abortablePromiseCache.default({ | ||
cache: new LRU({ | ||
maxSize: cacheSize !== undefined ? cacheSize : 50 }), | ||
fill: this._readChunk.bind(this) }); | ||
this.fetchSizeLimit = fetchSizeLimit || 50000000; | ||
this.chunkSizeLimit = chunkSizeLimit || 10000000; | ||
} | ||
}(0, _createClass2.default)(BamFile, [{ key: "getHeader", value: function () {var _getHeader = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee( | ||
(0, _createClass3.default)(BamFile, [{ | ||
key: 'getHeader', | ||
value: function () { | ||
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee() { | ||
var indexData, ret, buf, bytesRead, uncba, headLen, _ref3, chrToIndex, indexToChr; | ||
abortSignal) {var indexData, ret, buf, bytesRead, uncba, headLen, _ref2, chrToIndex, indexToChr;return _regenerator.default.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:_context.next = 2;return ( | ||
this.index.parse(abortSignal));case 2:indexData = _context.sent; | ||
ret = indexData.firstDataLine ? | ||
indexData.firstDataLine.blockPosition + 65535 : | ||
undefined;if (! | ||
return _regenerator2.default.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.next = 2; | ||
return this.index.parse(); | ||
ret) {_context.next = 14;break;} | ||
buf = Buffer.alloc(ret + blockLen);_context.next = 8;return ( | ||
this.bam.read( | ||
buf, | ||
0, | ||
ret + blockLen, | ||
0, | ||
abortSignal));case 8:bytesRead = _context.sent;if ( | ||
case 2: | ||
indexData = _context.sent; | ||
ret = indexData.firstDataLine ? indexData.firstDataLine.blockPosition + 65535 : undefined; | ||
buf = void 0; | ||
bytesRead) {_context.next = 11;break;}throw ( | ||
new Error('Error reading header'));case 11: | ||
if (!ret) { | ||
_context.next = 15; | ||
break; | ||
} | ||
buf = Buffer.alloc(ret + blockLen); | ||
_context.next = 9; | ||
return this.bam.read(buf, 0, ret + blockLen, 0); | ||
case 9: | ||
bytesRead = _context.sent; | ||
if (bytesRead) { | ||
_context.next = 12; | ||
break; | ||
} | ||
throw new Error('Error reading header'); | ||
case 12: | ||
if (bytesRead < ret) { | ||
@@ -155,96 +93,40 @@ buf = buf.slice(0, bytesRead); | ||
buf = buf.slice(0, ret); | ||
} | ||
_context.next = 18; | ||
break; | ||
}_context.next = 17;break;case 14:_context.next = 16;return ( | ||
case 15: | ||
_context.next = 17; | ||
return this.bam.readFile(); | ||
this.bam.readFile(abortSignal));case 16:buf = _context.sent;case 17:_context.next = 19;return ( | ||
case 17: | ||
buf = _context.sent; | ||
case 18: | ||
_context.next = 20; | ||
return unzip(buf); | ||
unzip(buf));case 19:uncba = _context.sent;if (!( | ||
case 20: | ||
uncba = _context.sent; | ||
if (!(uncba.readInt32LE(0) !== BAM_MAGIC)) { | ||
_context.next = 23; | ||
break; | ||
} | ||
throw new Error('Not a BAM file'); | ||
case 23: | ||
uncba.readInt32LE(0) !== BAM_MAGIC)) {_context.next = 22;break;}throw new Error('Not a BAM file');case 22: | ||
headLen = uncba.readInt32LE(4); | ||
this.header = uncba.toString('utf8', 8, 8 + headLen);_context.next = 26;return ( | ||
this._readRefSeqs( | ||
headLen + 8, | ||
65535, | ||
abortSignal));case 26:_ref2 = _context.sent;chrToIndex = _ref2.chrToIndex;indexToChr = _ref2.indexToChr; | ||
this.header = uncba.toString('utf8', 8, 8 + headLen); | ||
_context.next = 27; | ||
return this._readRefSeqs(headLen + 8, 65535); | ||
case 27: | ||
_ref3 = _context.sent; | ||
chrToIndex = _ref3.chrToIndex; | ||
indexToChr = _ref3.indexToChr; | ||
this.chrToIndex = chrToIndex; | ||
this.indexToChr = indexToChr; | ||
this.indexToChr = indexToChr;return _context.abrupt("return", | ||
return _context.abrupt('return', parseHeaderText(this.header)); | ||
parseHeaderText(this.header));case 32:case "end":return _context.stop();}}}, _callee, this);}));function getHeader(_x) {return _getHeader.apply(this, arguments);}return getHeader;}() | ||
case 33: | ||
case 'end': | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, this); | ||
})); | ||
function getHeader() { | ||
return _ref2.apply(this, arguments); | ||
} | ||
return getHeader; | ||
}() | ||
// the full length of the refseq block is not given in advance so this grabs a chunk and | ||
// doubles it if all refseqs haven't been processed | ||
}, { key: "_readRefSeqs", value: function () {var _readRefSeqs2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(start, refSeqBytes, abortSignal) {var buf, bytesRead, uncba, nRef, p, chrToIndex, indexToChr, i, lName, refName, lRef;return _regenerator.default.wrap(function _callee2$(_context2) {while (1) {switch (_context2.prev = _context2.next) {case 0: | ||
buf = Buffer.alloc(refSeqBytes + blockLen);if (!( | ||
start > refSeqBytes)) {_context2.next = 3;break;}return _context2.abrupt("return", | ||
this._readRefSeqs(start, refSeqBytes * 2));case 3:_context2.next = 5;return ( | ||
}, { | ||
key: '_readRefSeqs', | ||
value: function () { | ||
var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(start, refSeqBytes) { | ||
var buf, bytesRead, uncba, nRef, p, chrToIndex, indexToChr, i, lName, refName, lRef; | ||
return _regenerator2.default.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
buf = Buffer.alloc(refSeqBytes + blockLen); | ||
this.bam.read( | ||
buf, | ||
0, | ||
refSeqBytes + blockLen, | ||
abortSignal));case 5:bytesRead = _context2.sent;if ( | ||
if (!(start > refSeqBytes)) { | ||
_context2.next = 3; | ||
break; | ||
} | ||
bytesRead) {_context2.next = 8;break;}return _context2.abrupt("return", | ||
new Error('Error reading refseqs from header'));case 8: | ||
return _context2.abrupt('return', this._readRefSeqs(start, refSeqBytes * 2)); | ||
case 3: | ||
_context2.next = 5; | ||
return this.bam.read(buf, 0, refSeqBytes + blockLen); | ||
case 5: | ||
bytesRead = _context2.sent; | ||
if (bytesRead) { | ||
_context2.next = 8; | ||
break; | ||
} | ||
return _context2.abrupt('return', new Error('Error reading refseqs from header')); | ||
case 8: | ||
if (bytesRead < refSeqBytes) { | ||
@@ -254,8 +136,4 @@ buf = buf.slice(0, bytesRead); | ||
buf = buf.slice(0, refSeqBytes); | ||
} | ||
_context2.next = 11; | ||
return unzip(buf); | ||
case 11: | ||
uncba = _context2.sent; | ||
}_context2.next = 11;return ( | ||
unzip(buf));case 11:uncba = _context2.sent; | ||
nRef = uncba.readInt32LE(start); | ||
@@ -265,62 +143,25 @@ p = start + 4; | ||
indexToChr = []; | ||
i = 0; | ||
case 17: | ||
if (!(i < nRef)) { | ||
_context2.next = 31; | ||
break; | ||
} | ||
i = 0;case 17:if (!(i < nRef)) {_context2.next = 33;break;}_context2.next = 20;return ( | ||
abortBreakPoint(abortSignal));case 20: | ||
lName = uncba.readInt32LE(p); | ||
refName = uncba.toString('utf8', p + 4, p + 4 + lName - 1); | ||
refName = this.renameRefSeq(refName); | ||
lRef = uncba.readInt32LE(p + lName + 4); | ||
chrToIndex[refName] = i; | ||
indexToChr.push({ refName: refName, length: lRef }); | ||
p = p + 8 + lName; | ||
p = p + 8 + lName;if (!( | ||
p > uncba.length)) {_context2.next = 30;break;} | ||
// eslint-disable-next-line no-console | ||
console.warn("BAM header is very big. Re-fetching ".concat( | ||
refSeqBytes, " bytes."));return _context2.abrupt("return", | ||
if (!(p > uncba.length)) { | ||
_context2.next = 28; | ||
break; | ||
} | ||
this._readRefSeqs(start, refSeqBytes * 2));case 30:i += 1;_context2.next = 17;break;case 33:return _context2.abrupt("return", | ||
console.warn('BAM header is very big. Re-fetching ' + refSeqBytes + ' bytes.'); | ||
return _context2.abrupt('return', this._readRefSeqs(start, refSeqBytes * 2)); | ||
case 28: | ||
i += 1; | ||
_context2.next = 17; | ||
break; | ||
{ chrToIndex: chrToIndex, indexToChr: indexToChr });case 34:case "end":return _context2.stop();}}}, _callee2, this);}));function _readRefSeqs(_x2, _x3, _x4) {return _readRefSeqs2.apply(this, arguments);}return _readRefSeqs;}() }, { key: "getRecordsForRange", value: function () {var _getRecordsForRange = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3( | ||
case 31: | ||
return _context2.abrupt('return', { chrToIndex: chrToIndex, indexToChr: indexToChr }); | ||
case 32: | ||
case 'end': | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2, this); | ||
})); | ||
function _readRefSeqs(_x, _x2) { | ||
return _ref4.apply(this, arguments); | ||
} | ||
return _readRefSeqs; | ||
}() | ||
}, { | ||
key: 'getRecordsForRange', | ||
value: function () { | ||
var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(chr, min, max) { | ||
var opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; | ||
var chrId, chunks, i, size, totalSize; | ||
return _regenerator2.default.wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
chr, min, max) {var opts,chrId,chunks,i,size,totalSize,_args3 = arguments;return _regenerator.default.wrap(function _callee3$(_context3) {while (1) {switch (_context3.prev = _context3.next) {case 0:opts = _args3.length > 3 && _args3[3] !== undefined ? _args3[3] : {}; | ||
opts.viewAsPairs = opts.viewAsPairs || false; | ||
@@ -330,106 +171,42 @@ opts.pairAcrossChr = opts.pairAcrossChr || false; | ||
// todo regularize refseq names | ||
chrId = this.chrToIndex && this.chrToIndex[chr]; | ||
chunks = void 0; | ||
chrId = this.chrToIndex && this.chrToIndex[chr];if ( | ||
if (chrId >= 0) { | ||
_context3.next = 9; | ||
break; | ||
} | ||
chrId >= 0) {_context3.next = 9;break;} | ||
chunks = [];_context3.next = 14;break;case 9:_context3.next = 11;return ( | ||
chunks = []; | ||
_context3.next = 14; | ||
break; | ||
this.index.blocksForRange(chrId, min - 1, max, opts));case 11:chunks = _context3.sent;if ( | ||
case 9: | ||
_context3.next = 11; | ||
return this.index.blocksForRange(chrId, min - 1, max); | ||
chunks) {_context3.next = 14;break;}throw ( | ||
new Error('Error in index fetch'));case 14: | ||
case 11: | ||
chunks = _context3.sent; | ||
if (chunks) { | ||
_context3.next = 14; | ||
break; | ||
} | ||
throw new Error('Error in index fetch'); | ||
i = 0;case 15:if (!(i < chunks.length)) {_context3.next = 24;break;}_context3.next = 18;return ( | ||
abortBreakPoint(opts.signal));case 18: | ||
size = chunks[i].fetchedSize();if (!( | ||
size > this.chunkSizeLimit)) {_context3.next = 21;break;}throw ( | ||
new Error("Too many BAM features. BAM chunk size ".concat( | ||
size, " bytes exceeds chunkSizeLimit of ").concat( | ||
this.chunkSizeLimit)));case 21:i += 1;_context3.next = 15;break;case 24: | ||
case 14: | ||
i = 0; | ||
case 15: | ||
if (!(i < chunks.length)) { | ||
_context3.next = 22; | ||
break; | ||
} | ||
size = chunks[i].fetchedSize(); | ||
if (!(size > this.chunkSizeLimit)) { | ||
_context3.next = 19; | ||
break; | ||
} | ||
throw new Error('Too many BAM features. BAM chunk size ' + size + ' bytes exceeds chunkSizeLimit of ' + this.chunkSizeLimit); | ||
totalSize = chunks. | ||
map(function (s) {return s.fetchedSize();}). | ||
reduce(function (a, b) {return a + b;}, 0);if (!( | ||
totalSize > this.fetchSizeLimit)) {_context3.next = 27;break;}throw ( | ||
new Error("data size of ".concat( | ||
totalSize.toLocaleString(), " bytes exceeded fetch size limit of ").concat(this.fetchSizeLimit.toLocaleString(), " bytes")));case 27:return _context3.abrupt("return", | ||
case 19: | ||
i += 1; | ||
_context3.next = 15; | ||
break; | ||
case 22: | ||
totalSize = chunks.map(function (s) { | ||
return s.fetchedSize(); | ||
}).reduce(function (a, b) { | ||
return a + b; | ||
}, 0); | ||
this._fetchChunkFeatures(chunks, chrId, min, max, opts));case 28:case "end":return _context3.stop();}}}, _callee3, this);}));function getRecordsForRange(_x5, _x6, _x7) {return _getRecordsForRange.apply(this, arguments);}return getRecordsForRange;}() }, { key: "_fetchChunkFeatures", value: function () {var _fetchChunkFeatures2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee4( | ||
if (!(totalSize > this.fetchSizeLimit)) { | ||
_context3.next = 25; | ||
break; | ||
} | ||
throw new Error('data size of ' + totalSize.toLocaleString() + ' bytes exceeded fetch size limit of ' + this.fetchSizeLimit.toLocaleString() + ' bytes'); | ||
case 25: | ||
return _context3.abrupt('return', this._fetchChunkFeatures(chunks, chrId, min, max, opts)); | ||
case 26: | ||
case 'end': | ||
return _context3.stop(); | ||
} | ||
} | ||
}, _callee3, this); | ||
})); | ||
function getRecordsForRange(_x3, _x4, _x5) { | ||
return _ref5.apply(this, arguments); | ||
} | ||
return getRecordsForRange; | ||
}() | ||
}, { | ||
key: '_fetchChunkFeatures', | ||
value: function () { | ||
var _ref6 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(chunks, chrId, min, max) { | ||
var _this = this, | ||
_ref7; | ||
var opts = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {}; | ||
var recordPromises, featPromises, recs, ret, readNames, readIds, i, name, id, unmatedPairs, matePromises, _i, _name, blocks, mateBlocks, mateChunks, _i2, _mateChunks, mateRecordPromises, mateFeatPromises, mateTotalSize, newMateFeats, newMates; | ||
return _regenerator2.default.wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
chunks, chrId, min, max) {var _this = this,_ref3;var opts,recordPromises,featPromises,recs,ret,readNames,readIds,i,name,id,unmatedPairs,matePromises,_i,_name,blocks,mateBlocks,mateChunks,_i2,_mateChunks,mateRecordPromises,mateFeatPromises,mateTotalSize,newMateFeats,newMates,_args4 = arguments;return _regenerator.default.wrap(function _callee4$(_context4) {while (1) {switch (_context4.prev = _context4.next) {case 0:opts = _args4.length > 4 && _args4[4] !== undefined ? _args4[4] : {}; | ||
recordPromises = []; | ||
featPromises = []; | ||
chunks.forEach(function (c) { | ||
var recordPromise = _this.featureCache.get(c.toString()); | ||
if (!recordPromise) { | ||
recordPromise = _this._readChunk(c); | ||
_this.featureCache.set(c.toString(), recordPromise); | ||
} | ||
var recordPromise = _this.featureCache.get(c.toString(), c, opts.signal); | ||
recordPromises.push(recordPromise); | ||
@@ -444,3 +221,4 @@ var featPromise = recordPromise.then(function (f) { | ||
// past end of range, can stop iterating | ||
break;else if (feature.get('end') >= min) { | ||
break;else | ||
if (feature.get('end') >= min) { | ||
// must be in range | ||
@@ -454,22 +232,12 @@ recs.push(feature); | ||
featPromises.push(featPromise); | ||
}); | ||
_context4.next = 5; | ||
return _promise2.default.all(featPromises); | ||
case 5: | ||
recs = _context4.sent; | ||
ret = (_ref7 = []).concat.apply(_ref7, (0, _toConsumableArray3.default)(recs)); | ||
if (!opts.viewAsPairs) { | ||
_context4.next = 31; | ||
break; | ||
} | ||
});_context4.next = 6;return ( | ||
_promise.default.all(featPromises));case 6:recs = _context4.sent; | ||
checkAbortSignal(opts.signal); | ||
ret = (_ref3 = []).concat.apply(_ref3, (0, _toConsumableArray2.default)(recs));if (! | ||
opts.viewAsPairs) {_context4.next = 33;break;} | ||
readNames = {}; | ||
readIds = {}; | ||
for (i = 0; i < ret.length; i++) { | ||
name = ret[i].name(); | ||
id = ret[i].id(); | ||
if (!readNames[name]) readNames[name] = 0; | ||
@@ -480,8 +248,3 @@ readNames[name]++; | ||
unmatedPairs = {}; | ||
(0, _entries2.default)(readNames).forEach(function (_ref8) { | ||
var _ref9 = (0, _slicedToArray3.default)(_ref8, 2), | ||
k = _ref9[0], | ||
v = _ref9[1]; | ||
(0, _entries.default)(readNames).forEach(function (_ref4) {var _ref5 = (0, _slicedToArray2.default)(_ref4, 2),k = _ref5[0],v = _ref5[1]; | ||
if (v === 1) unmatedPairs[k] = true; | ||
@@ -491,49 +254,49 @@ }); | ||
matePromises = []; | ||
for (_i = 0; _i < ret.length; _i++) { | ||
_name = ret[_i].name(); | ||
if ( | ||
unmatedPairs[_name] && ( | ||
ret[_i]._next_refid() === chrId || opts.pairAcrossChr) && | ||
Math.abs(ret[_i].get('start') - ret[_i]._next_pos()) < | ||
opts.maxInsertSize) | ||
{ | ||
blocks = this.index.blocksForRange( | ||
ret[_i]._next_refid(), | ||
ret[_i]._next_pos(), | ||
ret[_i]._next_pos() + 1, | ||
opts); | ||
if (unmatedPairs[_name] && (ret[_i]._next_refid() === chrId || opts.pairAcrossChr) && Math.abs(ret[_i].get('start') - ret[_i]._next_pos()) < opts.maxInsertSize) { | ||
blocks = this.index.blocksForRange(ret[_i]._next_refid(), ret[_i]._next_pos(), ret[_i]._next_pos() + 1); | ||
matePromises.push(blocks); | ||
} | ||
} | ||
_context4.next = 17; | ||
return _promise2.default.all(matePromises); | ||
case 17: | ||
mateBlocks = _context4.sent; | ||
}_context4.next = 19;return ( | ||
_promise.default.all(matePromises));case 19:mateBlocks = _context4.sent; | ||
mateChunks = []; | ||
for (_i2 = 0; _i2 < mateBlocks.length; _i2++) { | ||
(_mateChunks = mateChunks).push.apply(_mateChunks, (0, _toConsumableArray3.default)(mateBlocks[_i2])); | ||
(_mateChunks = mateChunks).push.apply(_mateChunks, (0, _toConsumableArray2.default)(mateBlocks[_i2])); | ||
} | ||
// filter out duplicate chunks (the blocks are lists of chunks, blocks are concatenated, then filter dup chunks) | ||
mateChunks = mateChunks.sort().filter(function (item, pos, ary) { | ||
return !pos || item.toString() !== ary[pos - 1].toString(); | ||
}); | ||
mateChunks = mateChunks. | ||
sort(). | ||
filter( | ||
function (item, pos, ary) {return ( | ||
!pos || item.toString() !== ary[pos - 1].toString());}); | ||
mateRecordPromises = []; | ||
mateFeatPromises = []; | ||
mateTotalSize = mateChunks.map(function (s) { | ||
return s.fetchedSize(); | ||
}).reduce(function (a, b) { | ||
return a + b; | ||
}, 0); | ||
if (!(mateTotalSize > this.fetchSizeLimit)) { | ||
_context4.next = 26; | ||
break; | ||
} | ||
mateTotalSize = mateChunks. | ||
map(function (s) {return s.fetchedSize();}). | ||
reduce(function (a, b) {return a + b;}, 0);if (!( | ||
mateTotalSize > this.fetchSizeLimit)) {_context4.next = 28;break;}throw ( | ||
new Error("data size of ".concat( | ||
mateTotalSize.toLocaleString(), " bytes exceeded fetch size limit of ").concat(this.fetchSizeLimit.toLocaleString(), " bytes")));case 28: | ||
throw new Error('data size of ' + mateTotalSize.toLocaleString() + ' bytes exceeded fetch size limit of ' + this.fetchSizeLimit.toLocaleString() + ' bytes'); | ||
case 26: | ||
mateChunks.forEach(function (c) { | ||
var recordPromise = _this.featureCache.get(c.toString()); | ||
if (!recordPromise) { | ||
recordPromise = _this._readChunk(c); | ||
_this.featureCache.set(c.toString(), recordPromise); | ||
} | ||
var recordPromise = _this.featureCache.get( | ||
c.toString(), | ||
c, | ||
opts.signal); | ||
mateRecordPromises.push(recordPromise); | ||
@@ -544,3 +307,6 @@ var featPromise = recordPromise.then(function (feats) { | ||
var feature = feats[_i3]; | ||
if (unmatedPairs[feature.get('name')] && !readIds[feature.get('id')]) { | ||
if ( | ||
unmatedPairs[feature.get('name')] && | ||
!readIds[feature.get('id')]) | ||
{ | ||
mateRecs.push(feature); | ||
@@ -552,60 +318,30 @@ } | ||
mateFeatPromises.push(featPromise); | ||
}); | ||
_context4.next = 29; | ||
return _promise2.default.all(mateFeatPromises); | ||
});_context4.next = 31;return ( | ||
_promise.default.all(mateFeatPromises));case 31:newMateFeats = _context4.sent; | ||
if (newMateFeats.length) { | ||
newMates = newMateFeats.reduce(function (result, current) {return ( | ||
result.concat(current));}); | ||
case 29: | ||
newMateFeats = _context4.sent; | ||
if (newMateFeats.length) { | ||
newMates = newMateFeats.reduce(function (result, current) { | ||
return result.concat(current); | ||
}); | ||
// console.log(chrId, min, max, newMates.map(m => m.get('name')).sort()) | ||
ret = ret.concat(newMates); | ||
} | ||
}case 33:return _context4.abrupt("return", | ||
case 31: | ||
return _context4.abrupt('return', ret); | ||
ret);case 34:case "end":return _context4.stop();}}}, _callee4, this);}));function _fetchChunkFeatures(_x8, _x9, _x10, _x11) {return _fetchChunkFeatures2.apply(this, arguments);}return _fetchChunkFeatures;}() }, { key: "_readChunk", value: function () {var _readChunk2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee5( | ||
case 32: | ||
case 'end': | ||
return _context4.stop(); | ||
} | ||
} | ||
}, _callee4, this); | ||
})); | ||
function _fetchChunkFeatures(_x7, _x8, _x9, _x10) { | ||
return _ref6.apply(this, arguments); | ||
} | ||
return _fetchChunkFeatures; | ||
}() | ||
}, { | ||
key: '_readChunk', | ||
value: function () { | ||
var _ref10 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee5(chunk) { | ||
var bufsize, buf, bytesRead, data; | ||
return _regenerator2.default.wrap(function _callee5$(_context5) { | ||
while (1) { | ||
switch (_context5.prev = _context5.next) { | ||
case 0: | ||
chunk, abortSignal) {var bufsize, buf, bytesRead, data;return _regenerator.default.wrap(function _callee5$(_context5) {while (1) {switch (_context5.prev = _context5.next) {case 0: | ||
bufsize = chunk.fetchedSize(); | ||
buf = Buffer.alloc(bufsize + blockLen); | ||
_context5.next = 4; | ||
return this.bam.read(buf, 0, bufsize + blockLen, chunk.minv.blockPosition); | ||
buf = Buffer.alloc(bufsize + blockLen);_context5.next = 4;return ( | ||
this.bam.read( | ||
buf, | ||
0, | ||
bufsize + blockLen, | ||
chunk.minv.blockPosition, | ||
abortSignal));case 4:bytesRead = _context5.sent; | ||
case 4: | ||
bytesRead = _context5.sent; | ||
checkAbortSignal(abortSignal);if ( | ||
if (bytesRead) { | ||
_context5.next = 7; | ||
break; | ||
} | ||
bytesRead) {_context5.next = 8;break;}return _context5.abrupt("return", | ||
[]);case 8: | ||
return _context5.abrupt('return', []); | ||
case 7: | ||
if (bytesRead < bufsize) { | ||
@@ -615,28 +351,10 @@ buf = buf.slice(0, bytesRead); | ||
buf = buf.slice(0, bufsize); | ||
} | ||
}_context5.next = 11;return ( | ||
_context5.next = 10; | ||
return unzip(buf); | ||
unzip(buf));case 11:data = _context5.sent; | ||
checkAbortSignal(abortSignal);return _context5.abrupt("return", | ||
this.readBamFeatures(data, chunk.minv.dataPosition));case 14:case "end":return _context5.stop();}}}, _callee5, this);}));function _readChunk(_x12, _x13) {return _readChunk2.apply(this, arguments);}return _readChunk;}() }, { key: "readBamFeatures", value: function readBamFeatures( | ||
case 10: | ||
data = _context5.sent; | ||
return _context5.abrupt('return', this.readBamFeatures(data, chunk.minv.dataPosition)); | ||
case 12: | ||
case 'end': | ||
return _context5.stop(); | ||
} | ||
} | ||
}, _callee5, this); | ||
})); | ||
function _readChunk(_x12) { | ||
return _ref10.apply(this, arguments); | ||
} | ||
return _readChunk; | ||
}() | ||
}, { | ||
key: 'readBamFeatures', | ||
value: function readBamFeatures(ba, blockStart) { | ||
ba, blockStart) { | ||
var sink = []; | ||
@@ -651,4 +369,4 @@ | ||
var feature = new BAMFeature({ | ||
bytes: { byteArray: ba, start: blockStart, end: blockEnd } | ||
}); | ||
bytes: { byteArray: ba, start: blockStart, end: blockEnd } }); | ||
sink.push(feature); | ||
@@ -660,12 +378,9 @@ } | ||
return sink; | ||
} | ||
}, { | ||
key: 'hasRefSeq', | ||
value: function hasRefSeq(seqId) { | ||
} }, { key: "hasRefSeq", value: function hasRefSeq( | ||
seqId) { | ||
return this.index.hasRefSeq(seqId); | ||
} | ||
}]); | ||
return BamFile; | ||
}(); | ||
} }]);return BamFile;}(); | ||
module.exports = BamFile; |
@@ -1,24 +0,10 @@ | ||
"use strict"; | ||
var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck"); | ||
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); | ||
var _createClass2 = require("babel-runtime/helpers/createClass"); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
// little class representing a chunk in the index | ||
var Chunk = function () { | ||
"use strict";var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass")); // little class representing a chunk in the index | ||
var Chunk = /*#__PURE__*/function () { | ||
/** | ||
* @param {VirtualOffset} minv | ||
* @param {VirtualOffset} maxv | ||
* @param {number} bin | ||
* @param {number} [fetchedSize] | ||
*/ | ||
function Chunk(minv, maxv, bin, fetchedSize) { | ||
(0, _classCallCheck3.default)(this, Chunk); | ||
* @param {VirtualOffset} minv | ||
* @param {VirtualOffset} maxv | ||
* @param {number} bin | ||
* @param {number} [fetchedSize] | ||
*/ | ||
function Chunk(minv, maxv, bin, fetchedSize) {(0, _classCallCheck2.default)(this, Chunk); | ||
this.minv = minv; | ||
@@ -28,29 +14,28 @@ this.maxv = maxv; | ||
this._fetchedSize = fetchedSize; | ||
} | ||
}(0, _createClass2.default)(Chunk, [{ key: "toUniqueString", value: function toUniqueString() | ||
(0, _createClass3.default)(Chunk, [{ | ||
key: "toUniqueString", | ||
value: function toUniqueString() { | ||
return this.minv + ".." + this.maxv + " (bin " + this.bin + ", fetchedSize " + this.fetchedSize() + ")"; | ||
} | ||
}, { | ||
key: "toString", | ||
value: function toString() { | ||
{ | ||
return "".concat(this.minv, "..").concat(this.maxv, " (bin ").concat( | ||
this.bin, ", fetchedSize ").concat( | ||
this.fetchedSize(), ")"); | ||
} }, { key: "toString", value: function toString() | ||
{ | ||
return this.toUniqueString(); | ||
} | ||
}, { | ||
key: "compareTo", | ||
value: function compareTo(b) { | ||
return this.minv.compareTo(b.minv) || this.maxv.compareTo(b.maxv) || this.bin - b.bin; | ||
} | ||
}, { | ||
key: "fetchedSize", | ||
value: function fetchedSize() { | ||
} }, { key: "compareTo", value: function compareTo( | ||
b) { | ||
return ( | ||
this.minv.compareTo(b.minv) || | ||
this.maxv.compareTo(b.maxv) || | ||
this.bin - b.bin); | ||
} }, { key: "fetchedSize", value: function fetchedSize() | ||
{ | ||
if (this._fetchedSize !== undefined) return this._fetchedSize; | ||
return this.maxv.blockPosition + (1 << 16) - this.minv.blockPosition; | ||
} | ||
}]); | ||
return Chunk; | ||
}(); | ||
} }]);return Chunk;}(); | ||
module.exports = Chunk; |
@@ -1,4 +0,2 @@ | ||
"use strict"; | ||
module.exports = { | ||
"use strict";module.exports = { | ||
// the read is paired in sequencing, no matter whether it is mapped in a pair | ||
@@ -27,3 +25,2 @@ BAM_FPAIRED: 1, | ||
// supplementary alignment | ||
BAM_FSUPPLEMENTARY: 2048 | ||
}; | ||
BAM_FSUPPLEMENTARY: 2048 }; |
489
dist/csi.js
@@ -1,35 +0,9 @@ | ||
'use strict'; | ||
"use strict";var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));var Long = require('long');var _require = | ||
require('@gmod/bgzf-filehandle'),unzip = _require.unzip; | ||
var _assign = require('babel-runtime/core-js/object/assign'); | ||
var _assign2 = _interopRequireDefault(_assign); | ||
var _regenerator = require('babel-runtime/regenerator'); | ||
var _regenerator2 = _interopRequireDefault(_regenerator); | ||
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); | ||
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); | ||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | ||
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var Long = require('long'); | ||
var _require = require('@gmod/bgzf-filehandle'), | ||
unzip = _require.unzip; | ||
var VirtualOffset = require('./virtualOffset'); | ||
var Chunk = require('./chunk'); | ||
var IndexFile = require('./indexFile');var _require2 = | ||
var _require2 = require('./util'), | ||
longToNumber = _require2.longToNumber; | ||
require('./util'),longToNumber = _require2.longToNumber,abortBreakPoint = _require2.abortBreakPoint; | ||
@@ -44,93 +18,16 @@ var CSI1_MAGIC = 21582659; // CSI\1 | ||
return Math.floor(num / Math.pow(2, bits)); | ||
} | ||
}var | ||
var CSI = function () { | ||
/** | ||
* @param {filehandle} filehandle | ||
* @param {function} [renameRefSeqs] | ||
*/ | ||
function CSI(_ref) { | ||
var filehandle = _ref.filehandle, | ||
_ref$renameRefSeqs = _ref.renameRefSeqs, | ||
renameRefSeqs = _ref$renameRefSeqs === undefined ? function (n) { | ||
return n; | ||
} : _ref$renameRefSeqs; | ||
(0, _classCallCheck3.default)(this, CSI); | ||
CSI = /*#__PURE__*/function (_IndexFile) {(0, _inherits2.default)(CSI, _IndexFile);function CSI() {(0, _classCallCheck2.default)(this, CSI);return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(CSI).apply(this, arguments));}(0, _createClass2.default)(CSI, [{ key: "lineCount", value: function () {var _lineCount = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee( | ||
refId) {var indexData, idx, stats;return _regenerator.default.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:_context.next = 2;return ( | ||
this.parse());case 2:indexData = _context.sent;if ( | ||
indexData) {_context.next = 5;break;}return _context.abrupt("return", -1);case 5: | ||
idx = indexData.indices[refId];if ( | ||
idx) {_context.next = 8;break;}return _context.abrupt("return", -1);case 8: | ||
stats = indexData.indices[refId].stats;if (! | ||
stats) {_context.next = 11;break;}return _context.abrupt("return", stats.lineCount);case 11:return _context.abrupt("return", | ||
-1);case 12:case "end":return _context.stop();}}}, _callee, this);}));function lineCount(_x) {return _lineCount.apply(this, arguments);}return lineCount;}() }, { key: "parseAuxData", value: function parseAuxData( | ||
this.filehandle = filehandle; | ||
this.renameRefSeq = renameRefSeqs; | ||
} | ||
(0, _createClass3.default)(CSI, [{ | ||
key: '_findFirstData', | ||
value: function _findFirstData(data, virtualOffset) { | ||
var currentFdl = data.firstDataLine; | ||
if (currentFdl) { | ||
data.firstDataLine = currentFdl.compareTo(virtualOffset) > 0 ? virtualOffset : currentFdl; | ||
} else { | ||
data.firstDataLine = virtualOffset; | ||
} | ||
} | ||
}, { | ||
key: 'lineCount', | ||
value: function () { | ||
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(refId) { | ||
var indexData, idx, stats; | ||
return _regenerator2.default.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.next = 2; | ||
return this.parse(); | ||
case 2: | ||
indexData = _context.sent; | ||
if (indexData) { | ||
_context.next = 5; | ||
break; | ||
} | ||
return _context.abrupt('return', -1); | ||
case 5: | ||
idx = indexData.indices[refId]; | ||
if (idx) { | ||
_context.next = 8; | ||
break; | ||
} | ||
return _context.abrupt('return', -1); | ||
case 8: | ||
stats = indexData.indices[refId].stats; | ||
if (!stats) { | ||
_context.next = 11; | ||
break; | ||
} | ||
return _context.abrupt('return', stats.lineCount); | ||
case 11: | ||
return _context.abrupt('return', -1); | ||
case 12: | ||
case 'end': | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, this); | ||
})); | ||
function lineCount(_x) { | ||
return _ref2.apply(this, arguments); | ||
} | ||
return lineCount; | ||
}() | ||
}, { | ||
key: 'parseAuxData', | ||
value: function parseAuxData(bytes, offset, auxLength) { | ||
bytes, offset, auxLength) { | ||
if (auxLength < 30) return {}; | ||
@@ -140,10 +37,12 @@ | ||
data.formatFlags = bytes.readInt32LE(offset); | ||
data.coordinateType = data.formatFlags & 0x10000 ? 'zero-based-half-open' : '1-based-closed'; | ||
data.coordinateType = | ||
data.formatFlags & 0x10000 ? 'zero-based-half-open' : '1-based-closed'; | ||
data.format = { 0: 'generic', 1: 'SAM', 2: 'VCF' }[data.formatFlags & 0xf]; | ||
if (!data.format) throw new Error('invalid Tabix preset format flags ' + data.formatFlags); | ||
if (!data.format) | ||
throw new Error("invalid Tabix preset format flags ".concat(data.formatFlags)); | ||
data.columnNumbers = { | ||
ref: bytes.readInt32LE(offset + 4), | ||
start: bytes.readInt32LE(offset + 8), | ||
end: bytes.readInt32LE(offset + 12) | ||
}; | ||
end: bytes.readInt32LE(offset + 12) }; | ||
data.metaValue = bytes.readInt32LE(offset + 16); | ||
@@ -154,8 +53,12 @@ data.metaChar = data.metaValue ? String.fromCharCode(data.metaValue) : ''; | ||
(0, _assign2.default)(data, this._parseNameBytes(bytes.slice(offset + 28, offset + 28 + nameSectionLength))); | ||
(0, _assign.default)( | ||
data, | ||
this._parseNameBytes( | ||
bytes.slice(offset + 28, offset + 28 + nameSectionLength))); | ||
return data; | ||
} | ||
}, { | ||
key: '_parseNameBytes', | ||
value: function _parseNameBytes(namesBytes) { | ||
} }, { key: "_parseNameBytes", value: function _parseNameBytes( | ||
namesBytes) { | ||
var currRefId = 0; | ||
@@ -180,51 +83,17 @@ var currNameStart = 0; | ||
// memoize | ||
// fetch and parse the index | ||
}, { key: "_parse", value: function () {var _parse2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(abortSignal) {var data, bytes, auxLength, currOffset, i, binCount, binIndex, stats, j, bin, loffset, chunkCount, chunks, k, u, v;return _regenerator.default.wrap(function _callee2$(_context2) {while (1) {switch (_context2.prev = _context2.next) {case 0: | ||
data = { csi: true, maxBlockSize: 1 << 16 };_context2.t0 = | ||
unzip;_context2.next = 4;return this.filehandle.readFile(abortSignal);case 4:_context2.t1 = _context2.sent;_context2.next = 7;return (0, _context2.t0)(_context2.t1);case 7:bytes = _context2.sent;if (!( | ||
}, { | ||
key: 'parse', | ||
value: function () { | ||
var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() { | ||
var data, bytes, auxLength, currOffset, i, binCount, binIndex, stats, j, bin, loffset, chunkCount, chunks, k, u, v; | ||
return _regenerator2.default.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
data = { csi: true, maxBlockSize: 1 << 16 }; | ||
_context2.t0 = unzip; | ||
_context2.next = 4; | ||
return this.filehandle.readFile(); | ||
case 4: | ||
_context2.t1 = _context2.sent; | ||
_context2.next = 7; | ||
return (0, _context2.t0)(_context2.t1); | ||
bytes.readUInt32LE(0) === CSI1_MAGIC)) {_context2.next = 12;break;} | ||
data.csiVersion = 1;_context2.next = 17;break;case 12:if (!( | ||
bytes.readUInt32LE(0) === CSI2_MAGIC)) {_context2.next = 16;break;} | ||
data.csiVersion = 2;_context2.next = 17;break;case 16:throw ( | ||
case 7: | ||
bytes = _context2.sent; | ||
new Error('Not a CSI file'));case 17: | ||
if (!(bytes.readUInt32LE(0) === CSI1_MAGIC)) { | ||
_context2.next = 12; | ||
break; | ||
} | ||
data.csiVersion = 1; | ||
_context2.next = 17; | ||
break; | ||
case 12: | ||
if (!(bytes.readUInt32LE(0) === CSI2_MAGIC)) { | ||
_context2.next = 16; | ||
break; | ||
} | ||
data.csiVersion = 2; | ||
_context2.next = 17; | ||
break; | ||
case 16: | ||
throw new Error('Not a CSI file'); | ||
case 17: | ||
this.minShift = bytes.readInt32LE(4); | ||
@@ -234,5 +103,4 @@ this.depth = bytes.readInt32LE(8); | ||
auxLength = bytes.readInt32LE(12); | ||
if (auxLength) { | ||
(0, _assign2.default)(data, this.parseAuxData(bytes, 16, auxLength)); | ||
(0, _assign.default)(data, this.parseAuxData(bytes, 16, auxLength)); | ||
} | ||
@@ -244,62 +112,40 @@ data.refCount = bytes.readInt32LE(16 + auxLength); | ||
currOffset = 16 + auxLength + 4; | ||
for (i = 0; i < data.refCount; i += 1) { | ||
// the binning index | ||
binCount = bytes.readInt32LE(currOffset); | ||
currOffset += 4; | ||
binIndex = {}; | ||
stats = void 0; // < provided by parsing a pseudo-bin, if present | ||
for (j = 0; j < binCount; j += 1) { | ||
bin = bytes.readUInt32LE(currOffset); | ||
if (bin > this.maxBinNumber) { | ||
// this is a fake bin that actually has stats information | ||
// about the reference sequence in it | ||
stats = this.parsePseudoBin(bytes, currOffset + 4); | ||
currOffset += 4 + 8 + 4 + 16 + 16; | ||
} else { | ||
loffset = VirtualOffset.fromBytes(bytes, currOffset + 4); | ||
this._findFirstData(data, loffset); | ||
chunkCount = bytes.readInt32LE(currOffset + 12); | ||
i = 0;case 26:if (!(i < data.refCount)) {_context2.next = 38;break;}_context2.next = 29;return ( | ||
abortBreakPoint(abortSignal));case 29: | ||
// the binning index | ||
binCount = bytes.readInt32LE(currOffset); | ||
currOffset += 4; | ||
binIndex = {}; | ||
stats = void 0; // < provided by parsing a pseudo-bin, if present | ||
for (j = 0; j < binCount; j += 1) { | ||
bin = bytes.readUInt32LE(currOffset); | ||
if (bin > this.maxBinNumber) { | ||
// this is a fake bin that actually has stats information | ||
// about the reference sequence in it | ||
stats = this.parsePseudoBin(bytes, currOffset + 4); | ||
currOffset += 4 + 8 + 4 + 16 + 16; | ||
} else { | ||
loffset = VirtualOffset.fromBytes(bytes, currOffset + 4); | ||
this._findFirstData(data, loffset); | ||
chunkCount = bytes.readInt32LE(currOffset + 12); | ||
currOffset += 16; | ||
chunks = new Array(chunkCount); | ||
for (k = 0; k < chunkCount; k += 1) { | ||
u = VirtualOffset.fromBytes(bytes, currOffset); | ||
v = VirtualOffset.fromBytes(bytes, currOffset + 8); | ||
currOffset += 16; | ||
chunks = new Array(chunkCount); | ||
for (k = 0; k < chunkCount; k += 1) { | ||
u = VirtualOffset.fromBytes(bytes, currOffset); | ||
v = VirtualOffset.fromBytes(bytes, currOffset + 8); | ||
currOffset += 16; | ||
// this._findFirstData(data, u) | ||
chunks[k] = new Chunk(u, v, bin); | ||
} | ||
binIndex[bin] = chunks; | ||
// this._findFirstData(data, u) | ||
chunks[k] = new Chunk(u, v, bin); | ||
} | ||
binIndex[bin] = chunks; | ||
} | ||
data.indices[i] = { binIndex: binIndex, stats: stats }; | ||
} | ||
return _context2.abrupt('return', data); | ||
data.indices[i] = { binIndex: binIndex, stats: stats };case 35:i += 1;_context2.next = 26;break;case 38:return _context2.abrupt("return", | ||
case 27: | ||
case 'end': | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2, this); | ||
})); | ||
function parse() { | ||
return _ref3.apply(this, arguments); | ||
} | ||
data);case 39:case "end":return _context2.stop();}}}, _callee2, this);}));function _parse(_x2) {return _parse2.apply(this, arguments);}return _parse;}() }, { key: "parsePseudoBin", value: function parsePseudoBin( | ||
return parse; | ||
}() | ||
}, { | ||
key: 'parsePseudoBin', | ||
value: function parsePseudoBin(bytes, offset) { | ||
bytes, offset) { | ||
// const one = Long.fromBytesLE(bytes.slice(offset + 4, offset + 12), true) | ||
@@ -310,83 +156,47 @@ // const two = Long.fromBytesLE(bytes.slice(offset + 12, offset + 20), true) | ||
// ) | ||
var lineCount = longToNumber(Long.fromBytesLE(bytes.slice(offset + 28, offset + 36), true)); | ||
var lineCount = longToNumber( | ||
Long.fromBytesLE(bytes.slice(offset + 28, offset + 36), true)); | ||
return { lineCount: lineCount }; | ||
} | ||
}, { | ||
key: 'blocksForRange', | ||
value: function () { | ||
var _ref4 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3(refId, beg, end) { | ||
var indexData, indexes, binIndex, bins, l, numOffsets, i, off, _i, chunks, j, _i2, _i3, _i4; | ||
} }, { key: "blocksForRange", value: function () {var _blocksForRange = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3( | ||
return _regenerator2.default.wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (beg < 0) beg = 0; | ||
refId, beg, end, opts) {var indexData, indexes, binIndex, bins, l, numOffsets, i, off, _i, chunks, j, _i2, _i3, _i4;return _regenerator.default.wrap(function _callee3$(_context3) {while (1) {switch (_context3.prev = _context3.next) {case 0: | ||
if (beg < 0) beg = 0;_context3.next = 3;return ( | ||
_context3.next = 3; | ||
return this.parse(); | ||
this.parse(opts.signal));case 3:indexData = _context3.sent;if ( | ||
indexData) {_context3.next = 6;break;}return _context3.abrupt("return", []);case 6: | ||
indexes = indexData.indices[refId];if ( | ||
indexes) {_context3.next = 9;break;}return _context3.abrupt("return", []);case 9: | ||
case 3: | ||
indexData = _context3.sent; | ||
binIndex = indexes.binIndex; | ||
if (indexData) { | ||
_context3.next = 6; | ||
break; | ||
} | ||
bins = this.reg2bins(beg, end); | ||
return _context3.abrupt('return', []); | ||
case 6: | ||
indexes = indexData.indices[refId]; | ||
if (indexes) { | ||
_context3.next = 9; | ||
break; | ||
} | ||
return _context3.abrupt('return', []); | ||
case 9: | ||
binIndex = indexes.binIndex; | ||
bins = this.reg2bins(beg, end); | ||
l = void 0; | ||
numOffsets = 0; | ||
for (i = 0; i < bins.length; i += 1) { | ||
if (binIndex[bins[i]]) numOffsets += binIndex[bins[i]].length; | ||
} | ||
}if (!( | ||
if (!(numOffsets === 0)) { | ||
_context3.next = 16; | ||
break; | ||
} | ||
numOffsets === 0)) {_context3.next = 15;break;}return _context3.abrupt("return", []);case 15: | ||
return _context3.abrupt('return', []); | ||
case 16: | ||
off = []; | ||
numOffsets = 0; | ||
for (_i = 0; _i < bins.length; _i += 1) { | ||
chunks = binIndex[bins[_i]]; | ||
if (chunks) | ||
for (j = 0; j < chunks.length; j += 1) { | ||
off[numOffsets] = new Chunk( | ||
chunks[j].minv, | ||
chunks[j].maxv, | ||
chunks[j].bin); | ||
if (chunks) for (j = 0; j < chunks.length; j += 1) { | ||
off[numOffsets] = new Chunk(chunks[j].minv, chunks[j].maxv, chunks[j].bin); | ||
numOffsets += 1; | ||
} | ||
} | ||
}if ( | ||
if (off.length) { | ||
_context3.next = 21; | ||
break; | ||
} | ||
off.length) {_context3.next = 20;break;}return _context3.abrupt("return", []);case 20: | ||
return _context3.abrupt('return', []); | ||
off = off.sort(function (a, b) {return a.compareTo(b);}); | ||
case 21: | ||
off = off.sort(function (a, b) { | ||
return a.compareTo(b); | ||
}); | ||
// resolve completely contained adjacent blocks | ||
@@ -405,7 +215,10 @@ l = 0; | ||
for (_i3 = 1; _i3 < numOffsets; _i3 += 1) { | ||
if (off[_i3 - 1].maxv.compareTo(off[_i3].minv) >= 0) off[_i3 - 1].maxv = off[_i3].minv; | ||
} // merge adjacent blocks | ||
if (off[_i3 - 1].maxv.compareTo(off[_i3].minv) >= 0) | ||
off[_i3 - 1].maxv = off[_i3].minv;} | ||
// merge adjacent blocks | ||
l = 0; | ||
for (_i4 = 1; _i4 < numOffsets; _i4 += 1) { | ||
if (off[l].maxv.blockPosition === off[_i4].minv.blockPosition) off[l].maxv = off[_i4].maxv;else { | ||
if (off[l].maxv.blockPosition === off[_i4].minv.blockPosition) | ||
off[l].maxv = off[_i4].maxv;else | ||
{ | ||
l += 1; | ||
@@ -416,74 +229,12 @@ off[l].minv = off[_i4].minv; | ||
} | ||
numOffsets = l + 1; | ||
numOffsets = l + 1;return _context3.abrupt("return", | ||
return _context3.abrupt('return', off.slice(0, numOffsets)); | ||
off.slice(0, numOffsets));case 29:case "end":return _context3.stop();}}}, _callee3, this);}));function blocksForRange(_x3, _x4, _x5, _x6) {return _blocksForRange.apply(this, arguments);}return blocksForRange;}() | ||
case 30: | ||
case 'end': | ||
return _context3.stop(); | ||
} | ||
} | ||
}, _callee3, this); | ||
})); | ||
function blocksForRange(_x2, _x3, _x4) { | ||
return _ref4.apply(this, arguments); | ||
} | ||
return blocksForRange; | ||
}() | ||
/** | ||
* @param {number} seqId | ||
* @returns {Promise} true if the index contains entries for | ||
* the given reference sequence ID, false otherwise | ||
*/ | ||
}, { | ||
key: 'hasRefSeq', | ||
value: function () { | ||
var _ref5 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee4(seqId) { | ||
return _regenerator2.default.wrap(function _callee4$(_context4) { | ||
while (1) { | ||
switch (_context4.prev = _context4.next) { | ||
case 0: | ||
_context4.next = 2; | ||
return this.parse(); | ||
case 2: | ||
_context4.t1 = seqId; | ||
_context4.t0 = _context4.sent.indices[_context4.t1]; | ||
if (_context4.t0) { | ||
_context4.next = 6; | ||
break; | ||
} | ||
_context4.t0 = {}; | ||
case 6: | ||
return _context4.abrupt('return', !!_context4.t0.binIndex); | ||
case 7: | ||
case 'end': | ||
return _context4.stop(); | ||
} | ||
} | ||
}, _callee4, this); | ||
})); | ||
function hasRefSeq(_x5) { | ||
return _ref5.apply(this, arguments); | ||
} | ||
return hasRefSeq; | ||
}() | ||
/** | ||
* calculate the list of bins that may overlap with region [beg,end) (zero-based half-open) | ||
* @returns {Array[number]} | ||
*/ | ||
}, { | ||
key: 'reg2bins', | ||
value: function reg2bins(beg, end) { | ||
* calculate the list of bins that may overlap with region [beg,end) (zero-based half-open) | ||
* @returns {Array[number]} | ||
*/ }, { key: "reg2bins", value: function reg2bins( | ||
beg, end) { | ||
beg -= 1; // < convert to 1-based closed | ||
@@ -500,28 +251,16 @@ if (beg < 1) beg = 1; | ||
var e = t + rshift(end, s); | ||
if (e - b + bins.length > this.maxBinNumber) throw new Error('query ' + beg + '-' + end + ' is too large for current binning scheme (shift ' + this.minShift + ', depth ' + this.depth + '), try a smaller query or a coarser index binning scheme'); | ||
for (var i = b; i <= e; i += 1) { | ||
bins.push(i); | ||
} | ||
if (e - b + bins.length > this.maxBinNumber) | ||
throw new Error("query ".concat( | ||
beg, "-").concat(end, " is too large for current binning scheme (shift ").concat( | ||
this.minShift, ", depth ").concat( | ||
this.depth, "), try a smaller query or a coarser index binning scheme")); | ||
for (var i = b; i <= e; i += 1) {bins.push(i);} | ||
} | ||
return bins; | ||
} | ||
}]); | ||
return CSI; | ||
}(); | ||
} }]);return CSI;}(IndexFile); | ||
// this is the stupidest possible memoization, ignores arguments. | ||
function tinyMemoize(_class, methodName) { | ||
var method = _class.prototype[methodName]; | ||
if (!method) throw new Error('no method ' + methodName + ' found in class ' + _class.name); | ||
var memoAttrName = '_memo_' + methodName; | ||
_class.prototype[methodName] = function _tinyMemoized() { | ||
if (!(memoAttrName in this)) this[memoAttrName] = method.call(this); | ||
return this[memoAttrName]; | ||
}; | ||
} | ||
// memoize index.parse() | ||
tinyMemoize(CSI, 'parse'); | ||
module.exports = CSI; |
@@ -1,108 +0,24 @@ | ||
"use strict"; | ||
"use strict";var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));var _wrapNativeSuper2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/wrapNativeSuper"));var BamError = /*#__PURE__*/function (_Error) {(0, _inherits2.default)(BamError, _Error);function BamError() {(0, _classCallCheck2.default)(this, BamError);return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BamError).apply(this, arguments));}return BamError;}((0, _wrapNativeSuper2.default)(Error)); | ||
var _getPrototypeOf = require("babel-runtime/core-js/object/get-prototype-of"); | ||
/** Error caused by encountering a part of the BAM spec that has not yet been implemented */var | ||
BamUnimplementedError = /*#__PURE__*/function (_Error2) {(0, _inherits2.default)(BamUnimplementedError, _Error2);function BamUnimplementedError() {(0, _classCallCheck2.default)(this, BamUnimplementedError);return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BamUnimplementedError).apply(this, arguments));}return BamUnimplementedError;}((0, _wrapNativeSuper2.default)(Error)); | ||
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); | ||
/** An error caused by malformed data. */var | ||
BamMalformedError = /*#__PURE__*/function (_BamError) {(0, _inherits2.default)(BamMalformedError, _BamError);function BamMalformedError() {(0, _classCallCheck2.default)(this, BamMalformedError);return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BamMalformedError).apply(this, arguments));}return BamMalformedError;}(BamError); | ||
var _classCallCheck2 = require("babel-runtime/helpers/classCallCheck"); | ||
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); | ||
var _possibleConstructorReturn2 = require("babel-runtime/helpers/possibleConstructorReturn"); | ||
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); | ||
var _inherits2 = require("babel-runtime/helpers/inherits"); | ||
var _inherits3 = _interopRequireDefault(_inherits2); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var BamError = function (_Error) { | ||
(0, _inherits3.default)(BamError, _Error); | ||
function BamError() { | ||
(0, _classCallCheck3.default)(this, BamError); | ||
return (0, _possibleConstructorReturn3.default)(this, (BamError.__proto__ || (0, _getPrototypeOf2.default)(BamError)).apply(this, arguments)); | ||
} | ||
return BamError; | ||
}(Error); | ||
/** Error caused by encountering a part of the BAM spec that has not yet been implemented */ | ||
var BamUnimplementedError = function (_Error2) { | ||
(0, _inherits3.default)(BamUnimplementedError, _Error2); | ||
function BamUnimplementedError() { | ||
(0, _classCallCheck3.default)(this, BamUnimplementedError); | ||
return (0, _possibleConstructorReturn3.default)(this, (BamUnimplementedError.__proto__ || (0, _getPrototypeOf2.default)(BamUnimplementedError)).apply(this, arguments)); | ||
} | ||
return BamUnimplementedError; | ||
}(Error); | ||
/** An error caused by malformed data. */ | ||
var BamMalformedError = function (_BamError) { | ||
(0, _inherits3.default)(BamMalformedError, _BamError); | ||
function BamMalformedError() { | ||
(0, _classCallCheck3.default)(this, BamMalformedError); | ||
return (0, _possibleConstructorReturn3.default)(this, (BamMalformedError.__proto__ || (0, _getPrototypeOf2.default)(BamMalformedError)).apply(this, arguments)); | ||
} | ||
return BamMalformedError; | ||
}(BamError); | ||
/** | ||
* An error caused by attempting to read beyond the end of the defined data. | ||
*/ | ||
* An error caused by attempting to read beyond the end of the defined data. | ||
*/var | ||
BamBufferOverrunError = /*#__PURE__*/function (_BamMalformedError) {(0, _inherits2.default)(BamBufferOverrunError, _BamMalformedError);function BamBufferOverrunError() {(0, _classCallCheck2.default)(this, BamBufferOverrunError);return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BamBufferOverrunError).apply(this, arguments));}return BamBufferOverrunError;}(BamMalformedError); | ||
var BamBufferOverrunError = function (_BamMalformedError) { | ||
(0, _inherits3.default)(BamBufferOverrunError, _BamMalformedError); | ||
function BamBufferOverrunError() { | ||
(0, _classCallCheck3.default)(this, BamBufferOverrunError); | ||
return (0, _possibleConstructorReturn3.default)(this, (BamBufferOverrunError.__proto__ || (0, _getPrototypeOf2.default)(BamBufferOverrunError)).apply(this, arguments)); | ||
} | ||
return BamBufferOverrunError; | ||
}(BamMalformedError); | ||
/** | ||
* An error caused by data being too big, exceeding a size limit. | ||
*/ | ||
* An error caused by data being too big, exceeding a size limit. | ||
*/var | ||
BamSizeLimitError = /*#__PURE__*/function (_BamError2) {(0, _inherits2.default)(BamSizeLimitError, _BamError2);function BamSizeLimitError() {(0, _classCallCheck2.default)(this, BamSizeLimitError);return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BamSizeLimitError).apply(this, arguments));}return BamSizeLimitError;}(BamError); | ||
var BamSizeLimitError = function (_BamError2) { | ||
(0, _inherits3.default)(BamSizeLimitError, _BamError2); | ||
function BamSizeLimitError() { | ||
(0, _classCallCheck3.default)(this, BamSizeLimitError); | ||
return (0, _possibleConstructorReturn3.default)(this, (BamSizeLimitError.__proto__ || (0, _getPrototypeOf2.default)(BamSizeLimitError)).apply(this, arguments)); | ||
} | ||
return BamSizeLimitError; | ||
}(BamError); | ||
/** | ||
* An invalid argument was supplied to a bam-js method or object. | ||
*/ | ||
* An invalid argument was supplied to a bam-js method or object. | ||
*/var | ||
BamArgumentError = /*#__PURE__*/function (_BamError3) {(0, _inherits2.default)(BamArgumentError, _BamError3);function BamArgumentError() {(0, _classCallCheck2.default)(this, BamArgumentError);return (0, _possibleConstructorReturn2.default)(this, (0, _getPrototypeOf2.default)(BamArgumentError).apply(this, arguments));}return BamArgumentError;}(BamError); | ||
var BamArgumentError = function (_BamError3) { | ||
(0, _inherits3.default)(BamArgumentError, _BamError3); | ||
function BamArgumentError() { | ||
(0, _classCallCheck3.default)(this, BamArgumentError); | ||
return (0, _possibleConstructorReturn3.default)(this, (BamArgumentError.__proto__ || (0, _getPrototypeOf2.default)(BamArgumentError)).apply(this, arguments)); | ||
} | ||
return BamArgumentError; | ||
}(BamError); | ||
module.exports = { | ||
@@ -113,3 +29,2 @@ BamBufferOverrunError: BamBufferOverrunError, | ||
BamSizeLimitError: BamSizeLimitError, | ||
BamArgumentError: BamArgumentError | ||
}; | ||
BamArgumentError: BamArgumentError }; |
@@ -1,19 +0,2 @@ | ||
'use strict'; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.BamFile = exports.BAI = undefined; | ||
var _bai = require('./bai'); | ||
var _bai2 = _interopRequireDefault(_bai); | ||
var _bamFile = require('./bamFile'); | ||
var _bamFile2 = _interopRequireDefault(_bamFile); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
exports.BAI = _bai2.default; | ||
exports.BamFile = _bamFile2.default; | ||
"use strict";var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");Object.defineProperty(exports, "__esModule", { value: true });Object.defineProperty(exports, "BAI", { enumerable: true, get: function get() {return _bai.default;} });Object.defineProperty(exports, "BamFile", { enumerable: true, get: function get() {return _bamFile.default;} });var _bai = _interopRequireDefault(require("./bai")); | ||
var _bamFile = _interopRequireDefault(require("./bamFile")); |
@@ -1,31 +0,4 @@ | ||
'use strict'; | ||
"use strict";var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/typeof"));var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));var _require = require('es6-promisify'),promisify = _require.promisify; | ||
var _regenerator = require('babel-runtime/regenerator'); | ||
var _regenerator2 = _interopRequireDefault(_regenerator); | ||
var _typeof2 = require('babel-runtime/helpers/typeof'); | ||
var _typeof3 = _interopRequireDefault(_typeof2); | ||
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator'); | ||
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2); | ||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | ||
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var _require = require('es6-promisify'), | ||
promisify = _require.promisify; | ||
// don't load fs native module if running in webpacked code | ||
var fs = typeof __webpack_require__ !== 'function' ? require('fs') : null; // eslint-disable-line camelcase | ||
@@ -36,141 +9,34 @@ | ||
var fsFStat = fs && promisify(fs.fstat); | ||
var fsReadFile = fs && promisify(fs.readFile); | ||
var fsReadFile = fs && promisify(fs.readFile);var | ||
var LocalFile = function () { | ||
function LocalFile(source) { | ||
(0, _classCallCheck3.default)(this, LocalFile); | ||
LocalFile = /*#__PURE__*/function () { | ||
function LocalFile(source) {(0, _classCallCheck2.default)(this, LocalFile); | ||
this.position = 0; | ||
this.filename = source; | ||
this.fd = fsOpen(this.filename, 'r'); | ||
} | ||
}(0, _createClass2.default)(LocalFile, [{ key: "read", value: function () {var _read = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee( | ||
(0, _createClass3.default)(LocalFile, [{ | ||
key: 'read', | ||
value: function () { | ||
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(buffer) { | ||
var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; | ||
var length = arguments[2]; | ||
var position = arguments[3]; | ||
var readPosition, ret; | ||
return _regenerator2.default.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
buffer) {var offset,length,position,readPosition,ret,_args = arguments;return _regenerator.default.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:offset = _args.length > 1 && _args[1] !== undefined ? _args[1] : 0;length = _args.length > 2 ? _args[2] : undefined;position = _args.length > 3 ? _args[3] : undefined; | ||
readPosition = position; | ||
if (readPosition === null) { | ||
readPosition = this.position; | ||
this.position += length; | ||
} | ||
_context.t0 = fsRead; | ||
_context.next = 5; | ||
return this.fd; | ||
}_context.t0 = | ||
fsRead;_context.next = 8;return this.fd;case 8:_context.t1 = _context.sent;_context.t2 = buffer;_context.t3 = offset;_context.t4 = length;_context.t5 = position;_context.next = 15;return (0, _context.t0)(_context.t1, _context.t2, _context.t3, _context.t4, _context.t5);case 15:ret = _context.sent;if (!( | ||
(0, _typeof2.default)(ret) === 'object')) {_context.next = 18;break;}return _context.abrupt("return", ret.bytesRead);case 18:return _context.abrupt("return", | ||
ret);case 19:case "end":return _context.stop();}}}, _callee, this);}));function read(_x) {return _read.apply(this, arguments);}return read;}() }, { key: "readFile", value: function () {var _readFile = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2() {return _regenerator.default.wrap(function _callee2$(_context2) {while (1) {switch (_context2.prev = _context2.next) {case 0:return _context2.abrupt("return", | ||
case 5: | ||
_context.t1 = _context.sent; | ||
_context.t2 = buffer; | ||
_context.t3 = offset; | ||
_context.t4 = length; | ||
_context.t5 = position; | ||
_context.next = 12; | ||
return (0, _context.t0)(_context.t1, _context.t2, _context.t3, _context.t4, _context.t5); | ||
case 12: | ||
ret = _context.sent; | ||
if (!((typeof ret === 'undefined' ? 'undefined' : (0, _typeof3.default)(ret)) === 'object')) { | ||
_context.next = 15; | ||
break; | ||
} | ||
fsReadFile(this.filename));case 1:case "end":return _context2.stop();}}}, _callee2, this);}));function readFile() {return _readFile.apply(this, arguments);}return readFile;}() }, { key: "stat", value: function () {var _stat = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee3() {return _regenerator.default.wrap(function _callee3$(_context3) {while (1) {switch (_context3.prev = _context3.next) {case 0:if ( | ||
return _context.abrupt('return', ret.bytesRead); | ||
case 15: | ||
return _context.abrupt('return', ret); | ||
case 16: | ||
case 'end': | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, this); | ||
})); | ||
this._stat) {_context3.next = 8;break;}_context3.t0 = | ||
fsFStat;_context3.next = 4;return this.fd;case 4:_context3.t1 = _context3.sent;_context3.next = 7;return (0, _context3.t0)(_context3.t1);case 7:this._stat = _context3.sent;case 8:return _context3.abrupt("return", | ||
function read(_x) { | ||
return _ref.apply(this, arguments); | ||
} | ||
this._stat);case 9:case "end":return _context3.stop();}}}, _callee3, this);}));function stat() {return _stat.apply(this, arguments);}return stat;}() }]);return LocalFile;}(); | ||
return read; | ||
}() | ||
}, { | ||
key: 'readFile', | ||
value: function () { | ||
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() { | ||
return _regenerator2.default.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
return _context2.abrupt('return', fsReadFile(this.filename)); | ||
case 1: | ||
case 'end': | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2, this); | ||
})); | ||
function readFile() { | ||
return _ref2.apply(this, arguments); | ||
} | ||
return readFile; | ||
}() | ||
}, { | ||
key: 'stat', | ||
value: function () { | ||
var _ref3 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee3() { | ||
return _regenerator2.default.wrap(function _callee3$(_context3) { | ||
while (1) { | ||
switch (_context3.prev = _context3.next) { | ||
case 0: | ||
if (this._stat) { | ||
_context3.next = 8; | ||
break; | ||
} | ||
_context3.t0 = fsFStat; | ||
_context3.next = 4; | ||
return this.fd; | ||
case 4: | ||
_context3.t1 = _context3.sent; | ||
_context3.next = 7; | ||
return (0, _context3.t0)(_context3.t1); | ||
case 7: | ||
this._stat = _context3.sent; | ||
case 8: | ||
return _context3.abrupt('return', this._stat); | ||
case 9: | ||
case 'end': | ||
return _context3.stop(); | ||
} | ||
} | ||
}, _callee3, this); | ||
})); | ||
function stat() { | ||
return _ref3.apply(this, arguments); | ||
} | ||
return stat; | ||
}() | ||
}]); | ||
return LocalFile; | ||
}(); | ||
module.exports = LocalFile; |
@@ -1,19 +0,3 @@ | ||
'use strict'; | ||
var _keys = require('babel-runtime/core-js/object/keys'); | ||
var _keys2 = _interopRequireDefault(_keys); | ||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | ||
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
"use strict";var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");var _parseInt2 = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/parse-int"));var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));var crc32 = require('buffer-crc32'); | ||
var Constants = require('./constants'); | ||
var crc32 = require('buffer-crc32'); | ||
@@ -24,9 +8,6 @@ var SEQRET_DECODER = '=ACMGRSVTWYHKDBN'.split(''); | ||
/** | ||
* Class of each BAM record returned by this API. | ||
*/ | ||
var BamRecord = function () { | ||
function BamRecord(args) { | ||
(0, _classCallCheck3.default)(this, BamRecord); | ||
* Class of each BAM record returned by this API. | ||
*/var | ||
BamRecord = /*#__PURE__*/function () { | ||
function BamRecord(args) {(0, _classCallCheck2.default)(this, BamRecord); | ||
this.data = {}; | ||
@@ -36,5 +17,5 @@ this.bytes = { | ||
end: args.bytes.end, | ||
byteArray: args.bytes.byteArray | ||
}; | ||
byteArray: args.bytes.byteArray }; | ||
this._coreParse(); | ||
@@ -44,41 +25,33 @@ } | ||
/** | ||
* parse the core data: ref ID and start | ||
*/ | ||
(0, _createClass3.default)(BamRecord, [{ | ||
key: '_coreParse', | ||
value: function _coreParse() { | ||
var _bytes = this.bytes, | ||
start = _bytes.start, | ||
byteArray = _bytes.byteArray; | ||
* parse the core data: ref ID and start | ||
*/(0, _createClass2.default)(BamRecord, [{ key: "_coreParse", value: function _coreParse() | ||
{var _this$bytes = | ||
this.bytes,start = _this$bytes.start,byteArray = _this$bytes.byteArray; | ||
this._refID = byteArray.readInt32LE(start + 4); | ||
this.data.start = byteArray.readInt32LE(start + 8); | ||
this.flags = (byteArray.readInt32LE(start + 16) & 0xffff0000) >> 16; | ||
} | ||
}, { | ||
key: 'get', | ||
value: function get(field) { | ||
} }, { key: "get", value: function get( | ||
field) { | ||
return this._get(field.toLowerCase()); | ||
} | ||
}, { | ||
key: 'end', | ||
value: function end() { | ||
return this._get('start') + (this._get('length_on_ref') || this._get('seq_length') || undefined); | ||
} | ||
}, { | ||
key: 'seq_id', | ||
value: function seq_id() { | ||
} }, { key: "end", value: function end() | ||
{ | ||
return ( | ||
this._get('start') + ( | ||
this._get('length_on_ref') || this._get('seq_length') || undefined)); | ||
} }, { key: "seq_id", value: function seq_id() | ||
{ | ||
return this._refID; | ||
} | ||
// same as get(), except requires lower-case arguments. used | ||
// internally to save lots of calls to field.toLowerCase() | ||
}, { | ||
key: '_get', | ||
value: function _get(field) { | ||
}, { key: "_get", value: function _get(field) { | ||
if (field in this.data) { | ||
return this.data[field]; | ||
} else if (this[field]) { | ||
} | ||
if (this[field]) { | ||
this.data[field] = this[field](); | ||
@@ -89,20 +62,49 @@ } else { | ||
return this.data[field]; | ||
} | ||
}, { | ||
key: '_tags', | ||
value: function _tags() { | ||
var _this = this; | ||
} }, { key: "_tags", value: function _tags() | ||
{var _this = this; | ||
this._parseAllTags(); | ||
var tags = ['seq', 'seq_reverse_complemented', 'unmapped', 'qc_failed', 'duplicate', 'secondary_alignment', 'supplementary_alignment']; | ||
var tags = [ | ||
'seq', | ||
'seq_reverse_complemented', | ||
'unmapped', | ||
'qc_failed', | ||
'duplicate', | ||
'secondary_alignment', | ||
'supplementary_alignment']; | ||
if (!this.isSegmentUnmapped()) tags.push('start', 'end', 'strand', 'score', 'qual', 'MQ', 'CIGAR', 'length_on_ref', 'template_length'); | ||
if (!this.isSegmentUnmapped()) | ||
tags.push( | ||
'start', | ||
'end', | ||
'strand', | ||
'score', | ||
'qual', | ||
'MQ', | ||
'CIGAR', | ||
'length_on_ref', | ||
'template_length'); | ||
if (this.isPaired()) { | ||
tags.push('multi_segment_all_correctly_aligned', 'multi_segment_next_segment_unmapped', 'multi_segment_next_segment_reversed', 'multi_segment_first', 'multi_segment_last', 'next_segment_position', 'pair_orientation'); | ||
tags.push( | ||
'multi_segment_all_correctly_aligned', | ||
'multi_segment_next_segment_unmapped', | ||
'multi_segment_next_segment_reversed', | ||
'multi_segment_first', | ||
'multi_segment_last', | ||
'next_segment_position', | ||
'pair_orientation'); | ||
} | ||
tags = tags.concat(this._tagList || []); | ||
(0, _keys2.default)(this.data).forEach(function (k) { | ||
if (k[0] !== '_' && k !== 'multi_segment_all_aligned' && k !== 'next_seq_id') tags.push(k); | ||
(0, _keys.default)(this.data).forEach(function (k) { | ||
if ( | ||
k[0] !== '_' && | ||
k !== 'multi_segment_all_aligned' && | ||
k !== 'next_seq_id') | ||
tags.push(k); | ||
}); | ||
@@ -121,21 +123,19 @@ | ||
return tags; | ||
} | ||
}, { | ||
key: 'parent', | ||
value: function parent() { | ||
} }, { key: "parent", value: function parent() | ||
{ | ||
return undefined; | ||
} | ||
}, { | ||
key: 'children', | ||
value: function children() { | ||
} }, { key: "children", value: function children() | ||
{ | ||
return this._get('subfeatures'); | ||
} | ||
}, { | ||
key: 'id', | ||
value: function id() { | ||
return crc32.signed(this.bytes.byteArray.slice(this.bytes.start, this.bytes.end)); | ||
} | ||
}, { | ||
key: 'multi_segment_all_aligned', | ||
value: function multi_segment_all_aligned() { | ||
} }, { key: "id", value: function id() | ||
{ | ||
return crc32.signed( | ||
this.bytes.byteArray.slice(this.bytes.start, this.bytes.end)); | ||
} }, { key: "multi_segment_all_aligned", value: function multi_segment_all_aligned() | ||
{ | ||
return this._get('multi_segment_all_correctly_aligned'); | ||
@@ -147,24 +147,23 @@ } | ||
* Mapping quality score. | ||
*/ | ||
}, { | ||
key: 'mq', | ||
value: function mq() { | ||
*/ }, { key: "mq", value: function mq() | ||
{ | ||
var mq = (this._get('_bin_mq_nl') & 0xff00) >> 8; | ||
return mq === 255 ? undefined : mq; | ||
} | ||
}, { | ||
key: 'score', | ||
value: function score() { | ||
} }, { key: "score", value: function score() | ||
{ | ||
return this._get('mq'); | ||
} | ||
}, { | ||
key: 'qual', | ||
value: function qual() { | ||
} }, { key: "qual", value: function qual() | ||
{ | ||
if (this.isSegmentUnmapped()) return undefined; | ||
var qseq = []; | ||
var byteArray = this.bytes.byteArray; | ||
var p = this.bytes.start + 36 + this._get('_l_read_name') + this._get('_n_cigar_op') * 4 + this._get('_seq_bytes'); | ||
var qseq = [];var | ||
byteArray = this.bytes.byteArray; | ||
var p = | ||
this.bytes.start + | ||
36 + | ||
this._get('_l_read_name') + | ||
this._get('_n_cigar_op') * 4 + | ||
this._get('_seq_bytes'); | ||
var lseq = this._get('seq_length'); | ||
@@ -175,34 +174,31 @@ for (var j = 0; j < lseq; ++j) { | ||
return qseq.join(' '); | ||
} | ||
}, { | ||
key: 'strand', | ||
value: function strand() { | ||
} }, { key: "strand", value: function strand() | ||
{ | ||
return this.isReverseComplemented() ? -1 : 1; | ||
} | ||
}, { | ||
key: 'multi_segment_next_segment_strand', | ||
value: function multi_segment_next_segment_strand() { | ||
} }, { key: "multi_segment_next_segment_strand", value: function multi_segment_next_segment_strand() | ||
{ | ||
if (this.isMateUnmapped()) return undefined; | ||
return this.isMateReverseComplemented() ? -1 : 1; | ||
} | ||
}, { | ||
key: 'name', | ||
value: function name() { | ||
} }, { key: "name", value: function name() | ||
{ | ||
return this._get('_read_name'); | ||
} | ||
}, { | ||
key: '_read_name', | ||
value: function _read_name() { | ||
} }, { key: "_read_name", value: function _read_name() | ||
{ | ||
var nl = this._get('_l_read_name'); | ||
return this.bytes.byteArray.toString('ascii', this.bytes.start + 36, this.bytes.start + 36 + nl - 1); | ||
return this.bytes.byteArray.toString( | ||
'ascii', | ||
this.bytes.start + 36, | ||
this.bytes.start + 36 + nl - 1); | ||
} | ||
/** | ||
* Get the value of a tag, parsing the tags as far as necessary. | ||
* Only called if we have not already parsed that field. | ||
*/ | ||
}, { | ||
key: '_parseTag', | ||
value: function _parseTag(tagName) { | ||
* Get the value of a tag, parsing the tags as far as necessary. | ||
* Only called if we have not already parsed that field. | ||
*/ }, { key: "_parseTag", value: function _parseTag( | ||
tagName) { | ||
// if all of the tags have been parsed and we're still being | ||
@@ -213,9 +209,15 @@ // called, we already know that we have no such tag, because | ||
this._tagList = this._tagList || []; | ||
var byteArray = this.bytes.byteArray; | ||
this._tagList = this._tagList || [];var | ||
byteArray = this.bytes.byteArray; | ||
var p = | ||
this._tagOffset || | ||
this.bytes.start + | ||
36 + | ||
this._get('_l_read_name') + | ||
this._get('_n_cigar_op') * 4 + | ||
this._get('_seq_bytes') + | ||
this._get('seq_length'); | ||
var p = this._tagOffset || this.bytes.start + 36 + this._get('_l_read_name') + this._get('_n_cigar_op') * 4 + this._get('_seq_bytes') + this._get('seq_length'); | ||
var blockEnd = this.bytes.end; | ||
var lcTag = void 0; | ||
var lcTag; | ||
while (p < blockEnd && lcTag !== tagName) { | ||
@@ -261,4 +263,3 @@ var tag = String.fromCharCode(byteArray[p], byteArray[p + 1]); | ||
break; | ||
case 'b': | ||
{ | ||
case 'b':{ | ||
value = ''; | ||
@@ -306,3 +307,3 @@ var _cc = byteArray[p++]; | ||
default: | ||
console.warn('Unknown BAM tag type \'' + type + '\', tags may be incomplete'); | ||
console.warn("Unknown BAM tag type '".concat(type, "', tags may be incomplete")); | ||
value = undefined; | ||
@@ -321,121 +322,80 @@ p = blockEnd; // stop parsing tags | ||
return undefined; | ||
} | ||
}, { | ||
key: '_parseAllTags', | ||
value: function _parseAllTags() { | ||
} }, { key: "_parseAllTags", value: function _parseAllTags() | ||
{ | ||
this._parseTag(); | ||
} }, { key: "_parseCigar", value: function _parseCigar( | ||
cigar) { | ||
return cigar. | ||
match(/\d+\D/g). | ||
map(function (op) {return [op.match(/\D/)[0].toUpperCase(), (0, _parseInt2.default)(op, 10)];}); | ||
} | ||
}, { | ||
key: '_parseCigar', | ||
value: function _parseCigar(cigar) { | ||
return cigar.match(/\d+\D/g).map(function (op) { | ||
return [op.match(/\D/)[0].toUpperCase(), parseInt(op, 10)]; | ||
}); | ||
} | ||
/** | ||
* @returns {boolean} true if the read is paired, regardless of whether both segments are mapped | ||
*/ | ||
}, { | ||
key: 'isPaired', | ||
value: function isPaired() { | ||
* @returns {boolean} true if the read is paired, regardless of whether both segments are mapped | ||
*/ }, { key: "isPaired", value: function isPaired() | ||
{ | ||
return !!(this.flags & Constants.BAM_FPAIRED); | ||
} | ||
/** @returns {boolean} true if the read is paired, and both segments are mapped */ | ||
}, { | ||
key: 'isProperlyPaired', | ||
value: function isProperlyPaired() { | ||
/** @returns {boolean} true if the read is paired, and both segments are mapped */ }, { key: "isProperlyPaired", value: function isProperlyPaired() | ||
{ | ||
return !!(this.flags & Constants.BAM_FPROPER_PAIR); | ||
} | ||
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */ | ||
}, { | ||
key: 'isSegmentUnmapped', | ||
value: function isSegmentUnmapped() { | ||
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */ }, { key: "isSegmentUnmapped", value: function isSegmentUnmapped() | ||
{ | ||
return !!(this.flags & Constants.BAM_FUNMAP); | ||
} | ||
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */ | ||
}, { | ||
key: 'isMateUnmapped', | ||
value: function isMateUnmapped() { | ||
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */ }, { key: "isMateUnmapped", value: function isMateUnmapped() | ||
{ | ||
return !!(this.flags & Constants.BAM_FMUNMAP); | ||
} | ||
/** @returns {boolean} true if the read is mapped to the reverse strand */ | ||
}, { | ||
key: 'isReverseComplemented', | ||
value: function isReverseComplemented() { | ||
/** @returns {boolean} true if the read is mapped to the reverse strand */ }, { key: "isReverseComplemented", value: function isReverseComplemented() | ||
{ | ||
return !!(this.flags & Constants.BAM_FREVERSE); | ||
} | ||
/** @returns {boolean} true if the mate is mapped to the reverse strand */ | ||
}, { | ||
key: 'isMateReverseComplemented', | ||
value: function isMateReverseComplemented() { | ||
/** @returns {boolean} true if the mate is mapped to the reverse strand */ }, { key: "isMateReverseComplemented", value: function isMateReverseComplemented() | ||
{ | ||
return !!(this.flags & Constants.BAM_FMREVERSE); | ||
} | ||
/** @returns {boolean} true if this is read number 1 in a pair */ | ||
}, { | ||
key: 'isRead1', | ||
value: function isRead1() { | ||
/** @returns {boolean} true if this is read number 1 in a pair */ }, { key: "isRead1", value: function isRead1() | ||
{ | ||
return !!(this.flags & Constants.BAM_FREAD1); | ||
} | ||
/** @returns {boolean} true if this is read number 2 in a pair */ | ||
}, { | ||
key: 'isRead2', | ||
value: function isRead2() { | ||
/** @returns {boolean} true if this is read number 2 in a pair */ }, { key: "isRead2", value: function isRead2() | ||
{ | ||
return !!(this.flags & Constants.BAM_FREAD2); | ||
} | ||
/** @returns {boolean} true if this is a secondary alignment */ | ||
}, { | ||
key: 'isSecondary', | ||
value: function isSecondary() { | ||
/** @returns {boolean} true if this is a secondary alignment */ }, { key: "isSecondary", value: function isSecondary() | ||
{ | ||
return !!(this.flags & Constants.BAM_FSECONDARY); | ||
} | ||
/** @returns {boolean} true if this read has failed QC checks */ | ||
}, { | ||
key: 'isFailedQc', | ||
value: function isFailedQc() { | ||
/** @returns {boolean} true if this read has failed QC checks */ }, { key: "isFailedQc", value: function isFailedQc() | ||
{ | ||
return !!(this.flags & Constants.BAM_FQCFAIL); | ||
} | ||
/** @returns {boolean} true if the read is an optical or PCR duplicate */ | ||
}, { | ||
key: 'isDuplicate', | ||
value: function isDuplicate() { | ||
/** @returns {boolean} true if the read is an optical or PCR duplicate */ }, { key: "isDuplicate", value: function isDuplicate() | ||
{ | ||
return !!(this.flags & Constants.BAM_FDUP); | ||
} | ||
/** @returns {boolean} true if this is a supplementary alignment */ | ||
}, { | ||
key: 'isSupplementary', | ||
value: function isSupplementary() { | ||
/** @returns {boolean} true if this is a supplementary alignment */ }, { key: "isSupplementary", value: function isSupplementary() | ||
{ | ||
return !!(this.flags & Constants.BAM_FSUPPLEMENTARY); | ||
} | ||
}, { | ||
key: 'cigar', | ||
value: function cigar() { | ||
if (this.isSegmentUnmapped()) return undefined; | ||
} }, { key: "cigar", value: function cigar() | ||
var _bytes2 = this.bytes, | ||
byteArray = _bytes2.byteArray, | ||
start = _bytes2.start; | ||
{ | ||
if (this.isSegmentUnmapped()) return undefined;var _this$bytes2 = | ||
this.bytes,byteArray = _this$bytes2.byteArray,start = _this$bytes2.start; | ||
var numCigarOps = this._get('_n_cigar_op'); | ||
@@ -460,39 +420,35 @@ var p = start + 36 + this._get('_l_read_name'); | ||
return cigar; | ||
} | ||
}, { | ||
key: '_flags', | ||
value: function _flags() {} | ||
}, { | ||
key: 'length_on_ref', | ||
value: function length_on_ref() { | ||
} }, { key: "_flags", value: function _flags() | ||
{} }, { key: "length_on_ref", value: function length_on_ref() | ||
{ | ||
this._get('cigar'); // the length_on_ref is set as a | ||
// side effect of the CIGAR parsing | ||
return this.data.length_on_ref; | ||
} | ||
}, { | ||
key: '_n_cigar_op', | ||
value: function _n_cigar_op() { | ||
} }, { key: "_n_cigar_op", value: function _n_cigar_op() | ||
{ | ||
return this._get('_flag_nc') & 0xffff; | ||
} | ||
}, { | ||
key: '_l_read_name', | ||
value: function _l_read_name() { | ||
} }, { key: "_l_read_name", value: function _l_read_name() | ||
{ | ||
return this._get('_bin_mq_nl') & 0xff; | ||
} | ||
/** | ||
* number of bytes in the sequence field | ||
*/ | ||
}, { | ||
key: '_seq_bytes', | ||
value: function _seq_bytes() { | ||
* number of bytes in the sequence field | ||
*/ }, { key: "_seq_bytes", value: function _seq_bytes() | ||
{ | ||
return this._get('seq_length') + 1 >> 1; | ||
} | ||
}, { | ||
key: 'getReadBases', | ||
value: function getReadBases() { | ||
var seq = ''; | ||
var byteArray = this.bytes.byteArray; | ||
} }, { key: "getReadBases", value: function getReadBases() | ||
var p = this.bytes.start + 36 + this._get('_l_read_name') + this._get('_n_cigar_op') * 4; | ||
{ | ||
var seq = '';var | ||
byteArray = this.bytes.byteArray; | ||
var p = | ||
this.bytes.start + | ||
36 + | ||
this._get('_l_read_name') + | ||
this._get('_n_cigar_op') * 4; | ||
var seqBytes = this._get('_seq_bytes'); | ||
@@ -508,7 +464,8 @@ for (var j = 0; j < seqBytes; ++j) { | ||
// adapted from igv.js | ||
}, { | ||
key: 'getPairOrientation', | ||
value: function getPairOrientation() { | ||
if (!this.isSegmentUnmapped() && !this.isMateUnmapped() && this._refID === this._next_refid()) { | ||
}, { key: "getPairOrientation", value: function getPairOrientation() { | ||
if ( | ||
!this.isSegmentUnmapped() && | ||
!this.isMateUnmapped() && | ||
this._refID === this._next_refid()) | ||
{ | ||
var s1 = this.isReverseComplemented() ? 'R' : 'F'; | ||
@@ -542,40 +499,31 @@ var s2 = this.isMateReverseComplemented() ? 'R' : 'F'; | ||
return null; | ||
} | ||
}, { | ||
key: '_bin_mq_nl', | ||
value: function _bin_mq_nl() { | ||
} }, { key: "_bin_mq_nl", value: function _bin_mq_nl() | ||
{ | ||
return this.bytes.byteArray.readInt32LE(this.bytes.start + 12); | ||
} | ||
}, { | ||
key: '_flag_nc', | ||
value: function _flag_nc() { | ||
} }, { key: "_flag_nc", value: function _flag_nc() | ||
{ | ||
return this.bytes.byteArray.readInt32LE(this.bytes.start + 16); | ||
} | ||
}, { | ||
key: 'seq_length', | ||
value: function seq_length() { | ||
} }, { key: "seq_length", value: function seq_length() | ||
{ | ||
return this.bytes.byteArray.readInt32LE(this.bytes.start + 20); | ||
} | ||
}, { | ||
key: '_next_refid', | ||
value: function _next_refid() { | ||
} }, { key: "_next_refid", value: function _next_refid() | ||
{ | ||
return this.bytes.byteArray.readInt32LE(this.bytes.start + 24); | ||
} | ||
}, { | ||
key: '_next_pos', | ||
value: function _next_pos() { | ||
} }, { key: "_next_pos", value: function _next_pos() | ||
{ | ||
return this.bytes.byteArray.readInt32LE(this.bytes.start + 28); | ||
} | ||
}, { | ||
key: 'template_length', | ||
value: function template_length() { | ||
} }, { key: "template_length", value: function template_length() | ||
{ | ||
return this.bytes.byteArray.readInt32LE(this.bytes.start + 32); | ||
} | ||
}, { | ||
key: 'toJSON', | ||
value: function toJSON() { | ||
var _this2 = this; | ||
} }, { key: "toJSON", value: function toJSON() | ||
{var _this2 = this; | ||
var data = {}; | ||
(0, _keys2.default)(this).forEach(function (k) { | ||
(0, _keys.default)(this).forEach(function (k) { | ||
if (k.charAt(0) === '_' || k === 'bytes') return; | ||
@@ -586,7 +534,5 @@ data[k] = _this2[k]; | ||
return data; | ||
} | ||
}]); | ||
return BamRecord; | ||
}(); | ||
} }]);return BamRecord;}(); | ||
module.exports = BamRecord; |
@@ -1,28 +0,8 @@ | ||
'use strict'; | ||
var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray'); | ||
var _slicedToArray3 = _interopRequireDefault(_slicedToArray2); | ||
var _toArray2 = require('babel-runtime/helpers/toArray'); | ||
var _toArray3 = _interopRequireDefault(_toArray2); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
function parseHeaderText(text) { | ||
"use strict";var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));var _toArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toArray"));function parseHeaderText(text) { | ||
var lines = text.split(/\r?\n/); | ||
var data = []; | ||
lines.forEach(function (line) { | ||
var _line$split = line.split(/\t/), | ||
_line$split2 = (0, _toArray3.default)(_line$split), | ||
tag = _line$split2[0], | ||
fields = _line$split2.slice(1); | ||
var parsedFields = fields.map(function (f) { | ||
var _f$split = f.split(':', 2), | ||
_f$split2 = (0, _slicedToArray3.default)(_f$split, 2), | ||
fieldTag = _f$split2[0], | ||
value = _f$split2[1]; | ||
lines.forEach(function (line) {var _line$split = | ||
line.split(/\t/),_line$split2 = (0, _toArray2.default)(_line$split),tag = _line$split2[0],fields = _line$split2.slice(1); | ||
var parsedFields = fields.map(function (f) {var _f$split = | ||
f.split(':', 2),_f$split2 = (0, _slicedToArray2.default)(_f$split, 2),fieldTag = _f$split2[0],value = _f$split2[1]; | ||
return { tag: fieldTag, value: value }; | ||
@@ -29,0 +9,0 @@ }); |
@@ -1,20 +0,49 @@ | ||
'use strict'; | ||
"use strict";var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));var _minSafeInteger = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/number/min-safe-integer"));var _maxSafeInteger = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/number/max-safe-integer"));function longToNumber(long) { | ||
if ( | ||
long.greaterThan(_maxSafeInteger.default) || | ||
long.lessThan(_minSafeInteger.default)) | ||
{ | ||
throw new Error('integer overflow'); | ||
} | ||
return long.toNumber(); | ||
} | ||
var _minSafeInteger = require('babel-runtime/core-js/number/min-safe-integer'); | ||
/** | ||
* Properly check if the given AbortSignal is aborted. | ||
* Per the standard, if the signal reads as aborted, | ||
* this function throws either a DOMException AbortError, or a regular error | ||
* with a `code` attribute set to `ERR_ABORTED`. | ||
* | ||
* For convenience, passing `undefined` is a no-op | ||
* | ||
* @param {AbortSignal} [signal] an AbortSignal, or anything with an `aborted` attribute | ||
* @returns nothing | ||
*/ | ||
function checkAbortSignal(signal) { | ||
if (!signal) return; | ||
var _minSafeInteger2 = _interopRequireDefault(_minSafeInteger); | ||
if (signal.aborted) { | ||
// console.log('bam aborted!') | ||
if (typeof DOMException !== 'undefined') | ||
// eslint-disable-next-line no-undef | ||
throw new DOMException('aborted', 'AbortError');else | ||
{ | ||
var e = new Error('aborted'); | ||
e.code = 'ERR_ABORTED'; | ||
throw e; | ||
} | ||
} | ||
} | ||
var _maxSafeInteger = require('babel-runtime/core-js/number/max-safe-integer'); | ||
/** | ||
* Skips to the next tick, then runs `checkAbortSignal`. | ||
* Await this to inside an otherwise synchronous loop to | ||
* provide a place to break when an abort signal is received. | ||
* @param {AbortSignal} signal | ||
*/function | ||
abortBreakPoint(_x) {return _abortBreakPoint.apply(this, arguments);}function _abortBreakPoint() {_abortBreakPoint = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(signal) {return _regenerator.default.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:_context.next = 2;return ( | ||
_promise.default.resolve());case 2: | ||
checkAbortSignal(signal);case 3:case "end":return _context.stop();}}}, _callee);}));return _abortBreakPoint.apply(this, arguments);} | ||
var _maxSafeInteger2 = _interopRequireDefault(_maxSafeInteger); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
module.exports = { | ||
longToNumber: function longToNumber(long) { | ||
if (long.greaterThan(_maxSafeInteger2.default) || long.lessThan(_minSafeInteger2.default)) { | ||
throw new Error('integer overflow'); | ||
} | ||
return long.toNumber(); | ||
} | ||
}; | ||
module.exports = { longToNumber: longToNumber, checkAbortSignal: checkAbortSignal, abortBreakPoint: abortBreakPoint }; |
@@ -1,57 +0,43 @@ | ||
'use strict'; | ||
"use strict";var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));var VirtualOffset = /*#__PURE__*/function () { | ||
function VirtualOffset(blockPosition, dataPosition) {(0, _classCallCheck2.default)(this, VirtualOffset); | ||
this.blockPosition = blockPosition; // < offset of the compressed data block | ||
this.dataPosition = dataPosition; // < offset into the uncompressed data | ||
}(0, _createClass2.default)(VirtualOffset, [{ key: "toString", value: function toString() | ||
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); | ||
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); | ||
var _createClass2 = require('babel-runtime/helpers/createClass'); | ||
var _createClass3 = _interopRequireDefault(_createClass2); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var VirtualOffset = function () { | ||
function VirtualOffset(blockPosition, dataPosition) { | ||
(0, _classCallCheck3.default)(this, VirtualOffset); | ||
this.blockPosition = blockPosition; // < offset of the compressed data block | ||
this.dataPosition = dataPosition; // < offset into the uncompressed data | ||
} | ||
(0, _createClass3.default)(VirtualOffset, [{ | ||
key: 'toString', | ||
value: function toString() { | ||
return this.blockPosition + ':' + this.dataPosition; | ||
} | ||
}, { | ||
key: 'compareTo', | ||
value: function compareTo(b) { | ||
return this.blockPosition - b.blockPosition || this.dataPosition - b.dataPosition; | ||
} | ||
}], [{ | ||
key: 'fromBytes', | ||
value: function fromBytes(bytes) { | ||
var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; | ||
var bigendian = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; | ||
if (bigendian) throw new Error('big-endian virtual file offsets not implemented'); | ||
return new VirtualOffset(bytes[offset + 7] * 0x10000000000 + bytes[offset + 6] * 0x100000000 + bytes[offset + 5] * 0x1000000 + bytes[offset + 4] * 0x10000 + bytes[offset + 3] * 0x100 + bytes[offset + 2], bytes[offset + 1] << 8 | bytes[offset]); | ||
} | ||
}, { | ||
key: 'min', | ||
value: function min() { | ||
var min = void 0; | ||
{ | ||
return "".concat(this.blockPosition, ":").concat(this.dataPosition); | ||
} }, { key: "compareTo", value: function compareTo( | ||
b) { | ||
return ( | ||
this.blockPosition - b.blockPosition || this.dataPosition - b.dataPosition); | ||
} }], [{ key: "fromBytes", value: function fromBytes(bytes) {var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;var bigendian = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;if (bigendian) throw new Error('big-endian virtual file offsets not implemented');return new VirtualOffset(bytes[offset + 7] * 0x10000000000 + bytes[offset + 6] * 0x100000000 + bytes[offset + 5] * 0x1000000 + bytes[offset + 4] * 0x10000 + bytes[offset + 3] * 0x100 + bytes[offset + 2], bytes[offset + 1] << 8 | bytes[offset]);} }, { key: "min", value: function min() | ||
{ | ||
var min; | ||
var i = 0; | ||
for (; !min; i += 1) { | ||
min = arguments.length <= i ? undefined : arguments[i]; | ||
}for (; i < arguments.length; i += 1) { | ||
if (min.compareTo(arguments.length <= i ? undefined : arguments[i]) > 0) min = arguments.length <= i ? undefined : arguments[i]; | ||
for (; !min; i += 1) {min = i < 0 || arguments.length <= i ? undefined : arguments[i];} | ||
for (; i < arguments.length; i += 1) { | ||
if (min.compareTo(i < 0 || arguments.length <= i ? undefined : arguments[i]) > 0) min = i < 0 || arguments.length <= i ? undefined : arguments[i]; | ||
} | ||
return min; | ||
} | ||
}]); | ||
return VirtualOffset; | ||
}(); | ||
} }]);return VirtualOffset;}(); | ||
module.exports = VirtualOffset; |
{ | ||
"name": "@gmod/bam", | ||
"version": "1.0.14", | ||
"version": "1.0.15", | ||
"description": "Parser for BAM and BAM index (bai) files", | ||
@@ -22,9 +22,5 @@ "license": "MIT", | ||
"coverage": "npm test -- --coverage", | ||
"postcoverage": "opn coverage/lcov-report/index.html", | ||
"lint": "eslint src test", | ||
"flow": "flow check", | ||
"clean": "rimraf dist", | ||
"docs": "echo nothing", | ||
"flowbuild": "flow-copy-source src dist", | ||
"prebuild": "npm run docs && npm run clean && npm run flowbuild", | ||
"prebuild": "npm run clean && npm run lint", | ||
"build": "babel src -d dist", | ||
@@ -45,3 +41,5 @@ "preversion": "npm run lint && npm test && npm run build", | ||
"dependencies": { | ||
"@gmod/bgzf-filehandle": "^1.2.2", | ||
"@babel/runtime-corejs2": "^7.3.4", | ||
"@gmod/bgzf-filehandle": "^1.2.3", | ||
"abortable-promise-cache": "^1.0.0", | ||
"buffer-crc32": "^0.2.13", | ||
@@ -53,23 +51,14 @@ "es6-promisify": "^6.0.1", | ||
"devDependencies": { | ||
"babel-cli": "^6.26.0", | ||
"babel-core": "^6.26.0", | ||
"babel-eslint": "^8.2.2", | ||
"babel-jest": "^23.0.1", | ||
"babel-plugin-transform-runtime": "^6.23.0", | ||
"babel-preset-env": "^1.6.1", | ||
"babel-preset-flow": "^6.23.0", | ||
"babel-preset-stage-2": "^6.24.1", | ||
"cross-fetch": "^2.2.2", | ||
"documentation": "^7.1.0", | ||
"eslint": "^4.19.1", | ||
"eslint-config-airbnb-base": "^12.1.0", | ||
"eslint-config-prettier": "^2.9.0", | ||
"eslint-plugin-flowtype": "^2.46.1", | ||
"eslint-plugin-flowtype-errors": "^3.5.1", | ||
"@babel/cli": "^7.2.3", | ||
"@babel/core": "^7.3.3", | ||
"@babel/plugin-transform-runtime": "^7.2.0", | ||
"@babel/preset-env": "^7.3.1", | ||
"babel-jest": "^24.1.0", | ||
"documentation": "^9.1.1", | ||
"eslint": "^5.12.0", | ||
"eslint-config-airbnb-base": "^13.1.0", | ||
"eslint-config-prettier": "^4.1.0", | ||
"eslint-plugin-import": "^2.10.0", | ||
"eslint-plugin-prettier": "^2.6.0", | ||
"flow-bin": "^0.73.0", | ||
"flow-copy-source": "^1.3.0", | ||
"jest-cli": "^23.1.0", | ||
"opn-cli": "^3.1.0", | ||
"eslint-plugin-prettier": "^3.0.1", | ||
"jest": "^24.3.1", | ||
"prettier": "^1.11.1", | ||
@@ -76,0 +65,0 @@ "rimraf": "^2.6.2", |
[![Generated with nod](https://img.shields.io/badge/generator-nod-2196F3.svg?style=flat-square)](https://github.com/diegohaz/nod) | ||
[![NPM version](https://img.shields.io/npm/v/@gmod/bam.svg?style=flat-square)](https://npmjs.org/package/@gmod/bam) | ||
[![Build Status](https://img.shields.io/travis/GMOD/bam-js/master.svg?style=flat-square)](https://travis-ci.org/GMOD/bam-js) [![Coverage Status](https://img.shields.io/codecov/c/github/GMOD/bam-js/master.svg?style=flat-square)](https://codecov.io/gh/GMOD/bam-js/branch/master) | ||
[![Build Status](https://img.shields.io/travis/GMOD/bam-js/master.svg?style=flat-square)](https://travis-ci.org/GMOD/bam-js) | ||
[![Coverage Status](https://img.shields.io/codecov/c/github/GMOD/bam-js/master.svg?style=flat-square)](https://codecov.io/gh/GMOD/bam-js/branch/master) | ||
[![Greenkeeper badge](https://badges.greenkeeper.io/GMOD/bam-js.svg)](https://greenkeeper.io/) | ||
@@ -26,5 +28,35 @@ | ||
## Documentation | ||
BAM class constructor infers BAI by default as bamPath+'.bai', or you can specify it explicitely via baiPath (also accepts csiPath) | ||
BAM({ bamPath: "yourfile.bam", baiPath: "yourfile.bai" }) | ||
Or accepts filehandles, this is an abstract filehandle concept that can represent remote files. The remote file concept is not built into this repository, but see @gmod/cram for example of the remoteFile.js class | ||
BAM({ bamFilehandle: new FileHandle("http://localhost/file.bam", baiFilehandle: new FileHandle("yourfile.bai") }) | ||
The method getRecordsForRange(refName, start, end, opts) has the opts blob that can contain | ||
* opts.signal - an AbortSignal to indicate stop processing | ||
* opts.viewAsPairs - re-dispatches requests to find mate pairs | ||
* opts.pairAcrossChr - control the viewAsPairs option behavior to pair across chromosomes | ||
* opts.maxInsertSize - control the viewAsPairs option behavior to limit distance within a chromosome to fetch | ||
The returned features from BAM are lazy features meaning that it delays processing of all the feature tags until necessary. You can perform feature.get('field') to get the value of a feature attribute | ||
Example | ||
feature.get('seq_id') | ||
feature.get('start') | ||
feature.get('name') // QNAME | ||
feature.get('seq') // get feature sequence | ||
This may change in future versions to make it raw records but will be a major version bump | ||
## License | ||
MIT © [Colin Diesh](https://github.com/cmdcolin) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
15
62
90603
7
17
1339
2
1
+ Added@babel/runtime-corejs2@7.26.0(transitive)
+ Addedabortable-promise-cache@1.5.0(transitive)
+ Addedabortcontroller-polyfill@1.7.8(transitive)
+ Addedcore-js@2.6.12(transitive)
+ Addedregenerator-runtime@0.14.1(transitive)
Updated@gmod/bgzf-filehandle@^1.2.3