@aics/vole-core 3.15.7 → 4.0.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/Histogram.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { isFloatTypeArray } from "./types.js";
1
2
  const NBINS = 256;
2
3
  /**
3
4
  * Builds a histogram with 256 bins from a data array. Assume data is 8 bit single channel grayscale.
@@ -59,20 +60,38 @@ export default class Histogram {
59
60
  }
60
61
  }
61
62
  }
62
-
63
- // return the bin index of the given data value
64
- static findBin(dataValue, dataMin, binSize, numBins) {
65
- let binIndex = Math.floor((dataValue - dataMin) / binSize);
66
- // for values that lie exactly on last bin we need to subtract one
67
- if (binIndex === numBins) {
68
- binIndex--;
63
+ static findBin(dataValue, dataMin, binSize, castToInt) {
64
+ const binIndex = (dataValue - dataMin) / binSize;
65
+ if (!castToInt) {
66
+ return binIndex;
69
67
  }
70
- return binIndex;
68
+ return Math.max(Math.min(Math.floor(binIndex), NBINS - 1), 0);
71
69
  }
72
70
 
73
- // return the bin index of the given data value
71
+ /**
72
+ * Returns the integer bin index for the given value. If a value is outside
73
+ * the histogram range, it will be clamped to the nearest bin.
74
+ */
74
75
  findBinOfValue(value) {
75
- return Histogram.findBin(value, this.min, this.binSize, NBINS);
76
+ return Histogram.findBin(value, this.min, this.binSize, true);
77
+ }
78
+
79
+ /**
80
+ * Returns a fractional bin index for the given value. If a value is not a bin
81
+ * boundary, returns an interpolated index. Note that this can return a value
82
+ * outside the range of valid bins.
83
+ */
84
+ findFractionalBinOfValue(value) {
85
+ return Histogram.findBin(value, this.min, this.binSize, false);
86
+ }
87
+
88
+ /**
89
+ * Returns an absolute data value from a given (integer or fractional) bin index.
90
+ * Note that, if the bin index is outside of the bin range, the returned value
91
+ * will also be outside the value range.
92
+ */
93
+ getValueFromBinIndex(binIndex) {
94
+ return this.min + binIndex * this.binSize;
76
95
  }
77
96
 
78
97
  /**
@@ -234,10 +253,34 @@ export default class Histogram {
234
253
  }
235
254
  }
236
255
  const bins = new Uint32Array(numBins).fill(0);
237
- const binSize = (max - min) / numBins === 0 ? 1 : (max - min) / numBins;
256
+
257
+ // Bins should have equal widths and span the data min to the data max. The
258
+ // handling of the max value is slightly different between integers and
259
+ // floats; in the float case, the last bin should have `max` as its
260
+ // inclusive upper bound, while in the integer case, the last bin should
261
+ // have an exclusive upper bound of `max + 1`.
262
+ //
263
+ // For example, let's say we have a data range of `[min=0, max=3]` and 4
264
+ // bins.
265
+ //
266
+ // If this is integer data, we want each bin to have ranges [0, 1), [1, 2),
267
+ // [2, 3), [3, 4), and a bin size of 1.
268
+ //
269
+ // |----|----|----|----|
270
+ // 0 1 2 3 4 <- exclusive
271
+ //
272
+ // For continuous (float) data, our bins should have ranges [0, 0.75),
273
+ // [0.75, 1.5), [1.5, 2.25), [2.25, 3] and a bin size of 0.75.
274
+ //
275
+ // |----|----|----|----|
276
+ // 0 0.75 1.5 2.25 3 <- inclusive
277
+ //
278
+
279
+ const binMax = isFloatTypeArray(arr) ? max : max + 1;
280
+ const binSize = binMax <= min ? 1 : (binMax - min) / numBins;
238
281
  for (let i = 0; i < arr.length; i++) {
239
282
  const item = arr[i];
240
- const binIndex = Histogram.findBin(item, min, binSize, numBins);
283
+ const binIndex = Histogram.findBin(item, min, binSize, true);
241
284
  bins[binIndex]++;
242
285
  }
243
286
  return {
@@ -1,4 +1,4 @@
1
- import type { TypedArray, NumberType } from "./types.js";
1
+ import { type TypedArray, type NumberType } from "./types.js";
2
2
  /**
3
3
  * Builds a histogram with 256 bins from a data array. Assume data is 8 bit single channel grayscale.
4
4
  * @class
@@ -19,8 +19,24 @@ export default class Histogram {
19
19
  private pixelCount;
20
20
  maxBin: number;
21
21
  constructor(data: TypedArray<NumberType>);
22
- static findBin(dataValue: number, dataMin: number, binSize: number, numBins: number): number;
22
+ private static findBin;
23
+ /**
24
+ * Returns the integer bin index for the given value. If a value is outside
25
+ * the histogram range, it will be clamped to the nearest bin.
26
+ */
23
27
  findBinOfValue(value: number): number;
28
+ /**
29
+ * Returns a fractional bin index for the given value. If a value is not a bin
30
+ * boundary, returns an interpolated index. Note that this can return a value
31
+ * outside the range of valid bins.
32
+ */
33
+ findFractionalBinOfValue(value: number): number;
34
+ /**
35
+ * Returns an absolute data value from a given (integer or fractional) bin index.
36
+ * Note that, if the bin index is outside of the bin range, the returned value
37
+ * will also be outside the value range.
38
+ */
39
+ getValueFromBinIndex(binIndex: number): number;
24
40
  /**
25
41
  * Return the min data value
26
42
  * @return {number}
@@ -27,6 +27,7 @@ export declare const ARRAY_CONSTRUCTORS: {
27
27
  float32: Float32ArrayConstructor;
28
28
  float64: Float64ArrayConstructor;
29
29
  };
30
+ export declare function isFloatTypeArray(array: TypedArray<NumberType>): array is Float32Array | Float64Array;
30
31
  export interface ColorizeFeature {
31
32
  idsToFeatureValue: DataTexture;
32
33
  featureValueToColor: DataTexture;
package/es/types.js CHANGED
@@ -13,6 +13,9 @@ export const ARRAY_CONSTRUCTORS = {
13
13
  float32: Float32Array,
14
14
  float64: Float64Array
15
15
  };
16
+ export function isFloatTypeArray(array) {
17
+ return array instanceof Float32Array || array instanceof Float64Array;
18
+ }
16
19
  /** If `FuseChannel.rgbColor` is this value, it is disabled from fusion. */
17
20
  export const FUSE_DISABLED_RGB_COLOR = 0;
18
21
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aics/vole-core",
3
- "version": "3.15.7",
3
+ "version": "4.0.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",