spatiato 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. spatiato-0.2.0/.claude/settings.json +42 -0
  2. spatiato-0.2.0/.github/workflows/release.yaml +39 -0
  3. spatiato-0.2.0/.gitignore +129 -0
  4. spatiato-0.2.0/AGENTS.md +44 -0
  5. spatiato-0.2.0/CLAUDE.md +18 -0
  6. spatiato-0.2.0/LICENSE +29 -0
  7. spatiato-0.2.0/PKG-INFO +282 -0
  8. spatiato-0.2.0/README.md +174 -0
  9. spatiato-0.2.0/Roadmap/annotate_holes/annotation_widget_holes.md +1117 -0
  10. spatiato-0.2.0/Roadmap/annotate_holes/edit_anchors.md +1543 -0
  11. spatiato-0.2.0/Roadmap/annotation_fixes/annotation.md +1709 -0
  12. spatiato-0.2.0/Roadmap/annotation_fixes/magic_wand.md +768 -0
  13. spatiato-0.2.0/Roadmap/annotation_fixes/radius_based_move.md +251 -0
  14. spatiato-0.2.0/Roadmap/annotation_fixes/rendering_issue.md +695 -0
  15. spatiato-0.2.0/Roadmap/annotation_fixes/slow_annotation.md +126 -0
  16. spatiato-0.2.0/Roadmap/colormap/colormap.md +393 -0
  17. spatiato-0.2.0/Roadmap/create_table_feature_extraction/create_table.md +947 -0
  18. spatiato-0.2.0/Roadmap/dask_backed_tables.md +237 -0
  19. spatiato-0.2.0/Roadmap/feature_extraction_roadmap/feature_extraction.md +682 -0
  20. spatiato-0.2.0/Roadmap/feature_extraction_roadmap/feature_extraction_channel_selection.md +208 -0
  21. spatiato-0.2.0/Roadmap/feature_extraction_roadmap/napari_spatialdata_independance.md +419 -0
  22. spatiato-0.2.0/Roadmap/harpy_stale_zarr/cleanup.md +282 -0
  23. spatiato-0.2.0/Roadmap/headless/headless_roadmap.md +904 -0
  24. spatiato-0.2.0/Roadmap/issue_cache_adata.md +215 -0
  25. spatiato-0.2.0/Roadmap/issue_napari_spatialdata.md +504 -0
  26. spatiato-0.2.0/Roadmap/issue_points_rendering.md +562 -0
  27. spatiato-0.2.0/Roadmap/multiple_coordinate_systems/cross_sample_tables.md +760 -0
  28. spatiato-0.2.0/Roadmap/multiple_coordinate_systems/multiple_coordinate_systems.md +614 -0
  29. spatiato-0.2.0/Roadmap/multiple_coordinate_systems/multiple_samples_feature_extraction_widget.md +926 -0
  30. spatiato-0.2.0/Roadmap/multiple_coordinate_systems/object_classifier.md +892 -0
  31. spatiato-0.2.0/Roadmap/multiplex_viewing_optimization/optimize_multiplex.md +55 -0
  32. spatiato-0.2.0/Roadmap/object_classification_custom/highlight_upon_click.md +210 -0
  33. spatiato-0.2.0/Roadmap/pixel_classification/comments.md +44 -0
  34. spatiato-0.2.0/Roadmap/pixel_classification/comments_20_6_26.md +66 -0
  35. spatiato-0.2.0/Roadmap/pixel_classification/comments_27_7_26.md +98 -0
  36. spatiato-0.2.0/Roadmap/pixel_classification/pixel_classification.md +333 -0
  37. spatiato-0.2.0/Roadmap/pixel_classification/pixel_classification_17_7_26.md +2460 -0
  38. spatiato-0.2.0/Roadmap/pixel_classification/pixel_classification_phase_1.md +1323 -0
  39. spatiato-0.2.0/Roadmap/roadmap.md +194 -0
  40. spatiato-0.2.0/Roadmap/shapes_elements/add_new_shapes.md +1567 -0
  41. spatiato-0.2.0/Roadmap/shapes_elements/annotation_shapes.md +193 -0
  42. spatiato-0.2.0/Roadmap/shapes_elements/rendering_benchmark.md +344 -0
  43. spatiato-0.2.0/Roadmap/spec_phase_6.md +476 -0
  44. spatiato-0.2.0/Roadmap/tickets_phase_6.md +407 -0
  45. spatiato-0.2.0/Roadmap/transcripts_visualization/cache_construction_zarr.md +7133 -0
  46. spatiato-0.2.0/Roadmap/transcripts_visualization/comments.md +34 -0
  47. spatiato-0.2.0/Roadmap/transcripts_visualization/comments_16_9_26.md +73 -0
  48. spatiato-0.2.0/Roadmap/transcripts_visualization/comments_28_7_26.md +201 -0
  49. spatiato-0.2.0/Roadmap/transcripts_visualization/comments_cache_5_8_26.md +601 -0
  50. spatiato-0.2.0/Roadmap/transcripts_visualization/comments_slow_rendering_26_8_26.md +2657 -0
  51. spatiato-0.2.0/Roadmap/transcripts_visualization/compare_to_xenium.md +891 -0
  52. spatiato-0.2.0/Roadmap/transcripts_visualization/metadata_cache_1_9_26.md +581 -0
  53. spatiato-0.2.0/Roadmap/transcripts_visualization/multi_tile_cache_29_7_26.md +2665 -0
  54. spatiato-0.2.0/Roadmap/transcripts_visualization/napari_integration_10_8_26.md +971 -0
  55. spatiato-0.2.0/Roadmap/transcripts_visualization/napari_integration_21_8_26.md +3339 -0
  56. spatiato-0.2.0/Roadmap/transcripts_visualization/persistent_cache_construction_5_8_26.md +3118 -0
  57. spatiato-0.2.0/Roadmap/transcripts_visualization/sampler_17_9_26.md +123 -0
  58. spatiato-0.2.0/Roadmap/viewer/sync_napari.md +391 -0
  59. spatiato-0.2.0/create_env.sh +16 -0
  60. spatiato-0.2.0/docs/_static/Screenshot 2026-05-09 at 21.31.53.png +0 -0
  61. spatiato-0.2.0/docs/_static/Screenshot 2026-05-19 at 14.25.23.png +0 -0
  62. spatiato-0.2.0/docs/_static/object_classification.png +0 -0
  63. spatiato-0.2.0/docs/_static/viewer.png +0 -0
  64. spatiato-0.2.0/pyproject.toml +190 -0
  65. spatiato-0.2.0/scripts/benchmark_multi_scale_cache_points_zarr_acceptance.py +573 -0
  66. spatiato-0.2.0/scripts/benchmark_multi_scale_cache_points_zarr_bridge.py +352 -0
  67. spatiato-0.2.0/scripts/benchmark_multi_scale_cache_points_zarr_bucket.py +172 -0
  68. spatiato-0.2.0/scripts/benchmark_multi_scale_cache_points_zarr_catalog.py +670 -0
  69. spatiato-0.2.0/scripts/benchmark_multi_scale_cache_points_zarr_exact.py +549 -0
  70. spatiato-0.2.0/scripts/benchmark_multi_scale_cache_points_zarr_selected_value_index.py +554 -0
  71. spatiato-0.2.0/scripts/benchmark_multi_scale_cache_points_zarr_source_validation.py +307 -0
  72. spatiato-0.2.0/scripts/benchmark_multi_scale_cache_points_zarr_spatial.py +541 -0
  73. spatiato-0.2.0/scripts/benchmark_tiled_points_cache_to_canvas.py +961 -0
  74. spatiato-0.2.0/scripts/benchmark_tiled_points_retained_viewport.py +513 -0
  75. spatiato-0.2.0/scripts/benchmark_tiled_points_viewport_planning.py +230 -0
  76. spatiato-0.2.0/scripts/build_tiled_points_cache_variant.py +262 -0
  77. spatiato-0.2.0/scripts/debug_view_widget.py +67 -0
  78. spatiato-0.2.0/scripts/debug_widget.py +32 -0
  79. spatiato-0.2.0/scripts/profile_multi_scale_cache_points_zarr_bridge.py +370 -0
  80. spatiato-0.2.0/scripts/release_tag.sh +90 -0
  81. spatiato-0.2.0/scripts/validate_multi_scale_cache_points_zarr_exhaustive.py +495 -0
  82. spatiato-0.2.0/scripts/xenium_point_radius_shapes_viewer.py +103 -0
  83. spatiato-0.2.0/src/spatiato/__init__.py +37 -0
  84. spatiato-0.2.0/src/spatiato/_app_state.py +824 -0
  85. spatiato-0.2.0/src/spatiato/_interactive.py +152 -0
  86. spatiato-0.2.0/src/spatiato/_points_value_index.py +697 -0
  87. spatiato-0.2.0/src/spatiato/_reader.py +113 -0
  88. spatiato-0.2.0/src/spatiato/_resources.py +11 -0
  89. spatiato-0.2.0/src/spatiato/_shapes_triangulation.py +37 -0
  90. spatiato-0.2.0/src/spatiato/_static/logo.svg +102 -0
  91. spatiato-0.2.0/src/spatiato/_transcript_tiles.py +855 -0
  92. spatiato-0.2.0/src/spatiato/core/__init__.py +0 -0
  93. spatiato-0.2.0/src/spatiato/core/_color_source.py +97 -0
  94. spatiato-0.2.0/src/spatiato/core/class_palette.py +243 -0
  95. spatiato-0.2.0/src/spatiato/core/feature_extraction.py +183 -0
  96. spatiato-0.2.0/src/spatiato/core/feature_matrix_metadata.py +351 -0
  97. spatiato-0.2.0/src/spatiato/core/histogram.py +250 -0
  98. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/CACHE_FORMAT.md +779 -0
  99. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/__init__.py +1 -0
  100. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/build_plan.py +342 -0
  101. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/builder.py +409 -0
  102. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/cache_format.py +886 -0
  103. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/cache_location.py +23 -0
  104. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/hashing.py +83 -0
  105. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/models.py +124 -0
  106. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/payload.py +104 -0
  107. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/reader.py +2367 -0
  108. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/sampling.py +276 -0
  109. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/source/__init__.py +23 -0
  110. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/source/errors.py +31 -0
  111. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/source/models.py +291 -0
  112. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/source/resolution.py +64 -0
  113. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/source/signature.py +121 -0
  114. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/source/validation.py +750 -0
  115. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/source/value_normalization.py +38 -0
  116. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/__init__.py +1 -0
  117. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/_paths.py +53 -0
  118. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/_row_selection.py +45 -0
  119. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/_schema.py +249 -0
  120. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/bucket_reader.py +531 -0
  121. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/bucket_validation.py +379 -0
  122. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/bucket_writer.py +597 -0
  123. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/catalog_reader.py +800 -0
  124. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/catalog_writer.py +594 -0
  125. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/models.py +294 -0
  126. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/reader_cache.py +103 -0
  127. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/storage/value_major_reader.py +232 -0
  128. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/writer/__init__.py +1 -0
  129. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/writer/bridge.py +318 -0
  130. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/writer/catalog.py +545 -0
  131. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/writer/exact.py +856 -0
  132. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/writer/spatial.py +623 -0
  133. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/writer/staging_validation.py +623 -0
  134. spatiato-0.2.0/src/spatiato/core/multi_scale_cache_points_zarr/writer/value_major.py +499 -0
  135. spatiato-0.2.0/src/spatiato/core/object_classification/__init__.py +1 -0
  136. spatiato-0.2.0/src/spatiato/core/object_classification/annotation.py +192 -0
  137. spatiato-0.2.0/src/spatiato/core/object_classification/classifier.py +679 -0
  138. spatiato-0.2.0/src/spatiato/core/object_classification/classifier_export.py +310 -0
  139. spatiato-0.2.0/src/spatiato/core/persistence.py +416 -0
  140. spatiato-0.2.0/src/spatiato/core/shapes_annotation.py +830 -0
  141. spatiato-0.2.0/src/spatiato/core/shapes_geometry.py +875 -0
  142. spatiato-0.2.0/src/spatiato/core/spatial_query/__init__.py +115 -0
  143. spatiato-0.2.0/src/spatiato/core/spatial_query/annotation.py +664 -0
  144. spatiato-0.2.0/src/spatiato/core/spatial_query/canonical.py +892 -0
  145. spatiato-0.2.0/src/spatiato/core/spatial_query/canonical_models.py +448 -0
  146. spatiato-0.2.0/src/spatiato/core/spatial_query/centroids.py +162 -0
  147. spatiato-0.2.0/src/spatiato/core/spatial_query/query.py +113 -0
  148. spatiato-0.2.0/src/spatiato/core/spatial_query/query_models.py +129 -0
  149. spatiato-0.2.0/src/spatiato/core/spatialdata.py +934 -0
  150. spatiato-0.2.0/src/spatiato/core/spatialdata_io/__init__.py +13 -0
  151. spatiato-0.2.0/src/spatiato/core/spatialdata_io/shapes.py +478 -0
  152. spatiato-0.2.0/src/spatiato/core/validation.py +59 -0
  153. spatiato-0.2.0/src/spatiato/datasets.py +94 -0
  154. spatiato-0.2.0/src/spatiato/headless.py +534 -0
  155. spatiato-0.2.0/src/spatiato/napari.yaml +41 -0
  156. spatiato-0.2.0/src/spatiato/viewer/__init__.py +0 -0
  157. spatiato-0.2.0/src/spatiato/viewer/_styling.py +236 -0
  158. spatiato-0.2.0/src/spatiato/viewer/adapter.py +2974 -0
  159. spatiato-0.2.0/src/spatiato/viewer/image_styling.py +35 -0
  160. spatiato-0.2.0/src/spatiato/viewer/labels_async.py +175 -0
  161. spatiato-0.2.0/src/spatiato/viewer/labels_colormap.py +955 -0
  162. spatiato-0.2.0/src/spatiato/viewer/labels_styling.py +338 -0
  163. spatiato-0.2.0/src/spatiato/viewer/points_styling.py +236 -0
  164. spatiato-0.2.0/src/spatiato/viewer/shapes_styling.py +1170 -0
  165. spatiato-0.2.0/src/spatiato/viewer/tiled_points/__init__.py +31 -0
  166. spatiato-0.2.0/src/spatiato/viewer/tiled_points/application.py +107 -0
  167. spatiato-0.2.0/src/spatiato/viewer/tiled_points/contracts.py +642 -0
  168. spatiato-0.2.0/src/spatiato/viewer/tiled_points/napari/__init__.py +13 -0
  169. spatiato-0.2.0/src/spatiato/viewer/tiled_points/napari/controls.py +90 -0
  170. spatiato-0.2.0/src/spatiato/viewer/tiled_points/napari/layer.py +361 -0
  171. spatiato-0.2.0/src/spatiato/viewer/tiled_points/napari/registration.py +158 -0
  172. spatiato-0.2.0/src/spatiato/viewer/tiled_points/napari/viewport.py +131 -0
  173. spatiato-0.2.0/src/spatiato/viewer/tiled_points/render_batch.py +146 -0
  174. spatiato-0.2.0/src/spatiato/viewer/tiled_points/runtime/RUNTIME_FLOW.md +332 -0
  175. spatiato-0.2.0/src/spatiato/viewer/tiled_points/runtime/__init__.py +19 -0
  176. spatiato-0.2.0/src/spatiato/viewer/tiled_points/runtime/cache_session.py +1116 -0
  177. spatiato-0.2.0/src/spatiato/viewer/tiled_points/runtime/layer_runtime.py +610 -0
  178. spatiato-0.2.0/src/spatiato/viewer/tiled_points/runtime/lod.py +112 -0
  179. spatiato-0.2.0/src/spatiato/viewer/tiled_points/runtime/residency.py +172 -0
  180. spatiato-0.2.0/src/spatiato/viewer/tiled_points/runtime/viewport_scheduler.py +487 -0
  181. spatiato-0.2.0/src/spatiato/viewer/tiled_points/vispy/__init__.py +5 -0
  182. spatiato-0.2.0/src/spatiato/viewer/tiled_points/vispy/layer.py +339 -0
  183. spatiato-0.2.0/src/spatiato/viewer/tiled_points/vispy/visuals.py +319 -0
  184. spatiato-0.2.0/src/spatiato/widgets/__init__.py +34 -0
  185. spatiato-0.2.0/src/spatiato/widgets/annotation/__init__.py +19 -0
  186. spatiato-0.2.0/src/spatiato/widgets/annotation/models.py +95 -0
  187. spatiato-0.2.0/src/spatiato/widgets/annotation/widget.py +464 -0
  188. spatiato-0.2.0/src/spatiato/widgets/feature_extraction/__init__.py +1 -0
  189. spatiato-0.2.0/src/spatiato/widgets/feature_extraction/controller.py +845 -0
  190. spatiato-0.2.0/src/spatiato/widgets/feature_extraction/status_card.py +211 -0
  191. spatiato-0.2.0/src/spatiato/widgets/feature_extraction/widget.py +2557 -0
  192. spatiato-0.2.0/src/spatiato/widgets/histogram/__init__.py +5 -0
  193. spatiato-0.2.0/src/spatiato/widgets/histogram/controller.py +301 -0
  194. spatiato-0.2.0/src/spatiato/widgets/histogram/plot_widget.py +596 -0
  195. spatiato-0.2.0/src/spatiato/widgets/histogram/status_card.py +72 -0
  196. spatiato-0.2.0/src/spatiato/widgets/histogram/styles.py +19 -0
  197. spatiato-0.2.0/src/spatiato/widgets/histogram/widget.py +1811 -0
  198. spatiato-0.2.0/src/spatiato/widgets/image_layer_row.py +297 -0
  199. spatiato-0.2.0/src/spatiato/widgets/object_classification/__init__.py +1 -0
  200. spatiato-0.2.0/src/spatiato/widgets/object_classification/annotation_controller.py +446 -0
  201. spatiato-0.2.0/src/spatiato/widgets/object_classification/controller.py +1353 -0
  202. spatiato-0.2.0/src/spatiato/widgets/object_classification/feature_matrix_registration.py +76 -0
  203. spatiato-0.2.0/src/spatiato/widgets/object_classification/status_card.py +270 -0
  204. spatiato-0.2.0/src/spatiato/widgets/object_classification/viewer_styling.py +519 -0
  205. spatiato-0.2.0/src/spatiato/widgets/object_classification/widget.py +1759 -0
  206. spatiato-0.2.0/src/spatiato/widgets/overlay_color_button.py +131 -0
  207. spatiato-0.2.0/src/spatiato/widgets/persistence/__init__.py +6 -0
  208. spatiato-0.2.0/src/spatiato/widgets/persistence/controller.py +196 -0
  209. spatiato-0.2.0/src/spatiato/widgets/persistence/controls.py +374 -0
  210. spatiato-0.2.0/src/spatiato/widgets/shapes_annotation/__init__.py +2 -0
  211. spatiato-0.2.0/src/spatiato/widgets/shapes_annotation/_create_holes.py +199 -0
  212. spatiato-0.2.0/src/spatiato/widgets/shapes_annotation/_edit_guard.py +1213 -0
  213. spatiato-0.2.0/src/spatiato/widgets/shapes_annotation/_identity_feature_defaults.py +160 -0
  214. spatiato-0.2.0/src/spatiato/widgets/shapes_annotation/_layer_state.py +86 -0
  215. spatiato-0.2.0/src/spatiato/widgets/shapes_annotation/_layer_style.py +91 -0
  216. spatiato-0.2.0/src/spatiato/widgets/shapes_annotation/_snapshot.py +98 -0
  217. spatiato-0.2.0/src/spatiato/widgets/shapes_annotation/status_card.py +340 -0
  218. spatiato-0.2.0/src/spatiato/widgets/shapes_annotation/widget.py +1740 -0
  219. spatiato-0.2.0/src/spatiato/widgets/shared_styles.py +548 -0
  220. spatiato-0.2.0/src/spatiato/widgets/spatial_query/__init__.py +23 -0
  221. spatiato-0.2.0/src/spatiato/widgets/spatial_query/controller.py +417 -0
  222. spatiato-0.2.0/src/spatiato/widgets/spatial_query/status_card.py +266 -0
  223. spatiato-0.2.0/src/spatiato/widgets/spatial_query/viewer_styling.py +116 -0
  224. spatiato-0.2.0/src/spatiato/widgets/spatial_query/widget.py +1409 -0
  225. spatiato-0.2.0/src/spatiato/widgets/spatialdata_replacement_dialog.py +52 -0
  226. spatiato-0.2.0/src/spatiato/widgets/viewer/__init__.py +1 -0
  227. spatiato-0.2.0/src/spatiato/widgets/viewer/disclosure.py +227 -0
  228. spatiato-0.2.0/src/spatiato/widgets/viewer/image_widget.py +726 -0
  229. spatiato-0.2.0/src/spatiato/widgets/viewer/labels_widget.py +345 -0
  230. spatiato-0.2.0/src/spatiato/widgets/viewer/points_controller.py +734 -0
  231. spatiato-0.2.0/src/spatiato/widgets/viewer/points_widget.py +469 -0
  232. spatiato-0.2.0/src/spatiato/widgets/viewer/shapes_widget.py +399 -0
  233. spatiato-0.2.0/src/spatiato/widgets/viewer/status_card.py +338 -0
  234. spatiato-0.2.0/src/spatiato/widgets/viewer/styles.py +30 -0
  235. spatiato-0.2.0/src/spatiato/widgets/viewer/tiled_points_controller.py +342 -0
  236. spatiato-0.2.0/src/spatiato/widgets/viewer/widget.py +1763 -0
  237. spatiato-0.2.0/tests/_shapes_regression_fixtures.py +164 -0
  238. spatiato-0.2.0/tests/conftest.py +129 -0
  239. spatiato-0.2.0/tests/fixtures/create_holes_triangulation_failure.txt +570 -0
  240. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/conftest.py +170 -0
  241. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_benchmark_readers.py +240 -0
  242. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_bridge_writer.py +345 -0
  243. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_bucket_reader.py +347 -0
  244. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_bucket_validation.py +162 -0
  245. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_bucket_writer.py +176 -0
  246. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_build_plan.py +217 -0
  247. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_builder.py +287 -0
  248. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_cache_format.py +121 -0
  249. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_catalog_reader.py +109 -0
  250. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_catalog_writer.py +250 -0
  251. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_compact_tile_addressing.py +259 -0
  252. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_exact_writer.py +426 -0
  253. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_exhaustive_validation.py +257 -0
  254. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_hashing.py +73 -0
  255. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_models.py +204 -0
  256. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_payload.py +121 -0
  257. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_reader.py +779 -0
  258. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_reader_cache.py +121 -0
  259. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_sampling.py +266 -0
  260. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_source_inventory.py +141 -0
  261. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_source_models.py +77 -0
  262. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_source_resolution.py +44 -0
  263. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_source_scan.py +250 -0
  264. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_source_signature.py +104 -0
  265. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_source_validation.py +204 -0
  266. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_spatial_writer.py +580 -0
  267. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_staging_validation.py +187 -0
  268. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_value_major_level_reader.py +247 -0
  269. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_value_major_reader_lifecycle.py +158 -0
  270. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_value_major_viewport_reads.py +665 -0
  271. spatiato-0.2.0/tests/multi_scale_cache_points_zarr/test_value_major_writer.py +284 -0
  272. spatiato-0.2.0/tests/test_annotation.py +197 -0
  273. spatiato-0.2.0/tests/test_annotation_widget.py +805 -0
  274. spatiato-0.2.0/tests/test_app_state.py +938 -0
  275. spatiato-0.2.0/tests/test_class_palette.py +131 -0
  276. spatiato-0.2.0/tests/test_classifier.py +1414 -0
  277. spatiato-0.2.0/tests/test_classifier_export.py +74 -0
  278. spatiato-0.2.0/tests/test_color_source.py +136 -0
  279. spatiato-0.2.0/tests/test_feature_extraction.py +1205 -0
  280. spatiato-0.2.0/tests/test_feature_extraction_widget.py +2270 -0
  281. spatiato-0.2.0/tests/test_feature_matrix_metadata.py +321 -0
  282. spatiato-0.2.0/tests/test_headless.py +796 -0
  283. spatiato-0.2.0/tests/test_histogram.py +143 -0
  284. spatiato-0.2.0/tests/test_histogram_controller.py +256 -0
  285. spatiato-0.2.0/tests/test_histogram_plot_widget.py +428 -0
  286. spatiato-0.2.0/tests/test_histogram_status_card.py +80 -0
  287. spatiato-0.2.0/tests/test_histogram_widget.py +1385 -0
  288. spatiato-0.2.0/tests/test_image_layer_row.py +117 -0
  289. spatiato-0.2.0/tests/test_labels_async.py +146 -0
  290. spatiato-0.2.0/tests/test_labels_colormap.py +716 -0
  291. spatiato-0.2.0/tests/test_multi_widget_backed_zarr.py +661 -0
  292. spatiato-0.2.0/tests/test_object_classification_widget.py +3632 -0
  293. spatiato-0.2.0/tests/test_package.py +139 -0
  294. spatiato-0.2.0/tests/test_persistence.py +741 -0
  295. spatiato-0.2.0/tests/test_persistence_controls.py +156 -0
  296. spatiato-0.2.0/tests/test_points_controller.py +502 -0
  297. spatiato-0.2.0/tests/test_points_value_index.py +748 -0
  298. spatiato-0.2.0/tests/test_points_widget.py +200 -0
  299. spatiato-0.2.0/tests/test_reader.py +182 -0
  300. spatiato-0.2.0/tests/test_shapes_annotation.py +1003 -0
  301. spatiato-0.2.0/tests/test_shapes_annotation_create_holes.py +510 -0
  302. spatiato-0.2.0/tests/test_shapes_annotation_layer_state.py +91 -0
  303. spatiato-0.2.0/tests/test_shapes_annotation_snapshot.py +162 -0
  304. spatiato-0.2.0/tests/test_shapes_annotation_widget.py +6189 -0
  305. spatiato-0.2.0/tests/test_shapes_geometry.py +1460 -0
  306. spatiato-0.2.0/tests/test_shapes_native_polygon_mutations.py +224 -0
  307. spatiato-0.2.0/tests/test_shapes_styling.py +1296 -0
  308. spatiato-0.2.0/tests/test_shapes_triangulation_backend.py +135 -0
  309. spatiato-0.2.0/tests/test_shared_styles.py +131 -0
  310. spatiato-0.2.0/tests/test_spatial_query_annotation.py +425 -0
  311. spatiato-0.2.0/tests/test_spatial_query_canonical.py +476 -0
  312. spatiato-0.2.0/tests/test_spatial_query_centroids.py +209 -0
  313. spatiato-0.2.0/tests/test_spatial_query_controller.py +355 -0
  314. spatiato-0.2.0/tests/test_spatial_query_query.py +251 -0
  315. spatiato-0.2.0/tests/test_spatial_query_status_card.py +134 -0
  316. spatiato-0.2.0/tests/test_spatial_query_viewer_styling.py +226 -0
  317. spatiato-0.2.0/tests/test_spatial_query_widget.py +972 -0
  318. spatiato-0.2.0/tests/test_spatialdata.py +758 -0
  319. spatiato-0.2.0/tests/test_spatialdata_shapes_io.py +476 -0
  320. spatiato-0.2.0/tests/test_styling.py +119 -0
  321. spatiato-0.2.0/tests/test_transcript_tiles.py +1154 -0
  322. spatiato-0.2.0/tests/test_validation.py +31 -0
  323. spatiato-0.2.0/tests/test_viewer_adapter.py +3935 -0
  324. spatiato-0.2.0/tests/test_viewer_status_card.py +403 -0
  325. spatiato-0.2.0/tests/test_viewer_styling.py +645 -0
  326. spatiato-0.2.0/tests/test_viewer_widget.py +3906 -0
  327. spatiato-0.2.0/tests/viewer/tiled_points/napari/test_controls.py +124 -0
  328. spatiato-0.2.0/tests/viewer/tiled_points/napari/test_layer.py +213 -0
  329. spatiato-0.2.0/tests/viewer/tiled_points/napari/test_registration.py +166 -0
  330. spatiato-0.2.0/tests/viewer/tiled_points/napari/test_viewport.py +175 -0
  331. spatiato-0.2.0/tests/viewer/tiled_points/runtime/conftest.py +69 -0
  332. spatiato-0.2.0/tests/viewer/tiled_points/runtime/test_application_adapter.py +133 -0
  333. spatiato-0.2.0/tests/viewer/tiled_points/runtime/test_application_integration.py +105 -0
  334. spatiato-0.2.0/tests/viewer/tiled_points/runtime/test_cache_session.py +1074 -0
  335. spatiato-0.2.0/tests/viewer/tiled_points/runtime/test_layer_runtime.py +933 -0
  336. spatiato-0.2.0/tests/viewer/tiled_points/runtime/test_lod.py +108 -0
  337. spatiato-0.2.0/tests/viewer/tiled_points/runtime/test_lod_budgets.py +324 -0
  338. spatiato-0.2.0/tests/viewer/tiled_points/runtime/test_residency.py +190 -0
  339. spatiato-0.2.0/tests/viewer/tiled_points/runtime/test_viewport_scheduler.py +373 -0
  340. spatiato-0.2.0/tests/viewer/tiled_points/test_contracts.py +325 -0
  341. spatiato-0.2.0/tests/viewer/tiled_points/test_render_batch.py +167 -0
  342. spatiato-0.2.0/tests/viewer/tiled_points/vispy/test_layer.py +494 -0
  343. spatiato-0.2.0/tests/viewer/tiled_points/vispy/test_real_canvas.py +165 -0
  344. spatiato-0.2.0/uv.lock +6053 -0
