@jbrowse/cigar-utils 5.0.0-beta.11 → 5.0.0-beta.14
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 +1 -1
- package/esm/cigarCategoryBits.d.ts +19 -0
- package/esm/cigarCategoryBits.js +87 -0
- package/esm/index.d.ts +1 -1
- package/esm/index.js +1 -1
- package/package.json +1 -1
- package/esm/numericCigarHasSkip.d.ts +0 -1
- package/esm/numericCigarHasSkip.js +0 -11
package/README.md
CHANGED
|
@@ -77,7 +77,7 @@ segments — without paying to split and rejoin the tag around the filter.
|
|
|
77
77
|
|
|
78
78
|
```js
|
|
79
79
|
// type signature
|
|
80
|
-
(entries: string[], id: string, strand: number | undefined, readName: string | undefined, normalize?: boolean | undefined) => {
|
|
80
|
+
(entries: string[], id: string, strand: number | undefined, readName: string | undefined, normalize?: boolean | undefined) => { refName: string; start: number; end: number; seqLength: number; clipLengthAtStartOfRead: number; CIGAR: string; strand: 1 | -1; uniqueId: string; mate: { start: number; end: number; refName: string | undefined; }; }[]
|
|
81
81
|
```
|
|
82
82
|
|
|
83
83
|
[Source code](https://github.com/GMOD/jbrowse-components/blob/main/packages/cigar-utils/src/mismatchParser.ts)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** A CIGAR carries a reference skip, the `N` a spliced aligner writes across an intron. */
|
|
2
|
+
export declare const CIGAR_HAS_SKIP = 2;
|
|
3
|
+
/** A CIGAR carries a deletion of {@link SV_INDEL_MIN_BP} or more. */
|
|
4
|
+
export declare const CIGAR_HAS_SV_DELETION = 4;
|
|
5
|
+
/** A CIGAR carries an insertion of {@link SV_INDEL_MIN_BP} or more. */
|
|
6
|
+
export declare const CIGAR_HAS_SV_INSERTION = 8;
|
|
7
|
+
/** The indel length from which callers file an indel as a structural variant. */
|
|
8
|
+
export declare const SV_INDEL_MIN_BP = 50;
|
|
9
|
+
/**
|
|
10
|
+
* {@link CIGAR_HAS_SKIP}, {@link CIGAR_HAS_SV_DELETION} and
|
|
11
|
+
* {@link CIGAR_HAS_SV_INSERTION} over a packed CIGAR (`len << 4 | op`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function numericCigarCategoryBits(cigar: ArrayLike<number>): number;
|
|
14
|
+
/**
|
|
15
|
+
* {@link numericCigarCategoryBits} over a CIGAR string, walked without
|
|
16
|
+
* parsing it into an array, since a synteny block's CIGAR can run to millions
|
|
17
|
+
* of operations.
|
|
18
|
+
*/
|
|
19
|
+
export declare function cigarStringCategoryBits(cigar: string): number;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { CIGAR_D, CIGAR_I, CIGAR_N } from './cigarConstants.js';
|
|
2
|
+
/** A CIGAR carries a reference skip, the `N` a spliced aligner writes across an intron. */
|
|
3
|
+
export const CIGAR_HAS_SKIP = 2;
|
|
4
|
+
/** A CIGAR carries a deletion of {@link SV_INDEL_MIN_BP} or more. */
|
|
5
|
+
export const CIGAR_HAS_SV_DELETION = 4;
|
|
6
|
+
/** A CIGAR carries an insertion of {@link SV_INDEL_MIN_BP} or more. */
|
|
7
|
+
export const CIGAR_HAS_SV_INSERTION = 8;
|
|
8
|
+
/** The indel length from which callers file an indel as a structural variant. */
|
|
9
|
+
export const SV_INDEL_MIN_BP = 50;
|
|
10
|
+
const SV_INDEL_MIN_PACKED = SV_INDEL_MIN_BP << 4;
|
|
11
|
+
// The op count from which the branch-free scan wins. Interleaved in one
|
|
12
|
+
// process (`plugins/alignments/benches/categoryBits.bench.ts`), the branching
|
|
13
|
+
// form took 11.6 ms over 153,677 short reads against 13.5 branch-free, and
|
|
14
|
+
// 15.4 ms over 335 long reads of 7,300 ops against 9.7: a long read's ops mix
|
|
15
|
+
// in an order no predictor learns, and a short read has too few to repay the
|
|
16
|
+
// arithmetic.
|
|
17
|
+
const BRANCH_FREE_MIN_OPS = 32;
|
|
18
|
+
/**
|
|
19
|
+
* {@link CIGAR_HAS_SKIP}, {@link CIGAR_HAS_SV_DELETION} and
|
|
20
|
+
* {@link CIGAR_HAS_SV_INSERTION} over a packed CIGAR (`len << 4 | op`).
|
|
21
|
+
*/
|
|
22
|
+
export function numericCigarCategoryBits(cigar) {
|
|
23
|
+
if (cigar.length < BRANCH_FREE_MIN_OPS) {
|
|
24
|
+
let bits = 0;
|
|
25
|
+
for (let i = 0; i < cigar.length; i++) {
|
|
26
|
+
const packed = cigar[i];
|
|
27
|
+
const op = packed & 0xf;
|
|
28
|
+
if (op === CIGAR_N) {
|
|
29
|
+
bits |= CIGAR_HAS_SKIP;
|
|
30
|
+
}
|
|
31
|
+
else if (packed >= SV_INDEL_MIN_PACKED) {
|
|
32
|
+
if (op === CIGAR_D) {
|
|
33
|
+
bits |= CIGAR_HAS_SV_DELETION;
|
|
34
|
+
}
|
|
35
|
+
else if (op === CIGAR_I) {
|
|
36
|
+
bits |= CIGAR_HAS_SV_INSERTION;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return bits;
|
|
41
|
+
}
|
|
42
|
+
// One bit per op kind seen, and per op kind seen at SV length
|
|
43
|
+
let seen = 0;
|
|
44
|
+
let svLength = 0;
|
|
45
|
+
for (let i = 0; i < cigar.length; i++) {
|
|
46
|
+
const packed = cigar[i];
|
|
47
|
+
const op = packed & 0xf;
|
|
48
|
+
seen |= 1 << op;
|
|
49
|
+
svLength |= +(packed >= SV_INDEL_MIN_PACKED) << op;
|
|
50
|
+
}
|
|
51
|
+
return ((seen & (1 << CIGAR_N) ? CIGAR_HAS_SKIP : 0) |
|
|
52
|
+
(svLength & (1 << CIGAR_D) ? CIGAR_HAS_SV_DELETION : 0) |
|
|
53
|
+
(svLength & (1 << CIGAR_I) ? CIGAR_HAS_SV_INSERTION : 0));
|
|
54
|
+
}
|
|
55
|
+
const CHAR_D = 68;
|
|
56
|
+
const CHAR_I = 73;
|
|
57
|
+
const CHAR_N = 78;
|
|
58
|
+
/**
|
|
59
|
+
* {@link numericCigarCategoryBits} over a CIGAR string, walked without
|
|
60
|
+
* parsing it into an array, since a synteny block's CIGAR can run to millions
|
|
61
|
+
* of operations.
|
|
62
|
+
*/
|
|
63
|
+
export function cigarStringCategoryBits(cigar) {
|
|
64
|
+
let bits = 0;
|
|
65
|
+
let len = 0;
|
|
66
|
+
for (let i = 0; i < cigar.length; i++) {
|
|
67
|
+
const code = cigar.charCodeAt(i);
|
|
68
|
+
if (code >= 48 && code <= 57) {
|
|
69
|
+
len = len * 10 + code - 48;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
if (code === CHAR_N) {
|
|
73
|
+
bits |= CIGAR_HAS_SKIP;
|
|
74
|
+
}
|
|
75
|
+
else if (len >= SV_INDEL_MIN_BP) {
|
|
76
|
+
if (code === CHAR_D) {
|
|
77
|
+
bits |= CIGAR_HAS_SV_DELETION;
|
|
78
|
+
}
|
|
79
|
+
else if (code === CHAR_I) {
|
|
80
|
+
bits |= CIGAR_HAS_SV_INSERTION;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
len = 0;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return bits;
|
|
87
|
+
}
|
package/esm/index.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export { mdToMismatches2 } from './mdToMismatches2.ts';
|
|
|
18
18
|
export { getNextRefPos } from './getNextRefPos.ts';
|
|
19
19
|
export { refWindowToRead } from './refWindowToRead.ts';
|
|
20
20
|
export type { CigarCursor, ReadWindow } from './refWindowToRead.ts';
|
|
21
|
-
export {
|
|
21
|
+
export { CIGAR_HAS_SKIP, CIGAR_HAS_SV_DELETION, CIGAR_HAS_SV_INSERTION, SV_INDEL_MIN_BP, cigarStringCategoryBits, numericCigarCategoryBits, } from './cigarCategoryBits.ts';
|
|
22
22
|
export { numericCigarToString } from './numericCigarToString.ts';
|
|
23
23
|
export { connectionEndpointBps, readLeadingBodyDir, readLeadingBp, readTrailingBodyDir, readTrailingBp, } from './readEndpoints.ts';
|
|
24
24
|
export { clipLengthAtStartOfReadNumeric, featurizeSA, featurizeSAEntries, getClip, getLength, getLengthOnRef, getLengthSansClipping, getMismatches, parseCigar2, parseCigar2Typed, parseCigar, splitSA, } from './mismatchParser.ts';
|
package/esm/index.js
CHANGED
|
@@ -18,7 +18,7 @@ export { cigarToMismatches2 } from './cigarToMismatches2.js';
|
|
|
18
18
|
export { mdToMismatches2 } from './mdToMismatches2.js';
|
|
19
19
|
export { getNextRefPos } from './getNextRefPos.js';
|
|
20
20
|
export { refWindowToRead } from './refWindowToRead.js';
|
|
21
|
-
export {
|
|
21
|
+
export { CIGAR_HAS_SKIP, CIGAR_HAS_SV_DELETION, CIGAR_HAS_SV_INSERTION, SV_INDEL_MIN_BP, cigarStringCategoryBits, numericCigarCategoryBits, } from './cigarCategoryBits.js';
|
|
22
22
|
export { numericCigarToString } from './numericCigarToString.js';
|
|
23
23
|
export { connectionEndpointBps, readLeadingBodyDir, readLeadingBp, readTrailingBodyDir, readTrailingBp, } from './readEndpoints.js';
|
|
24
24
|
export { clipLengthAtStartOfReadNumeric, featurizeSA, featurizeSAEntries, getClip, getLength, getLengthOnRef, getLengthSansClipping, getMismatches, parseCigar2, parseCigar2Typed, parseCigar, splitSA, } from './mismatchParser.js';
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function numericCigarHasSkip(cigar: ArrayLike<number>): boolean;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { CIGAR_N } from './cigarConstants.js';
|
|
2
|
-
// Whether a packed CIGAR (`len << 4 | op`) carries a reference skip — the `N`
|
|
3
|
-
// a spliced aligner writes across an intron.
|
|
4
|
-
export function numericCigarHasSkip(cigar) {
|
|
5
|
-
for (let i = 0; i < cigar.length; i++) {
|
|
6
|
-
if ((cigar[i] & 0xf) === CIGAR_N) {
|
|
7
|
-
return true;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
return false;
|
|
11
|
-
}
|