@gmod/cram 1.5.9 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +90 -0
- package/README.md +182 -172
- package/dist/craiIndex.d.ts +37 -0
- package/dist/craiIndex.js +196 -301
- package/dist/craiIndex.js.map +1 -0
- package/dist/cram-bundle.js +6 -15
- package/dist/cramFile/codecs/_base.d.ts +6 -0
- package/dist/cramFile/codecs/_base.js +44 -53
- package/dist/cramFile/codecs/_base.js.map +1 -0
- package/dist/cramFile/codecs/beta.d.ts +4 -0
- package/dist/cramFile/codecs/beta.js +38 -48
- package/dist/cramFile/codecs/beta.js.map +1 -0
- package/dist/cramFile/codecs/byteArrayLength.d.ts +8 -0
- package/dist/cramFile/codecs/byteArrayLength.js +58 -78
- package/dist/cramFile/codecs/byteArrayLength.js.map +1 -0
- package/dist/cramFile/codecs/byteArrayStop.d.ts +6 -0
- package/dist/cramFile/codecs/byteArrayStop.js +62 -76
- package/dist/cramFile/codecs/byteArrayStop.js.map +1 -0
- package/dist/cramFile/codecs/external.d.ts +7 -0
- package/dist/cramFile/codecs/external.js +63 -81
- package/dist/cramFile/codecs/external.js.map +1 -0
- package/dist/cramFile/codecs/gamma.d.ts +4 -0
- package/dist/cramFile/codecs/gamma.js +43 -56
- package/dist/cramFile/codecs/gamma.js.map +1 -0
- package/dist/cramFile/codecs/huffman.d.ts +17 -0
- package/dist/cramFile/codecs/huffman.js +126 -199
- package/dist/cramFile/codecs/huffman.js.map +1 -0
- package/dist/cramFile/codecs/index.d.ts +2 -0
- package/dist/cramFile/codecs/index.js +31 -38
- package/dist/cramFile/codecs/index.js.map +1 -0
- package/dist/cramFile/codecs/subexp.d.ts +4 -0
- package/dist/cramFile/codecs/subexp.js +51 -64
- package/dist/cramFile/codecs/subexp.js.map +1 -0
- package/dist/cramFile/constants.d.ts +36 -0
- package/dist/cramFile/constants.js +52 -50
- package/dist/cramFile/constants.js.map +1 -0
- package/dist/cramFile/container/compressionScheme.d.ts +23 -0
- package/dist/cramFile/container/compressionScheme.js +115 -153
- package/dist/cramFile/container/compressionScheme.js.map +1 -0
- package/dist/cramFile/container/index.d.ts +13 -0
- package/dist/cramFile/container/index.js +169 -283
- package/dist/cramFile/container/index.js.map +1 -0
- package/dist/cramFile/file.d.ts +63 -0
- package/dist/cramFile/file.js +440 -766
- package/dist/cramFile/file.js.map +1 -0
- package/dist/cramFile/index.d.ts +2 -0
- package/dist/cramFile/index.js +7 -4
- package/dist/cramFile/index.js.map +1 -0
- package/dist/cramFile/record.d.ts +79 -0
- package/dist/cramFile/record.js +253 -308
- package/dist/cramFile/record.js.map +1 -0
- package/dist/cramFile/sectionParsers.d.ts +18 -0
- package/dist/cramFile/sectionParsers.js +324 -362
- package/dist/cramFile/sectionParsers.js.map +1 -0
- package/dist/cramFile/slice/decodeRecord.d.ts +2 -0
- package/dist/cramFile/slice/decodeRecord.js +278 -298
- package/dist/cramFile/slice/decodeRecord.js.map +1 -0
- package/dist/cramFile/slice/index.d.ts +20 -0
- package/dist/cramFile/slice/index.js +488 -789
- package/dist/cramFile/slice/index.js.map +1 -0
- package/dist/cramFile/util.d.ts +5 -0
- package/dist/cramFile/util.js +158 -144
- package/dist/cramFile/util.js.map +1 -0
- package/dist/errors.d.ts +23 -0
- package/dist/errors.js +66 -103
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +12 -12
- package/dist/index.js.map +1 -0
- package/dist/indexedCramFile.d.ts +39 -0
- package/dist/indexedCramFile.js +213 -315
- package/dist/indexedCramFile.js.map +1 -0
- package/dist/io/bufferCache.d.ts +12 -0
- package/dist/io/bufferCache.js +108 -128
- package/dist/io/bufferCache.js.map +1 -0
- package/dist/io/index.d.ts +5 -0
- package/dist/io/index.js +29 -27
- package/dist/io/index.js.map +1 -0
- package/dist/io/localFile.d.ts +10 -0
- package/dist/io/localFile.js +105 -162
- package/dist/io/localFile.js.map +1 -0
- package/dist/io/remoteFile.d.ts +16 -0
- package/dist/io/remoteFile.js +137 -206
- package/dist/io/remoteFile.js.map +1 -0
- package/dist/rans/constants.d.ts +3 -0
- package/dist/rans/constants.js +6 -6
- package/dist/rans/constants.js.map +1 -0
- package/dist/rans/d04.d.ts +1 -0
- package/dist/rans/d04.js +70 -99
- package/dist/rans/d04.js.map +1 -0
- package/dist/rans/d14.d.ts +1 -0
- package/dist/rans/d14.js +55 -93
- package/dist/rans/d14.js.map +1 -0
- package/dist/rans/decoding.d.ts +30 -0
- package/dist/rans/decoding.js +112 -159
- package/dist/rans/decoding.js.map +1 -0
- package/dist/rans/frequencies.d.ts +2 -0
- package/dist/rans/frequencies.js +110 -119
- package/dist/rans/frequencies.js.map +1 -0
- package/dist/rans/index.d.ts +1 -0
- package/dist/rans/index.js +111 -174
- package/dist/rans/index.js.map +1 -0
- package/dist/sam.d.ts +1 -0
- package/dist/sam.js +16 -41
- package/dist/sam.js.map +1 -0
- package/dist/unzip-pako.d.ts +2 -0
- package/dist/unzip-pako.js +9 -0
- package/dist/unzip-pako.js.map +1 -0
- package/dist/unzip.d.ts +2 -0
- package/dist/unzip.js +6 -0
- package/dist/unzip.js.map +1 -0
- package/errors.js +66 -103
- package/esm/craiIndex.d.ts +37 -0
- package/esm/craiIndex.js +158 -0
- package/esm/craiIndex.js.map +1 -0
- package/esm/cramFile/codecs/_base.d.ts +6 -0
- package/esm/cramFile/codecs/_base.js +42 -0
- package/esm/cramFile/codecs/_base.js.map +1 -0
- package/esm/cramFile/codecs/beta.d.ts +4 -0
- package/esm/cramFile/codecs/beta.js +15 -0
- package/esm/cramFile/codecs/beta.js.map +1 -0
- package/esm/cramFile/codecs/byteArrayLength.d.ts +8 -0
- package/esm/cramFile/codecs/byteArrayLength.js +35 -0
- package/esm/cramFile/codecs/byteArrayLength.js.map +1 -0
- package/esm/cramFile/codecs/byteArrayStop.d.ts +6 -0
- package/esm/cramFile/codecs/byteArrayStop.js +40 -0
- package/esm/cramFile/codecs/byteArrayStop.js.map +1 -0
- package/esm/cramFile/codecs/external.d.ts +7 -0
- package/esm/cramFile/codecs/external.js +40 -0
- package/esm/cramFile/codecs/external.js.map +1 -0
- package/esm/cramFile/codecs/gamma.d.ts +4 -0
- package/esm/cramFile/codecs/gamma.js +20 -0
- package/esm/cramFile/codecs/gamma.js.map +1 -0
- package/esm/cramFile/codecs/huffman.d.ts +17 -0
- package/esm/cramFile/codecs/huffman.js +107 -0
- package/esm/cramFile/codecs/huffman.js.map +1 -0
- package/esm/cramFile/codecs/index.d.ts +2 -0
- package/esm/cramFile/codecs/index.js +30 -0
- package/esm/cramFile/codecs/index.js.map +1 -0
- package/esm/cramFile/codecs/subexp.d.ts +4 -0
- package/esm/cramFile/codecs/subexp.js +28 -0
- package/esm/cramFile/codecs/subexp.js.map +1 -0
- package/esm/cramFile/constants.d.ts +36 -0
- package/esm/cramFile/constants.js +51 -0
- package/esm/cramFile/constants.js.map +1 -0
- package/esm/cramFile/container/compressionScheme.d.ts +23 -0
- package/esm/cramFile/container/compressionScheme.js +123 -0
- package/esm/cramFile/container/compressionScheme.js.map +1 -0
- package/esm/cramFile/container/index.d.ts +13 -0
- package/esm/cramFile/container/index.js +84 -0
- package/esm/cramFile/container/index.js.map +1 -0
- package/esm/cramFile/file.d.ts +63 -0
- package/esm/cramFile/file.js +281 -0
- package/esm/cramFile/file.js.map +1 -0
- package/esm/cramFile/index.d.ts +2 -0
- package/esm/cramFile/index.js +3 -0
- package/esm/cramFile/index.js.map +1 -0
- package/esm/cramFile/record.d.ts +79 -0
- package/esm/cramFile/record.js +297 -0
- package/esm/cramFile/record.js.map +1 -0
- package/esm/cramFile/sectionParsers.d.ts +18 -0
- package/esm/cramFile/sectionParsers.js +347 -0
- package/esm/cramFile/sectionParsers.js.map +1 -0
- package/esm/cramFile/slice/decodeRecord.d.ts +2 -0
- package/esm/cramFile/slice/decodeRecord.js +299 -0
- package/esm/cramFile/slice/decodeRecord.js.map +1 -0
- package/esm/cramFile/slice/index.d.ts +20 -0
- package/esm/cramFile/slice/index.js +364 -0
- package/esm/cramFile/slice/index.js.map +1 -0
- package/esm/cramFile/util.d.ts +5 -0
- package/esm/cramFile/util.js +161 -0
- package/esm/cramFile/util.js.map +1 -0
- package/esm/errors.d.ts +23 -0
- package/esm/errors.js +24 -0
- package/esm/errors.js.map +1 -0
- package/esm/index.d.ts +4 -0
- package/esm/index.js +5 -0
- package/esm/index.js.map +1 -0
- package/esm/indexedCramFile.d.ts +39 -0
- package/esm/indexedCramFile.js +155 -0
- package/esm/indexedCramFile.js.map +1 -0
- package/esm/io/bufferCache.d.ts +12 -0
- package/esm/io/bufferCache.js +54 -0
- package/esm/io/bufferCache.js.map +1 -0
- package/esm/io/index.d.ts +5 -0
- package/esm/io/index.js +24 -0
- package/esm/io/index.js.map +1 -0
- package/esm/io/localFile.d.ts +10 -0
- package/esm/io/localFile.js +31 -0
- package/esm/io/localFile.js.map +1 -0
- package/esm/io/remoteFile.d.ts +16 -0
- package/esm/io/remoteFile.js +64 -0
- package/esm/io/remoteFile.js.map +1 -0
- package/esm/rans/constants.d.ts +3 -0
- package/esm/rans/constants.js +5 -0
- package/esm/rans/constants.js.map +1 -0
- package/esm/rans/d04.d.ts +1 -0
- package/esm/rans/d04.js +67 -0
- package/esm/rans/d04.js.map +1 -0
- package/esm/rans/d14.d.ts +1 -0
- package/esm/rans/d14.js +52 -0
- package/esm/rans/d14.js.map +1 -0
- package/esm/rans/decoding.d.ts +30 -0
- package/esm/rans/decoding.js +118 -0
- package/esm/rans/decoding.js.map +1 -0
- package/esm/rans/frequencies.d.ts +2 -0
- package/esm/rans/frequencies.js +110 -0
- package/esm/rans/frequencies.js.map +1 -0
- package/esm/rans/index.d.ts +1 -0
- package/esm/rans/index.js +195 -0
- package/esm/rans/index.js.map +1 -0
- package/esm/sam.d.ts +1 -0
- package/esm/sam.js +16 -0
- package/esm/sam.js.map +1 -0
- package/esm/unzip-pako.d.ts +2 -0
- package/esm/unzip-pako.js +5 -0
- package/esm/unzip-pako.js.map +1 -0
- package/esm/unzip.d.ts +2 -0
- package/esm/unzip.js +3 -0
- package/esm/unzip.js.map +1 -0
- package/package.json +38 -35
- package/src/craiIndex.js +180 -0
- package/src/cramFile/codecs/_base.js +49 -0
- package/src/cramFile/codecs/beta.js +23 -0
- package/src/cramFile/codecs/byteArrayLength.js +55 -0
- package/src/cramFile/codecs/byteArrayStop.js +50 -0
- package/src/cramFile/codecs/external.js +54 -0
- package/src/cramFile/codecs/gamma.js +30 -0
- package/src/cramFile/codecs/huffman.js +137 -0
- package/src/cramFile/codecs/index.js +38 -0
- package/src/cramFile/codecs/subexp.js +32 -0
- package/src/cramFile/constants.js +55 -0
- package/src/cramFile/container/compressionScheme.js +144 -0
- package/src/cramFile/container/index.js +119 -0
- package/src/cramFile/file.js +347 -0
- package/src/cramFile/index.js +3 -0
- package/src/cramFile/record.js +337 -0
- package/src/cramFile/sectionParsers.js +379 -0
- package/src/cramFile/slice/decodeRecord.js +362 -0
- package/src/cramFile/slice/index.js +497 -0
- package/src/cramFile/util.js +169 -0
- package/src/errors.js +22 -0
- package/src/index.js +5 -0
- package/src/indexedCramFile.js +191 -0
- package/src/io/bufferCache.js +66 -0
- package/src/io/index.js +26 -0
- package/src/io/localFile.js +35 -0
- package/src/io/remoteFile.js +71 -0
- package/src/rans/README.md +1 -0
- package/src/rans/constants.js +5 -0
- package/src/rans/d04.js +83 -0
- package/src/rans/d14.js +59 -0
- package/src/rans/decoding.js +141 -0
- package/src/rans/frequencies.js +121 -0
- package/src/rans/index.js +249 -0
- package/src/sam.js +15 -0
- package/src/unzip-pako.ts +5 -0
- package/src/unzip.ts +2 -0
package/dist/cramFile/file.js
CHANGED
|
@@ -1,783 +1,457 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs3/regenerator"));
|
|
10
|
-
|
|
11
|
-
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/asyncToGenerator"));
|
|
12
|
-
|
|
13
|
-
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));
|
|
14
|
-
|
|
15
|
-
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));
|
|
16
|
-
|
|
17
|
-
var _context14;
|
|
18
|
-
|
|
19
|
-
var zlib = require('zlib');
|
|
20
|
-
|
|
21
|
-
var crc32 = require('buffer-crc32');
|
|
22
|
-
|
|
23
|
-
var LRU = require('quick-lru');
|
|
24
|
-
|
|
25
|
-
var _require = require('../errors'),
|
|
26
|
-
CramUnimplementedError = _require.CramUnimplementedError,
|
|
27
|
-
CramMalformedError = _require.CramMalformedError;
|
|
28
|
-
|
|
29
|
-
var rans = require('../rans');
|
|
30
|
-
|
|
31
|
-
var _require2 = require('./sectionParsers'),
|
|
32
|
-
cramFileDefinitionParser = _require2.cramFileDefinition,
|
|
33
|
-
_getSectionParsers = _require2.getSectionParsers;
|
|
34
|
-
|
|
35
|
-
var CramContainer = require('./container');
|
|
36
|
-
|
|
37
|
-
var _require3 = require('../io'),
|
|
38
|
-
open = _require3.open;
|
|
39
|
-
|
|
40
|
-
var _require4 = require('./util'),
|
|
41
|
-
parseItem = _require4.parseItem,
|
|
42
|
-
tinyMemoize = _require4.tinyMemoize;
|
|
43
|
-
|
|
44
|
-
var _require5 = require('../sam'),
|
|
45
|
-
parseHeaderText = _require5.parseHeaderText;
|
|
46
|
-
|
|
47
|
-
var CramFile =
|
|
48
|
-
/*#__PURE__*/
|
|
49
|
-
function () {
|
|
50
|
-
/**
|
|
51
|
-
* @param {object} args
|
|
52
|
-
* @param {object} [args.filehandle] - a filehandle that implements the stat() and
|
|
53
|
-
* read() methods of the Node filehandle API https://nodejs.org/api/fs.html#fs_class_filehandle
|
|
54
|
-
* @param {object} [args.path] - path to the cram file
|
|
55
|
-
* @param {object} [args.url] - url for the cram file. also supports file:// urls for local files
|
|
56
|
-
* @param {function} [args.seqFetch] - a function with signature
|
|
57
|
-
* `(seqId, startCoordinate, endCoordinate)` that returns a promise for a string of sequence bases
|
|
58
|
-
* @param {number} [args.cacheSize] optional maximum number of CRAM records to cache. default 20,000
|
|
59
|
-
* @param {boolean} [args.checkSequenceMD5] - default true. if false, disables verifying the MD5
|
|
60
|
-
* checksum of the reference sequence underlying a slice. In some applications, this check can cause an inconvenient amount (many megabases) of sequences to be fetched.
|
|
61
|
-
*/
|
|
62
|
-
function CramFile(args) {
|
|
63
|
-
(0, _classCallCheck2.default)(this, CramFile);
|
|
64
|
-
this.file = open(args.url, args.path, args.filehandle);
|
|
65
|
-
this.validateChecksums = true;
|
|
66
|
-
this.fetchReferenceSequenceCallback = args.seqFetch;
|
|
67
|
-
this.options = {
|
|
68
|
-
checkSequenceMD5: args.checkSequenceMD5 !== false,
|
|
69
|
-
cacheSize: args.cacheSize !== undefined ? args.cacheSize : 20000
|
|
70
|
-
}; // cache of features in a slice, keyed by the
|
|
71
|
-
// slice offset. caches all of the features in a slice, or none.
|
|
72
|
-
// the cache is actually used by the slice object, it's just
|
|
73
|
-
// kept here at the level of the file
|
|
74
|
-
|
|
75
|
-
this.featureCache = new LRU({
|
|
76
|
-
maxSize: this.options.cacheSize
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
77
9
|
});
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}, {
|
|
101
|
-
key: "getDefinition",
|
|
102
|
-
value: function () {
|
|
103
|
-
var _getDefinition = (0, _asyncToGenerator2.default)(
|
|
104
|
-
/*#__PURE__*/
|
|
105
|
-
_regenerator.default.mark(function _callee() {
|
|
106
|
-
var headbytes, definition;
|
|
107
|
-
return _regenerator.default.wrap(function _callee$(_context) {
|
|
108
|
-
while (1) {
|
|
109
|
-
switch (_context.prev = _context.next) {
|
|
110
|
-
case 0:
|
|
111
|
-
headbytes = Buffer.allocUnsafe(cramFileDefinitionParser.maxLength);
|
|
112
|
-
_context.next = 3;
|
|
113
|
-
return this.file.read(headbytes, 0, cramFileDefinitionParser.maxLength, 0);
|
|
114
|
-
|
|
115
|
-
case 3:
|
|
116
|
-
definition = cramFileDefinitionParser.parser.parse(headbytes).result;
|
|
117
|
-
|
|
118
|
-
if (!(definition.majorVersion !== 2 && definition.majorVersion !== 3)) {
|
|
119
|
-
_context.next = 6;
|
|
120
|
-
break;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
throw new CramUnimplementedError("CRAM version ".concat(definition.majorVersion, " not supported"));
|
|
124
|
-
|
|
125
|
-
case 6:
|
|
126
|
-
return _context.abrupt("return", definition);
|
|
127
|
-
|
|
128
|
-
case 7:
|
|
129
|
-
case "end":
|
|
130
|
-
return _context.stop();
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}, _callee, this);
|
|
134
|
-
}));
|
|
135
|
-
|
|
136
|
-
function getDefinition() {
|
|
137
|
-
return _getDefinition.apply(this, arguments);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return getDefinition;
|
|
141
|
-
}() // memoize
|
|
142
|
-
|
|
143
|
-
}, {
|
|
144
|
-
key: "getSamHeader",
|
|
145
|
-
value: function () {
|
|
146
|
-
var _getSamHeader = (0, _asyncToGenerator2.default)(
|
|
147
|
-
/*#__PURE__*/
|
|
148
|
-
_regenerator.default.mark(function _callee2() {
|
|
149
|
-
var firstContainer, _ref, content, headerLength, textStart, text;
|
|
150
|
-
|
|
151
|
-
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
152
|
-
while (1) {
|
|
153
|
-
switch (_context2.prev = _context2.next) {
|
|
154
|
-
case 0:
|
|
155
|
-
_context2.next = 2;
|
|
156
|
-
return this.getContainerById(0);
|
|
157
|
-
|
|
158
|
-
case 2:
|
|
159
|
-
firstContainer = _context2.sent;
|
|
160
|
-
|
|
161
|
-
if (firstContainer) {
|
|
162
|
-
_context2.next = 5;
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
throw new CramMalformedError('file contains no containers');
|
|
167
|
-
|
|
168
|
-
case 5:
|
|
169
|
-
_context2.next = 7;
|
|
170
|
-
return firstContainer.getFirstBlock();
|
|
171
|
-
|
|
172
|
-
case 7:
|
|
173
|
-
_ref = _context2.sent;
|
|
174
|
-
content = _ref.content;
|
|
175
|
-
// find the end of the trailing zeros in the header text
|
|
176
|
-
headerLength = content.readInt32LE(0);
|
|
177
|
-
textStart = 4; // let textEnd = content.length - 1
|
|
178
|
-
// while (textEnd >= textStart && !content[textEnd]) textEnd -= 1
|
|
179
|
-
// trim off the trailing zeros
|
|
180
|
-
|
|
181
|
-
text = content.toString('utf8', textStart, textStart + headerLength);
|
|
182
|
-
this.header = text;
|
|
183
|
-
return _context2.abrupt("return", parseHeaderText(text));
|
|
184
|
-
|
|
185
|
-
case 14:
|
|
186
|
-
case "end":
|
|
187
|
-
return _context2.stop();
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (_) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
188
32
|
}
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
return _regenerator.default.wrap(function _callee5$(_context5) {
|
|
273
|
-
while (1) {
|
|
274
|
-
switch (_context5.prev = _context5.next) {
|
|
275
|
-
case 0:
|
|
276
|
-
_context5.next = 2;
|
|
277
|
-
return this.getSectionParsers();
|
|
278
|
-
|
|
279
|
-
case 2:
|
|
280
|
-
sectionParsers = _context5.sent;
|
|
281
|
-
position = sectionParsers.cramFileDefinition.maxLength;
|
|
282
|
-
_context5.next = 6;
|
|
283
|
-
return this.file.stat();
|
|
284
|
-
|
|
285
|
-
case 6:
|
|
286
|
-
_ref3 = _context5.sent;
|
|
287
|
-
fileSize = _ref3.size;
|
|
288
|
-
cramContainerHeader1 = sectionParsers.cramContainerHeader1; // skip with a series of reads to the proper container
|
|
289
|
-
|
|
290
|
-
i = 0;
|
|
291
|
-
|
|
292
|
-
case 10:
|
|
293
|
-
if (!(i <= containerNumber)) {
|
|
294
|
-
_context5.next = 36;
|
|
295
|
-
break;
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
var unzip_1 = require("../unzip");
|
|
43
|
+
var buffer_crc32_1 = __importDefault(require("buffer-crc32"));
|
|
44
|
+
var quick_lru_1 = __importDefault(require("quick-lru"));
|
|
45
|
+
var errors_1 = require("../errors");
|
|
46
|
+
var rans_1 = __importDefault(require("../rans"));
|
|
47
|
+
var sectionParsers_1 = require("./sectionParsers");
|
|
48
|
+
var htscodecs_1 = __importDefault(require("@jkbonfield/htscodecs"));
|
|
49
|
+
var container_1 = __importDefault(require("./container"));
|
|
50
|
+
var io_1 = require("../io");
|
|
51
|
+
var util_1 = require("./util");
|
|
52
|
+
var sam_1 = require("../sam");
|
|
53
|
+
var CramFile = /** @class */ (function () {
|
|
54
|
+
/**
|
|
55
|
+
* @param {object} args
|
|
56
|
+
* @param {object} [args.filehandle] - a filehandle that implements the stat() and
|
|
57
|
+
* read() methods of the Node filehandle API https://nodejs.org/api/fs.html#fs_class_filehandle
|
|
58
|
+
* @param {object} [args.path] - path to the cram file
|
|
59
|
+
* @param {object} [args.url] - url for the cram file. also supports file:// urls for local files
|
|
60
|
+
* @param {function} [args.seqFetch] - a function with signature
|
|
61
|
+
* `(seqId, startCoordinate, endCoordinate)` that returns a promise for a string of sequence bases
|
|
62
|
+
* @param {number} [args.cacheSize] optional maximum number of CRAM records to cache. default 20,000
|
|
63
|
+
* @param {boolean} [args.checkSequenceMD5] - default true. if false, disables verifying the MD5
|
|
64
|
+
* checksum of the reference sequence underlying a slice. In some applications, this check can cause an inconvenient amount (many megabases) of sequences to be fetched.
|
|
65
|
+
*/
|
|
66
|
+
function CramFile(args) {
|
|
67
|
+
this.file = (0, io_1.open)(args.url, args.path, args.filehandle);
|
|
68
|
+
this.validateChecksums = true;
|
|
69
|
+
this.fetchReferenceSequenceCallback = args.seqFetch;
|
|
70
|
+
this.options = {
|
|
71
|
+
checkSequenceMD5: args.checkSequenceMD5 !== false,
|
|
72
|
+
cacheSize: args.cacheSize !== undefined ? args.cacheSize : 20000,
|
|
73
|
+
};
|
|
74
|
+
// cache of features in a slice, keyed by the
|
|
75
|
+
// slice offset. caches all of the features in a slice, or none.
|
|
76
|
+
// the cache is actually used by the slice object, it's just
|
|
77
|
+
// kept here at the level of the file
|
|
78
|
+
this.featureCache = new quick_lru_1.default({
|
|
79
|
+
maxSize: this.options.cacheSize,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
CramFile.prototype.toString = function () {
|
|
83
|
+
if (this.file.filename) {
|
|
84
|
+
return this.file.filename;
|
|
85
|
+
}
|
|
86
|
+
if (this.file.url) {
|
|
87
|
+
return this.file.url;
|
|
88
|
+
}
|
|
89
|
+
return '(cram file)';
|
|
90
|
+
};
|
|
91
|
+
// can just read this object like a filehandle
|
|
92
|
+
CramFile.prototype.read = function (buffer, offset, length, position) {
|
|
93
|
+
return this.file.read(buffer, offset, length, position);
|
|
94
|
+
};
|
|
95
|
+
// can just stat this object like a filehandle
|
|
96
|
+
CramFile.prototype.stat = function () {
|
|
97
|
+
return this.file.stat();
|
|
98
|
+
};
|
|
99
|
+
// memoized
|
|
100
|
+
CramFile.prototype.getDefinition = function () {
|
|
101
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
102
|
+
var headbytes, definition;
|
|
103
|
+
return __generator(this, function (_a) {
|
|
104
|
+
switch (_a.label) {
|
|
105
|
+
case 0:
|
|
106
|
+
headbytes = Buffer.allocUnsafe(sectionParsers_1.cramFileDefinition.maxLength);
|
|
107
|
+
return [4 /*yield*/, this.file.read(headbytes, 0, sectionParsers_1.cramFileDefinition.maxLength, 0)];
|
|
108
|
+
case 1:
|
|
109
|
+
_a.sent();
|
|
110
|
+
definition = sectionParsers_1.cramFileDefinition.parser.parse(headbytes).result;
|
|
111
|
+
if (definition.majorVersion !== 2 && definition.majorVersion !== 3) {
|
|
112
|
+
throw new errors_1.CramUnimplementedError("CRAM version ".concat(definition.majorVersion, " not supported"));
|
|
113
|
+
}
|
|
114
|
+
return [2 /*return*/, definition];
|
|
296
115
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
// memoize
|
|
120
|
+
CramFile.prototype.getSamHeader = function () {
|
|
121
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
122
|
+
var firstContainer, content, headerLength, textStart, text;
|
|
123
|
+
return __generator(this, function (_a) {
|
|
124
|
+
switch (_a.label) {
|
|
125
|
+
case 0: return [4 /*yield*/, this.getContainerById(0)];
|
|
126
|
+
case 1:
|
|
127
|
+
firstContainer = _a.sent();
|
|
128
|
+
if (!firstContainer) {
|
|
129
|
+
throw new errors_1.CramMalformedError('file contains no containers');
|
|
130
|
+
}
|
|
131
|
+
return [4 /*yield*/, firstContainer.getFirstBlock()
|
|
132
|
+
// find the end of the trailing zeros in the header text
|
|
133
|
+
];
|
|
134
|
+
case 2:
|
|
135
|
+
content = (_a.sent()).content;
|
|
136
|
+
headerLength = content.readInt32LE(0);
|
|
137
|
+
textStart = 4;
|
|
138
|
+
text = content.toString('utf8', textStart, textStart + headerLength);
|
|
139
|
+
this.header = text;
|
|
140
|
+
return [2 /*return*/, (0, sam_1.parseHeaderText)(text)];
|
|
301
141
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
if (currentHeader) {
|
|
314
|
-
_context5.next = 19;
|
|
315
|
-
break;
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
};
|
|
145
|
+
CramFile.prototype.getHeaderText = function () {
|
|
146
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
147
|
+
return __generator(this, function (_a) {
|
|
148
|
+
switch (_a.label) {
|
|
149
|
+
case 0: return [4 /*yield*/, this.getSamHeader()];
|
|
150
|
+
case 1:
|
|
151
|
+
_a.sent();
|
|
152
|
+
return [2 /*return*/, this.header];
|
|
316
153
|
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
// memoize
|
|
158
|
+
CramFile.prototype.getSectionParsers = function () {
|
|
159
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
160
|
+
var majorVersion;
|
|
161
|
+
return __generator(this, function (_a) {
|
|
162
|
+
switch (_a.label) {
|
|
163
|
+
case 0: return [4 /*yield*/, this.getDefinition()];
|
|
164
|
+
case 1:
|
|
165
|
+
majorVersion = (_a.sent()).majorVersion;
|
|
166
|
+
return [2 /*return*/, (0, sectionParsers_1.getSectionParsers)(majorVersion)];
|
|
324
167
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
};
|
|
171
|
+
CramFile.prototype.getContainerById = function (containerNumber) {
|
|
172
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
173
|
+
var sectionParsers, position, fileSize, cramContainerHeader1, currentContainer, i, currentHeader, j, block;
|
|
174
|
+
return __generator(this, function (_a) {
|
|
175
|
+
switch (_a.label) {
|
|
176
|
+
case 0: return [4 /*yield*/, this.getSectionParsers()];
|
|
177
|
+
case 1:
|
|
178
|
+
sectionParsers = _a.sent();
|
|
179
|
+
position = sectionParsers.cramFileDefinition.maxLength;
|
|
180
|
+
return [4 /*yield*/, this.file.stat()];
|
|
181
|
+
case 2:
|
|
182
|
+
fileSize = (_a.sent()).size;
|
|
183
|
+
cramContainerHeader1 = sectionParsers.cramContainerHeader1;
|
|
184
|
+
i = 0;
|
|
185
|
+
_a.label = 3;
|
|
186
|
+
case 3:
|
|
187
|
+
if (!(i <= containerNumber)) return [3 /*break*/, 11];
|
|
188
|
+
// if we are about to go off the end of the file
|
|
189
|
+
// and have not found that container, it does not exist
|
|
190
|
+
if (position + cramContainerHeader1.maxLength + 8 >= fileSize) {
|
|
191
|
+
return [2 /*return*/, undefined];
|
|
192
|
+
}
|
|
193
|
+
currentContainer = this.getContainerAtPosition(position);
|
|
194
|
+
return [4 /*yield*/, currentContainer.getHeader()];
|
|
195
|
+
case 4:
|
|
196
|
+
currentHeader = _a.sent();
|
|
197
|
+
if (!currentHeader) {
|
|
198
|
+
throw new errors_1.CramMalformedError("container ".concat(containerNumber, " not found in file"));
|
|
199
|
+
}
|
|
200
|
+
if (!(i === 0)) return [3 /*break*/, 9];
|
|
201
|
+
position = currentHeader._endPosition;
|
|
202
|
+
j = 0;
|
|
203
|
+
_a.label = 5;
|
|
204
|
+
case 5:
|
|
205
|
+
if (!(j < currentHeader.numBlocks)) return [3 /*break*/, 8];
|
|
206
|
+
return [4 /*yield*/, this.readBlock(position)];
|
|
207
|
+
case 6:
|
|
208
|
+
block = _a.sent();
|
|
209
|
+
position = block._endPosition;
|
|
210
|
+
_a.label = 7;
|
|
211
|
+
case 7:
|
|
212
|
+
j += 1;
|
|
213
|
+
return [3 /*break*/, 5];
|
|
214
|
+
case 8: return [3 /*break*/, 10];
|
|
215
|
+
case 9:
|
|
216
|
+
// otherwise, just traverse to the next container using the container's length
|
|
217
|
+
position += currentHeader._size + currentHeader.length;
|
|
218
|
+
_a.label = 10;
|
|
219
|
+
case 10:
|
|
220
|
+
i += 1;
|
|
221
|
+
return [3 /*break*/, 3];
|
|
222
|
+
case 11: return [2 /*return*/, currentContainer];
|
|
333
223
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
// otherwise, just traverse to the next container using the container's length
|
|
353
|
-
position += currentHeader._size + currentHeader.length;
|
|
354
|
-
|
|
355
|
-
case 33:
|
|
356
|
-
i += 1;
|
|
357
|
-
_context5.next = 10;
|
|
358
|
-
break;
|
|
359
|
-
|
|
360
|
-
case 36:
|
|
361
|
-
return _context5.abrupt("return", currentContainer);
|
|
362
|
-
|
|
363
|
-
case 37:
|
|
364
|
-
case "end":
|
|
365
|
-
return _context5.stop();
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
}, _callee5, this);
|
|
369
|
-
}));
|
|
370
|
-
|
|
371
|
-
function getContainerById(_x) {
|
|
372
|
-
return _getContainerById.apply(this, arguments);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
return getContainerById;
|
|
376
|
-
}()
|
|
377
|
-
}, {
|
|
378
|
-
key: "checkCrc32",
|
|
379
|
-
value: function () {
|
|
380
|
-
var _checkCrc = (0, _asyncToGenerator2.default)(
|
|
381
|
-
/*#__PURE__*/
|
|
382
|
-
_regenerator.default.mark(function _callee6(position, length, recordedCrc32, description) {
|
|
383
|
-
var b, calculatedCrc32, _context6, _context7;
|
|
384
|
-
|
|
385
|
-
return _regenerator.default.wrap(function _callee6$(_context8) {
|
|
386
|
-
while (1) {
|
|
387
|
-
switch (_context8.prev = _context8.next) {
|
|
388
|
-
case 0:
|
|
389
|
-
b = Buffer.allocUnsafe(length);
|
|
390
|
-
_context8.next = 3;
|
|
391
|
-
return this.file.read(b, 0, length, position);
|
|
392
|
-
|
|
393
|
-
case 3:
|
|
394
|
-
calculatedCrc32 = crc32.unsigned(b);
|
|
395
|
-
|
|
396
|
-
if (!(calculatedCrc32 !== recordedCrc32)) {
|
|
397
|
-
_context8.next = 6;
|
|
398
|
-
break;
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
CramFile.prototype.checkCrc32 = function (position, length, recordedCrc32, description) {
|
|
228
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
229
|
+
var b, calculatedCrc32;
|
|
230
|
+
return __generator(this, function (_a) {
|
|
231
|
+
switch (_a.label) {
|
|
232
|
+
case 0:
|
|
233
|
+
b = Buffer.allocUnsafe(length);
|
|
234
|
+
return [4 /*yield*/, this.file.read(b, 0, length, position)];
|
|
235
|
+
case 1:
|
|
236
|
+
_a.sent();
|
|
237
|
+
calculatedCrc32 = buffer_crc32_1.default.unsigned(b);
|
|
238
|
+
if (calculatedCrc32 !== recordedCrc32) {
|
|
239
|
+
throw new errors_1.CramMalformedError("crc mismatch in ".concat(description, ": recorded CRC32 = ").concat(recordedCrc32, ", but calculated CRC32 = ").concat(calculatedCrc32));
|
|
240
|
+
}
|
|
241
|
+
return [2 /*return*/];
|
|
399
242
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
case 6:
|
|
404
|
-
case "end":
|
|
405
|
-
return _context8.stop();
|
|
406
|
-
}
|
|
407
|
-
}
|
|
408
|
-
}, _callee6, this);
|
|
409
|
-
}));
|
|
410
|
-
|
|
411
|
-
function checkCrc32(_x2, _x3, _x4, _x5) {
|
|
412
|
-
return _checkCrc.apply(this, arguments);
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
return checkCrc32;
|
|
416
|
-
}()
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
};
|
|
417
246
|
/**
|
|
418
247
|
* @returns {Promise[number]} the number of containers in the file
|
|
419
248
|
*/
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
249
|
+
CramFile.prototype.containerCount = function () {
|
|
250
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
251
|
+
var sectionParsers, fileSize, cramContainerHeader1, containerCount, position, currentHeader, j, block;
|
|
252
|
+
return __generator(this, function (_a) {
|
|
253
|
+
switch (_a.label) {
|
|
254
|
+
case 0: return [4 /*yield*/, this.getSectionParsers()];
|
|
255
|
+
case 1:
|
|
256
|
+
sectionParsers = _a.sent();
|
|
257
|
+
return [4 /*yield*/, this.file.stat()];
|
|
258
|
+
case 2:
|
|
259
|
+
fileSize = (_a.sent()).size;
|
|
260
|
+
cramContainerHeader1 = sectionParsers.cramContainerHeader1;
|
|
261
|
+
containerCount = 0;
|
|
262
|
+
position = sectionParsers.cramFileDefinition.maxLength;
|
|
263
|
+
_a.label = 3;
|
|
264
|
+
case 3:
|
|
265
|
+
if (!(position + cramContainerHeader1.maxLength + 8 < fileSize)) return [3 /*break*/, 11];
|
|
266
|
+
return [4 /*yield*/, this.getContainerAtPosition(position).getHeader()];
|
|
267
|
+
case 4:
|
|
268
|
+
currentHeader = _a.sent();
|
|
269
|
+
if (!currentHeader) {
|
|
270
|
+
return [3 /*break*/, 11];
|
|
271
|
+
}
|
|
272
|
+
if (!(containerCount === 0)) return [3 /*break*/, 9];
|
|
273
|
+
position = currentHeader._endPosition;
|
|
274
|
+
j = 0;
|
|
275
|
+
_a.label = 5;
|
|
276
|
+
case 5:
|
|
277
|
+
if (!(j < currentHeader.numBlocks)) return [3 /*break*/, 8];
|
|
278
|
+
return [4 /*yield*/, this.readBlock(position)];
|
|
279
|
+
case 6:
|
|
280
|
+
block = _a.sent();
|
|
281
|
+
position = block._endPosition;
|
|
282
|
+
_a.label = 7;
|
|
283
|
+
case 7:
|
|
284
|
+
j += 1;
|
|
285
|
+
return [3 /*break*/, 5];
|
|
286
|
+
case 8: return [3 /*break*/, 10];
|
|
287
|
+
case 9:
|
|
288
|
+
// otherwise, just traverse to the next container using the container's length
|
|
289
|
+
position += currentHeader._size + currentHeader.length;
|
|
290
|
+
_a.label = 10;
|
|
291
|
+
case 10:
|
|
292
|
+
containerCount += 1;
|
|
293
|
+
return [3 /*break*/, 3];
|
|
294
|
+
case 11: return [2 /*return*/, containerCount];
|
|
452
295
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
};
|
|
299
|
+
CramFile.prototype.getContainerAtPosition = function (position) {
|
|
300
|
+
return new container_1.default(this, position);
|
|
301
|
+
};
|
|
302
|
+
CramFile.prototype.readBlockHeader = function (position) {
|
|
303
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
304
|
+
var sectionParsers, cramBlockHeader, fileSize, buffer;
|
|
305
|
+
return __generator(this, function (_a) {
|
|
306
|
+
switch (_a.label) {
|
|
307
|
+
case 0: return [4 /*yield*/, this.getSectionParsers()];
|
|
308
|
+
case 1:
|
|
309
|
+
sectionParsers = _a.sent();
|
|
310
|
+
cramBlockHeader = sectionParsers.cramBlockHeader;
|
|
311
|
+
return [4 /*yield*/, this.file.stat()];
|
|
312
|
+
case 2:
|
|
313
|
+
fileSize = (_a.sent()).size;
|
|
314
|
+
if (position + cramBlockHeader.maxLength >= fileSize) {
|
|
315
|
+
return [2 /*return*/, undefined];
|
|
316
|
+
}
|
|
317
|
+
buffer = Buffer.allocUnsafe(cramBlockHeader.maxLength);
|
|
318
|
+
return [4 /*yield*/, this.file.read(buffer, 0, cramBlockHeader.maxLength, position)];
|
|
319
|
+
case 3:
|
|
320
|
+
_a.sent();
|
|
321
|
+
return [2 /*return*/, (0, util_1.parseItem)(buffer, cramBlockHeader.parser, 0, position)];
|
|
463
322
|
}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
};
|
|
326
|
+
CramFile.prototype._parseSection = function (section, position, size, preReadBuffer) {
|
|
327
|
+
if (size === void 0) { size = section.maxLength; }
|
|
328
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
329
|
+
var buffer, fileSize, data;
|
|
330
|
+
return __generator(this, function (_a) {
|
|
331
|
+
switch (_a.label) {
|
|
332
|
+
case 0:
|
|
333
|
+
if (!preReadBuffer) return [3 /*break*/, 1];
|
|
334
|
+
buffer = preReadBuffer;
|
|
335
|
+
return [3 /*break*/, 4];
|
|
336
|
+
case 1: return [4 /*yield*/, this.file.stat()];
|
|
337
|
+
case 2:
|
|
338
|
+
fileSize = (_a.sent()).size;
|
|
339
|
+
if (position + size >= fileSize) {
|
|
340
|
+
return [2 /*return*/, undefined];
|
|
341
|
+
}
|
|
342
|
+
buffer = Buffer.allocUnsafe(size);
|
|
343
|
+
return [4 /*yield*/, this.file.read(buffer, 0, size, position)];
|
|
344
|
+
case 3:
|
|
345
|
+
_a.sent();
|
|
346
|
+
_a.label = 4;
|
|
347
|
+
case 4:
|
|
348
|
+
data = (0, util_1.parseItem)(buffer, section.parser, 0, position);
|
|
349
|
+
if (data._size !== size) {
|
|
350
|
+
throw new errors_1.CramMalformedError("section read error: requested size ".concat(size, " does not equal parsed size ").concat(data._size));
|
|
351
|
+
}
|
|
352
|
+
return [2 /*return*/, data];
|
|
471
353
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
};
|
|
357
|
+
CramFile.prototype._uncompress = function (compressionMethod, inputBuffer, outputBuffer) {
|
|
358
|
+
if (compressionMethod === 'gzip') {
|
|
359
|
+
var result = (0, unzip_1.unzip)(inputBuffer);
|
|
360
|
+
result.copy(outputBuffer);
|
|
361
|
+
}
|
|
362
|
+
else if (compressionMethod === 'bzip2') {
|
|
363
|
+
var bits = bzip2.array(inputBuffer);
|
|
364
|
+
var size = bzip2.header(bits);
|
|
365
|
+
var j = 0;
|
|
366
|
+
do {
|
|
367
|
+
var chunk = bzip2.decompress(bits, size);
|
|
368
|
+
if (chunk != -1) {
|
|
369
|
+
Buffer.from(chunk).copy(outputBuffer, j);
|
|
370
|
+
j += chunk.length;
|
|
371
|
+
size -= chunk.length;
|
|
480
372
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
_context10.next = 10;
|
|
556
|
-
break;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
return _context10.abrupt("return", undefined);
|
|
560
|
-
|
|
561
|
-
case 10:
|
|
562
|
-
buffer = Buffer.allocUnsafe(cramBlockHeader.maxLength);
|
|
563
|
-
_context10.next = 13;
|
|
564
|
-
return this.file.read(buffer, 0, cramBlockHeader.maxLength, position);
|
|
565
|
-
|
|
566
|
-
case 13:
|
|
567
|
-
return _context10.abrupt("return", parseItem(buffer, cramBlockHeader.parser, 0, position));
|
|
568
|
-
|
|
569
|
-
case 14:
|
|
570
|
-
case "end":
|
|
571
|
-
return _context10.stop();
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
}, _callee8, this);
|
|
575
|
-
}));
|
|
576
|
-
|
|
577
|
-
function readBlockHeader(_x6) {
|
|
578
|
-
return _readBlockHeader.apply(this, arguments);
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
return readBlockHeader;
|
|
582
|
-
}()
|
|
583
|
-
}, {
|
|
584
|
-
key: "_parseSection",
|
|
585
|
-
value: function () {
|
|
586
|
-
var _parseSection2 = (0, _asyncToGenerator2.default)(
|
|
587
|
-
/*#__PURE__*/
|
|
588
|
-
_regenerator.default.mark(function _callee9(section, position) {
|
|
589
|
-
var _context11;
|
|
590
|
-
|
|
591
|
-
var size,
|
|
592
|
-
preReadBuffer,
|
|
593
|
-
buffer,
|
|
594
|
-
_ref6,
|
|
595
|
-
fileSize,
|
|
596
|
-
data,
|
|
597
|
-
_args9 = arguments;
|
|
598
|
-
|
|
599
|
-
return _regenerator.default.wrap(function _callee9$(_context12) {
|
|
600
|
-
while (1) {
|
|
601
|
-
switch (_context12.prev = _context12.next) {
|
|
602
|
-
case 0:
|
|
603
|
-
size = _args9.length > 2 && _args9[2] !== undefined ? _args9[2] : section.maxLength;
|
|
604
|
-
preReadBuffer = _args9.length > 3 ? _args9[3] : undefined;
|
|
605
|
-
|
|
606
|
-
if (!preReadBuffer) {
|
|
607
|
-
_context12.next = 6;
|
|
608
|
-
break;
|
|
373
|
+
} while (chunk != -1);
|
|
374
|
+
}
|
|
375
|
+
else if (compressionMethod === 'rans') {
|
|
376
|
+
(0, rans_1.default)(inputBuffer, outputBuffer);
|
|
377
|
+
//htscodecs r4x8 is slower, but compatible.
|
|
378
|
+
//htscodecs.r4x8_uncompress(inputBuffer, outputBuffer);
|
|
379
|
+
}
|
|
380
|
+
else if (compressionMethod === 'rans4x16') {
|
|
381
|
+
htscodecs_1.default.r4x16_uncompress(inputBuffer, outputBuffer);
|
|
382
|
+
}
|
|
383
|
+
else if (compressionMethod === 'arith') {
|
|
384
|
+
htscodecs_1.default.arith_uncompress(inputBuffer, outputBuffer);
|
|
385
|
+
}
|
|
386
|
+
else if (compressionMethod === 'fqzcomp') {
|
|
387
|
+
htscodecs_1.default.fqzcomp_uncompress(inputBuffer, outputBuffer);
|
|
388
|
+
}
|
|
389
|
+
else if (compressionMethod === 'tok3') {
|
|
390
|
+
htscodecs_1.default.tok3_uncompress(inputBuffer, outputBuffer);
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
throw new errors_1.CramUnimplementedError("".concat(compressionMethod, " decompression not yet implemented"));
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
CramFile.prototype.readBlock = function (position) {
|
|
397
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
398
|
+
var majorVersion, sectionParsers, block, blockContentPosition, uncompressedData, compressedData, crc;
|
|
399
|
+
return __generator(this, function (_a) {
|
|
400
|
+
switch (_a.label) {
|
|
401
|
+
case 0: return [4 /*yield*/, this.getDefinition()];
|
|
402
|
+
case 1:
|
|
403
|
+
majorVersion = (_a.sent()).majorVersion;
|
|
404
|
+
return [4 /*yield*/, this.getSectionParsers()];
|
|
405
|
+
case 2:
|
|
406
|
+
sectionParsers = _a.sent();
|
|
407
|
+
return [4 /*yield*/, this.readBlockHeader(position)];
|
|
408
|
+
case 3:
|
|
409
|
+
block = _a.sent();
|
|
410
|
+
blockContentPosition = block._endPosition;
|
|
411
|
+
block.contentPosition = block._endPosition;
|
|
412
|
+
uncompressedData = Buffer.allocUnsafe(block.uncompressedSize);
|
|
413
|
+
if (!(block.compressionMethod !== 'raw')) return [3 /*break*/, 5];
|
|
414
|
+
compressedData = Buffer.allocUnsafe(block.compressedSize);
|
|
415
|
+
return [4 /*yield*/, this.read(compressedData, 0, block.compressedSize, blockContentPosition)];
|
|
416
|
+
case 4:
|
|
417
|
+
_a.sent();
|
|
418
|
+
this._uncompress(block.compressionMethod, compressedData, uncompressedData);
|
|
419
|
+
return [3 /*break*/, 7];
|
|
420
|
+
case 5: return [4 /*yield*/, this.read(uncompressedData, 0, block.uncompressedSize, blockContentPosition)];
|
|
421
|
+
case 6:
|
|
422
|
+
_a.sent();
|
|
423
|
+
_a.label = 7;
|
|
424
|
+
case 7:
|
|
425
|
+
block.content = uncompressedData;
|
|
426
|
+
if (!(majorVersion >= 3)) return [3 /*break*/, 11];
|
|
427
|
+
return [4 /*yield*/, this._parseSection(sectionParsers.cramBlockCrc32, blockContentPosition + block.compressedSize)];
|
|
428
|
+
case 8:
|
|
429
|
+
crc = _a.sent();
|
|
430
|
+
block.crc32 = crc.crc32;
|
|
431
|
+
if (!this.validateChecksums) return [3 /*break*/, 10];
|
|
432
|
+
return [4 /*yield*/, this.checkCrc32(position, block._size + block.compressedSize, block.crc32, 'block data')];
|
|
433
|
+
case 9:
|
|
434
|
+
_a.sent();
|
|
435
|
+
_a.label = 10;
|
|
436
|
+
case 10:
|
|
437
|
+
// make the endposition and size reflect the whole block
|
|
438
|
+
block._endPosition = crc._endPosition;
|
|
439
|
+
block._size =
|
|
440
|
+
block.compressedSize + sectionParsers.cramBlockCrc32.maxLength;
|
|
441
|
+
return [3 /*break*/, 12];
|
|
442
|
+
case 11:
|
|
443
|
+
block._endPosition = blockContentPosition + block.compressedSize;
|
|
444
|
+
block._size = block.compressedSize;
|
|
445
|
+
_a.label = 12;
|
|
446
|
+
case 12: return [2 /*return*/, block];
|
|
609
447
|
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
_ref6 = _context12.sent;
|
|
621
|
-
fileSize = _ref6.size;
|
|
622
|
-
|
|
623
|
-
if (!(position + size >= fileSize)) {
|
|
624
|
-
_context12.next = 12;
|
|
625
|
-
break;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
return _context12.abrupt("return", undefined);
|
|
629
|
-
|
|
630
|
-
case 12:
|
|
631
|
-
buffer = Buffer.allocUnsafe(size);
|
|
632
|
-
_context12.next = 15;
|
|
633
|
-
return this.file.read(buffer, 0, size, position);
|
|
634
|
-
|
|
635
|
-
case 15:
|
|
636
|
-
data = parseItem(buffer, section.parser, 0, position);
|
|
637
|
-
|
|
638
|
-
if (!(data._size !== size)) {
|
|
639
|
-
_context12.next = 18;
|
|
640
|
-
break;
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
throw new CramMalformedError((0, _concat.default)(_context11 = "section read error: requested size ".concat(size, " does not equal parsed size ")).call(_context11, data._size));
|
|
644
|
-
|
|
645
|
-
case 18:
|
|
646
|
-
return _context12.abrupt("return", data);
|
|
647
|
-
|
|
648
|
-
case 19:
|
|
649
|
-
case "end":
|
|
650
|
-
return _context12.stop();
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
}, _callee9, this);
|
|
654
|
-
}));
|
|
655
|
-
|
|
656
|
-
function _parseSection(_x7, _x8) {
|
|
657
|
-
return _parseSection2.apply(this, arguments);
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
return _parseSection;
|
|
661
|
-
}()
|
|
662
|
-
}, {
|
|
663
|
-
key: "_uncompress",
|
|
664
|
-
value: function _uncompress(compressionMethod, inputBuffer, outputBuffer) {
|
|
665
|
-
if (compressionMethod === 'gzip') {
|
|
666
|
-
var result = zlib.gunzipSync(inputBuffer);
|
|
667
|
-
result.copy(outputBuffer);
|
|
668
|
-
} else if (compressionMethod === 'rans') {
|
|
669
|
-
rans.uncompress(inputBuffer, outputBuffer);
|
|
670
|
-
} else {
|
|
671
|
-
throw new CramUnimplementedError("".concat(compressionMethod, " decompression not yet implemented"));
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
}, {
|
|
675
|
-
key: "readBlock",
|
|
676
|
-
value: function () {
|
|
677
|
-
var _readBlock = (0, _asyncToGenerator2.default)(
|
|
678
|
-
/*#__PURE__*/
|
|
679
|
-
_regenerator.default.mark(function _callee10(position) {
|
|
680
|
-
var _ref7, majorVersion, sectionParsers, block, blockContentPosition, uncompressedData, compressedData, crc;
|
|
681
|
-
|
|
682
|
-
return _regenerator.default.wrap(function _callee10$(_context13) {
|
|
683
|
-
while (1) {
|
|
684
|
-
switch (_context13.prev = _context13.next) {
|
|
685
|
-
case 0:
|
|
686
|
-
_context13.next = 2;
|
|
687
|
-
return this.getDefinition();
|
|
688
|
-
|
|
689
|
-
case 2:
|
|
690
|
-
_ref7 = _context13.sent;
|
|
691
|
-
majorVersion = _ref7.majorVersion;
|
|
692
|
-
_context13.next = 6;
|
|
693
|
-
return this.getSectionParsers();
|
|
694
|
-
|
|
695
|
-
case 6:
|
|
696
|
-
sectionParsers = _context13.sent;
|
|
697
|
-
_context13.next = 9;
|
|
698
|
-
return this.readBlockHeader(position);
|
|
699
|
-
|
|
700
|
-
case 9:
|
|
701
|
-
block = _context13.sent;
|
|
702
|
-
blockContentPosition = block._endPosition;
|
|
703
|
-
block.contentPosition = block._endPosition;
|
|
704
|
-
uncompressedData = Buffer.allocUnsafe(block.uncompressedSize);
|
|
705
|
-
|
|
706
|
-
if (!(block.compressionMethod !== 'raw')) {
|
|
707
|
-
_context13.next = 20;
|
|
708
|
-
break;
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
compressedData = Buffer.allocUnsafe(block.compressedSize);
|
|
712
|
-
_context13.next = 17;
|
|
713
|
-
return this.read(compressedData, 0, block.compressedSize, blockContentPosition);
|
|
714
|
-
|
|
715
|
-
case 17:
|
|
716
|
-
this._uncompress(block.compressionMethod, compressedData, uncompressedData);
|
|
717
|
-
|
|
718
|
-
_context13.next = 22;
|
|
719
|
-
break;
|
|
720
|
-
|
|
721
|
-
case 20:
|
|
722
|
-
_context13.next = 22;
|
|
723
|
-
return this.read(uncompressedData, 0, block.uncompressedSize, blockContentPosition);
|
|
724
|
-
|
|
725
|
-
case 22:
|
|
726
|
-
block.content = uncompressedData;
|
|
727
|
-
|
|
728
|
-
if (!(majorVersion >= 3)) {
|
|
729
|
-
_context13.next = 35;
|
|
730
|
-
break;
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
_context13.next = 26;
|
|
734
|
-
return this._parseSection(sectionParsers.cramBlockCrc32, blockContentPosition + block.compressedSize);
|
|
735
|
-
|
|
736
|
-
case 26:
|
|
737
|
-
crc = _context13.sent;
|
|
738
|
-
block.crc32 = crc.crc32; // check the block data crc32
|
|
739
|
-
|
|
740
|
-
if (!this.validateChecksums) {
|
|
741
|
-
_context13.next = 31;
|
|
742
|
-
break;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
_context13.next = 31;
|
|
746
|
-
return this.checkCrc32(position, block._size + block.compressedSize, block.crc32, 'block data');
|
|
747
|
-
|
|
748
|
-
case 31:
|
|
749
|
-
// make the endposition and size reflect the whole block
|
|
750
|
-
block._endPosition = crc._endPosition;
|
|
751
|
-
block._size = block.compressedSize + sectionParsers.cramBlockCrc32.maxLength;
|
|
752
|
-
_context13.next = 37;
|
|
753
|
-
break;
|
|
754
|
-
|
|
755
|
-
case 35:
|
|
756
|
-
block._endPosition = blockContentPosition + block.compressedSize;
|
|
757
|
-
block._size = block.compressedSize;
|
|
758
|
-
|
|
759
|
-
case 37:
|
|
760
|
-
return _context13.abrupt("return", block);
|
|
761
|
-
|
|
762
|
-
case 38:
|
|
763
|
-
case "end":
|
|
764
|
-
return _context13.stop();
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
}, _callee10, this);
|
|
768
|
-
}));
|
|
769
|
-
|
|
770
|
-
function readBlock(_x9) {
|
|
771
|
-
return _readBlock.apply(this, arguments);
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
return readBlock;
|
|
775
|
-
}()
|
|
776
|
-
}]);
|
|
777
|
-
return CramFile;
|
|
778
|
-
}();
|
|
779
|
-
|
|
780
|
-
(0, _forEach.default)(_context14 = 'getDefinition getSectionParsers getSamHeader'.split(' ')).call(_context14, function (method) {
|
|
781
|
-
return tinyMemoize(CramFile, method);
|
|
782
|
-
});
|
|
783
|
-
module.exports = CramFile;
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
};
|
|
451
|
+
return CramFile;
|
|
452
|
+
}());
|
|
453
|
+
exports.default = CramFile;
|
|
454
|
+
'getDefinition getSectionParsers getSamHeader'
|
|
455
|
+
.split(' ')
|
|
456
|
+
.forEach(function (method) { return (0, util_1.tinyMemoize)(CramFile, method); });
|
|
457
|
+
//# sourceMappingURL=file.js.map
|