@fideus-labs/ngff-zarr 0.0.1 → 0.1.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.
Files changed (174) hide show
  1. package/README.md +9 -2
  2. package/esm/io/from_ngff_zarr.d.ts +4 -1
  3. package/esm/io/from_ngff_zarr.d.ts.map +1 -1
  4. package/esm/io/from_ngff_zarr.js +94 -27
  5. package/esm/io/hcs.d.ts +18 -0
  6. package/esm/io/hcs.d.ts.map +1 -0
  7. package/esm/io/hcs.js +51 -0
  8. package/esm/io/itk_image_to_ngff_image.d.ts +25 -0
  9. package/esm/io/itk_image_to_ngff_image.d.ts.map +1 -0
  10. package/esm/io/itk_image_to_ngff_image.js +127 -0
  11. package/esm/io/ngff_image_to_itk_image.d.ts +30 -0
  12. package/esm/io/ngff_image_to_itk_image.d.ts.map +1 -0
  13. package/esm/io/ngff_image_to_itk_image.js +216 -0
  14. package/esm/io/to_multiscales.d.ts +18 -0
  15. package/esm/io/to_multiscales.d.ts.map +1 -0
  16. package/esm/io/to_multiscales.js +62 -0
  17. package/esm/io/to_ngff_image.d.ts +17 -0
  18. package/esm/io/to_ngff_image.d.ts.map +1 -0
  19. package/esm/io/to_ngff_image.js +136 -0
  20. package/esm/io/to_ngff_zarr.d.ts +3 -2
  21. package/esm/io/to_ngff_zarr.d.ts.map +1 -1
  22. package/esm/io/to_ngff_zarr.js +273 -26
  23. package/esm/methods/itkwasm.d.ts +6 -0
  24. package/esm/methods/itkwasm.d.ts.map +1 -0
  25. package/esm/methods/itkwasm.js +816 -0
  26. package/esm/mod.d.ts +9 -2
  27. package/esm/mod.d.ts.map +1 -1
  28. package/esm/mod.js +10 -2
  29. package/esm/schemas/coordinate_systems.d.ts +644 -0
  30. package/esm/schemas/coordinate_systems.d.ts.map +1 -0
  31. package/esm/schemas/coordinate_systems.js +140 -0
  32. package/esm/schemas/index.d.ts +9 -0
  33. package/esm/schemas/index.d.ts.map +1 -0
  34. package/esm/schemas/index.js +38 -0
  35. package/esm/schemas/methods.d.ts.map +1 -1
  36. package/esm/schemas/methods.js +2 -0
  37. package/esm/schemas/multiscales.d.ts.map +1 -1
  38. package/esm/schemas/multiscales.js +2 -0
  39. package/esm/schemas/ngff_image.d.ts +9 -2
  40. package/esm/schemas/ngff_image.d.ts.map +1 -1
  41. package/esm/schemas/ngff_image.js +11 -2
  42. package/esm/schemas/ome_zarr.d.ts +581 -0
  43. package/esm/schemas/ome_zarr.d.ts.map +1 -0
  44. package/esm/schemas/ome_zarr.js +208 -0
  45. package/esm/schemas/rfc4.d.ts +439 -0
  46. package/esm/schemas/rfc4.d.ts.map +1 -0
  47. package/esm/schemas/rfc4.js +129 -0
  48. package/esm/schemas/units.d.ts.map +1 -1
  49. package/esm/schemas/units.js +5 -0
  50. package/esm/schemas/zarr_metadata.d.ts +302 -9
  51. package/esm/schemas/zarr_metadata.d.ts.map +1 -1
  52. package/esm/schemas/zarr_metadata.js +22 -1
  53. package/esm/types/array_interface.d.ts +7 -0
  54. package/esm/types/array_interface.d.ts.map +1 -0
  55. package/esm/types/array_interface.js +1 -0
  56. package/esm/types/hcs.d.ts +70 -0
  57. package/esm/types/hcs.d.ts.map +1 -0
  58. package/esm/types/hcs.js +204 -0
  59. package/esm/types/methods.d.ts.map +1 -1
  60. package/esm/types/methods.js +2 -0
  61. package/esm/types/multiscales.d.ts.map +1 -1
  62. package/esm/types/ngff_image.d.ts +6 -3
  63. package/esm/types/ngff_image.d.ts.map +1 -1
  64. package/esm/types/ngff_image.js +13 -1
  65. package/esm/types/rfc4.d.ts +94 -0
  66. package/esm/types/rfc4.d.ts.map +1 -0
  67. package/esm/types/rfc4.js +135 -0
  68. package/esm/types/units.d.ts +1 -1
  69. package/esm/types/units.d.ts.map +1 -1
  70. package/esm/types/zarr_metadata.d.ts +14 -5
  71. package/esm/types/zarr_metadata.d.ts.map +1 -1
  72. package/esm/utils/create_queue.d.ts +6 -0
  73. package/esm/utils/create_queue.d.ts.map +1 -0
  74. package/esm/utils/create_queue.js +11 -0
  75. package/esm/utils/factory.d.ts +1 -1
  76. package/esm/utils/factory.d.ts.map +1 -1
  77. package/esm/utils/factory.js +16 -7
  78. package/esm/utils/method_metadata.d.ts +10 -0
  79. package/esm/utils/method_metadata.d.ts.map +1 -0
  80. package/esm/utils/method_metadata.js +37 -0
  81. package/esm/utils/validation.d.ts.map +1 -1
  82. package/package.json +7 -1
  83. package/script/io/from_ngff_zarr.d.ts +4 -1
  84. package/script/io/from_ngff_zarr.d.ts.map +1 -1
  85. package/script/io/from_ngff_zarr.js +94 -27
  86. package/script/io/hcs.d.ts +18 -0
  87. package/script/io/hcs.d.ts.map +1 -0
  88. package/script/io/hcs.js +55 -0
  89. package/script/io/itk_image_to_ngff_image.d.ts +25 -0
  90. package/script/io/itk_image_to_ngff_image.d.ts.map +1 -0
  91. package/script/io/itk_image_to_ngff_image.js +153 -0
  92. package/script/io/ngff_image_to_itk_image.d.ts +30 -0
  93. package/script/io/ngff_image_to_itk_image.d.ts.map +1 -0
  94. package/script/io/ngff_image_to_itk_image.js +242 -0
  95. package/script/io/to_multiscales.d.ts +18 -0
  96. package/script/io/to_multiscales.d.ts.map +1 -0
  97. package/script/io/to_multiscales.js +67 -0
  98. package/script/io/to_ngff_image.d.ts +17 -0
  99. package/script/io/to_ngff_image.d.ts.map +1 -0
  100. package/script/io/to_ngff_image.js +162 -0
  101. package/script/io/to_ngff_zarr.d.ts +3 -2
  102. package/script/io/to_ngff_zarr.d.ts.map +1 -1
  103. package/script/io/to_ngff_zarr.js +273 -26
  104. package/script/methods/itkwasm.d.ts +6 -0
  105. package/script/methods/itkwasm.d.ts.map +1 -0
  106. package/script/methods/itkwasm.js +842 -0
  107. package/script/mod.d.ts +9 -2
  108. package/script/mod.d.ts.map +1 -1
  109. package/script/mod.js +12 -3
  110. package/script/schemas/coordinate_systems.d.ts +644 -0
  111. package/script/schemas/coordinate_systems.d.ts.map +1 -0
  112. package/script/schemas/coordinate_systems.js +143 -0
  113. package/script/schemas/index.d.ts +9 -0
  114. package/script/schemas/index.d.ts.map +1 -0
  115. package/script/schemas/index.js +101 -0
  116. package/script/schemas/methods.d.ts.map +1 -1
  117. package/script/schemas/methods.js +2 -0
  118. package/script/schemas/multiscales.d.ts.map +1 -1
  119. package/script/schemas/multiscales.js +2 -0
  120. package/script/schemas/ngff_image.d.ts +9 -2
  121. package/script/schemas/ngff_image.d.ts.map +1 -1
  122. package/script/schemas/ngff_image.js +11 -2
  123. package/script/schemas/ome_zarr.d.ts +581 -0
  124. package/script/schemas/ome_zarr.d.ts.map +1 -0
  125. package/script/schemas/ome_zarr.js +211 -0
  126. package/script/schemas/rfc4.d.ts +439 -0
  127. package/script/schemas/rfc4.d.ts.map +1 -0
  128. package/script/schemas/rfc4.js +132 -0
  129. package/script/schemas/units.d.ts.map +1 -1
  130. package/script/schemas/units.js +5 -0
  131. package/script/schemas/zarr_metadata.d.ts +302 -9
  132. package/script/schemas/zarr_metadata.d.ts.map +1 -1
  133. package/script/schemas/zarr_metadata.js +23 -2
  134. package/script/types/array_interface.d.ts +7 -0
  135. package/script/types/array_interface.d.ts.map +1 -0
  136. package/script/types/array_interface.js +2 -0
  137. package/script/types/hcs.d.ts +70 -0
  138. package/script/types/hcs.d.ts.map +1 -0
  139. package/script/types/hcs.js +233 -0
  140. package/script/types/methods.d.ts.map +1 -1
  141. package/script/types/methods.js +2 -0
  142. package/script/types/multiscales.d.ts.map +1 -1
  143. package/script/types/ngff_image.d.ts +6 -3
  144. package/script/types/ngff_image.d.ts.map +1 -1
  145. package/script/types/ngff_image.js +13 -1
  146. package/script/types/rfc4.d.ts +94 -0
  147. package/script/types/rfc4.d.ts.map +1 -0
  148. package/script/types/rfc4.js +143 -0
  149. package/script/types/units.d.ts +1 -1
  150. package/script/types/units.d.ts.map +1 -1
  151. package/script/types/zarr_metadata.d.ts +14 -5
  152. package/script/types/zarr_metadata.d.ts.map +1 -1
  153. package/script/utils/create_queue.d.ts +6 -0
  154. package/script/utils/create_queue.d.ts.map +1 -0
  155. package/script/utils/create_queue.js +17 -0
  156. package/script/utils/factory.d.ts +1 -1
  157. package/script/utils/factory.d.ts.map +1 -1
  158. package/script/utils/factory.js +39 -7
  159. package/script/utils/method_metadata.d.ts +10 -0
  160. package/script/utils/method_metadata.d.ts.map +1 -0
  161. package/script/utils/method_metadata.js +40 -0
  162. package/script/utils/validation.d.ts.map +1 -1
  163. package/esm/schemas/lazy_array.d.ts +0 -8
  164. package/esm/schemas/lazy_array.d.ts.map +0 -1
  165. package/esm/schemas/lazy_array.js +0 -7
  166. package/esm/types/lazy_array.d.ts +0 -18
  167. package/esm/types/lazy_array.d.ts.map +0 -1
  168. package/esm/types/lazy_array.js +0 -27
  169. package/script/schemas/lazy_array.d.ts +0 -8
  170. package/script/schemas/lazy_array.d.ts.map +0 -1
  171. package/script/schemas/lazy_array.js +0 -10
  172. package/script/types/lazy_array.d.ts +0 -18
  173. package/script/types/lazy_array.d.ts.map +0 -1
  174. package/script/types/lazy_array.js +0 -31
