@jax-data-science/sci-image-visualizer 0.17.0 → 0.18.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/esm2022/lib/contracts/display-types.mjs +3 -2
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/ports/spatial-data.port.mjs +1 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
- package/esm2022/lib/contracts/spatial-dataset.contract.mjs +1 -1
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/geometry/cell-meshes.mjs +37 -0
- package/esm2022/lib/geometry/place.mjs +47 -0
- package/esm2022/lib/implementations/napari-js/napari-camera-depth.mjs +93 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +81 -15
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-cells.mjs +746 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +325 -18
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-transcripts.mjs +182 -24
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +95 -5
- package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +15 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +30 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +40 -1
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +111 -28
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +14 -2
- package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +180 -48
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +28 -8
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +2 -2
- package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +10 -1
- package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +30 -3
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +15 -3
- package/esm2022/lib/region-editor/region-editor.component.mjs +24 -4
- package/esm2022/lib/region-source/region-source-ops.mjs +7 -1
- package/esm2022/lib/region-source/region-tiles.mjs +1 -1
- package/esm2022/lib/region-source/worker-region-source.mjs +24 -1
- package/esm2022/lib/routing-visualizer.service.mjs +404 -7
- package/esm2022/lib/spatial/observations-in-selection.mjs +83 -0
- package/esm2022/lib/spatial/plane-cells.mjs +119 -0
- package/esm2022/lib/spatial/spatial-controls.facade.mjs +298 -5
- package/esm2022/lib/spatial/spatial-encoding.mjs +35 -3
- package/esm2022/lib/spatial/spatial-hover.mjs +34 -1
- package/esm2022/lib/spatial/spatial-planes.mjs +49 -0
- package/esm2022/lib/spatial/spatial-selection.mjs +2 -2
- package/esm2022/lib/spatial/spatial-tile-merge.mjs +38 -1
- package/esm2022/lib/spatial/transcripts-in-selection.mjs +208 -0
- package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +42 -65
- package/esm2022/lib/spatial-controls/spatial-color-by/spatial-color-by.component.mjs +187 -0
- package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +47 -12
- package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +3 -3
- package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +38 -10
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +3 -3
- package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +3 -3
- package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +79 -57
- package/esm2022/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.mjs +101 -0
- package/esm2022/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.mjs +94 -0
- package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +9 -3
- package/esm2022/lib/store/region-source-scope.mjs +10 -1
- package/esm2022/lib/store/region-store.service.mjs +33 -2
- package/esm2022/lib/toolbar/toolbar.component.mjs +10 -3
- package/esm2022/lib/visualizer/spatial-region-set.mjs +95 -0
- package/esm2022/lib/visualizer.component.mjs +40 -4
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs} +4521 -759
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs} +2 -2
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1 -1
- package/fesm2022/region-source.worker.js +84 -2
- package/lib/contracts/display-types.d.ts +90 -4
- package/lib/contracts/image.contract.d.ts +6 -0
- package/lib/contracts/ports/spatial-data.port.d.ts +7 -0
- package/lib/contracts/region-editor-api.contract.d.ts +9 -0
- package/lib/contracts/region-store.contract.d.ts +6 -0
- package/lib/contracts/spatial-dataset.contract.d.ts +7 -1
- package/lib/contracts/visualizer.contract.d.ts +43 -1
- package/lib/geometry/cell-meshes.d.ts +27 -0
- package/lib/geometry/place.d.ts +45 -0
- package/lib/implementations/napari-js/napari-camera-depth.d.ts +23 -0
- package/lib/implementations/napari-js/napari-loading-state.d.ts +1 -1
- package/lib/implementations/napari-js/napari-scene.d.ts +12 -0
- package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +19 -3
- package/lib/implementations/napari-js/napari-spatial-3d-cells.d.ts +141 -0
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +87 -0
- package/lib/implementations/napari-js/napari-spatial-3d-transcripts.d.ts +49 -8
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +22 -0
- package/lib/implementations/napari-js/napari-spatial-scene.d.ts +12 -0
- package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +15 -0
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +27 -1
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +38 -19
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +2 -0
- package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +53 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +11 -2
- package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +7 -0
- package/lib/region-editor/class-tree/class-tree.component.d.ts +16 -1
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +10 -1
- package/lib/region-editor/region-editor.component.d.ts +4 -0
- package/lib/region-source/region-source-ops.d.ts +12 -0
- package/lib/region-source/region-tiles.d.ts +8 -0
- package/lib/region-source/worker-region-source.d.ts +18 -0
- package/lib/routing-visualizer.service.d.ts +140 -1
- package/lib/spatial/observations-in-selection.d.ts +43 -0
- package/lib/spatial/plane-cells.d.ts +37 -0
- package/lib/spatial/spatial-controls.facade.d.ts +59 -0
- package/lib/spatial/spatial-encoding.d.ts +14 -1
- package/lib/spatial/spatial-hover.d.ts +23 -0
- package/lib/spatial/spatial-planes.d.ts +22 -0
- package/lib/spatial/spatial-selection.d.ts +2 -1
- package/lib/spatial/spatial-tile-merge.d.ts +9 -0
- package/lib/spatial/transcripts-in-selection.d.ts +95 -0
- package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +19 -28
- package/lib/spatial-controls/spatial-color-by/spatial-color-by.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-controls.component.d.ts +17 -2
- package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +16 -6
- package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +26 -23
- package/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.d.ts +48 -0
- package/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.d.ts +43 -0
- package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +3 -1
- package/lib/store/region-source-scope.d.ts +4 -0
- package/lib/store/region-store.service.d.ts +21 -0
- package/lib/toolbar/toolbar.component.d.ts +6 -1
- package/lib/visualizer/spatial-region-set.d.ts +55 -0
- package/lib/visualizer.component.d.ts +14 -0
- package/package.json +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs.map +0 -1
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { Viewer } from 'napari-js';
|
|
2
|
+
import { PlanePlacement, VolumeFrame, sliceZ, toWorld } from '../../geometry/place';
|
|
3
|
+
export type { PlanePlacement, VolumeFrame };
|
|
4
|
+
export { sliceZ, toWorld };
|
|
2
5
|
/** A region's 3D reconstruction to show in the volume: a mesh in image px (x, y) and slices (z). */
|
|
3
6
|
export interface RegionMesh3D {
|
|
4
7
|
/** Identity (a class name): a mesh with the same key and arrays is kept, not rebuilt. */
|
|
@@ -10,25 +13,20 @@ export interface RegionMesh3D {
|
|
|
10
13
|
vertices: Float32Array;
|
|
11
14
|
faces: Uint32Array;
|
|
12
15
|
}
|
|
13
|
-
/**
|
|
14
|
-
export
|
|
15
|
-
/** Image width, height (px) and slice count. */
|
|
16
|
-
size: [number, number, number];
|
|
17
|
-
/** The world box (centred on the origin), Z as currently stretched. */
|
|
18
|
-
world: [number, number, number];
|
|
19
|
-
/**
|
|
20
|
-
* How much of {@link world}'s depth is the view's Z stretch (default 1). The region surfaces keep
|
|
21
|
-
* their geometry in the unstretched box and take the stretch as a GPU scale (`scale3d`), so
|
|
22
|
-
* dragging the Z handle re-uploads no mesh.
|
|
23
|
-
*/
|
|
24
|
-
zScale?: number;
|
|
25
|
-
}
|
|
16
|
+
/** Places a mesh's vertices (image px, slices) in a 3D view's world, off the main thread. */
|
|
17
|
+
export type RegionPlacer = (vertices: Float32Array, frame: VolumeFrame) => Promise<Float32Array>;
|
|
26
18
|
/** Opacity of a region's surface in the volume. */
|
|
27
19
|
export declare const REGION_MESH_OPACITY = 0.55;
|
|
28
20
|
/** While some surfaces are highlighted: theirs (near opaque, so their shape reads) … */
|
|
29
21
|
export declare const REGION_MESH_HIGHLIGHT_OPACITY = 0.9;
|
|
30
22
|
/** … and the others' (ghosted: still there for context, not in the way). */
|
|
31
23
|
export declare const REGION_MESH_DIMMED_OPACITY = 0.12;
|
|
24
|
+
/**
|
|
25
|
+
* A selection's surfaces while the others are ghosted: opaque, so they are drawn first and write
|
|
26
|
+
* depth, and the ghosted surfaces in front of them are blended over them rather than hiding them
|
|
27
|
+
* (a translucent surface draws only its own nearest faces, and is drawn after the opaque ones).
|
|
28
|
+
*/
|
|
29
|
+
export declare const REGION_MESH_SELECTED_OPACITY = 1;
|
|
32
30
|
/**
|
|
33
31
|
* The region reconstructions shown in a volume view: one translucent surface per region, in its
|
|
34
32
|
* colour, placed in the volume's world box (pixel x, y and slice z mapped onto it the way the
|
|
@@ -42,13 +40,25 @@ export declare const REGION_MESH_DIMMED_OPACITY = 0.12;
|
|
|
42
40
|
*/
|
|
43
41
|
export declare class VolumeRegionMeshes {
|
|
44
42
|
private readonly viewer;
|
|
43
|
+
private readonly placer?;
|
|
45
44
|
private readonly layers;
|
|
46
45
|
private highlighted;
|
|
47
46
|
private hidden;
|
|
47
|
+
/** Surfaces faded: none of what is selected is in them. */
|
|
48
|
+
private muted;
|
|
48
49
|
/** The meshes to show (kept while the volume has no frame yet). */
|
|
49
50
|
private wanted;
|
|
50
51
|
private frame;
|
|
51
|
-
|
|
52
|
+
/** The placements in flight, by key: the mesh and box each is for. */
|
|
53
|
+
private readonly placing;
|
|
54
|
+
private token;
|
|
55
|
+
/**
|
|
56
|
+
* `placer`, when given, places a mesh's vertices in the world off the main thread (a worker, see
|
|
57
|
+
* `placeInWorker`): a class's surface has hundreds of thousands of vertices, and placing every
|
|
58
|
+
* one in a loop here held the UI for seconds. Each surface then comes up as its placement lands,
|
|
59
|
+
* the one it replaces kept until then. Without one, they are placed at once (the tests).
|
|
60
|
+
*/
|
|
61
|
+
constructor(viewer: Viewer, placer?: RegionPlacer | undefined);
|
|
52
62
|
/** Show exactly `meshes` (adding, keeping or removing surfaces). */
|
|
53
63
|
set(meshes: readonly RegionMesh3D[]): void;
|
|
54
64
|
/**
|
|
@@ -60,6 +70,12 @@ export declare class VolumeRegionMeshes {
|
|
|
60
70
|
private scale3d;
|
|
61
71
|
/** Highlight the surfaces of these keys (none: every surface as usual). */
|
|
62
72
|
setHighlight(keys: Iterable<string>): void;
|
|
73
|
+
/**
|
|
74
|
+
* Fade the surfaces of these keys, as a picked region fades the others (none: each as usual):
|
|
75
|
+
* with a selection, the regions none of it is in fade and those it is in come forward, each
|
|
76
|
+
* keeping its colour.
|
|
77
|
+
*/
|
|
78
|
+
setMuted(keys: Iterable<string>): void;
|
|
63
79
|
/** Hide the surfaces of these keys (they are kept, so showing them again is instant). */
|
|
64
80
|
setHidden(keys: Iterable<string>): void;
|
|
65
81
|
/** The front-most surface under screen point (`x`, `y`) (canvas CSS px), or null. */
|
|
@@ -73,12 +89,15 @@ export declare class VolumeRegionMeshes {
|
|
|
73
89
|
*/
|
|
74
90
|
clearFrame(): void;
|
|
75
91
|
private sync;
|
|
92
|
+
/**
|
|
93
|
+
* Place `mesh` in the current box, adding its surface or updating it: at once, or through the
|
|
94
|
+
* placer, its result kept only if the mesh and the box are still the ones wanted. A placement
|
|
95
|
+
* already in flight for the same mesh and box is not asked again.
|
|
96
|
+
*/
|
|
97
|
+
private place;
|
|
98
|
+
/** `mesh`'s surface with its vertices placed at `world`: updated in place, or added. */
|
|
99
|
+
private apply;
|
|
76
100
|
private add;
|
|
77
101
|
private opacityOf;
|
|
78
102
|
private remove;
|
|
79
103
|
}
|
|
80
|
-
/**
|
|
81
|
-
* Image px / slice coordinates → the volume's centred world box: pixel x of a `w`-wide image
|
|
82
|
-
* spans the box's width, slice k sits at the middle of its share of the box's depth.
|
|
83
|
-
*/
|
|
84
|
-
export declare function toWorld(vertices: Float32Array, frame: VolumeFrame): Float32Array;
|
|
@@ -99,6 +99,8 @@ export declare class VolumeScene implements NapariScene {
|
|
|
99
99
|
histogram(channel: number, bins: number): IHistogram | null;
|
|
100
100
|
isoControls(): IIsosurfaceControls | null;
|
|
101
101
|
surface3dControls(): ISurface3dControls | null;
|
|
102
|
+
/** Gives the camera back napari-js's own depth range (see keepSceneInDepth). */
|
|
103
|
+
private restoreDepth;
|
|
102
104
|
dispose(): void;
|
|
103
105
|
/**
|
|
104
106
|
* Restretch the volume's Z height live (driven by the in-view {@link NapariVolumeZHandle}). Only
|
|
@@ -1,12 +1,23 @@
|
|
|
1
|
+
import type { Colormap, RGBA } from 'napari-js';
|
|
1
2
|
import type { Rgb } from '../../../contracts/colormap-lut';
|
|
2
3
|
import type { SpatialDataPort } from '../../../contracts/ports/spatial-data.port';
|
|
3
4
|
import type { SpatialViewState } from '../../../contracts/display-types';
|
|
4
5
|
import { SpatialDataset } from '../../../contracts/spatial-dataset.contract';
|
|
5
6
|
import { SpatialSelectionMask } from '../../../spatial/spatial-selection';
|
|
6
7
|
import { DataRect } from '../../../spatial/lod';
|
|
8
|
+
import { ContrastWindowCache } from '../napari-spatial-encoding';
|
|
7
9
|
import type { CategoricalLookup } from './categorical-lookup';
|
|
8
10
|
import type { OrderedLayerGroups, TileGroup } from './layer-groups';
|
|
9
11
|
import type { PlanContext } from './plan-context';
|
|
12
|
+
/** The cells' colours as a shapes layer takes them: per-shape RGBA, values over a colormap, or
|
|
13
|
+
* one colour. */
|
|
14
|
+
export interface CellColors {
|
|
15
|
+
values?: Float32Array;
|
|
16
|
+
colormap?: Colormap;
|
|
17
|
+
contrastLimits?: [number, number];
|
|
18
|
+
color?: RGBA;
|
|
19
|
+
faceColor?: Float32Array;
|
|
20
|
+
}
|
|
10
21
|
/** What the cell layers need from the service. */
|
|
11
22
|
export interface CellLayersHost {
|
|
12
23
|
/** The continuous LUT the view is using (so cells coloured by a gene match the markers). */
|
|
@@ -39,9 +50,25 @@ export declare class CellLayers {
|
|
|
39
50
|
/** Continuous colourings' windows, per (vector, clip, log): `contrastWindow` sorts every
|
|
40
51
|
* value, and a selection or opacity change recolours with the vector unchanged (SPATIAL-12). */
|
|
41
52
|
private readonly contrastWindows;
|
|
53
|
+
/**
|
|
54
|
+
* The plane of a 3D segmentation the view shows (see {@link setPlane}), or null: every set draws
|
|
55
|
+
* its own tiles.
|
|
56
|
+
*/
|
|
57
|
+
private plane;
|
|
58
|
+
/** The region set opened for a boundary set's per-plane outlines: its id and the source. */
|
|
59
|
+
private planeSource;
|
|
42
60
|
constructor(port: SpatialDataPort, groups: OrderedLayerGroups<TileGroup>, lookup: CategoricalLookup, host: CellLayersHost);
|
|
43
61
|
/** True while outlines are on screen. */
|
|
44
62
|
get outlinesShown(): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Show plane `plane` (an index into the region set's planes) of a 3D segmentation, or none: a
|
|
65
|
+
* boundary set that names its region set (`regionSource`, a cell outlined on every plane it spans)
|
|
66
|
+
* then draws that plane's outlines, rather than one outline per cell, so the cells follow the
|
|
67
|
+
* slice. Its cells keep the view's colouring, groups and selection.
|
|
68
|
+
*/
|
|
69
|
+
setPlane(plane: number | null): void;
|
|
70
|
+
/** Close the region set opened for the per-plane outlines. */
|
|
71
|
+
dispose(): void;
|
|
45
72
|
/** The viewer went away (its layers with it): the outlines are no longer shown. */
|
|
46
73
|
detached(): void;
|
|
47
74
|
/** Draw the cells covering `rect` at the level `pxPerUnit` calls for, or drop them. */
|
|
@@ -64,7 +91,33 @@ export declare class CellLayers {
|
|
|
64
91
|
* view went stale or the dataset has no set to draw.
|
|
65
92
|
*/
|
|
66
93
|
private cellGeometry;
|
|
94
|
+
/**
|
|
95
|
+
* The cells of boundary set `set` on the plane shown, from its region set (`regionSource`): the
|
|
96
|
+
* plane's tiles meeting `rect`, at the detail the zoom calls for, each outline owned by its cell
|
|
97
|
+
* (by its id among the observations'), minus the hidden groups. Undefined when it cannot be drawn
|
|
98
|
+
* so (no observation ids to tell its cells by, no port to open the set, or a plane it has not), so
|
|
99
|
+
* the set's own tiles are drawn; null when the view went stale.
|
|
100
|
+
*/
|
|
101
|
+
private planeGeometry;
|
|
102
|
+
/** The region set `id`, opened once (another id closes the one before). */
|
|
103
|
+
private openPlaneSource;
|
|
67
104
|
/** Remove the cell layers and forget what they showed. */
|
|
68
105
|
drop(): void;
|
|
69
106
|
private setPolygonsShown;
|
|
70
107
|
}
|
|
108
|
+
/** What {@link cellColorsFor} reads with: the port, the categorical columns, the windows cache, the LUT. */
|
|
109
|
+
export interface CellColorDeps {
|
|
110
|
+
port: SpatialDataPort;
|
|
111
|
+
lookup: CategoricalLookup;
|
|
112
|
+
contrastWindows: ContrastWindowCache;
|
|
113
|
+
continuousLut(view: SpatialViewState): Rgb[];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The cells' colours by their owners (`owners[i]` the observation of shape i), by the view's
|
|
117
|
+
* cell-colour mode (Xenium Explorer's "Cell Color"): one RGBA per shape for a grouping, values +
|
|
118
|
+
* colormap for a measurement, one colour for "single". A selection mutes what it leaves out. The 2D
|
|
119
|
+
* cell outlines and the 3D cells both colour by it.
|
|
120
|
+
*/
|
|
121
|
+
export declare function cellColorsFor(deps: CellColorDeps, dataset: SpatialDataset, view: SpatialViewState, selection: SpatialSelectionMask, owners: Uint32Array): Promise<CellColors>;
|
|
122
|
+
/** {@link cellColorsFor}'s colours as one RGBA (0..1) per shape, `n` shapes. */
|
|
123
|
+
export declare function cellColorsRgba(colors: CellColors, n: number): Float32Array;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { PointSymbol } from 'napari-js';
|
|
2
2
|
import type { SpatialViewState } from '../../../contracts/display-types';
|
|
3
3
|
import { SpatialDataset } from '../../../contracts/spatial-dataset.contract';
|
|
4
|
+
import type { SpatialSelectionMask } from '../../../spatial/spatial-selection';
|
|
4
5
|
import { DataRect } from '../../../spatial/lod';
|
|
5
6
|
import { TranscriptGlyph } from '../../../spatial/glyphs';
|
|
6
7
|
import type { CategoricalLookup } from './categorical-lookup';
|
|
@@ -40,8 +41,12 @@ export declare class TranscriptLayers {
|
|
|
40
41
|
geneCountsIn(rect: DataRect): Record<string, number> | null;
|
|
41
42
|
/** The viewer went away: no counts until the next plan. */
|
|
42
43
|
detached(): void;
|
|
43
|
-
/**
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Draw the view's transcript markers (or drop them); an unchanged plan key is a no-op. With a
|
|
46
|
+
* `zBand`, the view shows one plane of a 3D assay: only the transcripts at that depth are drawn
|
|
47
|
+
* (summed density grids and aggregates, which mix depths, stay whole).
|
|
48
|
+
*/
|
|
49
|
+
plan(dataset: SpatialDataset, view: SpatialViewState, rect: DataRect, pxPerUnit: number, ctx: PlanContext, zBand?: readonly [number, number] | null, selection?: SpatialSelectionMask | null): Promise<void>;
|
|
45
50
|
/**
|
|
46
51
|
* Gene icons: each entry drawn as its gene's napari-js point symbol, in the same one points
|
|
47
52
|
* layer as the circles. With every gene drawn there is one icon for all of them — 18,000
|
|
@@ -53,6 +58,10 @@ export declare class TranscriptLayers {
|
|
|
53
58
|
* for, drawn as the layer's disc or as each entry's `symbols` code.
|
|
54
59
|
*/
|
|
55
60
|
private drawTranscripts;
|
|
61
|
+
/** The selection the last plan faded by, and its revision, bumped each time it changes. */
|
|
62
|
+
private lastSelection;
|
|
63
|
+
private selectionRevision;
|
|
64
|
+
private selectionRev;
|
|
56
65
|
/** Per-entry colours, as packed RGBA. */
|
|
57
66
|
private transcriptColors;
|
|
58
67
|
}
|
|
@@ -3,6 +3,7 @@ import { Observable } from 'rxjs';
|
|
|
3
3
|
import { SpatialDataPort, TranscriptTileQuery } from '../../contracts/ports/spatial-data.port';
|
|
4
4
|
import { SpatialColumn, SpatialDataset, SpatialDensityRaster, SpatialEmbedding, SpatialPolygonTile, SpatialPolygons, CategoricalColumnMeta, SpatialMarkerGenes, SpatialTranscriptCounts, SpatialTranscriptSummary, SpatialTranscriptTile } from '../../contracts/spatial-dataset.contract';
|
|
5
5
|
import { SpatialDatasetSummary, SpatialManifest } from './spatial-wire';
|
|
6
|
+
import type { RegionSource } from '../../region-source/region-source';
|
|
6
7
|
import * as i0 from "@angular/core";
|
|
7
8
|
/**
|
|
8
9
|
* A dataset selection that a newer selection (or a `clear`) overtook.
|
|
@@ -137,6 +138,12 @@ export declare class SpatialDataHttpService implements SpatialDataPort {
|
|
|
137
138
|
/** Oldest first, past the entry cap or the byte budget, keeping the newest. */
|
|
138
139
|
private evictTiles;
|
|
139
140
|
private dropTile;
|
|
141
|
+
/**
|
|
142
|
+
* The region set a boundary set names (`polygonTiles.sets[i].regionSource`), served beside the
|
|
143
|
+
* datasets as an HTTP region source (`{base}/regions/{id}/…`, see `openHttpRegionSource`), its
|
|
144
|
+
* requests through the host's `HttpClient` as every other request here.
|
|
145
|
+
*/
|
|
146
|
+
openRegionSet(id: string): Promise<RegionSource>;
|
|
140
147
|
/**
|
|
141
148
|
* The reference volume's voxels, single-flighted like the polygons.
|
|
142
149
|
*
|
|
@@ -33,6 +33,15 @@ export declare class ClassTreeComponent implements OnChanges {
|
|
|
33
33
|
volume: boolean;
|
|
34
34
|
/** The classes shown in 3D. */
|
|
35
35
|
shown3d: ReadonlySet<string>;
|
|
36
|
+
/** Classes that can be drawn as individual cells here (a 3D segmentation's, in spatial 3D). */
|
|
37
|
+
cellable: ReadonlySet<string>;
|
|
38
|
+
/** Those drawn as individual cells now. */
|
|
39
|
+
individual: ReadonlySet<string>;
|
|
40
|
+
/** Draw a class (its subclasses with it) as individual cells, or merged again. */
|
|
41
|
+
toggleCells: EventEmitter<{
|
|
42
|
+
classes: string[];
|
|
43
|
+
individual: boolean;
|
|
44
|
+
}>;
|
|
36
45
|
/** The classes hidden from view. */
|
|
37
46
|
hidden: ReadonlySet<string>;
|
|
38
47
|
pick: EventEmitter<ClassTreePick>;
|
|
@@ -63,6 +72,12 @@ export declare class ClassTreeComponent implements OnChanges {
|
|
|
63
72
|
protected total(name: string): number;
|
|
64
73
|
protected toggle(row: ClassTreeRow, event: Event): void;
|
|
65
74
|
protected choose(name: string, event: Event): void;
|
|
75
|
+
/** A class (with its subclasses) as individual cells, or merged again: all of them as it is. */
|
|
76
|
+
protected flipCells(name: string, event: Event): void;
|
|
77
|
+
/** Whether every cellable class of `name`'s subtree is drawn as cells. */
|
|
78
|
+
protected allIndividual(name: string): boolean;
|
|
79
|
+
/** Whether `name` or a subclass can be drawn as cells. */
|
|
80
|
+
protected anyCellable(name: string): boolean;
|
|
66
81
|
/** The eye: a class hidden (wholly) is shown again with its subclasses; otherwise they are hidden. */
|
|
67
82
|
protected flipHidden(name: string, event: Event): void;
|
|
68
83
|
protected flip3d(name: string, event: Event): void;
|
|
@@ -72,7 +87,7 @@ export declare class ClassTreeComponent implements OnChanges {
|
|
|
72
87
|
protected readonly trackRow: (_: number, r: ClassTreeRow) => string;
|
|
73
88
|
private refresh;
|
|
74
89
|
static ɵfac: i0.ɵɵFactoryDeclaration<ClassTreeComponent, never>;
|
|
75
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ClassTreeComponent, "region-class-tree", never, { "nodes": { "alias": "nodes"; "required": false; }; "counts": { "alias": "counts"; "required": false; }; "colorOf": { "alias": "colorOf"; "required": false; }; "picked": { "alias": "picked"; "required": false; }; "marked": { "alias": "marked"; "required": false; }; "volume": { "alias": "volume"; "required": false; }; "shown3d": { "alias": "shown3d"; "required": false; }; "hidden": { "alias": "hidden"; "required": false; }; }, { "pick": "pick"; "recolor": "recolor"; "toggle3d": "toggle3d"; "toggleHidden": "toggleHidden"; }, never, never, true, never>;
|
|
90
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ClassTreeComponent, "region-class-tree", never, { "nodes": { "alias": "nodes"; "required": false; }; "counts": { "alias": "counts"; "required": false; }; "colorOf": { "alias": "colorOf"; "required": false; }; "picked": { "alias": "picked"; "required": false; }; "marked": { "alias": "marked"; "required": false; }; "volume": { "alias": "volume"; "required": false; }; "shown3d": { "alias": "shown3d"; "required": false; }; "cellable": { "alias": "cellable"; "required": false; }; "individual": { "alias": "individual"; "required": false; }; "hidden": { "alias": "hidden"; "required": false; }; }, { "toggleCells": "toggleCells"; "pick": "pick"; "recolor": "recolor"; "toggle3d": "toggle3d"; "toggleHidden": "toggleHidden"; }, never, never, true, never>;
|
|
76
91
|
}
|
|
77
92
|
/** Scroll the row matching `selector` inside `host` into view, if it is out of it. */
|
|
78
93
|
export declare function scrollToPicked(host: HTMLElement, selector: string): void;
|
|
@@ -41,6 +41,15 @@ export declare class ClassesPanelComponent implements OnChanges {
|
|
|
41
41
|
volume: boolean;
|
|
42
42
|
/** The classes shown in 3D. */
|
|
43
43
|
shown3d: ReadonlySet<string>;
|
|
44
|
+
/** Classes that can be drawn as individual cells here (a 3D segmentation's, in spatial 3D). */
|
|
45
|
+
cellable: ReadonlySet<string>;
|
|
46
|
+
/** Those drawn as individual cells now. */
|
|
47
|
+
individual: ReadonlySet<string>;
|
|
48
|
+
/** Draw a class (its subclasses with it) as individual cells, or merged again. */
|
|
49
|
+
toggleCells: EventEmitter<{
|
|
50
|
+
classes: string[];
|
|
51
|
+
individual: boolean;
|
|
52
|
+
}>;
|
|
44
53
|
/** The classes hidden from view. */
|
|
45
54
|
hidden: ReadonlySet<string>;
|
|
46
55
|
/** A class's eye (its name): hide it, or show it again. */
|
|
@@ -81,6 +90,6 @@ export declare class ClassesPanelComponent implements OnChanges {
|
|
|
81
90
|
protected rowTooltip(name: string): string;
|
|
82
91
|
protected removeTooltip(name: string): string;
|
|
83
92
|
static ɵfac: i0.ɵɵFactoryDeclaration<ClassesPanelComponent, never>;
|
|
84
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<ClassesPanelComponent, "region-classes-panel", never, { "classes": { "alias": "classes"; "required": false; }; "counts": { "alias": "counts"; "required": false; }; "matchMode": { "alias": "matchMode"; "required": false; }; "activeClass": { "alias": "activeClass"; "required": false; }; "picked": { "alias": "picked"; "required": false; }; "marked": { "alias": "marked"; "required": false; }; "selectedCount": { "alias": "selectedCount"; "required": false; }; "defaultClassName": { "alias": "defaultClassName"; "required": false; }; "volume": { "alias": "volume"; "required": false; }; "shown3d": { "alias": "shown3d"; "required": false; }; "hidden": { "alias": "hidden"; "required": false; }; "treeView": { "alias": "treeView"; "required": false; }; }, { "toggleHidden": "toggleHidden"; "toggle3d": "toggle3d"; "treeViewChange": "treeViewChange"; "pick": "pick"; "recolor": "recolor"; "remove": "remove"; "manage": "manage"; }, never, ["*"], true, never>;
|
|
93
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ClassesPanelComponent, "region-classes-panel", never, { "classes": { "alias": "classes"; "required": false; }; "counts": { "alias": "counts"; "required": false; }; "matchMode": { "alias": "matchMode"; "required": false; }; "activeClass": { "alias": "activeClass"; "required": false; }; "picked": { "alias": "picked"; "required": false; }; "marked": { "alias": "marked"; "required": false; }; "selectedCount": { "alias": "selectedCount"; "required": false; }; "defaultClassName": { "alias": "defaultClassName"; "required": false; }; "volume": { "alias": "volume"; "required": false; }; "shown3d": { "alias": "shown3d"; "required": false; }; "cellable": { "alias": "cellable"; "required": false; }; "individual": { "alias": "individual"; "required": false; }; "hidden": { "alias": "hidden"; "required": false; }; "treeView": { "alias": "treeView"; "required": false; }; }, { "toggleCells": "toggleCells"; "toggleHidden": "toggleHidden"; "toggle3d": "toggle3d"; "treeViewChange": "treeViewChange"; "pick": "pick"; "recolor": "recolor"; "remove": "remove"; "manage": "manage"; }, never, ["*"], true, never>;
|
|
85
94
|
}
|
|
86
95
|
export {};
|
|
@@ -196,6 +196,10 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
196
196
|
*/
|
|
197
197
|
protected toggleClass3d(name: string, classes?: string[]): void;
|
|
198
198
|
/** Hide (or show again) these classes' regions, wherever they are drawn. */
|
|
199
|
+
/** Classes that can be drawn as individual cells in spatial 3D, and those that are. */
|
|
200
|
+
protected cellableClasses: ReadonlySet<string>;
|
|
201
|
+
protected individualClasses: ReadonlySet<string>;
|
|
202
|
+
protected setClassesIndividual3d(classes: readonly string[], individual: boolean): void;
|
|
199
203
|
protected setClassesHidden(classes: readonly string[], hidden: boolean): void;
|
|
200
204
|
/** The surfaces shown in 3D, in their classes' colours now. */
|
|
201
205
|
private groups3d;
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* Protocol: `{ id, op, ...args }` → `{ id, ok: true, result }` | `{ id, ok: false, error }`.
|
|
7
7
|
*/
|
|
8
8
|
import { ReconstructOptions, SliceOutlines } from '../geometry/reconstruct';
|
|
9
|
+
import { CellOutlines, CellsMesh } from '../geometry/cell-meshes';
|
|
10
|
+
import { VolumeFrame } from '../geometry/place';
|
|
9
11
|
import type { Mesh } from 'napari-js/geometry';
|
|
10
12
|
import { ClassOutlines, RegionIndexPage, RegionIndexQuery, RegionSourceInfo, RegionTile } from './region-tiles';
|
|
11
13
|
import type { SourceFeature } from './region-source';
|
|
@@ -44,6 +46,14 @@ export type RegionSourceRequest = {
|
|
|
44
46
|
op: 'mesh';
|
|
45
47
|
slices: readonly SliceOutlines[];
|
|
46
48
|
options?: ReconstructOptions;
|
|
49
|
+
} | {
|
|
50
|
+
op: 'cells';
|
|
51
|
+
cells: readonly CellOutlines[];
|
|
52
|
+
options?: ReconstructOptions;
|
|
53
|
+
} | {
|
|
54
|
+
op: 'place';
|
|
55
|
+
vertices: Float32Array;
|
|
56
|
+
frame: VolumeFrame;
|
|
47
57
|
} | {
|
|
48
58
|
op: 'export';
|
|
49
59
|
handle: number;
|
|
@@ -64,6 +74,8 @@ export interface RegionSourceResults {
|
|
|
64
74
|
classes: Record<string, number>;
|
|
65
75
|
outlines: ClassOutlines[];
|
|
66
76
|
mesh: Mesh;
|
|
77
|
+
cells: CellsMesh;
|
|
78
|
+
place: Float32Array;
|
|
67
79
|
export: string;
|
|
68
80
|
close: null;
|
|
69
81
|
}
|
|
@@ -53,6 +53,14 @@ export interface RegionSourceInfo {
|
|
|
53
53
|
hierarchy?: RegionClassNode[];
|
|
54
54
|
/** How the set wants to be drawn, when it says. */
|
|
55
55
|
style?: RegionSourceStyle;
|
|
56
|
+
/**
|
|
57
|
+
* Where each plane is, when the set says: `sliceZ[i]` the z of plane `planes[i]`, in the units of
|
|
58
|
+
* the coordinates its outlines are in (a 3D segmentation's planes, in its observations' units).
|
|
59
|
+
* Planes stay ordinals for addressing; these place them (see the spatial 3D view).
|
|
60
|
+
*/
|
|
61
|
+
sliceZ?: number[];
|
|
62
|
+
/** Microns per unit of the set's coordinates, when it says. */
|
|
63
|
+
micronsPerUnit?: number;
|
|
56
64
|
}
|
|
57
65
|
/** One feature as a tile carries it: identity, class and outline at the tile's level. */
|
|
58
66
|
export interface TileFeature {
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
import { RegionSource } from './region-source';
|
|
10
10
|
import { RegionSourceRequest, RegionSourceResults } from './region-source-ops';
|
|
11
11
|
import type { ReconstructOptions, SliceOutlines } from '../geometry/reconstruct';
|
|
12
|
+
import type { CellOutlines, CellsMesh } from '../geometry/cell-meshes';
|
|
13
|
+
import type { VolumeFrame } from '../geometry/place';
|
|
12
14
|
import type { Mesh } from 'napari-js/geometry';
|
|
13
15
|
/** Makes the worker; may be async, as the default one is (it imports the factory on demand). */
|
|
14
16
|
export type RegionSourceWorkerFactory = () => Worker | Promise<Worker>;
|
|
@@ -58,6 +60,22 @@ export declare function sharedRegionSourceClient(): RegionSourceWorkerClient;
|
|
|
58
60
|
* a collection without `features`.
|
|
59
61
|
*/
|
|
60
62
|
export declare function openGeoJsonRegionSource(text: string, client?: RegionSourceWorkerClient): Promise<RegionSource>;
|
|
63
|
+
/**
|
|
64
|
+
* The worker client cells are meshed on: a worker of its own, so a few thousand cells meshing does
|
|
65
|
+
* not hold up the region tiles the 2D views read from the shared one.
|
|
66
|
+
*/
|
|
67
|
+
export declare function cellsWorkerClient(): RegionSourceWorkerClient;
|
|
68
|
+
/**
|
|
69
|
+
* A 3D segmentation's cells, each meshed by itself (see `geometry/cell-meshes`), in the cells'
|
|
70
|
+
* worker (on the main thread where there is none). Batch them: one call meshes its cells in one go.
|
|
71
|
+
*/
|
|
72
|
+
export declare function reconstructCellsInWorker(cells: readonly CellOutlines[], options?: ReconstructOptions, client?: RegionSourceWorkerClient): Promise<CellsMesh>;
|
|
73
|
+
/**
|
|
74
|
+
* A mesh's vertices placed in a 3D view's world (see `geometry/place`), in the cells' worker: a
|
|
75
|
+
* class's surface has hundreds of thousands, and placing every surface on the main thread held it
|
|
76
|
+
* for seconds.
|
|
77
|
+
*/
|
|
78
|
+
export declare function placeInWorker(vertices: Float32Array, frame: VolumeFrame, client?: RegionSourceWorkerClient): Promise<Float32Array>;
|
|
61
79
|
/**
|
|
62
80
|
* The 3D reconstruction of a region from its outlines on a stack (see `geometry/reconstruct`),
|
|
63
81
|
* meshed in the region-source worker (on the main thread where there is none).
|
|
@@ -12,7 +12,7 @@ import { SpatialDataPort } from './contracts/ports/spatial-data.port';
|
|
|
12
12
|
import { CanvasToolOptions, ColormapNode, IBrushOptions, IWandOptions } from './contracts/display-types';
|
|
13
13
|
import { RegionStore } from './store/region-store.service';
|
|
14
14
|
import { RegionSource, RegionSourceView } from './region-source/region-source';
|
|
15
|
-
import type { RegionIndexPage, RegionIndexQuery } from './region-source/region-tiles';
|
|
15
|
+
import type { RegionIndexPage, RegionIndexQuery, RegionSourceInfo } from './region-source/region-tiles';
|
|
16
16
|
import type { RegionStyle } from './region-overlay/region-style';
|
|
17
17
|
import type { RegionSourceOpener, RegionSourceSlices } from './store/region-source-scope';
|
|
18
18
|
import { SpatialSelectionStore } from './store/spatial-selection.service';
|
|
@@ -94,6 +94,38 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
94
94
|
/** The class groups shown in 3D, and the image they belong to. */
|
|
95
95
|
private readonly classes3d$;
|
|
96
96
|
private classes3dImage;
|
|
97
|
+
/**
|
|
98
|
+
* The spatial dataset's region set attached to its image (see attachDatasetRegionSet): the image
|
|
99
|
+
* (its region scope key), the set's key, and where its slices are when it says (its `sliceZ`),
|
|
100
|
+
* which places its surfaces in spatial 3D on an image of one plane. `shown3d` once its classes
|
|
101
|
+
* were shown in 3D by themselves, which happens once per image.
|
|
102
|
+
*/
|
|
103
|
+
private datasetRegionSet;
|
|
104
|
+
/**
|
|
105
|
+
* Each image's attached region set, kept across image switches: coming back to the image finds
|
|
106
|
+
* its source still in the store (with what was taken from it, or deleted) and restores the set
|
|
107
|
+
* rather than attaching it again, which would start the source afresh.
|
|
108
|
+
*/
|
|
109
|
+
private readonly attachedRegionSets;
|
|
110
|
+
/** The spatial dataset on offer (the port's), for the boundary set its region set is. */
|
|
111
|
+
private spatialDataset;
|
|
112
|
+
/**
|
|
113
|
+
* Whether the Annotations switch last hid every class in a spatial view (see syncAnnotations), so
|
|
114
|
+
* a change of it, not every view emission, hides or shows them.
|
|
115
|
+
*/
|
|
116
|
+
private annotationsHidden;
|
|
117
|
+
/** The 3D view's global cells switch as last applied (see updateCells3d). */
|
|
118
|
+
private cells3dMode;
|
|
119
|
+
/** Classes set the other way than the global switch in the Region Editor. */
|
|
120
|
+
private readonly cells3dOverrides;
|
|
121
|
+
/** The classes drawn as individual cells in spatial 3D, as last applied. */
|
|
122
|
+
private readonly individual3d$;
|
|
123
|
+
/** The classes that can be drawn as individual cells now (see getCellableClasses3d$). */
|
|
124
|
+
private readonly cellable3d$;
|
|
125
|
+
/** Follows the dataset and the spatial view for {@link updatePlaneCells}. */
|
|
126
|
+
private readonly planeCellsSub;
|
|
127
|
+
/** The dataset region set's planes while they slice the plotted image (see getDatasetPlanes$). */
|
|
128
|
+
private readonly datasetPlanes$;
|
|
97
129
|
/** The groups last asked for in 3D, with their colours: what an edit's rebuild shows again. */
|
|
98
130
|
private shown3d;
|
|
99
131
|
/**
|
|
@@ -202,6 +234,18 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
202
234
|
setImageSmoothingEnabled(enabled: boolean): void;
|
|
203
235
|
setShowStack(showstack: boolean): void;
|
|
204
236
|
setZIndex(zIndex: number): void;
|
|
237
|
+
/**
|
|
238
|
+
* The image's own slice for slider position `z`: 0 while the dataset region set's planes slice an
|
|
239
|
+
* image of one plane (the slider then picks the plane, see getDatasetPlanes$), else `z`.
|
|
240
|
+
*/
|
|
241
|
+
private imageSlice;
|
|
242
|
+
/**
|
|
243
|
+
* The planes of the spatial dataset's region set (its `sliceZ`, in observation units) while they
|
|
244
|
+
* slice the plotted image, an image of one plane; null otherwise. The host's slice slider then
|
|
245
|
+
* runs over them: each position shows that plane's regions and, in the 2D spatial view, the
|
|
246
|
+
* observations and transcripts nearest it, over the same image.
|
|
247
|
+
*/
|
|
248
|
+
getDatasetPlanes$(): Observable<readonly number[] | null>;
|
|
205
249
|
getTrueImageSize(): {
|
|
206
250
|
width: number;
|
|
207
251
|
height: number;
|
|
@@ -299,6 +343,88 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
299
343
|
* another image (see {@link regionImportTicket}; one is taken here when `ticket` is not given).
|
|
300
344
|
*/
|
|
301
345
|
importRegionSourceOpener(open: RegionSourceOpener, ticket?: number): Promise<boolean>;
|
|
346
|
+
/**
|
|
347
|
+
* Attach a spatial dataset's region set (a 3D segmentation's cells, outlined on every plane they
|
|
348
|
+
* span) to its image, the image plotted now, as the image's own regions are: over every slice
|
|
349
|
+
* from the set's planes (`'planes'`), not marked imported (it is the dataset's, nothing to save),
|
|
350
|
+
* leaving the image's drawn regions as they are. Once per image and set: called again (the
|
|
351
|
+
* dataset re-emitted, the image re-plotted) it changes nothing. Where the set's slices are (its
|
|
352
|
+
* `sliceZ`) places its surfaces among the observations in spatial 3D, where the region editor then
|
|
353
|
+
* offers its classes in 3D; there, every class is shown once by itself (see showDatasetRegionSet3d).
|
|
354
|
+
* Back on an image the set was attached to, with its source still the store's, it is restored as
|
|
355
|
+
* it was (what was taken from the source, or deleted, stays so), not attached again.
|
|
356
|
+
* Resolves false, changing nothing (the source disposed), when another image was plotted or
|
|
357
|
+
* another set attached while it opened, it could not be opened, or the image has region sources
|
|
358
|
+
* of its own (which it would replace, see keepsOwnSources).
|
|
359
|
+
*/
|
|
360
|
+
attachDatasetRegionSet(open: RegionSourceOpener, key: string): Promise<boolean>;
|
|
361
|
+
/**
|
|
362
|
+
* Whether the plotted image has region sources of its own (a served set, large saved ROIs, an
|
|
363
|
+
* annotation folder's slices), which attaching the dataset's set over every plane would replace,
|
|
364
|
+
* dropping them and what was taken from them: they are kept, and the set is not attached.
|
|
365
|
+
*/
|
|
366
|
+
private keepsOwnSources;
|
|
367
|
+
/**
|
|
368
|
+
* Make `set` the plotted image's region set: its planes slice the image (its regions per plane,
|
|
369
|
+
* as a stack's per slice: those drawn before go to the plane shown), place its surfaces in
|
|
370
|
+
* spatial 3D and drive the slider.
|
|
371
|
+
*/
|
|
372
|
+
private useDatasetRegionSet;
|
|
373
|
+
/**
|
|
374
|
+
* The dataset no longer names the attached set while its image is still plotted (see
|
|
375
|
+
* IVisualizer.releaseDatasetRegionSet): its planes, its surfaces and cells in 3D go, as on another
|
|
376
|
+
* image. Its attachment is kept (attachedRegionSets): the same set asked for again is restored.
|
|
377
|
+
*/
|
|
378
|
+
releaseDatasetRegionSet(keep: string | null): void;
|
|
379
|
+
/** The dataset region set's classes while in spatial 3D: those that can be drawn as cells. */
|
|
380
|
+
getCellableClasses3d$(): Observable<ReadonlySet<string>>;
|
|
381
|
+
/** The classes the spatial 3D view draws as individual cells (see updateCells3d). */
|
|
382
|
+
getIndividualClasses3d$(): Observable<ReadonlySet<string>>;
|
|
383
|
+
/** Draw these classes as individual cells in spatial 3D, or merged again (the global switch aside). */
|
|
384
|
+
setClassesIndividual3d(classes: readonly string[], individual: boolean): void;
|
|
385
|
+
/**
|
|
386
|
+
* Which of the dataset region set's classes the spatial 3D view draws as individual cells: every
|
|
387
|
+
* one with the panel's global switch on "cells", none on "types", each class the Region Editor
|
|
388
|
+
* set the other way excepted. Turning the global switch resets those. The individual classes'
|
|
389
|
+
* merged surfaces are left out (see showRegionClasses3d); their cells are drawn instead.
|
|
390
|
+
*/
|
|
391
|
+
private updateCells3d;
|
|
392
|
+
/**
|
|
393
|
+
* In the spatial views (2D and 3D), the spatial panel's Regions switch (`showAnnotations`, off by
|
|
394
|
+
* default) is every class's in the Region Editor's list, as their eyes are: off, every class is
|
|
395
|
+
* hidden (the drawn regions' and the dataset region set's cell types alike: their regions in 2D,
|
|
396
|
+
* their surfaces in 3D, and the eyes show it); on again, every class is shown. Applied when the
|
|
397
|
+
* switch changes, or on entering a spatial view with it off (so by default), so a class hidden or
|
|
398
|
+
* shown by its own eye meanwhile stays as it was set.
|
|
399
|
+
*/
|
|
400
|
+
private syncAnnotations;
|
|
401
|
+
/**
|
|
402
|
+
* Every class the Region Editor lists for the image: the dataset region set's, those shown in 3D,
|
|
403
|
+
* the drawn regions', and any hidden now.
|
|
404
|
+
*/
|
|
405
|
+
private knownClasses;
|
|
406
|
+
/**
|
|
407
|
+
* The Cells panel's boundary set that is the dataset's region set (the one naming it as its
|
|
408
|
+
* `regionSource`), while its planes are shown on the plotted image with its source still the
|
|
409
|
+
* store's; null otherwise.
|
|
410
|
+
*/
|
|
411
|
+
private planeCellSet;
|
|
412
|
+
/**
|
|
413
|
+
* While the dataset region set's planes are shown, the Cells panel draws each plane's cells from
|
|
414
|
+
* it (its boundary set, see `CellLayers.setPlane`):
|
|
415
|
+
* - that set is the panel's boundaries by default: a view that has not chosen a set (none yet, or
|
|
416
|
+
* after a reset) is given it;
|
|
417
|
+
* - in the 2D spatial view, while the panel draws them, the overlays do not draw the same
|
|
418
|
+
* outlines a second time (`RegionStore.setRegionSourceDrawn`). They stay listed and editable
|
|
419
|
+
* in the Region Editor, and are drawn by the overlays everywhere else.
|
|
420
|
+
*/
|
|
421
|
+
private updatePlaneCells;
|
|
422
|
+
/**
|
|
423
|
+
* In spatial 3D, with the dataset's region set placed there: show each of its classes in 3D, in
|
|
424
|
+
* its colour, once per image, unless classes are shown already (the region editor's choice
|
|
425
|
+
* stands, and hiding them all stays hidden).
|
|
426
|
+
*/
|
|
427
|
+
private showDatasetRegionSet3d;
|
|
302
428
|
/** Empty every slice of a stack (its regions and undo history) for regions imported over it. */
|
|
303
429
|
private enterImportedStack;
|
|
304
430
|
getRegionSourceView$(): Observable<RegionSourceView | null>;
|
|
@@ -462,6 +588,8 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
462
588
|
/** Displayed slice. Only a volume-backed spatial dataset reads it, to keep a
|
|
463
589
|
* region drawn over one section from selecting the whole depth behind it. */
|
|
464
590
|
private currentZIndex;
|
|
591
|
+
/** The slice shown, the plot type or the dataset's planes changed (the spatial controls recount). */
|
|
592
|
+
private readonly spatialViewChanged$;
|
|
465
593
|
/** Angular calls this when the injector providing the router is destroyed — the host
|
|
466
594
|
* component for a `provideVisualization()` chain. The dataset subscription would
|
|
467
595
|
* otherwise keep the whole isolated chain reachable from the root data port. */
|
|
@@ -497,3 +625,14 @@ export declare class RoutingVisualizerService implements IVisualizer, IRegionEdi
|
|
|
497
625
|
static ɵfac: i0.ɵɵFactoryDeclaration<RoutingVisualizerService, [null, null, null, null, null, null, null, null, { optional: true; }]>;
|
|
498
626
|
static ɵprov: i0.ɵɵInjectableDeclaration<RoutingVisualizerService>;
|
|
499
627
|
}
|
|
628
|
+
/**
|
|
629
|
+
* A region set's classes as 3D groups, as the region editor's class tree shows them: one per root of
|
|
630
|
+
* its hierarchy with every class under it (one per class of a flat one), in the hierarchy's order;
|
|
631
|
+
* without a hierarchy, one per class its features have. Each in the colour the set gives it (its
|
|
632
|
+
* hierarchy's, else its features').
|
|
633
|
+
*/
|
|
634
|
+
export declare function regionSetGroups(info: RegionSourceInfo): Array<{
|
|
635
|
+
key: string;
|
|
636
|
+
classes: string[];
|
|
637
|
+
color: string;
|
|
638
|
+
}>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { SpatialViewState } from '../contracts/display-types';
|
|
2
|
+
import type { SpatialDataPort } from '../contracts/ports/spatial-data.port';
|
|
3
|
+
import { type SpatialDataset } from '../contracts/spatial-dataset.contract';
|
|
4
|
+
/**
|
|
5
|
+
* The observations of a selection (a mask), described: how many, by the grouping they are coloured
|
|
6
|
+
* by (else the cell types), the mean of a few measurements — or, for one cell, its id, its groups
|
|
7
|
+
* and its values. Pure but for the port's columns (cached by it).
|
|
8
|
+
*/
|
|
9
|
+
/** At most this many measurements (continuous columns) are given. */
|
|
10
|
+
export declare const OBSERVATION_DETAIL_COLUMNS = 6;
|
|
11
|
+
/** One group's observations in the selection. */
|
|
12
|
+
export interface GroupCount {
|
|
13
|
+
name: string;
|
|
14
|
+
count: number;
|
|
15
|
+
/** The group's colour, as the legend shows it. */
|
|
16
|
+
color: string;
|
|
17
|
+
}
|
|
18
|
+
/** What {@link describeObservations} finds. */
|
|
19
|
+
export interface ObservationsDescription {
|
|
20
|
+
total: number;
|
|
21
|
+
/** The grouping the observations are counted by, or null when the dataset has none. */
|
|
22
|
+
groupColumn: string | null;
|
|
23
|
+
/** Groups by count, most first (empty groups left out). */
|
|
24
|
+
groups: GroupCount[];
|
|
25
|
+
/**
|
|
26
|
+
* A few measurements: the mean over the selection (`mean` true), or one cell's own values. With
|
|
27
|
+
* one cell, its other groupings come first, as text.
|
|
28
|
+
*/
|
|
29
|
+
measures: {
|
|
30
|
+
name: string;
|
|
31
|
+
value: string | number;
|
|
32
|
+
unit?: string;
|
|
33
|
+
mean: boolean;
|
|
34
|
+
}[];
|
|
35
|
+
/** The one cell's id, when the selection is one cell. */
|
|
36
|
+
cellId?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Describe the observations `mask` selects (see {@link ObservationsDescription}): counted by the
|
|
40
|
+
* categorical column the view colours by, else the cell-type column; at most `maxMeasures`
|
|
41
|
+
* continuous columns averaged (or read, for one cell).
|
|
42
|
+
*/
|
|
43
|
+
export declare function describeObservations(port: Pick<SpatialDataPort, 'getColumn'>, dataset: SpatialDataset, view: Pick<SpatialViewState, 'colorBy' | 'cellTypeColumn' | 'groupColors'>, mask: Uint8Array, maxMeasures?: number): Promise<ObservationsDescription>;
|