Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,26 @@ Sections commonly used: Features, Bug fixes, Other changes.

- Read names are cut at `--readNameSeparator` (default `/`), as STAR does. A
read named `foo/1` was previously emitted as `foo/1` where STAR emits `foo`.
- `--soloOutLayout CellRanger` writes the solo matrices in the shape
`cellranger count` produces: `outs/raw_feature_bc_matrix/` and
`outs/filtered_feature_bc_matrix/`, gzipped, with a `-1` GEM-well suffix
on every barcode and one raw column per observed barcode. It implies
`--soloOutGzip yes`, `--soloOutRawBarcodes Observed` and an `outs/`
output directory, each still overridable on the command line. Counts are
unchanged. It is the default on 10x geometry, which **changes where
output files are written** on those runs; see `DIVERGENCE.md` §3.3.

- On 10x geometry (`CB_UMI_Simple`, a whitelist, 16 bp CB, 10 or 12 bp
UMI), the five CellRanger-matching flags now **default** to their
CellRanger values. Any flag named on the command line wins, and the
substitution is logged. **This changes default output on 10x runs** and
diverges from STARsolo; see `DIVERGENCE.md` §1.3.

- `--soloOutRawBarcodes Observed` writes the raw matrix with one column
per *observed* barcode instead of one per whitelist barcode, matching
what CellRanger's `raw_feature_bc_matrix` contains. Counts are
unchanged; on a 200-cell run `barcodes.tsv` goes from 62 MB to 3.4 kB.
**Not a STAR parameter**; default `Whitelist` keeps STARsolo behaviour.

- **STARsolo single-cell quantification (`--soloType`)** — the 10x
Chromium / plate-based count-matrix pipeline, ported from STAR and
Expand Down
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ noodles-bgzf = { version = "0.49", features = ["libdeflate"] }

[dev-dependencies]
assert_cmd = "2"
# Already a runtime dependency at the same version; listed here so the
# integration tests can read the gzipped CellRanger-layout matrix files.
flate2 = { version = "1", default-features = false, features = ["zlib-rs"] }
predicates = "3"

[build-dependencies]
Expand Down
90 changes: 90 additions & 0 deletions DIVERGENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,96 @@ On the 10k yeast PE benchmark, 4 reads differ in alignment score (AS) because ST
**Impact.** Past libc++'s load factor the map rehashes, and the order then depends on the bucket count, which depends on how many distinct barcodes were seen; beyond that size the order diverges. The **values never do** — only which line they appear on. Reading the file by barcode rather than by position is unaffected either way.

**Source.** `src/solo/cell_reads.rs`, locked by `rows_are_emitted_in_reverse_first_appearance_order`. STAR: `SoloFeature_statsOutput.cpp`.
### 1.3 CellRanger behaviour is the default on 10x geometry

**What STAR does.** STARsolo's defaults are its own (`1MM_multi`,
`1MM_All`, no UMI filtering, `Hamming` clipping, `outFilterScoreMin 0`)
whatever the barcode geometry. Matching CellRanger requires passing five flags,
listed in STAR's `docs/STARsolo.md`.

**What rustar-aligner does.** When the run is unambiguously 10x —
`CB_UMI_Simple`, a whitelist, a 16-base CB and a 10- or 12-base UMI — those
five flags default to their CellRanger values. Any flag given on the command
line wins, and the substitution is logged in full.

**Why.** A user aligning 10x data and comparing against CellRanger otherwise
gets a successful run and different numbers, with nothing pointing at the five
flags that explain it. Measured against CellRanger 10.0.0 on a 20 000-read
fixture, those flags move the count matrix from 8.96% above CellRanger to
0.03% above it, once #165's `cbMinP` posterior threshold is also applied.
STAR 2.7.11b with the same flags is at +0.09%, so all three agree to within a
fraction of a percent.

**Impact.** This is a **change of default output behaviour** and therefore the
largest divergence in this file. It is confined to a geometry nothing else in
common use shares, it is escapable by naming any flag explicitly, and it is
announced at `INFO` on every run it touches. It needs maintainer sign-off.

**Source.** `src/params/mod.rs` (`looks_like_10x`,
`apply_cellranger_defaults_on_10x`). STAR: `docs/STARsolo.md`, "Matching
CellRanger 4.x and 5.x results".

---

### 3.2 `--soloOutRawBarcodes Observed` (opt-in, non-STAR)

**What STAR does.** STARsolo's raw matrix has one column per whitelist
barcode, whether or not any read carried it. For 10x v3 that is 3 686 400
columns and a 62 MB `barcodes.tsv`, nearly all of it zeros.

**What rustar-aligner does.** The same, by default. `--soloOutRawBarcodes
Observed` narrows the raw matrix to the barcodes that actually hold a count,
which is what CellRanger's `raw_feature_bc_matrix` contains. On a 200-cell
fixture that is 200 columns and a 3.4 kB `barcodes.tsv`.

**Why.** Someone comparing our raw matrix against CellRanger's finds no
overlapping keys at all, because the two files mean different things by "raw".
The flag makes the comparison possible without changing what STARsolo users
get.

**Impact.** The counts are identical either way — same entries, same values,
verified on the fixture — only the columns present differ. This is a non-STAR
flag and needs maintainer sign-off; it is off by default so STARsolo parity is
untouched.

**Source.** `src/solo/count.rs` (`observed_barcodes`), `src/params/mod.rs`
(`solo_out_raw_barcodes`). CellRanger: `outs/raw_feature_bc_matrix/` from a
`cellranger count` run, observed directly rather than taken from its source.

---

### 3.3 `--soloOutLayout CellRanger` (non-STAR; on by default on 10x geometry)

**What STAR does.** STARsolo writes
`Solo.out/<feature>/{raw,filtered}/{matrix.mtx, barcodes.tsv, features.tsv}`,
uncompressed, with bare barcodes.

**What rustar-aligner does.** The same, by default, on non-10x geometry.
`--soloOutLayout CellRanger` writes the same numbers in the shape
`cellranger count` produces: `outs/{raw,filtered}_feature_bc_matrix/`, all three
files gzipped, a `-1` GEM-well suffix on every barcode, one raw column per
observed barcode, and no per-feature subdirectory when a single feature is
requested. It implies `--soloOutGzip yes`, `--soloOutRawBarcodes Observed` and
`--soloOutFileNames outs/ ...`, each still overridable on the command line.

Under §1.3 the same 10x detection turns this on by default, so a bare 10x run
lands in CellRanger's layout.

**Why.** Tools written against CellRanger's `outs/` (scanpy's `read_10x_mtx`,
Seurat's `Read10X`, any in-house loader) key on those directory names and on
the `-1` suffix. Without them the numbers are right and nothing downstream can
read them without a rename step.

**Impact.** No count changes: verified entry by entry on the 20 000-read
fixture, 13 959 entries and 15 439 counts in both layouts. On 10x geometry it
**changes where output files are written**, which needs maintainer sign-off
alongside §1.3. Against a real `cellranger count` run on the same fixture the
raw barcode sets match exactly, 200 of 200.

**Source.** `src/solo/count.rs` (`write_gene_matrix`, `write_one_barcode`),
`src/params/mod.rs` (`solo_out_layout`, `apply_cellranger_layout`). CellRanger:
`outs/` from a `cellranger count` 10.0.0 run, observed directly rather than
taken from its source.

---

Expand Down
Loading
Loading