@@ -1,15 +1,24 @@
1
- import { LazyArray } from "../types/lazy_array.js";
1
+ // SPDX-FileCopyrightText: Copyright (c) Fideus Labs LLC
2
+ // SPDX-License-Identifier: MIT
3
+ import * as zarr from "zarrita";
2
4
  import { NgffImage } from "../types/ngff_image.js";
3
5
  import { Multiscales } from "../types/multiscales.js";
4
- export function createNgffImage(_data, shape, dtype, dims, scale, translation, name = "image") {
5
- const lazyArray = new LazyArray({
6
+ // Create a zarr.Array for testing using an in-memory store
7
+ async function createTestZarrArray(shape, dtype, chunks, name) {
8
+ const store = new Map();
9
+ const root = zarr.root(store);
10
+ // Create the array using zarrita with correct options
11
+ const array = await zarr.create(root.resolve(name), {
6
12
  shape,
7
- dtype,
8
- chunks: [shape],
9
- name,
13
+ chunk_shape: chunks,
14
+ data_type: dtype,
10
15
  });
16
+ return array;
17
+ }
18
+ export async function createNgffImage(_data, shape, dtype, dims, scale, translation, name = "image") {
19
+ const zarrArray = await createTestZarrArray(shape, dtype, shape, name);
11
20
  return new NgffImage({
12
- data: lazyArray,
21
+ data: zarrArray,
13
22
  dims,
14
23
  scale,
15
24
  translation,
@@ -0,0 +1,10 @@
1
+ import type { Methods } from "../types/methods.js";
2
+ import type { MethodMetadata } from "../types/zarr_metadata.js";
3
+ /**
4
+ * Get metadata information for a given downsampling method.
5
+ *
6
+ * @param method - The downsampling method enum
7
+ * @returns MethodMetadata with description, method (package.function), and version
8
+ */
9
+ export declare function getMethodMetadata(method: Methods): MethodMetadata | undefined;
10
+ //# sourceMappingURL=method_metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method_metadata.d.ts","sourceRoot":"","sources":["../../src/utils/method_metadata.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AA6BhE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,GAAG,SAAS,CAe7E"}
@@ -0,0 +1,37 @@
1
+ const METHOD_INFO = {
2
+ itkwasm_gaussian: {
3
+ description: "Smoothed with a discrete gaussian filter to generate a scale space, ideal for intensity images. ITK-Wasm implementation is extremely portable and SIMD accelerated.",
4
+ package: "itkwasm-downsample",
5
+ method: "itkwasm_downsample.downsample",
6
+ },
7
+ itkwasm_bin_shrink: {
8
+ description: "Uses the local mean for the output value. WebAssembly build. Fast but generates more artifacts than gaussian-based methods. Appropriate for intensity images.",
9
+ package: "itkwasm-downsample",
10
+ method: "itkwasm_downsample.downsample_bin_shrink",
11
+ },
12
+ itkwasm_label_image: {
13
+ description: "A sample is the mode of the linearly weighted local labels in the image. Fast and minimal artifacts. For label images.",
14
+ package: "itkwasm-downsample",
15
+ method: "itkwasm_downsample.downsample_label_image",
16
+ },
17
+ };
18
+ /**
19
+ * Get metadata information for a given downsampling method.
20
+ *
21
+ * @param method - The downsampling method enum
22
+ * @returns MethodMetadata with description, method (package.function), and version
23
+ */
24
+ export function getMethodMetadata(method) {
25
+ const methodInfo = METHOD_INFO[method];
26
+ if (!methodInfo) {
27
+ return undefined;
28
+ }
29
+ // TODO: Determine package version dynamically if possible,
30
+ // For now use a placeholder
31
+ const version = "unknown";
32
+ return {
33
+ description: methodInfo.description,
34
+ method: methodInfo.method,
35
+ version,
36
+ };
37
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAG1D,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAQ5D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIjD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAyDjD"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAG1D,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,CAQ5D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAIjD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAErD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAyDjD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fideus-labs/ngff-zarr",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "TypeScript implementation of ngff-zarr for reading and writing OME-Zarr files",
5
5
  "keywords": [
6
6
  "ome-zarr",
@@ -39,9 +39,15 @@
39
39
  "LICENSE"
40
40
  ],
41
41
  "dependencies": {
42
+ "@itk-wasm/downsample": "^1.8.1",
43
+ "itk-wasm": "^1.0.0-b.195",
44
+ "p-queue": "^8.1.0",
42
45
  "@zarrita/storage": "^0.1.1",
43
46
  "zod": "^4.0.2",
44
47
  "zarrita": "^0.5.2"
45
48
  },
49
+ "devDependencies": {
50
+ "@itk-wasm/image-io": "^1.6.0"
51
+ },
46
52
  "_generatedBy": "dnt@dev"
47
53
  }
@@ -1,7 +1,10 @@
1
+ import * as zarr from "zarrita";
1
2
  import { Multiscales } from "../types/multiscales.js";
2
3
  export interface FromNgffZarrOptions {
3
4
  validate?: boolean;
5
+ version?: "0.4" | "0.5";
4
6
  }
5
- export declare function fromNgffZarr(storePath: string, options?: FromNgffZarrOptions): Promise<Multiscales>;
7
+ export type MemoryStore = Map<string, Uint8Array>;
8
+ export declare function fromNgffZarr(store: string | MemoryStore | zarr.FetchStore, options?: FromNgffZarrOptions): Promise<Multiscales>;
6
9
  export declare function readArrayData(storePath: string, arrayPath: string, selection?: (number | null)[]): Promise<unknown>;
7
10
  //# sourceMappingURL=from_ngff_zarr.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"from_ngff_zarr.d.ts","sourceRoot":"","sources":["../../src/io/from_ngff_zarr.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAOtD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,WAAW,CAAC,CAyItB;AAED,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAC5B,OAAO,CAAC,OAAO,CAAC,CAoBlB"}
1
+ {"version":3,"file":"from_ngff_zarr.d.ts","sourceRoot":"","sources":["../../src/io/from_ngff_zarr.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAMtD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;CACzB;AAED,MAAM,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAElD,wBAAsB,YAAY,CAEhC,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC,UAAU,EAC7C,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,WAAW,CAAC,CA6MtB;AAED,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,CAAC,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAC5B,OAAO,CAAC,OAAO,CAAC,CAmClB"}
@@ -25,48 +25,65 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.fromNgffZarr = fromNgffZarr;
27
27
  exports.readArrayData = readArrayData;
28
+ // SPDX-FileCopyrightText: Copyright (c) Fideus Labs LLC
29
+ // SPDX-License-Identifier: MIT
28
30
  const dntShim = __importStar(require("../_dnt.shims.js"));
29
31
  const zarr = __importStar(require("zarrita"));
30
32
  const multiscales_js_1 = require("../types/multiscales.js");
31
33
  const ngff_image_js_1 = require("../types/ngff_image.js");
32
- const lazy_array_js_1 = require("../types/lazy_array.js");
33
34
  const zarr_metadata_js_1 = require("../schemas/zarr_metadata.js");
34
- async function fromNgffZarr(storePath, options = {}) {
35
+ async function fromNgffZarr(
36
+ // Also accepts FileSystemStore, ZipFileStore objects in Node.js/Deno
37
+ store, options = {}) {
35
38
  const validate = options.validate ?? false;
39
+ const version = options.version;
36
40
  try {
37
41
  // Determine the appropriate store type based on the path
38
- let store;
39
- if (storePath.startsWith("http://") || storePath.startsWith("https://")) {
42
+ let resolvedStore;
43
+ if (store instanceof Map || store instanceof zarr.FetchStore) {
44
+ resolvedStore = store;
45
+ }
46
+ else if (store.startsWith("http://") || store.startsWith("https://")) {
40
47
  // Use FetchStore for HTTP/HTTPS URLs
41
- store = new zarr.FetchStore(storePath);
48
+ resolvedStore = new zarr.FetchStore(store);
42
49
  }
43
50
  else {
44
51
  // For local paths, check if we're in a browser environment
45
52
  if (typeof dntShim.dntGlobalThis !== "undefined") {
46
53
  throw new Error("Local file paths are not supported in browser environments. Use HTTP/HTTPS URLs instead.");
47
54
  }
48
- // Use dynamic import for FileSystemStore in Node.js/Deno environments
55
+ // Use dynamic import for FileSystemStore, ZipFileStore in Node.js/Deno environments
49
56
  try {
50
- const { FileSystemStore } = await Promise.resolve().then(() => __importStar(require("@zarrita/storage")));
51
- store = new FileSystemStore(storePath);
57
+ const { FileSystemStore, ZipFileStore } = await Promise.resolve().then(() => __importStar(require("@zarrita/storage")));
58
+ // @ts-ignore: Node/Deno workaround
59
+ if (store instanceof FileSystemStore || store instanceof ZipFileStore) {
60
+ // @ts-ignore: Node/Deno workaround
61
+ resolvedStore = store;
62
+ }
63
+ else {
64
+ // Normalize the path for cross-platform compatibility
65
+ const normalizedPath = store.replace(/^\/([A-Za-z]:)/, "$1");
66
+ // @ts-ignore: Node/Deno workaround
67
+ resolvedStore = new FileSystemStore(normalizedPath);
68
+ }
52
69
  }
53
70
  catch (error) {
54
71
  throw new Error(`Failed to load FileSystemStore: ${error}. Use HTTP/HTTPS URLs for browser compatibility.`);
55
72
  }
56
73
  }
57
- const root = zarr.root(store);
58
74
  // Try to use consolidated metadata for better performance
59
- let consolidatedRoot;
75
+ let optimizedStore;
60
76
  try {
61
- consolidatedRoot = await zarr.tryWithConsolidated(store);
77
+ // @ts-ignore: tryWithConsolidated typing
78
+ optimizedStore = await zarr.tryWithConsolidated(resolvedStore);
62
79
  }
63
80
  catch {
64
- consolidatedRoot = store;
81
+ optimizedStore = resolvedStore;
65
82
  }
66
- const group = await zarr.open.v2(zarr.root(consolidatedRoot), {
83
+ const root = await zarr.open(optimizedStore, {
67
84
  kind: "group",
68
85
  });
69
- const attrs = group.attrs;
86
+ const attrs = root.attrs;
70
87
  if (!attrs || !attrs.multiscales) {
71
88
  throw new Error("No multiscales metadata found in Zarr store");
72
89
  }
@@ -81,24 +98,60 @@ async function fromNgffZarr(storePath, options = {}) {
81
98
  if (!result.success) {
82
99
  throw new Error(`Invalid OME-Zarr metadata: ${result.error.message}`);
83
100
  }
101
+ // Check version compatibility if specified
102
+ if (version) {
103
+ const metadataWithVersion = multiscalesMetadata;
104
+ if (metadataWithVersion.version !== version) {
105
+ throw new Error(`Expected OME-Zarr version ${version}, but found ${metadataWithVersion.version || "unknown"}`);
106
+ }
107
+ }
84
108
  }
85
109
  const metadata = multiscalesMetadata;
86
110
  // Extract omero metadata from root attributes if present
87
111
  if (attrs.omero) {
88
- metadata.omero = attrs.omero;
112
+ const omeroData = attrs.omero;
113
+ // Handle backward compatibility for OMERO window metadata
114
+ if (omeroData.channels && Array.isArray(omeroData.channels)) {
115
+ for (const channel of omeroData.channels) {
116
+ if (channel.window && typeof channel.window === "object") {
117
+ const window = channel.window;
118
+ // Ensure both min/max and start/end are present for compatibility
119
+ if (window.min !== undefined && window.max !== undefined) {
120
+ // If only min/max present, use them for start/end
121
+ if (window.start === undefined) {
122
+ window.start = window.min;
123
+ }
124
+ if (window.end === undefined) {
125
+ window.end = window.max;
126
+ }
127
+ }
128
+ else if (window.start !== undefined && window.end !== undefined) {
129
+ // If only start/end present, use them for min/max
130
+ if (window.min === undefined) {
131
+ window.min = window.start;
132
+ }
133
+ if (window.max === undefined) {
134
+ window.max = window.end;
135
+ }
136
+ }
137
+ }
138
+ }
139
+ }
140
+ metadata.omero = omeroData;
89
141
  }
90
142
  const images = [];
91
143
  for (const dataset of metadata.datasets) {
92
144
  const arrayPath = dataset.path;
93
- const zarrArray = await zarr.open.v2(root.resolve(arrayPath), {
145
+ const zarrArray = (await zarr.open(root.resolve(arrayPath), {
94
146
  kind: "array",
95
- });
96
- const lazyArray = new lazy_array_js_1.LazyArray({
97
- shape: zarrArray.shape,
98
- dtype: zarrArray.dtype,
99
- chunks: [zarrArray.chunks],
100
- name: arrayPath,
101
- });
147
+ }));
148
+ // Verify we have an array with the expected properties
149
+ if (!zarrArray ||
150
+ !("shape" in zarrArray) ||
151
+ !("dtype" in zarrArray) ||
152
+ !("chunks" in zarrArray)) {
153
+ throw new Error(`Invalid zarr array at path ${arrayPath}: missing shape property`);
154
+ }
102
155
  const scale = {};
103
156
  const translation = {};
104
157
  for (const transform of dataset.coordinateTransformations) {
@@ -125,7 +178,7 @@ async function fromNgffZarr(storePath, options = {}) {
125
178
  return acc;
126
179
  }, {});
127
180
  const ngffImage = new ngff_image_js_1.NgffImage({
128
- data: lazyArray,
181
+ data: zarrArray,
129
182
  dims,
130
183
  scale,
131
184
  translation,
@@ -151,9 +204,23 @@ async function readArrayData(storePath, arrayPath, selection) {
151
204
  try {
152
205
  const store = new zarr.FetchStore(storePath);
153
206
  const root = zarr.root(store);
154
- const zarrArray = await zarr.open.v2(root.resolve(arrayPath), {
155
- kind: "array",
156
- });
207
+ // Try to open as zarr v2 first, then v3 if that fails
208
+ let zarrArray;
209
+ try {
210
+ zarrArray = await zarr.open.v2(root.resolve(arrayPath), {
211
+ kind: "array",
212
+ });
213
+ }
214
+ catch (v2Error) {
215
+ try {
216
+ zarrArray = await zarr.open.v3(root.resolve(arrayPath), {
217
+ kind: "array",
218
+ });
219
+ }
220
+ catch (v3Error) {
221
+ throw new Error(`Failed to open zarr array ${arrayPath} as either v2 or v3 format. v2 error: ${v2Error}. v3 error: ${v3Error}`);
222
+ }
223
+ }
157
224
  if (selection) {
158
225
  return await zarr.get(zarrArray, selection);
159
226
  }
@@ -0,0 +1,18 @@
1
+ import type { HCSPlate } from "../types/hcs.js";
2
+ export interface FromHcsZarrOptions {
3
+ validate?: boolean;
4
+ wellCacheSize?: number;
5
+ imageCacheSize?: number;
6
+ }
7
+ export interface ToHcsZarrOptions {
8
+ compressionLevel?: number;
9
+ }
10
+ /**
11
+ * Read an HCS plate from an OME-Zarr NGFF store.
12
+ */
13
+ export declare function fromHcsZarr(store: string | object, options?: FromHcsZarrOptions): HCSPlate;
14
+ /**
15
+ * Write an HCS plate to an OME-Zarr NGFF store.
16
+ */
17
+ export declare function toHcsZarr(plate: HCSPlate, store: string | object, _options?: ToHcsZarrOptions): void;
18
+ //# sourceMappingURL=hcs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hcs.d.ts","sourceRoot":"","sources":["../../src/io/hcs.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAiB,MAAM,iBAAiB,CAAC;AAG/D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAE/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,OAAO,GAAE,kBAAuB,GAC/B,QAAQ,CAkCV;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,QAAQ,EACf,KAAK,EAAE,MAAM,GAAG,MAAM,EACtB,QAAQ,GAAE,gBAAqB,GAC9B,IAAI,CAaN"}
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fromHcsZarr = fromHcsZarr;
4
+ exports.toHcsZarr = toHcsZarr;
5
+ const hcs_js_1 = require("../types/hcs.js");
6
+ /**
7
+ * Read an HCS plate from an OME-Zarr NGFF store.
8
+ */
9
+ function fromHcsZarr(store, options = {}) {
10
+ const { validate = false, wellCacheSize, imageCacheSize } = options;
11
+ if (validate) {
12
+ console.warn("HCS validation not yet implemented");
13
+ }
14
+ if (typeof store !== "string") {
15
+ throw new Error("Non-string store types not yet supported");
16
+ }
17
+ // For now, create a mock implementation
18
+ // This will be properly implemented when the zarrita API integration is complete
19
+ const plateMetadata = {
20
+ columns: [{ name: "1" }, { name: "2" }],
21
+ rows: [{ name: "A" }, { name: "B" }],
22
+ wells: [
23
+ { path: "A/1", rowIndex: 0, columnIndex: 0 },
24
+ { path: "A/2", rowIndex: 0, columnIndex: 1 },
25
+ { path: "B/1", rowIndex: 1, columnIndex: 0 },
26
+ { path: "B/2", rowIndex: 1, columnIndex: 1 },
27
+ ],
28
+ version: "0.4",
29
+ acquisitions: [{ id: 0, name: "Test Acquisition" }],
30
+ field_count: 2,
31
+ name: "Test Plate",
32
+ };
33
+ return new hcs_js_1.HCSPlate({
34
+ store,
35
+ metadata: plateMetadata,
36
+ wellCacheSize,
37
+ imageCacheSize,
38
+ });
39
+ }
40
+ /**
41
+ * Write an HCS plate to an OME-Zarr NGFF store.
42
+ */
43
+ function toHcsZarr(plate, store, _options = {}) {
44
+ if (typeof store !== "string") {
45
+ throw new Error("Non-string store types not yet supported");
46
+ }
47
+ // Mock implementation for now
48
+ console.log(`HCS plate structure would be created at ${store}`);
49
+ console.log(`Plate: ${plate.name}`);
50
+ console.log(`Wells: ${plate.wells.length}`);
51
+ console.log(`Rows: ${plate.rows.length}, Columns: ${plate.columns.length}`);
52
+ if (plate.acquisitions) {
53
+ console.log(`Acquisitions: ${plate.acquisitions.length}`);
54
+ }
55
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Convert ITK-Wasm Image to NgffImage
3
+ */
4
+ import type { Image } from "itk-wasm";
5
+ import { NgffImage } from "../types/ngff_image.js";
6
+ export interface ItkImageToNgffImageOptions {
7
+ /**
8
+ * Whether to add anatomical orientation metadata based on ITK LPS coordinate system
9
+ * @default true
10
+ */
11
+ addAnatomicalOrientation?: boolean;
12
+ }
13
+ /**
14
+ * Convert an ITK-Wasm Image to an NgffImage, preserving spatial metadata.
15
+ *
16
+ * This function converts ITK-Wasm Image objects to NgffImage format while
17
+ * preserving spatial information like spacing, origin, and optionally
18
+ * anatomical orientation based on the ITK LPS coordinate system.
19
+ *
20
+ * @param itkImage - The ITK-Wasm Image to convert
21
+ * @param options - Conversion options
22
+ * @returns Promise resolving to NgffImage
23
+ */
24
+ export declare function itkImageToNgffImage(itkImage: Image, options?: ItkImageToNgffImageOptions): Promise<NgffImage>;
25
+ //# sourceMappingURL=itk_image_to_ngff_image.d.ts.map
@@ -0,0 +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;CACpC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,KAAK,EACf,OAAO,GAAE,0BAA+B,GACvC,OAAO,CAAC,SAAS,CAAC,CAmHpB"}
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ // SPDX-FileCopyrightText: Copyright (c) Fideus Labs LLC
3
+ // SPDX-License-Identifier: MIT
4
+ /**
5
+ * Convert ITK-Wasm Image to NgffImage
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || function (mod) {
24
+ if (mod && mod.__esModule) return mod;
25
+ var result = {};
26
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
27
+ __setModuleDefault(result, mod);
28
+ return result;
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.itkImageToNgffImage = itkImageToNgffImage;
32
+ const zarr = __importStar(require("zarrita"));
33
+ const ngff_image_js_1 = require("../types/ngff_image.js");
34
+ const rfc4_js_1 = require("../types/rfc4.js");
35
+ // Import the get_strides function from zarrita utilities
36
+ const zarrita_1 = require("zarrita");
37
+ /**
38
+ * Convert an ITK-Wasm Image to an NgffImage, preserving spatial metadata.
39
+ *
40
+ * This function converts ITK-Wasm Image objects to NgffImage format while
41
+ * preserving spatial information like spacing, origin, and optionally
42
+ * anatomical orientation based on the ITK LPS coordinate system.
43
+ *
44
+ * @param itkImage - The ITK-Wasm Image to convert
45
+ * @param options - Conversion options
46
+ * @returns Promise resolving to NgffImage
47
+ */
48
+ async function itkImageToNgffImage(itkImage, options = {}) {
49
+ const { addAnatomicalOrientation = true } = options;
50
+ // Extract image properties from ITK-Wasm Image
51
+ const _data = itkImage.data;
52
+ const shape = itkImage.size;
53
+ const spacing = itkImage.spacing;
54
+ const origin = itkImage.origin;
55
+ const ndim = shape.length;
56
+ // Determine dimension names based on shape and image type
57
+ // This logic matches the Python implementation
58
+ let dims;
59
+ // Check if this is a vector image (multi-component)
60
+ const imageType = itkImage.imageType;
61
+ const isVector = imageType.components > 1;
62
+ if (ndim === 3 && isVector) {
63
+ // 2D RGB/vector image: 2D spatial + components
64
+ dims = ["y", "x", "c"];
65
+ }
66
+ else if (ndim < 4) {
67
+ // Scalar images up to 3D: take the last ndim spatial dimensions
68
+ dims = ["z", "y", "x"].slice(-ndim);
69
+ }
70
+ else if (ndim < 5) {
71
+ // 3D RGB/vector or 4D scalar
72
+ if (isVector) {
73
+ dims = ["z", "y", "x", "c"];
74
+ }
75
+ else {
76
+ dims = ["t", "z", "y", "x"];
77
+ }
78
+ }
79
+ else if (ndim < 6) {
80
+ // 4D RGB/vector
81
+ dims = ["t", "z", "y", "x", "c"];
82
+ }
83
+ else {
84
+ throw new Error(`Unsupported number of dimensions: ${ndim}`);
85
+ }
86
+ // Identify spatial dimensions
87
+ const allSpatialDims = new Set(["x", "y", "z"]);
88
+ const spatialDims = dims.filter((dim) => allSpatialDims.has(dim));
89
+ // Create scale mapping from spacing (ITK order: [z, y, x] for 3D, [y, x] for 2D)
90
+ const scale = {};
91
+ // Define canonical ITK spatial order for up to 3D
92
+ const itkSpatialOrder = ["z", "y", "x"].slice(-spatialDims.length);
93
+ spatialDims.forEach((dim) => {
94
+ const spatialIndex = itkSpatialOrder.indexOf(dim);
95
+ if (spatialIndex === -1) {
96
+ throw new Error(`Unknown spatial dimension: ${dim}`);
97
+ }
98
+ scale[dim] = spacing[spatialIndex];
99
+ });
100
+ // Create translation mapping from origin (ITK order: [z, y, x] for 3D, [y, x] for 2D)
101
+ const translation = {};
102
+ spatialDims.forEach((dim) => {
103
+ const spatialIndex = itkSpatialOrder.indexOf(dim);
104
+ if (spatialIndex === -1) {
105
+ throw new Error(`Unknown spatial dimension: ${dim}`);
106
+ }
107
+ translation[dim] = origin[spatialIndex];
108
+ });
109
+ // Create Zarr array from ITK-Wasm data
110
+ const store = new Map();
111
+ const root = zarr.root(store);
112
+ // Determine appropriate chunk size
113
+ const chunkShape = shape.map((s) => Math.min(s, 256));
114
+ const zarrArray = await zarr.create(root.resolve("image"), {
115
+ shape: shape,
116
+ chunk_shape: chunkShape,
117
+ data_type: imageType.componentType,
118
+ fill_value: 0,
119
+ });
120
+ // Write the ITK-Wasm data to the zarr array
121
+ // We use zarrita's set function to write the entire data efficiently
122
+ // Create a selection that covers the entire array (null means "all" for each dimension)
123
+ const selection = new Array(ndim).fill(null);
124
+ // Create a chunk object with the ITK-Wasm data in zarrita format
125
+ const dataChunk = {
126
+ data: itkImage.data,
127
+ shape: shape,
128
+ stride: (0, zarrita_1._zarrita_internal_get_strides)(shape, "C"), // C-order (row-major) strides for compatibility
129
+ };
130
+ // Write all data to the zarr array using zarrita's set function
131
+ // This handles chunking and encoding automatically
132
+ await zarr.set(zarrArray, selection, dataChunk); // Add anatomical orientation if requested
133
+ let axesOrientations;
134
+ if (addAnatomicalOrientation) {
135
+ axesOrientations = {};
136
+ for (const dim of spatialDims) {
137
+ const orientation = (0, rfc4_js_1.itkLpsToAnatomicalOrientation)(dim);
138
+ if (orientation !== undefined) {
139
+ axesOrientations[dim] = orientation;
140
+ }
141
+ }
142
+ }
143
+ return new ngff_image_js_1.NgffImage({
144
+ data: zarrArray,
145
+ dims,
146
+ scale,
147
+ translation,
148
+ name: "image",
149
+ axesUnits: undefined,
150
+ axesOrientations,
151
+ computedCallbacks: undefined,
152
+ });
153
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Convert NgffImage to ITK-Wasm Image
3
+ */
4
+ import type { Image } from "itk-wasm";
5
+ import { NgffImage } from "../types/ngff_image.js";
6
+ export interface NgffImageToItkImageOptions {
7
+ /**
8
+ * Extract a specific time index from a time-series image
9
+ * If specified and 't' dimension exists, extracts the slice at this time index
10
+ */
11
+ tIndex?: number;
12
+ /**
13
+ * Extract a specific channel index from a multi-channel image
14
+ * If specified and 'c' dimension exists, extracts the slice at this channel index
15
+ */
16
+ cIndex?: number;
17
+ }
18
+ /**
19
+ * Convert an NgffImage to an ITK-Wasm Image, preserving spatial metadata.
20
+ *
21
+ * This function converts NgffImage objects to ITK-Wasm Image format while
22
+ * preserving spatial information like spacing, origin, and direction matrix.
23
+ * Optionally extracts specific time or channel slices.
24
+ *
25
+ * @param ngffImage - The NgffImage to convert
26
+ * @param options - Conversion options
27
+ * @returns Promise resolving to ITK-Wasm Image
28
+ */
29
+ export declare function ngffImageToItkImage(ngffImage: NgffImage, options?: NgffImageToItkImageOptions): Promise<Image>;
30
+ //# sourceMappingURL=ngff_image_to_itk_image.d.ts.map
@@ -0,0 +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,CAiMhB"}