@fideus-labs/ngff-zarr 0.1.0 → 0.2.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/README.md +1 -0
- package/esm/io/itk_image_to_ngff_image.d.ts +5 -0
- package/esm/io/itk_image_to_ngff_image.d.ts.map +1 -1
- package/esm/io/itk_image_to_ngff_image.js +20 -20
- package/esm/io/ngff_image_to_itk_image.d.ts.map +1 -1
- package/esm/io/ngff_image_to_itk_image.js +2 -0
- package/esm/io/to_multiscales.js +1 -1
- package/esm/io/to_ngff_zarr.js +16 -0
- package/esm/methods/itkwasm.d.ts.map +1 -1
- package/esm/methods/itkwasm.js +568 -426
- package/esm/schemas/coordinate_systems.d.ts +159 -552
- package/esm/schemas/coordinate_systems.d.ts.map +1 -1
- package/esm/schemas/coordinate_systems.js +0 -1
- package/esm/schemas/ome_zarr.d.ts +105 -69
- package/esm/schemas/ome_zarr.d.ts.map +1 -1
- package/esm/schemas/rfc4.d.ts +26 -131
- package/esm/schemas/rfc4.d.ts.map +1 -1
- package/esm/schemas/units.d.ts +70 -5
- package/esm/schemas/units.d.ts.map +1 -1
- package/esm/schemas/units.js +2 -15
- package/esm/schemas/zarr_metadata.d.ts +13 -300
- package/esm/schemas/zarr_metadata.d.ts.map +1 -1
- package/package.json +1 -1
- package/script/io/itk_image_to_ngff_image.d.ts +5 -0
- package/script/io/itk_image_to_ngff_image.d.ts.map +1 -1
- package/script/io/itk_image_to_ngff_image.js +20 -20
- package/script/io/ngff_image_to_itk_image.d.ts.map +1 -1
- package/script/io/ngff_image_to_itk_image.js +2 -0
- package/script/io/to_multiscales.js +1 -1
- package/script/io/to_ngff_zarr.js +16 -0
- package/script/methods/itkwasm.d.ts.map +1 -1
- package/script/methods/itkwasm.js +567 -425
- package/script/schemas/coordinate_systems.d.ts +159 -552
- package/script/schemas/coordinate_systems.d.ts.map +1 -1
- package/script/schemas/coordinate_systems.js +0 -1
- package/script/schemas/ome_zarr.d.ts +105 -69
- package/script/schemas/ome_zarr.d.ts.map +1 -1
- package/script/schemas/rfc4.d.ts +26 -131
- package/script/schemas/rfc4.d.ts.map +1 -1
- package/script/schemas/units.d.ts +70 -5
- package/script/schemas/units.d.ts.map +1 -1
- package/script/schemas/units.js +2 -15
- package/script/schemas/zarr_metadata.d.ts +13 -300
- package/script/schemas/zarr_metadata.d.ts.map +1 -1
package/README.md
CHANGED
|
@@ -45,6 +45,7 @@ The main Python package provides:
|
|
|
45
45
|
- [Sharded Zarr] stores
|
|
46
46
|
- Optional writing via zarr-python 2, zarr-python 3, [tensorstore] or zarrita (TypeScript)
|
|
47
47
|
- [Anatomical orientation metadata](./docs/rfc4.md) (RFC-4)
|
|
48
|
+
- **OME-Zarr Zip (.ozx) file support** for single-file OME-Zarr datasets (RFC-9)
|
|
48
49
|
- **High Content Screening (HCS) support** for plate and well data
|
|
49
50
|
- **Model Context Protocol (MCP) server** for AI agent integration
|
|
50
51
|
|
|
@@ -9,6 +9,11 @@ export interface ItkImageToNgffImageOptions {
|
|
|
9
9
|
* @default true
|
|
10
10
|
*/
|
|
11
11
|
addAnatomicalOrientation?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Path prefix for the zarr array (e.g., "scale0/", "scale1/")
|
|
14
|
+
* @default "image"
|
|
15
|
+
*/
|
|
16
|
+
path?: string;
|
|
12
17
|
}
|
|
13
18
|
/**
|
|
14
19
|
* Convert an ITK-Wasm Image to an NgffImage, preserving spatial metadata.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"itk_image_to_ngff_image.d.ts","sourceRoot":"","sources":["../../src/io/itk_image_to_ngff_image.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAOnD,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"itk_image_to_ngff_image.d.ts","sourceRoot":"","sources":["../../src/io/itk_image_to_ngff_image.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEtC,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAOnD,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,KAAK,EACf,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,SAAS,CAAC,CAmHpB"}
|
|
@@ -20,10 +20,12 @@ import { _zarrita_internal_get_strides as getStrides } from "zarrita";
|
|
|
20
20
|
* @returns Promise resolving to NgffImage
|
|
21
21
|
*/
|
|
22
22
|
export async function itkImageToNgffImage(itkImage, options = {}) {
|
|
23
|
-
const { addAnatomicalOrientation = true } = options;
|
|
23
|
+
const { addAnatomicalOrientation = true, path = "image" } = options;
|
|
24
24
|
// Extract image properties from ITK-Wasm Image
|
|
25
25
|
const _data = itkImage.data;
|
|
26
|
-
|
|
26
|
+
// ITK stores size in physical space order [x, y, z], but the data buffer is in
|
|
27
|
+
// C-order (row-major) which means [z, y, x] indexing. Reverse to match data layout.
|
|
28
|
+
const shape = [...itkImage.size].reverse();
|
|
27
29
|
const spacing = itkImage.spacing;
|
|
28
30
|
const origin = itkImage.origin;
|
|
29
31
|
const ndim = shape.length;
|
|
@@ -60,32 +62,27 @@ export async function itkImageToNgffImage(itkImage, options = {}) {
|
|
|
60
62
|
// Identify spatial dimensions
|
|
61
63
|
const allSpatialDims = new Set(["x", "y", "z"]);
|
|
62
64
|
const spatialDims = dims.filter((dim) => allSpatialDims.has(dim));
|
|
63
|
-
// Create scale mapping from spacing
|
|
65
|
+
// Create scale mapping from spacing
|
|
66
|
+
// ITK stores spacing/origin in physical space order (x, y, z),
|
|
67
|
+
// but we need to map them to array order (z, y, x).
|
|
68
|
+
// Reverse the arrays to convert from physical to array order, matching Python implementation.
|
|
64
69
|
const scale = {};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const spatialIndex = itkSpatialOrder.indexOf(dim);
|
|
69
|
-
if (spatialIndex === -1) {
|
|
70
|
-
throw new Error(`Unknown spatial dimension: ${dim}`);
|
|
71
|
-
}
|
|
72
|
-
scale[dim] = spacing[spatialIndex];
|
|
70
|
+
const reversedSpacing = spacing.slice().reverse();
|
|
71
|
+
spatialDims.forEach((dim, idx) => {
|
|
72
|
+
scale[dim] = reversedSpacing[idx];
|
|
73
73
|
});
|
|
74
|
-
// Create translation mapping from origin
|
|
74
|
+
// Create translation mapping from origin
|
|
75
75
|
const translation = {};
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
throw new Error(`Unknown spatial dimension: ${dim}`);
|
|
80
|
-
}
|
|
81
|
-
translation[dim] = origin[spatialIndex];
|
|
76
|
+
const reversedOrigin = origin.slice().reverse();
|
|
77
|
+
spatialDims.forEach((dim, idx) => {
|
|
78
|
+
translation[dim] = reversedOrigin[idx];
|
|
82
79
|
});
|
|
83
80
|
// Create Zarr array from ITK-Wasm data
|
|
84
81
|
const store = new Map();
|
|
85
82
|
const root = zarr.root(store);
|
|
86
83
|
// Determine appropriate chunk size
|
|
87
84
|
const chunkShape = shape.map((s) => Math.min(s, 256));
|
|
88
|
-
const zarrArray = await zarr.create(root.resolve(
|
|
85
|
+
const zarrArray = await zarr.create(root.resolve(path), {
|
|
89
86
|
shape: shape,
|
|
90
87
|
chunk_shape: chunkShape,
|
|
91
88
|
data_type: imageType.componentType,
|
|
@@ -96,10 +93,13 @@ export async function itkImageToNgffImage(itkImage, options = {}) {
|
|
|
96
93
|
// Create a selection that covers the entire array (null means "all" for each dimension)
|
|
97
94
|
const selection = new Array(ndim).fill(null);
|
|
98
95
|
// Create a chunk object with the ITK-Wasm data in zarrita format
|
|
96
|
+
// ITK-Wasm stores data in column-major order with size [x, y, z],
|
|
97
|
+
// which has the same memory layout as C-order (row-major) with shape [z, y, x].
|
|
98
|
+
// We reversed the shape above, and now use C-order strides for that reversed shape.
|
|
99
99
|
const dataChunk = {
|
|
100
100
|
data: itkImage.data,
|
|
101
101
|
shape: shape,
|
|
102
|
-
stride: getStrides(shape, "C"), // C-order
|
|
102
|
+
stride: getStrides(shape, "C"), // C-order strides for the reversed shape
|
|
103
103
|
};
|
|
104
104
|
// Write all data to the zarr array using zarrita's set function
|
|
105
105
|
// This handles chunking and encoding automatically
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngff_image_to_itk_image.d.ts","sourceRoot":"","sources":["../../src/io/ngff_image_to_itk_image.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH,OAAO,KAAK,EAEV,KAAK,EAKN,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAsED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"ngff_image_to_itk_image.d.ts","sourceRoot":"","sources":["../../src/io/ngff_image_to_itk_image.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH,OAAO,KAAK,EAEV,KAAK,EAKN,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAsED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,SAAS,EACpB,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,KAAK,CAAC,CAmMhB"}
|
|
@@ -168,6 +168,8 @@ export async function ngffImageToItkImage(ngffImage, options = {}) {
|
|
|
168
168
|
return order.indexOf(a) - order.indexOf(b);
|
|
169
169
|
});
|
|
170
170
|
// Create ITK spacing, origin, and size arrays
|
|
171
|
+
// sortedItkDims is already in physical space order [x, y, z]
|
|
172
|
+
// Mapping from dims extracts the correct values from NGFF's array order [z, y, x]
|
|
171
173
|
const spacing = sortedItkDims.map((dim) => workingImage.scale[dim] || 1.0);
|
|
172
174
|
const origin = sortedItkDims.map((dim) => workingImage.translation[dim] || 0.0);
|
|
173
175
|
const size = sortedItkDims.map((dim) => data.shape[dims.indexOf(dim)]);
|
package/esm/io/to_multiscales.js
CHANGED
|
@@ -47,7 +47,7 @@ export async function toMultiscales(image, options = {}) {
|
|
|
47
47
|
});
|
|
48
48
|
// Create datasets for all images
|
|
49
49
|
const datasets = images.map((img, index) => {
|
|
50
|
-
return createDataset(
|
|
50
|
+
return createDataset(`scale${index}`, img.dims.map((dim) => img.scale[dim]), img.dims.map((dim) => img.translation[dim]));
|
|
51
51
|
});
|
|
52
52
|
// Create metadata with method information
|
|
53
53
|
const methodMetadata = getMethodMetadata(method);
|
package/esm/io/to_ngff_zarr.js
CHANGED
|
@@ -194,6 +194,22 @@ async function writeChunkWithGet(zarrArray, image, chunkIndex) {
|
|
|
194
194
|
// Convert chunk data to target type
|
|
195
195
|
const targetTypedArrayConstructor = getTypedArrayConstructor(zarrArray.dtype);
|
|
196
196
|
const chunkTargetData = convertChunkToTargetType(chunkSourceData, zarrArray.dtype, targetTypedArrayConstructor);
|
|
197
|
+
// Validate chunk data size
|
|
198
|
+
const expectedSize = chunkShape.reduce((a, b) => a * b, 1);
|
|
199
|
+
const actualSize = chunkTargetData.byteLength /
|
|
200
|
+
(chunkTargetData
|
|
201
|
+
.BYTES_PER_ELEMENT || 1);
|
|
202
|
+
if (actualSize !== expectedSize) {
|
|
203
|
+
console.error(`[writeChunkWithGet] Chunk data size mismatch!`);
|
|
204
|
+
console.error(` Image shape:`, shape);
|
|
205
|
+
console.error(` Chunk index:`, chunkIndex);
|
|
206
|
+
console.error(` Chunk start:`, chunkStart);
|
|
207
|
+
console.error(` Chunk end:`, chunkEnd);
|
|
208
|
+
console.error(` Chunk shape:`, chunkShape);
|
|
209
|
+
console.error(` Expected size:`, expectedSize);
|
|
210
|
+
console.error(` Actual size:`, actualSize);
|
|
211
|
+
throw new Error(`Chunk data size mismatch: expected ${expectedSize} elements, got ${actualSize}`);
|
|
212
|
+
}
|
|
197
213
|
// Create the selection for writing to the target zarr array
|
|
198
214
|
const targetSelection = chunkStart.map((start, dim) => zarr.slice(start, chunkEnd[dim]));
|
|
199
215
|
// Write the chunk using zarrita's set function
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"itkwasm.d.ts","sourceRoot":"","sources":["../../src/methods/itkwasm.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"itkwasm.d.ts","sourceRoot":"","sources":["../../src/methods/itkwasm.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAknCnD;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,EACjD,SAAS,EAAE,UAAU,GAAG,YAAY,GAAG,aAAa,GACnD,OAAO,CAAC,SAAS,EAAE,CAAC,CA8HtB"}
|