@fideus-labs/fidnii 0.1.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/LICENSE.txt +9 -0
- package/README.md +180 -0
- package/dist/BufferManager.d.ts +86 -0
- package/dist/BufferManager.d.ts.map +1 -0
- package/dist/BufferManager.js +146 -0
- package/dist/BufferManager.js.map +1 -0
- package/dist/ClipPlanes.d.ts +180 -0
- package/dist/ClipPlanes.d.ts.map +1 -0
- package/dist/ClipPlanes.js +513 -0
- package/dist/ClipPlanes.js.map +1 -0
- package/dist/OMEZarrNVImage.d.ts +545 -0
- package/dist/OMEZarrNVImage.d.ts.map +1 -0
- package/dist/OMEZarrNVImage.js +1799 -0
- package/dist/OMEZarrNVImage.js.map +1 -0
- package/dist/RegionCoalescer.d.ts +75 -0
- package/dist/RegionCoalescer.d.ts.map +1 -0
- package/dist/RegionCoalescer.js +151 -0
- package/dist/RegionCoalescer.js.map +1 -0
- package/dist/ResolutionSelector.d.ts +88 -0
- package/dist/ResolutionSelector.d.ts.map +1 -0
- package/dist/ResolutionSelector.js +224 -0
- package/dist/ResolutionSelector.js.map +1 -0
- package/dist/ViewportBounds.d.ts +50 -0
- package/dist/ViewportBounds.d.ts.map +1 -0
- package/dist/ViewportBounds.js +325 -0
- package/dist/ViewportBounds.js.map +1 -0
- package/dist/events.d.ts +122 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +12 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +273 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +126 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/affine.d.ts +72 -0
- package/dist/utils/affine.d.ts.map +1 -0
- package/dist/utils/affine.js +173 -0
- package/dist/utils/affine.js.map +1 -0
- package/dist/utils/coordinates.d.ts +80 -0
- package/dist/utils/coordinates.d.ts.map +1 -0
- package/dist/utils/coordinates.js +207 -0
- package/dist/utils/coordinates.js.map +1 -0
- package/package.json +61 -0
- package/src/BufferManager.ts +176 -0
- package/src/ClipPlanes.ts +640 -0
- package/src/OMEZarrNVImage.ts +2286 -0
- package/src/RegionCoalescer.ts +217 -0
- package/src/ResolutionSelector.ts +325 -0
- package/src/ViewportBounds.ts +369 -0
- package/src/events.ts +146 -0
- package/src/index.ts +153 -0
- package/src/types.ts +429 -0
- package/src/utils/affine.ts +218 -0
- package/src/utils/coordinates.ts +271 -0
|
@@ -0,0 +1,545 @@
|
|
|
1
|
+
import { NVImage } from "@niivue/niivue";
|
|
2
|
+
import type { Niivue } from "@niivue/niivue";
|
|
3
|
+
import type { Multiscales, Omero } from "@fideus-labs/ngff-zarr";
|
|
4
|
+
import type { ClipPlane, ClipPlanes, OMEZarrNVImageOptions, SlabBufferState, SlabSliceType, VolumeBounds } from "./types.js";
|
|
5
|
+
import { OMEZarrNVImageEventListener, OMEZarrNVImageEventListenerOptions, OMEZarrNVImageEventMap, PopulateTrigger } from "./events.js";
|
|
6
|
+
/**
|
|
7
|
+
* OMEZarrNVImage extends NVImage to support rendering OME-Zarr images in NiiVue.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Progressive loading: quick preview from lowest resolution, then target resolution
|
|
11
|
+
* - Arbitrary clip planes defined by point + normal (up to 6)
|
|
12
|
+
* - Dynamic buffer sizing to match fetched data exactly (no upsampling)
|
|
13
|
+
* - Request coalescing for efficient chunk fetching
|
|
14
|
+
* - Automatic metadata updates to reflect OME-Zarr coordinate transforms
|
|
15
|
+
*/
|
|
16
|
+
export declare class OMEZarrNVImage extends NVImage {
|
|
17
|
+
/** The OME-Zarr multiscales data */
|
|
18
|
+
readonly multiscales: Multiscales;
|
|
19
|
+
/** Maximum number of pixels to use */
|
|
20
|
+
readonly maxPixels: number;
|
|
21
|
+
/** Reference to NiiVue instance */
|
|
22
|
+
private readonly niivue;
|
|
23
|
+
/** Buffer manager for dynamically-sized pixel data */
|
|
24
|
+
private readonly bufferManager;
|
|
25
|
+
/** Region coalescer for efficient chunk fetching */
|
|
26
|
+
private readonly coalescer;
|
|
27
|
+
/** Decoded-chunk cache shared across 3D and 2D slab loads. */
|
|
28
|
+
private readonly _chunkCache;
|
|
29
|
+
/** Current clip planes in world space */
|
|
30
|
+
private _clipPlanes;
|
|
31
|
+
/** Target resolution level index (based on maxPixels) */
|
|
32
|
+
private targetLevelIndex;
|
|
33
|
+
/** Current resolution level index during progressive loading */
|
|
34
|
+
private currentLevelIndex;
|
|
35
|
+
/** True if currently loading data */
|
|
36
|
+
private isLoading;
|
|
37
|
+
/** Data type of the volume */
|
|
38
|
+
private readonly dtype;
|
|
39
|
+
/** Full volume bounds in world space */
|
|
40
|
+
private readonly _volumeBounds;
|
|
41
|
+
/** Current buffer bounds in world space (may differ from full volume when clipped) */
|
|
42
|
+
private _currentBufferBounds;
|
|
43
|
+
/** Previous clip plane change handler (to restore later) */
|
|
44
|
+
private previousOnClipPlaneChange?;
|
|
45
|
+
/** Debounce delay for clip plane updates (ms) */
|
|
46
|
+
private readonly clipPlaneDebounceMs;
|
|
47
|
+
/** Timeout handle for debounced clip plane refetch */
|
|
48
|
+
private clipPlaneRefetchTimeout;
|
|
49
|
+
/** Previous clip planes state for direction comparison */
|
|
50
|
+
private _previousClipPlanes;
|
|
51
|
+
/** Previous pixel count at current resolution (for direction comparison) */
|
|
52
|
+
private _previousPixelCount;
|
|
53
|
+
/** Cached/computed OMERO metadata for visualization (cal_min/cal_max) */
|
|
54
|
+
private _omero;
|
|
55
|
+
/** Active channel index for OMERO window selection (default: 0) */
|
|
56
|
+
private _activeChannel;
|
|
57
|
+
/** Resolution level at which OMERO was last computed (to track recomputation) */
|
|
58
|
+
private _omeroComputedForLevel;
|
|
59
|
+
/** Internal EventTarget for event dispatching (composition pattern) */
|
|
60
|
+
private readonly _eventTarget;
|
|
61
|
+
/** Pending populate request (latest wins - replaces any previous pending) */
|
|
62
|
+
private _pendingPopulateRequest;
|
|
63
|
+
/** Current populate trigger (set at start of populateVolume, used by events) */
|
|
64
|
+
private _currentPopulateTrigger;
|
|
65
|
+
/** Attached Niivue instances and their state */
|
|
66
|
+
private _attachedNiivues;
|
|
67
|
+
/** Per-slice-type slab buffers (lazily created) */
|
|
68
|
+
private _slabBuffers;
|
|
69
|
+
/** Debounce timeout for slab reload per slice type */
|
|
70
|
+
private _slabReloadTimeouts;
|
|
71
|
+
/** Whether viewport-aware resolution selection is enabled */
|
|
72
|
+
private _viewportAwareEnabled;
|
|
73
|
+
/**
|
|
74
|
+
* Viewport bounds for the 3D render volume (union of all RENDER/MULTIPLANAR NVs).
|
|
75
|
+
* Null = full volume, no viewport constraint.
|
|
76
|
+
*/
|
|
77
|
+
private _viewportBounds3D;
|
|
78
|
+
/**
|
|
79
|
+
* Per-slab viewport bounds (from the NV instance that displays each slab).
|
|
80
|
+
* Null entry = full volume, no viewport constraint for that slab.
|
|
81
|
+
*/
|
|
82
|
+
private _viewportBoundsPerSlab;
|
|
83
|
+
/** Timeout handle for debounced viewport update */
|
|
84
|
+
private _viewportUpdateTimeout;
|
|
85
|
+
/** Per-slab AbortController to cancel in-flight progressive loads */
|
|
86
|
+
private _slabAbortControllers;
|
|
87
|
+
/** Maximum 3D render zoom level for scroll-wheel zoom */
|
|
88
|
+
private readonly _max3DZoom;
|
|
89
|
+
/** Minimum 3D render zoom level for scroll-wheel zoom */
|
|
90
|
+
private readonly _min3DZoom;
|
|
91
|
+
/**
|
|
92
|
+
* Debounce delay for viewport-aware reloads (ms).
|
|
93
|
+
* Higher than clip plane debounce to avoid excessive reloads during
|
|
94
|
+
* continuous zoom/pan interactions.
|
|
95
|
+
*/
|
|
96
|
+
private static readonly VIEWPORT_DEBOUNCE_MS;
|
|
97
|
+
/**
|
|
98
|
+
* Private constructor. Use OMEZarrNVImage.create() for instantiation.
|
|
99
|
+
*/
|
|
100
|
+
private constructor();
|
|
101
|
+
/**
|
|
102
|
+
* Create a new OMEZarrNVImage instance.
|
|
103
|
+
*
|
|
104
|
+
* By default, the image is automatically added to NiiVue and progressive
|
|
105
|
+
* loading starts immediately (fire-and-forget). This enables progressive
|
|
106
|
+
* rendering where each resolution level is displayed as it loads.
|
|
107
|
+
*
|
|
108
|
+
* Set `autoLoad: false` for manual control over when loading starts.
|
|
109
|
+
* Listen to 'populateComplete' event to know when loading finishes.
|
|
110
|
+
*
|
|
111
|
+
* @param options - Options including multiscales, niivue reference, and optional maxPixels
|
|
112
|
+
* @returns Promise resolving to the OMEZarrNVImage instance
|
|
113
|
+
*/
|
|
114
|
+
static create(options: OMEZarrNVImageOptions): Promise<OMEZarrNVImage>;
|
|
115
|
+
/**
|
|
116
|
+
* Initialize NVImage properties with placeholder values.
|
|
117
|
+
* Actual values will be set by loadResolutionLevel() after first data fetch.
|
|
118
|
+
*/
|
|
119
|
+
private initializeNVImageProperties;
|
|
120
|
+
/**
|
|
121
|
+
* Populate the volume with data.
|
|
122
|
+
*
|
|
123
|
+
* Loading strategy:
|
|
124
|
+
* 1. Load lowest resolution first for quick preview (unless skipPreview is true)
|
|
125
|
+
* 2. Jump directly to target resolution (skip intermediate levels)
|
|
126
|
+
*
|
|
127
|
+
* If called while already loading, the request is queued. Only the latest
|
|
128
|
+
* queued request is kept (latest wins). When a queued request is replaced,
|
|
129
|
+
* a `loadingSkipped` event is emitted.
|
|
130
|
+
*
|
|
131
|
+
* @param skipPreview - If true, skip the preview load (used for clip plane updates)
|
|
132
|
+
* @param trigger - What triggered this population (default: 'initial')
|
|
133
|
+
*/
|
|
134
|
+
populateVolume(skipPreview?: boolean, trigger?: PopulateTrigger): Promise<void>;
|
|
135
|
+
/**
|
|
136
|
+
* Process any pending populate request after current load completes.
|
|
137
|
+
* If no pending request, emits populateComplete.
|
|
138
|
+
*/
|
|
139
|
+
private handlePendingPopulateRequest;
|
|
140
|
+
/**
|
|
141
|
+
* Load data at a specific resolution level.
|
|
142
|
+
*
|
|
143
|
+
* With dynamic buffer sizing:
|
|
144
|
+
* 1. Fetch data for the aligned region
|
|
145
|
+
* 2. Resize buffer to match fetched data exactly (no upsampling)
|
|
146
|
+
* 3. Update header with correct dimensions and voxel sizes
|
|
147
|
+
* 4. Refresh NiiVue
|
|
148
|
+
*
|
|
149
|
+
* @param levelIndex - Resolution level index
|
|
150
|
+
* @param requesterId - ID for request coalescing
|
|
151
|
+
*/
|
|
152
|
+
private loadResolutionLevel;
|
|
153
|
+
/**
|
|
154
|
+
* Update NVImage header for a loaded region.
|
|
155
|
+
*
|
|
156
|
+
* With dynamic buffer sizing, the buffer dimensions equal the fetched dimensions.
|
|
157
|
+
* We set pixDims directly from the resolution level's voxel size (no upsampling correction).
|
|
158
|
+
* The affine translation is adjusted to account for the region offset.
|
|
159
|
+
*
|
|
160
|
+
* @param ngffImage - The NgffImage at the current resolution level
|
|
161
|
+
* @param region - The chunk-aligned region that was loaded
|
|
162
|
+
* @param fetchedShape - The shape of the fetched data [z, y, x]
|
|
163
|
+
*/
|
|
164
|
+
private updateHeaderForRegion;
|
|
165
|
+
/**
|
|
166
|
+
* Update NiiVue clip planes from current _clipPlanes.
|
|
167
|
+
*
|
|
168
|
+
* Clip planes are converted relative to the CURRENT BUFFER bounds,
|
|
169
|
+
* not the full volume bounds. This is because NiiVue's shader works
|
|
170
|
+
* in texture coordinates of the currently loaded data.
|
|
171
|
+
*/
|
|
172
|
+
private updateNiivueClipPlanes;
|
|
173
|
+
/**
|
|
174
|
+
* Apply OMERO window settings to NIfTI header cal_min/cal_max.
|
|
175
|
+
*
|
|
176
|
+
* Uses the active channel's window (start/end preferred over min/max).
|
|
177
|
+
* This sets the display intensity range for NiiVue rendering.
|
|
178
|
+
*/
|
|
179
|
+
private applyOmeroToHeader;
|
|
180
|
+
/**
|
|
181
|
+
* Ensure OMERO metadata is available and applied.
|
|
182
|
+
*
|
|
183
|
+
* Strategy:
|
|
184
|
+
* - If OMERO exists in file metadata, use it (first time only)
|
|
185
|
+
* - If NOT present, compute dynamically:
|
|
186
|
+
* - Compute at preview (lowest) resolution for quick initial display
|
|
187
|
+
* - Recompute at target resolution for more accurate values
|
|
188
|
+
* - Keep target values for consistency on subsequent clip plane changes
|
|
189
|
+
*
|
|
190
|
+
* @param ngffImage - The NgffImage at the current resolution level
|
|
191
|
+
* @param levelIndex - The resolution level index
|
|
192
|
+
*/
|
|
193
|
+
private ensureOmeroMetadata;
|
|
194
|
+
/**
|
|
195
|
+
* Handle clip plane change from NiiVue.
|
|
196
|
+
* This is called when the user interacts with clip planes in NiiVue.
|
|
197
|
+
*/
|
|
198
|
+
private onNiivueClipPlaneChange;
|
|
199
|
+
/**
|
|
200
|
+
* Set clip planes.
|
|
201
|
+
*
|
|
202
|
+
* Visual clipping is updated immediately for responsive feedback.
|
|
203
|
+
* Data refetch is debounced to avoid excessive reloading during slider interaction.
|
|
204
|
+
* Resolution changes are direction-aware: reducing volume may increase resolution,
|
|
205
|
+
* increasing volume may decrease resolution.
|
|
206
|
+
*
|
|
207
|
+
* @param planes - Array of clip planes (max 6). Empty array = full volume visible.
|
|
208
|
+
* @throws Error if more than 6 planes provided or if planes are invalid
|
|
209
|
+
*/
|
|
210
|
+
setClipPlanes(planes: ClipPlanes): void;
|
|
211
|
+
/**
|
|
212
|
+
* Handle clip plane update after debounce delay.
|
|
213
|
+
* Implements direction-aware resolution selection.
|
|
214
|
+
*
|
|
215
|
+
* Only triggers a refetch when the resolution level needs to change.
|
|
216
|
+
* Visual clipping is handled by NiiVue clip planes (updated immediately in setClipPlanes).
|
|
217
|
+
*/
|
|
218
|
+
private handleDebouncedClipPlaneUpdate;
|
|
219
|
+
/**
|
|
220
|
+
* Calculate pixel count for a chunk-aligned region.
|
|
221
|
+
*/
|
|
222
|
+
private calculateAlignedPixelCount;
|
|
223
|
+
/**
|
|
224
|
+
* Create a deep copy of clip planes array.
|
|
225
|
+
*/
|
|
226
|
+
private copyClipPlanes;
|
|
227
|
+
/**
|
|
228
|
+
* Get current clip planes.
|
|
229
|
+
*
|
|
230
|
+
* @returns Copy of current clip planes array
|
|
231
|
+
*/
|
|
232
|
+
getClipPlanes(): ClipPlanes;
|
|
233
|
+
/**
|
|
234
|
+
* Add a single clip plane.
|
|
235
|
+
*
|
|
236
|
+
* @param plane - Clip plane to add
|
|
237
|
+
* @throws Error if already at maximum (6) clip planes
|
|
238
|
+
*/
|
|
239
|
+
addClipPlane(plane: ClipPlane): void;
|
|
240
|
+
/**
|
|
241
|
+
* Remove a clip plane by index.
|
|
242
|
+
*
|
|
243
|
+
* @param index - Index of plane to remove
|
|
244
|
+
* @throws Error if index is out of bounds
|
|
245
|
+
*/
|
|
246
|
+
removeClipPlane(index: number): void;
|
|
247
|
+
/**
|
|
248
|
+
* Clear all clip planes (show full volume).
|
|
249
|
+
*/
|
|
250
|
+
clearClipPlanes(): void;
|
|
251
|
+
/**
|
|
252
|
+
* Get the current resolution level index.
|
|
253
|
+
*/
|
|
254
|
+
getCurrentLevelIndex(): number;
|
|
255
|
+
/**
|
|
256
|
+
* Get the target resolution level index.
|
|
257
|
+
*/
|
|
258
|
+
getTargetLevelIndex(): number;
|
|
259
|
+
/**
|
|
260
|
+
* Get the number of resolution levels.
|
|
261
|
+
*/
|
|
262
|
+
getNumLevels(): number;
|
|
263
|
+
/**
|
|
264
|
+
* Get the volume bounds in world space.
|
|
265
|
+
*/
|
|
266
|
+
getVolumeBounds(): VolumeBounds;
|
|
267
|
+
/**
|
|
268
|
+
* Enable or disable viewport-aware resolution selection.
|
|
269
|
+
*
|
|
270
|
+
* When enabled, pan/zoom/rotation interactions are monitored and the fetch
|
|
271
|
+
* region is constrained to the visible viewport area. This allows higher
|
|
272
|
+
* resolution within the same `maxPixels` budget when zoomed in.
|
|
273
|
+
*
|
|
274
|
+
* @param enabled - Whether to enable viewport-aware resolution
|
|
275
|
+
*/
|
|
276
|
+
setViewportAware(enabled: boolean): void;
|
|
277
|
+
/**
|
|
278
|
+
* Get whether viewport-aware resolution selection is enabled.
|
|
279
|
+
*/
|
|
280
|
+
get viewportAware(): boolean;
|
|
281
|
+
/**
|
|
282
|
+
* Get the current 3D viewport bounds (null if viewport-aware is disabled
|
|
283
|
+
* or no viewport constraint is active).
|
|
284
|
+
*/
|
|
285
|
+
getViewportBounds(): VolumeBounds | null;
|
|
286
|
+
/**
|
|
287
|
+
* Hook viewport events (onMouseUp, onZoom3DChange, wheel) on a NV instance.
|
|
288
|
+
*/
|
|
289
|
+
private _hookViewportEvents;
|
|
290
|
+
/**
|
|
291
|
+
* Unhook viewport events from a NV instance.
|
|
292
|
+
*/
|
|
293
|
+
private _unhookViewportEvents;
|
|
294
|
+
/**
|
|
295
|
+
* Install a capturing-phase wheel listener on the NV canvas that overrides
|
|
296
|
+
* NiiVue's hardcoded 3D render zoom clamp ([0.5, 2.0]).
|
|
297
|
+
*
|
|
298
|
+
* The listener intercepts scroll events over 3D render tiles and applies
|
|
299
|
+
* zoom via `nv.setScale()` (which has no internal clamp), using the
|
|
300
|
+
* configurable `_min3DZoom` / `_max3DZoom` bounds instead.
|
|
301
|
+
*
|
|
302
|
+
* Clip-plane scrolling is preserved: when a clip plane is active
|
|
303
|
+
* (depth < 1.8), the event passes through to NiiVue's native handler.
|
|
304
|
+
*/
|
|
305
|
+
private _hookZoomOverride;
|
|
306
|
+
/**
|
|
307
|
+
* Remove the 3D zoom override wheel listener from a NV instance.
|
|
308
|
+
*/
|
|
309
|
+
private _unhookZoomOverride;
|
|
310
|
+
/**
|
|
311
|
+
* Called at the end of any viewport interaction (mouse up, touch end,
|
|
312
|
+
* zoom change, scroll wheel). Debounces the viewport bounds recomputation.
|
|
313
|
+
*/
|
|
314
|
+
private _handleViewportInteractionEnd;
|
|
315
|
+
/**
|
|
316
|
+
* Recompute viewport bounds from all attached NV instances and trigger
|
|
317
|
+
* resolution reselection if bounds changed significantly.
|
|
318
|
+
*/
|
|
319
|
+
private _recomputeViewportBounds;
|
|
320
|
+
/**
|
|
321
|
+
* Reload all active slabs (for all slice types that have buffers).
|
|
322
|
+
*/
|
|
323
|
+
private _reloadAllSlabs;
|
|
324
|
+
/**
|
|
325
|
+
* Get whether the image is currently loading.
|
|
326
|
+
*/
|
|
327
|
+
getIsLoading(): boolean;
|
|
328
|
+
/**
|
|
329
|
+
* Wait for all pending fetches to complete.
|
|
330
|
+
*/
|
|
331
|
+
waitForIdle(): Promise<void>;
|
|
332
|
+
/**
|
|
333
|
+
* Get OMERO metadata (if available).
|
|
334
|
+
*
|
|
335
|
+
* Returns the existing OMERO metadata from the OME-Zarr file,
|
|
336
|
+
* or the computed OMERO metadata if none was present in the file.
|
|
337
|
+
*
|
|
338
|
+
* OMERO metadata includes per-channel visualization parameters:
|
|
339
|
+
* - window.min/max: The actual data range
|
|
340
|
+
* - window.start/end: The display window (based on quantiles)
|
|
341
|
+
* - color: Hex color for the channel
|
|
342
|
+
* - label: Channel name
|
|
343
|
+
*
|
|
344
|
+
* @returns OMERO metadata or undefined if not yet loaded/computed
|
|
345
|
+
*/
|
|
346
|
+
getOmero(): Omero | undefined;
|
|
347
|
+
/**
|
|
348
|
+
* Get the active channel index used for OMERO window selection.
|
|
349
|
+
*
|
|
350
|
+
* For multi-channel images, this determines which channel's
|
|
351
|
+
* cal_min/cal_max values are applied to the NiiVue display.
|
|
352
|
+
*
|
|
353
|
+
* @returns Current active channel index (0-based)
|
|
354
|
+
*/
|
|
355
|
+
getActiveChannel(): number;
|
|
356
|
+
/**
|
|
357
|
+
* Set the active channel for OMERO window selection.
|
|
358
|
+
*
|
|
359
|
+
* For multi-channel images, this determines which channel's
|
|
360
|
+
* window (cal_min/cal_max) values are applied to the NiiVue display.
|
|
361
|
+
*
|
|
362
|
+
* Changing the active channel immediately updates the display intensity
|
|
363
|
+
* range and refreshes the NiiVue rendering.
|
|
364
|
+
*
|
|
365
|
+
* @param index - Channel index (0-based)
|
|
366
|
+
* @throws Error if no OMERO metadata is available
|
|
367
|
+
* @throws Error if index is out of range
|
|
368
|
+
*
|
|
369
|
+
* @example
|
|
370
|
+
* ```typescript
|
|
371
|
+
* // Get number of channels
|
|
372
|
+
* const omero = image.getOmero();
|
|
373
|
+
* if (omero) {
|
|
374
|
+
* console.log(`${omero.channels.length} channels available`);
|
|
375
|
+
* // Switch to channel 1
|
|
376
|
+
* image.setActiveChannel(1);
|
|
377
|
+
* }
|
|
378
|
+
* ```
|
|
379
|
+
*/
|
|
380
|
+
setActiveChannel(index: number): void;
|
|
381
|
+
/**
|
|
382
|
+
* Attach a Niivue instance for slice-type-aware rendering.
|
|
383
|
+
*
|
|
384
|
+
* The image auto-detects the NV's current slice type and hooks into
|
|
385
|
+
* `onOptsChange` to track mode changes and `onLocationChange` to track
|
|
386
|
+
* crosshair/slice position changes.
|
|
387
|
+
*
|
|
388
|
+
* When the NV is in a 2D slice mode (Axial, Coronal, Sagittal), the image
|
|
389
|
+
* loads a slab (one chunk thick in the orthogonal direction) at the current
|
|
390
|
+
* slice position, using a 2D pixel budget for resolution selection.
|
|
391
|
+
*
|
|
392
|
+
* @param nv - The Niivue instance to attach
|
|
393
|
+
*/
|
|
394
|
+
attachNiivue(nv: Niivue): void;
|
|
395
|
+
/**
|
|
396
|
+
* Detach a Niivue instance, restoring its original callbacks.
|
|
397
|
+
*
|
|
398
|
+
* @param nv - The Niivue instance to detach
|
|
399
|
+
*/
|
|
400
|
+
detachNiivue(nv: Niivue): void;
|
|
401
|
+
/**
|
|
402
|
+
* Get the slab buffer state for a given slice type, if it exists.
|
|
403
|
+
* Useful for testing and inspection.
|
|
404
|
+
*
|
|
405
|
+
* @param sliceType - The slice type to query
|
|
406
|
+
* @returns The slab buffer state, or undefined if not yet created
|
|
407
|
+
*/
|
|
408
|
+
getSlabBufferState(sliceType: SlabSliceType): SlabBufferState | undefined;
|
|
409
|
+
/**
|
|
410
|
+
* Get all attached Niivue instances.
|
|
411
|
+
*/
|
|
412
|
+
getAttachedNiivues(): Niivue[];
|
|
413
|
+
/**
|
|
414
|
+
* Detect the current slice type of a Niivue instance.
|
|
415
|
+
*/
|
|
416
|
+
private _detectSliceType;
|
|
417
|
+
/**
|
|
418
|
+
* Check if a slice type is one of the 2D slab types.
|
|
419
|
+
*/
|
|
420
|
+
private _isSlabSliceType;
|
|
421
|
+
/**
|
|
422
|
+
* Get the orthogonal axis index for a slab slice type.
|
|
423
|
+
* Returns index in [z, y, x] order:
|
|
424
|
+
* - Axial: slicing through Z → orthogonal axis = 0 (Z)
|
|
425
|
+
* - Coronal: slicing through Y → orthogonal axis = 1 (Y)
|
|
426
|
+
* - Sagittal: slicing through X → orthogonal axis = 2 (X)
|
|
427
|
+
*/
|
|
428
|
+
private _getOrthogonalAxis;
|
|
429
|
+
/**
|
|
430
|
+
* Handle a slice type change on an attached Niivue instance.
|
|
431
|
+
*/
|
|
432
|
+
private _handleSliceTypeChange;
|
|
433
|
+
/**
|
|
434
|
+
* Handle location (crosshair) change on an attached Niivue instance.
|
|
435
|
+
* Checks if the current slice position has moved outside the loaded slab.
|
|
436
|
+
*/
|
|
437
|
+
private _handleLocationChange;
|
|
438
|
+
/**
|
|
439
|
+
* Debounced slab reload to avoid excessive reloading during scrolling.
|
|
440
|
+
*/
|
|
441
|
+
private _debouncedSlabReload;
|
|
442
|
+
/**
|
|
443
|
+
* Ensure a slab buffer exists and is loaded for the given NV + slice type.
|
|
444
|
+
* If needed, creates the slab buffer and triggers an initial load.
|
|
445
|
+
*/
|
|
446
|
+
private _ensureSlabForNiivue;
|
|
447
|
+
/**
|
|
448
|
+
* Create a new slab buffer state for a slice type.
|
|
449
|
+
*/
|
|
450
|
+
private _createSlabBuffer;
|
|
451
|
+
/**
|
|
452
|
+
* Swap the NVImage in a Niivue instance's volume list.
|
|
453
|
+
* Removes any existing volumes from this OMEZarrNVImage and adds the target.
|
|
454
|
+
*/
|
|
455
|
+
private _swapVolumeInNiivue;
|
|
456
|
+
/**
|
|
457
|
+
* Load a slab for a 2D slice type at the given world position.
|
|
458
|
+
*
|
|
459
|
+
* The slab is one chunk thick in the orthogonal direction and uses
|
|
460
|
+
* the full in-plane extent (respecting clip planes).
|
|
461
|
+
*
|
|
462
|
+
* Loading follows a progressive strategy: preview (lowest res) then target.
|
|
463
|
+
* For viewport-triggered reloads, progressive rendering is skipped and
|
|
464
|
+
* only the target level is loaded (the user already sees the previous
|
|
465
|
+
* resolution, so a single jump is smoother).
|
|
466
|
+
*
|
|
467
|
+
* If a load is already in progress, the request is queued (latest-wins)
|
|
468
|
+
* and automatically drained when the current load finishes.
|
|
469
|
+
*/
|
|
470
|
+
private _loadSlab;
|
|
471
|
+
/**
|
|
472
|
+
* Process any pending slab reload request after the current load completes.
|
|
473
|
+
* Mirrors populateVolume's handlePendingPopulateRequest pattern.
|
|
474
|
+
*/
|
|
475
|
+
private _handlePendingSlabReload;
|
|
476
|
+
/**
|
|
477
|
+
* Load slab data at a specific resolution level.
|
|
478
|
+
*/
|
|
479
|
+
private _loadSlabAtLevel;
|
|
480
|
+
/**
|
|
481
|
+
* Update NVImage header for a slab region.
|
|
482
|
+
*/
|
|
483
|
+
private _updateSlabHeader;
|
|
484
|
+
/**
|
|
485
|
+
* Apply OMERO metadata to a slab NVImage header.
|
|
486
|
+
*/
|
|
487
|
+
private _applyOmeroToSlabHeader;
|
|
488
|
+
/**
|
|
489
|
+
* Widen the display intensity range if the actual data exceeds the current
|
|
490
|
+
* cal_min/cal_max window (typically set from OMERO metadata).
|
|
491
|
+
*
|
|
492
|
+
* OMERO window settings may have been computed at a lower resolution where
|
|
493
|
+
* downsampling averaged out extreme voxels. At higher resolutions, individual
|
|
494
|
+
* bright/dark voxels can exceed the OMERO range, causing clipping artifacts
|
|
495
|
+
* (e.g., "banding" where bright structures clip to solid white).
|
|
496
|
+
*
|
|
497
|
+
* Widens cal_min/cal_max to global_min/global_max (actual data extremes at
|
|
498
|
+
* the current resolution level) so no data is clipped. The hdr.cal_min/
|
|
499
|
+
* cal_max values are NOT modified — they preserve the original OMERO values
|
|
500
|
+
* for reuse on subsequent slab reloads.
|
|
501
|
+
*
|
|
502
|
+
* Must be called AFTER updateGLVolume() so that calMinMax() has computed
|
|
503
|
+
* global_min/global_max from the actual slab data.
|
|
504
|
+
*
|
|
505
|
+
* @returns true if the display range was widened
|
|
506
|
+
*/
|
|
507
|
+
private _widenCalRangeIfNeeded;
|
|
508
|
+
/**
|
|
509
|
+
* Add a type-safe event listener for OMEZarrNVImage events.
|
|
510
|
+
*
|
|
511
|
+
* @param type - Event type name
|
|
512
|
+
* @param listener - Event listener function
|
|
513
|
+
* @param options - Standard addEventListener options (once, signal, etc.)
|
|
514
|
+
*
|
|
515
|
+
* @example
|
|
516
|
+
* ```typescript
|
|
517
|
+
* image.addEventListener('resolutionChange', (event) => {
|
|
518
|
+
* console.log('New level:', event.detail.currentLevel);
|
|
519
|
+
* });
|
|
520
|
+
*
|
|
521
|
+
* // One-time listener
|
|
522
|
+
* image.addEventListener('loadingComplete', handler, { once: true });
|
|
523
|
+
*
|
|
524
|
+
* // With AbortController
|
|
525
|
+
* const controller = new AbortController();
|
|
526
|
+
* image.addEventListener('loadingStart', handler, { signal: controller.signal });
|
|
527
|
+
* controller.abort(); // removes the listener
|
|
528
|
+
* ```
|
|
529
|
+
*/
|
|
530
|
+
addEventListener<K extends keyof OMEZarrNVImageEventMap>(type: K, listener: OMEZarrNVImageEventListener<K>, options?: OMEZarrNVImageEventListenerOptions): void;
|
|
531
|
+
/**
|
|
532
|
+
* Remove a type-safe event listener for OMEZarrNVImage events.
|
|
533
|
+
*
|
|
534
|
+
* @param type - Event type name
|
|
535
|
+
* @param listener - Event listener function to remove
|
|
536
|
+
* @param options - Standard removeEventListener options
|
|
537
|
+
*/
|
|
538
|
+
removeEventListener<K extends keyof OMEZarrNVImageEventMap>(type: K, listener: OMEZarrNVImageEventListener<K>, options?: OMEZarrNVImageEventListenerOptions): void;
|
|
539
|
+
/**
|
|
540
|
+
* Internal helper to emit events.
|
|
541
|
+
* Catches and logs any errors from event listeners to prevent breaking execution.
|
|
542
|
+
*/
|
|
543
|
+
private _emitEvent;
|
|
544
|
+
}
|
|
545
|
+
//# sourceMappingURL=OMEZarrNVImage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OMEZarrNVImage.d.ts","sourceRoot":"","sources":["../src/OMEZarrNVImage.ts"],"names":[],"mappings":"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"}
|