Skip to content

Corrected mode (CLI): score-only prints -1 without an alignment (#23) - #57

Merged
cjfields merged 1 commit into
mainfrom
fix/unreachable-score-corrected
Oct 17, 2026
Merged

cjfields merged 1 commit into
mainfrom
fix/unreachable-score-corrected

Conversation

@cjfields

Copy link
Copy Markdown
Member

Refs #23, which stays open until upstream C resolves it. This change is behind --no-c-compat; C mode is unchanged.

Problem

In score-only mode, C prints a score even when there's no alignment. CIGAR mode prints -1 - for the same pairs. What score-only prints depends on the case:

  • Unreachable with a match reward: the classic score evaluated at the unset end position (k = INT_MAX, offset = OFFSET_NULL). v = offset - k is a signed overflow, which wraps so that v + h == 1. Example: wfa.utest.seq pair 262 with affine -3,5,3,2 and X-drop 20,1 prints -113. (The example in Known issue (C parity): score-only score for unreachable alignments evaluated at an unset end position #23, pair 101, is actually reachable; the pair number was off. I'll correct the issue.)
  • Unreachable with match == 0: the negated score where the search gave up.
  • Failed BiWFA score search: INT32_MIN, left by cigar_clear.

In Rust, the library already returns these results with an unreachable status, and its docs say the score is meaningless then. Only align_benchmark converts them, reproducing C. So the fix is in the CLI.

Fix

With --no-c-compat, score-only prints -1, as CIGAR mode does, when:

  • the alignment ended unreachable with no Z-drop cell; or
  • BiWFA's score search failed.

Z-drop results keep their score, because they come from a real cell.

Results

Left as is (FIXED_BUGS 14h)

  • BiWFA score-only has no partial result. When its search Z-drops it prints -1 (C: INT32_MIN), even though CIGAR mode returns the partial alignment. Example: utest with affine -3,5,3,2 and Z-drop 100,5, 7/305 pairs. Reporting a partial score there would need new BiWFA score-only logic.
  • BiWFA's score search can succeed where its CIGAR search fails in a sub-problem, because the cutoffs are independent.
  • A Z-drop whose CIGAR max-trims to empty keeps its score.
  • With a match reward, -1 can also be a real score (utest pair 281, 10 × 10 bp), as it can in C's CIGAR mode.

Tests

unreachable_score_only_corrected_prints_minus_one (tests/cli_output.rs, tests/data/issue23_unreachable.seq) covers:

  • unidirectional: C -113 vs corrected -1;
  • BiWFA: C INT32_MIN vs corrected -1;
  • banded with match == 0.

All tests pass; clippy is clean.

🤖 Generated with Claude Code

In score-only mode C always prints a score, even with no alignment (CIGAR
mode prints -1): for an unreachable pair with a match reward, the classic
score evaluated at the unset end position (a signed overflow); with
match == 0, the negated score where the search gave up; and INT32_MIN
for a failed BiWFA score search.

The library already returns these with an unreachable status; only the
CLI converts them, reproducing C. With --no-c-compat it now prints -1
when the alignment ended unreachable with no Z-drop cell, or BiWFA's
score search failed. Z-drop results keep their score.

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