@@ -0,0 +1,42 @@
1
+ {
2
+ "env": {
3
+ "UV_PROJECT_ENVIRONMENT": ".venv",
4
+ "PYTHONUNBUFFERED": "1",
5
+ "PYTHONPYCACHEPREFIX": ".cache/claude/pycache",
6
+ "XDG_CACHE_HOME": ".cache/claude",
7
+ "PIP_CACHE_DIR": ".cache/claude/pip",
8
+ "UV_CACHE_DIR": ".cache/claude/uv",
9
+ "MPLCONFIGDIR": ".cache/claude/matplotlib",
10
+ "RUFF_CACHE_DIR": ".cache/claude/ruff_cache"
11
+ },
12
+ "permissions": {
13
+ "allow": [
14
+ "Bash(source .venv/bin/activate)",
15
+ "Bash(.venv/bin/pytest:*)",
16
+ "Bash(.venv/bin/ruff:*)",
17
+ "Bash(.venv/bin/python:*)",
18
+ "Bash(.venv/bin/python3:*)",
19
+ "Bash(.venv/bin/pre-commit run:*)",
20
+ "Bash(pytest:*)",
21
+ "Bash(ruff:*)",
22
+ "Bash(pre-commit run:*)",
23
+ "Bash(python:*)",
24
+ "Bash(python3:*)",
25
+ "Bash(git status)",
26
+ "Bash(git diff:*)",
27
+ "Bash(git log:*)",
28
+ "Bash(git show:*)",
29
+ "Bash(git branch:*)",
30
+ "Bash(ls:*)",
31
+ "Bash(cat:*)",
32
+ "Bash(grep:*)",
33
+ "Bash(rg:*)",
34
+ "Bash(find:*)",
35
+ "Bash(shasum *)"
36
+ ],
37
+ "deny": [
38
+ "Read(./.env)",
39
+ "Read(./.env.*)"
40
+ ]
41
+ }
42
+ }
@@ -0,0 +1,39 @@
1
+ name: Release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ defaults:
8
+ run:
9
+ # Fail on errors in multiline statements (-e), pipes (-o pipefail), and unset variables (-u).
10
+ shell: bash -euo pipefail {0}
11
+
12
+ # Uses PyPI trusted publishing:
13
+ # https://docs.pypi.org/trusted-publishers/
14
+ jobs:
15
+ release:
16
+ name: Upload release to PyPI
17
+ runs-on: ubuntu-latest
18
+ environment:
19
+ name: pypi
20
+ url: https://pypi.org/p/spatiato
21
+ permissions:
22
+ contents: read
23
+ id-token: write
24
+ steps:
25
+ - uses: actions/checkout@v4
26
+ with:
27
+ filter: blob:none
28
+ fetch-depth: 0
29
+
30
+ - name: Install uv
31
+ uses: astral-sh/setup-uv@v5
32
+ with:
33
+ cache-dependency-glob: pyproject.toml
34
+
35
+ - name: Build package
36
+ run: uv build
37
+
38
+ - name: Publish package distributions to PyPI
39
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,129 @@
1
+ # Custom
2
+ scripts/code_ownership.py
3
+ configs/allocate/*
4
+ configs/annotate/*
5
+ configs/clean/*
6
+ configs/dataset/*
7
+ configs/experiment/*
8
+ configs/local/*
9
+ configs/segmentation/*
10
+ configs/visualize/*
11
+ data
12
+ spatial
13
+ logs
14
+ .env
15
+ .autoenv
16
+
17
+ notebooks
18
+
19
+ # Add exection for example configs for resolve and vizgen
20
+ !configs/allocate/resolve_liver.yaml
21
+ !configs/allocate/vizgen_example.yaml
22
+ !configs/annotate/resolve_liver.yaml
23
+ !configs/clean/resolve_liver.yaml
24
+ !configs/clean/vizgen_example.yaml
25
+ !configs/dataset/resolve_liver.yaml
26
+ !configs/dataset/resolve_liver_2.yaml
27
+ !configs/dataset/vizgen_example.yaml
28
+ !configs/experiment/resolve_liver.yaml
29
+ !configs/experiment/vizgen_example.yaml
30
+ !configs/local/default.example.yaml
31
+ !configs/segmentation/cellpose_resolve_liver.yaml
32
+ !configs/segmentation/cellpose_vizgen_example.yaml
33
+ !configs/visualize/resolve_liver.yaml
34
+
35
+ # Byte-compiled / optimized / DLL files
36
+ __pycache__/
37
+ *.py[cod]
38
+ *$py.class
39
+
40
+ # C extensions
41
+ *.so
42
+
43
+ # Distribution / packaging
44
+ .Python
45
+ env/
46
+ build/
47
+ develop-eggs/
48
+ dist/
49
+ downloads/
50
+ eggs/
51
+ .eggs/
52
+ lib/
53
+ lib64/
54
+ parts/
55
+ sdist/
56
+ var/
57
+ *.egg-info/
58
+ .installed.cfg
59
+ *.egg
60
+
61
+ # PyInstaller
62
+ # Usually these files are written by a python script from a template
63
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
64
+ *.manifest
65
+ *.spec
66
+
67
+ # Installer logs
68
+ pip-log.txt
69
+ pip-delete-this-directory.txt
70
+
71
+ # Unit test / coverage reports
72
+ htmlcov/
73
+ .tox/
74
+ .coverage
75
+ .coverage.*
76
+ .cache
77
+ nosetests.xml
78
+ coverage.xml
79
+ *,cover
80
+ .hypothesis/
81
+ .napari_cache
82
+ .codex
83
+ .codex-home/
84
+ .claude/*
85
+ !.claude/settings.json
86
+
87
+ # Translations
88
+ *.mo
89
+ *.pot
90
+
91
+ # Django stuff:
92
+ *.log
93
+ local_settings.py
94
+
95
+ # Flask instance folder
96
+ instance/
97
+
98
+ # Sphinx documentation
99
+ /docs/generated/
100
+ /docs/_build/
101
+
102
+ # MkDocs documentation
103
+ /site/
104
+
105
+ # PyBuilder
106
+ target/
107
+
108
+ # Pycharm and VSCode
109
+ .idea/
110
+ venv/
111
+ .vscode/
112
+ .venv/
113
+
114
+ # IPython Notebook
115
+ .ipynb_checkpoints
116
+
117
+ # pyenv
118
+ .python-version
119
+
120
+ # OS
121
+ .DS_Store
122
+
123
+ # written by setuptools_scm
124
+ **/_version.py
125
+
126
+ # asv benchmarks
127
+ .asv/**
128
+
129
+ agents.md
@@ -0,0 +1,44 @@
1
+ ## Python environment
2
+ Canonical environment: `.venv`
3
+
4
+ Run Python, tests, lint, and tooling by calling the environment's binaries directly via
5
+ their `.venv/bin/` path.
6
+
7
+ ```bash
8
+ .venv/bin/pytest
9
+ .venv/bin/python -m pytest
10
+ .venv/bin/pre-commit run ruff --all-files
11
+ ```
12
+
13
+ ## Test scope
14
+
15
+ Run only the focused unit tests directly affected by a change.
16
+
17
+ Do not run the full test suite by default. Run it only when:
18
+ - the user explicitly requests it; or
19
+ - the change is sufficiently broad that focused tests cannot provide reasonable coverage, in which case ask the user first.
20
+
21
+ Prefer focused commands such as:
22
+
23
+ ```bash
24
+ .venv/bin/pytest -q path/to/test_module.py
25
+ .venv/bin/pytest -q path/to/test_module.py::test_specific_behavior
26
+ ```
27
+
28
+ Run linting only on the changed or directly affected files where possible.
29
+
30
+ ## Code explanation references
31
+
32
+ When explaining or reviewing repository code:
33
+
34
+ - Include clickable Markdown links with the exact current line number for the functions, branches, and call sites central to the explanation.
35
+ - For event flows, link each material step to its implementation rather than linking only the containing class or module.
36
+ - Re-check line numbers against the current working tree immediately before responding because edits may move them.
37
+ - Use absolute paths with one starting line, not line ranges.
38
+ - Do not overload explanations with links to incidental symbols.
39
+
40
+ ## Codex config
41
+ Repository-local Codex settings for this project live in `.codex/config.toml`.
42
+
43
+ When checking or updating Codex sandbox, cache, approval, or environment settings for this repo,
44
+ use `.codex/config.toml` first rather than `~/.codex/config.toml`.
@@ -0,0 +1,18 @@
1
+ ## Python environment
2
+ Canonical environment: `.venv`. Use it as-is — do NOT sync, update, or install
3
+ into it (e.g. no `uv sync`/`uv run`); the maintainer manages env updates manually.
4
+
5
+ Run Python, tests, lint, and tooling by calling the environment's binaries directly via
6
+ their `.venv/bin/` path.
7
+
8
+ ```bash
9
+ .venv/bin/pytest
10
+ .venv/bin/python -m pytest
11
+ .venv/bin/pre-commit run ruff --all-files
12
+ ```
13
+
14
+ ## Claude config
15
+ Repository-local Claude Code settings for this project live in `.claude/settings.json`.
16
+
17
+ When checking or updating Claude cache, permission, or environment settings for this repo,
18
+ use `.claude/settings.json` first rather than `~/.claude/settings.json`.
spatiato-0.2.0/LICENSE ADDED
@@ -0,0 +1,29 @@
1
+ BSD 3-Clause License
2
+
3
+ Copyright (c) 2026, VIB spatial catalyst
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+
9
+ 1. Redistributions of source code must retain the above copyright notice, this
10
+ list of conditions and the following disclaimer.
11
+
12
+ 2. Redistributions in binary form must reproduce the above copyright notice,
13
+ this list of conditions and the following disclaimer in the documentation
14
+ and/or other materials provided with the distribution.
15
+
16
+ 3. Neither the name of the copyright holder nor the names of its
17
+ contributors may be used to endorse or promote products derived from
18
+ this software without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,282 @@
1
+ Metadata-Version: 2.5
2
+ Name: spatiato
3
+ Version: 0.2.0
4
+ Summary: A spatial omics interface for napari.
5
+ Project-URL: Homepage, https://github.com/vibspatial/spatiato
6
+ Project-URL: Documentation, https://github.com/vibspatial/spatiato#readme
7
+ Project-URL: Repository, https://github.com/vibspatial/spatiato
8
+ Project-URL: Issues, https://github.com/vibspatial/spatiato/issues
9
+ Project-URL: Changelog, https://github.com/vibspatial/spatiato/releases
10
+ Project-URL: Paper, https://doi.org/10.1093/bioinformatics/btag122
11
+ Project-URL: SaeysLab, https://saeyslab.sites.vib.be/en
12
+ Project-URL: VIBSpatialCatalyst, https://vib.be/en/technologies/technology-portfolio/spatial-catalyst
13
+ Author: VIB spatial catalyst
14
+ License: BSD 3-Clause License
15
+
16
+ Copyright (c) 2026, VIB spatial catalyst
17
+ All rights reserved.
18
+
19
+ Redistribution and use in source and binary forms, with or without
20
+ modification, are permitted provided that the following conditions are met:
21
+
22
+ 1. Redistributions of source code must retain the above copyright notice, this
23
+ list of conditions and the following disclaimer.
24
+
25
+ 2. Redistributions in binary form must reproduce the above copyright notice,
26
+ this list of conditions and the following disclaimer in the documentation
27
+ and/or other materials provided with the distribution.
28
+
29
+ 3. Neither the name of the copyright holder nor the names of its
30
+ contributors may be used to endorse or promote products derived from
31
+ this software without specific prior written permission.
32
+
33
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
34
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
36
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
37
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
40
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
41
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
42
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43
+ License-File: LICENSE
44
+ Keywords: anndata,image-analysis,napari,object-classification,plugin,spatialdata
45
+ Classifier: Development Status :: 4 - Beta
46
+ Classifier: Framework :: napari
47
+ Classifier: Intended Audience :: Developers
48
+ Classifier: Intended Audience :: Science/Research
49
+ Classifier: License :: OSI Approved :: BSD License
50
+ Classifier: Operating System :: OS Independent
51
+ Classifier: Programming Language :: Python
52
+ Classifier: Programming Language :: Python :: 3
53
+ Classifier: Programming Language :: Python :: 3 :: Only
54
+ Classifier: Programming Language :: Python :: 3.11
55
+ Classifier: Programming Language :: Python :: 3.12
56
+ Classifier: Programming Language :: Python :: 3.13
57
+ Classifier: Programming Language :: Python :: 3.14
58
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
59
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
60
+ Requires-Python: <3.15,>=3.12
61
+ Requires-Dist: dask[dataframe]
62
+ Requires-Dist: filelock>=3.20.1
63
+ Requires-Dist: harpy-analysis>=0.4.4
64
+ Requires-Dist: joblib
65
+ Requires-Dist: lazy-loader>=0.4
66
+ Requires-Dist: loguru
67
+ Requires-Dist: napari[all]>=0.4.18
68
+ Requires-Dist: pandas<3.0
69
+ Requires-Dist: pyarrow
70
+ Requires-Dist: pyqtgraph>=0.13.7
71
+ Requires-Dist: spatialdata>=0.7.2
72
+ Provides-Extra: dev
73
+ Requires-Dist: myst-nb; extra == 'dev'
74
+ Requires-Dist: pre-commit; extra == 'dev'
75
+ Requires-Dist: pytest; extra == 'dev'
76
+ Requires-Dist: pytest-cov; extra == 'dev'
77
+ Requires-Dist: pytest-qt; extra == 'dev'
78
+ Requires-Dist: pytest-xdist; extra == 'dev'
79
+ Requires-Dist: ruff; extra == 'dev'
80
+ Requires-Dist: sphinx-autodoc-typehints; extra == 'dev'
81
+ Requires-Dist: sphinx-book-theme>=1.0.0; extra == 'dev'
82
+ Requires-Dist: sphinx-copybutton; extra == 'dev'
83
+ Requires-Dist: sphinx-design; extra == 'dev'
84
+ Requires-Dist: sphinx-rtd-theme; extra == 'dev'
85
+ Requires-Dist: sphinx>=4.5; extra == 'dev'
86
+ Requires-Dist: sphinxcontrib-bibtex>=1.0.0; extra == 'dev'
87
+ Requires-Dist: torchvision; extra == 'dev'
88
+ Requires-Dist: tox; extra == 'dev'
89
+ Requires-Dist: twine>=4.0.2; extra == 'dev'
90
+ Provides-Extra: docs
91
+ Requires-Dist: myst-nb; extra == 'docs'
92
+ Requires-Dist: sphinx-autodoc-typehints; extra == 'docs'
93
+ Requires-Dist: sphinx-book-theme>=1.0.0; extra == 'docs'
94
+ Requires-Dist: sphinx-copybutton; extra == 'docs'
95
+ Requires-Dist: sphinx-design; extra == 'docs'
96
+ Requires-Dist: sphinx-rtd-theme; extra == 'docs'
97
+ Requires-Dist: sphinx>=4.5; extra == 'docs'
98
+ Requires-Dist: sphinxcontrib-bibtex>=1.0.0; extra == 'docs'
99
+ Provides-Extra: test
100
+ Requires-Dist: pytest; extra == 'test'
101
+ Requires-Dist: pytest-cov; extra == 'test'
102
+ Requires-Dist: pytest-qt; extra == 'test'
103
+ Requires-Dist: pytest-xdist; extra == 'test'
104
+ Requires-Dist: tox; extra == 'test'
105
+ Provides-Extra: torch
106
+ Requires-Dist: torchvision; extra == 'torch'
107
+ Description-Content-Type: text/markdown
108
+
109
+ <p align="center">
110
+ <img src="https://raw.githubusercontent.com/vibspatial/spatiato/main/src/spatiato/_static/logo.svg" alt="Spatiato logo" width="400">
111
+ </p>
112
+
113
+ <h1 align="center">spatiato: a spatial omics interface for napari.</h1>
114
+
115
+ [![PyPI](https://img.shields.io/pypi/v/spatiato.svg)](https://pypi.org/project/spatiato/)
116
+
117
+ 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.
118
+
119
+ `spatiato` is a napari plugin for viewing, exploring, and analyzing
120
+ `SpatialData` datasets. It includes its own viewer for loading and
121
+ browsing data inside napari, alongside annotation, feature extraction, and
122
+ interactive object classification workflows.
123
+
124
+ ## Installation
125
+
126
+ Install from [PyPI](https://pypi.org/project/spatiato/):
127
+
128
+ ```bash
129
+ pip install spatiato
130
+ ```
131
+
132
+ ## Quickstart
133
+
134
+ The quickest way to try the plugin is to create a small example `SpatialData`
135
+ object, write it to a temporary zarr store, read it back as an on-disk dataset,
136
+ and launch the Spatiato napari interface with `Interactive`.
137
+
138
+ ```python
139
+ import tempfile
140
+ from pathlib import Path
141
+
142
+ from spatialdata import read_zarr
143
+
144
+ from spatiato import Interactive
145
+ from spatiato.datasets import blobs_multi_region
146
+
147
+ zarr_path = Path(tempfile.mkdtemp()) / "blobs_multi_region.zarr"
148
+
149
+ sdata = blobs_multi_region()
150
+ sdata.write(zarr_path)
151
+
152
+ sdata = read_zarr(zarr_path)
153
+ Interactive(sdata)
154
+ ```
155
+
156
+ This opens napari with the Spatiato widgets docked and the
157
+ `blobs_multi_region` dataset available in the shared viewer state.
158
+ Shapes triangulation uses the fast Bermuda backend by default. To use Numba
159
+ instead, launch with `Interactive(sdata, triangulation_backend="numba")`.
160
+
161
+ The current repository contains four working widgets:
162
+
163
+ - `Viewer`
164
+ - `Feature Extraction`
165
+ - `Object Classification`
166
+ - `Annotation`
167
+
168
+ Today the plugin supports:
169
+
170
+ - loading and viewing `SpatialData` through the Spatiato viewer widget
171
+ - selecting a labels element, optional image, compatible coordinate system, and
172
+ linked table from the shared loaded `SpatialData`
173
+ - calculating intensity and morphology features through Harpy
174
+ - writing feature matrices into the selected `AnnData` table linked to the
175
+ labels element, as `.obsm[feature_key]`, with companion metadata in
176
+ `.uns["feature_matrices"][feature_key]`
177
+ - interactive manual annotation of instances in labels elements
178
+ - interactive creation and editing of polygon shapes annotations
179
+ - background `RandomForestClassifier` retraining on the selected feature
180
+ matrix stored in `.obsm[feature_key]` of the `AnnData` table linked to the
181
+ labels element
182
+ - live prediction updates and labels recoloring
183
+ - explicit write-back of in-memory table state to zarr
184
+ - explicit reload of on-disk table state back into memory
185
+ - multi-sample workflows through multi-region tables and explicit
186
+ labels/image/coordinate-system matching
187
+ - headless feature extraction and classifier application for scripted or batch
188
+ processing
189
+
190
+ Example spatiato session:
191
+
192
+ <p align="center">
193
+ <img src="https://raw.githubusercontent.com/vibspatial/spatiato/main/docs/_static/viewer.png" alt="spatiato viewer example screenshot" width="900">
194
+ </p>
195
+
196
+ <p align="center">
197
+ <img src="https://raw.githubusercontent.com/vibspatial/spatiato/main/docs/_static/object_classification.png" alt="spatiato object classification example screenshot" width="900">
198
+ </p>
199
+
200
+ ## Headless and Multi-Sample Workflows
201
+
202
+ For scripted or batch processing, use the public `spatiato.headless` module.
203
+ It can apply an exported classifier to an existing feature matrix, or compute
204
+ the required features before applying the classifier.
205
+
206
+ The headless APIs accept one labels element or a sequence of labels elements.
207
+ For multi-sample data, pass matching labels, image, and coordinate-system
208
+ sequences so Harpy can build or apply a shared table-level feature matrix across
209
+ the selected samples. When features need image intensities, the channel
210
+ selection is read from the exported classifier's `source_channels` metadata.
211
+
212
+ ```python
213
+ from spatialdata import read_zarr
214
+
215
+ from spatiato import headless
216
+
217
+ sdata = read_zarr("experiment.zarr")
218
+
219
+ result = headless.apply_classifier_with_feature_extraction_from_path(
220
+ sdata,
221
+ "classifier.spatiato-classifier.joblib",
222
+ table_name="table_multi",
223
+ labels_name=["sample_1_labels", "sample_2_labels"],
224
+ coordinate_system=["sample_1", "sample_2"],
225
+ image_name=["sample_1_image", "sample_2_image"],
226
+ )
227
+ ```
228
+
229
+ ## Local development
230
+
231
+ Create the development environment:
232
+
233
+ ```bash
234
+ ./create_env.sh
235
+ ```
236
+
237
+ Then launch napari:
238
+
239
+ ```bash
240
+ source .venv/bin/activate
241
+ napari
242
+ ```
243
+
244
+ Open the widgets from the napari plugin menu:
245
+
246
+ - `Plugins -> spatiato -> Viewer`
247
+ - `Plugins -> spatiato -> Feature Extraction`
248
+ - `Plugins -> spatiato -> Object Classification`
249
+ - `Plugins -> spatiato -> Annotation`
250
+
251
+ ### Optional real-OpenGL renderer qualification
252
+
253
+ The tiled-points renderer includes one opt-in real-canvas qualification test at
254
+ [`tests/viewer/tiled_points/vispy/test_real_canvas.py`](tests/viewer/tiled_points/vispy/test_real_canvas.py).
255
+ It is skipped during ordinary test runs because it requires a working
256
+ Qt, VisPy, and OpenGL environment. Run it explicitly with:
257
+
258
+ ```bash
259
+ SPATIATO_RUN_REAL_GL_TESTS=1 \
260
+ .venv/bin/pytest -q tests/viewer/tiled_points/vispy/test_real_canvas.py
261
+ ```
262
+
263
+ The focused renderer unit tests remain part of ordinary test runs; this
264
+ additional qualification creates a real canvas, compiles and executes the
265
+ custom shaders, and compares the framebuffer result with standard VisPy
266
+ markers.
267
+
268
+ ## Debug script
269
+
270
+ A small local debug script is available at
271
+ [`scripts/debug_widget.py`](scripts/debug_widget.py).
272
+
273
+ It creates a temporary `blobs_multi_region` zarr store, loads it into napari,
274
+ and docks the Spatiato widgets automatically.
275
+ This is useful for quickly reproducing widget behavior during development.
276
+
277
+ Run it with:
278
+
279
+ ```bash
280
+ source .venv/bin/activate
281
+ python scripts/debug_widget.py
282
+ ```