Skip to content
Merged
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
16 changes: 4 additions & 12 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,11 @@ xenium_example/

# Local scratch work: new notebooks and scripts stay untracked by default
# (already-tracked files are unaffected; use `git add -f` to version a new one)
/docs/notebooks/*.ipynb
/scripts/*.py
/scripts/convert_panel_sample.py
/graphify-out/
/slurm/
/slurm-logs/

# ...except the segmentation pipeline, which is part of the package's public
# surface rather than scratch: the CLI wrappers are documented entry points and
# the SLURM scripts are the supported way to run them on a cluster.
!/scripts/instanseg_segment.py
!/scripts/geojson_to_spatialdata.py
!/slurm/
/slurm/*
!/slurm/segment_node_worker.sh
!/slurm/segment_slurm.sh
!/slurm/SEGMENTATION_PLAN.md
# ...except the segmentation pipeline's documented entry points: the tutorial
# notebook and the two CLI wrappers. The SLURM scripts stay untracked -- they
# are cluster-specific scratch.
42 changes: 40 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
[badge-coverage]: https://codecov.io/github/peng-lab/spatialrefinery/branch/main/graph/badge.svg

A toolkit for turning raw spatial-omics vendor outputs into analysis-ready data: 10x Genomics Xenium bundles become
[SpatialData][] zarr stores, and whole-slide/microscopy images become pyramidal OME-TIFF.
[SpatialData][] zarr stores, whole-slide/microscopy images become pyramidal OME-TIFF, and H&E slides can be segmented
into nucleus boundaries packaged as a SpatialData store of their own.

## Why spatialrefinery

Expand All @@ -21,6 +22,9 @@ zarr store with pseudo-spots binned at whatever sizes a given resolution needs (
paired whole-slide image to a pyramidal OME-TIFF for fast viewing. Run it over a batch of raw bundles and you get one
common, multi-resolution dataset to train Phoenix on.

The same pipeline also runs on histology that has no paired Xenium run: nucleus segmentation turns an H&E slide into a
SpatialData store of nucleus boundaries with an empty table over a gene panel -- the shape Phoenix predicts into.

## Getting started

Please refer to the [documentation][], in particular the [installation guide][], [tutorials][], and
Expand All @@ -44,6 +48,27 @@ xenium_to_spatialdata(
convert_to_ometiff(source="raw_files/my_study/slide.svs", output_dir="processed")
```

Nucleus segmentation needs the optional `segmentation` extra, and is reached through `spatialrefinery.segmentation`
rather than the top-level package:

```python
from spatialrefinery.segmentation.instanseg import segment_wsi
from spatialrefinery.segmentation.to_spatialdata import default_zarr_path, geojson_to_spatialdata

slide = "processed/slide.ome.tif"

# 4. Segment nuclei with InstanSeg -> segmentation/slide.ome.tif/cells.geojson
cells = segment_wsi(slide, outdir="segmentation")

# 5. Package the boundaries with the slide -> processed/slide.zarr (+ .zarr.zip)
geojson_to_spatialdata(
geojson_path=cells,
zarr_path=default_zarr_path(slide, "processed"),
image_path=slide,
template_adata_path="panel_template.h5ad",
)
```

## Installation

You need to have Python 3.12 or newer installed on your system.
Expand Down Expand Up @@ -75,7 +100,20 @@ Choose from the options below to install spatialrefinery:
pip install git+https://github.com/peng-lab/spatialrefinery.git # (or `uv add`)
```

See the [installation guide][] for the optional `czi` extra and a verification snippet.
### Optional extras

```bash
# Zeiss CZI images, via bioio
pip install "spatialrefinery[czi] @ git+https://github.com/peng-lab/spatialrefinery.git"

# H&E nucleus segmentation, via InstanSeg
pip install "spatialrefinery[segmentation] @ git+https://github.com/peng-lab/spatialrefinery.git"
```

`segmentation` is kept out of the base install because it pulls `instanseg-torch`, and therefore torch's multi-GB CUDA
wheels, which most uses do not need. A CUDA GPU is strongly recommended for it.

See the [installation guide][] for details and a verification snippet.

## Release notes

Expand Down
35 changes: 32 additions & 3 deletions docs/api.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# API reference

This page documents the functions used in the [tutorial notebooks](tutorials.md): the two entry points for pulling raw
Xenium data and converting it to a [SpatialData](https://spatialdata.scverse.org/en/stable/) zarr store, and the one entry
point for converting whole-slide images to pyramidal OME-TIFF. All four are importable directly off the top-level package.
Xenium data and converting it to a [SpatialData](https://spatialdata.scverse.org/en/stable/) zarr store, the one entry
point for converting whole-slide images to pyramidal OME-TIFF, and the two that carry an H&E slide through nucleus
segmentation. The first four are importable directly off the top-level package; the segmentation pair is reached through
`spatialrefinery.segmentation`, since it needs the optional `segmentation` extra.

## Downloading

Expand Down Expand Up @@ -35,9 +37,36 @@ Convert raw vendor bundles and whole-slide images into analysis-ready formats: a
convert_to_ometiff
```

## Segmenting

Segment nuclei in an H&E whole-slide image with [InstanSeg](https://github.com/instanseg/instanseg), then package the
boundaries as a [SpatialData](https://spatialdata.scverse.org/en/stable/) zarr store. Needs the optional `segmentation`
extra -- see [Installation](installation.md).

```{eval-rst}
.. currentmodule:: spatialrefinery.segmentation.instanseg

.. autosummary::
:toctree: generated
:nosignatures:

segment_wsi
```

```{eval-rst}
.. currentmodule:: spatialrefinery.segmentation.to_spatialdata

.. autosummary::
:toctree: generated
:nosignatures:

geojson_to_spatialdata
default_zarr_path
```

:::{note}
This reference is deliberately narrow. `spatialrefinery.core` and `spatialrefinery.io` contain additional lower-level
machinery -- the technology/converter registry, `BaseDownloader`, `XeniumConverter`, and the pseudo-spot helpers in
`core.utils` -- that other modules build on but that isn't part of the documented, stable surface yet. Expect it to change
without notice; the four functions above are the supported way to use `spatialrefinery`.
without notice; the functions above are the supported way to use `spatialrefinery`.
:::
3 changes: 3 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ any zoom level.
* - Convert a whole-slide image to pyramidal OME-TIFF
- {py:obj}`~spatialrefinery.convert_to_ometiff`
- [Converting images to OME-TIFF](notebooks/convert_to_ometiff)
* - Segment nuclei in an H&E slide and store them as SpatialData
- {py:obj}`~spatialrefinery.segmentation.instanseg.segment_wsi`
- [Nucleus segmentation to SpatialData zarr](notebooks/segment_nuclei)
```

```{toctree}
Expand Down
13 changes: 13 additions & 0 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ pip install "spatialrefinery[czi] @ git+https://github.com/peng-lab/spatialrefin
Without the `czi` extra, {py:obj}`~spatialrefinery.convert_to_ometiff` still handles every other registered format
(`.svs`, `.ndpi`, `.tif`, `.tiff`, `.mrxs`, `.scn`, `.bif`, `.vms`, `.svslide`) -- only `.czi` requires it.

## Optional: nucleus segmentation

Nucleus segmentation on H&E whole-slide images needs the `segmentation` extra, which pulls
[InstanSeg](https://github.com/instanseg/instanseg) (`instanseg-torch`) plus `rasterio`, `geojson` and `tiffslide`:

```bash
pip install "spatialrefinery[segmentation] @ git+https://github.com/peng-lab/spatialrefinery.git"
```

It is kept optional because `instanseg-torch` brings torch and therefore multi-GB CUDA wheels, which most
`spatialrefinery` uses do not need. A CUDA GPU is strongly recommended -- see
[Nucleus segmentation to SpatialData zarr](notebooks/segment_nuclei).

## Verifying the install

```python
Expand Down
3 changes: 2 additions & 1 deletion docs/notebooks/convert_to_ometiff.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,8 @@
"source": [
"## What's next\n",
"\n",
"That's the full pipeline -- see the [API reference](../api.md) for the complete parameter list of each function used across these tutorials."
"Continue to [Nucleus segmentation to SpatialData zarr](segment_nuclei) to segment nuclei in the OME-TIFF you just\n",
"wrote and package them as a SpatialData zarr store."
]
}
],
Expand Down
Loading