@aics/vole-core 4.0.0 → 4.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/es/VolumeMaker.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { ARRAY_CONSTRUCTORS } from "./types.js";
2
+
1
3
  /**
2
4
  * Basic utility functions to create sample volume data
3
5
  * @class
@@ -9,9 +11,11 @@ export default class VolumeMaker {
9
11
  * @param {number} vy
10
12
  * @param {number} vz
11
13
  * @param {function} sdFunc A function f(x,y,z) that returns a distance. f < 0 will be the interior of the volume, and f>=0 will be outside.
14
+ * @param {NumberType} dtype The data type for the output array
12
15
  */
13
- static createVolume(vx, vy, vz, sdFunc) {
14
- const data = new Uint8Array(vx * vy * vz).fill(0);
16
+ static createVolume(vx, vy, vz, sdFunc, dtype = "uint8") {
17
+ const ctor = ARRAY_CONSTRUCTORS[dtype];
18
+ const data = new ctor(vx * vy * vz).fill(0);
15
19
  const cx = vx / 2;
16
20
  const cy = vy / 2;
17
21
  const cz = vz / 2;
@@ -40,11 +44,12 @@ export default class VolumeMaker {
40
44
  * @param {number} vy
41
45
  * @param {number} vz
42
46
  * @param {number} radius
47
+ * @param {NumberType} dtype The data type for the output array
43
48
  */
44
- static createSphere(vx, vy, vz, radius) {
49
+ static createSphere(vx, vy, vz, radius, dtype = "uint8") {
45
50
  return VolumeMaker.createVolume(vx, vy, vz, (px, py, pz) => {
46
51
  return Math.sqrt(px * px + py * py + pz * pz) - radius;
47
- });
52
+ }, dtype);
48
53
  }
49
54
 
50
55
  /**
@@ -54,8 +59,9 @@ export default class VolumeMaker {
54
59
  * @param {number} vz
55
60
  * @param {number} hx width of cap (?)
56
61
  * @param {number} hy depth of cap (?)
62
+ * @param {NumberType} dtype The data type for the output array
57
63
  */
58
- static createCylinder(vx, vy, vz, hx, hy) {
64
+ static createCylinder(vx, vy, vz, hx, hy, dtype = "uint8") {
59
65
  let dx, dy, mdx, mdy;
60
66
  return VolumeMaker.createVolume(vx, vy, vz, (px, py, pz) => {
61
67
  dx = Math.abs(Math.sqrt(px * px + pz * pz)) - hx;
@@ -63,7 +69,7 @@ export default class VolumeMaker {
63
69
  mdx = Math.max(dx, 0.0);
64
70
  mdy = Math.max(dy, 0.0);
65
71
  return Math.min(Math.max(dx, dy), 0.0) + Math.sqrt(mdx * mdx + mdy * mdy);
66
- });
72
+ }, dtype);
67
73
  }
68
74
 
69
75
  /**
@@ -73,14 +79,15 @@ export default class VolumeMaker {
73
79
  * @param {number} vz
74
80
  * @param {number} tx inner radius
75
81
  * @param {number} ty outer radius
82
+ * @param {NumberType} dtype The data type for the output array
76
83
  */
77
- static createTorus(vx, vy, vz, tx, ty) {
84
+ static createTorus(vx, vy, vz, tx, ty, dtype = "uint8") {
78
85
  let qx, qy;
79
86
  return VolumeMaker.createVolume(vx, vy, vz, (px, py, pz) => {
80
87
  qx = Math.sqrt(px * px + pz * pz) - tx;
81
88
  qy = py;
82
89
  return Math.sqrt(qx * qx + qy * qy) - ty;
83
- });
90
+ }, dtype);
84
91
  }
85
92
 
86
93
  /**
@@ -90,12 +97,30 @@ export default class VolumeMaker {
90
97
  * @param {number} vz
91
98
  * @param {number} cx base radius
92
99
  * @param {number} cy height
100
+ * @param {NumberType} dtype The data type for the output array
93
101
  */
94
- static createCone(vx, vy, vz, cx, cy) {
102
+ static createCone(vx, vy, vz, cx, cy, dtype = "uint8") {
95
103
  let q;
96
104
  return VolumeMaker.createVolume(vx, vy, vz, (px, py, pz) => {
97
105
  q = Math.sqrt(px * px + py * py);
98
106
  return cx * q + cy * pz;
99
- });
107
+ }, dtype);
108
+ }
109
+
110
+ // take a list of TypedArrays and concatenate them into a single TypedArray of the same Type:
111
+ static concatenateArrays(arrays, dtype) {
112
+ if (arrays.length === 0) {
113
+ throw new Error("Cannot concatenate empty array list");
114
+ }
115
+ const totalLength = arrays.reduce((acc, arr) => acc + arr.length, 0);
116
+
117
+ // Create a new array of the same type as the input arrays
118
+ const result = new ARRAY_CONSTRUCTORS[dtype](totalLength);
119
+ let offset = 0;
120
+ for (const arr of arrays) {
121
+ result.set(arr, offset);
122
+ offset += arr.length;
123
+ }
124
+ return result;
100
125
  }
