@vitessce/spatial-utils 3.1.2 → 3.1.3

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,5 +1,5 @@
1
1
  import { i as inflate_1 } from "./pako.esm-68f84e2a.js";
2
- import { B as BaseDecoder } from "./index-551fa504.js";
2
+ import { B as BaseDecoder } from "./index-e86d2626.js";
3
3
  import "react";
4
4
  class DeflateDecoder extends BaseDecoder {
5
5
  decodeBlock(buffer) {
@@ -133297,16 +133297,16 @@ function addDecoder(cases, importFn) {
133297
133297
  }
133298
133298
  cases.forEach((c) => registry$1.set(c, importFn));
133299
133299
  }
133300
- addDecoder([void 0, 1], () => import("./raw-8e22b1c4.js").then((m) => m.default));
133301
- addDecoder(5, () => import("./lzw-c3783269.js").then((m) => m.default));
133300
+ addDecoder([void 0, 1], () => import("./raw-01deac62.js").then((m) => m.default));
133301
+ addDecoder(5, () => import("./lzw-61ae68b2.js").then((m) => m.default));
133302
133302
  addDecoder(6, () => {
133303
133303
  throw new Error("old style JPEG compression is not supported.");
133304
133304
  });
133305
- addDecoder(7, () => import("./jpeg-d67d9d82.js").then((m) => m.default));
133306
- addDecoder([8, 32946], () => import("./deflate-6fd0bca9.js").then((m) => m.default));
133307
- addDecoder(32773, () => import("./packbits-209c03d7.js").then((m) => m.default));
133308
- addDecoder(34887, () => import("./lerc-522345a3.js").then((m) => m.default));
133309
- addDecoder(50001, () => import("./webimage-a5d2769c.js").then((m) => m.default));
133305
+ addDecoder(7, () => import("./jpeg-03b93228.js").then((m) => m.default));
133306
+ addDecoder([8, 32946], () => import("./deflate-e2811f40.js").then((m) => m.default));
133307
+ addDecoder(32773, () => import("./packbits-b1d8eca2.js").then((m) => m.default));
133308
+ addDecoder(34887, () => import("./lerc-d5a641c1.js").then((m) => m.default));
133309
+ addDecoder(50001, () => import("./webimage-f6e6dcb0.js").then((m) => m.default));
133310
133310
  function decodeRowAcc(row, stride) {
133311
133311
  let length2 = row.length - stride;
133312
133312
  let offset = 0;
@@ -144475,6 +144475,41 @@ function coordinateTransformationsToMatrix(coordinateTransformations, axes) {
144475
144475
  }
144476
144476
  return mat;
144477
144477
  }
144478
+ function normalizeCoordinateTransformations(coordinateTransformations, datasets) {
144479
+ var _a2;
144480
+ let result = [];
144481
+ if (Array.isArray(coordinateTransformations)) {
144482
+ result = coordinateTransformations.map((transform2) => {
144483
+ if (transform2.input && transform2.output) {
144484
+ const { type } = transform2;
144485
+ if (type === "translation") {
144486
+ return {
144487
+ type,
144488
+ translation: transform2.translation
144489
+ };
144490
+ }
144491
+ if (type === "scale") {
144492
+ return {
144493
+ type,
144494
+ scale: transform2.scale
144495
+ };
144496
+ }
144497
+ if (type === "identity") {
144498
+ return { type };
144499
+ }
144500
+ console.warn(`Coordinate transformation type "${type}" is not supported.`);
144501
+ }
144502
+ return transform2;
144503
+ });
144504
+ }
144505
+ if (Array.isArray((_a2 = datasets == null ? void 0 : datasets[0]) == null ? void 0 : _a2.coordinateTransformations)) {
144506
+ result = [
144507
+ ...datasets[0].coordinateTransformations,
144508
+ ...result
144509
+ ];
144510
+ }
144511
+ return result;
144512
+ }
144478
144513
  export {
144479
144514
  BaseDecoder as B,
144480
144515
  DEFAULT_CELLS_LAYER as D,
@@ -144493,5 +144528,6 @@ export {
144493
144528
  getNgffAxes as l,
144494
144529
  getNgffAxesForTiff as m,
144495
144530
  coordinateTransformationsToMatrix as n,
144531
+ normalizeCoordinateTransformations as o,
144496
144532
  square as s
144497
144533
  };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { D, e, a, b, c, d, G, n, l, m, h, i, f, j, k, s } from "./index-551fa504.js";
1
+ import { D, e, a, b, c, d, G, n, l, m, h, i, f, j, k, o, s } from "./index-e86d2626.js";
2
2
  import "react";
3
3
  export {
4
4
  D as DEFAULT_CELLS_LAYER,
@@ -16,5 +16,6 @@ export {
16
16
  f as initializeRasterLayersAndChannels,
17
17
  j as isInterleaved,
18
18
  k as isRgb,
19
+ o as normalizeCoordinateTransformations,
19
20
  s as square
20
21
  };
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-551fa504.js";
1
+ import { B as BaseDecoder } from "./index-e86d2626.js";
2
2
  import "react";
3
3
  const dctZigZag = new Int32Array([
4
4
  0,
@@ -1,5 +1,5 @@
1
1
  import { i as inflate_1 } from "./pako.esm-68f84e2a.js";
2
- import { g as getDefaultExportFromCjs, B as BaseDecoder } from "./index-551fa504.js";
2
+ import { g as getDefaultExportFromCjs, B as BaseDecoder } from "./index-e86d2626.js";
3
3
  import "react";
4
4
  const LercParameters = {
5
5
  Version: 0,
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-551fa504.js";
1
+ import { B as BaseDecoder } from "./index-e86d2626.js";
2
2
  import "react";
3
3
  const MIN_BITS = 9;
4
4
  const CLEAR_CODE = 256;
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-551fa504.js";
1
+ import { B as BaseDecoder } from "./index-e86d2626.js";
2
2
  import "react";
3
3
  class PackbitsDecoder extends BaseDecoder {
4
4
  decodeBlock(buffer) {
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-551fa504.js";
1
+ import { B as BaseDecoder } from "./index-e86d2626.js";
2
2
  import "react";
3
3
  class RawDecoder extends BaseDecoder {
4
4
  decodeBlock(buffer) {
@@ -1,4 +1,4 @@
1
- import { B as BaseDecoder } from "./index-551fa504.js";
1
+ import { B as BaseDecoder } from "./index-e86d2626.js";
2
2
  import "react";
3
3
  class WebImageDecoder extends BaseDecoder {
4
4
  constructor() {
@@ -1,2 +1,2 @@
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 } from "./spatial.js";
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, normalizeCoordinateTransformations } from "./spatial.js";
2
2
  //# sourceMappingURL=index.d.ts.map
package/dist-tsc/index.js CHANGED
@@ -1 +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, } from './spatial.js';
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, normalizeCoordinateTransformations, } from './spatial.js';
@@ -51,6 +51,17 @@ export function getNgffAxesForTiff(dimOrder: any): any;
51
51
  * @returns {Array<number>} Array of 16 numbers representing the Matrix4.
52
52
  */
53
53
  export function coordinateTransformationsToMatrix(coordinateTransformations: object[], axes: object[]): Array<number>;
54
+ /**
55
+ * Normalize coordinate transformations to the OME-NGFF v0.4 format,
56
+ * despite potentially being in the new format proposed in
57
+ * https://github.com/ome/ngff/pull/138 (As of 2023-09-02).
58
+ * @param {object[]|undefined} coordinateTransformations Value of
59
+ * multiscales[0].coordinateTransformations in either OME-NGFF v0.4 format
60
+ * or that proposed in https://github.com/ome/ngff/pull/138.
61
+ * @param {object[]} datasets Value of multiscales[0].datasets in OME-NGFF v0.4 format.
62
+ * @returns {object[]} Array of coordinateTransformations in OME-NGFF v0.4 format.
63
+ */
64
+ export function normalizeCoordinateTransformations(coordinateTransformations: object[] | undefined, datasets: object[]): object[];
54
65
  export const GLOBAL_LABELS: string[];
55
66
  export const DEFAULT_RASTER_DOMAIN_TYPE: "Min/Max";
56
67
  export namespace DEFAULT_RASTER_LAYER_PROPS {
@@ -1 +1 @@
1
- {"version":3,"file":"spatial.d.ts","sourceRoot":"","sources":["../src/spatial.js"],"names":[],"mappings":"AAOA,wDAEC;AAiCD;;;;;;GAMG;AACH,4CAJW,MAAM,UACN,MAAM,eACJ,MAAM,CAMlB;AAED;;;;GAIG;AACH,8BAHW,MAAM,YACN,QAAM,IAAI,WAiBpB;AAmHD;;GAEG;AACH,qCAFW,MAAO,MAAM,CAAC,WAKxB;AAED;;;;;;GAMG;AACH,gDALW,MAAM,eAEJ,MAAM,EAAE,CAuCpB;AAED;;;;;;;;;GASG;AACH,gEAJW,MAAM,EAAE,sBAER,CAAC,MAAM,EAAE,GAAC,IAAI,CAAC,+CAuEzB;AASD;;;IAuBC;AAED,uDAQC;AAED;;;;;;;;GAQG;AACH,6EANW,MAAM,EAAE,QAER,MAAM,EAAE,GAEN,MAAM,MAAM,CAAC,CA4CzB;AAtZD,qCAAwC;AAExC,mDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBpD,mDAKE"}
1
+ {"version":3,"file":"spatial.d.ts","sourceRoot":"","sources":["../src/spatial.js"],"names":[],"mappings":"AAOA,wDAEC;AAiCD;;;;;;GAMG;AACH,4CAJW,MAAM,UACN,MAAM,eACJ,MAAM,CAMlB;AAED;;;;GAIG;AACH,8BAHW,MAAM,YACN,QAAM,IAAI,WAiBpB;AAmHD;;GAEG;AACH,qCAFW,MAAO,MAAM,CAAC,WAKxB;AAED;;;;;;GAMG;AACH,gDALW,MAAM,eAEJ,MAAM,EAAE,CAuCpB;AAED;;;;;;;;;GASG;AACH,gEAJW,MAAM,EAAE,sBAER,CAAC,MAAM,EAAE,GAAC,IAAI,CAAC,+CAuEzB;AASD;;;IAuBC;AAED,uDAQC;AAED;;;;;;;;GAQG;AACH,6EANW,MAAM,EAAE,QAER,MAAM,EAAE,GAEN,MAAM,MAAM,CAAC,CA4CzB;AAED;;;;;;;;;GASG;AACH,8EANW,MAAM,EAAE,GAAC,SAAS,YAGlB,MAAM,EAAE,GACN,MAAM,EAAE,CAiDpB;AAjdD,qCAAwC;AAExC,mDAAoD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBpD,mDAKE"}
@@ -373,3 +373,58 @@ export function coordinateTransformationsToMatrix(coordinateTransformations, axe
373
373
  }
374
374
  return mat;
375
375
  }
376
+ /**
377
+ * Normalize coordinate transformations to the OME-NGFF v0.4 format,
378
+ * despite potentially being in the new format proposed in
379
+ * https://github.com/ome/ngff/pull/138 (As of 2023-09-02).
380
+ * @param {object[]|undefined} coordinateTransformations Value of
381
+ * multiscales[0].coordinateTransformations in either OME-NGFF v0.4 format
382
+ * or that proposed in https://github.com/ome/ngff/pull/138.
383
+ * @param {object[]} datasets Value of multiscales[0].datasets in OME-NGFF v0.4 format.
384
+ * @returns {object[]} Array of coordinateTransformations in OME-NGFF v0.4 format.
385
+ */
386
+ export function normalizeCoordinateTransformations(coordinateTransformations, datasets) {
387
+ // "The transformations in the list are applied sequentially and in order."
388
+ // Reference: https://ngff.openmicroscopy.org/0.4/index.html#trafo-md
389
+ let result = [];
390
+ if (Array.isArray(coordinateTransformations)) {
391
+ result = coordinateTransformations.map((transform) => {
392
+ if (transform.input && transform.output) {
393
+ // This is a new-style coordinate transformation.
394
+ // (As proposed in https://github.com/ome/ngff/pull/138)
395
+ const { type } = transform;
396
+ if (type === 'translation') {
397
+ return {
398
+ type,
399
+ translation: transform.translation,
400
+ };
401
+ }
402
+ if (type === 'scale') {
403
+ return {
404
+ type,
405
+ scale: transform.scale,
406
+ };
407
+ }
408
+ if (type === 'identity') {
409
+ return { type };
410
+ }
411
+ console.warn(`Coordinate transformation type "${type}" is not supported.`);
412
+ }
413
+ // Assume it was already an old-style (NGFF v0.4) coordinate transformation.
414
+ return transform;
415
+ });
416
+ }
417
+ if (Array.isArray(datasets?.[0]?.coordinateTransformations)) {
418
+ // "Datasets SHOULD define a transformation from array space
419
+ // to their "native physical space."
420
+ // This transformation SHOULD describe physical pixel spacing
421
+ // and origin only, and therefore SHOULD consist of
422
+ // `scale` and/or `translation` types only.""
423
+ // Reference: https://github.com/ome/ngff/blob/b92f540dc95440f2d6b7012185b09c2b862aa744/latest/transform-details.bs#L99
424
+ result = [
425
+ ...datasets[0].coordinateTransformations,
426
+ ...result,
427
+ ];
428
+ }
429
+ return result;
430
+ }
@@ -1,5 +1,5 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { square, coordinateTransformationsToMatrix } from './spatial.js';
2
+ import { square, coordinateTransformationsToMatrix, normalizeCoordinateTransformations, } from './spatial.js';
3
3
  const defaultAxes = [
4
4
  { type: 'time', name: 't' },
5
5
  { type: 'channel', name: 'c' },
@@ -41,4 +41,159 @@ describe('Spatial.js', () => {
41
41
  ]);
42
42
  });
43
43
  });
44
+ describe('normalizeCoordinateTransformations', () => {
45
+ it('does nothing for OME-NGFF v0.4 input', () => {
46
+ const datasets = [
47
+ {
48
+ coordinateTransformations: [
49
+ {
50
+ scale: [
51
+ 1,
52
+ 0.5002025531914894,
53
+ 0.3603981534640209,
54
+ 0.3603981534640209,
55
+ ],
56
+ type: 'scale',
57
+ },
58
+ ],
59
+ path: '0',
60
+ },
61
+ {
62
+ coordinateTransformations: [
63
+ {
64
+ scale: [
65
+ 1,
66
+ 0.5002025531914894,
67
+ 0.7207963069280418,
68
+ 0.7207963069280418,
69
+ ],
70
+ type: 'scale',
71
+ },
72
+ ],
73
+ path: '1',
74
+ },
75
+ {
76
+ coordinateTransformations: [
77
+ {
78
+ scale: [
79
+ 1,
80
+ 0.5002025531914894,
81
+ 1.4415926138560835,
82
+ 1.4415926138560835,
83
+ ],
84
+ type: 'scale',
85
+ },
86
+ ],
87
+ path: '2',
88
+ },
89
+ ];
90
+ expect(normalizeCoordinateTransformations(undefined, datasets)).toEqual([
91
+ // Here, we expect only the first dataset to be used.
92
+ // However, we should eventually support transforms
93
+ // specified for each dataset individually,
94
+ // since there could in theory be irregular ways of downsampling.
95
+ {
96
+ scale: [
97
+ 1,
98
+ 0.5002025531914894,
99
+ 0.3603981534640209,
100
+ 0.3603981534640209,
101
+ ],
102
+ type: 'scale',
103
+ },
104
+ ]);
105
+ });
106
+ it('transforms SpatialData input', () => {
107
+ const newCoordinateTransformations = [
108
+ {
109
+ input: {
110
+ axes: [
111
+ {
112
+ name: 'c',
113
+ type: 'channel',
114
+ },
115
+ {
116
+ name: 'y',
117
+ type: 'space',
118
+ unit: 'unit',
119
+ },
120
+ {
121
+ name: 'x',
122
+ type: 'space',
123
+ unit: 'unit',
124
+ },
125
+ ],
126
+ name: 'cyx',
127
+ },
128
+ output: {
129
+ axes: [
130
+ {
131
+ name: 'c',
132
+ type: 'channel',
133
+ },
134
+ {
135
+ name: 'y',
136
+ type: 'space',
137
+ unit: 'unit',
138
+ },
139
+ {
140
+ name: 'x',
141
+ type: 'space',
142
+ unit: 'unit',
143
+ },
144
+ ],
145
+ name: 'ST8059048',
146
+ },
147
+ scale: [
148
+ 1.0,
149
+ 8.670500183814605,
150
+ 8.670500183814605,
151
+ ],
152
+ type: 'scale',
153
+ },
154
+ ];
155
+ const datasets = [
156
+ {
157
+ coordinateTransformations: [
158
+ {
159
+ scale: [
160
+ 1.0,
161
+ 1.0,
162
+ 1.0,
163
+ ],
164
+ type: 'scale',
165
+ },
166
+ ],
167
+ path: '0',
168
+ },
169
+ ];
170
+ expect(normalizeCoordinateTransformations(newCoordinateTransformations, datasets)).toEqual([
171
+ // Here, we expect only the first dataset to be used.
172
+ // However, we should eventually support transforms
173
+ // specified for each dataset individually,
174
+ // since there could in theory be irregular ways of downsampling.
175
+ {
176
+ scale: [
177
+ 1.0,
178
+ 1.0,
179
+ 1.0,
180
+ ],
181
+ type: 'scale',
182
+ },
183
+ // We expect the dataset transform to be prepended
184
+ // to the newCoordinateTransformations items.
185
+ // We do not check the input/output coordinate systems, but we should eventually allow
186
+ // the user to specify this somehow and use that information to filter which transforms
187
+ // are included here.
188
+ {
189
+ scale: [
190
+ 1.0,
191
+ 8.670500183814605,
192
+ 8.670500183814605,
193
+ ],
194
+ type: 'scale',
195
+ },
196
+ ]);
197
+ });
198
+ });
44
199
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vitessce/spatial-utils",
3
- "version": "3.1.2",
3
+ "version": "3.1.3",
4
4
  "author": "Gehlenborg Lab",
5
5
  "homepage": "http://vitessce.io",
6
6
  "repository": {
@@ -19,8 +19,8 @@
19
19
  "lodash-es": "^4.17.21",
20
20
  "math.gl": "^3.5.6",
21
21
  "mathjs": "^9.2.0",
22
- "@vitessce/gl": "3.1.2",
23
- "@vitessce/utils": "3.1.2"
22
+ "@vitessce/gl": "3.1.3",
23
+ "@vitessce/utils": "3.1.3"
24
24
  },
25
25
  "scripts": {
26
26
  "bundle": "pnpm exec vite build -c ../../../scripts/vite.config.js",
package/src/index.js CHANGED
@@ -15,4 +15,5 @@ export {
15
15
  getNgffAxes,
16
16
  getNgffAxesForTiff,
17
17
  coordinateTransformationsToMatrix,
18
+ normalizeCoordinateTransformations,
18
19
  } from './spatial.js';
package/src/spatial.js CHANGED
@@ -416,3 +416,62 @@ export function coordinateTransformationsToMatrix(coordinateTransformations, axe
416
416
  }
417
417
  return mat;
418
418
  }
419
+
420
+ /**
421
+ * Normalize coordinate transformations to the OME-NGFF v0.4 format,
422
+ * despite potentially being in the new format proposed in
423
+ * https://github.com/ome/ngff/pull/138 (As of 2023-09-02).
424
+ * @param {object[]|undefined} coordinateTransformations Value of
425
+ * multiscales[0].coordinateTransformations in either OME-NGFF v0.4 format
426
+ * or that proposed in https://github.com/ome/ngff/pull/138.
427
+ * @param {object[]} datasets Value of multiscales[0].datasets in OME-NGFF v0.4 format.
428
+ * @returns {object[]} Array of coordinateTransformations in OME-NGFF v0.4 format.
429
+ */
430
+ export function normalizeCoordinateTransformations(coordinateTransformations, datasets) {
431
+ // "The transformations in the list are applied sequentially and in order."
432
+ // Reference: https://ngff.openmicroscopy.org/0.4/index.html#trafo-md
433
+ let result = [];
434
+
435
+ if (Array.isArray(coordinateTransformations)) {
436
+ result = coordinateTransformations.map((transform) => {
437
+ if (transform.input && transform.output) {
438
+ // This is a new-style coordinate transformation.
439
+ // (As proposed in https://github.com/ome/ngff/pull/138)
440
+ const { type } = transform;
441
+ if (type === 'translation') {
442
+ return {
443
+ type,
444
+ translation: transform.translation,
445
+ };
446
+ }
447
+ if (type === 'scale') {
448
+ return {
449
+ type,
450
+ scale: transform.scale,
451
+ };
452
+ }
453
+ if (type === 'identity') {
454
+ return { type };
455
+ }
456
+ console.warn(`Coordinate transformation type "${type}" is not supported.`);
457
+ }
458
+ // Assume it was already an old-style (NGFF v0.4) coordinate transformation.
459
+ return transform;
460
+ });
461
+ }
462
+
463
+ if (Array.isArray(datasets?.[0]?.coordinateTransformations)) {
464
+ // "Datasets SHOULD define a transformation from array space
465
+ // to their "native physical space."
466
+ // This transformation SHOULD describe physical pixel spacing
467
+ // and origin only, and therefore SHOULD consist of
468
+ // `scale` and/or `translation` types only.""
469
+ // Reference: https://github.com/ome/ngff/blob/b92f540dc95440f2d6b7012185b09c2b862aa744/latest/transform-details.bs#L99
470
+
471
+ result = [
472
+ ...datasets[0].coordinateTransformations,
473
+ ...result,
474
+ ];
475
+ }
476
+ return result;
477
+ }
@@ -1,5 +1,9 @@
1
1
  import { describe, it, expect } from 'vitest';
2
- import { square, coordinateTransformationsToMatrix } from './spatial.js';
2
+ import {
3
+ square,
4
+ coordinateTransformationsToMatrix,
5
+ normalizeCoordinateTransformations,
6
+ } from './spatial.js';
3
7
 
4
8
  const defaultAxes = [
5
9
  { type: 'time', name: 't' },
@@ -43,4 +47,159 @@ describe('Spatial.js', () => {
43
47
  ]);
44
48
  });
45
49
  });
50
+ describe('normalizeCoordinateTransformations', () => {
51
+ it('does nothing for OME-NGFF v0.4 input', () => {
52
+ const datasets = [
53
+ {
54
+ coordinateTransformations: [
55
+ {
56
+ scale: [
57
+ 1,
58
+ 0.5002025531914894,
59
+ 0.3603981534640209,
60
+ 0.3603981534640209,
61
+ ],
62
+ type: 'scale',
63
+ },
64
+ ],
65
+ path: '0',
66
+ },
67
+ {
68
+ coordinateTransformations: [
69
+ {
70
+ scale: [
71
+ 1,
72
+ 0.5002025531914894,
73
+ 0.7207963069280418,
74
+ 0.7207963069280418,
75
+ ],
76
+ type: 'scale',
77
+ },
78
+ ],
79
+ path: '1',
80
+ },
81
+ {
82
+ coordinateTransformations: [
83
+ {
84
+ scale: [
85
+ 1,
86
+ 0.5002025531914894,
87
+ 1.4415926138560835,
88
+ 1.4415926138560835,
89
+ ],
90
+ type: 'scale',
91
+ },
92
+ ],
93
+ path: '2',
94
+ },
95
+ ];
96
+ expect(normalizeCoordinateTransformations(undefined, datasets)).toEqual([
97
+ // Here, we expect only the first dataset to be used.
98
+ // However, we should eventually support transforms
99
+ // specified for each dataset individually,
100
+ // since there could in theory be irregular ways of downsampling.
101
+ {
102
+ scale: [
103
+ 1,
104
+ 0.5002025531914894,
105
+ 0.3603981534640209,
106
+ 0.3603981534640209,
107
+ ],
108
+ type: 'scale',
109
+ },
110
+ ]);
111
+ });
112
+ it('transforms SpatialData input', () => {
113
+ const newCoordinateTransformations = [
114
+ {
115
+ input: {
116
+ axes: [
117
+ {
118
+ name: 'c',
119
+ type: 'channel',
120
+ },
121
+ {
122
+ name: 'y',
123
+ type: 'space',
124
+ unit: 'unit',
125
+ },
126
+ {
127
+ name: 'x',
128
+ type: 'space',
129
+ unit: 'unit',
130
+ },
131
+ ],
132
+ name: 'cyx',
133
+ },
134
+ output: {
135
+ axes: [
136
+ {
137
+ name: 'c',
138
+ type: 'channel',
139
+ },
140
+ {
141
+ name: 'y',
142
+ type: 'space',
143
+ unit: 'unit',
144
+ },
145
+ {
146
+ name: 'x',
147
+ type: 'space',
148
+ unit: 'unit',
149
+ },
150
+ ],
151
+ name: 'ST8059048',
152
+ },
153
+ scale: [
154
+ 1.0,
155
+ 8.670500183814605,
156
+ 8.670500183814605,
157
+ ],
158
+ type: 'scale',
159
+ },
160
+ ];
161
+ const datasets = [
162
+ {
163
+ coordinateTransformations: [
164
+ {
165
+ scale: [
166
+ 1.0,
167
+ 1.0,
168
+ 1.0,
169
+ ],
170
+ type: 'scale',
171
+ },
172
+ ],
173
+ path: '0',
174
+ },
175
+ ];
176
+ expect(normalizeCoordinateTransformations(newCoordinateTransformations, datasets)).toEqual([
177
+ // Here, we expect only the first dataset to be used.
178
+ // However, we should eventually support transforms
179
+ // specified for each dataset individually,
180
+ // since there could in theory be irregular ways of downsampling.
181
+ {
182
+ scale: [
183
+ 1.0,
184
+ 1.0,
185
+ 1.0,
186
+ ],
187
+ type: 'scale',
188
+ },
189
+ // We expect the dataset transform to be prepended
190
+ // to the newCoordinateTransformations items.
191
+ // We do not check the input/output coordinate systems, but we should eventually allow
192
+ // the user to specify this somehow and use that information to filter which transforms
193
+ // are included here.
194
+ {
195
+ scale: [
196
+ 1.0,
197
+ 8.670500183814605,
198
+ 8.670500183814605,
199
+ ],
200
+ type: 'scale',
201
+ },
202
+ ]);
203
+ });
204
+ });
46
205
  });