Metadata-Version: 2.4
Name: napari-harpy
Version: 0.0.4
Summary: A spatial omics interface for napari.
Project-URL: Homepage, https://github.com/vibspatial/napari-harpy
Project-URL: Documentation, https://github.com/vibspatial/napari-harpy#readme
Project-URL: Repository, https://github.com/vibspatial/napari-harpy
Project-URL: Issues, https://github.com/vibspatial/napari-harpy/issues
Project-URL: Changelog, https://github.com/vibspatial/napari-harpy/releases
Project-URL: Paper, https://doi.org/10.1093/bioinformatics/btag122
Project-URL: SaeysLab, https://saeyslab.sites.vib.be/en
Project-URL: VIBSpatialCatalyst, https://vib.be/en/technologies/technology-portfolio/spatial-catalyst
Author: VIB spatial catalyst
License: BSD 3-Clause License
        
        Copyright (c) 2026, VIB spatial catalyst
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
        modification, are permitted provided that the following conditions are met:
        
        1. Redistributions of source code must retain the above copyright notice, this
           list of conditions and the following disclaimer.
        
        2. Redistributions in binary form must reproduce the above copyright notice,
           this list of conditions and the following disclaimer in the documentation
           and/or other materials provided with the distribution.
        
        3. Neither the name of the copyright holder nor the names of its
           contributors may be used to endorse or promote products derived from
           this software without specific prior written permission.
        
        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
        AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
        FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
        CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
        OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License-File: LICENSE
Keywords: anndata,image-analysis,napari,object-classification,plugin,spatialdata
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: napari
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
Classifier: Topic :: Scientific/Engineering :: Image Processing
Requires-Python: <3.15,>=3.11
Requires-Dist: dask[dataframe]
Requires-Dist: harpy-analysis>=0.4.0
Requires-Dist: joblib
Requires-Dist: lazy-loader>=0.4
Requires-Dist: loguru
Requires-Dist: napari[all]>=0.4.18
Requires-Dist: pandas<3.0
Requires-Dist: pyarrow
Provides-Extra: dev
Requires-Dist: myst-nb; extra == 'dev'
Requires-Dist: pre-commit; extra == 'dev'
Requires-Dist: pytest; extra == 'dev'
Requires-Dist: pytest-cov; extra == 'dev'
Requires-Dist: pytest-qt; extra == 'dev'
Requires-Dist: ruff; extra == 'dev'
Requires-Dist: sphinx-autodoc-typehints; extra == 'dev'
Requires-Dist: sphinx-book-theme>=1.0.0; extra == 'dev'
Requires-Dist: sphinx-copybutton; extra == 'dev'
Requires-Dist: sphinx-design; extra == 'dev'
Requires-Dist: sphinx-rtd-theme; extra == 'dev'
Requires-Dist: sphinx>=4.5; extra == 'dev'
Requires-Dist: sphinxcontrib-bibtex>=1.0.0; extra == 'dev'
Requires-Dist: tox; extra == 'dev'
Requires-Dist: twine>=4.0.2; extra == 'dev'
Provides-Extra: docs
Requires-Dist: myst-nb; extra == 'docs'
Requires-Dist: sphinx-autodoc-typehints; extra == 'docs'
Requires-Dist: sphinx-book-theme>=1.0.0; extra == 'docs'
Requires-Dist: sphinx-copybutton; extra == 'docs'
Requires-Dist: sphinx-design; extra == 'docs'
Requires-Dist: sphinx-rtd-theme; extra == 'docs'
Requires-Dist: sphinx>=4.5; extra == 'docs'
Requires-Dist: sphinxcontrib-bibtex>=1.0.0; extra == 'docs'
Provides-Extra: test
Requires-Dist: pytest; extra == 'test'
Requires-Dist: pytest-cov; extra == 'test'
Requires-Dist: pytest-qt; extra == 'test'
Requires-Dist: tox; extra == 'test'
Description-Content-Type: text/markdown

<p align="center">
  <img src="https://raw.githubusercontent.com/vibspatial/napari-harpy/main/docs/_static/logo.png" alt="Harpy logo" width="200">
</p>

<h1 align="center">napari-harpy: a spatial omics interface for napari.</h1>