101
126
  }
@@ -1,6 +1,7 @@
1
1
  import { Box3, Vector3 } from "three";
2
2
  import { ThreadableVolumeLoader } from "./IVolumeLoader.js";
3
3
  import { computePackedAtlasDims } from "./VolumeLoaderUtils.js";
4
+ import { ARRAY_CONSTRUCTORS } from "../types.js";
4
5
  import { getDataRange } from "../utils/num_utils.js";
5
6
 
6
7
  // this is the form in which a 4D numpy array arrives as converted
@@ -9,7 +10,25 @@ import { getDataRange } from "../utils/num_utils.js";
9
10
 
10
11
  // minimal metadata for visualization
11
12
 
12
- const convertImageInfo = json => {
13
+ function getBytesPerPixel(dtype) {
14
+ switch (dtype) {
15
+ case "uint8":
16
+ case "int8":
17
+ return 1;
18
+ case "uint16":
19
+ case "int16":
20
+ return 2;
21
+ case "uint32":
22
+ case "int32":
23
+ case "float32":
24
+ return 4;
25
+ case "float64":
26
+ return 8;
27
+ default:
28
+ throw new Error(`Unsupported dtype: ${dtype}`);
29
+ }
30
+ }
31
+ const convertImageInfo = (json, dtype) => {
13
32
  const atlasTileDims = computePackedAtlasDims(json.sizeZ, json.sizeX, json.sizeY);
14
33
  return {
15
34
  name: json.name,
@@ -27,7 +46,7 @@ const convertImageInfo = json => {
27
46
  spacing: [1, 1, json.physicalPixelSize[2], json.physicalPixelSize[1], json.physicalPixelSize[0]],
28
47
  spaceUnit: json.spatialUnit || "μm",
29
48
  timeUnit: "s",
30
- dataType: "uint8"
49
+ dataType: dtype
31
50
  }],
32
51
  transform: {
33
52
  translation: [0, 0, 0],
@@ -53,14 +72,14 @@ class RawArrayLoader extends ThreadableVolumeLoader {
53
72
  shape: [1, jsonInfo.sizeC, jsonInfo.sizeZ, jsonInfo.sizeY, jsonInfo.sizeX],
54
73
  spacing: [1, 1, jsonInfo.physicalPixelSize[2], jsonInfo.physicalPixelSize[1], jsonInfo.physicalPixelSize[0]],
55
74
  spaceUnit: jsonInfo.spatialUnit || "μm",
56
- dataType: "uint8",
75
+ dataType: this.data.dtype,
57
76
  timeUnit: "s" // time unit not specified
58
77
  };
59
78
  return [d];
60
79
  }
61
80
  async createImageInfo(loadSpec) {
62
81
  return {
63
- imageInfo: convertImageInfo(this.jsonInfo),
82
+ imageInfo: convertImageInfo(this.jsonInfo, this.data.dtype),
64
83
  loadSpec
65
84
  };
66
85
  }
@@ -77,11 +96,12 @@ class RawArrayLoader extends ThreadableVolumeLoader {
77
96
  if (requestedChannels && requestedChannels.length > 0 && !requestedChannels.includes(chindex)) {
78
97
  continue;
79
98
  }
80
- const volSizeBytes = this.data.shape[3] * this.data.shape[2] * this.data.shape[1]; // x*y*z pixels * 1 byte/pixel
81
- const channelData = new Uint8Array(this.data.buffer.buffer, chindex * volSizeBytes, volSizeBytes);
99
+ // x*y*z pixels
100
+ const volSizePixels = this.data.shape[3] * this.data.shape[2] * this.data.shape[1];
101
+ const ctor = ARRAY_CONSTRUCTORS[this.data.dtype];
102
+ const channelData = new ctor(this.data.buffer.buffer, chindex * volSizePixels * getBytesPerPixel(this.data.dtype), volSizePixels);
82
103
  const range = getDataRange(channelData);
83
- // all data coming from this loader is natively 8-bit
84
- onData([chindex], ["uint8"], [channelData], [range]);
104
+ onData([chindex], [this.data.dtype], [channelData], [range]);
85
105
  }
86
106
  return Promise.resolve();
87
107
  }
@@ -1,3 +1,4 @@
1
+ import { type NumberType, type TypedArray } from "./types.js";
1
2
  /**
2
3
  * Basic utility functions to create sample volume data
3
4
  * @class
@@ -9,16 +10,18 @@ export default class VolumeMaker {
9
10
  * @param {number} vy
10
11
  * @param {number} vz
11
12
  * @param {function} sdFunc A function f(x,y,z) that returns a distance. f < 0 will be the interior of the volume, and f>=0 will be outside.
13
+ * @param {NumberType} dtype The data type for the output array
12
14
  */
13
- static createVolume(vx: number, vy: number, vz: number, sdFunc: (px: number, py: number, pz: number) => number): Uint8Array;
15
+ static createVolume(vx: number, vy: number, vz: number, sdFunc: (px: number, py: number, pz: number) => number, dtype?: NumberType): TypedArray<NumberType>;
14
16
  /**
15
17
  * Create a volume filled with a sphere in the center
16
18
  * @param {number} vx
17
19
  * @param {number} vy
18
20
  * @param {number} vz
19
21
  * @param {number} radius
22
+ * @param {NumberType} dtype The data type for the output array
20
23
  */
21
- static createSphere(vx: number, vy: number, vz: number, radius: number): Uint8Array;
24
+ static createSphere(vx: number, vy: number, vz: number, radius: number, dtype?: NumberType): TypedArray<NumberType>;
22
25
  /**
23
26
  * Create a volume with a cylinder centered inside.
24
27
  * @param {number} vx
@@ -26,8 +29,9 @@ export default class VolumeMaker {
26
29
  * @param {number} vz
27
30
  * @param {number} hx width of cap (?)
28
31
  * @param {number} hy depth of cap (?)
32
+ * @param {NumberType} dtype The data type for the output array
29
33
  */
30
- static createCylinder(vx: number, vy: number, vz: number, hx: number, hy: number): Uint8Array;
34
+ static createCylinder(vx: number, vy: number, vz: number, hx: number, hy: number, dtype?: NumberType): TypedArray<NumberType>;
31
35
  /**
32
36
  * Create a volume with a torus centered inside
33
37
  * @param {number} vx
@@ -35,8 +39,9 @@ export default class VolumeMaker {
35
39
  * @param {number} vz
36
40
  * @param {number} tx inner radius
37
41
  * @param {number} ty outer radius
42
+ * @param {NumberType} dtype The data type for the output array
38
43
  */
39
- static createTorus(vx: number, vy: number, vz: number, tx: number, ty: number): Uint8Array;
44
+ static createTorus(vx: number, vy: number, vz: number, tx: number, ty: number, dtype?: NumberType): TypedArray<NumberType>;
40
45
  /**
41
46
  * Create a volume with a cone centered inside. cx, cy must be a 2d normalized pair...?
42
47
  * @param {number} vx
@@ -44,6 +49,8 @@ export default class VolumeMaker {
44
49
  * @param {number} vz
45
50
  * @param {number} cx base radius
46
51
  * @param {number} cy height
52
+ * @param {NumberType} dtype The data type for the output array
47
53
  */
48
- static createCone(vx: number, vy: number, vz: number, cx: number, cy: number): Uint8Array;
54
+ static createCone(vx: number, vy: number, vz: number, cx: number, cy: number, dtype?: NumberType): TypedArray<NumberType>;
55
+ static concatenateArrays(arrays: TypedArray<NumberType>[], dtype: NumberType): TypedArray<NumberType>;
49
56
  }
