Repository navigation
fix(quant): Aligned.toTranscriptome.out.bam record for record as STAR (primary draw, pair-level soft-clip budget, MAPQ, mate order, merged CIGAR, deletions, alignment order) - #315
Open
BenjaminDEMAILLE wants to merge 8 commits into
Conversation
…nd STAR's fixed unmapped / quant tag sets) STAR writes optional tags in the order given to --outSAMattributes (outSAMattrOrder), appends derived ones (RG, then XS for intronMotif), gives unmapped records the fixed NH HI AS nM uT then RG, and writes only NH HI [RG] in the transcriptome BAM. rustar used a fixed bitflag order everywhere. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ven (GeneCounts, solo Gene/GeneFull, GX/GN) STAR reads the annotation tables from --genomeDir (Transcriptome.cpp) and only fails when they are missing; rustar demanded --sjdbGTFfile for GeneCounts and STARsolo gene features even when the index was built with a GTF. The gene model is now assembled from the index tables when no GTF is given at mapping time, a mapping-time GTF still wins, and STAR's geneInfo.tab error is given when neither exists. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n STAR's transcript order With --sjdbGTFfile at mapping time, STAR rebuilds the transcript tables from that GTF (_STARgenome) and Transcriptome.cpp reads them from there; rustar kept reading the index tables. Transcripts are also put in STAR's order, sorted by (start, end) with ties in GTF order, so the transcriptome BAM's @sq lines match STAR's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…p/transcriptome-records
…tf' into wip/transcriptome-records
… (primary draw, pair-level soft-clip budget, MAPQ, mate order, merged CIGAR, deletions, alignment order) - Primary among a read's transcriptomic alignments: STAR draws int(rngUniformReal0to1(rngMultOrder)*nAlignT) once per mapped read from an mt19937 seeded runRNGseed*(iChunk+1); drawn here in the ordered writer stage, so any thread count reproduces STAR --runThreadN 1. - Soft-clip extension mismatches of both mates and the pair's own share one budget; insertions count as indels for the ban. - Adjacent M blocks merge after projection (25M125M -> 150M); deletions are not junctions. - MAPQ from nAlignT; left segment first; transcriptomic alignments in STAR's discovery order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
8 of 31 tasks
…fter the held reads are re-mapped Single-end transcriptomic alignments follow STAR's discovery order (new Transcript::star_order, set before the genomic sort). With --outFilterType BySJout, STAR writes the reads it did not hold first and maps the held ones again with the surviving novel junctions before drawing their primary; rustar now does the same for the transcriptome output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Stacked on #311 (genomic alignments matching STAR), with #306 (transcriptome BAM carries only NH HI [RG]) and #313 (transcript tables in STAR's order) merged into the branch; their changes show in this diff until they land. The transcriptome BAM header (no @HD/@pg) is #297's.
Finding
On the yeast 200k pairs (annotated index,
--quantMode TranscriptomeSAM GeneCounts) the transcriptome BAM differed from STAR 2.7.11b in primary flags, dropped/extra alignments, MAPQ, mate order, CIGARs (25M125Mvs150M), HI order and (with indels allowed) missing deletion alignments.Causes and fixes
int(rngUniformReal0to1(rngMultOrder)*nAlignT)once per mapped read (also when nAlignT is 0), from a per-thread mt19937 seededrunRNGseed*(iChunk+1)(ReadAlign.cpp, ReadAlign_quantTranscriptome.cpp). Workers now emit records flagged secondary and the ordered writer stage draws from the libc++Mt19937(src/solo/libcxx_rng.rs) seeded withrunRNGseed, so the result equals STAR--runThreadN 1for any rustar thread count. STAR with several threads is not reproducible (chunk to thread assignment varies); documented, not reproducible by design.min(outFilterMismatchNmaxTotal, outFilterMismatchNoverLmax*(Lread-1)), Lread = len1+len2+1. rustar tested each mate alone. Newfilter_and_project_pair.n_gapmisses insertions of stitched pairs).block_gaps).star_order(rank before that sort) and the transcriptome follows it.Results (rustar vs STAR, samtools view, identical/total records)
STAR 8 threads vs STAR 1 thread: 244946/274542 (primary flags only), confirming the nondeterminism.
Genomic Aligned.out.sam on the 200k pairs: records byte-identical to the starting build.
--quantTranscriptomeBandoes not exist in 2.7.11b; its Singleend is--quantTranscriptomeSAMoutput BanSingleEnd.Single-end and BySJout
Transcriptgetsstar_order(rank before the genomic score/position sort, which is unchanged); the SE transcriptome follows it. Single-end r1_200k vs STAR 1 thread: default 20k 16147/16147, 200k 161592/161592; BanSingleEnd_ExtendSoftclip 20k 16392/16392, 200k 164574/164574.--outFilterType BySJout: STAR holds a read with an unannotated junction (outFilterBySJout), writes every other read first, then maps the held reads again with only the filtered novel junctions (stitchWindowAligns.cpp,outFilterBySJoutStage==2) and draws for them then. The writer now writes non-held reads in read order, then the held reads, re-mapped with the second-stage junction filter (thread-local novel set checked inpasses_finalization_filters; the genomic output is untouched). A junction counts as annotated if the stitcher flagged it or its CIGAR coordinates are in the sjdb. PE vs STAR 1 thread: 20k 27466/27470, 200k 274526/274606 (default mode unchanged at 274542/274542).Tests
cargo test --release (609 unit tests, new: deletion kept in one exon, pair-level budget, merged CIGAR across a junction), clippy -D warnings, fmt.
Checked again by the main session on 20k yeast reads: paired-end 27,468 and single-end 16,147 transcriptome records identical to STAR
--runThreadN 1, in order, rustar on 8 threads.Part of #298.
🤖 Generated with Claude Code