@vitessce/spatial-utils 3.2.2 → 3.3.1

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.
@@ -1,4 +1,5 @@
1
1
  export { DOMAINS } from "./constants.js";
2
2
  export { GLOBAL_LABELS, DEFAULT_CELLS_LAYER, DEFAULT_MOLECULES_LAYER, DEFAULT_NEIGHBORHOODS_LAYER, DEFAULT_RASTER_DOMAIN_TYPE, DEFAULT_RASTER_LAYER_PROPS, DEFAULT_LAYER_TYPE_ORDERING, square, initializeLayerChannels, initializeRasterLayersAndChannels, getSourceFromLoader, isInterleaved, isRgb, getNgffAxes, getNgffAxesForTiff, coordinateTransformationsToMatrix, physicalSizeToMatrix, hexToRgb, getStatsForResolution, canLoadResolution, normalizeCoordinateTransformations } from "./spatial.js";
3
+ export { loadOmeZarr, guessTileSize, ZarritaPixelSource } from "./load-ome-zarr.js";
3
4
  export { toRgbUIString, getSingleSelectionStats, getMultiSelectionStats, getPhysicalSizeScalingMatrix, getBoundingCube, abbreviateNumber, filterSelection } from "./layer-controller.js";
4
5
  //# sourceMappingURL=index.d.ts.map
package/dist-tsc/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export { GLOBAL_LABELS, DEFAULT_CELLS_LAYER, DEFAULT_MOLECULES_LAYER, DEFAULT_NEIGHBORHOODS_LAYER, DEFAULT_RASTER_DOMAIN_TYPE, DEFAULT_RASTER_LAYER_PROPS, DEFAULT_LAYER_TYPE_ORDERING, square, initializeLayerChannels, initializeRasterLayersAndChannels, getSourceFromLoader, isInterleaved, isRgb, getNgffAxes, getNgffAxesForTiff, coordinateTransformationsToMatrix, physicalSizeToMatrix, hexToRgb, getStatsForResolution, canLoadResolution, normalizeCoordinateTransformations, } from './spatial.js';
2
+ export { loadOmeZarr, guessTileSize, ZarritaPixelSource, } from './load-ome-zarr.js';
2
3
  export { toRgbUIString, getSingleSelectionStats, getMultiSelectionStats, getPhysicalSizeScalingMatrix, getBoundingCube, abbreviateNumber, filterSelection, } from './layer-controller.js';
3
4
  export { DOMAINS, } from './constants.js';
