Repository navigation
CellReads.stats rows in whitelist order, not thread order - #371
Open
BenjaminDEMAILLE wants to merge 1 commit into
Open
BenjaminDEMAILLE wants to merge 1 commit into
BenjaminDEMAILLE wants to merge 1 commit into
Conversation
The cell rows were written in reverse order of first appearance, taken from whichever thread folded a read first, so the file changed with --runThreadN. Write them in whitelist order (sorted by barcode) from the BTreeMap that already holds them. STAR's own order is a libstdc++ unordered_map walk; reproducing it would mean porting libstdc++'s hash table, so DIVERGENCE.md 3.2 documents the difference for sign-off. 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.
Part of #354 (
CellReads.statsrow order changed with--runThreadN).Problem
Solo.out/<feature>/CellReads.statshad the same rows at 1, 4 and 8 threads, but in a different order each time.CellReadStatswrote the cell rows in reverse order of first appearance. That order came from whichever thread folded a read into the shared accumulator first, so it depended on scheduling. The module docs andDIVERGENCE.md3.2 said it was thread-independent; it was not.What STAR does (2.7.11b source)
std::unordered_map<uintCB, array<uint64,nBits>>(SoloCommon.h:47), filled withinsert(SoloCommon.h:60).nCB*3/2entries (SoloFeature_countCBgeneUMI.cpp:42), then filled from each thread's temporary file, thread 0 first (SoloFeature_countCBgeneUMI.cpp:45-48,SoloReadFeature_inputRecords.cpp:141-152).SoloFeature_statsOutput.cpp:102).CBnotInPasslistcomes first (:97-100).So STAR's order is the standard library's bucket layout, after rehashes, not a sort. The STAR build here (Linux) uses libstdc++. As a check, I fed STAR's 725 keys to a libstdc++
unordered_mapin rustar's first-appearance order withreserve(338): 713 of 725 lines landed where STAR has them. The 12 others are likely reads whose first appearance differs between the two tools. The old rustar order (reverse first appearance) matched 1 of 725 cell lines.Change
src/solo/cell_reads.rs: write the cell rows by iterating theBTreeMapthat already holds them, keyed by whitelist index. That is whitelist order, sorted by barcode. Theordervector andseenset are gone.CBnotInPassliststays first.DIVERGENCE.md3.2 rewritten: it wrongly named libc++ and claimed thread-independence. It is marked Needs maintainer sign-off.Measured against STAR 2.7.11b
data/parity/solo(100k reads, 50k-barcode whitelist, mm19 subset),--soloType CB_UMI_Simple --soloFeatures Gene --outSAMtype None, STAR with--soloCellReadStats Standard, rustar-aligner with--soloCellReadStats CB. Each tool used its own index. STAR is the Linux build in Docker.419f291d…73f38551…419f291d…73f38551…419f291d…73f38551…850f503e…b54794b6…22e85bd9…b54794b6…a6024efb…b54794b6…0896877e…b54794b6…0896877e…b54794b6…0896877e…b54794b6…rustar-aligner's file is now the same at every thread count. The sorted md5 is unchanged, so no value moved. Lines at the same position as STAR's: 3 of 727 (header,
CBnotInPasslist, one cell row by chance), before and after.The row values differ from STAR, before and after this PR, and that is not addressed here: rustar-aligner writes 20 cell rows STAR does not, 238 of 726 shared rows differ (mostly
exonic, alsocbMatch/cbMMmultiple), andCBnotInPasslistcounts 30 reads against STAR's 94260.Tests
rows_follow_whitelist_order_not_arrival_order(replacesrows_are_emitted_in_reverse_first_appearance_order): two arrival orders give the same file, in whitelist order. It fails onmain(["CB9", "CB1", "CB4"]) and passes here.umi_and_gene_totals_come_from_the_matrixupdated for the new order.cargo test --release,cargo clippy --all-targets -- -D warningsandcargo fmt --checkare clean on macOS.Not checked
--soloCellReadStats Standardand only takesCB. That is a separate gap.git merge-tree), which also touchesCellReads.statscode insrc/solo/mod.rsandcount.rs.🤖 Generated with Claude Code