Skip to content

Corrected mode: Z-drop ends (#22), X-drop/Z-drop score with match == 0 (#55), BiWFA - #56

Merged
cjfields merged 4 commits into
mainfrom
fix/zdrop-med-corrected
Oct 17, 2026
Merged

cjfields merged 4 commits into
mainfrom
fix/zdrop-med-corrected

Conversation

@cjfields

Copy link
Copy Markdown
Member

Refs #22, #55, #21. These stay open until upstream C resolves them. All changes are behind Compat::Corrected (#32); Compat::C is unchanged. There are four atomic commits:

1. 210f60e: Z-drop ends backtraced at the best cell's score (#22)

On a Z-drop, C backtraces the best cell's diagonal and offset starting at the current score, where that cell needn't exist.

Corrected mode backtraces the cell at the score it was found at:

  • high memory from the stored wavefronts;
  • med/low from the cell's (pcigar, prev), saved when it became the best and pinned through backtrace-buffer compaction (compaction now takes a slice of pinned chains).

2. b7b7889: X-drop/Z-drop score with match == 0 (#55, new)

C's Smith-Waterman score for these heuristics uses swg_match = -1 when match == 0, which is the default for every gap metric. This regression from C's 51fb1aa flipped the old "match-score=1" stand-in, so progress lowers the score:

  • X-drop prunes the diagonals that progress most, abandoning nearly every divergent pair (long.seq: typically 0/300 optimal).
  • Z-drop's best cell is the start of the alignment.

Corrected mode uses +1 (heuristic::swg_match). With default penalties, X-drop is then optimal on 300/300 long.seq pairs at 50,10 / 100,5 for affine, linear and affine2p, and Z-drop gives real partial alignments.

The #21 tests move to wfa.utest.seq pair 305 with match-reward penalties and X-drop 20,2, so they still check that corrected scores equal C's. Their CIGAR check now uses the SW-score bound, which is meaningful with a match reward.

3. 6374f4d: pass Compat to BiWFA's sub-aligners (Rust bug from #54)

BiWFA's forward, reverse and base sub-aligners were created with Compat::C and only given the parent's heuristic. So the #21 fix (and now #55) never applied under BiWFA; #54's "BiWFA identical to C" was this, not parity. Now:

  • BiWFA X-drop has no invalid CIGARs in corrected mode (C: up to 213/300).
  • With default penalties, BiWFA X-drop is optimal on 168–303 pairs (C: 0–240).

4. 70e6f2d: BiWFA Z-drop ends at the best cell (#22)

BiWFA's base step backtraces a Z-drop in the same way as C, and also starts in the sub-problem's end component (I/D at a breakpoint), though the best cell is an M cell. Corrected mode starts in M at the best cell's score. Across BiWFA Z-drop configurations:

  • no invalid CIGARs (C: up to 64);
  • with default penalties, far fewer empty results (long.seq 50,10: 0, C: 300).

Results

  • Differential suite, C mode: 1262 cases, only the 20 known Known issue (C bug): Z-drop in med/low backtraces from uninitialized cells (high vs med differ) #22 differences.
  • Differential suite, corrected mode: every difference is X-drop, Z-drop, or ends-free/extension with match < 0 (the existing fix). Banded, adaptive and core cases are identical to C.
  • Z-drop 20,1 / 50,1 / 50,10 / 100,5 × default and -3,5,3,2 × global / extension / ends-free × wfa.utest.seq and long.seq:
    • every partial CIGAR is valid;
    • high = med except co-optimal ties (an empty CIGAR vs 1M/2M, both scoring 0).

Tests

  • tests/corrected_zdrop.rs:
    • C mode's invalid CIGAR is reproduced; corrected high/med/low agree;
    • a compaction case that fails without the pin (checked by mutation);
    • BiWFA.
  • tests/corrected_xdrop.rs: now also checks BiWFA.
  • test_compute_sw_scores_c_formula: covers both stand-ins.
  • cargo test passes in release and debug; clippy is clean.

Docs: the Compat list, the XDrop/ZDrop rustdoc, the README, and FIXED_BUGS 14e, 14f and 14g.

🤖 Generated with Claude Code

cjfields and others added 4 commits October 17, 2026 13:35
On a Z-drop, C backtraces the best cell's diagonal and offset starting at
the current score, where that cell needn't exist. High memory then finds
no source and returns an empty CIGAR or unchecked matches (invalid with
match < 0); med/low read a dead cell whose backtrace C never initialized,
so C's high and med results differ.

In Compat::Corrected, a Z-drop end is backtraced at the score the best
cell was found at: from the stored wavefronts in high memory, and in
med/low from the cell's (pcigar, prev), kept when it became the best and
pinned through backtrace-buffer compaction (which now pins a slice).
All memory modes then give a valid partial alignment with the same score.
Compat::C is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
X-drop and Z-drop score cells with (swg_match*(v+h) - wf_score)/2. For
match == 0, C's stand-in match score is -1 since its commit 51fb1aa (before,
a special case used "match-score=1"), so progress lowers the score: X-drop
prunes the diagonals that progress most, abandoning nearly every divergent
pair with default penalties, and Z-drop's best cell is the start.

heuristic::swg_match returns -1 in Compat::C and +1 in Compat::Corrected,
passed to the heuristics in place of the match penalty. With default
penalties, X-drop goes from ~0/300 to 300/300 optimal on long.seq.

The #21 tests move to wfa.utest.seq pair 305 with match-reward penalties
and X-drop 20,2, so they still compare corrected scores with C's; their
CIGAR check now uses the SW score bound.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The forward, reverse and base sub-aligners run the heuristics and the
base backtrace, but were created with Compat::C and only given the
parent's heuristic, so corrected mode never reached BiWFA: the #21 and
#55 fixes didn't apply there. take_biwfa_subs now sets their compat to
the parent's on every call.

The #21 tests check BiWFA too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A BiWFA base sub-alignment that Z-drops is backtraced like the
unidirectional end in C: at the current score, and in the sub-problem's
end component, which can be I/D, though the best cell is an M cell. In
Compat::Corrected it starts in M at the best cell's score, so BiWFA's
partial alignments are valid too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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