@@ -0,0 +1,11 @@
1
+ export function guessTileSize(arr: any): number;
2
+ export function loadOmeZarr(url: any, requestInit: any): Promise<{
3
+ data: ZarritaPixelSource[];
4
+ metadata: import("zarrita").Attributes;
5
+ }>;
6
+ export class ZarritaPixelSource extends viv.ZarrPixelSource<any> {
7
+ constructor(arr: any, labels: any, tileSize: any);
8
+ _readChunks: boolean;
9
+ }
10
+ import { viv } from "@vitessce/gl";
11
+ //# sourceMappingURL=load-ome-zarr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-ome-zarr.d.ts","sourceRoot":"","sources":["../src/load-ome-zarr.js"],"names":[],"mappings":"AAkBA,gDAMC;AAiDD;;;GAcC;AA9BD;IACE,kDASC;IADC,qBAAwB;CAE3B"}
@@ -0,0 +1,75 @@
1
+ import { viv } from '@vitessce/gl';
2
+ import { open as zarrOpen } from 'zarrita';
3
+ import { zarrOpenRoot, createZarrArrayAdapter } from '@vitessce/zarr-utils';
4
+ function prevPowerOf2(x) {
5
+ return 2 ** Math.floor(Math.log2(x));
6
+ }
7
+ /*
8
+ * Helper method to determine whether pixel data is interleaved or not.
9
+ * > isInterleaved([1, 24, 24]) === false;
10
+ * > isInterleaved([1, 24, 24, 3]) === true;
11
+ */
12
+ function isInterleaved(shape) {
13
+ const lastDimSize = shape[shape.length - 1];
14
+ return lastDimSize === 3 || lastDimSize === 4;
15
+ }
16
+ export function guessTileSize(arr) {
17
+ const interleaved = isInterleaved(arr.shape);
18
+ const [yChunk, xChunk] = arr.chunks.slice(interleaved ? -3 : -2);
19
+ const size = Math.min(yChunk, xChunk);
20
+ // deck.gl requirement for power-of-two tile size.
21
+ return prevPowerOf2(size);
22
+ }
23
+ function isAxis(axisOrLabel) {
24
+ return typeof axisOrLabel[0] !== 'string';
25
+ }
26
+ async function loadMultiscales(root) {
27
+ const rootAttrs = (await zarrOpen(root)).attrs;
28
+ let paths = ['0'];
29
+ // Default axes used for v0.1 and v0.2.
30
+ let labels = ['t', 'c', 'z', 'y', 'x'];
31
+ if ('multiscales' in rootAttrs) {
32
+ const { datasets, axes } = rootAttrs.multiscales[0];
33
+ paths = datasets.map(d => d.path);
34
+ if (axes) {
35
+ if (isAxis(axes)) {
36
+ labels = axes.map(axis => axis.name);
37
+ }
38
+ else {
39
+ labels = axes;
40
+ }
41
+ }
42
+ }
43
+ const data = paths
44
+ .map(path => zarrOpen(root.resolve(path), { kind: 'array' }));
45
+ return {
46
+ data: (await Promise.all(data)),
47
+ rootAttrs,
48
+ labels,
49
+ };
50
+ }
51
+ export class ZarritaPixelSource extends viv.ZarrPixelSource {
52
+ constructor(arr, labels, tileSize) {
53
+ super(arr, labels, tileSize);
54
+ // We prevent reading chunks directly, since Zarrita does not
55
+ // handle x/y chunk differences the same as zarr.js.
56
+ // TODO: fix this once fixed in either zarrita getChunk or
57
+ // in createZarrArrayAdapter.
58
+ // Reference: https://github.com/hms-dbmi/vizarr/pull/172#issuecomment-1714497516
59
+ // eslint-disable-next-line no-underscore-dangle
60
+ this._readChunks = false;
61
+ }
62
+ }
63
+ // We use our own loadOmeZarr function (instead of viv.loadOmeZarr)
64
+ // to bypass usage of zarr.js which is used in Viv's version.
65
+ export async function loadOmeZarr(url, requestInit) {
66
+ const root = await zarrOpenRoot(url, requestInit);
67
+ const { data, rootAttrs, labels } = await loadMultiscales(root);
68
+ const tileSize = guessTileSize(data[0]);
69
+ const pyramid = data
70
+ .map(arr => new ZarritaPixelSource(createZarrArrayAdapter(arr), labels, tileSize));
71
+ return {
72
+ data: pyramid,
73
+ metadata: rootAttrs,
74
+ };
75
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitessce/spatial-utils",
3
- "version": "3.2.2",
3
+ "version": "3.3.1",
4
4
  "author": "Gehlenborg Lab",
5
5
  "homepage": "http://vitessce.io",
6
6
  "repository": {
@@ -17,10 +17,12 @@
17
17
  ],
18
18
  "dependencies": {
19
19
  "lodash-es": "^4.17.21",
20
+ "zarrita": "0.4.0-next.4",
20
21
  "math.gl": "^3.5.6",
21
22
  "mathjs": "^9.2.0",
22
- "@vitessce/gl": "3.2.2",
23
- "@vitessce/utils": "3.2.2"
23
+ "@vitessce/gl": "3.3.1",
24
+ "@vitessce/zarr-utils": "3.3.1",
25
+ "@vitessce/utils": "3.3.1"
24
26
  },
25
27
  "scripts": {
26
28
  "bundle": "pnpm exec vite build -c ../../../scripts/vite.config.js",
package/src/index.js CHANGED
@@ -21,6 +21,11 @@ export {
21
21
  canLoadResolution,
22
22
  normalizeCoordinateTransformations,
23
23
  } from './spatial.js';
24
+ export {
25
+ loadOmeZarr,
26
+ guessTileSize,
27
+ ZarritaPixelSource,
28
+ } from './load-ome-zarr.js';
24
29
  export {
25
30
  toRgbUIString,
26
31
  getSingleSelectionStats,
@@ -0,0 +1,88 @@
1
+ import { viv } from '@vitessce/gl';
2
+ import { open as zarrOpen } from 'zarrita';
3
+ import { zarrOpenRoot, createZarrArrayAdapter } from '@vitessce/zarr-utils';
4
+
5
+ function prevPowerOf2(x) {
6
+ return 2 ** Math.floor(Math.log2(x));
7
+ }
8
+
9
+ /*
10
+ * Helper method to determine whether pixel data is interleaved or not.
11
+ * > isInterleaved([1, 24, 24]) === false;
12
+ * > isInterleaved([1, 24, 24, 3]) === true;
13
+ */
14
+ function isInterleaved(shape) {
15
+ const lastDimSize = shape[shape.length - 1];
16
+ return lastDimSize === 3 || lastDimSize === 4;
17
+ }
18
+
19
+ export function guessTileSize(arr) {
20
+ const interleaved = isInterleaved(arr.shape);
21
+ const [yChunk, xChunk] = arr.chunks.slice(interleaved ? -3 : -2);
22
+ const size = Math.min(yChunk, xChunk);
23
+ // deck.gl requirement for power-of-two tile size.
24
+ return prevPowerOf2(size);
25
+ }
26
+
27
+ function isAxis(axisOrLabel) {
28
+ return typeof axisOrLabel[0] !== 'string';
29
+ }
30
+
31
+ async function loadMultiscales(root) {
32
+ const rootAttrs = (await zarrOpen(root)).attrs;
33
+
34
+ let paths = ['0'];
35
+ // Default axes used for v0.1 and v0.2.
36
+ let labels = ['t', 'c', 'z', 'y', 'x'];
37
+ if ('multiscales' in rootAttrs) {
38
+ const { datasets, axes } = rootAttrs.multiscales[0];
39
+ paths = datasets.map(d => d.path);
40
+ if (axes) {
41
+ if (isAxis(axes)) {
42
+ labels = axes.map(axis => axis.name);
43
+ } else {
44
+ labels = axes;
45
+ }
46
+ }
47
+ }
48
+
49
+ const data = paths
50
+ .map(path => zarrOpen(root.resolve(path), { kind: 'array' }));
51
+ return {
52
+ data: (await Promise.all(data)),
53
+ rootAttrs,
54
+ labels,
55
+ };
56
+ }
57
+
58
+ export class ZarritaPixelSource extends viv.ZarrPixelSource {
59
+ constructor(arr, labels, tileSize) {
60
+ super(arr, labels, tileSize);
61
+ // We prevent reading chunks directly, since Zarrita does not
62
+ // handle x/y chunk differences the same as zarr.js.
63
+ // TODO: fix this once fixed in either zarrita getChunk or
64
+ // in createZarrArrayAdapter.
65
+ // Reference: https://github.com/hms-dbmi/vizarr/pull/172#issuecomment-1714497516
66
+ // eslint-disable-next-line no-underscore-dangle
67
+ this._readChunks = false;
68
+ }
69
+ }
70
+
71
+
72
+ // We use our own loadOmeZarr function (instead of viv.loadOmeZarr)
73
+ // to bypass usage of zarr.js which is used in Viv's version.
74
+ export async function loadOmeZarr(url, requestInit) {
75
+ const root = await zarrOpenRoot(url, requestInit);
76
+ const { data, rootAttrs, labels } = await loadMultiscales(root);
77
+ const tileSize = guessTileSize(data[0]);
78
+ const pyramid = data
79
+ .map(arr => new ZarritaPixelSource(
80
+ createZarrArrayAdapter(arr),
81
+ labels,
82
+ tileSize,
83
+ ));
84
+ return {
85
+ data: pyramid,
86
+ metadata: rootAttrs,
87
+ };
88
+ }