@jax-data-science/sci-image-visualizer 0.9.0 → 0.11.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/index.mjs +10 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/ports/region-io.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/section-view.contract.mjs +2 -0
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +1 -1
- package/esm2022/lib/geometry/loft.mjs +128 -0
- package/esm2022/lib/geometry/polylabel.mjs +156 -0
- package/esm2022/lib/geometry/reconstruct.mjs +315 -0
- package/esm2022/lib/geometry/reslice-image.mjs +57 -0
- package/esm2022/lib/geometry/section.mjs +215 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +11 -7
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +20 -3
- package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +28 -5
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +9 -2
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +5 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +81 -1
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +115 -4
- package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +15 -3
- package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +18 -2
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +9 -1
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +18 -7
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +38 -8
- package/esm2022/lib/implementations/osd/osd-tile-loading.mjs +71 -0
- package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +1 -1
- package/esm2022/lib/implementations/osd/slice-cache.mjs +35 -6
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +1 -1
- package/esm2022/lib/models/class-preset.mjs +1 -1
- package/esm2022/lib/models/polygon-factory.mjs +17 -1
- package/esm2022/lib/models/region-geojson.mjs +44 -6
- package/esm2022/lib/models/region.mjs +1 -1
- 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 +77 -13
- package/esm2022/lib/region-editor/region-editor.component.mjs +670 -42
- package/esm2022/lib/region-editor/region-metrics.mjs +20 -2
- package/esm2022/lib/region-editor/region-persistence.service.mjs +44 -10
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +24 -8
- package/esm2022/lib/region-import/label-classes.mjs +149 -0
- package/esm2022/lib/region-import/label-volume.mjs +194 -0
- package/esm2022/lib/region-import/region-import.mjs +71 -0
- package/esm2022/lib/region-overlay/region-geometry.mjs +3 -3
- 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-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/routing-visualizer.service.mjs +510 -22
- package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
- package/esm2022/lib/store/class-color.util.mjs +10 -5
- package/esm2022/lib/store/class-signatures.mjs +63 -0
- package/esm2022/lib/store/region-scope-cache.mjs +5 -1
- package/esm2022/lib/store/region-source-scope.mjs +186 -0
- package/esm2022/lib/store/region-store.service.mjs +774 -12
- package/esm2022/lib/store/visualizer-store.service.mjs +33 -6
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +8 -2
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +55 -15
- package/esm2022/lib/toolbar/toolbar.component.mjs +19 -5
- package/esm2022/lib/visualizer/region-load.mjs +67 -4
- package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
- package/esm2022/lib/visualizer.component.mjs +155 -7
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BELcx0jv.mjs} +9851 -2904
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BELcx0jv.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-DEDSm_NL.mjs} +4 -4
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-DEDSm_NL.mjs.map} +1 -1
- 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.mjs +3 -3
- package/fesm2022/region-source.worker.js +1067 -0
- package/index.d.ts +12 -0
- package/lib/contracts/image.contract.d.ts +4 -0
- package/lib/contracts/ports/region-io.port.d.ts +24 -0
- package/lib/contracts/region-editor-api.contract.d.ts +102 -0
- package/lib/contracts/region-store.contract.d.ts +22 -0
- package/lib/contracts/section-view.contract.d.ts +44 -0
- package/lib/contracts/visualizer.contract.d.ts +10 -0
- package/lib/contracts/viz-config.d.ts +8 -0
- package/lib/geometry/loft.d.ts +22 -0
- package/lib/geometry/polylabel.d.ts +23 -0
- package/lib/geometry/reconstruct.d.ts +54 -0
- package/lib/geometry/reslice-image.d.ts +33 -0
- package/lib/geometry/section.d.ts +52 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -2
- package/lib/implementations/napari-js/napari-loading-state.d.ts +8 -1
- package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +6 -1
- package/lib/implementations/napari-js/napari-scene.d.ts +33 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +3 -1
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +48 -0
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +45 -1
- package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
- package/lib/implementations/osd/openseadragon-viewer-options.d.ts +2 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +2 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +4 -3
- package/lib/implementations/osd/osd-region-overlay.d.ts +10 -3
- package/lib/implementations/osd/osd-tile-loading.d.ts +43 -0
- package/lib/implementations/osd/osd-viewer-like.d.ts +14 -0
- package/lib/implementations/osd/slice-cache.d.ts +13 -3
- package/lib/implementations/tile-server/tile-protocol.d.ts +3 -0
- package/lib/models/class-preset.d.ts +7 -0
- package/lib/models/polygon-factory.d.ts +5 -0
- package/lib/models/region-geojson.d.ts +40 -0
- package/lib/models/region.d.ts +19 -0
- 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 +36 -6
- package/lib/region-editor/region-editor.component.d.ts +159 -17
- package/lib/region-editor/region-metrics.d.ts +8 -0
- package/lib/region-editor/region-persistence.service.d.ts +17 -5
- package/lib/region-editor/region-table/region-table.component.d.ts +10 -4
- package/lib/region-import/label-classes.d.ts +39 -0
- package/lib/region-import/label-volume.d.ts +31 -0
- package/lib/region-import/region-import.d.ts +46 -0
- package/lib/region-overlay/region-geometry.d.ts +4 -3
- package/lib/region-overlay/region-source-layer.d.ts +96 -0
- package/lib/region-overlay/region-style.d.ts +52 -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/routing-visualizer.service.d.ts +168 -1
- package/lib/section-pane/section-pane.component.d.ts +47 -0
- package/lib/store/class-color.util.d.ts +6 -3
- package/lib/store/class-signatures.d.ts +11 -0
- package/lib/store/region-scope-cache.d.ts +2 -0
- package/lib/store/region-source-scope.d.ts +74 -0
- package/lib/store/region-store.service.d.ts +216 -2
- package/lib/store/visualizer-store.service.d.ts +10 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +3 -1
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +20 -9
- package/lib/toolbar/toolbar.component.d.ts +9 -2
- package/lib/visualizer/region-load.d.ts +23 -4
- package/lib/visualizer/volume-sections.d.ts +64 -0
- package/lib/visualizer.component.d.ts +40 -0
- package/package.json +2 -2
- package/src/lib/assets/slice.svg +23 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +0 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { RegionClassNode } from '../../region-source/region-tiles';
|
|
2
|
+
/** A class hierarchy as a tree: children in order, subtree counts, depths. Pure. */
|
|
3
|
+
export interface ClassTree {
|
|
4
|
+
roots: string[];
|
|
5
|
+
node: Map<string, RegionClassNode>;
|
|
6
|
+
children: Map<string, string[]>;
|
|
7
|
+
parent: Map<string, string | null>;
|
|
8
|
+
/** Regions of the class and every class under it. */
|
|
9
|
+
total: Map<string, number>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Build the tree of `nodes`, counting `counts` (regions per class) up through it. A node whose
|
|
13
|
+
* parent is not in the hierarchy is a root; siblings sort by `order`, then as listed.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildClassTree(nodes: readonly RegionClassNode[], counts: ReadonlyMap<string, number>): ClassTree;
|
|
16
|
+
/** `name` and every class under it. */
|
|
17
|
+
export declare function subtree(tree: ClassTree, name: string): string[];
|
|
18
|
+
/** The classes from the root down to `name`'s parent. */
|
|
19
|
+
export declare function ancestors(tree: ClassTree, name: string): string[];
|
|
20
|
+
/** One visible row of the tree. */
|
|
21
|
+
export interface ClassTreeRow {
|
|
22
|
+
name: string;
|
|
23
|
+
depth: number;
|
|
24
|
+
hasChildren: boolean;
|
|
25
|
+
expanded: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The rows to draw: depth-first through the expanded nodes. With a `query`, only the nodes whose
|
|
29
|
+
* name or title contains it and their ancestors, all expanded.
|
|
30
|
+
*/
|
|
31
|
+
export declare function visibleRows(tree: ClassTree, expanded: ReadonlySet<string>, query?: string): ClassTreeRow[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EventEmitter, OnChanges } from '@angular/core';
|
|
1
|
+
import { ElementRef, EventEmitter, OnChanges, SimpleChanges } from '@angular/core';
|
|
2
2
|
import { ClassPreset, MatchMode } from '../../models/class-preset';
|
|
3
3
|
import * as i0 from "@angular/core";
|
|
4
4
|
/** One class row as the template draws it, derived once per input change. */
|
|
@@ -14,10 +14,13 @@ interface ClassRow {
|
|
|
14
14
|
* The Region Editor's docked "Classes" panel (jit-ui#70): every annotation
|
|
15
15
|
* class with its colour swatch and region count. A row click picks the active
|
|
16
16
|
* class (and re-classifies a selection), the swatch recolours the class, the
|
|
17
|
-
* trash removes it, Manage opens the full editor
|
|
18
|
-
*
|
|
17
|
+
* trash removes it, Manage opens the full editor; the search box filters the
|
|
18
|
+
* rows by name; the eye hides a class's regions. For a class hierarchy the editor projects a class tree in,
|
|
19
|
+
* shown in place of the list while {@link treeView} is on. Presentational: the
|
|
20
|
+
* editor applies every action.
|
|
19
21
|
*/
|
|
20
22
|
export declare class ClassesPanelComponent implements OnChanges {
|
|
23
|
+
private readonly el;
|
|
21
24
|
/** The classes in display order. */
|
|
22
25
|
classes: ClassPreset[];
|
|
23
26
|
/** Region count per class, keyed by {@link presetKey} under `matchMode`. */
|
|
@@ -26,10 +29,28 @@ export declare class ClassesPanelComponent implements OnChanges {
|
|
|
26
29
|
matchMode: MatchMode;
|
|
27
30
|
/** The active class (highlighted), or null. */
|
|
28
31
|
activeClass: string | null;
|
|
32
|
+
/** The class picked last (in the class tree, or a surface in 3D): highlighted, scrolled into view. */
|
|
33
|
+
picked: string | null;
|
|
34
|
+
/** Classes with a selected region (marked). */
|
|
35
|
+
marked: ReadonlySet<string>;
|
|
29
36
|
/** Number of selected regions (changes what a row click does). */
|
|
30
37
|
selectedCount: number;
|
|
31
38
|
/** The class regions revert to; it can't be removed while in use. */
|
|
32
39
|
defaultClassName: string;
|
|
40
|
+
/** Whether a volume view is on screen: each class can then be shown in 3D. */
|
|
41
|
+
volume: boolean;
|
|
42
|
+
/** The classes shown in 3D. */
|
|
43
|
+
shown3d: ReadonlySet<string>;
|
|
44
|
+
/** The classes hidden from view. */
|
|
45
|
+
hidden: ReadonlySet<string>;
|
|
46
|
+
/** A class's eye (its name): hide it, or show it again. */
|
|
47
|
+
toggleHidden: EventEmitter<string>;
|
|
48
|
+
/** A class's 3D toggle (its name). */
|
|
49
|
+
toggle3d: EventEmitter<string>;
|
|
50
|
+
/** Whether the projected class tree is shown instead of the list; null: there is no tree. */
|
|
51
|
+
treeView: boolean | null;
|
|
52
|
+
/** The list / tree switch. */
|
|
53
|
+
treeViewChange: EventEmitter<boolean>;
|
|
33
54
|
/** A row was clicked: make the class active / apply it to the selection. */
|
|
34
55
|
pick: EventEmitter<string>;
|
|
35
56
|
/** A class's swatch picked a new colour. */
|
|
@@ -43,14 +64,23 @@ export declare class ClassesPanelComponent implements OnChanges {
|
|
|
43
64
|
manage: EventEmitter<void>;
|
|
44
65
|
/** trackBy for the class rows so re-sorting doesn't re-create the pickers. */
|
|
45
66
|
protected readonly trackByName: (_: number, c: ClassRow) => string;
|
|
46
|
-
/**
|
|
67
|
+
/** Every class's row, rebuilt when an input changes rather than per check. */
|
|
47
68
|
protected rows: ClassRow[];
|
|
48
|
-
|
|
69
|
+
/** The rows matching {@link query}. */
|
|
70
|
+
protected shownRows: ClassRow[];
|
|
71
|
+
/** The search box's text. */
|
|
72
|
+
protected query: string;
|
|
73
|
+
constructor(el: ElementRef<HTMLElement>);
|
|
74
|
+
ngOnChanges(changes?: SimpleChanges): void;
|
|
75
|
+
protected onQuery(value: string): void;
|
|
76
|
+
/** Enter in the search box picks the first match. */
|
|
77
|
+
protected pickFirstMatch(): void;
|
|
78
|
+
private filter;
|
|
49
79
|
private count;
|
|
50
80
|
private canRemove;
|
|
51
81
|
protected rowTooltip(name: string): string;
|
|
52
82
|
protected removeTooltip(name: string): string;
|
|
53
83
|
static ɵfac: i0.ɵɵFactoryDeclaration<ClassesPanelComponent, never>;
|
|
54
|
-
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; }; "selectedCount": { "alias": "selectedCount"; "required": false; }; "defaultClassName": { "alias": "defaultClassName"; "required": false; }; }, { "pick": "pick"; "recolor": "recolor"; "remove": "remove"; "manage": "manage"; }, 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>;
|
|
55
85
|
}
|
|
56
86
|
export {};
|
|
@@ -5,20 +5,12 @@ import { ConfirmationService, MessageService } from 'primeng/api';
|
|
|
5
5
|
import { IRegionEditorApi } from '../contracts/region-editor-api.contract';
|
|
6
6
|
import { RegionPersistenceService } from './region-persistence.service';
|
|
7
7
|
import { ClassColorEdit } from './region-color-dialog/region-color-dialog.component';
|
|
8
|
+
import { ClassTreePick } from './class-tree/class-tree.component';
|
|
9
|
+
import type { RegionSourceView } from '../region-source/region-source';
|
|
10
|
+
import type { RegionClassNode } from '../region-source/region-tiles';
|
|
8
11
|
import { MaskExportService, MaskMode } from './mask-export.service';
|
|
9
12
|
import { PixelSize } from './region-metrics';
|
|
10
13
|
import * as i0 from "@angular/core";
|
|
11
|
-
/**
|
|
12
|
-
* The Region Editor (`<region-editor>`): the table of the active image's
|
|
13
|
-
* annotation regions with class presets, colours, labels, GeoJSON import /
|
|
14
|
-
* export / server save and mask export. Self-contained: it talks to the viewer
|
|
15
|
-
* only through {@link REGION_EDITOR_API} (and the host's REGION_IO_PORT), so it
|
|
16
|
-
* has no inputs or outputs.
|
|
17
|
-
*
|
|
18
|
-
* OnPush: template events re-render it; state that lands asynchronously (the
|
|
19
|
-
* API's region / selection / preset / image-meta streams, save and mask-export
|
|
20
|
-
* progress, file reads) marks it for check.
|
|
21
|
-
*/
|
|
22
14
|
export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
23
15
|
private regionApi;
|
|
24
16
|
private messageService;
|
|
@@ -26,6 +18,16 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
26
18
|
private persistence;
|
|
27
19
|
private maskExport;
|
|
28
20
|
private overlayPanel;
|
|
21
|
+
/**
|
|
22
|
+
* Whether the editor is on screen (its dialog open). Closed, it asks the region source nothing:
|
|
23
|
+
* its page of features, its class counts and, in a volume view, its classes' volumes are each a
|
|
24
|
+
* request over the whole set (a stack's every slice), and they competed with the volume's own
|
|
25
|
+
* slice loading for nothing anyone could see. Opened, it reads them again.
|
|
26
|
+
*/
|
|
27
|
+
set active(value: boolean);
|
|
28
|
+
private isActive;
|
|
29
|
+
/** The host's HttpClient: a served region set's requests go through it (its auth). */
|
|
30
|
+
private readonly http;
|
|
29
31
|
protected regions: Region[];
|
|
30
32
|
protected selectedRegions: Region[];
|
|
31
33
|
protected showShapeLabel: boolean;
|
|
@@ -62,6 +64,56 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
62
64
|
* avoids needing a unique id field. */
|
|
63
65
|
protected editingLabelRegions: Map<Region, string>;
|
|
64
66
|
protected showSaveAsDialog: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* The slice's region source (a large region set drawn by level of detail), or null. Its
|
|
69
|
+
* features are rows of the table after the regions — stand-ins until one is selected or edited,
|
|
70
|
+
* which takes it into the regions — and its classes count in the classes panel.
|
|
71
|
+
*/
|
|
72
|
+
protected sourceView: RegionSourceView | null;
|
|
73
|
+
/** Features still in the source (the table's rows after the regions). */
|
|
74
|
+
private sourceTotal;
|
|
75
|
+
/** Stand-in rows for the source features on the current page. */
|
|
76
|
+
private sourceRows;
|
|
77
|
+
/** Features per class still in the source. */
|
|
78
|
+
private sourceClassCounts;
|
|
79
|
+
/** The stand-in rows (rows of a source feature, not of a region). */
|
|
80
|
+
private readonly standIns;
|
|
81
|
+
private standInSeq;
|
|
82
|
+
/** Bumped per source refresh, so a late answer is dropped. */
|
|
83
|
+
private sourceRequest;
|
|
84
|
+
/** The classes the table's Class column offers: the presets and the region source's classes
|
|
85
|
+
* (a dropdown can only show a value that is one of its options). */
|
|
86
|
+
protected tablePresetSet: PresetSet;
|
|
87
|
+
/** Whether regions are drawn filled (the atlas look) rather than outlined. */
|
|
88
|
+
protected regionsFilled: boolean;
|
|
89
|
+
/** Whether a volume view is on screen (classes can then be shown in 3D). */
|
|
90
|
+
protected volumeView: boolean;
|
|
91
|
+
/** Whether the volume view's slice pane is wanted (one slice edited beside the 3D view). */
|
|
92
|
+
private slicePane;
|
|
93
|
+
/** Whether the volume view draws the regions through the volume (see toggleThroughVolume). */
|
|
94
|
+
protected regionsThroughVolume: boolean;
|
|
95
|
+
/** Classes shown in 3D in the volume view, each with the classes its surface covers. */
|
|
96
|
+
protected shown3d: Map<string, string[]>;
|
|
97
|
+
/** The classes of the class tree's pick (it and its subtree), as long as the pick holds. */
|
|
98
|
+
private pickedClasses;
|
|
99
|
+
/** The selected rows' classes, marked in the class lists. */
|
|
100
|
+
protected markedClasses: ReadonlySet<string>;
|
|
101
|
+
/** The surfaces highlighted in the volume view (their keys, joined). */
|
|
102
|
+
private highlighted3d;
|
|
103
|
+
/** The colour each shown surface was last drawn in. */
|
|
104
|
+
private colors3d;
|
|
105
|
+
/** Their names, for the class lists' toggles (a new set per change, for OnPush). */
|
|
106
|
+
protected shown3dNames: ReadonlySet<string>;
|
|
107
|
+
/** The classes hidden from view (their regions, source features and surfaces). */
|
|
108
|
+
protected hiddenClasses: ReadonlySet<string>;
|
|
109
|
+
/** Whether a region set's class hierarchy is shown as a tree (rather than the class list). */
|
|
110
|
+
protected classTreeView: boolean;
|
|
111
|
+
/** The class picked last in the class tree. */
|
|
112
|
+
protected pickedClass: string | null;
|
|
113
|
+
/** Regions per class (the regions' and the source's), for the class tree. */
|
|
114
|
+
protected treeCounts: Map<string, number>;
|
|
115
|
+
/** A class's colour, for the class tree: a new function per colour change, so the tree repaints. */
|
|
116
|
+
protected treeColor: (name: string) => string;
|
|
65
117
|
protected saveAsFilename: string;
|
|
66
118
|
protected saveAsFileExists: boolean;
|
|
67
119
|
/** True while a GeoJSON persist is serializing/uploading — drives the dialog's
|
|
@@ -115,6 +167,52 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
115
167
|
* intensity-profile lines the editor never sees).
|
|
116
168
|
*/
|
|
117
169
|
protected onSelectionChanged(): void;
|
|
170
|
+
/** Whether the slice has a region source: it then has regions to save even with an empty table. */
|
|
171
|
+
protected get hasRegionSource(): boolean;
|
|
172
|
+
/** Rows in the table: the regions, then the features still in the region source. */
|
|
173
|
+
protected get tableTotal(): number;
|
|
174
|
+
/** The class hierarchy of the slice's region source, when it has one (the classes as a tree). */
|
|
175
|
+
protected get classHierarchy(): RegionClassNode[] | null;
|
|
176
|
+
/** Whether `row` is a region-source feature's stand-in rather than a region. */
|
|
177
|
+
protected isSourceRow(row: Region): boolean;
|
|
178
|
+
private sourceIds;
|
|
179
|
+
/** A table row for a source feature: no geometry until it is taken. */
|
|
180
|
+
private standIn;
|
|
181
|
+
/**
|
|
182
|
+
* Re-read the source part of the table (the stand-ins on the current page, the count) and the
|
|
183
|
+
* source's class counts. The page holds regions first, so its source rows start at
|
|
184
|
+
* `max(first, regions)` − regions.
|
|
185
|
+
*/
|
|
186
|
+
private refreshSource;
|
|
187
|
+
/** Take a source row's feature into the regions, then run `then` on the region it became. */
|
|
188
|
+
private takeThen;
|
|
189
|
+
/** Toggle the filled (atlas) look: each region filled in its colour, labels inside. */
|
|
190
|
+
/** In a volume view: the regions drawn through the volume, or hidden behind what it shows. */
|
|
191
|
+
protected toggleThroughVolume(): void;
|
|
192
|
+
protected toggleFill(): void;
|
|
193
|
+
/**
|
|
194
|
+
* Show or hide a class in the volume view as a 3D reconstruction — a tree node with every class
|
|
195
|
+
* under it, as one surface in its colour.
|
|
196
|
+
*/
|
|
197
|
+
protected toggleClass3d(name: string, classes?: string[]): void;
|
|
198
|
+
/** Hide (or show again) these classes' regions, wherever they are drawn. */
|
|
199
|
+
protected setClassesHidden(classes: readonly string[], hidden: boolean): void;
|
|
200
|
+
/** The surfaces shown in 3D, in their classes' colours now. */
|
|
201
|
+
private groups3d;
|
|
202
|
+
/** The classes selected now: the class tree's pick (with its subtree) and the selected rows'. */
|
|
203
|
+
private selectedClassNames;
|
|
204
|
+
/**
|
|
205
|
+
* Highlight, in the volume view, the surfaces holding a selected class (focus + context: they
|
|
206
|
+
* turn near opaque, the others fade), and mark the selected rows' classes in the class lists.
|
|
207
|
+
*/
|
|
208
|
+
private updateSelectionHighlight;
|
|
209
|
+
/** A surface clicked in the volume view: pick its class as the tree would; beside them, clear. */
|
|
210
|
+
private onPicked3d;
|
|
211
|
+
/** A class colour changed (its swatch, or Manage): repaint the surfaces shown in 3D whose colour it changed. */
|
|
212
|
+
private recolor3d;
|
|
213
|
+
private show3d;
|
|
214
|
+
/** Pick a class in the class tree: select its regions and its subclasses', the source's taken. */
|
|
215
|
+
protected pickClasses(pick: ClassTreePick): Promise<void>;
|
|
118
216
|
/**
|
|
119
217
|
* Rows for regions coming from the visualizer: neutral `Region`s with bounds,
|
|
120
218
|
* colour and label already populated. A region without a colour is shown with
|
|
@@ -154,16 +252,26 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
154
252
|
/** The current page of the table. Memoized on (regions, first, rows), so
|
|
155
253
|
* change detection doesn't hand p-table a new array every tick (RT-20). */
|
|
156
254
|
protected get pagedRegions(): Region[];
|
|
255
|
+
/** In a volume view, each class's volume over the whole stack, for the table (null: areas). */
|
|
256
|
+
protected tableVolumes: ReadonlyMap<string, number | null> | null;
|
|
257
|
+
/** Bumped when the regions change, so a volume computed before is dropped. */
|
|
258
|
+
private volumeRequest;
|
|
259
|
+
/** Compute the volumes of the classes on the table's page that are not known yet. */
|
|
260
|
+
private requestVolumes;
|
|
261
|
+
/** The regions changed (or the view did): forget the volumes and compute the page's again. */
|
|
262
|
+
private resetVolumes;
|
|
157
263
|
private _pageKey;
|
|
158
264
|
private _page;
|
|
159
265
|
protected onPageChange(event: {
|
|
160
266
|
first?: number;
|
|
161
267
|
rows?: number;
|
|
162
268
|
}): void;
|
|
163
|
-
/** Select every region in the table (and highlight them on the diagram). */
|
|
164
|
-
protected selectAllRegions(): void
|
|
269
|
+
/** Select every region in the table (and highlight them on the diagram), the source's taken. */
|
|
270
|
+
protected selectAllRegions(): Promise<void>;
|
|
165
271
|
protected deleteSelectedRegions(): void;
|
|
166
272
|
protected clearAllRegions(): void;
|
|
273
|
+
/** Delete every feature still in the slice's region source (with "Delete all regions"). */
|
|
274
|
+
private deleteAllSourceFeatures;
|
|
167
275
|
protected deleteRegion(shapeIdx: number): void;
|
|
168
276
|
private clampPaginatorFirst;
|
|
169
277
|
protected changeShowShapeLabel(showLabel: boolean): void;
|
|
@@ -198,9 +306,15 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
198
306
|
* labels are ignored. (jit-ui#70)
|
|
199
307
|
*/
|
|
200
308
|
private syncClassesFromRegions;
|
|
201
|
-
/**
|
|
309
|
+
/**
|
|
310
|
+
* Whether the classes count every slice of the stack: in a volume view (the whole stack on
|
|
311
|
+
* screen), unless its slice pane shows one slice. The table lists the slice's regions anyway.
|
|
312
|
+
*/
|
|
313
|
+
private get stackCounts();
|
|
314
|
+
/** Rebuild the per-class region counts shown in the panel (the stack's, see stackCounts). */
|
|
202
315
|
private recomputeClassCounts;
|
|
203
|
-
/** Rebuild the panel's display order — most-used classes first, then by name.
|
|
316
|
+
/** Rebuild the panel's display order — most-used classes first, then by name. A class only
|
|
317
|
+
* the region source has is listed too, in its colour. */
|
|
204
318
|
private updateDisplayClasses;
|
|
205
319
|
/** Number of regions currently using a class (keyed by the active match mode). */
|
|
206
320
|
protected classCount(name: string): number;
|
|
@@ -236,8 +350,36 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
236
350
|
protected importPresets(event: Event): void;
|
|
237
351
|
/** Validate and apply an imported annotation-classes JSON file. */
|
|
238
352
|
private applyImportedPresets;
|
|
353
|
+
/** The files chosen in the import inputs: one GeoJSON, a label volume with its ontology, or a
|
|
354
|
+
* folder of per-slice GeoJSON files. */
|
|
239
355
|
protected importRois(event: Event): void;
|
|
240
|
-
/**
|
|
356
|
+
/** Whether the host can pick regions on its server ("Import regions from server"). */
|
|
357
|
+
protected get canImportFromServer(): boolean;
|
|
358
|
+
/** An import from the server is in flight. */
|
|
359
|
+
protected importing: boolean;
|
|
360
|
+
/** "Import regions from server": the host picks files or a served region set; they import as chosen files do. */
|
|
361
|
+
protected importFromServer(): void;
|
|
362
|
+
/**
|
|
363
|
+
* Import `files` (see planRegionImport): one GeoJSON file as before; a label volume as one
|
|
364
|
+
* region source per slice, traced from it the first time the slice is shown, its classes named
|
|
365
|
+
* (and treed) by the ontology chosen with it; a folder as one source per slice file. Either
|
|
366
|
+
* replaces the regions and sources of every slice.
|
|
367
|
+
*/
|
|
368
|
+
private importRegionFiles;
|
|
369
|
+
/** A region set the host's server serves (jit-service's /regions/{id}/), read through its HttpClient. */
|
|
370
|
+
private importServedRegionSet;
|
|
371
|
+
/** An import that finished after another image was shown (or another import began): dropped. */
|
|
372
|
+
private importStale;
|
|
373
|
+
/** The table and selection after the regions were replaced by imported sources. */
|
|
374
|
+
private afterSourceImport;
|
|
375
|
+
/** Warn when an imported volume's slices are not the image's size: its outlines would not fit. */
|
|
376
|
+
private warnIfSizeDiffers;
|
|
377
|
+
private importFailed;
|
|
378
|
+
/**
|
|
379
|
+
* Replace the regions with an imported GeoJSON file's, and the slice's region source with them.
|
|
380
|
+
* A large file becomes the slice's region source instead (drawn by level of detail; listed above
|
|
381
|
+
* the table), the table emptied.
|
|
382
|
+
*/
|
|
241
383
|
private applyImportedRois;
|
|
242
384
|
/** Regions to serialize on save/export (every slice for a combined z-stack). */
|
|
243
385
|
private regionsForSave;
|
|
@@ -268,5 +410,5 @@ export declare class RegionEditorComponent implements OnInit, OnDestroy {
|
|
|
268
410
|
protected cancelSaveAs(): void;
|
|
269
411
|
private toast;
|
|
270
412
|
static ɵfac: i0.ɵɵFactoryDeclaration<RegionEditorComponent, never>;
|
|
271
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<RegionEditorComponent, "region-editor", never, {}, {}, never, never, true, never>;
|
|
413
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RegionEditorComponent, "region-editor", never, { "active": { "alias": "active"; "required": false; }; }, {}, never, never, true, never>;
|
|
272
414
|
}
|
|
@@ -4,6 +4,8 @@ import { IImageMetadata } from '../contracts/image.contract';
|
|
|
4
4
|
export interface PixelSize {
|
|
5
5
|
mppX?: number;
|
|
6
6
|
mppY?: number;
|
|
7
|
+
/** Spacing between slices (µm), when the stack declares it. */
|
|
8
|
+
mppZ?: number;
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
11
|
* Choose the physical pixel size for area display from the image meta. The
|
|
@@ -24,3 +26,9 @@ export declare function regionAreaPx(region: Pick<Region, 'bounds'>): number;
|
|
|
24
26
|
* otherwise px². Empty for a degenerate (non-positive) area.
|
|
25
27
|
*/
|
|
26
28
|
export declare function formatArea(px: number, mpp?: PixelSize): string;
|
|
29
|
+
/**
|
|
30
|
+
* A volume in px² × slices for display: mm³ (three significant digits) from 0.001 mm³, µm³ below,
|
|
31
|
+
* when the pixel size and the slice spacing are known; otherwise voxels (one pixel by one slice).
|
|
32
|
+
* Empty for a non-positive volume.
|
|
33
|
+
*/
|
|
34
|
+
export declare function formatVolume(pxSlices: number, mpp?: PixelSize): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Observable } from 'rxjs';
|
|
2
2
|
import { Region } from '../models/region';
|
|
3
3
|
import { IRegionEditorApi } from '../contracts/region-editor-api.contract';
|
|
4
|
-
import { RegionIoPort } from '../contracts/ports/region-io.port';
|
|
4
|
+
import { RegionIoPort, ServerRegionPick } from '../contracts/ports/region-io.port';
|
|
5
5
|
import * as i0 from "@angular/core";
|
|
6
6
|
/** One slice-file's serialized regions (folder stack, jit-ui#93). */
|
|
7
7
|
export interface SliceGeoJson {
|
|
@@ -43,8 +43,14 @@ export declare class RegionPersistenceService {
|
|
|
43
43
|
* "does not exist" and later checks keep working.
|
|
44
44
|
*/
|
|
45
45
|
fileExists(names: Observable<string>): Observable<boolean>;
|
|
46
|
-
/**
|
|
47
|
-
|
|
46
|
+
/**
|
|
47
|
+
* `regions` as GeoJSON, merged with the image's region source when it has one (the source's
|
|
48
|
+
* features that were not taken or deleted, then `regions`); `slice` names a folder stack's
|
|
49
|
+
* slice.
|
|
50
|
+
*/
|
|
51
|
+
serialize(regions: Region[], slice?: number): Promise<string>;
|
|
52
|
+
/** Download `regions` (with the region source behind them) as a GeoJSON file named `filename`. */
|
|
53
|
+
download(regions: Region[], filename: string): Promise<void>;
|
|
48
54
|
/**
|
|
49
55
|
* Save `regions()` to the host as `filename`. Serializing is deferred one
|
|
50
56
|
* tick (so a progress indicator paints before a large synchronous
|
|
@@ -56,9 +62,15 @@ export declare class RegionPersistenceService {
|
|
|
56
62
|
* A folder stack's regions as one geojson per slice-file (jit-ui#93), each
|
|
57
63
|
* serialized on the default plane (z=0): every slice-file is one plane, and
|
|
58
64
|
* the loader re-derives the slice index from the file's position. Slices
|
|
59
|
-
* cleared since load are included (empty) so their file is overwritten
|
|
65
|
+
* cleared since load are included (empty) so their file is overwritten, and so are slices
|
|
66
|
+
* whose region source lost features; a slice with a region source keeps the features still
|
|
67
|
+
* in it.
|
|
60
68
|
*/
|
|
61
|
-
sliceGeoJsons(): SliceGeoJson[]
|
|
69
|
+
sliceGeoJsons(): Promise<SliceGeoJson[]>;
|
|
70
|
+
/** Whether the host can pick regions on its server (see RegionIoPort.pickServerRegions). */
|
|
71
|
+
canPickServerRegions(): boolean;
|
|
72
|
+
/** Let the user pick regions on the host's server; null when cancelled or unsupported. */
|
|
73
|
+
pickServerRegions(): Observable<ServerRegionPick | null>;
|
|
62
74
|
/** Write per-slice geojsons through the host port. */
|
|
63
75
|
saveSlices(slices: SliceGeoJson[]): Observable<void>;
|
|
64
76
|
/** Read the file chosen in a file input's change event as text, then call
|
|
@@ -40,6 +40,11 @@ export declare class RegionTableComponent implements OnChanges {
|
|
|
40
40
|
defaultColor: string;
|
|
41
41
|
/** Pixel size for the area column. */
|
|
42
42
|
mpp: PixelSize;
|
|
43
|
+
/**
|
|
44
|
+
* In a volume view, each class's volume over the whole stack (px² × slices; null while it is
|
|
45
|
+
* computed): the column shows the row's class volume instead of its area. Null: areas.
|
|
46
|
+
*/
|
|
47
|
+
volumes: ReadonlyMap<string, number | null> | null;
|
|
43
48
|
/** Rows whose label is being edited → the typed draft. A new map per start/stop. */
|
|
44
49
|
labelDrafts: Map<Region, string>;
|
|
45
50
|
/** A row's pencil: start editing its label. */
|
|
@@ -63,13 +68,14 @@ export declare class RegionTableComponent implements OnChanges {
|
|
|
63
68
|
deleteRow: EventEmitter<number>;
|
|
64
69
|
/** The paginator moved or changed its page size. */
|
|
65
70
|
pageChange: EventEmitter<RegionPage>;
|
|
66
|
-
/** Per row of {@link page}: its class swatch colour and formatted area
|
|
67
|
-
* an input changes instead of per check (the area walks the region's geometry). */
|
|
71
|
+
/** Per row of {@link page}: its class swatch colour and formatted area (or class volume),
|
|
72
|
+
* derived when an input changes instead of per check (the area walks the region's geometry). */
|
|
68
73
|
protected rowView: Map<Region, {
|
|
69
74
|
color: string;
|
|
70
|
-
|
|
75
|
+
measure: string;
|
|
71
76
|
}>;
|
|
72
77
|
ngOnChanges(): void;
|
|
78
|
+
private measure;
|
|
73
79
|
private classColor;
|
|
74
80
|
private area;
|
|
75
81
|
protected startEdit(region: Region, event: Event): void;
|
|
@@ -79,5 +85,5 @@ export declare class RegionTableComponent implements OnChanges {
|
|
|
79
85
|
rows?: number;
|
|
80
86
|
}): void;
|
|
81
87
|
static ɵfac: i0.ɵɵFactoryDeclaration<RegionTableComponent, never>;
|
|
82
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<RegionTableComponent, "region-table", never, { "page": { "alias": "page"; "required": false; }; "total": { "alias": "total"; "required": false; }; "first": { "alias": "first"; "required": false; }; "rows": { "alias": "rows"; "required": false; }; "rowsPerPageOptions": { "alias": "rowsPerPageOptions"; "required": false; }; "metaKey": { "alias": "metaKey"; "required": false; }; "selection": { "alias": "selection"; "required": false; }; "presetSet": { "alias": "presetSet"; "required": false; }; "defaultColor": { "alias": "defaultColor"; "required": false; }; "mpp": { "alias": "mpp"; "required": false; }; "labelDrafts": { "alias": "labelDrafts"; "required": false; }; }, { "selectionChange": "selectionChange"; "rowSelect": "rowSelect"; "labelEditStart": "labelEditStart"; "labelDraftChange": "labelDraftChange"; "labelEditStop": "labelEditStop"; "classPick": "classPick"; "deleteRow": "deleteRow"; "pageChange": "pageChange"; }, never, never, true, never>;
|
|
88
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RegionTableComponent, "region-table", never, { "page": { "alias": "page"; "required": false; }; "total": { "alias": "total"; "required": false; }; "first": { "alias": "first"; "required": false; }; "rows": { "alias": "rows"; "required": false; }; "rowsPerPageOptions": { "alias": "rowsPerPageOptions"; "required": false; }; "metaKey": { "alias": "metaKey"; "required": false; }; "selection": { "alias": "selection"; "required": false; }; "presetSet": { "alias": "presetSet"; "required": false; }; "defaultColor": { "alias": "defaultColor"; "required": false; }; "mpp": { "alias": "mpp"; "required": false; }; "volumes": { "alias": "volumes"; "required": false; }; "labelDrafts": { "alias": "labelDrafts"; "required": false; }; }, { "selectionChange": "selectionChange"; "rowSelect": "rowSelect"; "labelEditStart": "labelEditStart"; "labelDraftChange": "labelDraftChange"; "labelEditStop": "labelEditStop"; "classPick": "classPick"; "deleteRow": "deleteRow"; "pageChange": "pageChange"; }, never, never, true, never>;
|
|
83
89
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { RegionClassNode, RegionSourceStyle } from '../region-source/region-tiles';
|
|
2
|
+
import type { LabelVolume } from './label-volume';
|
|
3
|
+
/**
|
|
4
|
+
* The classes of a label volume's values: their names and colours and, when the volume comes
|
|
5
|
+
* with an ontology, their tree. Pure.
|
|
6
|
+
*/
|
|
7
|
+
export interface LabelClasses {
|
|
8
|
+
/** The class of label `value` (> 0); one without an ontology entry is `label <value>`. */
|
|
9
|
+
classOf(value: number): {
|
|
10
|
+
name: string;
|
|
11
|
+
color: string;
|
|
12
|
+
title?: string;
|
|
13
|
+
};
|
|
14
|
+
/** The class tree, when the ontology has one. */
|
|
15
|
+
hierarchy?: RegionClassNode[];
|
|
16
|
+
/** How the set wants to be drawn (an atlas's filled look), when the ontology says. */
|
|
17
|
+
style?: RegionSourceStyle;
|
|
18
|
+
}
|
|
19
|
+
/** The look the Allen atlas region sets carry (see the brain-atlas example's GeoJSON). */
|
|
20
|
+
export declare const ATLAS_STYLE: RegionSourceStyle;
|
|
21
|
+
/**
|
|
22
|
+
* The classes of a label volume from `ontology`, a parsed JSON document:
|
|
23
|
+
*
|
|
24
|
+
* - an **Allen structure graph** (`structure_graph_1.json`: `{ msg: [root] }`, or a node or a
|
|
25
|
+
* list of nodes with `id`, `acronym`, `name`, `color_hex_triplet`, `graph_order` and
|
|
26
|
+
* `children`): label = structure id, class = acronym, its tree the ontology's, drawn as the
|
|
27
|
+
* atlas region sets are;
|
|
28
|
+
* - a **region set description** (a `regionset.json`: `classHierarchy`, optional `style`), whose
|
|
29
|
+
* classes name their label as `value` (or `id`), or with a `labels` map of value → class name.
|
|
30
|
+
*
|
|
31
|
+
* Without one (or with another document), each label is its own class `label <value>`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function labelClasses(ontology?: unknown): LabelClasses;
|
|
34
|
+
/**
|
|
35
|
+
* Slice `z` of `volume` as a GeoJSON FeatureCollection string: one feature per label on the
|
|
36
|
+
* slice, its every piece (with holes) traced along pixel edges, in image pixels with y down;
|
|
37
|
+
* classified by `classes`, which also give the collection its class tree and style.
|
|
38
|
+
*/
|
|
39
|
+
export declare function labelSliceGeoJson(volume: LabelVolume, z: number, classes: LabelClasses): string;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A label volume (a NIfTI-1 `.nii` / `.nii.gz` or a NRRD `.nrrd` of integer structure ids, an
|
|
3
|
+
* atlas annotation say) read in the browser, sliced as the server opens the matching image:
|
|
4
|
+
*
|
|
5
|
+
* - **NRRD**: a 3D volume is cut along its FIRST axis, each section its third axis wide and its
|
|
6
|
+
* second axis high, as jit-service opens a NRRD volume (`AtlasNrrdReader`: the Allen CCF's 528
|
|
7
|
+
* coronal sections of 456 × 320, anterior first). A 2D NRRD is one slice.
|
|
8
|
+
* - **NIfTI**: along its third axis, each slice its first axis wide and its second axis high, as
|
|
9
|
+
* Bio-Formats reads one (no row flip).
|
|
10
|
+
*
|
|
11
|
+
* Only what label volumes use: a single file (NRRD with attached data, NIfTI-1 `n+1`), integer
|
|
12
|
+
* or integer-valued float samples, either byte order, raw or gzip. Anything else throws rather
|
|
13
|
+
* than be read approximately. Pure: usable from workers.
|
|
14
|
+
*/
|
|
15
|
+
/** A label volume, sliced (see the module comment). Label 0 is background. */
|
|
16
|
+
export interface LabelVolume {
|
|
17
|
+
format: 'nrrd' | 'nifti';
|
|
18
|
+
/** A slice's width and height, in voxels (the image's pixels). */
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
/** Number of slices. */
|
|
22
|
+
slices: number;
|
|
23
|
+
/** Slice `z`'s labels, row-major (`height` rows of `width`). */
|
|
24
|
+
sliceLabels(z: number): Uint32Array;
|
|
25
|
+
}
|
|
26
|
+
/** Decompress gzip bytes (default: the platform's `DecompressionStream`). */
|
|
27
|
+
export type Gunzip = (bytes: Uint8Array) => Promise<Uint8Array>;
|
|
28
|
+
/** Whether a file name is a label volume this reads. */
|
|
29
|
+
export declare function isLabelVolumeName(name: string): boolean;
|
|
30
|
+
/** Read the label volume in `bytes`, named `name` (`.nrrd`, `.nii`, `.nii.gz`). */
|
|
31
|
+
export declare function readLabelVolume(name: string, bytes: Uint8Array, gunzip?: Gunzip): Promise<LabelVolume>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** A file to import regions from: one the user chose, or one the host's server sent. */
|
|
2
|
+
export interface RegionImportFile {
|
|
3
|
+
name: string;
|
|
4
|
+
text(): Promise<string>;
|
|
5
|
+
bytes(): Promise<Uint8Array>;
|
|
6
|
+
}
|
|
7
|
+
/** A file's contents as the host may hand them over (see `ServerRegionPick`). */
|
|
8
|
+
export type RegionImportData = Blob | ArrayBuffer | Uint8Array | string;
|
|
9
|
+
/** `data`, named `name`, as an import file. A `File`'s own name is used when `name` is omitted. */
|
|
10
|
+
export declare function importFile(data: RegionImportData, name?: string): RegionImportFile;
|
|
11
|
+
/** What a set of chosen files imports as. */
|
|
12
|
+
export type RegionImportPlan =
|
|
13
|
+
/** A label volume, its classes named by an ontology (or a region set description) beside it. */
|
|
14
|
+
{
|
|
15
|
+
kind: 'volume';
|
|
16
|
+
volume: RegionImportFile;
|
|
17
|
+
ontology: RegionImportFile | null;
|
|
18
|
+
}
|
|
19
|
+
/** A folder of per-slice region files, in slice order, with the set's `regionset.json`. */
|
|
20
|
+
| {
|
|
21
|
+
kind: 'folder';
|
|
22
|
+
slices: RegionImportFile[];
|
|
23
|
+
regionSet: RegionImportFile | null;
|
|
24
|
+
}
|
|
25
|
+
/** One region file. */
|
|
26
|
+
| {
|
|
27
|
+
kind: 'single';
|
|
28
|
+
file: RegionImportFile;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* What `files` import as: a label volume (`.nii`, `.nii.gz`, `.nrrd`) with the ontology JSON chosen
|
|
32
|
+
* with it (a `regionset.json`, else an Allen `structure_graph*.json`, else any `.json`); several
|
|
33
|
+
* region files (a folder of per-slice `.geojson`, in natural name order, its `regionset.json`
|
|
34
|
+
* apart); or one region file (`.geojson` or `.json`). Null when none of them is one.
|
|
35
|
+
*/
|
|
36
|
+
export declare function planRegionImport(files: readonly RegionImportFile[]): RegionImportPlan | null;
|
|
37
|
+
/** "slice_2" before "slice_10": runs of digits compared as numbers. */
|
|
38
|
+
export declare function naturalCompare(a: string, b: string): number;
|
|
39
|
+
/**
|
|
40
|
+
* A folder slice's GeoJSON with the set's class tree and style (its `regionset.json`) as the
|
|
41
|
+
* collection's own members, unless the file has its own: what a served folder's slice carries.
|
|
42
|
+
*/
|
|
43
|
+
export declare function folderSliceGeoJson(file: RegionImportFile, regionSet: {
|
|
44
|
+
classHierarchy?: unknown;
|
|
45
|
+
style?: unknown;
|
|
46
|
+
} | null): Promise<string>;
|
|
@@ -70,16 +70,17 @@ export interface ContainsOptions {
|
|
|
70
70
|
*/
|
|
71
71
|
export declare function regionContains(region: Pick<Region, 'bounds'>, x: number, y: number, opts?: ContainsOptions): boolean;
|
|
72
72
|
/** Index of the topmost (last) region containing (x, y), or -1. */
|
|
73
|
-
export declare function topmostRegionAt
|
|
74
|
-
skip?: (r:
|
|
73
|
+
export declare function topmostRegionAt<R extends Pick<Region, 'bounds'>>(regions: ReadonlyArray<R>, x: number, y: number, opts?: ContainsOptions & {
|
|
74
|
+
skip?: (r: R) => boolean;
|
|
75
75
|
}): number;
|
|
76
76
|
/**
|
|
77
77
|
* Indices of every region whose bounding box intersects the world box
|
|
78
78
|
* [x0,y0]–[x1,y1] (rubber-band selection). `skipProfiles` leaves out
|
|
79
|
-
* intensity-profile lines.
|
|
79
|
+
* intensity-profile lines, `skip` any other region.
|
|
80
80
|
*/
|
|
81
81
|
export declare function regionsInRect(regions: ReadonlyArray<Region>, x0: number, y0: number, x1: number, y1: number, opts?: {
|
|
82
82
|
skipProfiles?: boolean;
|
|
83
|
+
skip?: (r: Region) => boolean;
|
|
83
84
|
}): number[];
|
|
84
85
|
/** The handle offsets a bézier ring is drawn with; absent arrays fall back to the default. */
|
|
85
86
|
export interface RingHandleOffsets {
|