Skip to content

Have clip-vg trim flanks of big unaligned sequences - #1990

Merged
glennhickey merged 1 commit into
masterfrom
satellite-edge
Aug 31, 2026
Merged

Have clip-vg trim flanks of big unaligned sequences#1990
glennhickey merged 1 commit into
masterfrom
satellite-edge

Conversation

@glennhickey

Copy link
Copy Markdown
Collaborator

Right now, 10kb+ unaligned regions are clipped out by default in pangenome graphs (except in .full output). But sometimes, the flanks of these regions are poorly aligned (often extending into satellites). This PR adds logic to trim these flanks if they seem too sparsely aligned.

This is done with the new clip-vg -k option. From each edge of a clipped interval it walks outward node by node, up to clipFlank bp, scoring every unaligned base +(1−T) and every aligned base −T — so the running total over any stretch is u − L·T, positive exactly when that stretch's unaligned fraction exceeds T. It cuts at the furthest position where that running total was at its maximum, clipping everything between there and the original edge. Because it takes the maximum over the whole window rather than stopping at the first negative, it will cross an aligned stretch if enough unaligned sequence resumes beyond it.

This scheme is pretty conservative. Drops some censat sequence from hprc graphs, without much impact of vcf-related benchmarks or path/fragmentation stats. There may be room to be more aggressive later on.

Both aligners work by extending anchors, so an anchor in unique sequence beside
a satellite array gets extended into it, and inside the array the orthologous
alignment is undefined.  Each haplotype takes some arbitrary but locally
high-scoring path for a while past the boundary, and they disagree with each
other.  clip-vg's -u removes the runs longer than its threshold; what survives
is a tangle at every boundary, in runs too short for -u to reach.

clip-vg v1.2.2 adds -k/--flank for this, and this wires it up:

  --clipFlank        alongside --clip, how far to trim outward.  This is the
                     control that matters -- inside a repeat the gate seldom
                     closes on its own, so the cap decides how much goes.
  clipFlank          config, default 50000, so it is on by default.
  clipFlankThreshold config, negative to calibrate per graph, which is the
                     default and what you want.

One command-line option, the rest config, because only the cap is worth
reaching for from a command line.  --clipFlank rejects a negative value and
rejects being combined with --clip 0; both would otherwise fall through the same
test as 0 and disable the trim silently, which next to clipFlankThreshold -- where
negative is the meaningful "calibrate" value -- is an easy thing to type.

The calibrated threshold decides how much sequence goes and clip-vg reports it
on stderr, which cactus_call only surfaces when a command fails, so clip_vg()
captures it into a flank-stats.tsv per chromosome.  The threshold gets its own
column because that is the number worth reading down; the whole message sits
beside it so a rewording upstream costs the column rather than the record.

Validated whole-genome on HPRC v2.1 against CHM13, on the same chrom-alignments
as the release so only the clipping differs.  Graph: nodes -1.53%, edges -1.98%,
length -1.49%, concentrated where it should be (chrY -9.4% of edges, the
acrocentrics next, chr6 -0.1%).  VCF: raw -0.92%, final -0.61%.  Accuracy
against dipcall truth over 231 HPRC samples, aardvark: F1 improves in 231 of
231, driven by recall.

Needs hal2vg v1.2.2, pinned here: v1.2.1 predates -k, so with clipFlank on by
default every run using downloaded binaries died at the clip phase on an unknown
option.  All six hal2vg binaries move together, since they ship from one release.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@glennhickey
glennhickey merged commit d9d5f15 into master Aug 31, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant