@gmod/bam 8.5.1 → 8.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/dist/bamFile.d.ts +94 -1
- package/dist/bamFile.js +94 -3
- package/dist/bamFile.js.map +1 -1
- package/dist/htsget.d.ts +8 -1
- package/dist/htsget.js +4 -1
- package/dist/htsget.js.map +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/mismatches.d.ts +114 -0
- package/dist/mismatches.js +397 -0
- package/dist/mismatches.js.map +1 -0
- package/dist/record.d.ts +45 -0
- package/dist/record.js +76 -10
- package/dist/record.js.map +1 -1
- package/dist/reference.d.ts +45 -0
- package/dist/reference.js +61 -0
- package/dist/reference.js.map +1 -0
- package/dist/seqAlphabet.d.ts +3 -0
- package/dist/seqAlphabet.js +14 -0
- package/dist/seqAlphabet.js.map +1 -0
- package/esm/bamFile.d.ts +94 -1
- package/esm/bamFile.js +94 -3
- package/esm/bamFile.js.map +1 -1
- package/esm/htsget.d.ts +8 -1
- package/esm/htsget.js +4 -1
- package/esm/htsget.js.map +1 -1
- package/esm/index.d.ts +5 -1
- package/esm/index.js +6 -0
- package/esm/index.js.map +1 -1
- package/esm/mismatches.d.ts +114 -0
- package/esm/mismatches.js +393 -0
- package/esm/mismatches.js.map +1 -0
- package/esm/record.d.ts +45 -0
- package/esm/record.js +69 -3
- package/esm/record.js.map +1 -1
- package/esm/reference.d.ts +45 -0
- package/esm/reference.js +55 -0
- package/esm/reference.js.map +1 -0
- package/esm/seqAlphabet.d.ts +3 -0
- package/esm/seqAlphabet.js +11 -0
- package/esm/seqAlphabet.js.map +1 -0
- package/package.json +1 -1
- package/src/bamFile.ts +178 -1
- package/src/htsget.ts +16 -2
- package/src/index.ts +26 -1
- package/src/mismatches.ts +623 -0
- package/src/record.ts +95 -3
- package/src/reference.ts +87 -0
- package/src/seqAlphabet.ts +10 -0
package/esm/htsget.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import BamFile from './bamFile.ts';
|
|
2
|
-
import type { BamRecordClass, BamRecordLike } from './bamFile.ts';
|
|
2
|
+
import type { BamRecordClass, BamRecordLike, ReferenceSequenceFetcher } from './bamFile.ts';
|
|
3
3
|
import type BamRecord from './record.ts';
|
|
4
4
|
import type { BamOpts, BaseOpts } from './util.ts';
|
|
5
5
|
import type { Fetcher } from 'generic-filehandle2';
|
|
@@ -33,6 +33,13 @@ export default class HtsgetFile<T extends BamRecordLike = BamRecord> extends Bam
|
|
|
33
33
|
maxCacheBytes?: number;
|
|
34
34
|
/** see {@link maxCacheBytes}: inherited, and inert in htsget mode */
|
|
35
35
|
cacheIdleTimeoutMs?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Reference bases for reads with no `MD` tag — see {@link BamFile}'s option
|
|
38
|
+
* of the same name. Unlike the cache options this one is live here: an
|
|
39
|
+
* htsget query resolves its reads' mismatches exactly as an indexed one
|
|
40
|
+
* does.
|
|
41
|
+
*/
|
|
42
|
+
fetchReferenceSequence?: ReferenceSequenceFetcher;
|
|
36
43
|
});
|
|
37
44
|
/**
|
|
38
45
|
* Requests a ticket and returns its data blocks decompressed and
|
package/esm/htsget.js
CHANGED
|
@@ -75,6 +75,7 @@ export default class HtsgetFile extends BamFile {
|
|
|
75
75
|
recordClass: args.recordClass,
|
|
76
76
|
maxCacheBytes: args.maxCacheBytes,
|
|
77
77
|
cacheIdleTimeoutMs: args.cacheIdleTimeoutMs,
|
|
78
|
+
fetchReferenceSequence: args.fetchReferenceSequence,
|
|
78
79
|
});
|
|
79
80
|
this.baseUrl = args.baseUrl;
|
|
80
81
|
this.trackId = args.trackId;
|
|
@@ -101,7 +102,9 @@ export default class HtsgetFile extends BamFile {
|
|
|
101
102
|
const uncba = await this.fetchTicket(`referenceName=${chr}&start=${min}&end=${max}&format=BAM`, opts);
|
|
102
103
|
const zero = new VirtualOffset(0, 0);
|
|
103
104
|
const records = this.readBamFeatures(uncba.subarray(recordsOffset(uncba)), [], [], new Chunk(zero, zero, 0));
|
|
104
|
-
|
|
105
|
+
const result = appendInRange(records, chrId, min, max);
|
|
106
|
+
await this._applyReferenceSequence(result, chrId, chr, opts);
|
|
107
|
+
return result;
|
|
105
108
|
}
|
|
106
109
|
async getHeaderPre(opts = {}) {
|
|
107
110
|
// format is the only parameter the spec permits alongside class=header;
|
package/esm/htsget.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"htsget.js","sourceRoot":"","sources":["../src/htsget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAA;AAE7C,OAAO,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACjD,OAAO,KAAK,MAAM,YAAY,CAAA;AAC9B,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"htsget.js","sourceRoot":"","sources":["../src/htsget.ts"],"names":[],"mappings":"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"}
|
package/esm/index.d.ts
CHANGED
|
@@ -3,8 +3,12 @@ export { DEFAULT_CACHE_IDLE_TIMEOUT_MS, DEFAULT_MAX_CACHE_BYTES, default as BamF
|
|
|
3
3
|
export { default as CSI } from './csi.ts';
|
|
4
4
|
export { default as BamRecord } from './record.ts';
|
|
5
5
|
export { default as HtsgetFile } from './htsget.ts';
|
|
6
|
+
export { MISMATCH_DELETION, MISMATCH_HARD_CLIP, MISMATCH_INSERTION, MISMATCH_REF_SKIP, MISMATCH_SOFT_CLIP, MISMATCH_SUBST, forEachMismatchNumeric, } from './mismatches.ts';
|
|
7
|
+
export { packReference } from './reference.ts';
|
|
6
8
|
export type { NumericCigar } from './record.ts';
|
|
7
|
-
export type { BamRecordClass, BamRecordLike } from './bamFile.ts';
|
|
9
|
+
export type { BamRecordClass, BamRecordLike, ReferenceSequenceFetcher, } from './bamFile.ts';
|
|
10
|
+
export type { Mismatch, MismatchCallback, MismatchOptions, } from './mismatches.ts';
|
|
11
|
+
export type { PackedReference } from './reference.ts';
|
|
8
12
|
export type { BamOpts, BaseOpts } from './util.ts';
|
|
9
13
|
export type { IndexCovEntry } from './bai.ts';
|
|
10
14
|
export type { Fetcher } from 'generic-filehandle2';
|
package/esm/index.js
CHANGED
|
@@ -3,4 +3,10 @@ export { DEFAULT_CACHE_IDLE_TIMEOUT_MS, DEFAULT_MAX_CACHE_BYTES, default as BamF
|
|
|
3
3
|
export { default as CSI } from "./csi.js";
|
|
4
4
|
export { default as BamRecord } from "./record.js";
|
|
5
5
|
export { default as HtsgetFile } from "./htsget.js";
|
|
6
|
+
// The mismatch walk, and the codes it reports differences as. The walk is
|
|
7
|
+
// exported alongside `record.forEachMismatch` for callers holding BAM's packed
|
|
8
|
+
// arrays without a record around them — a SAM parser, or a worker that was
|
|
9
|
+
// posted the typed arrays.
|
|
10
|
+
export { MISMATCH_DELETION, MISMATCH_HARD_CLIP, MISMATCH_INSERTION, MISMATCH_REF_SKIP, MISMATCH_SOFT_CLIP, MISMATCH_SUBST, forEachMismatchNumeric, } from "./mismatches.js";
|
|
11
|
+
export { packReference } from "./reference.js";
|
|
6
12
|
//# sourceMappingURL=index.js.map
|
package/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EACvB,OAAO,IAAI,OAAO,GACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EACvB,OAAO,IAAI,OAAO,GACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,UAAU,CAAA;AACzC,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,aAAa,CAAA;AAEnD,0EAA0E;AAC1E,+EAA+E;AAC/E,2EAA2E;AAC3E,2BAA2B;AAC3B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,sBAAsB,GACvB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { PackedReference } from './reference.ts';
|
|
2
|
+
/**
|
|
3
|
+
* The kind of difference a {@link Mismatch} reports, as the CIGAR-style char
|
|
4
|
+
* code it corresponds to. `@gmod/cram`'s `forEachMismatch` emits the same
|
|
5
|
+
* values (its `RF_*` constants), so one `switch` handles records from either
|
|
6
|
+
* format.
|
|
7
|
+
*
|
|
8
|
+
* Note these are char codes and NOT the packed-CIGAR op numbers in `cigar.ts`
|
|
9
|
+
* — `MISMATCH_DELETION` is 68 (`'D'`), where `CIGAR_DEL` is 2.
|
|
10
|
+
*/
|
|
11
|
+
export declare const MISMATCH_SUBST = 88;
|
|
12
|
+
export declare const MISMATCH_INSERTION = 73;
|
|
13
|
+
export declare const MISMATCH_DELETION = 68;
|
|
14
|
+
export declare const MISMATCH_REF_SKIP = 78;
|
|
15
|
+
export declare const MISMATCH_SOFT_CLIP = 83;
|
|
16
|
+
export declare const MISMATCH_HARD_CLIP = 72;
|
|
17
|
+
/**
|
|
18
|
+
* One difference between a read and the reference, as
|
|
19
|
+
* {@link BamRecord.getMismatches} reports it.
|
|
20
|
+
*
|
|
21
|
+
* This is the level most consumers want. Deriving the same thing from `CIGAR`
|
|
22
|
+
* and `MD` yourself means knowing that MD counts reference bases and the CIGAR
|
|
23
|
+
* counts both, that MD is absent from a majority of aligners' output and the
|
|
24
|
+
* reference has to stand in for it, that an `=`/`X` CIGAR carries the
|
|
25
|
+
* substitutions itself, and that a deletion's MD payload has to be stepped over
|
|
26
|
+
* rather than read as matches. Every one of those has been a bug in a
|
|
27
|
+
* downstream consumer.
|
|
28
|
+
*/
|
|
29
|
+
export interface Mismatch {
|
|
30
|
+
/**
|
|
31
|
+
* Which kind of difference: `MISMATCH_SUBST` (X), `MISMATCH_INSERTION` (I),
|
|
32
|
+
* `MISMATCH_DELETION` (D), `MISMATCH_REF_SKIP` (N), `MISMATCH_SOFT_CLIP` (S)
|
|
33
|
+
* or `MISMATCH_HARD_CLIP` (H). A substitution arrives as `MISMATCH_SUBST`
|
|
34
|
+
* whether the file spelled it with MD, with an `X` CIGAR op, or not at all
|
|
35
|
+
* (leaving it to be found against the reference).
|
|
36
|
+
*/
|
|
37
|
+
code: number;
|
|
38
|
+
/** 0-based reference position the difference starts at */
|
|
39
|
+
refPos: number;
|
|
40
|
+
/**
|
|
41
|
+
* How many reference bases it covers: 1 for a substitution, the deleted or
|
|
42
|
+
* skipped length for D/N, and 0 for insertions and clips, which consume read
|
|
43
|
+
* bases without consuming reference.
|
|
44
|
+
*/
|
|
45
|
+
length: number;
|
|
46
|
+
/**
|
|
47
|
+
* The substituted base for X, or the inserted bases for I; empty for
|
|
48
|
+
* D/N/S/H, which have no bases of their own to report. Also empty for an
|
|
49
|
+
* insertion in a read with no stored sequence (`SEQ` of `*`), where the
|
|
50
|
+
* length is all the file kept.
|
|
51
|
+
*/
|
|
52
|
+
bases: string;
|
|
53
|
+
/** quality score of a substituted base, or -1 when the read stores none */
|
|
54
|
+
qual: number;
|
|
55
|
+
/**
|
|
56
|
+
* Char code of the reference base a substitution replaces, 0 when unknown —
|
|
57
|
+
* which is what an `X` CIGAR op in a read carrying neither an MD tag nor a
|
|
58
|
+
* reference gives. Upper-cased, since a soft-masked reference would otherwise
|
|
59
|
+
* report lowercase.
|
|
60
|
+
*/
|
|
61
|
+
refBaseCode: number;
|
|
62
|
+
/** read bases consumed: the inserted or clipped length; 0 otherwise */
|
|
63
|
+
clipLength: number;
|
|
64
|
+
}
|
|
65
|
+
export type MismatchCallback = (code: number, refPos: number, length: number, bases: string, qual: number, refBaseCode: number, clipLength: number) => void;
|
|
66
|
+
export interface MismatchOptions {
|
|
67
|
+
/**
|
|
68
|
+
* Only report differences touching this reference range, 0-based and
|
|
69
|
+
* half-open like every other range this library takes. A deletion or skip is
|
|
70
|
+
* reported when any of the bases it covers falls in the range; everything
|
|
71
|
+
* else when its own position does.
|
|
72
|
+
*
|
|
73
|
+
* (`@gmod/cram`'s equivalent option is **closed** at `end` — a known wart
|
|
74
|
+
* over there, tracked in its TODO.md. Half-open is the one to write new code
|
|
75
|
+
* against.)
|
|
76
|
+
*/
|
|
77
|
+
start?: number;
|
|
78
|
+
end?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Reference bases to resolve substitutions against, for reads with no MD tag.
|
|
81
|
+
* Overrides whatever {@link BamRecord.setReference} bound, and unlike that
|
|
82
|
+
* method it takes a region of any extent: bases outside it are simply left
|
|
83
|
+
* uncompared. Pack it once per region with `packReference`, not per read.
|
|
84
|
+
*/
|
|
85
|
+
ref?: PackedReference;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* The mismatch walk over a record's already-packed fields, for callers holding
|
|
89
|
+
* BAM's arrays without a {@link BamRecord} around them — a SAM parser, or a
|
|
90
|
+
* worker that was handed the typed arrays rather than the record.
|
|
91
|
+
* `record.forEachMismatch()` is this function with the record's own fields
|
|
92
|
+
* filled in, and is what most code should call.
|
|
93
|
+
*
|
|
94
|
+
* Nothing here allocates per difference except the `bases` string, and that
|
|
95
|
+
* only for substitutions and insertions.
|
|
96
|
+
*
|
|
97
|
+
* @param cigar packed CIGAR ops, i.e. `record.NUMERIC_CIGAR`
|
|
98
|
+
* @param numericSeq 4-bit packed SEQ, i.e. `record.NUMERIC_SEQ`
|
|
99
|
+
* @param seqLength bases in `numericSeq`; 0 for a read stored with `SEQ` of `*`
|
|
100
|
+
* @param md the MD tag's bytes (`record.NUMERIC_MD`), or undefined. Preferred
|
|
101
|
+
* over `ref` when present, being both cheaper and what the aligner asserted
|
|
102
|
+
* @param qual per-base quality scores, or null/undefined when the read has none
|
|
103
|
+
* @param ref reference bases to compare against when there is no MD tag. Bases
|
|
104
|
+
* the region does not cover are left uncompared
|
|
105
|
+
* @param refStart the record's own 0-based start, which every reported position
|
|
106
|
+
* is relative to
|
|
107
|
+
* @param windowStart 0-based half-open reference window to report within. Pass
|
|
108
|
+
* `-Infinity`/`Infinity` for the whole read; a viewport that clips the walk
|
|
109
|
+
* is what keeps a chromosome-spanning contig alignment from being walked in
|
|
110
|
+
* full for every screenful
|
|
111
|
+
* @param windowEnd
|
|
112
|
+
* @param callback `(code, refPos, length, bases, qual, refBaseCode, clipLength)`
|
|
113
|
+
*/
|
|
114
|
+
export declare function forEachMismatchNumeric(cigar: ArrayLike<number>, numericSeq: ArrayLike<number>, seqLength: number, md: ArrayLike<number> | undefined, qual: ArrayLike<number> | null | undefined, ref: PackedReference | undefined, refStart: number, windowStart: number, windowEnd: number, callback: MismatchCallback): void;
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
import { CIGAR_DEL, CIGAR_DIFF, CIGAR_EQUAL, CIGAR_HARD_CLIP, CIGAR_INS, CIGAR_MATCH, CIGAR_REF_SKIP, CIGAR_SOFT_CLIP, } from "./cigar.js";
|
|
2
|
+
import { CHAR_CODE_FROM_NIBBLE, referenceNibble } from "./reference.js";
|
|
3
|
+
import { SEQRET_DECODER } from "./seqAlphabet.js";
|
|
4
|
+
/**
|
|
5
|
+
* The kind of difference a {@link Mismatch} reports, as the CIGAR-style char
|
|
6
|
+
* code it corresponds to. `@gmod/cram`'s `forEachMismatch` emits the same
|
|
7
|
+
* values (its `RF_*` constants), so one `switch` handles records from either
|
|
8
|
+
* format.
|
|
9
|
+
*
|
|
10
|
+
* Note these are char codes and NOT the packed-CIGAR op numbers in `cigar.ts`
|
|
11
|
+
* — `MISMATCH_DELETION` is 68 (`'D'`), where `CIGAR_DEL` is 2.
|
|
12
|
+
*/
|
|
13
|
+
export const MISMATCH_SUBST = 88; // 'X'
|
|
14
|
+
export const MISMATCH_INSERTION = 73; // 'I'
|
|
15
|
+
export const MISMATCH_DELETION = 68; // 'D'
|
|
16
|
+
export const MISMATCH_REF_SKIP = 78; // 'N'
|
|
17
|
+
export const MISMATCH_SOFT_CLIP = 83; // 'S'
|
|
18
|
+
export const MISMATCH_HARD_CLIP = 72; // 'H'
|
|
19
|
+
// M and = both mean "aligned to the reference", differing only in whether the
|
|
20
|
+
// file promises the bases match. Which is exactly the distinction MD (or the
|
|
21
|
+
// reference) exists to settle, so the walk treats them identically.
|
|
22
|
+
const CIGAR_M_EQ_MASK = (1 << CIGAR_MATCH) | (1 << CIGAR_EQUAL);
|
|
23
|
+
// A clip has no bases to report — its length travels in `clipLength`, which is
|
|
24
|
+
// what every consumer reads.
|
|
25
|
+
const NO_BASES = '';
|
|
26
|
+
function reportRefMismatch(callback, refPos, seqNibble, qual, refNibble) {
|
|
27
|
+
callback(MISMATCH_SUBST, refPos, 1, SEQRET_DECODER[seqNibble], qual, CHAR_CODE_FROM_NIBBLE[refNibble], 0);
|
|
28
|
+
}
|
|
29
|
+
// One base compared on its own: the ends of a run whose length or alignment
|
|
30
|
+
// leaves it without a partner in the same byte.
|
|
31
|
+
function compareRefBase(callback, numericSeq, qual, ref, seqIdx, refIdx, refPos) {
|
|
32
|
+
const seqNibble = (numericSeq[seqIdx >> 1] >> ((1 - (seqIdx & 1)) << 2)) & 0xf;
|
|
33
|
+
const refNibble = referenceNibble(ref, refIdx);
|
|
34
|
+
if (seqNibble !== refNibble) {
|
|
35
|
+
reportRefMismatch(callback, refPos, seqNibble, qual ? qual[seqIdx] : -1, refNibble);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* The mismatch walk over a record's already-packed fields, for callers holding
|
|
40
|
+
* BAM's arrays without a {@link BamRecord} around them — a SAM parser, or a
|
|
41
|
+
* worker that was handed the typed arrays rather than the record.
|
|
42
|
+
* `record.forEachMismatch()` is this function with the record's own fields
|
|
43
|
+
* filled in, and is what most code should call.
|
|
44
|
+
*
|
|
45
|
+
* Nothing here allocates per difference except the `bases` string, and that
|
|
46
|
+
* only for substitutions and insertions.
|
|
47
|
+
*
|
|
48
|
+
* @param cigar packed CIGAR ops, i.e. `record.NUMERIC_CIGAR`
|
|
49
|
+
* @param numericSeq 4-bit packed SEQ, i.e. `record.NUMERIC_SEQ`
|
|
50
|
+
* @param seqLength bases in `numericSeq`; 0 for a read stored with `SEQ` of `*`
|
|
51
|
+
* @param md the MD tag's bytes (`record.NUMERIC_MD`), or undefined. Preferred
|
|
52
|
+
* over `ref` when present, being both cheaper and what the aligner asserted
|
|
53
|
+
* @param qual per-base quality scores, or null/undefined when the read has none
|
|
54
|
+
* @param ref reference bases to compare against when there is no MD tag. Bases
|
|
55
|
+
* the region does not cover are left uncompared
|
|
56
|
+
* @param refStart the record's own 0-based start, which every reported position
|
|
57
|
+
* is relative to
|
|
58
|
+
* @param windowStart 0-based half-open reference window to report within. Pass
|
|
59
|
+
* `-Infinity`/`Infinity` for the whole read; a viewport that clips the walk
|
|
60
|
+
* is what keeps a chromosome-spanning contig alignment from being walked in
|
|
61
|
+
* full for every screenful
|
|
62
|
+
* @param windowEnd
|
|
63
|
+
* @param callback `(code, refPos, length, bases, qual, refBaseCode, clipLength)`
|
|
64
|
+
*/
|
|
65
|
+
export function forEachMismatchNumeric(cigar, numericSeq, seqLength, md, qual, ref, refStart, windowStart, windowEnd, callback) {
|
|
66
|
+
// The walk runs in read-relative offsets — `roffset` reference bases and
|
|
67
|
+
// `soffset` read bases consumed — and converts back at the callback, so the
|
|
68
|
+
// window is converted once here rather than per op.
|
|
69
|
+
//
|
|
70
|
+
// Clamped to int32 rather than left at the ±Infinity an unwindowed walk
|
|
71
|
+
// passes, because every op of the walk compares an offset against these and
|
|
72
|
+
// Infinity makes each of those a Float64 comparison. BAM positions are int32,
|
|
73
|
+
// so this cannot narrow a window anyone can express.
|
|
74
|
+
const winLo = windowStart <= -0x80000000 ? -0x80000000 : windowStart - refStart;
|
|
75
|
+
const winHi = windowEnd >= 0x7fffffff ? 0x7fffffff : windowEnd - refStart;
|
|
76
|
+
// Fast path for reads with no sequence (e.g. secondary alignments with SEQ='*')
|
|
77
|
+
if (seqLength === 0) {
|
|
78
|
+
let roffset = 0;
|
|
79
|
+
for (let i = 0, l = cigar.length; i < l; i++) {
|
|
80
|
+
// `roffset` only grows, and nothing at or past the window's right edge is
|
|
81
|
+
// reported, so the rest of the CIGAR cannot produce anything (see the
|
|
82
|
+
// same check in the main loop)
|
|
83
|
+
if (roffset >= winHi) {
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
const packed = cigar[i];
|
|
87
|
+
const len = packed >>> 4;
|
|
88
|
+
const op = packed & 0xf;
|
|
89
|
+
// X consumes the reference exactly like M/=; without a sequence there are
|
|
90
|
+
// no bases to report for it, but it still has to advance — leaving it out
|
|
91
|
+
// shifted every later op left by the total X length, which is every indel
|
|
92
|
+
// in an --eqx CIGAR walked without a sequence.
|
|
93
|
+
if ((1 << op) & CIGAR_M_EQ_MASK || op === CIGAR_DIFF) {
|
|
94
|
+
roffset += len;
|
|
95
|
+
}
|
|
96
|
+
else if (op === CIGAR_INS) {
|
|
97
|
+
if (roffset >= winLo && roffset < winHi) {
|
|
98
|
+
callback(MISMATCH_INSERTION, refStart + roffset, 0, '', -1, 0, len);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else if (op === CIGAR_DEL) {
|
|
102
|
+
if (roffset < winHi && roffset + len > winLo) {
|
|
103
|
+
callback(MISMATCH_DELETION, refStart + roffset, len, NO_BASES, -1, 0, 0);
|
|
104
|
+
}
|
|
105
|
+
roffset += len;
|
|
106
|
+
}
|
|
107
|
+
else if (op === CIGAR_REF_SKIP) {
|
|
108
|
+
if (roffset < winHi && roffset + len > winLo) {
|
|
109
|
+
callback(MISMATCH_REF_SKIP, refStart + roffset, len, NO_BASES, -1, 0, 0);
|
|
110
|
+
}
|
|
111
|
+
roffset += len;
|
|
112
|
+
}
|
|
113
|
+
else if (op === CIGAR_SOFT_CLIP) {
|
|
114
|
+
if (roffset >= winLo && roffset < winHi) {
|
|
115
|
+
callback(MISMATCH_SOFT_CLIP, refStart + roffset, 0, NO_BASES, -1, 0, len);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else if (op === CIGAR_HARD_CLIP) {
|
|
119
|
+
if (roffset >= winLo && roffset < winHi) {
|
|
120
|
+
callback(MISMATCH_HARD_CLIP, refStart + roffset, 0, NO_BASES, -1, 0, len);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const mdLength = md?.length ?? 0;
|
|
127
|
+
const hasQual = !!qual;
|
|
128
|
+
const hasMD = md && mdLength > 0;
|
|
129
|
+
// Where the reference region sits in read-relative offsets, and the window
|
|
130
|
+
// narrowed to it. Only base COMPARISON is bounded by the region — an indel or
|
|
131
|
+
// a clip needs no reference base, so a region covering part of a read still
|
|
132
|
+
// reports every one of them.
|
|
133
|
+
//
|
|
134
|
+
// Ternaries rather than Math.max/Math.min, which matters more than it looks:
|
|
135
|
+
// an unwindowed walk has `winLo`/`winHi` at ±Infinity, so Math.min would hand
|
|
136
|
+
// back a Float64 and `cmpHi` would carry that all the way into `jHi`, the
|
|
137
|
+
// bound of the innermost (two-bases-per-byte) loop. This way an unwindowed
|
|
138
|
+
// walk keeps that bound a Smi, which measured ~8% of the reference path on
|
|
139
|
+
// dense short reads.
|
|
140
|
+
let refOffset = 0;
|
|
141
|
+
let cmpLo = 0;
|
|
142
|
+
let cmpHi = 0;
|
|
143
|
+
if (ref !== undefined) {
|
|
144
|
+
refOffset = refStart - ref.start;
|
|
145
|
+
const refLo = -refOffset;
|
|
146
|
+
const refHi = ref.length - refOffset;
|
|
147
|
+
cmpLo = winLo > refLo ? winLo : refLo;
|
|
148
|
+
cmpHi = winHi < refHi ? winHi : refHi;
|
|
149
|
+
}
|
|
150
|
+
let roffset = 0;
|
|
151
|
+
let soffset = 0;
|
|
152
|
+
let mdIdx = 0;
|
|
153
|
+
let mdMatchRemaining = 0;
|
|
154
|
+
if (hasMD) {
|
|
155
|
+
while (mdIdx < mdLength) {
|
|
156
|
+
const c = md[mdIdx];
|
|
157
|
+
if (c >= 48 && c <= 57) {
|
|
158
|
+
mdMatchRemaining = mdMatchRemaining * 10 + (c - 48);
|
|
159
|
+
mdIdx++;
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
for (let i = 0, l = cigar.length; i < l; i++) {
|
|
167
|
+
// Stop at the window's right edge rather than walking the rest of the
|
|
168
|
+
// CIGAR: `roffset` only grows, and every report below needs
|
|
169
|
+
// `roffset < winHi`, so nothing past here can produce anything. Matters for
|
|
170
|
+
// a whole chromosome stored as one BAM read, whose CIGAR runs to millions
|
|
171
|
+
// of ops for a screenful of them — and costs one compare per op otherwise,
|
|
172
|
+
// since an unwindowed walk has `winHi` at +Infinity.
|
|
173
|
+
if (roffset >= winHi) {
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
const packed = cigar[i];
|
|
177
|
+
const len = packed >>> 4;
|
|
178
|
+
const op = packed & 0xf;
|
|
179
|
+
if ((1 << op) & CIGAR_M_EQ_MASK) {
|
|
180
|
+
if (hasMD) {
|
|
181
|
+
let remaining = len;
|
|
182
|
+
let localOffset = 0;
|
|
183
|
+
while (remaining > 0) {
|
|
184
|
+
if (mdMatchRemaining >= remaining) {
|
|
185
|
+
mdMatchRemaining -= remaining;
|
|
186
|
+
localOffset += remaining;
|
|
187
|
+
remaining = 0;
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
localOffset += mdMatchRemaining;
|
|
191
|
+
remaining -= mdMatchRemaining;
|
|
192
|
+
mdMatchRemaining = 0;
|
|
193
|
+
if (mdIdx < mdLength && md[mdIdx] >= 65 && md[mdIdx] <= 90) {
|
|
194
|
+
const pos = roffset + localOffset;
|
|
195
|
+
if (pos >= winLo && pos < winHi) {
|
|
196
|
+
const seqIdx = soffset + localOffset;
|
|
197
|
+
const sb = numericSeq[seqIdx >> 1];
|
|
198
|
+
const nibble = (sb >> ((1 - (seqIdx & 1)) << 2)) & 0xf;
|
|
199
|
+
callback(MISMATCH_SUBST, refStart + pos, 1, SEQRET_DECODER[nibble], hasQual ? qual[seqIdx] : -1, md[mdIdx], 0);
|
|
200
|
+
}
|
|
201
|
+
mdIdx++;
|
|
202
|
+
localOffset++;
|
|
203
|
+
remaining--;
|
|
204
|
+
mdMatchRemaining = 0;
|
|
205
|
+
while (mdIdx < mdLength) {
|
|
206
|
+
const c = md[mdIdx];
|
|
207
|
+
if (c >= 48 && c <= 57) {
|
|
208
|
+
mdMatchRemaining = mdMatchRemaining * 10 + (c - 48);
|
|
209
|
+
mdIdx++;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
else if (ref) {
|
|
223
|
+
// Only compare bases whose reference position falls in the window AND
|
|
224
|
+
// in the region. A whole-chromosome contig has M ops totalling ~250M
|
|
225
|
+
// bases; without this clip every one is compared (and `ref` would have
|
|
226
|
+
// to cover the whole chromosome).
|
|
227
|
+
const jLo = cmpLo > roffset ? cmpLo - roffset : 0;
|
|
228
|
+
const jHi = cmpHi < roffset + len ? cmpHi - roffset : len;
|
|
229
|
+
let j = jLo;
|
|
230
|
+
// A leading odd read index has no partner in its byte, so compare it
|
|
231
|
+
// alone and let the pair loop start on a byte boundary.
|
|
232
|
+
if (j < jHi && (soffset + j) & 1) {
|
|
233
|
+
compareRefBase(callback, numericSeq, qual, ref, soffset + j, refOffset + roffset + j, refStart + roffset + j);
|
|
234
|
+
j++;
|
|
235
|
+
}
|
|
236
|
+
// Two bases per byte load and compare. `even`/`odd` differ only in
|
|
237
|
+
// which reference parity they put on a byte boundary, so one of them
|
|
238
|
+
// always lines up with the read's packed sequence; the nibbles are
|
|
239
|
+
// unpacked only for the byte that actually differs.
|
|
240
|
+
const refIdx = refOffset + roffset + j;
|
|
241
|
+
const refPairs = refIdx & 1 ? ref.odd : ref.even;
|
|
242
|
+
let refByte = (refIdx + (refIdx & 1)) >> 1;
|
|
243
|
+
let seqByte = (soffset + j) >> 1;
|
|
244
|
+
for (; j + 1 < jHi; j += 2, refByte++, seqByte++) {
|
|
245
|
+
const seqPair = numericSeq[seqByte];
|
|
246
|
+
const refPair = refPairs[refByte];
|
|
247
|
+
if (seqPair !== refPair) {
|
|
248
|
+
const seqHi = (seqPair >> 4) & 0xf;
|
|
249
|
+
const refHi = (refPair >> 4) & 0xf;
|
|
250
|
+
if (seqHi !== refHi) {
|
|
251
|
+
reportRefMismatch(callback, refStart + roffset + j, seqHi, hasQual ? qual[soffset + j] : -1, refHi);
|
|
252
|
+
}
|
|
253
|
+
const seqLo = seqPair & 0xf;
|
|
254
|
+
const refLo = refPair & 0xf;
|
|
255
|
+
if (seqLo !== refLo) {
|
|
256
|
+
reportRefMismatch(callback, refStart + roffset + j + 1, seqLo, hasQual ? qual[soffset + j + 1] : -1, refLo);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
if (j < jHi) {
|
|
261
|
+
compareRefBase(callback, numericSeq, qual, ref, soffset + j, refOffset + roffset + j, refStart + roffset + j);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
soffset += len;
|
|
265
|
+
roffset += len;
|
|
266
|
+
}
|
|
267
|
+
else if (op === CIGAR_INS) {
|
|
268
|
+
if (roffset >= winLo && roffset < winHi) {
|
|
269
|
+
// Optimized insertion base extraction - avoid string concat for common
|
|
270
|
+
// cases
|
|
271
|
+
let insertedBases;
|
|
272
|
+
if (len === 1) {
|
|
273
|
+
// Single base insertion - most common case
|
|
274
|
+
const sb = numericSeq[soffset >> 1];
|
|
275
|
+
const nibble = (sb >> ((1 - (soffset & 1)) << 2)) & 0xf;
|
|
276
|
+
insertedBases = SEQRET_DECODER[nibble];
|
|
277
|
+
}
|
|
278
|
+
else if (len === 2) {
|
|
279
|
+
// Two base insertion - second most common
|
|
280
|
+
const seqIdx0 = soffset;
|
|
281
|
+
const sb0 = numericSeq[seqIdx0 >> 1];
|
|
282
|
+
const nibble0 = (sb0 >> ((1 - (seqIdx0 & 1)) << 2)) & 0xf;
|
|
283
|
+
const seqIdx1 = soffset + 1;
|
|
284
|
+
const sb1 = numericSeq[seqIdx1 >> 1];
|
|
285
|
+
const nibble1 = (sb1 >> ((1 - (seqIdx1 & 1)) << 2)) & 0xf;
|
|
286
|
+
insertedBases = SEQRET_DECODER[nibble0] + SEQRET_DECODER[nibble1];
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
const bases = new Array(len);
|
|
290
|
+
for (let j = 0; j < len; j++) {
|
|
291
|
+
const seqIdx = soffset + j;
|
|
292
|
+
const sb = numericSeq[seqIdx >> 1];
|
|
293
|
+
const nibble = (sb >> ((1 - (seqIdx & 1)) << 2)) & 0xf;
|
|
294
|
+
bases[j] = SEQRET_DECODER[nibble];
|
|
295
|
+
}
|
|
296
|
+
insertedBases = bases.join('');
|
|
297
|
+
}
|
|
298
|
+
callback(MISMATCH_INSERTION, refStart + roffset, 0, insertedBases, -1, 0, len);
|
|
299
|
+
}
|
|
300
|
+
soffset += len;
|
|
301
|
+
}
|
|
302
|
+
else if (op === CIGAR_DEL) {
|
|
303
|
+
if (roffset < winHi && roffset + len > winLo) {
|
|
304
|
+
callback(MISMATCH_DELETION, refStart + roffset, len, NO_BASES, -1, 0, 0);
|
|
305
|
+
}
|
|
306
|
+
// MD spells a deletion as ^ then the deleted reference bases, which are
|
|
307
|
+
// not a difference this reports (the D above already is) but do have to
|
|
308
|
+
// be stepped over, or every later position in the read reads off the
|
|
309
|
+
// wrong part of the tag.
|
|
310
|
+
// eslint-disable-next-line @typescript-eslint/no-confusing-non-null-assertion
|
|
311
|
+
if (hasMD && mdIdx < mdLength && md[mdIdx] === 94) {
|
|
312
|
+
mdIdx++;
|
|
313
|
+
while (mdIdx < mdLength && md[mdIdx] >= 65) {
|
|
314
|
+
mdIdx++;
|
|
315
|
+
}
|
|
316
|
+
mdMatchRemaining = 0;
|
|
317
|
+
while (mdIdx < mdLength) {
|
|
318
|
+
const c = md[mdIdx];
|
|
319
|
+
if (c >= 48 && c <= 57) {
|
|
320
|
+
mdMatchRemaining = mdMatchRemaining * 10 + (c - 48);
|
|
321
|
+
mdIdx++;
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
roffset += len;
|
|
329
|
+
}
|
|
330
|
+
else if (op === CIGAR_REF_SKIP) {
|
|
331
|
+
if (roffset < winHi && roffset + len > winLo) {
|
|
332
|
+
callback(MISMATCH_REF_SKIP, refStart + roffset, len, NO_BASES, -1, 0, 0);
|
|
333
|
+
}
|
|
334
|
+
roffset += len;
|
|
335
|
+
}
|
|
336
|
+
else if (op === CIGAR_DIFF) {
|
|
337
|
+
for (let j = 0; j < len; j++) {
|
|
338
|
+
const seqIdx = soffset + j;
|
|
339
|
+
const sb = numericSeq[seqIdx >> 1];
|
|
340
|
+
const nibble = (sb >> ((1 - (seqIdx & 1)) << 2)) & 0xf;
|
|
341
|
+
// An X op says a substitution is here without saying what it replaces,
|
|
342
|
+
// so the reference base comes from MD or the region — and is 0, i.e.
|
|
343
|
+
// unknown, when the read carries neither.
|
|
344
|
+
let refBaseCode = 0;
|
|
345
|
+
if (hasMD) {
|
|
346
|
+
if (mdMatchRemaining === 0 && mdIdx < mdLength && md[mdIdx] >= 65) {
|
|
347
|
+
refBaseCode = md[mdIdx];
|
|
348
|
+
mdIdx++;
|
|
349
|
+
mdMatchRemaining = 0;
|
|
350
|
+
while (mdIdx < mdLength) {
|
|
351
|
+
const c = md[mdIdx];
|
|
352
|
+
if (c >= 48 && c <= 57) {
|
|
353
|
+
mdMatchRemaining = mdMatchRemaining * 10 + (c - 48);
|
|
354
|
+
mdIdx++;
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
else if (mdMatchRemaining > 0) {
|
|
362
|
+
mdMatchRemaining--;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
else if (ref) {
|
|
366
|
+
const refIdx = refOffset + roffset + j;
|
|
367
|
+
if (refIdx >= 0 && refIdx < ref.length) {
|
|
368
|
+
refBaseCode = CHAR_CODE_FROM_NIBBLE[referenceNibble(ref, refIdx)];
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
const pos = roffset + j;
|
|
372
|
+
if (pos >= winLo && pos < winHi) {
|
|
373
|
+
callback(MISMATCH_SUBST, refStart + pos, 1, SEQRET_DECODER[nibble], hasQual ? qual[seqIdx] : -1, refBaseCode, 0);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
soffset += len;
|
|
377
|
+
roffset += len;
|
|
378
|
+
}
|
|
379
|
+
else if (op === CIGAR_SOFT_CLIP) {
|
|
380
|
+
if (roffset >= winLo && roffset < winHi) {
|
|
381
|
+
callback(MISMATCH_SOFT_CLIP, refStart + roffset, 0, NO_BASES, -1, 0, len);
|
|
382
|
+
}
|
|
383
|
+
soffset += len;
|
|
384
|
+
}
|
|
385
|
+
else if (op === CIGAR_HARD_CLIP) {
|
|
386
|
+
if (roffset >= winLo && roffset < winHi) {
|
|
387
|
+
callback(MISMATCH_HARD_CLIP, refStart + roffset, 0, NO_BASES, -1, 0, len);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
// P (padding) consumes neither read nor reference and is not a difference
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
//# sourceMappingURL=mismatches.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mismatches.js","sourceRoot":"","sources":["../src/mismatches.ts"],"names":[],"mappings":"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"}
|