@jax-data-science/sci-image-visualizer 0.8.3 → 0.10.0
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.
- package/README.md +201 -460
- package/esm2022/index.mjs +34 -15
- package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +163 -91
- package/esm2022/lib/contracts/capabilities.contract.mjs +4 -3
- package/esm2022/lib/contracts/cell-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +5 -1
- package/esm2022/lib/contracts/color.mjs +60 -0
- package/esm2022/lib/contracts/colormap-lut.mjs +213 -57
- package/esm2022/lib/contracts/coordinate-transform.contract.mjs +1 -1
- package/esm2022/lib/contracts/display-types.mjs +11 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/instance-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/intensity.mjs +48 -5
- package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +1 -1
- package/esm2022/lib/contracts/plot-type.mjs +134 -17
- package/esm2022/lib/contracts/ports/image-state.port.mjs +4 -1
- package/esm2022/lib/contracts/ports/preferences.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/region-io.port.mjs +2 -1
- package/esm2022/lib/contracts/ports/spatial-data.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/tile-access.port.mjs +2 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-overlay.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
- package/esm2022/lib/contracts/sam.contract.mjs +1 -1
- package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
- package/esm2022/lib/contracts/semantic-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/spatial-dataset.contract.mjs +3 -1
- package/esm2022/lib/contracts/toolbar-tool.contract.mjs +6 -4
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +2 -1
- package/esm2022/lib/geometry/contour.mjs +63 -0
- package/esm2022/lib/geometry/loft.mjs +128 -0
- package/esm2022/lib/geometry/polylabel.mjs +156 -0
- package/esm2022/lib/geometry/raster.mjs +98 -0
- package/esm2022/lib/geometry/reconstruct.mjs +315 -0
- package/esm2022/lib/geometry/reslice-image.mjs +57 -0
- package/esm2022/lib/geometry/ring.mjs +201 -0
- package/esm2022/lib/geometry/section.mjs +215 -0
- package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +202 -102
- package/esm2022/lib/implementations/base-store-visualizer.mjs +201 -48
- package/esm2022/lib/implementations/napari-js/napari-axes-gizmo.mjs +65 -0
- package/esm2022/lib/implementations/napari-js/napari-display-state.mjs +136 -0
- package/esm2022/lib/implementations/napari-js/napari-helpers.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +602 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +12 -9
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +83 -0
- package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +180 -591
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +2 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +614 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +769 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +270 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +159 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +106 -1408
- package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-surface-scene.mjs +271 -0
- package/esm2022/lib/implementations/napari-js/napari-tile-client.mjs +562 -0
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +347 -0
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +427 -4207
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +550 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +6 -6
- package/esm2022/lib/implementations/napari-js/region-overlay/overlay-projection.mjs +96 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-edit.mjs +35 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +194 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +30 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +274 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +144 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/layer-groups.mjs +165 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/plan-context.mjs +78 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +182 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +369 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +306 -0
- package/esm2022/lib/implementations/osd/display-pipeline.mjs +102 -40
- package/esm2022/lib/implementations/osd/histogram-sampler.mjs +56 -31
- package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +128 -0
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +333 -1685
- package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/osd/osd-coords.mjs +5 -6
- package/esm2022/lib/implementations/osd/osd-export.mjs +122 -0
- package/esm2022/lib/implementations/osd/osd-lib.mjs +15 -1
- package/esm2022/lib/implementations/osd/osd-navigator-chrome.mjs +205 -0
- package/esm2022/lib/implementations/osd/osd-pixel-readback.mjs +68 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +164 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +213 -716
- package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +52 -60
- package/esm2022/lib/implementations/osd/osd-tile-source.mjs +105 -0
- package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +2 -0
- package/esm2022/lib/implementations/osd/osd-viewer-mount.mjs +44 -0
- package/esm2022/lib/implementations/osd/osd-viewport.mjs +184 -0
- package/esm2022/lib/implementations/osd/osd-zoom.mjs +7 -1
- package/esm2022/lib/implementations/osd/simple-source.mjs +395 -0
- package/esm2022/lib/implementations/osd/slice-cache.mjs +53 -48
- package/esm2022/lib/implementations/osd/tile-client.mjs +32 -11
- package/esm2022/lib/implementations/osd/tile-recolor.mjs +330 -0
- package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +161 -73
- package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/plotly/plotly-image-loader.mjs +112 -0
- package/esm2022/lib/implementations/plotly/plotly-image-recolor.mjs +178 -0
- package/esm2022/lib/implementations/plotly/plotly-intensity-inset.mjs +33 -0
- package/esm2022/lib/implementations/plotly/plotly-isosurface-controls.mjs +83 -0
- package/esm2022/lib/implementations/plotly/plotly-layouts.mjs +121 -0
- package/esm2022/lib/implementations/plotly/plotly-readback.mjs +117 -0
- package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +19 -10
- package/esm2022/lib/implementations/plotly/plotly-shape-projection.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +79 -19
- package/esm2022/lib/implementations/plotly/plotly-zoom-controller.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly.service.mjs +439 -1655
- package/esm2022/lib/implementations/region-centroids.mjs +47 -0
- package/esm2022/lib/implementations/simple-slice-access.service.mjs +22 -12
- package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +172 -92
- package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +103 -22
- package/esm2022/lib/implementations/tile-server/index.mjs +6 -0
- package/esm2022/lib/implementations/tile-server/native-histogram.mjs +30 -0
- package/esm2022/lib/implementations/tile-server/poll-descriptor.mjs +65 -0
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +42 -0
- package/esm2022/lib/implementations/tile-server/transport.mjs +135 -0
- package/esm2022/lib/intensity/intensity-profile.mjs +107 -0
- package/esm2022/lib/intensity/intensity-profile.service.mjs +223 -0
- package/esm2022/lib/intensity-inset/intensity-inset.component.mjs +133 -0
- package/esm2022/lib/models/bezier.mjs +1 -11
- package/esm2022/lib/models/class-preset.mjs +41 -3
- package/esm2022/lib/models/geometry.mjs +27 -164
- package/esm2022/lib/models/polygon-edit.mjs +254 -0
- package/esm2022/lib/models/polygon-factory.mjs +134 -0
- package/esm2022/lib/models/region-clone.mjs +68 -0
- package/esm2022/lib/models/region-geojson.mjs +411 -0
- package/esm2022/lib/models/region.mjs +34 -33
- package/esm2022/lib/models/shape.mjs +18 -16
- package/esm2022/lib/plot-mode/contribution-host.mjs +297 -0
- package/esm2022/lib/plot-mode/plot-mode-controller.mjs +9 -6
- package/esm2022/lib/plot-mode/plot-type-menu.mjs +85 -0
- package/esm2022/lib/plot-mode/tool-params-model.mjs +87 -0
- package/esm2022/lib/plot.utilities.mjs +296 -473
- package/esm2022/lib/processing/image-crop.mjs +1 -1
- package/esm2022/lib/processing/processing-image.mjs +28 -15
- package/esm2022/lib/provide-visualization.mjs +40 -14
- package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
- package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +163 -0
- package/esm2022/lib/region-editor/file-stem.mjs +13 -0
- package/esm2022/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.mjs +118 -0
- package/esm2022/lib/region-editor/mask-export.service.mjs +98 -0
- package/esm2022/lib/region-editor/mask-raster.mjs +11 -5
- package/esm2022/lib/region-editor/region-color-dialog/region-color-dialog.component.mjs +56 -0
- package/esm2022/lib/region-editor/region-editor-help/region-editor-help.component.mjs +28 -0
- package/esm2022/lib/region-editor/region-editor.component.mjs +896 -660
- package/esm2022/lib/region-editor/region-metrics.mjs +86 -0
- package/esm2022/lib/region-editor/region-persistence.service.mjs +160 -0
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +169 -0
- package/esm2022/lib/region-editor/save-mask-dialog/save-mask-dialog.component.mjs +91 -0
- package/esm2022/lib/region-editor/save-regions-dialog/save-regions-dialog.component.mjs +92 -0
- package/esm2022/lib/region-ops.service.mjs +28 -70
- package/esm2022/lib/region-overlay/region-geometry.mjs +360 -0
- package/esm2022/lib/region-overlay/region-hit-test.mjs +103 -0
- package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
- package/esm2022/lib/region-overlay/region-style.mjs +97 -0
- package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
- package/esm2022/lib/region-source/http-region-source.mjs +104 -0
- package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
- package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
- package/esm2022/lib/region-source/region-source.mjs +67 -0
- package/esm2022/lib/region-source/region-tiles.mjs +708 -0
- package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
- package/esm2022/lib/render-orchestrator.mjs +14 -11
- package/esm2022/lib/render-session.mjs +207 -0
- package/esm2022/lib/routing-visualizer.service.mjs +858 -414
- package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
- package/esm2022/lib/spatial/density-raster.mjs +14 -0
- package/esm2022/lib/spatial/embedding-compute-coordinator.mjs +239 -0
- package/esm2022/lib/spatial/embedding-compute.mjs +43 -10
- package/esm2022/lib/spatial/gene-search.mjs +1 -1
- package/esm2022/lib/spatial/glyphs.mjs +97 -0
- package/esm2022/lib/spatial/lod.mjs +187 -0
- package/esm2022/lib/spatial/spatial-controls.facade.mjs +200 -0
- package/esm2022/lib/spatial/spatial-density.mjs +25 -16
- package/esm2022/lib/spatial/spatial-encoding.mjs +26 -82
- package/esm2022/lib/spatial/spatial-expression.mjs +43 -42
- package/esm2022/lib/spatial/spatial-framing.mjs +1 -1
- package/esm2022/lib/spatial/spatial-heatmap.mjs +6 -3
- package/esm2022/lib/spatial/spatial-hover.mjs +5 -33
- package/esm2022/lib/spatial/spatial-panel-model.mjs +282 -0
- package/esm2022/lib/spatial/spatial-sections.mjs +1 -1
- package/esm2022/lib/spatial/spatial-selection.mjs +33 -46
- package/esm2022/lib/spatial/spatial-tile-merge.mjs +219 -0
- package/esm2022/lib/spatial/spatial-tiles.mjs +12 -648
- package/esm2022/lib/spatial/spatial-volume-image.mjs +2 -4
- package/esm2022/lib/spatial/stats.mjs +71 -0
- package/esm2022/lib/spatial/transcript-grouping.mjs +307 -0
- package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +150 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-data-model.mjs +309 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-help.mjs +145 -0
- package/esm2022/lib/spatial-controls/spatial-charts/plotly-chart-host.mjs +158 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.mjs +47 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +297 -802
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.mjs +89 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.mjs +52 -0
- package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +143 -1238
- package/esm2022/lib/spatial-controls/spatial-gene-picker.mjs +153 -0
- package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +241 -0
- package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +193 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +132 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.model.mjs +67 -0
- package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +147 -0
- package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +300 -0
- package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +370 -0
- package/esm2022/lib/store/class-color.util.mjs +53 -5
- package/esm2022/lib/store/class-signatures.mjs +63 -0
- package/esm2022/lib/store/region-history.mjs +146 -0
- package/esm2022/lib/store/region-scope-cache.mjs +144 -0
- package/esm2022/lib/store/region-selection.mjs +82 -0
- package/esm2022/lib/store/region-source-scope.mjs +171 -0
- package/esm2022/lib/store/region-store.service.mjs +986 -670
- package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
- package/esm2022/lib/store/visualizer-store.service.mjs +81 -76
- package/esm2022/lib/toast-outlets.mjs +5 -4
- package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +92 -434
- package/esm2022/lib/toolbar/canvas-tools.mjs +20 -0
- package/esm2022/lib/toolbar/crop/slide-crop.mjs +26 -42
- package/esm2022/lib/toolbar/plot-type-selector/plot-type-selector.component.mjs +85 -0
- package/esm2022/lib/toolbar/region-tools/region-tool-buttons.mjs +74 -0
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +120 -0
- package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +74 -78
- package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +50 -8
- package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +61 -42
- package/esm2022/lib/toolbar/segmentation/pending-calls.mjs +47 -0
- package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +12 -4
- package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +70 -14
- package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +135 -172
- package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +9 -90
- package/esm2022/lib/toolbar/segmentation/sam-session.service.mjs +183 -0
- package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +95 -150
- package/esm2022/lib/toolbar/segmentation/segmentation-commit.mjs +12 -0
- package/esm2022/lib/toolbar/segmentation/segmentation-runner.mjs +108 -0
- package/esm2022/lib/toolbar/segmentation-tools/segmentation-tools.component.mjs +155 -0
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +121 -0
- package/esm2022/lib/toolbar/tool-kit/async-tool-status.mjs +37 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool-manager.mjs +63 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool.mjs +2 -0
- package/esm2022/lib/toolbar/tool-kit/frame-pixels.mjs +108 -0
- package/esm2022/lib/toolbar/tool-kit/mask-stroke-editor.mjs +306 -0
- package/esm2022/lib/toolbar/tool-kit/matrix-frame.mjs +61 -0
- package/esm2022/lib/toolbar/tool-kit/tool-overlay.mjs +140 -0
- package/esm2022/lib/toolbar/tool-kit/undo-gesture.mjs +24 -0
- package/esm2022/lib/toolbar/tool-slider/tool-slider.component.mjs +63 -0
- package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +50 -0
- package/esm2022/lib/toolbar/toolbar.component.mjs +84 -119
- package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +93 -115
- package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +107 -0
- package/esm2022/lib/toolbar/wand/wand-region-grow.mjs +321 -0
- package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +121 -416
- package/esm2022/lib/toolbar/wand/wand.service.mjs +30 -894
- package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +48 -90
- package/esm2022/lib/util/mark-for-check.mjs +17 -0
- package/esm2022/lib/util/supersede.mjs +56 -0
- package/esm2022/lib/visualization.module.mjs +39 -141
- package/esm2022/lib/visualizer/floating-drag.directive.mjs +58 -0
- package/esm2022/lib/visualizer/region-actions.mjs +149 -0
- package/esm2022/lib/visualizer/region-load.mjs +123 -0
- package/esm2022/lib/visualizer/spatial-dataset-binder.mjs +163 -0
- package/esm2022/lib/visualizer/tool-modes.mjs +113 -0
- package/esm2022/lib/visualizer/viewer-shortcuts.mjs +167 -0
- package/esm2022/lib/visualizer/visualizer-context-menu.mjs +119 -0
- package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
- package/esm2022/lib/visualizer.component.mjs +602 -1902
- package/esm2022/lib/workers/spatial-math-ops.mjs +43 -0
- package/esm2022/lib/workers/spatial-math-worker.mjs +10 -0
- package/esm2022/lib/workers/spatial-math.mjs +190 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs +47169 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs +238 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +41 -34467
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/fesm2022/mask.worker.js +36 -917
- package/fesm2022/onnx-sam.worker.js +52 -16
- package/fesm2022/region-source.worker.js +1067 -0
- package/fesm2022/spatial-math.worker.js +471 -0
- package/fesm2022/tsne.worker.js +32 -15
- package/index.d.ts +19 -10
- package/lib/channel-histogram/channel-histogram.component.d.ts +53 -43
- package/lib/contracts/capabilities.contract.d.ts +4 -2
- package/lib/contracts/cell-segmenter.contract.d.ts +1 -0
- package/lib/contracts/channel-histogram-api.contract.d.ts +4 -0
- package/lib/contracts/color.d.ts +27 -0
- package/lib/contracts/colormap-lut.d.ts +19 -4
- package/lib/contracts/coordinate-transform.contract.d.ts +3 -3
- package/lib/contracts/display-types.d.ts +21 -0
- package/lib/contracts/image.contract.d.ts +4 -0
- package/lib/contracts/instance-segmenter.contract.d.ts +5 -0
- package/lib/contracts/intensity.d.ts +13 -2
- package/lib/contracts/plot-type.d.ts +3 -1
- package/lib/contracts/ports/image-state.port.d.ts +6 -2
- package/lib/contracts/ports/preferences.port.d.ts +4 -0
- package/lib/contracts/ports/region-io.port.d.ts +1 -0
- package/lib/contracts/ports/spatial-data.port.d.ts +4 -10
- package/lib/contracts/ports/tile-access.port.d.ts +1 -0
- package/lib/contracts/region-editor-api.contract.d.ts +85 -1
- package/lib/contracts/region-overlay.contract.d.ts +5 -0
- package/lib/contracts/region-store.contract.d.ts +22 -0
- package/lib/contracts/sam.contract.d.ts +7 -0
- package/lib/contracts/section-view.contract.d.ts +44 -0
- package/lib/contracts/semantic-segmenter.contract.d.ts +6 -0
- package/lib/contracts/spatial-dataset.contract.d.ts +19 -6
- package/lib/contracts/toolbar-tool.contract.d.ts +1 -0
- package/lib/contracts/visualizer.contract.d.ts +231 -54
- package/lib/contracts/viz-config.d.ts +9 -0
- package/lib/geometry/contour.d.ts +24 -0
- package/lib/geometry/loft.d.ts +22 -0
- package/lib/geometry/polylabel.d.ts +23 -0
- package/lib/geometry/raster.d.ts +42 -0
- package/lib/geometry/reconstruct.d.ts +54 -0
- package/lib/geometry/reslice-image.d.ts +33 -0
- package/lib/geometry/ring.d.ts +67 -0
- package/lib/geometry/section.d.ts +52 -0
- package/lib/hex-color-picker/hex-color-picker.component.d.ts +61 -27
- package/lib/implementations/base-store-visualizer.d.ts +61 -15
- package/lib/implementations/napari-js/napari-axes-gizmo.d.ts +36 -0
- package/lib/implementations/napari-js/napari-display-state.d.ts +76 -0
- package/lib/implementations/napari-js/napari-helpers.d.ts +129 -0
- package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +162 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -3
- package/lib/implementations/napari-js/napari-loading-state.d.ts +37 -0
- package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +68 -71
- package/lib/implementations/napari-js/napari-scene.d.ts +126 -0
- package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +163 -0
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +212 -0
- package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +114 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +91 -0
- package/lib/implementations/napari-js/napari-spatial-scene.d.ts +118 -0
- package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +56 -263
- package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +1 -1
- package/lib/implementations/napari-js/napari-surface-scene.d.ts +76 -0
- package/lib/implementations/napari-js/napari-tile-client.d.ts +214 -0
- package/lib/implementations/napari-js/napari-tool-bridge.d.ts +179 -0
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +169 -883
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +148 -0
- package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
- package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +8 -12
- package/lib/implementations/napari-js/region-overlay/overlay-projection.d.ts +59 -0
- package/lib/implementations/napari-js/region-overlay/region-edit.d.ts +15 -0
- package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +54 -0
- package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +26 -0
- package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +70 -0
- package/lib/implementations/napari-js/spatial-tiles/density-layer.d.ts +61 -0
- package/lib/implementations/napari-js/spatial-tiles/layer-groups.d.ts +67 -0
- package/lib/implementations/napari-js/spatial-tiles/plan-context.d.ts +38 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +71 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-jobs.d.ts +105 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +56 -0
- package/lib/implementations/osd/display-pipeline.d.ts +38 -9
- package/lib/implementations/osd/histogram-sampler.d.ts +22 -12
- package/lib/implementations/osd/openseadragon-viewer-options.d.ts +35 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +78 -354
- package/lib/implementations/osd/osd-coordinate-transform.d.ts +2 -1
- package/lib/implementations/osd/osd-coords.d.ts +6 -4
- package/lib/implementations/osd/osd-export.d.ts +36 -0
- package/lib/implementations/osd/osd-lib.d.ts +7 -0
- package/lib/implementations/osd/osd-navigator-chrome.d.ts +69 -0
- package/lib/implementations/osd/osd-pixel-readback.d.ts +22 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +38 -0
- package/lib/implementations/osd/osd-region-overlay.d.ts +46 -51
- package/lib/implementations/osd/osd-scale-bar.d.ts +8 -6
- package/lib/implementations/osd/osd-tile-source.d.ts +49 -0
- package/lib/implementations/osd/osd-viewer-like.d.ts +100 -0
- package/lib/implementations/osd/osd-viewer-mount.d.ts +14 -0
- package/lib/implementations/osd/osd-viewport.d.ts +77 -0
- package/lib/implementations/osd/osd-zoom.d.ts +6 -0
- package/lib/implementations/osd/simple-source.d.ts +161 -0
- package/lib/implementations/osd/slice-cache.d.ts +12 -3
- package/lib/implementations/osd/tile-client.d.ts +11 -14
- package/lib/implementations/osd/tile-recolor.d.ts +141 -0
- package/lib/implementations/plotly/omics-trace-builders.d.ts +32 -20
- package/lib/implementations/plotly/plotly-image-loader.d.ts +49 -0
- package/lib/implementations/plotly/plotly-image-recolor.d.ts +75 -0
- package/lib/implementations/plotly/plotly-intensity-inset.d.ts +8 -0
- package/lib/implementations/plotly/plotly-isosurface-controls.d.ts +38 -0
- package/lib/implementations/plotly/plotly-layouts.d.ts +188 -0
- package/lib/implementations/plotly/plotly-readback.d.ts +41 -0
- package/lib/implementations/plotly/plotly-region-overlay.d.ts +2 -2
- package/lib/implementations/plotly/plotly-shape-projection.d.ts +92 -0
- package/lib/implementations/plotly/plotly-trace-builders.d.ts +23 -12
- package/lib/implementations/plotly/plotly-zoom-controller.d.ts +86 -0
- package/lib/implementations/plotly/plotly.service.d.ts +136 -401
- package/lib/implementations/region-centroids.d.ts +14 -0
- package/lib/implementations/simple-slice-access.service.d.ts +7 -4
- package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +42 -18
- package/lib/implementations/spatial-data-http/spatial-wire.d.ts +34 -9
- package/lib/implementations/tile-server/index.d.ts +5 -0
- package/lib/implementations/tile-server/native-histogram.d.ts +25 -0
- package/lib/implementations/tile-server/poll-descriptor.d.ts +39 -0
- package/lib/implementations/tile-server/tile-protocol.d.ts +83 -0
- package/lib/implementations/tile-server/transport.d.ts +62 -0
- package/lib/intensity/intensity-profile.d.ts +66 -0
- package/lib/intensity/intensity-profile.service.d.ts +108 -0
- package/lib/intensity-inset/intensity-inset.component.d.ts +58 -0
- package/lib/models/bezier.d.ts +0 -5
- package/lib/models/class-preset.d.ts +25 -0
- package/lib/models/geometry.d.ts +14 -48
- package/lib/models/polygon-edit.d.ts +72 -0
- package/lib/models/polygon-factory.d.ts +45 -0
- package/lib/models/region-clone.d.ts +20 -0
- package/lib/models/region-geojson.d.ts +57 -0
- package/lib/models/region.d.ts +59 -4
- package/lib/models/shape.d.ts +8 -0
- package/lib/plot-mode/contribution-host.d.ts +125 -0
- package/lib/plot-mode/plot-type-menu.d.ts +60 -0
- package/lib/plot-mode/tool-params-model.d.ts +49 -0
- package/lib/plot.utilities.d.ts +19 -30
- package/lib/processing/processing-image.d.ts +5 -2
- package/lib/provide-visualization.d.ts +19 -2
- package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
- package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +86 -0
- package/lib/region-editor/file-stem.d.ts +7 -0
- package/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.d.ts +45 -0
- package/lib/region-editor/mask-export.service.d.ts +54 -0
- package/lib/region-editor/mask-raster.d.ts +2 -8
- package/lib/region-editor/region-color-dialog/region-color-dialog.component.d.ts +29 -0
- package/lib/region-editor/region-editor-help/region-editor-help.component.d.ts +11 -0
- package/lib/region-editor/region-editor.component.d.ts +283 -200
- package/lib/region-editor/region-metrics.d.ts +34 -0
- package/lib/region-editor/region-persistence.service.d.ts +77 -0
- package/lib/region-editor/region-table/region-table.component.d.ts +89 -0
- package/lib/region-editor/save-mask-dialog/save-mask-dialog.component.d.ts +36 -0
- package/lib/region-editor/save-regions-dialog/save-regions-dialog.component.d.ts +37 -0
- package/lib/region-ops.service.d.ts +1 -7
- package/lib/region-overlay/region-geometry.d.ts +158 -0
- package/lib/region-overlay/region-hit-test.d.ts +38 -0
- package/lib/region-overlay/region-source-layer.d.ts +96 -0
- package/lib/region-overlay/region-style.d.ts +52 -0
- package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
- package/lib/region-source/http-region-source.d.ts +45 -0
- package/lib/region-source/region-source-ops.d.ts +89 -0
- package/lib/region-source/region-source-worker.d.ts +7 -0
- package/lib/region-source/region-source.d.ts +82 -0
- package/lib/region-source/region-tiles.d.ts +289 -0
- package/lib/region-source/worker-region-source.d.ts +65 -0
- package/lib/render-orchestrator.d.ts +6 -2
- package/lib/render-session.d.ts +75 -0
- package/lib/routing-visualizer.service.d.ts +248 -59
- package/lib/section-pane/section-pane.component.d.ts +47 -0
- package/lib/spatial/density-raster.d.ts +6 -0
- package/lib/spatial/embedding-compute-coordinator.d.ts +123 -0
- package/lib/spatial/embedding-compute.d.ts +21 -2
- package/lib/spatial/glyphs.d.ts +16 -0
- package/lib/spatial/lod.d.ts +94 -0
- package/lib/spatial/spatial-controls.facade.d.ts +64 -0
- package/lib/spatial/spatial-density.d.ts +15 -5
- package/lib/spatial/spatial-encoding.d.ts +11 -44
- package/lib/spatial/spatial-expression.d.ts +40 -22
- package/lib/spatial/spatial-framing.d.ts +1 -0
- package/lib/spatial/spatial-heatmap.d.ts +2 -0
- package/lib/spatial/spatial-hover.d.ts +4 -16
- package/lib/spatial/spatial-panel-model.d.ts +135 -0
- package/lib/spatial/spatial-selection.d.ts +21 -26
- package/lib/spatial/spatial-tile-merge.d.ts +41 -0
- package/lib/spatial/spatial-tiles.d.ts +9 -256
- package/lib/spatial/stats.d.ts +38 -0
- package/lib/spatial/transcript-grouping.d.ts +119 -0
- package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-charts/chart-data-model.d.ts +153 -0
- package/lib/spatial-controls/spatial-charts/chart-help.d.ts +69 -0
- package/lib/spatial-controls/spatial-charts/plotly-chart-host.d.ts +98 -0
- package/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.d.ts +26 -0
- package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +101 -260
- package/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.d.ts +43 -0
- package/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.d.ts +27 -0
- package/lib/spatial-controls/spatial-controls.component.d.ts +68 -448
- package/lib/spatial-controls/spatial-gene-picker.d.ts +86 -0
- package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +102 -0
- package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +72 -0
- package/lib/spatial-controls/spatial-key/spatial-key.component.d.ts +66 -0
- package/lib/spatial-controls/spatial-key/spatial-key.model.d.ts +33 -0
- package/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +117 -0
- package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +142 -0
- package/lib/store/class-color.util.d.ts +39 -2
- package/lib/store/class-signatures.d.ts +11 -0
- package/lib/store/region-history.d.ts +66 -0
- package/lib/store/region-scope-cache.d.ts +65 -0
- package/lib/store/region-selection.d.ts +36 -0
- package/lib/store/region-source-scope.d.ts +68 -0
- package/lib/store/region-store.service.d.ts +312 -116
- package/lib/store/visualizer-store.service.d.ts +32 -33
- package/lib/toast-outlets.d.ts +4 -3
- package/lib/toolbar/brush/brush-tool.service.d.ts +31 -98
- package/lib/toolbar/canvas-tools.d.ts +20 -0
- package/lib/toolbar/crop/slide-crop.d.ts +10 -4
- package/lib/toolbar/plot-type-selector/plot-type-selector.component.d.ts +38 -0
- package/lib/toolbar/region-tools/region-tool-buttons.d.ts +21 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +62 -0
- package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +10 -14
- package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +12 -2
- package/lib/toolbar/segmentation/onnx-sam-session.d.ts +22 -3
- package/lib/toolbar/segmentation/pending-calls.d.ts +31 -0
- package/lib/toolbar/segmentation/sam-model-registry.d.ts +9 -3
- package/lib/toolbar/segmentation/sam-onnx-core.d.ts +18 -5
- package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +46 -32
- package/lib/toolbar/segmentation/sam-prompt.d.ts +7 -31
- package/lib/toolbar/segmentation/sam-session.service.d.ts +74 -0
- package/lib/toolbar/segmentation/sam-tool.service.d.ts +23 -30
- package/lib/toolbar/segmentation/segmentation-commit.d.ts +8 -0
- package/lib/toolbar/segmentation/segmentation-runner.d.ts +52 -0
- package/lib/toolbar/segmentation-tools/segmentation-tools.component.d.ts +87 -0
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +51 -0
- package/lib/toolbar/tool-kit/async-tool-status.d.ts +21 -0
- package/lib/toolbar/tool-kit/canvas-tool-manager.d.ts +36 -0
- package/lib/toolbar/tool-kit/canvas-tool.d.ts +86 -0
- package/lib/toolbar/tool-kit/frame-pixels.d.ts +45 -0
- package/lib/toolbar/tool-kit/mask-stroke-editor.d.ts +125 -0
- package/lib/toolbar/tool-kit/matrix-frame.d.ts +40 -0
- package/lib/toolbar/tool-kit/tool-overlay.d.ts +60 -0
- package/lib/toolbar/tool-kit/undo-gesture.d.ts +17 -0
- package/lib/toolbar/tool-slider/tool-slider.component.d.ts +33 -0
- package/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.d.ts +24 -0
- package/lib/toolbar/toolbar.component.d.ts +55 -84
- package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +33 -40
- package/lib/toolbar/view-controls/view-controls.component.d.ts +54 -0
- package/lib/toolbar/wand/wand-region-grow.d.ts +49 -0
- package/lib/toolbar/wand/wand-tool.service.d.ts +39 -124
- package/lib/toolbar/wand/wand.service.d.ts +22 -116
- package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +17 -37
- package/lib/util/mark-for-check.d.ts +11 -0
- package/lib/util/supersede.d.ts +53 -0
- package/lib/visualization.module.d.ts +18 -39
- package/lib/visualizer/floating-drag.directive.d.ts +30 -0
- package/lib/visualizer/region-actions.d.ts +54 -0
- package/lib/visualizer/region-load.d.ts +46 -0
- package/lib/visualizer/spatial-dataset-binder.d.ts +74 -0
- package/lib/visualizer/tool-modes.d.ts +49 -0
- package/lib/visualizer/viewer-shortcuts.d.ts +71 -0
- package/lib/visualizer/visualizer-context-menu.d.ts +55 -0
- package/lib/visualizer/volume-sections.d.ts +64 -0
- package/lib/visualizer.component.d.ts +232 -447
- package/lib/workers/spatial-math-ops.d.ts +65 -0
- package/lib/workers/spatial-math-worker.d.ts +7 -0
- package/lib/workers/spatial-math.d.ts +74 -0
- package/package.json +12 -3
- package/src/lib/assets/slice.svg +23 -0
- package/src/lib/styles/_viz-icons-rules.scss +73 -0
- package/src/lib/styles/viz-icons.scss +14 -0
- package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +0 -97
- package/esm2022/lib/implementations/napari-js/napari-navigator.mjs +0 -195
- package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +0 -92
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs +0 -329
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map +0 -1
- package/lib/implementations/napari-js/napari-axes-labels.d.ts +0 -49
- package/lib/implementations/napari-js/napari-navigator.d.ts +0 -72
- package/lib/implementations/napari-js/napari-scale-bar.d.ts +0 -35
- package/src/lib/assets/cell-detection.svg +0 -37
- package/src/lib/assets/click.svg +0 -1
- package/src/lib/assets/colormap-luts.json +0 -1
- package/src/lib/assets/edit-selection-white.svg +0 -47
- package/src/lib/assets/icons/colormap-earth.png +0 -0
- package/src/lib/assets/icons/colormap-placeholder.png +0 -0
- package/src/lib/assets/icons/colormap-pubu.png +0 -0
- package/src/lib/assets/interactive-segmentation-cursor.svg +0 -1
- package/src/lib/assets/picture-segmentation.svg +0 -43
- package/src/lib/assets/test/download-379.svg +0 -1
- package/src/lib/assets/test/download-98.svg +0 -1
- package/src/lib/assets/test/json-1.svg +0 -1
- package/src/lib/assets/test/load-53.svg +0 -1
- package/src/lib/assets/test/mask-44.svg +0 -1
- package/src/lib/assets/test/mask-download-44.svg +0 -15
- package/src/lib/assets/test/mask-save-44.svg +0 -11
- package/src/lib/assets/test/overlay-1.svg +0 -1
- package/src/lib/assets/test/overlay-4.svg +0 -1
- package/src/lib/assets/test/region-26.svg +0 -1
- package/src/lib/assets/test/save-56.svg +0 -1
- package/src/lib/assets/test/upload-43.svg +0 -1
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { RegionMesh3D } from './napari-volume-region-meshes';
|
|
2
|
+
import type { Viewer } from 'napari-js';
|
|
3
|
+
import type { VolumeFrame } from './napari-volume-region-meshes';
|
|
4
|
+
import type { PlaneAxis, SlicePlanes } from './napari-volume-slice-planes';
|
|
5
|
+
import { IImageInfo } from '../../contracts/image.contract';
|
|
6
|
+
import { IHistogram } from '../../contracts/channel-histogram-api.contract';
|
|
7
|
+
import { IIsosurfaceControls, ISurface3dControls } from '../../contracts/visualizer.contract';
|
|
8
|
+
import { SpatialObservations } from '../../contracts/spatial-dataset.contract';
|
|
9
|
+
import { VisualizerStore } from '../../store/visualizer-store.service';
|
|
10
|
+
import { RegionStore } from '../../store/region-store.service';
|
|
11
|
+
import { NapariTileClient } from './napari-tile-client';
|
|
12
|
+
import { NapariDisplayState } from './napari-display-state';
|
|
13
|
+
import { LoadingBadgeState } from './napari-loading-state';
|
|
14
|
+
import { NapariToolBridge } from './napari-tool-bridge';
|
|
15
|
+
/**
|
|
16
|
+
* What one `plot()` mounts into the viewer (review Appendix B): the 2D image (alone, under the
|
|
17
|
+
* region-centroid scatter, or under the spatial markers), a volume, a surface, a 3D scatter or the
|
|
18
|
+
* spatial 3D cloud. The service picks one per plot type and talks to it through this interface
|
|
19
|
+
* instead of asking which layer handle happens to be non-null; a scene owns every layer, key,
|
|
20
|
+
* subscription and listener it creates, and {@link dispose} drops them all — so a re-plot can no
|
|
21
|
+
* longer inherit a stale "already built" key from the previous one (NAPARI-SVC-1, -8).
|
|
22
|
+
*/
|
|
23
|
+
export interface NapariScene {
|
|
24
|
+
/** Build the scene into the viewer. Resolves once the first frame's data is in. */
|
|
25
|
+
mount(): Promise<void>;
|
|
26
|
+
/** The stack slider moved to `z` (already recorded as the image's slice). */
|
|
27
|
+
setZ(z: number): void;
|
|
28
|
+
/** The histogram pane's distribution for `channel`, or null when there is none (yet). */
|
|
29
|
+
histogram(channel: number, bins: number): IHistogram | null;
|
|
30
|
+
/** The isosurface threshold controls (volume scenes only). */
|
|
31
|
+
isoControls?(): IIsosurfaceControls | null;
|
|
32
|
+
/** The 3D camera/axes/wireframe controls (3D scenes only). */
|
|
33
|
+
surface3dControls?(): ISurface3dControls | null;
|
|
34
|
+
/** Bilinear vs nearest-neighbour image sampling changed (2D image scenes). */
|
|
35
|
+
setImageSmoothing?(enabled: boolean): void;
|
|
36
|
+
/** The overview navigator was shown or hidden (2D image scenes). */
|
|
37
|
+
setNavigatorVisible?(visible: boolean): void;
|
|
38
|
+
/** Observations projected to canvas pixels (the spatial 3D cloud), or null. */
|
|
39
|
+
screenProjection?(obs: SpatialObservations): Float32Array | null;
|
|
40
|
+
/** Show these region reconstructions in the 3D view (volume scenes only). */
|
|
41
|
+
setRegionMeshes?(meshes: readonly RegionMesh3D[]): void;
|
|
42
|
+
/** Highlight the reconstructions of these keys (none: all as usual). */
|
|
43
|
+
setRegionHighlight?(keys: readonly string[]): void;
|
|
44
|
+
/** Hide the reconstructions of these keys. */
|
|
45
|
+
setRegionHidden?(keys: readonly string[]): void;
|
|
46
|
+
/**
|
|
47
|
+
* Draw the region reconstructions through the volume (it hides none of them) rather than hidden
|
|
48
|
+
* where it is in front of them (see VolumeScene.setRegionsThroughVolume).
|
|
49
|
+
*/
|
|
50
|
+
setRegionsThroughVolume?(through: boolean): void;
|
|
51
|
+
/** Show the planes of the sections beside the 3D view (volume scenes only). */
|
|
52
|
+
setSlicePlanes?(planes: SlicePlanes): void;
|
|
53
|
+
/** The assembled volume the sections are cut from (volume scenes only). */
|
|
54
|
+
volumeVoxels?(): VolumeVoxelsOnScreen | null;
|
|
55
|
+
/** Image px per voxel of the assembled volume, in-plane (volume scenes only). */
|
|
56
|
+
voxelStep?(): number | null;
|
|
57
|
+
/** Remove everything the scene added; called before the viewer is disposed. */
|
|
58
|
+
dispose(): void;
|
|
59
|
+
}
|
|
60
|
+
/** Viewer settings that outlive a scene: a re-plot keeps them. */
|
|
61
|
+
export interface NapariSettings {
|
|
62
|
+
/** Decimate factor for the 3D types (1 = Full, 2 = ½, 4 = ¼ default, 8 = ⅛). */
|
|
63
|
+
resolutionScale: number;
|
|
64
|
+
/** Whether the 2D overview navigator is shown (the same host setting OSD's navigator honours). */
|
|
65
|
+
navigatorVisible: boolean;
|
|
66
|
+
/** Image smoothing (bilinear) vs nearest-neighbour (crisp pixels, the default). */
|
|
67
|
+
imageSmoothing: boolean;
|
|
68
|
+
/** The 3D axes gizmo's on/off choice. */
|
|
69
|
+
axesVisible: boolean;
|
|
70
|
+
/** The surface's wireframe choice. */
|
|
71
|
+
surfaceWireframe: boolean;
|
|
72
|
+
/** The volume's user Z-height factor (1 = the volume's natural proportions). */
|
|
73
|
+
volumeZScale: number;
|
|
74
|
+
}
|
|
75
|
+
/** The stack-loading flag and progress the host shows while frames load. */
|
|
76
|
+
export interface StackProgress {
|
|
77
|
+
loading(on: boolean): void;
|
|
78
|
+
progress(percent: number): void;
|
|
79
|
+
}
|
|
80
|
+
/** Everything a scene is built from: the viewer and its DOM, the service's collaborators, and the
|
|
81
|
+
* service state a scene reads live. */
|
|
82
|
+
/** A volume as assembled for display (voxels per channel, key 0 the grayscale one) and its frame. */
|
|
83
|
+
export interface VolumeVoxelsOnScreen {
|
|
84
|
+
width: number;
|
|
85
|
+
height: number;
|
|
86
|
+
depth: number;
|
|
87
|
+
channels: ReadonlyMap<number, Uint8Array>;
|
|
88
|
+
multichannel: boolean;
|
|
89
|
+
frame: VolumeFrame;
|
|
90
|
+
}
|
|
91
|
+
export interface SceneContext {
|
|
92
|
+
readonly viewer: Viewer;
|
|
93
|
+
readonly host: HTMLElement;
|
|
94
|
+
readonly canvas: HTMLCanvasElement;
|
|
95
|
+
/** The scene's lifetime: aborted when the service resets into the next scene. */
|
|
96
|
+
readonly signal: AbortSignal;
|
|
97
|
+
/** Frame loading (volume assembly, surface preload): aborted by a reset AND by
|
|
98
|
+
* `cancelLoading()`, which renews it — so read it when a load starts. */
|
|
99
|
+
loading(): AbortSignal;
|
|
100
|
+
/** The image on screen and its current slice, as `load()`/`setZIndex()` recorded them. */
|
|
101
|
+
info(): IImageInfo | undefined;
|
|
102
|
+
z(): number;
|
|
103
|
+
readonly tiles: NapariTileClient;
|
|
104
|
+
readonly display: NapariDisplayState;
|
|
105
|
+
readonly badge: LoadingBadgeState;
|
|
106
|
+
readonly tools: NapariToolBridge;
|
|
107
|
+
readonly store: VisualizerStore;
|
|
108
|
+
readonly regionStore: RegionStore;
|
|
109
|
+
readonly settings: NapariSettings;
|
|
110
|
+
readonly stack: StackProgress;
|
|
111
|
+
/** The image's full-resolution size as the scene drew it — read by the readback, the camera
|
|
112
|
+
* fit and `getTrueImageSize()`; it outlives the scene. */
|
|
113
|
+
imageSize(): {
|
|
114
|
+
width: number;
|
|
115
|
+
height: number;
|
|
116
|
+
};
|
|
117
|
+
setImageSize(width: number, height: number): void;
|
|
118
|
+
/** Fit the 2D camera to the image on the next frame. */
|
|
119
|
+
fitCameraSoon(): void;
|
|
120
|
+
outsideZone<T>(fn: () => T): T;
|
|
121
|
+
inZone<T>(fn: () => T): T;
|
|
122
|
+
/** A region reconstruction was clicked (its key), or the volume beside them (null). */
|
|
123
|
+
regionMeshPicked(key: string | null, additive: boolean): void;
|
|
124
|
+
/** A section's plane dragged in the volume to `value` along its axis. */
|
|
125
|
+
slicePlaneMoved(axis: PlaneAxis, value: number): void;
|
|
126
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import type { ImageLayer, Viewer } from 'napari-js';
|
|
2
|
+
import { IHistogram } from '../../contracts/channel-histogram-api.contract';
|
|
3
|
+
import { SpatialDataset } from '../../contracts/spatial-dataset.contract';
|
|
4
|
+
import { SpatialViewState } from '../../contracts/display-types';
|
|
5
|
+
import { SpatialSelectionMask } from '../../spatial/spatial-selection';
|
|
6
|
+
import { NapariSpatialTileLayers } from './napari-spatial-tiles';
|
|
7
|
+
import { Image2dScene } from './napari-image-2d-scene';
|
|
8
|
+
import { SpatialSceneBase, SpatialSession, SpatialTileOwner } from './napari-spatial-scene';
|
|
9
|
+
import type { NapariScene, SceneContext } from './napari-scene';
|
|
10
|
+
/**
|
|
11
|
+
* SPATIAL_OMICS (review Appendix B, cluster J): the tissue image (an {@link Image2dScene}) with one
|
|
12
|
+
* marker per observation, coloured by an annotation column or a gene, the gene map under the
|
|
13
|
+
* cells, and the level-of-detail tile layers (outlines, transcripts, density) over them. The
|
|
14
|
+
* markers rebuild whenever the dataset or the view state changes, so switching the colour-by
|
|
15
|
+
* column does not remount the scene.
|
|
16
|
+
*
|
|
17
|
+
* Sets up the full 2D interaction stack — region overlay, pixel tools, readback currency — exactly
|
|
18
|
+
* as the plain image view does. That is NOT optional here: this mode's selection is driven by
|
|
19
|
+
* drawn ROIs, so without the overlay there is no way to make a selection at all.
|
|
20
|
+
*/
|
|
21
|
+
export declare class Spatial2dScene extends SpatialSceneBase implements NapariScene, SpatialTileOwner {
|
|
22
|
+
readonly image: Image2dScene;
|
|
23
|
+
/** The observation markers, and which dataset/plane they were built for — so a display-only
|
|
24
|
+
* change (size, colour, opacity, selection) can update them in place. */
|
|
25
|
+
private points;
|
|
26
|
+
private layerKey;
|
|
27
|
+
/** The observation each marker is, in draw order; null when every observation is drawn. */
|
|
28
|
+
private drawn;
|
|
29
|
+
/** The gene map's layer and the inputs it was coloured for (its field is cached in the session,
|
|
30
|
+
* on a clock of its own). */
|
|
31
|
+
geneMapLayer: ImageLayer | null;
|
|
32
|
+
private geneMapKey;
|
|
33
|
+
/** The dataset the camera has been framed on — see {@link frameOnce}. */
|
|
34
|
+
private framed;
|
|
35
|
+
/** The gene-map estimate in flight (off the main thread past the worker threshold,
|
|
36
|
+
* SPATIAL-19): a new field key supersedes — and aborts — it; a rebuild that leaves the key
|
|
37
|
+
* alone lets it finish. */
|
|
38
|
+
private readonly geneMapLoads;
|
|
39
|
+
/** `noImage`: an image-less dataset opened before any image — the observations alone. */
|
|
40
|
+
constructor(ctx: SceneContext, session: SpatialSession, noImage?: boolean);
|
|
41
|
+
mount(): Promise<void>;
|
|
42
|
+
setZ(z: number): void;
|
|
43
|
+
histogram(channel: number, bins: number): IHistogram | null;
|
|
44
|
+
setImageSmoothing(enabled: boolean): void;
|
|
45
|
+
setNavigatorVisible(visible: boolean): void;
|
|
46
|
+
dispose(): void;
|
|
47
|
+
canvasSize(): [number, number];
|
|
48
|
+
polygonsShownChanged(): void;
|
|
49
|
+
protected afterChange(): void;
|
|
50
|
+
protected hoverTiles(): NapariSpatialTileLayers | null;
|
|
51
|
+
/**
|
|
52
|
+
* The observation under a client position: napari-js's pick on the marker layer itself (a grid
|
|
53
|
+
* over its positions, rebuilt only when they change), so the tooltip cannot name a cell that is
|
|
54
|
+
* not drawn, then the drawn index mapped back to the observation.
|
|
55
|
+
*
|
|
56
|
+
* A marker is hit anywhere on its drawn disc, or within `slackPx` screen pixels of its centre
|
|
57
|
+
* when it is smaller than that (a 1.5 px dot still has to be hoverable), and of several hits the
|
|
58
|
+
* NEAREST centre wins (an exact tie goes to the one drawn on top). Not napari's `'topmost'`: the
|
|
59
|
+
* slack is wider than most markers, and over a dense field of small ones "the last drawn within
|
|
60
|
+
* 10 px" names a neighbour rather than the cell under the cursor.
|
|
61
|
+
*/
|
|
62
|
+
protected pickObservation(clientX: number, clientY: number, slackPx: number): number;
|
|
63
|
+
/**
|
|
64
|
+
* Whether the markers are drawn: when the user wants them, and not while cell outlines are on
|
|
65
|
+
* screen — then a cell IS its outline, and a circle on top of it is noise. Zoomed out past the
|
|
66
|
+
* outline threshold, the circles stand in for the cells.
|
|
67
|
+
*/
|
|
68
|
+
private pointsVisible;
|
|
69
|
+
/**
|
|
70
|
+
* Redraw the markers over a freshly rendered image. Two reasons, both invisible from the
|
|
71
|
+
* spatial store — which is why a scrub or a re-render never reached the markers on its own:
|
|
72
|
+
* - the image render CLEARS the layer list, taking the markers with it;
|
|
73
|
+
* - over a volume-backed dataset the displayed plane decides which observations belong on
|
|
74
|
+
* screen at all, so the cells have to move with the section rather than hang over another.
|
|
75
|
+
*/
|
|
76
|
+
private redrawMarkers;
|
|
77
|
+
/** (Re)build the observation marker layer for the current dataset + view state. */
|
|
78
|
+
protected rebuild(dataset: SpatialDataset | null, view: SpatialViewState, selection?: SpatialSelectionMask): Promise<void>;
|
|
79
|
+
/** Nothing to draw: drop the markers and the gene map. */
|
|
80
|
+
private removeLayers;
|
|
81
|
+
/**
|
|
82
|
+
* Draw the observation markers over the image (and the gene map): restyled in place for a
|
|
83
|
+
* display-only change, else a new layer.
|
|
84
|
+
*/
|
|
85
|
+
private drawMarkers;
|
|
86
|
+
/**
|
|
87
|
+
* Tell the region overlay how finely a drawn vertex may be placed.
|
|
88
|
+
*
|
|
89
|
+
* Region geometry is stored in whole world units, which is right when the world IS
|
|
90
|
+
* pixels — a region should align to them. It is wrong for a dataset that registers onto
|
|
91
|
+
* no image: seqFISH's observations span about 5 x 7 units in total, so whole-unit
|
|
92
|
+
* vertices leave roughly six by eight placeable positions across the entire sample and
|
|
93
|
+
* an ROI cannot be drawn at any zoom. Nothing errors; the tool just cannot express the
|
|
94
|
+
* shape.
|
|
95
|
+
*
|
|
96
|
+
* Keyed on whether the dataset brings PIXELS rather than on the extent, because the
|
|
97
|
+
* extent cannot tell the two apart — 2,000 units is a small slide or a large section
|
|
98
|
+
* depending only on what the units are, and only the dataset knows.
|
|
99
|
+
*/
|
|
100
|
+
private setRegionGridFor;
|
|
101
|
+
/**
|
|
102
|
+
* Hide the image layer for a dataset that brings no image of its own.
|
|
103
|
+
*
|
|
104
|
+
* The host's viewer keeps whatever image was last loaded, and for a dataset that
|
|
105
|
+
* registers onto none that picture belongs to something else entirely — the example's
|
|
106
|
+
* default slide, say. It is not merely irrelevant: the two live in different coordinate
|
|
107
|
+
* spaces (image pixels against the embedding's own units), so the leftover is magnified
|
|
108
|
+
* roughly a hundredfold. At the fitted zoom the camera sits inside its corner, where it
|
|
109
|
+
* reads as blank background, and it appears only once you zoom out far enough to find
|
|
110
|
+
* it — which is exactly how it gets noticed.
|
|
111
|
+
*
|
|
112
|
+
* Hidden rather than removed, and hidden HERE rather than by clearing the host's image
|
|
113
|
+
* state: that state drives the whole render pipeline, including a Plotly backend whose
|
|
114
|
+
* fields are declared with definite-assignment assertions, so emptying it throws from
|
|
115
|
+
* whichever field the next path happens to read. This touches one layer's visibility
|
|
116
|
+
* and nothing else.
|
|
117
|
+
*/
|
|
118
|
+
hideForeignImage(viewer: Pick<Viewer, 'layers' | 'requestRender'>, datasetHasPixels: boolean): void;
|
|
119
|
+
/**
|
|
120
|
+
* Frame the camera on the observations, for a dataset that brings no image.
|
|
121
|
+
*
|
|
122
|
+
* The 2D camera is normally fitted to the IMAGE, because the observations are in that
|
|
123
|
+
* image's pixel space and framing the image frames them too. A dataset with no
|
|
124
|
+
* reference image has coordinates in its own units instead — seqFISH's span about
|
|
125
|
+
* 5x7 — so the image framing left over from whatever was on screen before puts the
|
|
126
|
+
* whole cloud offscreen: measured at 9.7 x 13.4 PIXELS, centred 256px from where the
|
|
127
|
+
* camera was looking. The points are all there and drawn; they are a speck. Which
|
|
128
|
+
* looks exactly like the dataset having failed to load.
|
|
129
|
+
*
|
|
130
|
+
* Once per dataset, as napari-js's `fit3d: 'once'` does for the cloud: re-colouring,
|
|
131
|
+
* slicing or picking a gene re-adds this layer, and re-framing on those would move
|
|
132
|
+
* the camera under the user — the camera tools and the canvas drag are meant to be
|
|
133
|
+
* the only things that do.
|
|
134
|
+
*/
|
|
135
|
+
private frameOnce;
|
|
136
|
+
/**
|
|
137
|
+
* The **gene map**: the active gene's expression as a continuous field drawn under
|
|
138
|
+
* the cells.
|
|
139
|
+
*
|
|
140
|
+
* A scatter coloured by a gene says which cells express it; it cannot say where,
|
|
141
|
+
* because the eye will not integrate thousands of dots into a territory. The field
|
|
142
|
+
* is a kernel-weighted MEAN per cell (see `spatial-expression.ts`), so a dense
|
|
143
|
+
* region does not glow merely for being dense, and it is transparent wherever no
|
|
144
|
+
* cell was measured — an unsampled gap must not read as "not expressed".
|
|
145
|
+
*
|
|
146
|
+
* It shares the points' LUT, percentile window and log flag, so the layer under
|
|
147
|
+
* the cells and the cells themselves cannot disagree about what a colour means.
|
|
148
|
+
*
|
|
149
|
+
* Estimated on the DISPLAYED image's pixel grid, coarsened so the long side is at
|
|
150
|
+
* most `GENE_MAP_MAX_SIDE`: a smooth field gains nothing from a slide's full
|
|
151
|
+
* resolution. For a volume-backed dataset that grid is the current slice, and only
|
|
152
|
+
* that plane's observations are included — the same rule the markers follow.
|
|
153
|
+
*/
|
|
154
|
+
private ensureGeneMap;
|
|
155
|
+
/**
|
|
156
|
+
* Per-observation colours for the current view state, or a single flat colour when nothing is
|
|
157
|
+
* selected to colour by. Categorical columns use the column's own palette; continuous columns
|
|
158
|
+
* and gene vectors go through the active colormap with a percentile-clipped window.
|
|
159
|
+
*/
|
|
160
|
+
private faceColors;
|
|
161
|
+
/** Continuous values → RGBA through the active colormap and a clipped window. */
|
|
162
|
+
encodeContinuous(values: Float32Array, view: SpatialViewState, muted?: Uint8Array | null): Float32Array;
|
|
163
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { IHistogram } from '../../contracts/channel-histogram-api.contract';
|
|
2
|
+
import { SpatialDataset, SpatialObservations } from '../../contracts/spatial-dataset.contract';
|
|
3
|
+
import { SpatialViewState } from '../../contracts/display-types';
|
|
4
|
+
import { SpatialSelectionMask } from '../../spatial/spatial-selection';
|
|
5
|
+
import { Spatial3dScalars } from './napari-spatial-encoding';
|
|
6
|
+
import { SpatialSceneBase, SpatialSession } from './napari-spatial-scene';
|
|
7
|
+
import type { NapariScene, SceneContext } from './napari-scene';
|
|
8
|
+
/**
|
|
9
|
+
* SPATIAL_OMICS_3D (review Appendix B, cluster K): observations as a 3D point cloud under the
|
|
10
|
+
* orbit camera, with the dataset's reference volume around it, per-cluster density volumes and the
|
|
11
|
+
* 3D gene map.
|
|
12
|
+
*
|
|
13
|
+
* Thinner than the 2D scene: there is no tissue image to render (a registered volume like the
|
|
14
|
+
* Allen CCF has no single reference plane), so no readback and no navigator; the 3D scale bar
|
|
15
|
+
* follows the dataset (see {@link installScaleBar}). The region tools work in SCREEN space through
|
|
16
|
+
* the tool bridge's 3D interaction — a lasso selects the cells under it, and an orbit clears the
|
|
17
|
+
* shape while keeping the selection. The first 3D layer added frames the camera (`fit3d: 'once'`).
|
|
18
|
+
*/
|
|
19
|
+
export declare class Spatial3dScene extends SpatialSceneBase implements NapariScene {
|
|
20
|
+
/** The 3D point cloud. One layer: selection is a per-point alpha on it, not a second. */
|
|
21
|
+
private points;
|
|
22
|
+
private layerKey;
|
|
23
|
+
/** Interleaved x,y,z, cached so a colour change does not re-walk 3.7M observations. */
|
|
24
|
+
private positions;
|
|
25
|
+
/** Identity of the scalars currently uploaded — see {@link rebuild}. */
|
|
26
|
+
private scalarKey;
|
|
27
|
+
/** Observation indices the cached positions belong to, in the same order; null when every
|
|
28
|
+
* observation is drawn. Without it a projection built from the positions is indexed by DRAWN
|
|
29
|
+
* order and silently attributes each point to the wrong observation as soon as a section is
|
|
30
|
+
* isolated. */
|
|
31
|
+
private drawn;
|
|
32
|
+
/** The anatomical volume the cloud sits inside, when the dataset has one. */
|
|
33
|
+
private volume;
|
|
34
|
+
private volumeKey;
|
|
35
|
+
/** Per-cluster density volumes drawn alongside the cloud, and what they were
|
|
36
|
+
* built from — rasterising is seconds of work, so it must not repeat for a
|
|
37
|
+
* change that cannot affect the field. */
|
|
38
|
+
private densityLayers;
|
|
39
|
+
private densityKey;
|
|
40
|
+
/** The 3D gene map's volume layer and the inputs it was coloured for (its field is cached in
|
|
41
|
+
* the session, on a clock of its own). */
|
|
42
|
+
private geneMapLayer;
|
|
43
|
+
private geneMapKey;
|
|
44
|
+
/** Offset applied to observation coordinates to sit them in the volume's box. */
|
|
45
|
+
private origin;
|
|
46
|
+
/**
|
|
47
|
+
* napari-js's depth-aware pick over the cloud, and the projection the ROI selection reads. It
|
|
48
|
+
* owns the caching policy: re-project lazily, on the first pick after the camera, the canvas or
|
|
49
|
+
* the cloud's data moved (never on the camera event, so an orbit drag pays nothing), into
|
|
50
|
+
* reused buffers, with a screen index once the cloud is large enough.
|
|
51
|
+
*/
|
|
52
|
+
private picker;
|
|
53
|
+
private scaleBar;
|
|
54
|
+
/** Dataset the scale bar was built for. */
|
|
55
|
+
private scaleBarKey;
|
|
56
|
+
/** The density rasterisation and the 3D gene-map estimate in flight (off the main thread
|
|
57
|
+
* past the worker threshold, SPATIAL-19): a new key supersedes — and aborts — the previous
|
|
58
|
+
* one; a rebuild that leaves the key alone lets it finish. */
|
|
59
|
+
private readonly densityLoads;
|
|
60
|
+
private readonly geneMapLoads;
|
|
61
|
+
/** The store's invert setting, which the density volumes follow (no other subscription of
|
|
62
|
+
* this scene carries it). */
|
|
63
|
+
private invertSub;
|
|
64
|
+
constructor(ctx: SceneContext, session: SpatialSession);
|
|
65
|
+
mount(): Promise<void>;
|
|
66
|
+
/** The observations' own z is on screen: there is no plane to step. */
|
|
67
|
+
setZ(): void;
|
|
68
|
+
/** A cloud has no intensity distribution for the histogram pane. */
|
|
69
|
+
histogram(): IHistogram | null;
|
|
70
|
+
/**
|
|
71
|
+
* Every observation's position on the canvas under the current 3D camera (for the ROI
|
|
72
|
+
* selection), indexed by observation with NaN for anything not drawn. Null before the cloud
|
|
73
|
+
* is built.
|
|
74
|
+
*
|
|
75
|
+
* The projection is the picker's (see {@link picker}); what is left is the part that is
|
|
76
|
+
* genuinely this adapter's: SCATTERING the drawn subset back into observation order. The cloud
|
|
77
|
+
* holds only the points of the displayed section, in its own packing; every consumer indexes by
|
|
78
|
+
* observation. NaN stands for "not on screen", which is also the right answer for an
|
|
79
|
+
* observation whose section is hidden.
|
|
80
|
+
*/
|
|
81
|
+
screenProjection(obs: SpatialObservations): Float32Array | null;
|
|
82
|
+
dispose(): void;
|
|
83
|
+
/**
|
|
84
|
+
* The observation under a client position: the FRONT-most marker within `slackPx` of the
|
|
85
|
+
* pointer (ties by distance), as napari-js's {@link PointPicker} picks it. That matters more
|
|
86
|
+
* than it sounds: the renderer depth-tests the billboards, and in a 3.7M-point cloud the cursor
|
|
87
|
+
* covers many of them — picking the one nearest the cursor's centre regularly names a cell that
|
|
88
|
+
* something else is drawn over. The picker also takes each point's radius from the layer's
|
|
89
|
+
* per-point `sizes`, so a selected marker, drawn larger, is as large to the pointer.
|
|
90
|
+
*/
|
|
91
|
+
protected pickObservation(clientX: number, clientY: number, slackPx: number): number;
|
|
92
|
+
/** Replace the cloud's picker (null: no cloud), releasing the old one's camera listener. */
|
|
93
|
+
private setPicker;
|
|
94
|
+
/**
|
|
95
|
+
* Scale bar for the cloud, measured at the ORBIT PIVOT.
|
|
96
|
+
*
|
|
97
|
+
* A perspective camera has no single scale — things farther away are smaller — so a bar can
|
|
98
|
+
* only be true at one depth. The pivot is the honest choice: it is what the camera is framing,
|
|
99
|
+
* what a zoom moves towards, and where the eye is anyway. napari's own 3D scale bar works the
|
|
100
|
+
* same way.
|
|
101
|
+
*
|
|
102
|
+
* napari-js's `ScaleBarOverlay` in `'3d'` mode measures there: CSS px per world unit is the
|
|
103
|
+
* reciprocal of `Camera3D.worldPerPixel` — the scale `Camera3D.pan` uses to track the cursor.
|
|
104
|
+
* The bar then converts through `micronsPerUnit`, and draws nothing at all when the dataset does
|
|
105
|
+
* not declare one, because a bar labelled in microns over unknown units would read as a
|
|
106
|
+
* measurement.
|
|
107
|
+
*/
|
|
108
|
+
private installScaleBar;
|
|
109
|
+
/** (Re)build the 3D point cloud for the current dataset + view state. */
|
|
110
|
+
protected rebuild(dataset: SpatialDataset | null, view: SpatialViewState, selection?: SpatialSelectionMask): Promise<void>;
|
|
111
|
+
/**
|
|
112
|
+
* Draw the point cloud: a new layer for new geometry (a dataset or a section), the colour
|
|
113
|
+
* source swapped in place otherwise; then the selection and the visibility.
|
|
114
|
+
*/
|
|
115
|
+
private drawCloud;
|
|
116
|
+
/** Interleaved x,y,z of the `shown` observations (null: all of them), offset by {@link origin}. */
|
|
117
|
+
private cloudPositions;
|
|
118
|
+
/**
|
|
119
|
+
* Selection is a PER-POINT alpha, in the one layer.
|
|
120
|
+
*
|
|
121
|
+
* It used to be a second layer: with a single opacity for the whole cloud, the only way
|
|
122
|
+
* to highlight a subset was to draw it again on top at full opacity while the parent
|
|
123
|
+
* dropped to the muted level. That second layer had to be kept in step through every
|
|
124
|
+
* colormap, window and size change, and the two then depth-sorted against each other as
|
|
125
|
+
* separate draws. Per-point alphas and sizes give the same reading — muted cloud, bright
|
|
126
|
+
* selection, slightly larger so a small one is findable inside 3.7M points — in one.
|
|
127
|
+
*
|
|
128
|
+
* `shown` is the drawn subset (null: every one of the `total` observations), so the alphas
|
|
129
|
+
* follow the drawn order.
|
|
130
|
+
*/
|
|
131
|
+
private applySelection;
|
|
132
|
+
/**
|
|
133
|
+
* The **3D gene map**: the active gene's expression over the whole sectioned
|
|
134
|
+
* specimen, as one raymarched volume.
|
|
135
|
+
*
|
|
136
|
+
* Two things it can be, and the panel's `Volume rendering` toggle picks which:
|
|
137
|
+
*
|
|
138
|
+
* - **sheets** — exactly the planes that were imaged, each carrying that
|
|
139
|
+
* slide's own 2D gene map, with the gaps between sections empty. A stack of
|
|
140
|
+
* measured fields, at their true z.
|
|
141
|
+
* - **volume** — the same fields smoothed along z, so the planes between the
|
|
142
|
+
* sections carry an interpolated value. An estimate, and drawn as a
|
|
143
|
+
* translucent cloud for the same reason the density volumes are.
|
|
144
|
+
*
|
|
145
|
+
* One `VolumeLayer` rather than a textured quad per section: an `ImageLayer`
|
|
146
|
+
* renders only at `ndisplay === 2`, so 53 sheets in the orbit view would need a
|
|
147
|
+
* new layer type upstream — while a scalar volume whose z sampling already IS
|
|
148
|
+
* the section spacing expresses the sheets exactly, and the same lattice then
|
|
149
|
+
* gives the interpolated version for free.
|
|
150
|
+
*
|
|
151
|
+
* Estimated on the reference volume's own lattice (`densityGrid` at stride 1),
|
|
152
|
+
* so the field lands voxel-for-voxel on the anatomy and needs no offset — a
|
|
153
|
+
* `VolumeLayer` has no translate, and napari centres both boxes on the world
|
|
154
|
+
* origin.
|
|
155
|
+
*/
|
|
156
|
+
private ensureGeneMap;
|
|
157
|
+
/**
|
|
158
|
+
* Cluster density volumes: each cluster rasterised into a smooth scalar field and
|
|
159
|
+
* raymarched alongside the cloud, tinted with the cluster's own legend colour.
|
|
160
|
+
*
|
|
161
|
+
* This is what makes a serially sectioned dataset readable as an anatomical
|
|
162
|
+
* distribution. The cloud shows measured cells and nothing else — but at 200 µm
|
|
163
|
+
* section spacing the eye cannot integrate a stack of discs into a shape, and
|
|
164
|
+
* every gap reads as absence. A density field is a different object from a cell:
|
|
165
|
+
* an estimate, defined between the imaged planes, drawn as a translucent cloud so
|
|
166
|
+
* it cannot be mistaken for measurement. Individual cells are never interpolated —
|
|
167
|
+
* consecutive sections sample different cells, so there is nothing to interpolate
|
|
168
|
+
* along.
|
|
169
|
+
*
|
|
170
|
+
* One volume per cluster rather than one for everything: additive blending is what
|
|
171
|
+
* makes two clusters' territories comparable, and a single blended field would
|
|
172
|
+
* answer no question anyone asks of a taxonomy. Capped at `DENSITY_MAX_CLUSTERS` by cell
|
|
173
|
+
* count.
|
|
174
|
+
*
|
|
175
|
+
* Keyed so it rebuilds only when the field would actually differ — the dataset,
|
|
176
|
+
* the colour column, the bandwidth, or the selection.
|
|
177
|
+
*/
|
|
178
|
+
private ensureDensityVolumes;
|
|
179
|
+
/**
|
|
180
|
+
* The clusters to rasterise: the categories of the active categorical colouring,
|
|
181
|
+
* biggest first and capped, each with its legend colour, restricted to the current selection
|
|
182
|
+
* when there is one. With no categorical colouring there is one group — total cell density,
|
|
183
|
+
* which is a real question on its own ("where is the tissue dense?") and the honest thing to
|
|
184
|
+
* show when the view is not encoding a taxonomy.
|
|
185
|
+
*/
|
|
186
|
+
private densityGroups;
|
|
187
|
+
/**
|
|
188
|
+
* Add (or keep) the dataset's reference volume, and derive the offset that sits the
|
|
189
|
+
* observations inside it.
|
|
190
|
+
*
|
|
191
|
+
* `VolumeLayer` has no translate: napari-js maps the volume's unit cube to a world box
|
|
192
|
+
* **centred on the origin**, sized `dims x voxelSize`. The observations, by contract, are in
|
|
193
|
+
* the volume's own frame with its near corner at the coordinate origin. So the two only line
|
|
194
|
+
* up if the POINTS move — by half the box — which is what {@link origin} is.
|
|
195
|
+
*
|
|
196
|
+
* A failed or absent volume is not fatal: the cloud renders on its own, at its own
|
|
197
|
+
* coordinates, and the camera frames the points instead.
|
|
198
|
+
*/
|
|
199
|
+
private ensureVolume;
|
|
200
|
+
/** Drop every layer of the cloud (the dataset went away, or has no z). */
|
|
201
|
+
private removeLayers;
|
|
202
|
+
/**
|
|
203
|
+
* What colours the cloud.
|
|
204
|
+
*
|
|
205
|
+
* Continuous data goes through the active colormap with the same percentile window the 2D path
|
|
206
|
+
* uses. Categorical data is one RGBA per point from the column's palette, so any number of
|
|
207
|
+
* categories keeps its own colour — see `encodeSpatial3dCategorical`.
|
|
208
|
+
*/
|
|
209
|
+
private scalarEncoding;
|
|
210
|
+
/** Continuous values → the active colormap over a percentile-clipped window. */
|
|
211
|
+
encodeContinuous(source: Float32Array, view: SpatialViewState): Spatial3dScalars;
|
|
212
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { Colormap } from 'napari-js';
|
|
2
|
+
import { Rgb } from '../../contracts/colormap-lut';
|
|
3
|
+
import { CategoricalColumn } from '../../contracts/spatial-dataset.contract';
|
|
4
|
+
import { SpatialViewState } from '../../contracts/display-types';
|
|
5
|
+
import { type RGBA } from '../../spatial/spatial-encoding';
|
|
6
|
+
import { SpatialSelectionMask } from '../../spatial/spatial-selection';
|
|
7
|
+
/**
|
|
8
|
+
* The spatial scenes' pure colour and grouping math: what the 2D markers, the 3D cloud and the
|
|
9
|
+
* density volumes are coloured with, as functions of the data, the view and a LUT. No viewer, no
|
|
10
|
+
* port, no store (review Appendix B, step 1).
|
|
11
|
+
*/
|
|
12
|
+
/** Marker radius (image px) for a dataset that declares none — segmented cells often don't. */
|
|
13
|
+
export declare const SPATIAL_FALLBACK_RADIUS = 4;
|
|
14
|
+
/** Smallest marker DIAMETER, in slice pixels, over a volume-backed dataset. A cell's real
|
|
15
|
+
* size is honoured wherever it survives the grid: the ABC atlas serves 5 µm radii on a
|
|
16
|
+
* 40 µm/px template, so drawing them to scale would put every cell a fifth of a pixel wide
|
|
17
|
+
* and the section would come up empty. The point-size control scales up from this floor. */
|
|
18
|
+
export declare const SPATIAL_SLICE_MIN_DIAMETER_PX = 1.5;
|
|
19
|
+
/** Longest side of the gene-map raster, in field pixels. A gene map is a smooth
|
|
20
|
+
* field read as territory, so it gains nothing from matching a 2 Gpx slide's
|
|
21
|
+
* resolution — and the estimate costs one pass over this many pixels. */
|
|
22
|
+
export declare const GENE_MAP_MAX_SIDE = 512;
|
|
23
|
+
/** Kernel σ in field pixels at smoothing 1: wide enough to read between cells,
|
|
24
|
+
* tight enough to keep a nucleus-scale structure distinct. */
|
|
25
|
+
export declare const GENE_MAP_SIGMA = 2.5;
|
|
26
|
+
/**
|
|
27
|
+
* In-plane coarsening of the 3D gene map's lattice, relative to the reference
|
|
28
|
+
* volume. The field is smooth, so its detail is set by the kernel rather than the
|
|
29
|
+
* raster — and the estimate is a pair of separable blurs, which at the template's
|
|
30
|
+
* full resolution means seconds of work per toggle.
|
|
31
|
+
*/
|
|
32
|
+
export declare const GENE_MAP_VOLUME_STRIDE = 2;
|
|
33
|
+
/** Clusters drawn as density volumes at once. Past a handful, additive translucent
|
|
34
|
+
* clouds stop being separable by eye — and each one is a full rasterisation. */
|
|
35
|
+
export declare const DENSITY_MAX_CLUSTERS = 6;
|
|
36
|
+
/** How much larger a selected marker is drawn, so a small selection is findable inside a
|
|
37
|
+
* 3.7M-point cloud rather than merely brighter. */
|
|
38
|
+
export declare const SPATIAL_SELECTED_SIZE_SCALE = 1.6;
|
|
39
|
+
/** Base marker diameter for the 3D cloud, in SCREEN pixels (the layer's unit). */
|
|
40
|
+
export declare const SPATIAL_3D_BASE_SIZE = 3;
|
|
41
|
+
/** Colour for observations when nothing is selected to colour by: visible, neutral, and
|
|
42
|
+
* obviously not encoding anything. */
|
|
43
|
+
export declare const SPATIAL_NEUTRAL_COLOR: [number, number, number, number];
|
|
44
|
+
/** {@link SPATIAL_NEUTRAL_COLOR} as a hex colour (alpha dropped), for the encoders and the
|
|
45
|
+
* density-volume tint. */
|
|
46
|
+
export declare const SPATIAL_NEUTRAL_HEX: string;
|
|
47
|
+
/**
|
|
48
|
+
* Contrast windows memoised per (values array, lo, hi, log). `contrastWindow` sorts every value,
|
|
49
|
+
* and the spatial colouring re-runs it on each opacity, selection or colormap change while the
|
|
50
|
+
* coloured vector itself is unchanged (review SPATIAL-12). Keyed by the vector's identity, so a
|
|
51
|
+
* new column or gene vector is a miss and an old one is collected with its windows.
|
|
52
|
+
*/
|
|
53
|
+
export declare class ContrastWindowCache {
|
|
54
|
+
private readonly byVector;
|
|
55
|
+
get(values: Float32Array, lo: number, hi: number, log: boolean, compute: () => [number, number]): [number, number];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* What the 3D points layer needs to colour a cloud: for continuous data, one scalar per point, a
|
|
59
|
+
* colormap and the window that maps scalars onto it; for categorical data, one packed RGBA per
|
|
60
|
+
* point (`Points3DLayer.colors`, which wins over the scalars).
|
|
61
|
+
*/
|
|
62
|
+
export type Spatial3dEncoding = Spatial3dScalars | Spatial3dColors;
|
|
63
|
+
/** A cloud coloured through the colormap: scalars, colormap and window. */
|
|
64
|
+
export interface Spatial3dScalars {
|
|
65
|
+
kind: 'scalars';
|
|
66
|
+
values: Float32Array;
|
|
67
|
+
colormap: Colormap;
|
|
68
|
+
contrastLimits: [number, number];
|
|
69
|
+
}
|
|
70
|
+
/** A cloud coloured point by point: packed RGBA, 4 floats per point. */
|
|
71
|
+
export interface Spatial3dColors {
|
|
72
|
+
kind: 'colors';
|
|
73
|
+
colors: Float32Array;
|
|
74
|
+
}
|
|
75
|
+
/** A one-colour colormap, for the "nothing to colour by" state. */
|
|
76
|
+
export declare function spatialFlatColormap(): Colormap;
|
|
77
|
+
/**
|
|
78
|
+
* Category codes → one RGBA per point, for any number of categories.
|
|
79
|
+
*
|
|
80
|
+
* The 2D markers' encoding, with one difference: a point with no category stays opaque (grey),
|
|
81
|
+
* as it always has in the cloud, where the selection dims through the layer's per-point alphas
|
|
82
|
+
* instead. It used to be smuggled through the scalar channel as a stepped 256-entry LUT, which
|
|
83
|
+
* kept at most 95 categories apart (review SPATIAL-11, NAPARI-SVC-18).
|
|
84
|
+
*/
|
|
85
|
+
export declare function encodeSpatial3dCategorical(codes: Uint16Array, colors: string[]): Spatial3dColors;
|
|
86
|
+
/** Continuous values → `lut` over a percentile-clipped window (log1p first when the view's log
|
|
87
|
+
* scale is on), for the 3D cloud's scalar channel. */
|
|
88
|
+
export declare function encodeSpatial3dContinuous(source: Float32Array, view: SpatialViewState, lut: Rgb[], windows: ContrastWindowCache): Spatial3dScalars;
|
|
89
|
+
/** Continuous values → per-point RGBA through `lut` and a clipped window (log scale per the
|
|
90
|
+
* view), for the 2D markers. */
|
|
91
|
+
export declare function encodeSpatialContinuous(values: Float32Array, view: SpatialViewState, lut: Rgb[], windows: ContrastWindowCache, muted?: Uint8Array | null): Float32Array;
|
|
92
|
+
/** Marker colours: packed per-point RGBA (4 floats per point, the shape napari-js copies straight
|
|
93
|
+
* into its instance buffer), or one RGBA broadcast to every point. */
|
|
94
|
+
export type PointColors = Float32Array | RGBA;
|
|
95
|
+
/** Whether a colour input is one RGBA per point rather than one broadcast RGBA. */
|
|
96
|
+
export declare function isPerPoint(colors: PointColors): colors is Float32Array;
|
|
97
|
+
/** Per-point colours for the drawn subset. A broadcast tuple stays broadcast —
|
|
98
|
+
* it is one colour for every point either way. */
|
|
99
|
+
export declare function gatherColors(colors: PointColors, indices?: Uint32Array): PointColors;
|
|
100
|
+
/** One density volume's observations: a cluster (or all cells), with its legend colour. */
|
|
101
|
+
export interface DensityGroup {
|
|
102
|
+
name: string;
|
|
103
|
+
color: string;
|
|
104
|
+
indices?: Uint32Array;
|
|
105
|
+
}
|
|
106
|
+
/** The single group drawn when the colouring is not categorical: total cell density, within the
|
|
107
|
+
* selection when there is one. */
|
|
108
|
+
export declare function totalDensityGroup(selection: SpatialSelectionMask): DensityGroup;
|
|
109
|
+
/**
|
|
110
|
+
* The clusters of a categorical column to rasterise, biggest first and capped at
|
|
111
|
+
* {@link DENSITY_MAX_CLUSTERS}, each with its legend colour — restricted to the selection when
|
|
112
|
+
* there is one, so "select a region, check the box" answers which clusters live there.
|
|
113
|
+
*/
|
|
114
|
+
export declare function rankDensityGroups(columnName: string, column: CategoricalColumn, count: number, selection: SpatialSelectionMask): DensityGroup[];
|