@aics/vole-core 3.12.4
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 +26 -0
- package/README.md +119 -0
- package/es/Atlas2DSlice.js +224 -0
- package/es/Channel.js +264 -0
- package/es/FileSaver.js +31 -0
- package/es/FusedChannelData.js +192 -0
- package/es/Histogram.js +250 -0
- package/es/ImageInfo.js +127 -0
- package/es/Light.js +74 -0
- package/es/Lut.js +500 -0
- package/es/MarchingCubes.js +507 -0
- package/es/MeshVolume.js +334 -0
- package/es/NaiveSurfaceNets.js +251 -0
- package/es/PathTracedVolume.js +482 -0
- package/es/RayMarchedAtlasVolume.js +250 -0
- package/es/RenderToBuffer.js +31 -0
- package/es/ThreeJsPanel.js +633 -0
- package/es/Timing.js +28 -0
- package/es/TrackballControls.js +538 -0
- package/es/View3d.js +848 -0
- package/es/Volume.js +352 -0
- package/es/VolumeCache.js +161 -0
- package/es/VolumeDims.js +16 -0
- package/es/VolumeDrawable.js +702 -0
- package/es/VolumeMaker.js +101 -0
- package/es/VolumeRenderImpl.js +1 -0
- package/es/VolumeRenderSettings.js +203 -0
- package/es/constants/basicShaders.js +29 -0
- package/es/constants/colors.js +59 -0
- package/es/constants/denoiseShader.js +43 -0
- package/es/constants/lights.js +42 -0
- package/es/constants/materials.js +85 -0
- package/es/constants/pathtraceOutputShader.js +13 -0
- package/es/constants/scaleBarSVG.js +21 -0
- package/es/constants/time.js +34 -0
- package/es/constants/volumePTshader.js +153 -0
- package/es/constants/volumeRayMarchShader.js +123 -0
- package/es/constants/volumeSliceShader.js +115 -0
- package/es/index.js +21 -0
- package/es/loaders/IVolumeLoader.js +131 -0
- package/es/loaders/JsonImageInfoLoader.js +255 -0
- package/es/loaders/OmeZarrLoader.js +495 -0
- package/es/loaders/OpenCellLoader.js +65 -0
- package/es/loaders/RawArrayLoader.js +89 -0
- package/es/loaders/TiffLoader.js +219 -0
- package/es/loaders/VolumeLoadError.js +44 -0
- package/es/loaders/VolumeLoaderUtils.js +221 -0
- package/es/loaders/index.js +40 -0
- package/es/loaders/zarr_utils/ChunkPrefetchIterator.js +143 -0
- package/es/loaders/zarr_utils/WrappedStore.js +51 -0
- package/es/loaders/zarr_utils/types.js +24 -0
- package/es/loaders/zarr_utils/utils.js +225 -0
- package/es/loaders/zarr_utils/validation.js +49 -0
- package/es/test/ChunkPrefetchIterator.test.js +208 -0
- package/es/test/RequestQueue.test.js +442 -0
- package/es/test/SubscribableRequestQueue.test.js +244 -0
- package/es/test/VolumeCache.test.js +118 -0
- package/es/test/VolumeRenderSettings.test.js +71 -0
- package/es/test/lut.test.js +671 -0
- package/es/test/num_utils.test.js +140 -0
- package/es/test/volume.test.js +98 -0
- package/es/test/zarr_utils.test.js +358 -0
- package/es/types/Atlas2DSlice.d.ts +41 -0
- package/es/types/Channel.d.ts +44 -0
- package/es/types/FileSaver.d.ts +6 -0
- package/es/types/FusedChannelData.d.ts +26 -0
- package/es/types/Histogram.d.ts +57 -0
- package/es/types/ImageInfo.d.ts +87 -0
- package/es/types/Light.d.ts +27 -0
- package/es/types/Lut.d.ts +67 -0
- package/es/types/MarchingCubes.d.ts +53 -0
- package/es/types/MeshVolume.d.ts +40 -0
- package/es/types/NaiveSurfaceNets.d.ts +11 -0
- package/es/types/PathTracedVolume.d.ts +65 -0
- package/es/types/RayMarchedAtlasVolume.d.ts +41 -0
- package/es/types/RenderToBuffer.d.ts +17 -0
- package/es/types/ThreeJsPanel.d.ts +107 -0
- package/es/types/Timing.d.ts +11 -0
- package/es/types/TrackballControls.d.ts +51 -0
- package/es/types/View3d.d.ts +357 -0
- package/es/types/Volume.d.ts +152 -0
- package/es/types/VolumeCache.d.ts +43 -0
- package/es/types/VolumeDims.d.ts +28 -0
- package/es/types/VolumeDrawable.d.ts +108 -0
- package/es/types/VolumeMaker.d.ts +49 -0
- package/es/types/VolumeRenderImpl.d.ts +22 -0
- package/es/types/VolumeRenderSettings.d.ts +98 -0
- package/es/types/constants/basicShaders.d.ts +4 -0
- package/es/types/constants/colors.d.ts +2 -0
- package/es/types/constants/denoiseShader.d.ts +40 -0
- package/es/types/constants/lights.d.ts +38 -0
- package/es/types/constants/materials.d.ts +20 -0
- package/es/types/constants/pathtraceOutputShader.d.ts +11 -0
- package/es/types/constants/scaleBarSVG.d.ts +2 -0
- package/es/types/constants/time.d.ts +19 -0
- package/es/types/constants/volumePTshader.d.ts +137 -0
- package/es/types/constants/volumeRayMarchShader.d.ts +117 -0
- package/es/types/constants/volumeSliceShader.d.ts +109 -0
- package/es/types/glsl.d.js +0 -0
- package/es/types/index.d.ts +28 -0
- package/es/types/loaders/IVolumeLoader.d.ts +113 -0
- package/es/types/loaders/JsonImageInfoLoader.d.ts +80 -0
- package/es/types/loaders/OmeZarrLoader.d.ts +87 -0
- package/es/types/loaders/OpenCellLoader.d.ts +9 -0
- package/es/types/loaders/RawArrayLoader.d.ts +33 -0
- package/es/types/loaders/TiffLoader.d.ts +45 -0
- package/es/types/loaders/VolumeLoadError.d.ts +18 -0
- package/es/types/loaders/VolumeLoaderUtils.d.ts +38 -0
- package/es/types/loaders/index.d.ts +22 -0
- package/es/types/loaders/zarr_utils/ChunkPrefetchIterator.d.ts +22 -0
- package/es/types/loaders/zarr_utils/WrappedStore.d.ts +24 -0
- package/es/types/loaders/zarr_utils/types.d.ts +94 -0
- package/es/types/loaders/zarr_utils/utils.d.ts +23 -0
- package/es/types/loaders/zarr_utils/validation.d.ts +7 -0
- package/es/types/test/ChunkPrefetchIterator.test.d.ts +1 -0
- package/es/types/test/RequestQueue.test.d.ts +1 -0
- package/es/types/test/SubscribableRequestQueue.test.d.ts +1 -0
- package/es/types/test/VolumeCache.test.d.ts +1 -0
- package/es/types/test/VolumeRenderSettings.test.d.ts +1 -0
- package/es/types/test/lut.test.d.ts +1 -0
- package/es/types/test/num_utils.test.d.ts +1 -0
- package/es/types/test/volume.test.d.ts +1 -0
- package/es/types/test/zarr_utils.test.d.ts +1 -0
- package/es/types/types.d.ts +115 -0
- package/es/types/utils/RequestQueue.d.ts +112 -0
- package/es/types/utils/SubscribableRequestQueue.d.ts +52 -0
- package/es/types/utils/num_utils.d.ts +43 -0
- package/es/types/workers/VolumeLoaderContext.d.ts +106 -0
- package/es/types/workers/types.d.ts +101 -0
- package/es/types/workers/util.d.ts +3 -0
- package/es/types.js +75 -0
- package/es/typings.d.js +0 -0
- package/es/utils/RequestQueue.js +267 -0
- package/es/utils/SubscribableRequestQueue.js +187 -0
- package/es/utils/num_utils.js +231 -0
- package/es/workers/FetchTiffWorker.js +153 -0
- package/es/workers/VolumeLoadWorker.js +129 -0
- package/es/workers/VolumeLoaderContext.js +271 -0
- package/es/workers/types.js +41 -0
- package/es/workers/util.js +8 -0
- package/package.json +83 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import * as zarr from "@zarrita/core";
|
|
2
|
+
import type WrappedStore from "./WrappedStore.js";
|
|
3
|
+
import type SubscribableRequestQueue from "../../utils/SubscribableRequestQueue.js";
|
|
4
|
+
export type TCZYX<T> = [T, T, T, T, T];
|
|
5
|
+
export type SubscriberId = ReturnType<SubscribableRequestQueue["addSubscriber"]>;
|
|
6
|
+
/**
|
|
7
|
+
* Directions in which to move outward from the loaded set of chunks while prefetching.
|
|
8
|
+
*
|
|
9
|
+
* Ordered in pairs of opposite directions both because that's a sensible order in which to prefetch for our purposes,
|
|
10
|
+
* and because it lets us treat the least significant bit as the sign. So `direction >> 1` gives the index of the
|
|
11
|
+
* direction in TZYX-ordered arrays, and `direction & 1` gives the sign of the direction (e.g. positive vs negative Z).
|
|
12
|
+
*/
|
|
13
|
+
export declare const enum PrefetchDirection {
|
|
14
|
+
T_MINUS = 0,
|
|
15
|
+
T_PLUS = 1,
|
|
16
|
+
Z_MINUS = 2,
|
|
17
|
+
Z_PLUS = 3,
|
|
18
|
+
Y_MINUS = 4,
|
|
19
|
+
Y_PLUS = 5,
|
|
20
|
+
X_MINUS = 6,
|
|
21
|
+
X_PLUS = 7
|
|
22
|
+
}
|
|
23
|
+
export type OMECoordinateTransformation = {
|
|
24
|
+
type: "identity";
|
|
25
|
+
} | {
|
|
26
|
+
type: "translation";
|
|
27
|
+
translation: number[];
|
|
28
|
+
} | {
|
|
29
|
+
type: "scale";
|
|
30
|
+
scale: number[];
|
|
31
|
+
} | {
|
|
32
|
+
type: "translation" | "scale";
|
|
33
|
+
path: string;
|
|
34
|
+
};
|
|
35
|
+
export type OMEAxis = {
|
|
36
|
+
name: string;
|
|
37
|
+
type?: string;
|
|
38
|
+
unit?: string;
|
|
39
|
+
};
|
|
40
|
+
export type OMEDataset = {
|
|
41
|
+
path: string;
|
|
42
|
+
coordinateTransformations?: OMECoordinateTransformation[];
|
|
43
|
+
};
|
|
44
|
+
/** https://ngff.openmicroscopy.org/latest/#multiscale-md */
|
|
45
|
+
export type OMEMultiscale = {
|
|
46
|
+
version?: string;
|
|
47
|
+
name?: string;
|
|
48
|
+
axes: OMEAxis[];
|
|
49
|
+
datasets: OMEDataset[];
|
|
50
|
+
coordinateTransformations?: OMECoordinateTransformation[];
|
|
51
|
+
type?: string;
|
|
52
|
+
metadata?: Record<string, unknown>;
|
|
53
|
+
};
|
|
54
|
+
/** https://ngff.openmicroscopy.org/latest/#omero-md */
|
|
55
|
+
export type OmeroTransitionalMetadata = {
|
|
56
|
+
id: number;
|
|
57
|
+
name: string;
|
|
58
|
+
version: string;
|
|
59
|
+
channels: {
|
|
60
|
+
active: boolean;
|
|
61
|
+
coefficient: number;
|
|
62
|
+
color: string;
|
|
63
|
+
family: string;
|
|
64
|
+
inverted: boolean;
|
|
65
|
+
label: string;
|
|
66
|
+
window: {
|
|
67
|
+
end: number;
|
|
68
|
+
max: number;
|
|
69
|
+
min: number;
|
|
70
|
+
start: number;
|
|
71
|
+
};
|
|
72
|
+
}[];
|
|
73
|
+
};
|
|
74
|
+
export type OMEZarrMetadata = {
|
|
75
|
+
multiscales: OMEMultiscale[];
|
|
76
|
+
omero: OmeroTransitionalMetadata;
|
|
77
|
+
};
|
|
78
|
+
export type NumericZarrArray = zarr.Array<zarr.NumberDataType, WrappedStore<RequestInit>>;
|
|
79
|
+
/** A record with everything we need to access and use a single remote source of multiscale OME-Zarr data. */
|
|
80
|
+
export type ZarrSource = {
|
|
81
|
+
/** Representations of each scale level in this zarr. We pick one and pass it to zarrita to load data. */
|
|
82
|
+
scaleLevels: NumericZarrArray[];
|
|
83
|
+
/**
|
|
84
|
+
* Zarr dimensions may be ordered in many ways or missing altogether (e.g. TCXYZ, TYX). `axesTCZYX` represents
|
|
85
|
+
* dimension order as a mapping from dimensions to their indices in dimension-ordered arrays for this source.
|
|
86
|
+
*/
|
|
87
|
+
axesTCZYX: TCZYX<number>;
|
|
88
|
+
/** OME-specified metadata record with most useful info on the current image, e.g. sizes, axis order, etc. */
|
|
89
|
+
multiscaleMetadata: OMEMultiscale;
|
|
90
|
+
/** OME-specified "transitional" metadata record which we mostly ignore, but which gives channel & volume names. */
|
|
91
|
+
omeroMetadata?: OmeroTransitionalMetadata;
|
|
92
|
+
/** Which channels in the volume come out of this source - i.e. source channel 0 is volume channel `channelOffset` */
|
|
93
|
+
channelOffset: number;
|
|
94
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { OMEAxis, OMEDataset, OMEMultiscale, TCZYX, ZarrSource } from "./types.js";
|
|
2
|
+
/** Extracts channel names from a `ZarrSource`. Handles missing `omeroMetadata`. Does *not* resolve name collisions. */
|
|
3
|
+
export declare function getSourceChannelNames(src: ZarrSource): string[];
|
|
4
|
+
/** Turns `axesTCZYX` into the number of dimensions in the array */
|
|
5
|
+
export declare const getDimensionCount: ([t, c, z]: TCZYX<number>) => number;
|
|
6
|
+
export declare function remapAxesToTCZYX(axes: OMEAxis[]): TCZYX<number>;
|
|
7
|
+
/** Reorder an array of values [T, C, Z, Y, X] to the given dimension order */
|
|
8
|
+
export declare function orderByDimension<T>(valsTCZYX: TCZYX<T>, orderTCZYX: TCZYX<number>): T[];
|
|
9
|
+
/** Reorder an array of values in the given dimension order to [T, C, Z, Y, X] */
|
|
10
|
+
export declare function orderByTCZYX<T>(valsDimension: T[], orderTCZYX: TCZYX<number>, defaultValue: T): TCZYX<T>;
|
|
11
|
+
/** Select the scale transform from an OME metadata object with coordinate transforms, and return it in TCZYX order */
|
|
12
|
+
export declare function getScale(dataset: OMEDataset | OMEMultiscale, orderTCZYX: TCZYX<number>): TCZYX<number>;
|
|
13
|
+
/**
|
|
14
|
+
* Ensures that all scale levels in `sources` are matched up by size. More precisely: enforces that, for any scale
|
|
15
|
+
* level `i`, the size of zarr array `s[i]` is equal for every source `s`. We accomplish this by removing any arrays
|
|
16
|
+
* (and their associated OME dataset metadata) which don't match up in all sources.
|
|
17
|
+
*
|
|
18
|
+
* Note that this function modifies the input `sources` array rather than returning a new value.
|
|
19
|
+
*
|
|
20
|
+
* Assumes all sources have scale levels ordered by size from largest to smallest. (This should always be true for
|
|
21
|
+
* compliant OME-Zarr data.)
|
|
22
|
+
*/
|
|
23
|
+
export declare function matchSourceScaleLevels(sources: ZarrSource[]): void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { OMEZarrMetadata } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Validates that the `OMEZarrMetadata` record `data` has the minimal amount of data required to open a volume. Since
|
|
4
|
+
* we only ever open one multiscale, we only validate the multiscale metadata record at index `multiscaleIdx` here.
|
|
5
|
+
* `name` is used in error messages to identify the source of the metadata.
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateOMEZarrMetadata(data: unknown, multiscaleIdx?: number, name?: string): asserts data is OMEZarrMetadata;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { Camera, OrthographicCamera, PerspectiveCamera, Vector3 } from "three";
|
|
2
|
+
export interface Bounds {
|
|
3
|
+
bmin: Vector3;
|
|
4
|
+
bmax: Vector3;
|
|
5
|
+
}
|
|
6
|
+
export type Int8 = "int8";
|
|
7
|
+
export type Int16 = "int16";
|
|
8
|
+
export type Int32 = "int32";
|
|
9
|
+
export type Int64 = "int64";
|
|
10
|
+
export type Uint8 = "uint8";
|
|
11
|
+
export type Uint16 = "uint16";
|
|
12
|
+
export type Uint32 = "uint32";
|
|
13
|
+
export type Uint64 = "uint64";
|
|
14
|
+
export type Float32 = "float32";
|
|
15
|
+
export type Float64 = "float64";
|
|
16
|
+
export type NumberType = Int8 | Int16 | Int32 | Uint8 | Uint16 | Uint32 | Float32 | Float64;
|
|
17
|
+
export type TypedArray<D> = D extends Int8 ? Int8Array : D extends Int16 ? Int16Array : D extends Int32 ? Int32Array : D extends Int64 ? BigInt64Array : D extends Uint8 ? Uint8Array : D extends Uint16 ? Uint16Array : D extends Uint32 ? Uint32Array : D extends Uint64 ? BigUint64Array : D extends Float32 ? Float32Array : D extends Float64 ? Float64Array : never;
|
|
18
|
+
export declare const ARRAY_CONSTRUCTORS: {
|
|
19
|
+
int8: Int8ArrayConstructor;
|
|
20
|
+
int16: Int16ArrayConstructor;
|
|
21
|
+
int32: Int32ArrayConstructor;
|
|
22
|
+
int64: BigInt64ArrayConstructor;
|
|
23
|
+
uint8: Uint8ArrayConstructor;
|
|
24
|
+
uint16: Uint16ArrayConstructor;
|
|
25
|
+
uint32: Uint32ArrayConstructor;
|
|
26
|
+
uint64: BigUint64ArrayConstructor;
|
|
27
|
+
float32: Float32ArrayConstructor;
|
|
28
|
+
float64: Float64ArrayConstructor;
|
|
29
|
+
};
|
|
30
|
+
export interface FuseChannel {
|
|
31
|
+
chIndex: number;
|
|
32
|
+
lut: Uint8Array;
|
|
33
|
+
rgbColor: [number, number, number] | number;
|
|
34
|
+
}
|
|
35
|
+
/** If `FuseChannel.rgbColor` is this value, it is disabled from fusion. */
|
|
36
|
+
export declare const FUSE_DISABLED_RGB_COLOR = 0;
|
|
37
|
+
/**
|
|
38
|
+
* Provide options to control the visual appearance of a Volume
|
|
39
|
+
* @typedef {Object} VolumeChannelDisplayOptions
|
|
40
|
+
* @property {boolean} enabled array of boolean per channel
|
|
41
|
+
* @property {Array.<number>} color array of rgb per channel
|
|
42
|
+
* @property {Array.<number>} specularColor array of rgb per channel
|
|
43
|
+
* @property {Array.<number>} emissiveColor array of rgb per channel
|
|
44
|
+
* @property {number} glossiness array of float per channel
|
|
45
|
+
* @property {boolean} isosurfaceEnabled array of boolean per channel
|
|
46
|
+
* @property {number} isovalue array of number per channel
|
|
47
|
+
* @property {number} isosurfaceOpacity array of number per channel
|
|
48
|
+
* @example let options = {
|
|
49
|
+
};
|
|
50
|
+
*/
|
|
51
|
+
export interface VolumeChannelDisplayOptions {
|
|
52
|
+
enabled?: boolean;
|
|
53
|
+
color?: [number, number, number];
|
|
54
|
+
specularColor?: [number, number, number];
|
|
55
|
+
emissiveColor?: [number, number, number];
|
|
56
|
+
glossiness?: number;
|
|
57
|
+
isosurfaceEnabled?: boolean;
|
|
58
|
+
isovalue?: number;
|
|
59
|
+
isosurfaceOpacity?: number;
|
|
60
|
+
}
|
|
61
|
+
export declare enum RenderMode {
|
|
62
|
+
RAYMARCH = 0,
|
|
63
|
+
PATHTRACE = 1,
|
|
64
|
+
SLICE = 2
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Provide options to control the visual appearance of a Volume
|
|
68
|
+
* @typedef {Object} VolumeDisplayOptions
|
|
69
|
+
* @property {Array.<VolumeChannelDisplayOptions>} channels array of channel display options
|
|
70
|
+
* @property {number} density
|
|
71
|
+
* @property {Array.<number>} translation xyz
|
|
72
|
+
* @property {Array.<number>} rotation xyz angles in radians
|
|
73
|
+
* @property {number} maskChannelIndex
|
|
74
|
+
* @property {number} maskAlpha
|
|
75
|
+
* @property {Array.<number>} clipBounds [xmin, xmax, ymin, ymax, zmin, zmax] all range from 0 to 1 as a percentage of the volume on that axis
|
|
76
|
+
* @property {Array.<number>} scale xyz voxel size scaling
|
|
77
|
+
* @property {boolean} maxProjection true or false (ray marching)
|
|
78
|
+
* @property {number} renderMode 0 for raymarch, 1 for pathtrace
|
|
79
|
+
* @property {number} shadingMethod 0 for phase, 1 for brdf, 2 for hybrid (path tracer)
|
|
80
|
+
* @property {Array.<number>} gamma [min, max, scale]
|
|
81
|
+
* @property {number} primaryRayStepSize in voxels
|
|
82
|
+
* @property {number} secondaryRayStepSize in voxels
|
|
83
|
+
* @property {boolean} showBoundingBox true or false
|
|
84
|
+
* @property {Array.<number>} boundingBoxColor r,g,b for bounding box lines
|
|
85
|
+
* @example let options = {
|
|
86
|
+
};
|
|
87
|
+
*/
|
|
88
|
+
export interface VolumeDisplayOptions {
|
|
89
|
+
channels?: VolumeChannelDisplayOptions[];
|
|
90
|
+
density?: number;
|
|
91
|
+
translation?: [number, number, number];
|
|
92
|
+
rotation?: [number, number, number];
|
|
93
|
+
maskChannelIndex?: number;
|
|
94
|
+
maskAlpha?: number;
|
|
95
|
+
clipBounds?: [number, number, number, number, number, number];
|
|
96
|
+
maxProjection?: boolean;
|
|
97
|
+
renderMode?: RenderMode;
|
|
98
|
+
shadingMethod?: number;
|
|
99
|
+
gamma?: [number, number, number];
|
|
100
|
+
primaryRayStepSize?: number;
|
|
101
|
+
secondaryRayStepSize?: number;
|
|
102
|
+
showBoundingBox?: boolean;
|
|
103
|
+
boundingBoxColor?: [number, number, number];
|
|
104
|
+
}
|
|
105
|
+
export declare const isOrthographicCamera: (def: Camera) => def is OrthographicCamera;
|
|
106
|
+
export declare const isPerspectiveCamera: (def: Camera) => def is PerspectiveCamera;
|
|
107
|
+
export declare const enum ViewportCorner {
|
|
108
|
+
TOP_LEFT = "top_left",
|
|
109
|
+
TOP_RIGHT = "top_right",
|
|
110
|
+
BOTTOM_LEFT = "bottom_left",
|
|
111
|
+
BOTTOM_RIGHT = "bottom_right"
|
|
112
|
+
}
|
|
113
|
+
export declare const isTop: (corner: ViewportCorner) => boolean;
|
|
114
|
+
export declare const isRight: (corner: ViewportCorner) => boolean;
|
|
115
|
+
export declare const DATARANGE_UINT8: [number, number];
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/** Object format used when passing multiple requests to RequestQueue at once. */
|
|
2
|
+
export type Request<V> = {
|
|
3
|
+
key: string;
|
|
4
|
+
requestAction: () => Promise<V>;
|
|
5
|
+
};
|
|
6
|
+
export declare const DEFAULT_REQUEST_CANCEL_REASON = "request cancelled";
|
|
7
|
+
/**
|
|
8
|
+
* Manages a queue of asynchronous requests with unique string keys, which can be added to or cancelled.
|
|
9
|
+
* If redundant requests with the same key are issued, the request action will only be run once per key
|
|
10
|
+
* while the original request is still in the queue.
|
|
11
|
+
*/
|
|
12
|
+
export default class RequestQueue {
|
|
13
|
+
/**
|
|
14
|
+
* The maximum number of requests that can be handled concurrently.
|
|
15
|
+
* Once reached, additional requests will be queued up to run once a running request completes.
|
|
16
|
+
*/
|
|
17
|
+
private maxActiveRequests;
|
|
18
|
+
/**
|
|
19
|
+
* The maximum number of requests that can be handled concurrently if only low-priority requests are waiting. Set
|
|
20
|
+
* lower than `concurrencyLimit` to always leave space for high-priority requests. Cannot be set higher than
|
|
21
|
+
* `concurrencyLimit`.
|
|
22
|
+
*/
|
|
23
|
+
private maxLowPriorityRequests;
|
|
24
|
+
/** A queue of requests that are ready to be executed, in order of request time. */
|
|
25
|
+
private queue;
|
|
26
|
+
/** A queue of low-priority tasks that are ready to be executed. `queue` must be empty before any of these tasks run. */
|
|
27
|
+
private queueLowPriority;
|
|
28
|
+
/** Stores all requests, even those that are currently active. */
|
|
29
|
+
private allRequests;
|
|
30
|
+
/** Stores requests whose actions are currently being run. */
|
|
31
|
+
private activeRequests;
|
|
32
|
+
/**
|
|
33
|
+
* Creates a new RequestQueue.
|
|
34
|
+
* @param maxActiveRequests The maximum number of requests that will be handled concurrently. This is 10 by default.
|
|
35
|
+
* @param maxLowPriorityRequests The maximum number of low-priority requests that will be handled concurrently. Equal
|
|
36
|
+
* to `maxActiveRequests` by default, but may be set lower to always leave space for new high-priority requests.
|
|
37
|
+
*/
|
|
38
|
+
constructor(maxActiveRequests?: number, maxLowPriorityRequests?: number);
|
|
39
|
+
/**
|
|
40
|
+
* Stores request metadata to the internal map of all pending requests.
|
|
41
|
+
* @param key string identifier of the request.
|
|
42
|
+
* @param requestAction callable function action of the request.
|
|
43
|
+
* @returns a reference to the new, registered RequestItem.
|
|
44
|
+
*/
|
|
45
|
+
private registerRequest;
|
|
46
|
+
/**
|
|
47
|
+
* Moves a registered request into the processing queue, clearing any timeouts on the request.
|
|
48
|
+
* @param key string identifier of the request.
|
|
49
|
+
* @param lowPriority Whether this request should be added with low priority. False by default.
|
|
50
|
+
*/
|
|
51
|
+
private addRequestToQueue;
|
|
52
|
+
/**
|
|
53
|
+
* Adds a request with a unique key to the queue, if it doesn't already exist.
|
|
54
|
+
* @param key The key used to track the request.
|
|
55
|
+
* @param requestAction Function that will be called to complete the request. The function
|
|
56
|
+
* will be run only once per unique key while the request exists, and may be deferred by the
|
|
57
|
+
* queue at any time.
|
|
58
|
+
* @param lowPriority Whether this request should be added with low priority. False by default.
|
|
59
|
+
* @param delayMs Minimum delay, in milliseconds, before this request should be executed.
|
|
60
|
+
*
|
|
61
|
+
* NOTE: Cancelling a request while the action is running WILL NOT stop the action. If this behavior is desired,
|
|
62
|
+
* actions must be responsible for checking the RequestQueue, determining if the request is still valid (e.g.
|
|
63
|
+
* using `.hasRequest()`), and stopping or returning early.
|
|
64
|
+
*
|
|
65
|
+
* @returns A promise that will resolve on completion of the request, or reject if the request is cancelled.
|
|
66
|
+
* If multiple requests are issued with the same key, a promise for the first request will be returned
|
|
67
|
+
* until the request is resolved or cancelled.
|
|
68
|
+
* Note that the return type of the promise will match that of the first request's instance.
|
|
69
|
+
*/
|
|
70
|
+
addRequest<T>(key: string, requestAction: () => Promise<T>, lowPriority?: boolean, delayMs?: number): Promise<T>;
|
|
71
|
+
/**
|
|
72
|
+
* Adds multiple requests to the queue, with an optional delay between each.
|
|
73
|
+
* @param requests An array of RequestItems, which include a key and a request action.
|
|
74
|
+
* @param lowPriority Whether these requests should be added with low priority. False by default.
|
|
75
|
+
* @param delayMs An optional minimum delay in milliseconds to be added between each request.
|
|
76
|
+
* For example, a delay of 10 ms will cause the second request to be added to the processing queue
|
|
77
|
+
* after 10 ms, the third to added after 20 ms, and so on. Set to 10 ms by default.
|
|
78
|
+
* @returns An array of promises corresponding to the provided requests. (i.e., the `i`th value
|
|
79
|
+
* of the returned array will be a Promise for the resolution of `requests[i]`). If a request
|
|
80
|
+
* with a matching key is already pending, returns the promise for the initial request.
|
|
81
|
+
*/
|
|
82
|
+
addRequests<T>(requests: Request<T>[], lowPriority?: boolean, delayMs?: number): Promise<unknown>[];
|
|
83
|
+
/**
|
|
84
|
+
* Attempts to remove and run the next queued request item, if resources are available.
|
|
85
|
+
* @returns true if a request was started, or false if there are too many
|
|
86
|
+
* requests already active.
|
|
87
|
+
*/
|
|
88
|
+
private dequeue;
|
|
89
|
+
/**
|
|
90
|
+
* Removes any request matching the provided key from the queue and rejects its promise.
|
|
91
|
+
* @param key The key that should be matched against.
|
|
92
|
+
* @param cancelReason A message or object that will be used as the promise rejection.
|
|
93
|
+
*/
|
|
94
|
+
cancelRequest(key: string, cancelReason?: unknown): void;
|
|
95
|
+
/**
|
|
96
|
+
* Rejects all request promises and clears the queue.
|
|
97
|
+
* @param cancelReason A message or object that will be used as the promise rejection.
|
|
98
|
+
*/
|
|
99
|
+
cancelAllRequests(cancelReason?: unknown): void;
|
|
100
|
+
/**
|
|
101
|
+
* Returns whether a request with the given key exists in the RequestQueue and is not cancelled.
|
|
102
|
+
* @param key the key to search for.
|
|
103
|
+
* @returns true if the request is in the RequestQueue.
|
|
104
|
+
*/
|
|
105
|
+
hasRequest(key: string): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Returns whether the request with the given key is currently running (not waiting in the queue).
|
|
108
|
+
* @param key the key to search for.
|
|
109
|
+
* @returns true if the request is actively running.
|
|
110
|
+
*/
|
|
111
|
+
requestRunning(key: string): boolean;
|
|
112
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import RequestQueue from "./RequestQueue.js";
|
|
2
|
+
/**
|
|
3
|
+
* An extension of `RequestQueue` that adds a concept of "subscribers," which may share references to a single request
|
|
4
|
+
* or cancel their subscription without disrupting the request for other subscribers.
|
|
5
|
+
*/
|
|
6
|
+
export default class SubscribableRequestQueue {
|
|
7
|
+
private queue;
|
|
8
|
+
/** The next unused subscriber ID. Increments whenever a subscriber is added. */
|
|
9
|
+
private nextSubscriberId;
|
|
10
|
+
/**
|
|
11
|
+
* Map of subscribers keyed by ID. Subscribers store a map to all their subscriptions by request key.
|
|
12
|
+
* Subscribers are only useful as handles to cancel subscriptions early, so we only need to store rejecters here.
|
|
13
|
+
*/
|
|
14
|
+
private subscribers;
|
|
15
|
+
/** Map from "inner" request (managed by `queue`) to "outer" promises generated per-subscriber. */
|
|
16
|
+
private requests;
|
|
17
|
+
/**
|
|
18
|
+
* Since `SubscribableRequestQueue` wraps `RequestQueue`, its constructor may either take the same arguments as the
|
|
19
|
+
* `RequestQueue` constructor and create a new `RequestQueue`, or it may take an existing `RequestQueue` to wrap.
|
|
20
|
+
*/
|
|
21
|
+
constructor(maxActiveRequests?: number, maxLowPriorityRequests?: number);
|
|
22
|
+
constructor(inner: RequestQueue);
|
|
23
|
+
/** Resolves all subscriptions to request `key` with `value` */
|
|
24
|
+
private resolveAll;
|
|
25
|
+
/** Rejects all subscriptions to request `key` with `reason` */
|
|
26
|
+
private rejectAll;
|
|
27
|
+
/** Adds a new request subscriber. Returns a unique ID to identify this subscriber. */
|
|
28
|
+
addSubscriber(): number;
|
|
29
|
+
/**
|
|
30
|
+
* Queues a new request, or adds a subscription if the request is already queued/running.
|
|
31
|
+
*
|
|
32
|
+
* If `subscriberId` is already subscribed to the request, this rejects the existing promise and returns a new one.
|
|
33
|
+
*/
|
|
34
|
+
addRequest<T>(key: string, subscriberId: number, requestAction: () => Promise<T>, lowPriority?: boolean, delayMs?: number): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* Rejects a subscription and removes it from the list of subscriptions for a request, then cancels the underlying
|
|
37
|
+
* request if it is no longer subscribed and is not running already.
|
|
38
|
+
*/
|
|
39
|
+
private rejectSubscription;
|
|
40
|
+
/** Cancels a request subscription, and cancels the underlying request if it is no longer subscribed or running. */
|
|
41
|
+
cancelRequest(key: string, subscriberId: number, cancelReason?: unknown): boolean;
|
|
42
|
+
/** Removes a subscriber and cancels its remaining subscriptions. */
|
|
43
|
+
removeSubscriber(subscriberId: number, cancelReason?: unknown): void;
|
|
44
|
+
/** Returns whether a request with the given `key` is running or waiting in the queue */
|
|
45
|
+
hasRequest(key: string): boolean;
|
|
46
|
+
/** Returns whether a request with the given `key` is running */
|
|
47
|
+
requestRunning(key: string): boolean;
|
|
48
|
+
/** Returns whether a subscriber with the given `subscriberId` exists */
|
|
49
|
+
hasSubscriber(subscriberId: number): boolean;
|
|
50
|
+
/** Returns whether a subscriber with the given `subscriberId` is subscribed to the request with the given `key` */
|
|
51
|
+
isSubscribed(subscriberId: number, key: string): boolean;
|
|
52
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { TimeUnit } from "../constants/time.js";
|
|
2
|
+
import { Axis } from "../VolumeRenderSettings.js";
|
|
3
|
+
export declare const DEFAULT_SIG_FIGS = 5;
|
|
4
|
+
/**
|
|
5
|
+
* Formats numbers for display as a string with a (hopefully) limited length.
|
|
6
|
+
*
|
|
7
|
+
* - If the number is an integer with 4 or fewer digits, it is returned as a string.
|
|
8
|
+
* - If the number is a decimal, it is rounded to `sigFigs` significant figures. (default 5)
|
|
9
|
+
* - If the number's absolute value is over 10,000 or less than 0.01, it is formatted in scientific notation to
|
|
10
|
+
* `sciSigFigs` significant figures. (Default `sigFigs - 2`, so 3 if neither are specified. The `- 2` leaves space
|
|
11
|
+
* for the exponential part. Remember: the purpose of this function is keeping number strings *consistently* short!)
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatNumber(value: number, sigFigs?: number, sciSigFigs?: number): string;
|
|
14
|
+
export declare function timeToMilliseconds(time: number, unit: TimeUnit): number;
|
|
15
|
+
/**
|
|
16
|
+
* Gets a timestamp formatted as `{time} / {total} {unit}`. If `unit` is a recognized
|
|
17
|
+
* time unit, the timestamp will be formatted as a `d:hh:mm:ss.ms` string.
|
|
18
|
+
*
|
|
19
|
+
* @param time Current time, in specified units.
|
|
20
|
+
* @param total Total time, in specified units.
|
|
21
|
+
* @param unit The unit of time.
|
|
22
|
+
* @returns A formatted timestamp string.
|
|
23
|
+
* - If `unit` is not recognized, the timestamp will be formatted as `{time} / {total} {unit}`,
|
|
24
|
+
* where `time` and `total` are formatted with significant digits as needed.
|
|
25
|
+
* - If `unit` is recognized, the timestamp will be formatted as `d:hh:mm:ss.ms`, specifying
|
|
26
|
+
* the most significant unit based on the total time, and the least significant unit with
|
|
27
|
+
* `unit`. See `parseTimeUnit()` for recognized time units.
|
|
28
|
+
*/
|
|
29
|
+
export declare function getTimestamp(time: number, total: number, unit: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Constrains the `src` vector relative to the `target` so it only has freedom along the
|
|
32
|
+
* specified `axis`. Does nothing if `axis = Axis.NONE`.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```
|
|
36
|
+
* const src = [1, 2, 3];
|
|
37
|
+
* const target = [4, 5, 6];
|
|
38
|
+
* const constrained = constrainToAxis(src, target, Axis.X);
|
|
39
|
+
* console.log(constrained); // [1, 5, 6]
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare function constrainToAxis(src: [number, number, number], target: [number, number, number], axis: Axis): [number, number, number];
|
|
43
|
+
export declare function getDataRange(data: ArrayLike<number>): [number, number];
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { ImageInfo } from "../ImageInfo.js";
|
|
2
|
+
import { VolumeDims } from "../VolumeDims.js";
|
|
3
|
+
import { CreateLoaderOptions, PrefetchDirection } from "../loaders/index.js";
|
|
4
|
+
import { ThreadableVolumeLoader, LoadSpec, RawChannelDataCallback, LoadedVolumeInfo } from "../loaders/IVolumeLoader.js";
|
|
5
|
+
import { RawArrayLoader } from "../loaders/RawArrayLoader.js";
|
|
6
|
+
import { TiffLoader } from "../loaders/TiffLoader.js";
|
|
7
|
+
import type { WorkerRequestPayload, WorkerResponsePayload, ChannelLoadEvent, MetadataUpdateEvent } from "./types.js";
|
|
8
|
+
import type { ZarrLoaderFetchOptions } from "../loaders/OmeZarrLoader.js";
|
|
9
|
+
import { WorkerMsgType } from "./types.js";
|
|
10
|
+
/**
|
|
11
|
+
* A handle that holds the worker and manages requests and messages to/from it.
|
|
12
|
+
*
|
|
13
|
+
* `VolumeLoaderContext` and every `LoaderWorker` it creates all hold references to one `SharedLoadWorkerHandle`.
|
|
14
|
+
* They use it to interact with the worker via `sendMessage`, which speaks the protocol defined in ./types.ts and
|
|
15
|
+
* converts messages received from the worker into resolved `Promise`s and called callbacks.
|
|
16
|
+
*
|
|
17
|
+
* This class exists to represent that access to the worker is shared between `VolumeLoaderContext` and any
|
|
18
|
+
* `LoaderWorker`s. This is as opposed to implementing `sendMessage` directly on `VolumeLoaderContext`, where making
|
|
19
|
+
* the method public to `LoaderWorker`s would require also allowing access to users of the class.
|
|
20
|
+
*/
|
|
21
|
+
declare class SharedLoadWorkerHandle {
|
|
22
|
+
private worker;
|
|
23
|
+
private pendingRequests;
|
|
24
|
+
private workerOpen;
|
|
25
|
+
private throttleChannelData;
|
|
26
|
+
onChannelData: ((e: ChannelLoadEvent) => void) | undefined;
|
|
27
|
+
onUpdateMetadata: ((e: MetadataUpdateEvent) => void) | undefined;
|
|
28
|
+
constructor();
|
|
29
|
+
/** Given a handle for settling a promise when a response is received from the worker, store it and return its ID */
|
|
30
|
+
private registerMessagePromise;
|
|
31
|
+
get isOpen(): boolean;
|
|
32
|
+
/** Close the worker. */
|
|
33
|
+
close(): void;
|
|
34
|
+
/**
|
|
35
|
+
* Send a message of type `T` to the worker.
|
|
36
|
+
* Returns a `Promise` that resolves with the worker's response, or rejects with an error message.
|
|
37
|
+
*/
|
|
38
|
+
sendMessage<T extends WorkerMsgType>(type: T, payload: WorkerRequestPayload<T>): Promise<WorkerResponsePayload<T>>;
|
|
39
|
+
/** Receive a message from the worker. If it's an event, call a callback; otherwise, resolve/reject a promise. */
|
|
40
|
+
private receiveMessage;
|
|
41
|
+
setThrottleChannelData(throttle: boolean): void;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A context in which volume loaders can be run, which allows loading to run on a WebWorker (where it won't block
|
|
45
|
+
* rendering or UI updates) and loaders to share a single `VolumeCache` and `RequestQueue`.
|
|
46
|
+
*
|
|
47
|
+
* ### To use:
|
|
48
|
+
* 1. Create a `VolumeLoaderContext` with the desired cache and queue configuration.
|
|
49
|
+
* 2. Before creating a loader, await `onOpen` to ensure the worker is ready.
|
|
50
|
+
* 3. Create a loader with `createLoader`. This accepts nearly the same arguments as `createVolumeLoader`, but without
|
|
51
|
+
* options to directly link to a cache or queue (the loader will always be linked to the context's shared instances
|
|
52
|
+
* of these if possible).
|
|
53
|
+
*
|
|
54
|
+
* The returned `WorkerLoader` can be used like any other `IVolumeLoader` and acts as a handle to the actual loader
|
|
55
|
+
* running on the worker.
|
|
56
|
+
*/
|
|
57
|
+
declare class VolumeLoaderContext {
|
|
58
|
+
private workerHandle;
|
|
59
|
+
private openPromise;
|
|
60
|
+
private activeLoader;
|
|
61
|
+
private activeLoaderId;
|
|
62
|
+
constructor(maxCacheSize?: number, maxActiveRequests?: number, maxLowPriorityRequests?: number);
|
|
63
|
+
/** Returns a `Promise` that resolves when the worker is ready. `await` it before trying to create a loader. */
|
|
64
|
+
onOpen(): Promise<void>;
|
|
65
|
+
/** Close this context, its worker, and any active loaders. */
|
|
66
|
+
close(): void;
|
|
67
|
+
/**
|
|
68
|
+
* Create a new loader within this context. This loader will share the context's `VolumeCache` and `RequestQueue`.
|
|
69
|
+
*
|
|
70
|
+
* This works just like `createVolumeLoader`. A file format may be provided, or it may be inferred from the URL.
|
|
71
|
+
*/
|
|
72
|
+
createLoader(path: string | string[], options?: Omit<CreateLoaderOptions, "cache" | "queue">): Promise<WorkerLoader | TiffLoader | RawArrayLoader>;
|
|
73
|
+
setThrottleChannelData(throttle: boolean): void;
|
|
74
|
+
getActiveLoader(): WorkerLoader | undefined;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* A handle to an instance of `IVolumeLoader` (technically, a `ThreadableVolumeLoader`) running on a WebWorker.
|
|
78
|
+
*
|
|
79
|
+
* Created with `VolumeLoaderContext.createLoader`. See its documentation for more.
|
|
80
|
+
*/
|
|
81
|
+
declare class WorkerLoader extends ThreadableVolumeLoader {
|
|
82
|
+
private loaderId;
|
|
83
|
+
private workerHandle;
|
|
84
|
+
private isOpen;
|
|
85
|
+
private currentLoadId;
|
|
86
|
+
private currentLoadCallback;
|
|
87
|
+
private currentMetadataUpdateCallback;
|
|
88
|
+
constructor(loaderId: number, workerHandle: SharedLoadWorkerHandle);
|
|
89
|
+
private checkIsOpen;
|
|
90
|
+
/** Close and permanently invalidate this loader. */
|
|
91
|
+
close(): void;
|
|
92
|
+
/**
|
|
93
|
+
* Change which directions to prioritize when prefetching. All chunks will be prefetched in these directions before
|
|
94
|
+
* any chunks are prefetched in any other directions. Has no effect if this loader doesn't support prefetching.
|
|
95
|
+
*/
|
|
96
|
+
setPrefetchPriority(directions: PrefetchDirection[]): Promise<void>;
|
|
97
|
+
updateFetchOptions(fetchOptions: Partial<ZarrLoaderFetchOptions>): Promise<void>;
|
|
98
|
+
syncMultichannelLoading(sync: boolean): Promise<void>;
|
|
99
|
+
loadDims(loadSpec: LoadSpec): Promise<VolumeDims[]>;
|
|
100
|
+
createImageInfo(loadSpec: LoadSpec): Promise<LoadedVolumeInfo>;
|
|
101
|
+
loadRawChannelData(imageInfo: ImageInfo, loadSpec: LoadSpec, onUpdateMetadata: (imageInfo?: ImageInfo, loadSpec?: LoadSpec) => void, onData: RawChannelDataCallback): Promise<void>;
|
|
102
|
+
onChannelData(e: ChannelLoadEvent): void;
|
|
103
|
+
onUpdateMetadata(e: MetadataUpdateEvent): void;
|
|
104
|
+
}
|
|
105
|
+
export default VolumeLoaderContext;
|
|
106
|
+
export type { WorkerLoader };
|