@@ -8,7 +8,7 @@ import RequestQueue from "./utils/RequestQueue.js";
8
8
  import SubscribableRequestQueue from "./utils/SubscribableRequestQueue.js";
9
9
  import Histogram from "./Histogram.js";
10
10
  import { Lut, remapControlPoints } from "./Lut.js";
11
- import { type ColorizeFeature, ViewportCorner } from "./types.js";
11
+ import { type ColorizeFeature, type NumberType, ViewportCorner } from "./types.js";
12
12
  import { VolumeFileFormat, createVolumeLoader, PrefetchDirection } from "./loaders/index.js";
13
13
  import { LoadSpec } from "./loaders/IVolumeLoader.js";
14
14
  import { OMEZarrLoader } from "./loaders/OmeZarrLoader.js";
@@ -26,4 +26,4 @@ export type { CreateLoaderOptions } from "./loaders/index.js";
26
26
  export type { IVolumeLoader, PerChannelCallback, ThreadableVolumeLoader } from "./loaders/IVolumeLoader.js";
27
27
  export type { ZarrLoaderFetchOptions } from "./loaders/OmeZarrLoader.js";
28
28
  export type { WorkerLoader } from "./workers/VolumeLoaderContext.js";
29
- export { Histogram, Lut, Line3d, remapControlPoints, View3d, Volume, VolumeDrawable, LoadSpec, VolumeMaker, VolumeCache, RequestQueue, SubscribableRequestQueue, PrefetchDirection, OMEZarrLoader, JsonImageInfoLoader, RawArrayLoader, type RawArrayData, type RawArrayInfo, type RawArrayLoaderOptions, TiffLoader, VolumeLoaderContext, VolumeLoadError, VolumeLoadErrorType, VolumeFileFormat, createVolumeLoader, Channel, Light, ViewportCorner, AREA_LIGHT, RENDERMODE_PATHTRACE, RENDERMODE_RAYMARCH, SKY_LIGHT, type CameraState, type ColorizeFeature, };
29
+ export { Histogram, Lut, Line3d, remapControlPoints, View3d, Volume, VolumeDrawable, LoadSpec, VolumeMaker, VolumeCache, RequestQueue, SubscribableRequestQueue, PrefetchDirection, OMEZarrLoader, JsonImageInfoLoader, RawArrayLoader, type RawArrayData, type RawArrayInfo, type RawArrayLoaderOptions, TiffLoader, VolumeLoaderContext, VolumeLoadError, VolumeLoadErrorType, VolumeFileFormat, createVolumeLoader, Channel, Light, ViewportCorner, AREA_LIGHT, RENDERMODE_PATHTRACE, RENDERMODE_RAYMARCH, SKY_LIGHT, type CameraState, type ColorizeFeature, type NumberType, };
@@ -1,9 +1,9 @@
1
1
  import { ThreadableVolumeLoader, type LoadSpec, type RawChannelDataCallback, type LoadedVolumeInfo } from "./IVolumeLoader.js";
2
2
  import type { ImageInfo } from "../ImageInfo.js";
3
3
  import type { VolumeDims } from "../VolumeDims.js";
4
- import { Uint8 } from "../types.js";
4
+ import { NumberType } from "../types.js";
5
5
  export type RawArrayData = {
6
- dtype: Uint8;
6
+ dtype: NumberType;
7
7
  shape: [number, number, number, number];
8
8
  buffer: DataView;
9
9
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aics/vole-core",
3
- "version": "4.0.0",
3
+ "version": "4.1.0",
4
4
  "description": "volume renderer for 3d, 4d, or 5d imaging data with OME-Zarr support",
5
5
  "main": "es/index.js",
6
6
  "type": "module",