Skip to content

fix(sam): paired-end nM is the pair's mismatch total, as in STAR - #294

Closed
BenjaminDEMAILLE wants to merge 1 commit into
mainfrom
fix/pe-nm-pair-total
Closed

BenjaminDEMAILLE wants to merge 1 commit into
mainfrom
fix/pe-nm-pair-total

Conversation

@BenjaminDEMAILLE

Copy link
Copy Markdown
Contributor

Follow-up to #293, where this divergence came up.

Problem

For a pair, STAR writes nM per pair, as it does for AS: both mates carry the sum of the two mates' mismatches. rustar-aligner wrote each mate's own count:

rustar  99  chr21 23390830 1S73M1S ... AS:i:128 nM:i:5
rustar  163 chr21 23390779 75M     ... AS:i:128 nM:i:4
STAR    99  chr21 23390830 1S73M1S ... AS:i:128 nM:i:9
STAR    163 chr21 23390779 75M     ... AS:i:128 nM:i:9

Change

build_paired_mate_record (src/io/sam.rs) writes transcript.n_mismatch + mate_transcript.n_mismatch for nM. Nothing else changes:

  • NM is still per mate. It is an edit distance computed from the mate's own CIGAR, and STAR computes it per mate as well.
  • Half-mapped mates (built in another function) keep their own count.
  • The per-mate n_mismatch values on the transcripts are untouched, so the mismatch filters and fix(quant): filter TranscriptomeSAM pairs as a unit, like STAR (#292) #293's pair budget still see per-mate counts.

Results

Same data as #293: the first 2M pairs of ERR188021 against chr21 + GENCODE v44 chr21, with a STAR 2.7.11b index. Each paired record is matched to STAR's on (read, mate, position, CIGAR, mate position), secondaries included:

nM equal to STAR nM differs
main 633,910 247,069
this PR 880,623 356

I checked a sample of the 356 that still differ. In each case the other mate aligns differently (for example, it is spliced in STAR and not in rustar), so the pair's mismatch count legitimately differs.

Tests

  • test_build_paired_mate_record_per_mate_tags and test_build_paired_mate_record_mate_fields asserted the old per-mate nM; they now assert the pair total. Mate1 in the first test now has 1 mismatch so that the sum differs from either mate's own count.
  • cargo test --release and cargo clippy --all-targets pass.

🤖 Generated with Claude Code

STAR writes nM per pair, like AS: both mates carry the sum of their
mismatches. rustar-aligner wrote each mate's own count (5 and 4 where STAR
writes 9). NM stays per mate.

On 2M ERR188021 pairs vs chr21, paired records with the same alignment as
STAR 2.7.11b: 247,069 nM mismatches before, 356 after (all pairs whose
other mate aligns differently).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Psy-Fer

Psy-Fer commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

PE nM = pair total landed in #307

@Psy-Fer Psy-Fer closed this Oct 12, 2026
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.

2 participants