imaging-server-kit 0.2.0__tar.gz → 0.3.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.
- imaging_server_kit-0.3.0/.github/workflows/deploy.yml +53 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/.github/workflows/publish.yml +4 -8
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/.gitignore +3 -2
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/PKG-INFO +16 -29
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/README.md +6 -19
- imaging_server_kit-0.3.0/docs/assets/extra.css +11 -0
- imaging_server_kit-0.3.0/docs/assets/images/napari_widget.png +0 -0
- imaging_server_kit-0.3.0/docs/assets/videos/auto_call.mp4 +0 -0
- imaging_server_kit-0.3.0/docs/citing.md +22 -0
- imaging_server_kit-0.3.0/docs/concepts/algorithms.md +65 -0
- imaging_server_kit-0.3.0/docs/concepts/coordinates.md +96 -0
- imaging_server_kit-0.3.0/docs/concepts/layers-and-stacks.md +44 -0
- imaging_server_kit-0.3.0/docs/developers/ai_policy.md +21 -0
- imaging_server_kit-0.3.0/docs/examples.md +3 -0
- imaging_server_kit-0.3.0/docs/getting-started/demos.md +68 -0
- imaging_server_kit-0.3.0/docs/getting-started/installation.md +55 -0
- imaging_server_kit-0.3.0/docs/hooks/redirects.py +32 -0
- imaging_server_kit-0.3.0/docs/how-to/combine.md +117 -0
- imaging_server_kit-0.3.0/docs/how-to/deploy-server.md +32 -0
- imaging_server_kit-0.3.0/docs/how-to/live-updates.md +81 -0
- imaging_server_kit-0.3.0/docs/how-to/napari.md +110 -0
- imaging_server_kit-0.3.0/docs/how-to/qupath.md +68 -0
- imaging_server_kit-0.3.0/docs/how-to/regions.md +66 -0
- imaging_server_kit-0.3.0/docs/how-to/tiling.md +83 -0
- imaging_server_kit-0.3.0/docs/index.md +83 -0
- imaging_server_kit-0.3.0/docs/reference/api/algorithms.md +37 -0
- imaging_server_kit-0.3.0/docs/reference/api/gui.md +9 -0
- imaging_server_kit-0.3.0/docs/reference/api/layers.md +72 -0
- imaging_server_kit-0.3.0/docs/reference/api/remote.md +10 -0
- imaging_server_kit-0.3.0/docs/reference/api/stack.md +16 -0
- imaging_server_kit-0.3.0/docs/reference/cli.md +15 -0
- imaging_server_kit-0.3.0/docs/reference/http.md +27 -0
- imaging_server_kit-0.3.0/docs/tutorial/create-algorithm.md +203 -0
- imaging_server_kit-0.3.0/docs/tutorial/python.md +145 -0
- imaging_server_kit-0.3.0/docs/tutorial/samples-and-metadata.md +87 -0
- imaging_server_kit-0.3.0/docs/tutorial/serve.md +54 -0
- imaging_server_kit-0.3.0/mkdocs.yml +151 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/pyproject.toml +13 -8
- imaging_server_kit-0.3.0/src/imaging_server_kit/__init__.py +144 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/_version.py +3 -3
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/cli.py +35 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/core/_fmt.py +37 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/core/_progress_display.py +97 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/core/algorithm.py +561 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/core/domain.py +216 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/core/errors.py +13 -5
- imaging_server_kit-0.3.0/src/imaging_server_kit/core/multialgo.py +132 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/core/runner.py +396 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/core/stack.py +123 -89
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/core/templates/info.html +30 -6
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/core/tiling.py +18 -10
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/demo/examples.py +32 -26
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/demo/tools.py +127 -77
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/common/parameter_panel.py +8 -9
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/napari_serverkit/__init__.py +25 -9
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/napari_serverkit/napari_stack.py +39 -35
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/napari_serverkit/napari_widget.py +1 -1
- imaging_server_kit-0.3.0/src/imaging_server_kit/gui/qupath_serverkit/__init__.py +112 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/qupath_serverkit/qupath_bridge.py +42 -37
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/qupath_serverkit/qupath_widget.py +2 -2
- imaging_server_kit-0.3.0/src/imaging_server_kit/merge/_image_merger.py +81 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/merge/_mask_merger.py +336 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/merge/common.py +74 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/merge/layer_merger.py +37 -17
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/__init__.py +15 -5
- imaging_server_kit-0.3.0/src/imaging_server_kit/remote/_any_serializer.py +65 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/_boxes_serializer.py +9 -7
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/_image_serializer.py +5 -5
- imaging_server_kit-0.3.0/src/imaging_server_kit/remote/_mask_serializer.py +26 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/_null_serializer.py +3 -4
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/_paths_serializer.py +2 -2
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/_points_serializer.py +8 -23
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/_tracks_serializer.py +6 -13
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/_vectors_serializer.py +12 -9
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/app.py +38 -35
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/client.py +58 -40
- imaging_server_kit-0.3.0/src/imaging_server_kit/remote/encoding.py +64 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/layer_serializer.py +12 -23
- imaging_server_kit-0.3.0/src/imaging_server_kit/remote/meta_serializer.py +48 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/serializer.py +8 -4
- imaging_server_kit-0.3.0/src/imaging_server_kit/remote/stack_serializer.py +16 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/remote/tile_serializer.py +2 -2
- imaging_server_kit-0.3.0/src/imaging_server_kit/skills/isk-napari-qupath-gui/SKILL.md +64 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/skills/isk-write-algorithm/SKILL.md +89 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/types/__init__.py +3 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/types/_any.py +46 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/types/_bool.py +12 -5
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/types/_boxes.py +49 -26
- imaging_server_kit-0.3.0/src/imaging_server_kit/types/_choice.py +70 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/types/_float.py +68 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/types/_image.py +171 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/types/_integer.py +68 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/types/_mask.py +382 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/types/_notification.py +15 -7
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/types/_null.py +11 -4
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/types/_paths.py +19 -12
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/types/_points.py +43 -23
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/types/_progress.py +16 -18
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/types/_string.py +10 -5
- imaging_server_kit-0.3.0/src/imaging_server_kit/types/_tracks.py +77 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/types/_vectors.py +48 -27
- imaging_server_kit-0.3.0/src/imaging_server_kit/types/common.py +119 -0
- imaging_server_kit-0.3.0/src/imaging_server_kit/types/layer.py +359 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/validation/layer_validator.py +3 -6
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit.egg-info/PKG-INFO +16 -29
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit.egg-info/SOURCES.txt +66 -31
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit.egg-info/requires.txt +10 -5
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit.egg-info/scm_file_list.json +66 -31
- imaging_server_kit-0.3.0/src/imaging_server_kit.egg-info/scm_version.json +8 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/tests/core/test_basic.py +26 -1
- imaging_server_kit-0.3.0/tests/core/test_description.py +38 -0
- imaging_server_kit-0.3.0/tests/core/test_errors.py +58 -0
- imaging_server_kit-0.3.0/tests/core/test_indexing.py +135 -0
- imaging_server_kit-0.3.0/tests/core/test_repr.py +97 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/tests/core/test_streaming.py +34 -0
- imaging_server_kit-0.3.0/tests/core/test_tiled_runs.py +431 -0
- imaging_server_kit-0.3.0/tests/demo/test_examples.py +204 -0
- imaging_server_kit-0.3.0/tests/demo/test_tools.py +397 -0
- imaging_server_kit-0.3.0/tests/gui/test_napari_stack.py +41 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/tests/remote/test_app.py +25 -6
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/tests/remote/test_client_server.py +34 -3
- imaging_server_kit-0.3.0/tests/remote/test_serialization.py +160 -0
- imaging_server_kit-0.3.0/tests/test_cli.py +33 -0
- imaging_server_kit-0.3.0/tests/test_docs.py +39 -0
- imaging_server_kit-0.3.0/tests/types/test_mask.py +118 -0
- imaging_server_kit-0.3.0/uv.lock +10878 -0
- imaging_server_kit-0.2.0/.github/workflows/deploy.yml +0 -40
- imaging_server_kit-0.2.0/docs/_config.yml +0 -26
- imaging_server_kit-0.2.0/docs/_static/stardist_blobs.mp4 +0 -0
- imaging_server_kit-0.2.0/docs/_toc.yml +0 -14
- imaging_server_kit-0.2.0/docs/assets/threshold_qupath.png +0 -0
- imaging_server_kit-0.2.0/docs/index.md +0 -99
- imaging_server_kit-0.2.0/docs/sections/00_getting_started.md +0 -83
- imaging_server_kit-0.2.0/docs/sections/01_algorithm.ipynb +0 -400
- imaging_server_kit-0.2.0/docs/sections/02_samples.ipynb +0 -106
- imaging_server_kit-0.2.0/docs/sections/03_metadata.ipynb +0 -101
- imaging_server_kit-0.2.0/docs/sections/04_multialgo.ipynb +0 -114
- imaging_server_kit-0.2.0/docs/sections/05_streams.ipynb +0 -149
- imaging_server_kit-0.2.0/docs/sections/06_tiled.ipynb +0 -101
- imaging_server_kit-0.2.0/docs/sections/07_server.md +0 -60
- imaging_server_kit-0.2.0/docs/sections/08_python.ipynb +0 -443
- imaging_server_kit-0.2.0/docs/sections/09_layers.md +0 -23
- imaging_server_kit-0.2.0/docs/sections/10_examples.md +0 -3
- imaging_server_kit-0.2.0/src/imaging_server_kit/__init__.py +0 -85
- imaging_server_kit-0.2.0/src/imaging_server_kit/core/algorithm.py +0 -523
- imaging_server_kit-0.2.0/src/imaging_server_kit/core/domain.py +0 -140
- imaging_server_kit-0.2.0/src/imaging_server_kit/core/multialgo.py +0 -103
- imaging_server_kit-0.2.0/src/imaging_server_kit/core/runner.py +0 -264
- imaging_server_kit-0.2.0/src/imaging_server_kit/gui/qupath_serverkit/__init__.py +0 -76
- imaging_server_kit-0.2.0/src/imaging_server_kit/merge/_image_merger.py +0 -178
- imaging_server_kit-0.2.0/src/imaging_server_kit/merge/_mask_merger.py +0 -447
- imaging_server_kit-0.2.0/src/imaging_server_kit/merge/common.py +0 -16
- imaging_server_kit-0.2.0/src/imaging_server_kit/remote/_mask_serializer.py +0 -43
- imaging_server_kit-0.2.0/src/imaging_server_kit/remote/encoding.py +0 -31
- imaging_server_kit-0.2.0/src/imaging_server_kit/remote/meta_serializer.py +0 -67
- imaging_server_kit-0.2.0/src/imaging_server_kit/remote/stack_serializer.py +0 -25
- imaging_server_kit-0.2.0/src/imaging_server_kit/types/_choice.py +0 -54
- imaging_server_kit-0.2.0/src/imaging_server_kit/types/_float.py +0 -46
- imaging_server_kit-0.2.0/src/imaging_server_kit/types/_image.py +0 -205
- imaging_server_kit-0.2.0/src/imaging_server_kit/types/_integer.py +0 -46
- imaging_server_kit-0.2.0/src/imaging_server_kit/types/_mask.py +0 -362
- imaging_server_kit-0.2.0/src/imaging_server_kit/types/_tracks.py +0 -54
- imaging_server_kit-0.2.0/src/imaging_server_kit/types/common.py +0 -24
- imaging_server_kit-0.2.0/src/imaging_server_kit/types/layer.py +0 -319
- imaging_server_kit-0.2.0/src/imaging_server_kit.egg-info/scm_version.json +0 -8
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/.gitattributes +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/CITATION.cff +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/LICENSE +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/MANIFEST.in +0 -0
- {imaging_server_kit-0.2.0/docs/assets → imaging_server_kit-0.3.0/docs/assets/images}/demo_napari_screenshot.png +0 -0
- {imaging_server_kit-0.2.0/docs/assets → imaging_server_kit-0.3.0/docs/assets/images}/gaussian_result.png +0 -0
- {imaging_server_kit-0.2.0/docs/assets → imaging_server_kit-0.3.0/docs/assets/images}/meta_sc.png +0 -0
- {imaging_server_kit-0.2.0/docs/assets → imaging_server_kit-0.3.0/docs/assets/images}/samples_sc.png +0 -0
- {imaging_server_kit-0.2.0/docs/assets → imaging_server_kit-0.3.0/docs/assets/images}/screenshot_napari_threshold.png +0 -0
- {imaging_server_kit-0.2.0/docs/assets → imaging_server_kit-0.3.0/docs/assets/images}/screenshot_server.png +0 -0
- {imaging_server_kit-0.2.0/docs/assets → imaging_server_kit-0.3.0/docs/assets/images}/server_running.png +0 -0
- {imaging_server_kit-0.2.0/docs/assets → imaging_server_kit-0.3.0/docs/assets/images}/threshold_qubalab.png +0 -0
- {imaging_server_kit-0.2.0/docs/_static → imaging_server_kit-0.3.0/docs/assets/videos}/cellpose_example.mp4 +0 -0
- {imaging_server_kit-0.2.0/docs/_static → imaging_server_kit-0.3.0/docs/assets/videos}/oripy_threshold.mp4 +0 -0
- {imaging_server_kit-0.2.0/docs/_static → imaging_server_kit-0.3.0/docs/assets/videos}/progressive_threshold.mp4 +0 -0
- {imaging_server_kit-0.2.0/docs/_static → imaging_server_kit-0.3.0/docs/assets/videos}/server_napari.mp4 +0 -0
- {imaging_server_kit-0.2.0/docs/_static → imaging_server_kit-0.3.0/docs/assets/videos}/tiles.mp4 +0 -0
- {imaging_server_kit-0.2.0/docs/_static → imaging_server_kit-0.3.0/docs/assets/videos}/tiling2.mp4 +0 -0
- {imaging_server_kit-0.2.0/docs/_static → imaging_server_kit-0.3.0/docs/assets/videos}/yolo-stream.mp4 +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/docs/logo.ico +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/examples/readme.md +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/setup.cfg +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/core/__init__.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/core/_etc.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/core/static/css/index.css +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/core/static/css/info.css +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/core/templates/index.html +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/demo/__init__.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/demo/sample_images/blobs.tif +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/demo/sample_images/tracks.tif +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/__init__.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/common/__init__.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/common/runner_widget.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/common/task_manager.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/napari_serverkit/extra_widgets.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/napari_serverkit/napari.yaml +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/napari_serverkit/napari_http_widget.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/gui/qupath_serverkit/qupath_http_widget.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/merge/__init__.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/merge/_object_merger.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/merge/merger.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/validation/__init__.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/validation/_boxes_validator.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/validation/_image_validator.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/validation/_mask_validator.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/validation/_points_validator.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/validation/_vectors_validator.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit/validation/validator.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit.egg-info/dependency_links.txt +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit.egg-info/entry_points.txt +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/src/imaging_server_kit.egg-info/top_level.txt +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/tests/core/test_multialgo.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/tests/core/test_results.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/tests/core/test_tiling.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/tests/merge/test_merging.py +0 -0
- {imaging_server_kit-0.2.0 → imaging_server_kit-0.3.0}/tests/sample_images/blobs.tif +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Docs
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
pull_request:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
pages: write
|
|
12
|
+
id-token: write
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: docs-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
build:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v4
|
|
23
|
+
|
|
24
|
+
- name: Set up Python 3.11
|
|
25
|
+
uses: actions/setup-python@v5
|
|
26
|
+
with:
|
|
27
|
+
python-version: '3.11'
|
|
28
|
+
cache: pip
|
|
29
|
+
cache-dependency-path: pyproject.toml
|
|
30
|
+
|
|
31
|
+
- name: Install dependencies
|
|
32
|
+
run: pip install ".[docs]"
|
|
33
|
+
|
|
34
|
+
- name: Build the docs
|
|
35
|
+
run: mkdocs build --strict
|
|
36
|
+
|
|
37
|
+
- name: Upload artifact
|
|
38
|
+
if: github.event_name == 'push'
|
|
39
|
+
uses: actions/upload-pages-artifact@v3
|
|
40
|
+
with:
|
|
41
|
+
path: site
|
|
42
|
+
|
|
43
|
+
deploy:
|
|
44
|
+
if: github.event_name == 'push'
|
|
45
|
+
needs: build
|
|
46
|
+
runs-on: ubuntu-latest
|
|
47
|
+
environment:
|
|
48
|
+
name: github-pages
|
|
49
|
+
url: ${{ steps.deployment.outputs.page_url }}
|
|
50
|
+
steps:
|
|
51
|
+
- name: Deploy to GitHub Pages
|
|
52
|
+
id: deployment
|
|
53
|
+
uses: actions/deploy-pages@v4
|
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
# Build the package and publish it to PyPI on tag push.
|
|
2
1
|
name: Publish to PyPI
|
|
3
2
|
on:
|
|
4
3
|
push:
|
|
5
4
|
tags:
|
|
6
5
|
- "v*"
|
|
7
6
|
|
|
8
|
-
permissions:
|
|
9
|
-
contents: write
|
|
10
|
-
|
|
11
7
|
jobs:
|
|
12
8
|
publish:
|
|
13
9
|
name: publish
|
|
14
10
|
runs-on: ubuntu-latest
|
|
11
|
+
environment: pypi
|
|
12
|
+
permissions:
|
|
13
|
+
id-token: write
|
|
15
14
|
steps:
|
|
16
15
|
- name: Checkout source
|
|
17
16
|
uses: actions/checkout@v4
|
|
@@ -24,10 +23,7 @@ jobs:
|
|
|
24
23
|
python -m pip install -U pip build
|
|
25
24
|
python -m build
|
|
26
25
|
- name: Publish
|
|
27
|
-
uses: pypa/gh-action-pypi-publish@v1.
|
|
28
|
-
with:
|
|
29
|
-
user: __token__
|
|
30
|
-
password: ${{ secrets.TWINE_API_KEY }}
|
|
26
|
+
uses: pypa/gh-action-pypi-publish@v1.13.0
|
|
31
27
|
- name: Create Release
|
|
32
28
|
env:
|
|
33
29
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: imaging-server-kit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Convert image processing functions to GUIs, FastAPI servers, and more.
|
|
5
5
|
Author-email: Mallory Wittwer <mallory.wittwer@epfl.ch>
|
|
6
6
|
License: Copyright (c) 2024, EPFL
|
|
@@ -33,10 +33,7 @@ License: Copyright (c) 2024, EPFL
|
|
|
33
33
|
|
|
34
34
|
Project-URL: repository, https://github.com/Imaging-Server-Kit/imaging-server-kit
|
|
35
35
|
Project-URL: documentation, https://imaging-server-kit.github.io/imaging-server-kit
|
|
36
|
-
Classifier: Development Status :: 2 - Pre-Alpha
|
|
37
|
-
Classifier: Intended Audience :: Developers
|
|
38
36
|
Classifier: License :: OSI Approved :: BSD License
|
|
39
|
-
Classifier: Operating System :: OS Independent
|
|
40
37
|
Classifier: Programming Language :: Python
|
|
41
38
|
Classifier: Programming Language :: Python :: 3
|
|
42
39
|
Classifier: Programming Language :: Python :: 3.10
|
|
@@ -50,12 +47,13 @@ License-File: LICENSE
|
|
|
50
47
|
Requires-Dist: numpy
|
|
51
48
|
Requires-Dist: pandas
|
|
52
49
|
Requires-Dist: tifffile
|
|
53
|
-
Requires-Dist:
|
|
50
|
+
Requires-Dist: rich
|
|
54
51
|
Requires-Dist: pydantic>=2.0
|
|
55
52
|
Requires-Dist: scikit-image[optional]
|
|
56
53
|
Requires-Dist: jinja2
|
|
57
54
|
Requires-Dist: PyYAML
|
|
58
|
-
Requires-Dist:
|
|
55
|
+
Requires-Dist: rasterio
|
|
56
|
+
Requires-Dist: shapely>=2.0
|
|
59
57
|
Requires-Dist: geojson
|
|
60
58
|
Requires-Dist: fastapi
|
|
61
59
|
Requires-Dist: uvicorn[standard]
|
|
@@ -69,14 +67,16 @@ Requires-Dist: napari-toolkit; extra == "napari"
|
|
|
69
67
|
Requires-Dist: opencv-contrib-python-headless; extra == "napari"
|
|
70
68
|
Provides-Extra: qupath
|
|
71
69
|
Requires-Dist: imaging-server-kit[napari]; extra == "qupath"
|
|
72
|
-
Requires-Dist: qubalab>=0.2.0; extra == "qupath"
|
|
70
|
+
Requires-Dist: qubalab>=0.2.0; python_version >= "3.11" and extra == "qupath"
|
|
73
71
|
Provides-Extra: docs
|
|
74
|
-
Requires-Dist:
|
|
75
|
-
Requires-Dist:
|
|
72
|
+
Requires-Dist: mkdocs<2,>=1.6; extra == "docs"
|
|
73
|
+
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
|
|
74
|
+
Requires-Dist: mkdocstrings[python]>=0.26; extra == "docs"
|
|
75
|
+
Requires-Dist: ruff; extra == "docs"
|
|
76
76
|
Provides-Extra: test
|
|
77
77
|
Requires-Dist: pytest; extra == "test"
|
|
78
78
|
Requires-Dist: coverage; extra == "test"
|
|
79
|
-
Requires-Dist:
|
|
79
|
+
Requires-Dist: httpx2; extra == "test"
|
|
80
80
|
Provides-Extra: all
|
|
81
81
|
Requires-Dist: imaging-server-kit[docs,napari,qupath,test]; extra == "all"
|
|
82
82
|
Dynamic: license-file
|
|
@@ -85,19 +85,19 @@ Dynamic: license-file
|
|
|
85
85
|
|
|
86
86
|
Turn Python-based image processing workflows into **algorithms** that gain extra functionalities.
|
|
87
87
|
|
|
88
|
-
- [**Turn your algorithms into web servers**](https://imaging-server-kit.github.io/imaging-server-kit/
|
|
88
|
+
- [**Turn your algorithms into web servers**](https://imaging-server-kit.github.io/imaging-server-kit/tutorial/serve.html) and run computations from [Napari](https://napari.org/stable/), [QuPath](https://qupath.github.io/), or [Python](https://imaging-server-kit.github.io/imaging-server-kit/tutorial/python.html) via HTTP requests.
|
|
89
89
|
|
|
90
90
|
https://github.com/user-attachments/assets/0be819ea-fcc1-48ee-8fae-7265e63a00d4
|
|
91
91
|
|
|
92
|
-
- [**Generate dock widgets**](https://imaging-server-kit.github.io/imaging-server-kit/
|
|
92
|
+
- [**Generate dock widgets**](https://imaging-server-kit.github.io/imaging-server-kit/how-to/napari.html) to run your algorithms interactively in Napari or QuPath.
|
|
93
93
|
|
|
94
94
|
https://github.com/user-attachments/assets/1ff572f7-f159-4f5a-afd4-7a157de3d9f8
|
|
95
95
|
|
|
96
|
-
- Run your algorithms [**tile-by-tile**](https://imaging-server-kit.github.io/imaging-server-kit/
|
|
96
|
+
- Run your algorithms [**tile-by-tile**](https://imaging-server-kit.github.io/imaging-server-kit/how-to/tiling.html) on the input data.
|
|
97
97
|
|
|
98
98
|
https://github.com/user-attachments/assets/47c2f734-5683-49d9-8aea-388c3a2bc16d
|
|
99
99
|
|
|
100
|
-
- [**Stream results**](https://imaging-server-kit.github.io/imaging-server-kit/
|
|
100
|
+
- [**Stream results**](https://imaging-server-kit.github.io/imaging-server-kit/how-to/live-updates.html) to inspect them in real-time.
|
|
101
101
|
|
|
102
102
|
https://github.com/user-attachments/assets/a3f69a9f-fb68-4580-a804-6c57d5807b9a
|
|
103
103
|
|
|
@@ -151,22 +151,9 @@ If you encounter any problems, please file an issue along with a detailed descri
|
|
|
151
151
|
|
|
152
152
|
## Citing
|
|
153
153
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
If you use the Imaging Server Kit in the context of scientific publication, you can cite it as below.
|
|
157
|
-
|
|
158
|
-
BibTeX:
|
|
154
|
+
If you use *Imaging Server Kit* in the context of scientific publication, you can cite it from the Zenodo repository:
|
|
159
155
|
|
|
160
|
-
|
|
161
|
-
@software{mallory_wittwer_2025_15673152,
|
|
162
|
-
author = {Mallory Wittwer and Edward Andò and Maud Barthélemy and Florian Aymanns},
|
|
163
|
-
title = {Imaging-Server-Kit/imaging-server-kit: v0.0.14},
|
|
164
|
-
url = {https://doi.org/10.5281/zenodo.15673152},
|
|
165
|
-
doi = {10.5281/zenodo.15673152},
|
|
166
|
-
version = {v0.0.14},
|
|
167
|
-
year = 2025,
|
|
168
|
-
}
|
|
169
|
-
```
|
|
156
|
+
[](https://doi.org/10.5281/zenodo.15673151)
|
|
170
157
|
|
|
171
158
|
## Acknowledgements
|
|
172
159
|
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Turn Python-based image processing workflows into **algorithms** that gain extra functionalities.
|
|
4
4
|
|
|
5
|
-
- [**Turn your algorithms into web servers**](https://imaging-server-kit.github.io/imaging-server-kit/
|
|
5
|
+
- [**Turn your algorithms into web servers**](https://imaging-server-kit.github.io/imaging-server-kit/tutorial/serve.html) and run computations from [Napari](https://napari.org/stable/), [QuPath](https://qupath.github.io/), or [Python](https://imaging-server-kit.github.io/imaging-server-kit/tutorial/python.html) via HTTP requests.
|
|
6
6
|
|
|
7
7
|
https://github.com/user-attachments/assets/0be819ea-fcc1-48ee-8fae-7265e63a00d4
|
|
8
8
|
|
|
9
|
-
- [**Generate dock widgets**](https://imaging-server-kit.github.io/imaging-server-kit/
|
|
9
|
+
- [**Generate dock widgets**](https://imaging-server-kit.github.io/imaging-server-kit/how-to/napari.html) to run your algorithms interactively in Napari or QuPath.
|
|
10
10
|
|
|
11
11
|
https://github.com/user-attachments/assets/1ff572f7-f159-4f5a-afd4-7a157de3d9f8
|
|
12
12
|
|
|
13
|
-
- Run your algorithms [**tile-by-tile**](https://imaging-server-kit.github.io/imaging-server-kit/
|
|
13
|
+
- Run your algorithms [**tile-by-tile**](https://imaging-server-kit.github.io/imaging-server-kit/how-to/tiling.html) on the input data.
|
|
14
14
|
|
|
15
15
|
https://github.com/user-attachments/assets/47c2f734-5683-49d9-8aea-388c3a2bc16d
|
|
16
16
|
|
|
17
|
-
- [**Stream results**](https://imaging-server-kit.github.io/imaging-server-kit/
|
|
17
|
+
- [**Stream results**](https://imaging-server-kit.github.io/imaging-server-kit/how-to/live-updates.html) to inspect them in real-time.
|
|
18
18
|
|
|
19
19
|
https://github.com/user-attachments/assets/a3f69a9f-fb68-4580-a804-6c57d5807b9a
|
|
20
20
|
|
|
@@ -68,22 +68,9 @@ If you encounter any problems, please file an issue along with a detailed descri
|
|
|
68
68
|
|
|
69
69
|
## Citing
|
|
70
70
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
If you use the Imaging Server Kit in the context of scientific publication, you can cite it as below.
|
|
74
|
-
|
|
75
|
-
BibTeX:
|
|
71
|
+
If you use *Imaging Server Kit* in the context of scientific publication, you can cite it from the Zenodo repository:
|
|
76
72
|
|
|
77
|
-
|
|
78
|
-
@software{mallory_wittwer_2025_15673152,
|
|
79
|
-
author = {Mallory Wittwer and Edward Andò and Maud Barthélemy and Florian Aymanns},
|
|
80
|
-
title = {Imaging-Server-Kit/imaging-server-kit: v0.0.14},
|
|
81
|
-
url = {https://doi.org/10.5281/zenodo.15673152},
|
|
82
|
-
doi = {10.5281/zenodo.15673152},
|
|
83
|
-
version = {v0.0.14},
|
|
84
|
-
year = 2025,
|
|
85
|
-
}
|
|
86
|
-
```
|
|
73
|
+
[](https://doi.org/10.5281/zenodo.15673151)
|
|
87
74
|
|
|
88
75
|
## Acknowledgements
|
|
89
76
|
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Citing
|
|
2
|
+
|
|
3
|
+
If you use *Imaging Server Kit* in a scientific publication, please cite it using its Zenodo record:
|
|
4
|
+
|
|
5
|
+
[](https://doi.org/10.5281/zenodo.15673151)
|
|
6
|
+
|
|
7
|
+
The DOI [10.5281/zenodo.15673151](https://doi.org/10.5281/zenodo.15673151) always resolves to the latest version. Zenodo also provides citations for specific versions, in several formats including BibTeX.
|
|
8
|
+
|
|
9
|
+
For example, for version 0.0.14:
|
|
10
|
+
|
|
11
|
+
```bibtex
|
|
12
|
+
@software{mallory_wittwer_2025_15673152,
|
|
13
|
+
author = {Mallory Wittwer and Edward Andò and Maud Barthélemy and Florian Aymanns},
|
|
14
|
+
title = {Imaging-Server-Kit/imaging-server-kit: v0.0.14},
|
|
15
|
+
url = {https://doi.org/10.5281/zenodo.15673152},
|
|
16
|
+
doi = {10.5281/zenodo.15673152},
|
|
17
|
+
version = {v0.0.14},
|
|
18
|
+
year = 2025,
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The repository also contains a [`CITATION.cff`](https://github.com/Imaging-Server-Kit/imaging-server-kit/blob/main/CITATION.cff) file.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Algorithms
|
|
2
|
+
|
|
3
|
+
## Algorithms
|
|
4
|
+
|
|
5
|
+
An **algorithm** (`sk.Algorithm`) wraps a Python function together with a description of its inputs and outputs. It is usually created with the `@sk.algorithm` decorator.
|
|
6
|
+
|
|
7
|
+
From the function signature and the annotations, the algorithm knows:
|
|
8
|
+
|
|
9
|
+
- Which [data layer](layers-and-stacks.md) corresponds to each parameter the function takes.
|
|
10
|
+
- How to interpret the **outputs** of the function as data layers.
|
|
11
|
+
- Extra information (samples, name, description, compatibility with tiling, etc.).
|
|
12
|
+
|
|
13
|
+
This representation is what allows the package to generate user interfaces, documentation pages, and web APIs for the algorithm without extra code.
|
|
14
|
+
|
|
15
|
+
### Matching parameters with data layers
|
|
16
|
+
|
|
17
|
+
Each parameter of the function is matched with a data layer. The layer is chosen from the first of these sources that applies:
|
|
18
|
+
|
|
19
|
+
1. **Explicit annotations** in `parameters={}`, for example `parameters={"sigma": sk.Float(min=0)}`.
|
|
20
|
+
2. **Type hints**: `int`, `float`, `bool`, `str`, data layer classes such as `sk.Image`, or `np.ndarray` (interpreted as an image).
|
|
21
|
+
3. **Default values**: a data layer instance (for example `sigma=sk.Float(default=1.0)`), or a value whose type is used as in type hints (for example `sigma=1.0` gives an `sk.Float`).
|
|
22
|
+
4. **Variable names**, for parameters without a type hint or default value: `image`, `mask`, `points`, `vectors`, `boxes`, `paths`, and `tracks` are matched with the corresponding data layer.
|
|
23
|
+
|
|
24
|
+
Parameters that cannot be resolved, for example custom classes, lists, or dictionaries, become `sk.Any` layers. They are not shown in user interfaces, and they may not work with servers if they cannot be serialized.
|
|
25
|
+
|
|
26
|
+
### Matching outputs with data layers
|
|
27
|
+
|
|
28
|
+
The values returned (or [yielded](../how-to/live-updates.md)) by the function are converted to data layers:
|
|
29
|
+
|
|
30
|
+
- Data layers, such as `sk.Mask(mask)`, are used as they are.
|
|
31
|
+
- Values of simple types (`int`, `float`, `bool`, `str`, `np.ndarray`, and `None`) are converted to the matching layer. A NumPy array becomes an `sk.Image`.
|
|
32
|
+
- A tuple or a list is treated as several outputs, each converted separately.
|
|
33
|
+
- Any other value becomes an `sk.Any` layer.
|
|
34
|
+
|
|
35
|
+
Wrapping outputs in data layers explicitly is recommended for arrays, since only the data layer tells whether an array is an image, a mask, or a set of points.
|
|
36
|
+
|
|
37
|
+
## Algorithm collections
|
|
38
|
+
|
|
39
|
+
An **algorithm collection** (`sk.MultiAlgorithm`) groups several algorithms under one name. It is created with [`sk.combine`](../how-to/combine.md). In user interfaces, the algorithms of a collection appear in a single dropdown. In Python, methods take an extra `algorithm` argument to select an algorithm by name.
|
|
40
|
+
|
|
41
|
+
## Clients
|
|
42
|
+
|
|
43
|
+
A **client** (`sk.Client`) is connected to an [algorithm server](../tutorial/serve.md). It gives access to the algorithms of the server, and sends the computations to the server when it runs them.
|
|
44
|
+
|
|
45
|
+
## Shared interface
|
|
46
|
+
|
|
47
|
+
Algorithms, collections, and clients share the same interface, defined by the `AlgorithmRunner` base class:
|
|
48
|
+
|
|
49
|
+
| Method | Description |
|
|
50
|
+
|---|---|
|
|
51
|
+
| `run()` | Run an algorithm and return a [`Stack`](layers-and-stacks.md) of results. Supports [tiling](../how-to/tiling.md) and [regions](../how-to/regions.md). |
|
|
52
|
+
| `get_sample()` | Get a sample as a `Stack` of parameters. |
|
|
53
|
+
| `get_n_samples()` | Get the number of samples. |
|
|
54
|
+
| `info()` | Open the documentation page in a web browser. |
|
|
55
|
+
| `get_parameters()` | Get the parameters schema. |
|
|
56
|
+
| `algorithms` | The list of available algorithm names. |
|
|
57
|
+
|
|
58
|
+
As a result, the same code works on a local algorithm, an algorithm collection, or a remote server, and the same Napari widget works for all three via `sk.to_napari`.
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
# All three work the same way:
|
|
62
|
+
results = threshold_algo.run(image, threshold=100)
|
|
63
|
+
results = multi_algo.run(image, algorithm="threshold", threshold=100)
|
|
64
|
+
results = sk.Client("http://localhost:8000").run(image, threshold=100)
|
|
65
|
+
```
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Pixel space
|
|
2
|
+
|
|
3
|
+
## Coordinates
|
|
4
|
+
|
|
5
|
+
Spatial layers (images, masks, points, etc.) have a `position`, which places them in **global pixel coordinates**. A layer's data is expressed in *local* coordinates, and `position` is the offset that translates them to global coordinates.
|
|
6
|
+
|
|
7
|
+
For example, an image cropped from a larger image keeps track of where the crop came from: its data starts at index `(0, 0)`, while its `position` records where that pixel is in the original image.
|
|
8
|
+
|
|
9
|
+
You can set the position when creating a layer:
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
import imaging_server_kit as sk
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
img = sk.Image(np.zeros((100, 200)), position=(50, 20))
|
|
16
|
+
|
|
17
|
+
print(img) # <Image 'Image' float64 (100, 200), at (50, 20)>
|
|
18
|
+
print(img.position) # (50, 20)
|
|
19
|
+
print(img.extent) # Domain(position=(50, 20), size=(100, 200))
|
|
20
|
+
print(img.coords_min) # (50.0, 20.0)
|
|
21
|
+
print(img.coords_max) # (150.0, 220.0)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
For object layers such as points, the extent is the bounding box of the objects:
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
pts = sk.Points(np.array([[30, 10], [60, 90]]))
|
|
28
|
+
|
|
29
|
+
print(pts.position) # (0, 0)
|
|
30
|
+
print(pts.coords_min) # (30.0, 10.0)
|
|
31
|
+
print(pts.coords_max) # (61.0, 91.0)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Stacks have a position and an extent too. Setting the position of a stack moves all of its layers:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
stack = sk.Stack([img, pts])
|
|
38
|
+
|
|
39
|
+
print(stack.extent) # Domain(position=(30, 10), size=(120, 210))
|
|
40
|
+
|
|
41
|
+
stack.position = (10, 10)
|
|
42
|
+
|
|
43
|
+
print(img.position) # (60, 30)
|
|
44
|
+
print(pts.position) # (10, 10)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Layers and stacks share the following properties:
|
|
48
|
+
|
|
49
|
+
| Property | Type | Description |
|
|
50
|
+
|---|---|---|
|
|
51
|
+
| `position` | `tuple` | Offset of the local coordinates in global pixel coordinates. |
|
|
52
|
+
| `extent` | `sk.Domain` | Region covered by the data, in global coordinates. |
|
|
53
|
+
| `coords_min` | `tuple` | Lower corner of the extent (top-left in 2D). |
|
|
54
|
+
| `coords_max` | `tuple` | Upper corner of the extent (bottom-right in 2D). |
|
|
55
|
+
| `size` | `tuple` | Size of the extent along each axis. |
|
|
56
|
+
| `ndim` | `int` | Number of spatial dimensions. |
|
|
57
|
+
|
|
58
|
+
## Domains
|
|
59
|
+
|
|
60
|
+
Extents are `sk.Domain` objects. A domain is a box defined by a `size` and a `position` (its lower corner, which defaults to the origin):
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
roi = sk.Domain(position=(20, 30), size=(60, 80))
|
|
64
|
+
|
|
65
|
+
print(roi.coords_min) # (20.0, 30.0)
|
|
66
|
+
print(roi.coords_max) # (80.0, 110.0)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Domains are used to describe regions of interest and to [restrict computations](../how-to/regions.md), for example.
|
|
70
|
+
|
|
71
|
+
## Merging data
|
|
72
|
+
|
|
73
|
+
### Merging tiles
|
|
74
|
+
|
|
75
|
+
When an algorithm runs [tile-by-tile](../how-to/tiling.md), the input layers are split into tiles, the algorithm runs on each tile, and the results are merged into a single stack. How results are merged depends on the layer type:
|
|
76
|
+
|
|
77
|
+
| Layer | Merging |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `sk.Image` | Intensities are **averaged** in overlapping regions. |
|
|
80
|
+
| `sk.Mask` | By default, the **last tile overwrites** overlapping regions. With `merger="instances"` and a non-zero overlap between tiles, labels are made unique across tiles and objects crossing tiles are stitched together (experimental). |
|
|
81
|
+
| `sk.Points`, `sk.Vectors`, `sk.Boxes` | Each object belongs to the tile that contains it (vectors are placed based on their origin, boxes based on their center). When tiles overlap, objects in overlapping regions are returned once per tile. |
|
|
82
|
+
| Other layers (`sk.Paths`, `sk.Tracks`, values, etc.) | Each tile **replaces** the previous value. |
|
|
83
|
+
|
|
84
|
+
### Merging layers
|
|
85
|
+
|
|
86
|
+
You can use `sk.merge_layers()` to merge a list of layers of the same kind into a new layer, using the rules above. For example, to assemble two images:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
left = sk.Image(np.ones((100, 100)))
|
|
90
|
+
right = sk.Image(np.full((100, 100), 2.0), position=(0, 100))
|
|
91
|
+
|
|
92
|
+
merged = sk.merge_layers([left, right])
|
|
93
|
+
|
|
94
|
+
print(merged) # <Image 'Image' float32 (100, 200)>
|
|
95
|
+
print(merged.position) # (0.0, 0.0)
|
|
96
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Data layers
|
|
2
|
+
|
|
3
|
+
## Data layers
|
|
4
|
+
|
|
5
|
+
A **data layer** holds a single piece of data, such as an image, a segmentation mask, a set of points, or a numeric value, together with information about what that data means. All data layers derive from `sk.Layer`, and the available types are listed in [Data layers](../reference/api/layers.md).
|
|
6
|
+
|
|
7
|
+
Data layers play two roles:
|
|
8
|
+
|
|
9
|
+
- **Describing parameters.** Layers passed in `parameters={}` describe the algorithm's inputs: their type, constraints such as `min` and `max`, a default value, a name, and a description. User interfaces and documentation pages are generated from these descriptions, and parameter values are validated against them.
|
|
10
|
+
- **Holding results.** Layers returned by an algorithm wrap its outputs, so that each output is displayed and handled correctly. For example, an array wrapped in `sk.Mask` is shown as a `Labels` layer in Napari.
|
|
11
|
+
|
|
12
|
+
Every layer has the following attributes:
|
|
13
|
+
|
|
14
|
+
| Attribute | Description |
|
|
15
|
+
|---|---|
|
|
16
|
+
| `data` | The data itself, for example a NumPy array or a number. |
|
|
17
|
+
| `name` | The name of the layer. Defaults to the name of the layer type, such as `"Mask"`. |
|
|
18
|
+
| `meta` | A dictionary of metadata: the description, the merging strategy, and any extra keyword arguments passed to the layer (for example `colormap="viridis"`). |
|
|
19
|
+
| `kind` | A short string identifying the layer type, such as `"mask"`. |
|
|
20
|
+
|
|
21
|
+
Spatial layers also have a position and an extent in global pixel coordinates (see [Coordinates, domains and tile merging](coordinates.md)).
|
|
22
|
+
|
|
23
|
+
## Stacks
|
|
24
|
+
|
|
25
|
+
A **stack** (`sk.Stack`) is an ordered collection of data layers. `.run()` returns the results of an algorithm as a stack, and `.get_sample()` returns samples as a stack of parameter layers.
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
import imaging_server_kit as sk
|
|
29
|
+
import numpy as np
|
|
30
|
+
|
|
31
|
+
stack = sk.Stack([sk.Image(np.zeros((10, 10))), sk.Mask(np.ones((10, 10), dtype=int))])
|
|
32
|
+
|
|
33
|
+
image_layer = stack[0] # By index
|
|
34
|
+
mask_layer = stack.read("Mask") # By name
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Within a stack, layer names are unique. When a layer is added with `stack.add()` under a name that is already taken, a suffix is appended to its name, for example `Image-01`.
|
|
38
|
+
|
|
39
|
+
When results are merged into a stack, layers are matched by name:
|
|
40
|
+
|
|
41
|
+
- A layer with a *new name* is **added** to the stack.
|
|
42
|
+
- A layer with the *same name* as an existing layer **updates** that layer's data and metadata.
|
|
43
|
+
|
|
44
|
+
This concept is the basis of [live updates](../how-to/live-updates.md) and [tiled inference](../how-to/tiling.md); each yielded output, or processed tile, is merged into a single result stack according to the rule above, based on layer name.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# AI policy
|
|
2
|
+
|
|
3
|
+
*Imaging Server Kit* is being developed with passion and intent by humans, with the occasional help of AI to **improve the overall quality of the project**. The table below summarizes the respective contributions of humans and AI agents within the project.
|
|
4
|
+
|
|
5
|
+
| Human contributions |
|
|
6
|
+
| ----- |
|
|
7
|
+
| Conceptualization of the project |
|
|
8
|
+
| Implementing core functionalities (public API) |
|
|
9
|
+
| Deciding which features to prioritize |
|
|
10
|
+
| Writing the initial documentation site |
|
|
11
|
+
| Reviewing and validating AI-generated outputs |
|
|
12
|
+
| Reviewing tests and testing the package on real scientific data |
|
|
13
|
+
|
|
14
|
+
| AI contributions |
|
|
15
|
+
| -- |
|
|
16
|
+
| Catching and fixing bugs |
|
|
17
|
+
| Identifying series of actions that lead to unexpected results |
|
|
18
|
+
| Targeted refactoring to improve code clarity or maintainability |
|
|
19
|
+
| Enhancing the documentation site |
|
|
20
|
+
| Writing or fixing public docstrings |
|
|
21
|
+
| Writing tests and testing the package on toy scientific data |
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Try the demos
|
|
2
|
+
|
|
3
|
+
The package comes with a set of demo algorithms. Running them is the quickest way to get a feel for what *Imaging Server Kit* does before writing any code.
|
|
4
|
+
|
|
5
|
+
!!! note
|
|
6
|
+
The demos below use Napari. Install it with `pip install "imaging-server-kit[napari]"` (see [Installation](installation.md)).
|
|
7
|
+
|
|
8
|
+
## Napari demo
|
|
9
|
+
|
|
10
|
+
From a terminal, run:
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
serverkit demo napari
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
This opens a **Napari viewer** with the *Imaging Server Kit* plugin already loaded. The *Algorithm* dropdown lists the demo algorithms.
|
|
17
|
+
|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
When you select an **algorithm**, the *Parameters* panel updates to show the tunable **parameters** of that algorithm.
|
|
21
|
+
|
|
22
|
+
Most algorithms need an input image. You can **load a sample image** by selecting it in the *Samples* dropdown and clicking *Load*. Once an image is loaded, you can run the algorithm and look at the results.
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
Some algorithms re-run automatically when you change a parameter. For example, *Intensity threshold* updates its output as soon as you adjust the threshold value.
|
|
27
|
+
|
|
28
|
+
!!! tip "Algorithm documentation"
|
|
29
|
+
Click the **🌐 Doc** button to open the **documentation page** of an algorithm in a web browser.
|
|
30
|
+
|
|
31
|
+
## Server demo
|
|
32
|
+
|
|
33
|
+
To see how algorithms can be served over HTTP, start the demo server:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
serverkit demo serve
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This starts a web server on your machine at http://localhost:8000. If you open this address in a browser, you will see an overview of the algorithms available on the server.
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
### Connecting from Napari
|
|
44
|
+
|
|
45
|
+
While the server is running, open another terminal and run:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
napari -w imaging-server-kit
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
This is equivalent to opening `Plugins > Imaging Server Kit > Connect to server` in Napari.
|
|
52
|
+
|
|
53
|
+
In the plugin panel, enter the server address (http://localhost:8000) and press *Connect*. The *Algorithm* dropdown fills with the algorithms available on the server, which you can use just like in the local demo.
|
|
54
|
+
|
|
55
|
+
<video width="640" controls loop autoplay muted playsinline>
|
|
56
|
+
<source src="../assets/videos/server_napari.mp4" type="video/mp4">
|
|
57
|
+
</video>
|
|
58
|
+
|
|
59
|
+
!!! note
|
|
60
|
+
In this demo, the client and the server run on the same machine. The server could just as well run on another machine of your network, such as a workstation or a cluster node (see [Serve an algorithm](../how-to/deploy-server.md)).
|
|
61
|
+
|
|
62
|
+
### Connecting from QuPath
|
|
63
|
+
|
|
64
|
+
Algorithm servers can also be used from QuPath, for segmentation and object detection tasks. See [Usage with QuPath](../how-to/qupath.md) for a walkthrough with the demo server.
|
|
65
|
+
|
|
66
|
+
## Next steps
|
|
67
|
+
|
|
68
|
+
Learn how to [create your own algorithm](../tutorial/create-algorithm.md), so that it can be served and used in Napari just like the demos.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
The Imaging Server Kit supports Python 3.10 to 3.13.
|
|
4
|
+
|
|
5
|
+
## Installing with pip
|
|
6
|
+
|
|
7
|
+
Install the `imaging-server-kit` package with `pip`:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pip install imaging-server-kit
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Optional dependencies
|
|
14
|
+
|
|
15
|
+
The Napari and QuPath integrations rely on extra packages that are not installed by default. Install them through the corresponding extras:
|
|
16
|
+
|
|
17
|
+
| Command | Adds |
|
|
18
|
+
|---|---|
|
|
19
|
+
| `pip install "imaging-server-kit[napari]"` | [Napari](https://github.com/napari/napari) and [napari-toolkit](https://github.com/MIC-DKFZ/napari_toolkit), for dock widgets and the Napari plugin |
|
|
20
|
+
| `pip install "imaging-server-kit[qupath]"` | [QuBaLab](https://pypi.org/project/qubalab/) (`>=0.2.0`) and the Napari extra, for the QuPath integration |
|
|
21
|
+
| `pip install "imaging-server-kit[all]"` | All the above, plus the documentation and test dependencies |
|
|
22
|
+
|
|
23
|
+
!!! note
|
|
24
|
+
The `qupath` extra requires Python 3.11 or later, because of QuBaLab.
|
|
25
|
+
|
|
26
|
+
## Agent skills
|
|
27
|
+
|
|
28
|
+
The package includes two skills for AI coding agents such as [Claude Code](https://claude.com/claude-code). They help the agent write algorithms with `@sk.algorithm` and build Napari or QuPath interfaces for them. Agents do not pick up skills from installed Python packages, so install them with:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
serverkit install-skills
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This copies the skills to `.claude/skills/` in the current directory, which makes them available in that project. To make them available in all projects, use `serverkit install-skills --user` (installs to `~/.claude/skills/`).
|
|
35
|
+
|
|
36
|
+
| Skill | Helps with |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `isk-write-algorithm` | Turning a function into an algorithm: parameters, outputs, samples, tiling, and servers |
|
|
39
|
+
| `isk-napari-qupath-gui` | Running algorithms in Napari or QuPath, and troubleshooting the widgets |
|
|
40
|
+
|
|
41
|
+
Existing skills are not overwritten unless you pass `--force`, so after upgrading the package, run `serverkit install-skills --force` to get the updated skills. See [Command line](../reference/cli.md) for all options.
|
|
42
|
+
|
|
43
|
+
## Development version
|
|
44
|
+
|
|
45
|
+
Clone the repository and install the package in editable mode:
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
git clone https://github.com/Imaging-Server-Kit/imaging-server-kit.git
|
|
49
|
+
cd imaging-server-kit
|
|
50
|
+
pip install -e ".[all]"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Next steps
|
|
54
|
+
|
|
55
|
+
[Try the demos](demos.md) to get a first look at what the package can do.
|