@gmod/bam 1.1.16 → 1.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -3
- package/README.md +15 -2
- package/dist/bai.js +164 -253
- package/dist/bai.js.map +1 -1
- package/dist/bamFile.js +331 -556
- package/dist/bamFile.js.map +1 -1
- package/dist/chunk.js +12 -14
- package/dist/chunk.js.map +1 -1
- package/dist/csi.d.ts +2 -2
- package/dist/csi.js +147 -237
- package/dist/csi.js.map +1 -1
- package/dist/errors.js +12 -57
- package/dist/errors.js.map +1 -1
- package/dist/htsget.js +92 -206
- package/dist/htsget.js.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/indexFile.js +20 -59
- package/dist/indexFile.js.map +1 -1
- package/dist/record.js +169 -172
- package/dist/record.js.map +1 -1
- package/dist/sam.js +7 -7
- package/dist/sam.js.map +1 -1
- package/dist/util.js +11 -46
- package/dist/util.js.map +1 -1
- package/dist/virtualOffset.js +13 -20
- package/dist/virtualOffset.js.map +1 -1
- package/esm/csi.d.ts +2 -2
- package/esm/csi.js +3 -6
- package/esm/csi.js.map +1 -1
- package/package.json +16 -16
- package/src/csi.ts +4 -7
package/dist/record.js
CHANGED
|
@@ -4,19 +4,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const constants_1 = __importDefault(require("./constants"));
|
|
8
|
+
const SEQRET_DECODER = '=ACMGRSVTWYHKDBN'.split('');
|
|
9
|
+
const CIGAR_DECODER = 'MIDNSHP=X???????'.split('');
|
|
10
10
|
/**
|
|
11
11
|
* Class of each BAM record returned by this API.
|
|
12
12
|
*/
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
class BamRecord {
|
|
14
|
+
constructor(args) {
|
|
15
15
|
this.data = {};
|
|
16
16
|
this._tagList = [];
|
|
17
17
|
this._allTagsParsed = false;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const { bytes, fileOffset } = args;
|
|
19
|
+
const { byteArray, start } = bytes;
|
|
20
20
|
this.data = {};
|
|
21
21
|
this.bytes = bytes;
|
|
22
22
|
this._id = fileOffset;
|
|
@@ -24,7 +24,7 @@ var BamRecord = /** @class */ (function () {
|
|
|
24
24
|
this.data.start = byteArray.readInt32LE(start + 8);
|
|
25
25
|
this.flags = (byteArray.readInt32LE(start + 16) & 0xffff0000) >> 16;
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
get(field) {
|
|
28
28
|
//@ts-ignore
|
|
29
29
|
if (this[field]) {
|
|
30
30
|
//@ts-ignore
|
|
@@ -36,26 +36,25 @@ var BamRecord = /** @class */ (function () {
|
|
|
36
36
|
return this.data[field];
|
|
37
37
|
}
|
|
38
38
|
return this._get(field.toLowerCase());
|
|
39
|
-
}
|
|
40
|
-
|
|
39
|
+
}
|
|
40
|
+
end() {
|
|
41
41
|
return this.get('start') + this.get('length_on_ref');
|
|
42
|
-
}
|
|
43
|
-
|
|
42
|
+
}
|
|
43
|
+
seq_id() {
|
|
44
44
|
return this._refID;
|
|
45
|
-
}
|
|
45
|
+
}
|
|
46
46
|
// same as get(), except requires lower-case arguments. used
|
|
47
47
|
// internally to save lots of calls to field.toLowerCase()
|
|
48
|
-
|
|
48
|
+
_get(field) {
|
|
49
49
|
if (field in this.data) {
|
|
50
50
|
return this.data[field];
|
|
51
51
|
}
|
|
52
52
|
this.data[field] = this._parseTag(field);
|
|
53
53
|
return this.data[field];
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
var _this = this;
|
|
54
|
+
}
|
|
55
|
+
_tags() {
|
|
57
56
|
this._parseAllTags();
|
|
58
|
-
|
|
57
|
+
let tags = ['seq'];
|
|
59
58
|
if (!this.isSegmentUnmapped()) {
|
|
60
59
|
tags.push('start', 'end', 'strand', 'score', 'qual', 'MQ', 'CIGAR', 'length_on_ref', 'template_length');
|
|
61
60
|
}
|
|
@@ -63,105 +62,105 @@ var BamRecord = /** @class */ (function () {
|
|
|
63
62
|
tags.push('next_segment_position', 'pair_orientation');
|
|
64
63
|
}
|
|
65
64
|
tags = tags.concat(this._tagList || []);
|
|
66
|
-
Object.keys(this.data).forEach(
|
|
65
|
+
Object.keys(this.data).forEach(k => {
|
|
67
66
|
if (k[0] !== '_' && k !== 'next_seq_id') {
|
|
68
67
|
tags.push(k);
|
|
69
68
|
}
|
|
70
69
|
});
|
|
71
|
-
|
|
72
|
-
return tags.filter(
|
|
73
|
-
if ((t in
|
|
70
|
+
const seen = {};
|
|
71
|
+
return tags.filter(t => {
|
|
72
|
+
if ((t in this.data && this.data[t] === undefined) ||
|
|
74
73
|
t === 'CG' ||
|
|
75
74
|
t === 'cg') {
|
|
76
75
|
return false;
|
|
77
76
|
}
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
const lt = t.toLowerCase();
|
|
78
|
+
const s = seen[lt];
|
|
80
79
|
seen[lt] = true;
|
|
81
80
|
return !s;
|
|
82
81
|
});
|
|
83
|
-
}
|
|
84
|
-
|
|
82
|
+
}
|
|
83
|
+
parent() {
|
|
85
84
|
return undefined;
|
|
86
|
-
}
|
|
87
|
-
|
|
85
|
+
}
|
|
86
|
+
children() {
|
|
88
87
|
return this.get('subfeatures');
|
|
89
|
-
}
|
|
90
|
-
|
|
88
|
+
}
|
|
89
|
+
id() {
|
|
91
90
|
return this._id;
|
|
92
|
-
}
|
|
91
|
+
}
|
|
93
92
|
// special parsers
|
|
94
93
|
/**
|
|
95
94
|
* Mapping quality score.
|
|
96
95
|
*/
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
mq() {
|
|
97
|
+
const mq = (this.get('_bin_mq_nl') & 0xff00) >> 8;
|
|
99
98
|
return mq === 255 ? undefined : mq;
|
|
100
|
-
}
|
|
101
|
-
|
|
99
|
+
}
|
|
100
|
+
score() {
|
|
102
101
|
return this.get('mq');
|
|
103
|
-
}
|
|
104
|
-
|
|
102
|
+
}
|
|
103
|
+
qual() {
|
|
105
104
|
var _a;
|
|
106
105
|
return (_a = this.qualRaw()) === null || _a === void 0 ? void 0 : _a.join(' ');
|
|
107
|
-
}
|
|
108
|
-
|
|
106
|
+
}
|
|
107
|
+
qualRaw() {
|
|
109
108
|
if (this.isSegmentUnmapped()) {
|
|
110
109
|
return undefined;
|
|
111
110
|
}
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
const { start, byteArray } = this.bytes;
|
|
112
|
+
const p = start +
|
|
114
113
|
36 +
|
|
115
114
|
this.get('_l_read_name') +
|
|
116
115
|
this.get('_n_cigar_op') * 4 +
|
|
117
116
|
this.get('_seq_bytes');
|
|
118
|
-
|
|
117
|
+
const lseq = this.get('seq_length');
|
|
119
118
|
return byteArray.subarray(p, p + lseq);
|
|
120
|
-
}
|
|
121
|
-
|
|
119
|
+
}
|
|
120
|
+
strand() {
|
|
122
121
|
return this.isReverseComplemented() ? -1 : 1;
|
|
123
|
-
}
|
|
124
|
-
|
|
122
|
+
}
|
|
123
|
+
multi_segment_next_segment_strand() {
|
|
125
124
|
if (this.isMateUnmapped()) {
|
|
126
125
|
return undefined;
|
|
127
126
|
}
|
|
128
127
|
return this.isMateReverseComplemented() ? -1 : 1;
|
|
129
|
-
}
|
|
130
|
-
|
|
128
|
+
}
|
|
129
|
+
name() {
|
|
131
130
|
return this.get('_read_name');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
}
|
|
132
|
+
_read_name() {
|
|
133
|
+
const nl = this.get('_l_read_name');
|
|
134
|
+
const { byteArray, start } = this.bytes;
|
|
136
135
|
return byteArray.toString('ascii', start + 36, start + 36 + nl - 1);
|
|
137
|
-
}
|
|
136
|
+
}
|
|
138
137
|
/**
|
|
139
138
|
* Get the value of a tag, parsing the tags as far as necessary.
|
|
140
139
|
* Only called if we have not already parsed that field.
|
|
141
140
|
*/
|
|
142
|
-
|
|
141
|
+
_parseTag(tagName) {
|
|
143
142
|
// if all of the tags have been parsed and we're still being
|
|
144
143
|
// called, we already know that we have no such tag, because
|
|
145
144
|
// it would already have been cached.
|
|
146
145
|
if (this._allTagsParsed) {
|
|
147
146
|
return undefined;
|
|
148
147
|
}
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
const { byteArray, start } = this.bytes;
|
|
149
|
+
let p = this._tagOffset ||
|
|
151
150
|
start +
|
|
152
151
|
36 +
|
|
153
152
|
this.get('_l_read_name') +
|
|
154
153
|
this.get('_n_cigar_op') * 4 +
|
|
155
154
|
this.get('_seq_bytes') +
|
|
156
155
|
this.get('seq_length');
|
|
157
|
-
|
|
158
|
-
|
|
156
|
+
const blockEnd = this.bytes.end;
|
|
157
|
+
let lcTag;
|
|
159
158
|
while (p < blockEnd && lcTag !== tagName) {
|
|
160
|
-
|
|
159
|
+
const tag = String.fromCharCode(byteArray[p], byteArray[p + 1]);
|
|
161
160
|
lcTag = tag.toLowerCase();
|
|
162
|
-
|
|
161
|
+
const type = String.fromCharCode(byteArray[p + 2]);
|
|
163
162
|
p += 3;
|
|
164
|
-
|
|
163
|
+
let value;
|
|
165
164
|
switch (type) {
|
|
166
165
|
case 'A':
|
|
167
166
|
value = String.fromCharCode(byteArray[p]);
|
|
@@ -199,7 +198,7 @@ var BamRecord = /** @class */ (function () {
|
|
|
199
198
|
case 'H':
|
|
200
199
|
value = '';
|
|
201
200
|
while (p <= blockEnd) {
|
|
202
|
-
|
|
201
|
+
const cc = byteArray[p++];
|
|
203
202
|
if (cc === 0) {
|
|
204
203
|
break;
|
|
205
204
|
}
|
|
@@ -210,22 +209,22 @@ var BamRecord = /** @class */ (function () {
|
|
|
210
209
|
break;
|
|
211
210
|
case 'B': {
|
|
212
211
|
value = '';
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
212
|
+
const cc = byteArray[p++];
|
|
213
|
+
const Btype = String.fromCharCode(cc);
|
|
214
|
+
const limit = byteArray.readInt32LE(p);
|
|
216
215
|
p += 4;
|
|
217
216
|
if (Btype === 'i') {
|
|
218
217
|
if (tag === 'CG') {
|
|
219
|
-
for (
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
218
|
+
for (let k = 0; k < limit; k++) {
|
|
219
|
+
const cigop = byteArray.readInt32LE(p);
|
|
220
|
+
const lop = cigop >> 4;
|
|
221
|
+
const op = CIGAR_DECODER[cigop & 0xf];
|
|
223
222
|
value += lop + op;
|
|
224
223
|
p += 4;
|
|
225
224
|
}
|
|
226
225
|
}
|
|
227
226
|
else {
|
|
228
|
-
for (
|
|
227
|
+
for (let k = 0; k < limit; k++) {
|
|
229
228
|
value += byteArray.readInt32LE(p);
|
|
230
229
|
if (k + 1 < limit) {
|
|
231
230
|
value += ',';
|
|
@@ -236,16 +235,16 @@ var BamRecord = /** @class */ (function () {
|
|
|
236
235
|
}
|
|
237
236
|
if (Btype === 'I') {
|
|
238
237
|
if (tag === 'CG') {
|
|
239
|
-
for (
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
238
|
+
for (let k = 0; k < limit; k++) {
|
|
239
|
+
const cigop = byteArray.readUInt32LE(p);
|
|
240
|
+
const lop = cigop >> 4;
|
|
241
|
+
const op = CIGAR_DECODER[cigop & 0xf];
|
|
243
242
|
value += lop + op;
|
|
244
243
|
p += 4;
|
|
245
244
|
}
|
|
246
245
|
}
|
|
247
246
|
else {
|
|
248
|
-
for (
|
|
247
|
+
for (let k = 0; k < limit; k++) {
|
|
249
248
|
value += byteArray.readUInt32LE(p);
|
|
250
249
|
if (k + 1 < limit) {
|
|
251
250
|
value += ',';
|
|
@@ -255,7 +254,7 @@ var BamRecord = /** @class */ (function () {
|
|
|
255
254
|
}
|
|
256
255
|
}
|
|
257
256
|
if (Btype === 's') {
|
|
258
|
-
for (
|
|
257
|
+
for (let k = 0; k < limit; k++) {
|
|
259
258
|
value += byteArray.readInt16LE(p);
|
|
260
259
|
if (k + 1 < limit) {
|
|
261
260
|
value += ',';
|
|
@@ -264,7 +263,7 @@ var BamRecord = /** @class */ (function () {
|
|
|
264
263
|
}
|
|
265
264
|
}
|
|
266
265
|
if (Btype === 'S') {
|
|
267
|
-
for (
|
|
266
|
+
for (let k = 0; k < limit; k++) {
|
|
268
267
|
value += byteArray.readUInt16LE(p);
|
|
269
268
|
if (k + 1 < limit) {
|
|
270
269
|
value += ',';
|
|
@@ -273,7 +272,7 @@ var BamRecord = /** @class */ (function () {
|
|
|
273
272
|
}
|
|
274
273
|
}
|
|
275
274
|
if (Btype === 'c') {
|
|
276
|
-
for (
|
|
275
|
+
for (let k = 0; k < limit; k++) {
|
|
277
276
|
value += byteArray.readInt8(p);
|
|
278
277
|
if (k + 1 < limit) {
|
|
279
278
|
value += ',';
|
|
@@ -282,7 +281,7 @@ var BamRecord = /** @class */ (function () {
|
|
|
282
281
|
}
|
|
283
282
|
}
|
|
284
283
|
if (Btype === 'C') {
|
|
285
|
-
for (
|
|
284
|
+
for (let k = 0; k < limit; k++) {
|
|
286
285
|
value += byteArray.readUInt8(p);
|
|
287
286
|
if (k + 1 < limit) {
|
|
288
287
|
value += ',';
|
|
@@ -291,7 +290,7 @@ var BamRecord = /** @class */ (function () {
|
|
|
291
290
|
}
|
|
292
291
|
}
|
|
293
292
|
if (Btype === 'f') {
|
|
294
|
-
for (
|
|
293
|
+
for (let k = 0; k < limit; k++) {
|
|
295
294
|
value += byteArray.readFloatLE(p);
|
|
296
295
|
if (k + 1 < limit) {
|
|
297
296
|
value += ',';
|
|
@@ -302,7 +301,7 @@ var BamRecord = /** @class */ (function () {
|
|
|
302
301
|
break;
|
|
303
302
|
}
|
|
304
303
|
default:
|
|
305
|
-
console.warn(
|
|
304
|
+
console.warn(`Unknown BAM tag type '${type}', tags may be incomplete`);
|
|
306
305
|
value = undefined;
|
|
307
306
|
p = blockEnd; // stop parsing tags
|
|
308
307
|
}
|
|
@@ -315,83 +314,83 @@ var BamRecord = /** @class */ (function () {
|
|
|
315
314
|
}
|
|
316
315
|
this._allTagsParsed = true;
|
|
317
316
|
return undefined;
|
|
318
|
-
}
|
|
319
|
-
|
|
317
|
+
}
|
|
318
|
+
_parseAllTags() {
|
|
320
319
|
this._parseTag('');
|
|
321
|
-
}
|
|
322
|
-
|
|
320
|
+
}
|
|
321
|
+
_parseCigar(cigar) {
|
|
323
322
|
return (
|
|
324
323
|
//@ts-ignore
|
|
325
324
|
cigar
|
|
326
325
|
.match(/\d+\D/g)
|
|
327
326
|
//@ts-ignore
|
|
328
|
-
.map(
|
|
329
|
-
}
|
|
327
|
+
.map(op => [op.match(/\D/)[0].toUpperCase(), parseInt(op, 10)]));
|
|
328
|
+
}
|
|
330
329
|
/**
|
|
331
330
|
* @returns {boolean} true if the read is paired, regardless of whether both segments are mapped
|
|
332
331
|
*/
|
|
333
|
-
|
|
332
|
+
isPaired() {
|
|
334
333
|
return !!(this.flags & constants_1.default.BAM_FPAIRED);
|
|
335
|
-
}
|
|
334
|
+
}
|
|
336
335
|
/** @returns {boolean} true if the read is paired, and both segments are mapped */
|
|
337
|
-
|
|
336
|
+
isProperlyPaired() {
|
|
338
337
|
return !!(this.flags & constants_1.default.BAM_FPROPER_PAIR);
|
|
339
|
-
}
|
|
338
|
+
}
|
|
340
339
|
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */
|
|
341
|
-
|
|
340
|
+
isSegmentUnmapped() {
|
|
342
341
|
return !!(this.flags & constants_1.default.BAM_FUNMAP);
|
|
343
|
-
}
|
|
342
|
+
}
|
|
344
343
|
/** @returns {boolean} true if the read itself is unmapped; conflictive with isProperlyPaired */
|
|
345
|
-
|
|
344
|
+
isMateUnmapped() {
|
|
346
345
|
return !!(this.flags & constants_1.default.BAM_FMUNMAP);
|
|
347
|
-
}
|
|
346
|
+
}
|
|
348
347
|
/** @returns {boolean} true if the read is mapped to the reverse strand */
|
|
349
|
-
|
|
348
|
+
isReverseComplemented() {
|
|
350
349
|
return !!(this.flags & constants_1.default.BAM_FREVERSE);
|
|
351
|
-
}
|
|
350
|
+
}
|
|
352
351
|
/** @returns {boolean} true if the mate is mapped to the reverse strand */
|
|
353
|
-
|
|
352
|
+
isMateReverseComplemented() {
|
|
354
353
|
return !!(this.flags & constants_1.default.BAM_FMREVERSE);
|
|
355
|
-
}
|
|
354
|
+
}
|
|
356
355
|
/** @returns {boolean} true if this is read number 1 in a pair */
|
|
357
|
-
|
|
356
|
+
isRead1() {
|
|
358
357
|
return !!(this.flags & constants_1.default.BAM_FREAD1);
|
|
359
|
-
}
|
|
358
|
+
}
|
|
360
359
|
/** @returns {boolean} true if this is read number 2 in a pair */
|
|
361
|
-
|
|
360
|
+
isRead2() {
|
|
362
361
|
return !!(this.flags & constants_1.default.BAM_FREAD2);
|
|
363
|
-
}
|
|
362
|
+
}
|
|
364
363
|
/** @returns {boolean} true if this is a secondary alignment */
|
|
365
|
-
|
|
364
|
+
isSecondary() {
|
|
366
365
|
return !!(this.flags & constants_1.default.BAM_FSECONDARY);
|
|
367
|
-
}
|
|
366
|
+
}
|
|
368
367
|
/** @returns {boolean} true if this read has failed QC checks */
|
|
369
|
-
|
|
368
|
+
isFailedQc() {
|
|
370
369
|
return !!(this.flags & constants_1.default.BAM_FQCFAIL);
|
|
371
|
-
}
|
|
370
|
+
}
|
|
372
371
|
/** @returns {boolean} true if the read is an optical or PCR duplicate */
|
|
373
|
-
|
|
372
|
+
isDuplicate() {
|
|
374
373
|
return !!(this.flags & constants_1.default.BAM_FDUP);
|
|
375
|
-
}
|
|
374
|
+
}
|
|
376
375
|
/** @returns {boolean} true if this is a supplementary alignment */
|
|
377
|
-
|
|
376
|
+
isSupplementary() {
|
|
378
377
|
return !!(this.flags & constants_1.default.BAM_FSUPPLEMENTARY);
|
|
379
|
-
}
|
|
380
|
-
|
|
378
|
+
}
|
|
379
|
+
cigar() {
|
|
381
380
|
if (this.isSegmentUnmapped()) {
|
|
382
381
|
return undefined;
|
|
383
382
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
383
|
+
const { byteArray, start } = this.bytes;
|
|
384
|
+
const numCigarOps = this.get('_n_cigar_op');
|
|
385
|
+
let p = start + 36 + this.get('_l_read_name');
|
|
386
|
+
const seqLen = this.get('seq_length');
|
|
387
|
+
let cigar = '';
|
|
388
|
+
let lref = 0;
|
|
390
389
|
// check for CG tag by inspecting whether the CIGAR field
|
|
391
390
|
// contains a clip that consumes entire seqLen
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
391
|
+
let cigop = byteArray.readInt32LE(p);
|
|
392
|
+
let lop = cigop >> 4;
|
|
393
|
+
let op = CIGAR_DECODER[cigop & 0xf];
|
|
395
394
|
if (op === 'S' && lop === seqLen) {
|
|
396
395
|
// if there is a CG the second CIGAR field will
|
|
397
396
|
// be a N tag the represents the length on ref
|
|
@@ -406,7 +405,7 @@ var BamRecord = /** @class */ (function () {
|
|
|
406
405
|
return this.get('CG');
|
|
407
406
|
}
|
|
408
407
|
else {
|
|
409
|
-
for (
|
|
408
|
+
for (let c = 0; c < numCigarOps; ++c) {
|
|
410
409
|
cigop = byteArray.readInt32LE(p);
|
|
411
410
|
lop = cigop >> 4;
|
|
412
411
|
op = CIGAR_DECODER[cigop & 0xf];
|
|
@@ -421,9 +420,9 @@ var BamRecord = /** @class */ (function () {
|
|
|
421
420
|
this.data.length_on_ref = lref;
|
|
422
421
|
return cigar;
|
|
423
422
|
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
|
|
423
|
+
}
|
|
424
|
+
_flags() { }
|
|
425
|
+
length_on_ref() {
|
|
427
426
|
if (this.data.length_on_ref) {
|
|
428
427
|
return this.data.length_on_ref;
|
|
429
428
|
}
|
|
@@ -431,31 +430,31 @@ var BamRecord = /** @class */ (function () {
|
|
|
431
430
|
this.get('cigar'); // the length_on_ref is set as a side effect
|
|
432
431
|
return this.data.length_on_ref;
|
|
433
432
|
}
|
|
434
|
-
}
|
|
435
|
-
|
|
433
|
+
}
|
|
434
|
+
_n_cigar_op() {
|
|
436
435
|
return this.get('_flag_nc') & 0xffff;
|
|
437
|
-
}
|
|
438
|
-
|
|
436
|
+
}
|
|
437
|
+
_l_read_name() {
|
|
439
438
|
return this.get('_bin_mq_nl') & 0xff;
|
|
440
|
-
}
|
|
439
|
+
}
|
|
441
440
|
/**
|
|
442
441
|
* number of bytes in the sequence field
|
|
443
442
|
*/
|
|
444
|
-
|
|
443
|
+
_seq_bytes() {
|
|
445
444
|
return (this.get('seq_length') + 1) >> 1;
|
|
446
|
-
}
|
|
447
|
-
|
|
445
|
+
}
|
|
446
|
+
getReadBases() {
|
|
448
447
|
return this.seq();
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
for (
|
|
458
|
-
|
|
448
|
+
}
|
|
449
|
+
seq() {
|
|
450
|
+
const { byteArray, start } = this.bytes;
|
|
451
|
+
const p = start + 36 + this.get('_l_read_name') + this.get('_n_cigar_op') * 4;
|
|
452
|
+
const seqBytes = this.get('_seq_bytes');
|
|
453
|
+
const len = this.get('seq_length');
|
|
454
|
+
let buf = '';
|
|
455
|
+
let i = 0;
|
|
456
|
+
for (let j = 0; j < seqBytes; ++j) {
|
|
457
|
+
const sb = byteArray[p + j];
|
|
459
458
|
buf += SEQRET_DECODER[(sb & 0xf0) >> 4];
|
|
460
459
|
i++;
|
|
461
460
|
if (i < len) {
|
|
@@ -464,16 +463,16 @@ var BamRecord = /** @class */ (function () {
|
|
|
464
463
|
}
|
|
465
464
|
}
|
|
466
465
|
return buf;
|
|
467
|
-
}
|
|
466
|
+
}
|
|
468
467
|
// adapted from igv.js
|
|
469
|
-
|
|
468
|
+
getPairOrientation() {
|
|
470
469
|
if (!this.isSegmentUnmapped() &&
|
|
471
470
|
!this.isMateUnmapped() &&
|
|
472
471
|
this._refID === this._next_refid()) {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
472
|
+
const s1 = this.isReverseComplemented() ? 'R' : 'F';
|
|
473
|
+
const s2 = this.isMateReverseComplemented() ? 'R' : 'F';
|
|
474
|
+
let o1 = ' ';
|
|
475
|
+
let o2 = ' ';
|
|
477
476
|
if (this.isRead1()) {
|
|
478
477
|
o1 = '1';
|
|
479
478
|
o2 = '2';
|
|
@@ -482,8 +481,8 @@ var BamRecord = /** @class */ (function () {
|
|
|
482
481
|
o1 = '2';
|
|
483
482
|
o2 = '1';
|
|
484
483
|
}
|
|
485
|
-
|
|
486
|
-
|
|
484
|
+
const tmp = [];
|
|
485
|
+
const isize = this.template_length();
|
|
487
486
|
if (isize > 0) {
|
|
488
487
|
tmp[0] = s1;
|
|
489
488
|
tmp[1] = o1;
|
|
@@ -499,38 +498,36 @@ var BamRecord = /** @class */ (function () {
|
|
|
499
498
|
return tmp.join('');
|
|
500
499
|
}
|
|
501
500
|
return null;
|
|
502
|
-
}
|
|
503
|
-
|
|
501
|
+
}
|
|
502
|
+
_bin_mq_nl() {
|
|
504
503
|
return this.bytes.byteArray.readInt32LE(this.bytes.start + 12);
|
|
505
|
-
}
|
|
506
|
-
|
|
504
|
+
}
|
|
505
|
+
_flag_nc() {
|
|
507
506
|
return this.bytes.byteArray.readInt32LE(this.bytes.start + 16);
|
|
508
|
-
}
|
|
509
|
-
|
|
507
|
+
}
|
|
508
|
+
seq_length() {
|
|
510
509
|
return this.bytes.byteArray.readInt32LE(this.bytes.start + 20);
|
|
511
|
-
}
|
|
512
|
-
|
|
510
|
+
}
|
|
511
|
+
_next_refid() {
|
|
513
512
|
return this.bytes.byteArray.readInt32LE(this.bytes.start + 24);
|
|
514
|
-
}
|
|
515
|
-
|
|
513
|
+
}
|
|
514
|
+
_next_pos() {
|
|
516
515
|
return this.bytes.byteArray.readInt32LE(this.bytes.start + 28);
|
|
517
|
-
}
|
|
518
|
-
|
|
516
|
+
}
|
|
517
|
+
template_length() {
|
|
519
518
|
return this.bytes.byteArray.readInt32LE(this.bytes.start + 32);
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
Object.keys(this).forEach(function (k) {
|
|
519
|
+
}
|
|
520
|
+
toJSON() {
|
|
521
|
+
const data = {};
|
|
522
|
+
Object.keys(this).forEach(k => {
|
|
525
523
|
if (k.charAt(0) === '_' || k === 'bytes') {
|
|
526
524
|
return;
|
|
527
525
|
}
|
|
528
526
|
//@ts-ignore
|
|
529
|
-
data[k] =
|
|
527
|
+
data[k] = this[k];
|
|
530
528
|
});
|
|
531
529
|
return data;
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
}());
|
|
530
|
+
}
|
|
531
|
+
}
|
|
535
532
|
exports.default = BamRecord;
|
|
536
533
|
//# sourceMappingURL=record.js.map
|