@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.
- package/dist/{deflate-6fd0bca9.js → deflate-e2811f40.js} +1 -1
- package/dist/{index-551fa504.js → index-e86d2626.js} +43 -7
- package/dist/index.js +2 -1
- package/dist/{jpeg-d67d9d82.js → jpeg-03b93228.js} +1 -1
- package/dist/{lerc-522345a3.js → lerc-d5a641c1.js} +1 -1
- package/dist/{lzw-c3783269.js → lzw-61ae68b2.js} +1 -1
- package/dist/{packbits-209c03d7.js → packbits-b1d8eca2.js} +1 -1
- package/dist/{raw-8e22b1c4.js → raw-01deac62.js} +1 -1
- package/dist/{webimage-a5d2769c.js → webimage-f6e6dcb0.js} +1 -1
- package/dist-tsc/index.d.ts +1 -1
- package/dist-tsc/index.js +1 -1
- package/dist-tsc/spatial.d.ts +11 -0
- package/dist-tsc/spatial.d.ts.map +1 -1
- package/dist-tsc/spatial.js +55 -0
- package/dist-tsc/spatial.test.js +156 -1
- package/package.json +3 -3
- package/src/index.js +1 -0
- package/src/spatial.js +59 -0
- package/src/spatial.test.js +160 -1
|
@@ -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-
|
|
133301
|
-
addDecoder(5, () => import("./lzw-
|
|
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-
|
|
133306
|
-
addDecoder([8, 32946], () => import("./deflate-
|
|
133307
|
-
addDecoder(32773, () => import("./packbits-
|
|
133308
|
-
addDecoder(34887, () => import("./lerc-
|
|
133309
|
-
addDecoder(50001, () => import("./webimage-
|
|
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-
|
|
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,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-
|
|
2
|
+
import { g as getDefaultExportFromCjs, B as BaseDecoder } from "./index-e86d2626.js";
|
|
3
3
|
import "react";
|
|
4
4
|
const LercParameters = {
|
|
5
5
|
Version: 0,
|
package/dist-tsc/index.d.ts
CHANGED
|
@@ -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';
|
package/dist-tsc/spatial.d.ts
CHANGED
|
@@ -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;
|
|
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"}
|
package/dist-tsc/spatial.js
CHANGED
|
@@ -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
|
+
}
|
package/dist-tsc/spatial.test.js
CHANGED
|
@@ -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.
|
|
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.
|
|
23
|
-
"@vitessce/utils": "3.1.
|
|
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
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
|
+
}
|
package/src/spatial.test.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import {
|
|
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
|
});
|