Ben consolidation 2 - #135
Merged
Merged
Conversation
Port STAR-rs's Hamming-mode adapter clipping from STAR-rs `crates/star-align/src/star_clip.rs`, extending rustar-aligner's existing fixed-count `--clip5pNbases`/`--clip3pNbases` with a 3' adapter scan and the after-adapter trim. - src/clip/mod.rs: ClipEnd/ClipParams + clip_mate (STAR's two ClipMate passes: 5' then 3' on the 5'-clipped read) + local_search (STAR's localSearch Hamming scan). clip_params_from builds the config once per run from Parameters. Scoped to --clipAdapterType Hamming (STAR's default and the only mode that supports a 3' adapter); CellRanger4 (10x TSO + poly-A trim) is deferred to its own PR alongside STARsolo, which rustar-aligner doesn't have yet. - src/params/mod.rs: --clip3pAdapterSeq (`-` = none, matching STAR's own CLI sentinel), --clip3pAdapterMMp, --clip3pAfterAdapterNbases, --clip5pAfterAdapterNbases. - src/lib.rs: build ClipParams once per run in both the single-end and paired-end loops; clip_mate now runs per read (each mate's adapter position is scanned independently) in place of the old fixed clip5p/clip3p constants. Output behavior otherwise unchanged: the clipped read is fed to alignment and SAM output as before, clipped bases are not soft-clip-reinserted (matches the pre-existing --clip5pNbases/--clip3pNbases convention). Also fixes CLAUDE.md's source layout, which omitted src/wasp/ (missed when condensing the doc in 8c28a4c). Gate green: cargo build, clippy -D warnings, fmt, 470 tests (6 new clip unit tests). Byte-level validation against native STAR via the test/ harness is a separate step. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Psy-Fer
enabled auto-merge (squash)
July 26, 2026 08:55
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.
Batch 2: adapter clipping + STAR-faithful soft-clips + coverage signal (closes #113, #114)
Second consolidation batch of BenjaminDEMAILLE's STAR-rs-ported PRs. Each PR's logic was reviewed against real STAR (not trusted on STAR-rs provenance), the flagged bugs were fixed, and every change is byte-validated against STAR on the yeast test set.
Closes #113, #114
#113 — adapter-aware read clipping (
--clip3pAdapterSeq)Ported from STAR-rs, but the review found the headline feature was dead code: reads reaching
clip_mateare already numeric base codes, but it calledencode_baseon them again → every base becameN→ the 3' adapter Hamming scan never matched → nothing was ever clipped. The unit tests passed only because they fed ASCII string literals, a path production never hits.clip_params_from(it's the ASCII CLI value);clip_matenow compares the already-numeric read against the numeric adapter with no re-encoding.clip_params_from(params, mate)— the fixed--clip{5,3}pNbasesare per-mate).Soft-clip convention — align rustar's clip output with STAR
Investigating #113 surfaced a broader, pre-existing divergence: rustar dropped clipped bases from the record, while STAR (and STAR-rs) soft-clip them — the mapped read is the clipped insert, but the output SEQ keeps the full read with leading/trailing
Sin the CIGAR. (Notably: on clipping, STAR-rs is byte-identical to STAR — rustar was the one diverging. The drop was an early phase-6 shortcut, no real reason.)This is now fixed to match STAR:
apply_read_clipsinio/sam.rs: the record is built from the clipped read (so CIGAR core / MD / NM stay correct over the aligned bases), then the full original read is restored as SEQ/QUAL and the CIGAR is wrapped with strand-aware soft-clips (a read-3' clip becomes a leadingSon a reverse-strand record; adjacent soft-clips are merged).0,0) to preserve the batch-1 byte-exact STARsolo validation; inert on default 10x (no cDNA clipping). Tracked in TODO.#114 — coverage signal (
--outWigType bedGraph)Ported from STAR-rs's
star_wig.rs(STAR'ssignalFromBAM.cpp): four strandedSignal.{Unique,UniqueMultiple}.str{1,2}.out.bgtracks, RPM (default) or raw.signalFromBAMcounts BAM records, so both mates of a pair contribute tonUniq/nMult; the PR counted once per pair, halving the denominator and doubling every PE RPM track. Fix: per mate-record — a uniquely-mapped pair adds 2 tonUniq, a multimapped pair adds 2 tonMult. SE stays+1(a multimapper's records sum to exactly 1:NH × 1/NH), verified againstsignalFromBAM.cpp:22-28.Validation
Byte-compared against STAR 2.7.11b (and STAR-rs) on synthetic + 10k yeast reads:
137M13S, full SEQ — byte-identical to STAR13S137M(leading soft-clip) — byte-identical99/137M13S+147/13S137M— byte-identical--outWigType bedGraphPE RPMSignal.*.str1byte-identical; total ratio 1.0000 (was 2.0)--outWigType bedGraphSE(The
str2bedGraph differs by ~0.002% — one read's coverage — from the known PE alignment tie-break divergence bleeding into coverage, not a signal bug.)Gate: 559 tests pass ·
clippy --all-targets0 warnings ·fmtclean.