Repository navigation
feat: Updates for 10x Genomics Atera bundles - #426
stephenwilliams22 wants to merge 21 commits into
Conversation
Adds a native reader for 10x Genomics Atera datasets: cell-by-gene expression table, cell/nucleus segmentation labels and boundary polygons, per-transcript locations, and morphology images. - Table (`cell_feature_matrix.zarr.zip`/`csc_cell_feature_matrix.zarr.zip`) is read directly with `anndata`'s own zarr IO (`anndata.io.read_elem`/ `anndata.io.sparse_dataset`), with `X` lazily backed by dask. - Cell/nucleus labels are lazily backed by dask; boundary polygons are read via `shapely.from_ragged_array`, with an optional tiled/pyramided partial-read path (`read_cell_boundaries`) for large bundles. - Transcripts are read lazily per spatial tile via dask-delayed. - Morphology images are read via `tifffile`'s native OME-TIFF tile grid, avoiding materializing full-resolution planes. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #426 +/- ##
==========================================
- Coverage 66.60% 66.00% -0.61%
==========================================
Files 26 29 +3
Lines 3345 3927 +582
==========================================
+ Hits 2228 2592 +364
- Misses 1117 1335 +218
🚀 New features to boost your workflow:
|
|
@stephenwilliams22 could you please always ensure that the pre-commit checks are green? Ideally a PR should always have green CI before anyone has a look. Thanks! |
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@Zethson sorry about that. we should be good to go now. |
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
@stephenwilliams22 It seems you write I'm going from what Claude has said more than actually having read through the code in detail. Ideally you'd be able to record an association between more than one somewhat equivalent spatial element (so a given cell could be associated with nucleus & boundary shapes/labels), I've been meaning to find if there's an open issue or discussion on that. |
|
Also
s = pd.Series(obs.index, index=obs.index)
s.equals(obs["barcode"]) # False
s.equals(obs["barcode"].astype(obs.index.dtype)) # TrueBuilding the index and the column from the same array (so their dtypes match), or not naming the index after an existing column, fixes it. Seen with the Atera v1 WTA kidney dataset; spatialdata 0.8.0, anndata 0.13.4, pandas 3.1.0. |
Thanks @xinaesthete I put in a fix |
Fixed |
A tile can hold 100M+ transcripts. Each dask partition was a whole tile, so writing a large dataset ran many multi-GB partitions at once and swapped to disk. atera_to_parquet likewise decoded a whole tile per batch. - _read_transcript_tile takes start/stop and reads only those rows; the per-row gene index comes from searchsorted over gene_offset. - _get_points makes one partition per 5M-row chunk of a tile. - atera_to_parquet reads and writes each tile in the same chunks. - Add tests that chunked reads match whole-tile reads across gene boundaries, and that partitions are bounded. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Removed code for calculating the number of genes detected per cell as this is now in the atera loader
Adds a native reader for 10x Genomics Atera datasets: cell-by-gene expression table, cell/nucleus segmentation labels and boundary polygons, per-transcript locations, and morphology images.
cell_feature_matrix.zarr.zip/csc_cell_feature_matrix.zarr.zip) is read directly withanndata's own zarr IO (anndata.io.read_elem/anndata.io.sparse_dataset), withXlazily backed by dask.shapely.from_ragged_array, with an optional tiled/pyramided partial-read path (read_cell_boundaries) for large bundles.tifffile's native OME-TIFF tile grid, avoiding materializing full-resolution planes.Enables massive datasets on a basic laptop (2M cells, 11 billion transcripts). Basic analysis workflow (loading, plotting, HVG, PCA, normalization, clustering, etc) max memory usage was 7GB on a new mac in ~15min.