Skip to content

convert: CellBender remove-background output, with its latents - #51

Merged
Claptar merged 2 commits into
mainfrom
feat/convert-cellbender
Oct 16, 2026
Merged

Claptar merged 2 commits into
mainfrom
feat/convert-cellbender

Conversation

@Claptar

@Claptar Claptar commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

Fixes #29.

adata convert output.h5 -o out.h5ad now recognises CellBender's remove-background output (0.2, 0.3 and 0.4 layouts, full and filtered) by its latents, whatever the file is called. X is the denoised counts, and the latents are kept under the names CellBender's own loaders use:

  • per-droplet latents → obs columns (cell_probability, cell_size, background_fraction, droplet_efficiency; latent_* for 0.2), NaN for droplets CellBender did not analyse, plus obs["cellbender_analyzed"];
  • the embedding → obsm["gene_expression_encoding"] (latent_gene_encoding for 0.2), written in row blocks;
  • the ambient profile → var["ambient_expression"];
  • everything else (global latents, metadata) → uns["cellbender"].

New flags:

  • --min-cell-probability P keeps droplets with cell_probability >= P, in file order.
  • --raw raw_feature_bc_matrix.h5 adds layers["cellranger"] (the raw counts of the same barcodes) and layers["cellbender"] (a copy of X), as load_anndata_from_input_and_output does. Filtered files list cells by UMI count rather than file order, so their raw counts go through the on-disk bucket sort; that code moves from formats/mtx.py into core/csr_build.write_runs and is shared.

--from 10x-h5 still reads a CellBender file as a plain 10x matrix. Registering a read-only .h5 format also changed how output extensions resolve: an extension now picks the first format that can be written, and --to cellbender is refused with "can be read but not written".

Tests: 21 in tests/test_cellbender.py (every layout, h5ad and Zarr, each latent at its barcode, --raw with filters and splits, refusals that write nothing), a scanpy read_10x_h5 comparison, and perf guards for linear work and block-wise obsm writes.

🤖 Generated with Claude Code

Fixes #29. A CellBender output.h5 or output_filtered.h5, 0.2 or later,
is recognised by its latents and read as a 10x matrix plus:

- per-droplet latents as obs columns, NaN for droplets CellBender did
  not analyse, and obs["cellbender_analyzed"];
- the gene-expression encoding in obsm, the ambient profile in var, and
  everything else in uns["cellbender"];

under the names CellBender's own loaders give, so its notebooks keep
working. Which latent belongs to which barcode follows CellBender's own
rule: 0.3+ filtered files still store every analysed droplet's index.

--min-cell-probability keeps likely cells. --raw adds the Cell Ranger
counts CellBender ran on as layers["cellranger"] (and X again as
layers["cellbender"]), matched by barcode: straight across for the full
output, through the on-disk buckets for the filtered one, whose cells
CellBender orders by count. That path is now core/csr_build.write_runs,
shared with the MTX import; fan_out_sparse_matrix can name each target's
matrix, so X and layers["cellbender"] come from one read.

An .h5 output is still a 10x matrix: outputs pick the first format with
that extension that can be written, and --to a read-only format says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 16, 2026 09:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-16T09:04:20.981038Z 533ac38 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (py3.12)

1 441 tests   1 441 ✅  3m 25s ⏱️
    1 suites      0 💤
    1 files        0 ❌

Results for commit 3db9c67.

♻️ This comment has been updated with latest results.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 533ac38cfc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/adata/conversion/cellbender.py Outdated
Comment thread src/adata/conversion/cellbender.py Outdated
Comment thread src/adata/conversion/cellbender.py Outdated
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (py3.13)

1 441 tests   1 441 ✅  3m 23s ⏱️
    1 suites      0 💤
    1 files        0 ❌

Results for commit 3db9c67.

♻️ This comment has been updated with latest results.

From review on #51:
- The embedding was read whole before the block loop. Latents are now read
  in slices and sorted into output blocks through scratch, since fancy
  indexing scattered rows is ~500x slower than a slice.
- --raw matched barcodes through a dict of the whole column. It now picks
  the output's barcodes out of contiguous reads and looks raw blocks up in
  a sorted numpy array.
- Raw-layer bucket sizes were estimated from feature widths, which rounds
  to zero for a narrow filter. A counting pass gives exact sizes.

Also adds var["cellbender_analyzed"] from features_analyzed_inds, as
CellBender's anndata_from_h5 does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Claptar
Claptar merged commit 13f12a0 into main Oct 16, 2026
6 checks passed
@Claptar
Claptar deleted the feat/convert-cellbender branch October 16, 2026 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Convert: CellBender remove-background output h5

2 participants