1
1
import logging
2
- from typing import Any , Optional , Sequence , Union
2
+ from collections .abc import Sequence
3
+ from typing import Any , Optional , Union
3
4
4
5
import numpy as np
5
6
import zarr
@@ -29,7 +30,9 @@ def open_ds(
29
30
voxel_size : Optional [Sequence [int ]] = None ,
30
31
axis_names : Optional [Sequence [str ]] = None ,
31
32
units : Optional [Sequence [str ]] = None ,
33
+ types : Optional [Sequence [str ]] = None ,
32
34
chunks : Optional [Union [int , Sequence [int ], str ]] = "strict" ,
35
+ strict_metadata : bool = False ,
33
36
** kwargs ,
34
37
) -> Array :
35
38
"""
@@ -68,6 +71,11 @@ def open_ds(
68
71
69
72
An override for the units of your dataset.
70
73
74
+ types (`str`, (optional)):
75
+
76
+ An override for the types of your axes. For more details see:
77
+ https://ngff.openmicroscopy.org/latest/#axes-md
78
+
71
79
chunks (`Coordinate`, (optional)):
72
80
73
81
An override for the size of the chunks in the dataset.
@@ -77,6 +85,11 @@ def open_ds(
77
85
See https://docs.dask.org/en/stable/generated/dask.array.from_array.html
78
86
for more information.
79
87
88
+ strict_metadata (`bool`, (optional)):
89
+
90
+ If True, all metadata fields (offset, voxel_size, axis_names, units, types)
91
+ must be provided either as arguments or read from dataset attributes.
92
+
80
93
kwargs:
81
94
82
95
See additional arguments available here:
@@ -106,6 +119,8 @@ def open_ds(
106
119
voxel_size = voxel_size ,
107
120
axis_names = axis_names ,
108
121
units = units ,
122
+ types = types ,
123
+ strict = strict_metadata ,
109
124
)
110
125
111
126
return Array (
@@ -114,6 +129,7 @@ def open_ds(
114
129
metadata .voxel_size ,
115
130
metadata .axis_names ,
116
131
metadata .units ,
132
+ metadata .types ,
117
133
data .chunks if chunks == "strict" else chunks ,
118
134
)
119
135
@@ -125,6 +141,7 @@ def prepare_ds(
125
141
voxel_size : Optional [Coordinate ] = None ,
126
142
axis_names : Optional [Sequence [str ]] = None ,
127
143
units : Optional [Sequence [str ]] = None ,
144
+ types : Optional [Sequence [str ]] = None ,
128
145
chunk_shape : Optional [Sequence [int ]] = None ,
129
146
dtype : DTypeLike = np .float32 ,
130
147
mode : str = "a" ,
@@ -156,8 +173,7 @@ def prepare_ds(
156
173
157
174
axis_names:
158
175
159
- The axis names of the dataset to create. The names of non-physical
160
- dimensions should end with "^". e.g. ["samples^", "channels^", "z", "y", "x"]
176
+ The axis names of the dataset to create.
161
177
Set to ["c{i}^", "d{j}"] by default. Where i, j are the index of the non-physical
162
178
and physical dimensions respectively.
163
179
@@ -166,6 +182,17 @@ def prepare_ds(
166
182
The units of the dataset to create. Only provide for physical dimensions.
167
183
Set to all "" by default.
168
184
185
+ types:
186
+
187
+ The types of the axes of the dataset to create. For more details see:
188
+ https://ngff.openmicroscopy.org/latest/#axes-md
189
+ If not provided, we will first fall back on to axis_names if provided
190
+ and use "channel" for axis names ending in "^", and "space" otherwise.
191
+ If neither are provided, we will assume all dimensions are spatial.
192
+ Note that axis name parsing is depricated and will be removed in the
193
+ future. Please provide types directly if you have a mix of spatial and
194
+ non-spatial dimensions.
195
+
169
196
chunk_shape:
170
197
171
198
The shape of the chunks to use in the dataset. For all dimensions,
@@ -207,6 +234,7 @@ def prepare_ds(
207
234
voxel_size = voxel_size ,
208
235
axis_names = axis_names ,
209
236
units = units ,
237
+ types = types ,
210
238
)
211
239
212
240
try :
@@ -256,6 +284,14 @@ def prepare_ds(
256
284
)
257
285
metadata_compatible = False
258
286
287
+ if given_metadata .types != existing_metadata .types :
288
+ logger .info (
289
+ "Types differ: given (%s) vs parsed (%s)" ,
290
+ given_metadata .types ,
291
+ existing_metadata .types ,
292
+ )
293
+ metadata_compatible = False
294
+
259
295
if given_metadata .axis_names != existing_metadata .axis_names :
260
296
logger .info (
261
297
"Axis names differ: given (%s) vs parsed (%s)" ,
@@ -298,6 +334,7 @@ def prepare_ds(
298
334
existing_metadata .voxel_size ,
299
335
existing_metadata .axis_names ,
300
336
existing_metadata .units ,
337
+ existing_metadata .types ,
301
338
ds .chunks ,
302
339
)
303
340
@@ -308,6 +345,7 @@ def prepare_ds(
308
345
voxel_size = voxel_size ,
309
346
axis_names = axis_names ,
310
347
units = units ,
348
+ types = types ,
311
349
)
312
350
313
351
# create the dataset
@@ -330,6 +368,7 @@ def prepare_ds(
330
368
default_metadata_format .units_attr : combined_metadata .units ,
331
369
default_metadata_format .voxel_size_attr : combined_metadata .voxel_size ,
332
370
default_metadata_format .offset_attr : combined_metadata .offset ,
371
+ default_metadata_format .types_attr : combined_metadata .types ,
333
372
}
334
373
# check keys don't conflict
335
374
if custom_metadata is not None :
@@ -339,6 +378,6 @@ def prepare_ds(
339
378
ds .attrs .put (our_metadata )
340
379
341
380
# open array
342
- array = Array (ds , offset , voxel_size , axis_names , units )
381
+ array = Array (ds , offset , voxel_size , axis_names , units , types )
343
382
344
383
return array
0 commit comments