scverse / scverse/rustar-aligner
CellRanger4 + clip5pNbases/clip3pNbases misplaces reads by clip5pNbases
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 75
- Forks
- 7
- Avg merge
- 8m
- Merged PRs (30d)
- 1
Description
Summary
--clipAdapterType CellRanger4 combined with a non-zero --clip5pNbases / --clip3pNbases misplaces most reads by exactly clip5pNbases. Each option on its own is fine; only the pairing breaks.
Found while validating the CR4 clip work in the hyalite PR (#198 ). It predates that PR and is not caused by it.
Reproduction
Real 10x mouse chr19 (see CONTRIBUTING.md for dataset) , rustar and STAR 2.7.11b with the same flags:
SC=test/data/singlecell
COMMON="--readFilesIn $SC/reads/S10_L001_R2_001.fastq.gz $SC/reads/S10_L001_R1_001.fastq.gz \
--readFilesCommand zcat --soloType CB_UMI_Simple \
--soloCBwhitelist $SC/reference/10xv2_whitelist_sub50K.txt --soloFeatures Gene \
--clipAdapterType CellRanger4 --clip5pNbases 5 --clip3pNbases 3 \
--outSAMattributes NH HI AS nM --outSAMtype SAM --runThreadN 4"
./target/release/rustar-aligner --runMode alignReads --genomeDir $SC/solo_idx \
--sjdbGTFfile $SC/reference/gencode.vM19.annotation.chr19.gtf \
$COMMON --outFileNamePrefix $SC/rustar_cr4clip_
STAR --genomeDir $SC/star_solo_idx $COMMON --outFileNamePrefix $SC/star_cr4clip_
Then histogram the per-read POS delta (rustar − STAR) over primary records present in both.
What it looks like
POS delta, ~16.8k reads in both:
| delta | reads |
|---|---|
| −5 | 8527 |
| +5 | 3546 |
| 0 | 552 |
−5 and +5 are exactly clip5pNbases. Same read at the same POS carries CIGARs differing by 5 in the leading soft clip, e.g. 5S82M3S (rustar) vs 10S77M3S (STAR).
Mapped counts stay close — 14747 vs 14687 uniquely mapped — so reads are being misplaced, not lost, which is why Log.final.out looks healthy.
Scope: only the combination
| configuration | result |
|---|---|
CellRanger4 alone |
fine — 0 clip diffs, 900 other (the usual mapping/tie baseline) |
--clip5pNbases 5 --clip3pNbases 3 alone (no CR4) |
fine — 1 leading-clip diff, 980 other |
| both together | broken — 15605 differing, dominated by ±5 |
Notes for whoever picks this up
- Not
apply_read_clips(src/io/sam.rs:1106). It already swaps lead/trail for reverse strand and does not touch POS. I checked this first; it's clean. The cause is upstream, in what sequence reaches the aligner or how POS is derived from it. - The bidirectional ±5 split (~70/30) suggests something strand-dependent, but that is a hypothesis, not a finding.
- The POS-delta histogram is the diagnostic that made this obvious. CIGAR-level diffing hid it, because the CIGARs look individually plausible.
Dead end — please don't repeat it
STAR's ClipMate::clip does the fixed N-trim before the adapter trim, so our poly-A scan window is formally wrong for this pairing (we scan raw[TSO..], STAR scans raw[TSO+clip5p .. len-clip3p]). I tried narrowing the window to match, and agreement got worse: leading-clip diffs went 475 → 549, because the position bug swamps the window effect. It's reverted, with an NB comment at solo::clip_adapter_cr4_with_tso.
Fix the position bug first; then the window correction can be measured honestly.
Why it matters now
#176 makes clip_adapter_type = "CellRanger4" a default on 10x geometry (CELLRANGER_DEFAULTS). Today CR4 is opt-in, so this only bites users who asked for it. If #176 lands first, any 10x user who adds --clip5pNbases hits this without ever typing --clipAdapterType CellRanger4.
This should be fixed before #176 merges.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the mismatch with the commands and dataset in the issue, then trace how clipping reaches the aligner and how POS is derived. Start by reviewing src/io/sam.rs:1106 and solo::clip_adapter_cr4_with_tso, while treating apply_read_clips as already checked. Done means the combined CellRanger4 and fixed-clip configuration no longer produces the ±5 POS deltas against STAR.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- bioinformatics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100