[![PyPI](https://img.shields.io/pypi/v/napari-harpy.svg)](https://pypi.org/project/napari-harpy/)

Built around [`SpatialData`](https://spatialdata.scverse.org/en/stable/) and [`Harpy`](https://harpy.readthedocs.io/en/latest/) for interactive exploration, feature extraction, and object classification.

`napari-harpy` is a napari plugin for viewing, exploring, and analyzing
`SpatialData` datasets. It includes its own viewer for loading and
browsing data inside napari, alongside feature extraction and interactive
object classification workflows.

## Installation

Install from [PyPI](https://pypi.org/project/napari-harpy/):

```bash
pip install napari-harpy
```

## Quickstart

The quickest way to try the plugin is to create a small example `SpatialData`
object, write it to a temporary zarr store, read it back as an on-disk dataset,
and launch the Harpy napari interface with `Interactive`.

```python
import tempfile
from pathlib import Path

from spatialdata import read_zarr

from napari_harpy import Interactive
from napari_harpy.datasets import blobs_multi_region

zarr_path = Path(tempfile.mkdtemp()) / "blobs_multi_region.zarr"

sdata = blobs_multi_region()
sdata.write(zarr_path)

sdata = read_zarr(zarr_path)
Interactive(sdata)
```

This opens napari with the Harpy widgets docked and the
`blobs_multi_region` dataset available in the shared viewer state.

The current repository contains three working widgets:

- `Viewer`
- `Feature Extraction`
- `Object Classification`

Today the plugin supports:

- loading and viewing `SpatialData` through the Harpy viewer widget
- selecting a labels element, optional image, compatible coordinate system, and
  linked table from the shared loaded `SpatialData`
- calculating intensity and morphology features through Harpy
- writing feature matrices into the selected `AnnData` table linked to the
  labels element, as `.obsm[feature_key]`, with companion metadata in
  `.uns["feature_matrices"][feature_key]`
- interactive manual annotation of instances in labels elements
- background `RandomForestClassifier` retraining on the selected feature
  matrix stored in `.obsm[feature_key]` of the `AnnData` table linked to the
  labels element
- live prediction updates and labels recoloring
- explicit write-back of in-memory table state to zarr
- explicit reload of on-disk table state back into memory
- multi-sample workflows through multi-region tables and explicit
  labels/image/coordinate-system matching
- headless feature extraction and classifier application for scripted or batch
  processing

Example napari-harpy session:

<p align="center">
  <img src="https://raw.githubusercontent.com/vibspatial/napari-harpy/main/docs/_static/Screenshot%202026-05-19%20at%2014.25.23.png" alt="napari-harpy viewer example screenshot" width="900">
</p>

<p align="center">
  <img src="https://raw.githubusercontent.com/vibspatial/napari-harpy/main/docs/_static/Screenshot%202026-05-09%20at%2021.31.53.png" alt="napari-harpy object classification example screenshot" width="900">
</p>

## Headless and Multi-Sample Workflows

For scripted or batch processing, use the public `napari_harpy.headless` module.
It can apply an exported classifier to an existing feature matrix, or compute
the required features before applying the classifier.

The headless APIs accept one labels element or a sequence of labels elements.
For multi-sample data, pass matching labels, image, and coordinate-system
sequences so Harpy can build or apply a shared table-level feature matrix across
the selected samples.

```python
from spatialdata import read_zarr

from napari_harpy import headless

sdata = read_zarr("experiment.zarr")

result = headless.apply_classifier_with_feature_extraction_from_path(
    sdata,
    "classifier.harpy-classifier.joblib",
    table_name="table_multi",
    labels_name=["sample_1_labels", "sample_2_labels"],
    coordinate_system=["sample_1", "sample_2"],
    image_name=["sample_1_image", "sample_2_image"],
)
```

## Local development

Create the development environment:

```bash
./create_env.sh
```

Then launch napari:

```bash
source .venv/bin/activate
napari
```

Open the widgets from the napari plugin menu:

- `Plugins -> napari-harpy -> Viewer`
- `Plugins -> napari-harpy -> Feature Extraction`
- `Plugins -> napari-harpy -> Object Classification`

## Debug script

A small local debug script is available at
[`scripts/debug_widget.py`](scripts/debug_widget.py).

It creates a temporary `blobs_multi_region` zarr store, loads it into napari,
and docks the Harpy widgets automatically.
This is useful for quickly reproducing widget behavior during development.

Run it with:

```bash
source .venv/bin/activate
python scripts/debug_widget.py
```
