Repository navigation
feat: paired-end alignment with adapter read-through detection - #3
Merged
Merged
Conversation
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.
Closes #1.
What
Paired-end alignment:
-1/-2,--interleaved, or a BAM of 0x1/0x40/0x80 mates align read pairs as pairs.eschalign::Aligner::map_pairs): candidate = (reference, template strand); score = mate 1 + mate 2 (R2 reverse-complemented), both mates >=--min-score. Candidates are traced a score tier at a time; the first tier containing a candidate that passes the constraints (no outie, insert <=--max-insertdefault 500, both mates align a base) is the tie set. No qualifying candidate: written without 0x2, each mate at its own best reference on either strand.eschalign::adapter): TruSeq R1/R2 prefix detected on each mate's 3' end first (--adapter-r1/-r2,--min-adapter-overlapdefault 5,--no-adapter-trim); only the bases before it are aligned, the adapter stays as soft clip withad:i; nothing is discarded.RNEXT/PNEXT/TLEN,MC, per-mateNM/MD/AS/XS/XA, MAPQ 60 only for a unique best reference, mates adjacent in input order;--sort coordinateand--secondarywork.cut_chunksnever cuts between mates (pair-in-one-chunk), no barrier added; the GPU thread scores flattened mates with the same adapter trimming as the workers.unpaired_output_unchangedpins a digest of the uncompressed record stream over 6 flag combinations, blessed from the binary at the commit before this branch.Decisions on the open details
ad:i: each mate's own adapter length; present (0 if none) on every primary record of a paired run that searched, absent under--no-adapter-trim. One mate reading through: it carries the count, the otherad:i:0. The two mates must agree where the insert ends (len - adequal) or the weaker detection is dropped (both on a tie); checked in insert coordinates before alignment (the same quantity as in the reference frame, keeps the DP input fixed).XA: not both mates' positions. Each mate'sXAlists that mate's alignment in every other tied pair, in bwa's grammar, same order on both mates (entry k of each = tied pair k).--secondarywrites the same ties as 0x100 records, mate 1 then mate 2 per pair.--min-score: both mates must clear it, not just the sum.--mode semiglobal(localclips terminal mismatches, which is what the issue wants kept); an explicit--mode localis honoured with a warning. Consequence, documented: semi-global gives every read some positive score, so paired runs need--min-score(all tests pass one).--strand bothadds the reverse template strand. FF/RR are never candidates. Fallback mates are mapped on both strands.--max-read-len: that mate unmapped, partner aligned alone.Tests
cargo fmt --all --check: cleancargo clippy --workspace --all-targets -- -D warningsand with--features gpu: cleancargo nextest run --workspace(rna node): 120 passed, 0 failedcargo nextest run --features gpu --workspace(gpu node): 126 passed, 0 failed, includingpair_gpu_matches_cpu(confirmed it ran on the device, not skipped)cargo test --doc --workspace: no failurespair_resolves_paralog_tie,pair_insert_shorter_than_read,pair_terminal_mismatch_not_clipped,pair_over_max_insert_not_proper,pair_wrong_orientation_not_proper,pair_inputs_agree_fastq_interleaved_ubam,pair_orphan_is_error,pair_adapter_tag_counts,pair_gpu_matches_cpu,pair_sort_coordinate_matches_samtools(against realsamtools sort),unpaired_output_unchanged; pluspair_tie_is_reported_in_xa_and_secondaries,pair_ubam_tags_are_copied_on_both_mates,pair_chunking_keeps_mates_together, and unit tests foradapterandmapper::pair.tests/fixtures/pairs/(4 references, 9 hand-built pairs, 5 KB, regenerable withgen_pair_fixture.py); no pod5, no real data.Not verified