Pe overlap consolidation - #138
Merged
Merged
Conversation
Port of STAR's ReadAlign::peMergeMates / peOverlapSEtoPE (STAR-rs star_pe_overlap.rs): when mates overlap in genome space, merge them into one SE read, realign through the existing SE pipeline, and convert the result back into a two-mate pair, rescoring from scratch. Unconditional overwrite of the separate-mate result on success, per STAR semantics. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
(matches STAR); reverse-strand conversion test
Psy-Fer
enabled auto-merge (squash)
July 27, 2026 11:10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
--peOverlapNbasesMinmate-overlap merge-and-realign — consolidated + STAR-faithful filter stage (closes #119)Consolidates BenjaminDEMAILLE's PE mate-overlap PR, with the review-flagged filter-stage divergence from real STAR fixed and the feature validated against STAR 2.7.11b on 10k yeast pairs.
When a fragment is shorter than
mate1_len + mate2_len, the mates overlap in genome space. STAR (peOverlapMergeMap) merges them into one contiguous single-end read, aligns that, and converts the result back to a two-mate pair — often stitching cleanly across the overlap where separate-mate alignment fails.Closes #119.
Fix: merged-read find must be filter-free (defer to the PE stage)
The port aligned the merged read with the full SE driver (
align_read), which appliesmappedFilter's read-length gates —outFilterMatchNminOverLread(default 0.66) andoutFilterScoreMinOverLread— against the merged length. STAR'speMergeRA->mapOneRead()is a find step: it locates windows without those gates, converts every candidate to PE, and runsmultMapSelect()/mappedFilter()only afterward at the PE level, on the reconstructed pair (ReadAlign_oneRead.cpp:87-91). Applying the SE gate to the longer merged read silently dropped merges the PE stage would keep.Fixed: the merged-read find now runs with the length-relative gates disabled; the existing PE decision tree (
filter_paired_transcripts, which already applies the combined-length match/score gates) does the real filtering afterconvert_merged_transcript_to_pe.Validation (yeast PE,
--peOverlapNbasesMin 10, vs STAR 2.7.11b)After the fix rustar is a strict superset of STAR's peOverlap rescues: 0 pairs mapped by STAR but not rustar, plus 11 extra — all verified legitimate (proper pairs, FLAG 99/147,
nM0–1) that STAR's peMerge heuristic misses, consistent with rustar's already-documented PE-improvement cases. CIGAR agreement 17367/17624 (98.5%).Tests
convert_reverse_strand_flips_mates_and_swaps_coordsunit test — the review-flagged untested path: the reverse-strandm_sta = Lread − readLen − m_stacoordinate swap + the mate-strand flip (mate1 takes the fragment strand, mate2 the opposite). Asserts the strand flip, per-mate coverage, and the mirrored genomic spans.ERR12389696.16897393).Gate: 574 tests pass ·
clippy --all-targets0 warnings ·fmtclean.--peOverlapNbasesMindefaults to 0 (off), so the default path is unchanged.