Skip to content

solo: --runMode soloCellFiltering - #159

Open
BenjaminDEMAILLE wants to merge 1 commit into
scverse:mainfrom
BenjaminDEMAILLE:bd/solo-cell-filtering
Open

solo: --runMode soloCellFiltering#159
BenjaminDEMAILLE wants to merge 1 commit into
scverse:mainfrom
BenjaminDEMAILLE:bd/solo-cell-filtering

Conversation

@BenjaminDEMAILLE

@BenjaminDEMAILLE BenjaminDEMAILLE commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

--runMode soloCellFiltering <raw dir> <output prefix>: cell-call an existing raw count matrix without aligning anything.

What changed

The mode reads matrix.mtx, barcodes.tsv and features.tsv from a raw directory (plain or gzipped), applies --soloCellFilter, and writes the called subset under the output prefix. No genome, no reads, no index.

--runMode becomes a token list, because that is what STAR's is: the mode followed by its arguments (SoloFeature_loadRawMatrix.cpp reads runModeIn[1] and runModeIn[2]). The mode itself is now validated rather than falling back to alignReads, so a typo is refused instead of quietly running something else.

Why

Cell calling is a decision about a matrix, not about reads. Re-calling with different --soloCellFilter parameters should not mean re-aligning, and a matrix produced by another tool should be callable too.

How it avoids a second implementation

The matrix is streamed into the same temp-body form the align path builds, so called_cells and emptydrops_called are the identical code here and there rather than a copy free to drift. Counts are rounded on the way in: a --soloMultiMappers matrix carries real values, and the cell filters work on UMI totals.

Verification

Two integration tests in tests/alignment_features.rs, run with cargo test --release --test alignment_features solo_cell_filtering:

  • test_run_mode_solo_cell_filtering_calls_cells_from_a_raw_matrix — a 20-barcode synthetic matrix where five barcodes carry 1000 UMIs and fifteen carry 2; --soloCellFilter TopCells 5 writes exactly those five, with a 50 5 50 matrix header and the feature list carried through.
  • test_run_mode_solo_cell_filtering_requires_its_paths — the mode without its two paths is refused.

Gate: 560 lib + 23 integration tests, cargo clippy --all-targets -- -D warnings, cargo fmt --check, MSRV 1.89 — all green.

Output-neutral for every other run mode.

Known duplication left in place

The standalone emptydrops binary still carries its own copy of the algorithm, which this mode supersedes. Removing it means first moving test/solo_genefull_compare.py and test/solo_genefull_h5_compare.py onto the new mode, so it is left alone here rather than broken. Happy to do that as a follow-up if you want it gone.

Split out of #152 following the one-theme rule in CONTRIBUTING.md.

Cell-calls an existing raw count matrix without aligning anything, taking the
raw directory and an output prefix as STAR does:
`--runMode soloCellFiltering /path/to/raw/ /path/to/out/prefix`.

Cell calling is a decision about a matrix, not about reads. Re-calling with
different `--soloCellFilter` parameters should not mean re-aligning 400 million
reads, and a matrix produced by another tool should be callable too.

The matrix is streamed into the same temp-body form the align path builds, so
`called_cells` and `emptydrops_called` are the identical code here and there
rather than a second implementation free to drift. Counts are rounded on the way
in: a multimapper matrix carries real values, and the filters work on UMI
totals.

`--runMode` becomes a token list, because that is what STAR's is: the mode
followed by its arguments. The mode itself is now validated rather than falling
back to `alignReads`, so a typo is refused instead of quietly running something
else.

The standalone `emptydrops` binary still exists and still carries its own copy
of the algorithm, which no longer matches this one. Removing it means moving
`test/solo_genefull_compare.py` and `test/solo_genefull_h5_compare.py` to the
new mode first, so it is left alone here rather than broken.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant