{"name":"napari-harpy","display_name":"napari-harpy","visibility":"public","icon":"","categories":["Annotation"],"schema_version":"0.1.0","on_activate":null,"on_deactivate":null,"contributions":{"commands":[{"id":"napari-harpy.read_spatialdata_store","title":"Read SpatialData zarr store into Harpy state","python_name":"napari_harpy._reader:get_reader","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-harpy.viewer","title":"Open viewer widget","python_name":"napari_harpy.widgets.viewer.widget:ViewerWidget","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-harpy.feature_extraction","title":"Open feature extraction widget","python_name":"napari_harpy.widgets.feature_extraction.widget:FeatureExtractionWidget","short_title":null,"category":null,"icon":null,"enablement":null},{"id":"napari-harpy.object_classification","title":"Open object classification widget","python_name":"napari_harpy.widgets.object_classification.widget:ObjectClassificationWidget","short_title":null,"category":null,"icon":null,"enablement":null}],"readers":[{"command":"napari-harpy.read_spatialdata_store","filename_patterns":["*.zarr"],"accepts_directories":true}],"writers":null,"widgets":[{"command":"napari-harpy.viewer","display_name":"Viewer","autogenerate":false},{"command":"napari-harpy.feature_extraction","display_name":"Feature Extraction","autogenerate":false},{"command":"napari-harpy.object_classification","display_name":"Object Classification","autogenerate":false}],"sample_data":null,"themes":null,"menus":{},"submenus":null,"keybindings":null,"configuration":[]},"package_metadata":{"metadata_version":"2.4","name":"napari-harpy","version":"0.0.7","dynamic":null,"platform":null,"supported_platform":null,"summary":"A spatial omics interface for napari.","description":"<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/vibspatial/napari-harpy/main/docs/_static/logo.png\" alt=\"Harpy logo\" width=\"200\">\n</p>\n\n<h1 align=\"center\">napari-harpy: a spatial omics interface for napari.</h1>\n\n[![PyPI](https://img.shields.io/pypi/v/napari-harpy.svg)](https://pypi.org/project/napari-harpy/)\n\nBuilt around [`SpatialData`](https://spatialdata.scverse.org/en/stable/) and [`Harpy`](https://harpy.readthedocs.io/en/latest/) for interactive exploration, feature extraction, and object classification.\n\n`napari-harpy` is a napari plugin for viewing, exploring, and analyzing\n`SpatialData` datasets. It includes its own viewer for loading and\nbrowsing data inside napari, alongside feature extraction and interactive\nobject classification workflows.\n\n## Installation\n\nInstall from [PyPI](https://pypi.org/project/napari-harpy/):\n\n```bash\npip install napari-harpy\n```\n\n## Quickstart\n\nThe quickest way to try the plugin is to create a small example `SpatialData`\nobject, write it to a temporary zarr store, read it back as an on-disk dataset,\nand launch the Harpy napari interface with `Interactive`.\n\n```python\nimport tempfile\nfrom pathlib import Path\n\nfrom spatialdata import read_zarr\n\nfrom napari_harpy import Interactive\nfrom napari_harpy.datasets import blobs_multi_region\n\nzarr_path = Path(tempfile.mkdtemp()) / \"blobs_multi_region.zarr\"\n\nsdata = blobs_multi_region()\nsdata.write(zarr_path)\n\nsdata = read_zarr(zarr_path)\nInteractive(sdata)\n```\n\nThis opens napari with the Harpy widgets docked and the\n`blobs_multi_region` dataset available in the shared viewer state.\n\nThe current repository contains three working widgets:\n\n- `Viewer`\n- `Feature Extraction`\n- `Object Classification`\n\nToday the plugin supports:\n\n- loading and viewing `SpatialData` through the Harpy viewer widget\n- selecting a labels element, optional image, compatible coordinate system, and\n  linked table from the shared loaded `SpatialData`\n- calculating intensity and morphology features through Harpy\n- writing feature matrices into the selected `AnnData` table linked to the\n  labels element, as `.obsm[feature_key]`, with companion metadata in\n  `.uns[\"feature_matrices\"][feature_key]`\n- interactive manual annotation of instances in labels elements\n- background `RandomForestClassifier` retraining on the selected feature\n  matrix stored in `.obsm[feature_key]` of the `AnnData` table linked to the\n  labels element\n- live prediction updates and labels recoloring\n- explicit write-back of in-memory table state to zarr\n- explicit reload of on-disk table state back into memory\n- multi-sample workflows through multi-region tables and explicit\n  labels/image/coordinate-system matching\n- headless feature extraction and classifier application for scripted or batch\n  processing\n\nExample napari-harpy session:\n\n<p align=\"center\">\n  <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\">\n</p>\n\n<p align=\"center\">\n  <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\">\n</p>\n\n## Headless and Multi-Sample Workflows\n\nFor scripted or batch processing, use the public `napari_harpy.headless` module.\nIt can apply an exported classifier to an existing feature matrix, or compute\nthe required features before applying the classifier.\n\nThe headless APIs accept one labels element or a sequence of labels elements.\nFor multi-sample data, pass matching labels, image, and coordinate-system\nsequences so Harpy can build or apply a shared table-level feature matrix across\nthe selected samples. When features need image intensities, the channel\nselection is read from the exported classifier's `source_channels` metadata.\n\n```python\nfrom spatialdata import read_zarr\n\nfrom napari_harpy import headless\n\nsdata = read_zarr(\"experiment.zarr\")\n\nresult = headless.apply_classifier_with_feature_extraction_from_path(\n    sdata,\n    \"classifier.harpy-classifier.joblib\",\n    table_name=\"table_multi\",\n    labels_name=[\"sample_1_labels\", \"sample_2_labels\"],\n    coordinate_system=[\"sample_1\", \"sample_2\"],\n    image_name=[\"sample_1_image\", \"sample_2_image\"],\n)\n```\n\n## Local development\n\nCreate the development environment:\n\n```bash\n./create_env.sh\n```\n\nThen launch napari:\n\n```bash\nsource .venv/bin/activate\nnapari\n```\n\nOpen the widgets from the napari plugin menu:\n\n- `Plugins -> napari-harpy -> Viewer`\n- `Plugins -> napari-harpy -> Feature Extraction`\n- `Plugins -> napari-harpy -> Object Classification`\n\n## Debug script\n\nA small local debug script is available at\n[`scripts/debug_widget.py`](scripts/debug_widget.py).\n\nIt creates a temporary `blobs_multi_region` zarr store, loads it into napari,\nand docks the Harpy widgets automatically.\nThis is useful for quickly reproducing widget behavior during development.\n\nRun it with:\n\n```bash\nsource .venv/bin/activate\npython scripts/debug_widget.py\n```\n","description_content_type":"text/markdown","keywords":"anndata,image-analysis,napari,object-classification,plugin,spatialdata","home_page":null,"download_url":null,"author":"VIB spatial catalyst","author_email":null,"maintainer":null,"maintainer_email":null,"license":"BSD 3-Clause License\n\nCopyright (c) 2026, VIB spatial catalyst\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n1. Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n2. Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n3. Neither the name of the copyright holder nor the names of its\n   contributors may be used to endorse or promote products derived from\n   this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.","classifier":["Development Status :: 4 - Beta","Framework :: napari","Intended Audience :: Developers","Intended Audience :: Science/Research","License :: OSI Approved :: BSD License","Operating System :: OS Independent","Programming Language :: Python","Programming Language :: Python :: 3","Programming Language :: Python :: 3 :: Only","Programming Language :: Python :: 3.11","Programming Language :: Python :: 3.12","Programming Language :: Python :: 3.13","Programming Language :: Python :: 3.14","Topic :: Scientific/Engineering :: Bio-Informatics","Topic :: Scientific/Engineering :: Image Processing"],"requires_dist":["dask[dataframe]","harpy-analysis>=0.4.0","joblib","lazy-loader>=0.4","loguru","napari[all]>=0.4.18","pandas<3.0","pyarrow","myst-nb; extra == 'dev'","pre-commit; extra == 'dev'","pytest; extra == 'dev'","pytest-cov; extra == 'dev'","pytest-qt; extra == 'dev'","ruff; extra == 'dev'","sphinx-autodoc-typehints; extra == 'dev'","sphinx-book-theme>=1.0.0; extra == 'dev'","sphinx-copybutton; extra == 'dev'","sphinx-design; extra == 'dev'","sphinx-rtd-theme; extra == 'dev'","sphinx>=4.5; extra == 'dev'","sphinxcontrib-bibtex>=1.0.0; extra == 'dev'","tox; extra == 'dev'","twine>=4.0.2; extra == 'dev'","myst-nb; extra == 'docs'","sphinx-autodoc-typehints; extra == 'docs'","sphinx-book-theme>=1.0.0; extra == 'docs'","sphinx-copybutton; extra == 'docs'","sphinx-design; extra == 'docs'","sphinx-rtd-theme; extra == 'docs'","sphinx>=4.5; extra == 'docs'","sphinxcontrib-bibtex>=1.0.0; extra == 'docs'","pytest; extra == 'test'","pytest-cov; extra == 'test'","pytest-qt; extra == 'test'","tox; extra == 'test'"],"requires_python":"<3.15,>=3.11","requires_external":null,"project_url":["Homepage, https://github.com/vibspatial/napari-harpy","Documentation, https://github.com/vibspatial/napari-harpy#readme","Repository, https://github.com/vibspatial/napari-harpy","Issues, https://github.com/vibspatial/napari-harpy/issues","Changelog, https://github.com/vibspatial/napari-harpy/releases","Paper, https://doi.org/10.1093/bioinformatics/btag122","SaeysLab, https://saeyslab.sites.vib.be/en","VIBSpatialCatalyst, https://vib.be/en/technologies/technology-portfolio/spatial-catalyst"],"provides_extra":["dev","docs","test"],"provides_dist":null,"obsoletes_dist":null},"npe1_shim":false}