@jbrowse/cigar-utils
Auto-generated from exported functions tagged #api in the source. See
imports and re-exports for how to
import these from a plugin.
buildReadVsRefFeatures
Decompose one alignment record plus its SA tag into the segments of the split
read, ordered along the read. The layer above featurizeSA: it folds the
record itself in as one more segment, in the same normalized read coordinate
space the SA entries are put in, and pairs each segment with a mate
describing its span on the read.
The "read vs ref" launchers (linear synteny + dotplot) draw these features against a synthetic read assembly, and the alignments feature-detail widget lists split-read junctions from them.
getCanonicalRefName resolves each segment's refName against the reference
assembly's aliases: a BAM whose header names the sequence chr1 against a FASTA
that names it 1 otherwise yields regions no track can be opened on. Optional
only because a caller may not have the assembly in hand; pass it when you do.
// type signature
(feature: ReadVsRefInput, getCanonicalRefName?: ((refName: string) => string | undefined) | undefined) => ReadVsRefFeaturescoarseCigarOwnAxis
The coarse CIGAR as a plain CIGAR over the row's axis, for a walk that
places mismatches by reference position: a run keeps only its own length, a
run with no own length is the insertion it amounts to, and one with no
mate length the deletion. Kept indels are exact, so they land where the fine
tier's would.
// type signature
(s: string) => stringcoarsenCigar
Fold a CIGAR into a coarse CIGAR whose straight lines stay within gap of
the alignment's own path. An indel longer than half the gap keeps its letter
and length (D/N/I); a shorter one is absorbed into the match run around it,
and a run whose two axes advanced by different amounts is written
<own>:<mate>M, a square run <n>M. =/X count as M. ownLen/mateLen
are the totals each axis consumed, for the caller to check against the row's
coordinate columns.
The bound: a run is closed before a folded indel would push its running skew (own minus mate) past half the gap, and no folded indel is longer than that, so inside a run the skew never exceeds half the gap and the line between the run's corners is never more than the gap off the path. That is what lets a reader interpolate within a run, and it costs a new run only where the two genomes' small indels are lopsided.
// type signature
(cigar: string, gap: number) => CoarsenedCigarfeaturizeSAEntries
featurizeSA over pre-split entries (see splitSA). Lets a caller filter the entries first — e.g. deduplicating the records repeated across a split read's segments — without paying to split and rejoin the tag around the filter.
// type signature
(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; mapq: number; strand: 1 | -1; uniqueId: string; mate: { start: number; end: number; refName: string | undefined; }; }[]flipCoarseCigar
The coarse CIGAR seen from the other axis on the minus strand: swapped as
swapCoarseCigar does, and in reverse op order. The twin of flipCigar.
// type signature
(s: string) => stringgetLength
Length of the read sequence (sum of all ops except D/N).
// type signature
(cigar: string) => numbergetLengthOnRef
Length the read spans on the reference (sum of M/=/X/D/N ops).
// type signature
(cigar: string) => numbergetMismatches
Computes the list of mismatches (SNVs, indels, clips, skips) for a read from its CIGAR, optional MD tag, sequence, reference, and quality.
// type signature
(cigar?: string | undefined, md?: string | undefined, seq?: string | undefined, ref?: string | undefined, qual?: Uint8Array<ArrayBufferLike> | undefined) => Mismatch[]getNextRefPos
Maps read-sequence positions to reference-sequence positions via the CIGAR, invoking the callback for each. Handles both packed Uint32Array and unpacked number[] CIGAR formats.
The walk is driven by the positions, not by the read bases. An inner loop
over every base an op spans, testing positions[currPos] === readPos + j,
takes O(read length) to find something O(positions) in size. On the full
extent of 200x.longread.mod.bam that loop scans 43.7 Mbp of read sequence to
place 0.84M modification calls. Within one op the read-to-reference offset is
a constant, so each position's answer is one addition and the ops only have to
be walked once: O(positions + ops).
plugins/alignments/benches/cigarWalkShape.bench.ts prices it at 1.17x on
the whole per-read modification pipeline, of which this walk is 45%.
1.17x is the whole speedup, and does not grow on a cleaner alignment. The
op loop does not cap it, although these reads have 7,000 ops apiece and
neither shape avoids the op loop: cigarOpDensity.bench.ts sweeps op density
over a 5,000x range and the ratio stays between 1.10x and 1.18x. What this
phase is bound by is the per-call work
both shapes share (the callback, the ML lookup, the compare, the write), not
the traversal that differs. Changing how the scan is shaped therefore has a
low ceiling here, however lopsided the iteration counts look.
positions must be ascending, which every caller's producer guarantees. A
repeated position emits once per occurrence.
from starts the walk at a refWindowToRead cursor instead of the first op,
for positions that all lie at or past its readStart.
// type signature
(cigarOps: ArrayLike<number>, positions: number[], callback: (ref: number, idx: number) => void, from?: CigarCursor | undefined) => voidparseCigar
Parses a CIGAR string to an alternating [length, op, ...] string array.
// type signature
(s?: string) => string[]parseCigar2
Parses a CIGAR string to a packed number array where each value is
(length << 4) | opIndex.
// type signature
(s?: string) => number[]parseCigar2Typed
Same encoding as parseCigar2 but writes into a packed Uint32Array —
matches the NUMERIC_CIGAR format that BAM/CRAM adapters emit, so consumers can
use a single typed-array code path.
// type signature
(s?: string) => Uint32Array<ArrayBuffer>parseCoarseCigar
Parse a coarse CIGAR into the packed (len << 4) | op form
visitCigarRenderedSegments walks. A square run packs as one CIGAR_M
word; an unequal run as a CIGAR_RUN word pair, own axis first.
// type signature
(s: string) => Uint32Array<ArrayBuffer>refWindowToRead
The read offsets [readStart, readEnd) holding every aligned base whose
read-relative reference offset lies in [refStart, refEnd), and the op a
getNextRefPos walk over them starts at. Aligned read offsets map to
ascending reference offsets, so the range holds exactly those bases; a
clip or insertion inside it has no reference offset. The returned
refStart/refEnd are the requested ones clipped to the read's span.
The op loop adds each op's lengths through the masks above rather than branching on the op, because a long read's op sequence is close to random and the branches mispredict; only the op that crosses the next edge takes the slow path.
// type signature
(cigarOps: ArrayLike<number>, refStart: number, refEnd: number) => ReadWindowsplitSA
The ;-separated alignment records of an SA tag, empties dropped — the input
featurizeSAEntries expects.
// type signature
(SA: string) => string[]swapCoarseCigar
The coarse CIGAR seen from the other axis on the plus strand: the two lengths
of every run trade places and D<->I swap, op order untouched. The twin of
swapIndelCigar.
// type signature
(s: string) => stringRelated links
- Developer guide: Dependencies and re-exports