ngio 0.3.0a1__py3-none-any.whl → 0.3.2__py3-none-any.whl

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,10 +1,11 @@
1
1
  from collections.abc import Collection, Iterable
2
2
  from typing import Literal
3
3
 
4
- import dask
5
- import dask.delayed
4
+ import dask.array as da
6
5
  import numpy as np
7
6
  import zarr
7
+ from dask.array import Array as DaskArray
8
+ from dask.delayed import Delayed, delayed
8
9
 
9
10
  from ngio.common._axes_transforms import transform_dask_array, transform_numpy_array
10
11
  from ngio.common._common_types import ArrayLike
@@ -55,26 +56,26 @@ def _numpy_get_pipe(
55
56
  slices: SliceTransform,
56
57
  transformations: tuple[AxesTransformation, ...],
57
58
  ) -> np.ndarray:
58
- array = numpy_get_slice(array, slices)
59
- return transform_numpy_array(array, transformations)
59
+ _array = numpy_get_slice(array, slices)
60
+ return transform_numpy_array(_array, transformations)
60
61
 
61
62
 
62
63
  def _delayed_numpy_get_pipe(
63
64
  array: zarr.Array,
64
65
  slices: SliceTransform,
65
66
  transformations: tuple[AxesTransformation, ...],
66
- ) -> dask.delayed:
67
- array = dask.delayed(numpy_get_slice)(array, slices)
68
- return dask.delayed(transform_numpy_array)(array, transformations)
67
+ ) -> Delayed:
68
+ _array = delayed(numpy_get_slice)(array, slices)
69
+ return delayed(transform_numpy_array)(_array, transformations)
69
70
 
70
71
 
71
72
  def _dask_get_pipe(
72
73
  array: zarr.Array,
73
74
  slices: SliceTransform,
74
75
  transformations: tuple[AxesTransformation, ...],
75
- ) -> dask.array:
76
- array = dask_get_slice(array, slices)
77
- return transform_dask_array(array, transformations)
76
+ ) -> DaskArray:
77
+ _array = dask_get_slice(array, slices)
78
+ return transform_dask_array(_array, transformations)
78
79
 
79
80
 
80
81
  def _numpy_set_pipe(
@@ -89,22 +90,22 @@ def _numpy_set_pipe(
89
90
 
90
91
  def _dask_set_pipe(
91
92
  array: zarr.Array,
92
- patch: np.ndarray,
93
+ patch: DaskArray,
93
94
  slices: SliceTransform,
94
95
  transformations: tuple[AxesTransformation, ...],
95
96
  ) -> None:
96
- patch = transform_dask_array(patch, transformations)
97
- dask_set_slice(array, patch, slices)
97
+ _patch = transform_dask_array(patch, transformations)
98
+ dask_set_slice(array, _patch, slices)
98
99
 
99
100
 
100
101
  def _delayed_numpy_set_pipe(
101
102
  array: zarr.Array,
102
- patch: np.ndarray,
103
+ patch: np.ndarray | Delayed,
103
104
  slices: SliceTransform,
104
105
  transformations: tuple[AxesTransformation, ...],
105
- ) -> dask.delayed:
106
- patch = dask.delayed(transform_numpy_array)(patch, transformations)
107
- return dask.delayed(numpy_set_slice)(array, patch, slices)
106
+ ) -> Delayed:
107
+ _patch = delayed(transform_numpy_array)(patch, transformations)
108
+ return delayed(numpy_set_slice)(array, _patch, slices)
108
109
 
109
110
 
110
111
  def get_pipe(
@@ -144,7 +145,7 @@ def set_pipe(
144
145
  slices, transformations = _compute_to_disk_transforms(
145
146
  dimensions=dimensions, axes_order=axes_order, **slice_kwargs
146
147
  )
147
- if isinstance(patch, dask.array.Array):
148
+ if isinstance(patch, DaskArray):
148
149
  _dask_set_pipe(
149
150
  array=array, patch=patch, slices=slices, transformations=transformations
150
151
  )
@@ -152,7 +153,7 @@ def set_pipe(
152
153
  _numpy_set_pipe(
153
154
  array=array, patch=patch, slices=slices, transformations=transformations
154
155
  )
155
- elif isinstance(patch, dask.delayed.Delayed):
156
+ elif isinstance(patch, Delayed):
156
157
  _delayed_numpy_set_pipe(
157
158
  array=array, patch=patch, slices=slices, transformations=transformations
158
159
  )
@@ -193,12 +194,15 @@ def _mask_pipe_common(
193
194
  **slice_kwargs,
194
195
  )
195
196
 
196
- if isinstance(array_patch, np.ndarray):
197
+ if isinstance(array_patch, np.ndarray) and isinstance(label_patch, np.ndarray):
197
198
  label_patch = np.broadcast_to(label_patch, array_patch.shape)
198
- elif isinstance(array_patch, dask.array.Array):
199
- label_patch = dask.array.broadcast_to(label_patch, array_patch.shape)
199
+ elif isinstance(array_patch, DaskArray) and isinstance(label_patch, DaskArray):
200
+ label_patch = da.broadcast_to(label_patch, array_patch.shape)
200
201
  else:
201
- raise NgioValueError(f"Mode {mode} not yet supported for masked array.")
202
+ raise NgioValueError(
203
+ "Incompatible types for array and label: "
204
+ f"{type(array_patch)} and {type(label_patch)}"
205
+ )
202
206
 
203
207
  mask = label_patch == label
204
208
  return array_patch, mask
@@ -225,7 +229,14 @@ def get_masked_pipe(
225
229
  mode=mode,
226
230
  **slice_kwargs,
227
231
  )
228
- array_patch[~mask] = 0
232
+ if isinstance(array_patch, np.ndarray):
233
+ array_patch[~mask] = 0
234
+ elif isinstance(array_patch, DaskArray):
235
+ array_patch = da.where(mask, array_patch, 0)
236
+ else:
237
+ raise NgioValueError(
238
+ "Mode not yet supported for masked array. Expected a numpy or dask array."
239
+ )
229
240
  return array_patch
230
241
 
231
242
 
@@ -240,7 +251,7 @@ def set_masked_pipe(
240
251
  axes_order: Collection[str] | None = None,
241
252
  **slice_kwargs: slice | int | Iterable[int],
242
253
  ):
243
- if isinstance(patch, dask.array.Array):
254
+ if isinstance(patch, DaskArray):
244
255
  mode = "dask"
245
256
  elif isinstance(patch, np.ndarray):
246
257
  mode = "numpy"
@@ -259,7 +270,19 @@ def set_masked_pipe(
259
270
  mode=mode,
260
271
  **slice_kwargs,
261
272
  )
262
- patch = np.where(mask, patch, array_patch)
273
+ if isinstance(patch, np.ndarray):
274
+ assert isinstance(array_patch, np.ndarray)
275
+ _patch = np.where(mask, patch, array_patch)
276
+ elif isinstance(patch, DaskArray):
277
+ _patch = da.where(mask, patch, array_patch)
278
+ else:
279
+ raise NgioValueError(
280
+ "Mode not yet supported for masked array. Expected a numpy or dask array."
281
+ )
263
282
  set_pipe(
264
- array, patch, dimensions=dimensions_array, axes_order=axes_order, **slice_kwargs
283
+ array,
284
+ _patch,
285
+ dimensions=dimensions_array,
286
+ axes_order=axes_order,
287
+ **slice_kwargs,
265
288
  )
ngio/common/_roi.py CHANGED
@@ -57,6 +57,7 @@ class Roi(BaseModel):
57
57
  x_length=_to_raster(self.x_length, pixel_size.x, dim_x),
58
58
  y_length=_to_raster(self.y_length, pixel_size.y, dim_y),
59
59
  z_length=_to_raster(self.z_length, pixel_size.z, dim_z),
60
+ **self.model_extra,
60
61
  )
61
62
 
62
63
  def zoom(self, zoom_factor: float = 1) -> "Roi":
@@ -94,6 +95,7 @@ class RoiPixels(BaseModel):
94
95
  y_length=_to_world(self.y_length, pixel_size.y),
95
96
  z_length=_to_world(self.z_length, pixel_size.z),
96
97
  unit=pixel_size.space_unit,
98
+ **self.model_extra,
97
99
  )
98
100
 
99
101
  def to_slices(self) -> dict[str, slice]:
ngio/common/_table_ops.py CHANGED
@@ -9,7 +9,7 @@ from typing import Literal
9
9
  import pandas as pd
10
10
  import polars as pl
11
11
 
12
- from ngio.images.ome_zarr_container import OmeZarrContainer
12
+ from ngio.images._ome_zarr_container import OmeZarrContainer
13
13
  from ngio.tables import Table, TableType
14
14
 
15
15
 
ngio/hcs/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """OME-Zarr HCS objects models."""
2
2
 
3
- from ngio.hcs.plate import (
3
+ from ngio.hcs._plate import (
4
4
  OmeZarrPlate,
5
5
  OmeZarrWell,
6
6
  create_empty_plate,
@@ -27,6 +27,7 @@ from ngio.ome_zarr_meta import (
27
27
  )
28
28
  from ngio.tables import (
29
29
  ConditionTable,
30
+ DefaultTableBackend,
30
31
  FeatureTable,
31
32
  GenericRoiTable,
32
33
  MaskingRoiTable,
@@ -39,7 +40,6 @@ from ngio.tables import (
39
40
  )
40
41
  from ngio.utils import (
41
42
  AccessModeLiteral,
42
- NgioValidationError,
43
43
  NgioValueError,
44
44
  StoreOrGroup,
45
45
  ZarrGroupHandler,
@@ -805,22 +805,38 @@ class OmeZarrPlate:
805
805
  parallel_safe=parallel_safe,
806
806
  )
807
807
 
808
- @property
809
- def tables_container(self) -> TablesContainer:
808
+ def _get_tables_container(self) -> TablesContainer | None:
810
809
  """Return the tables container."""
811
810
  if self._tables_container is None:
812
- self._tables_container = _default_table_container(self._group_handler)
813
- if self._tables_container is None:
814
- raise NgioValidationError("No tables found in the image.")
811
+ _tables_container = _default_table_container(self._group_handler)
812
+ if _tables_container is None:
813
+ return None
814
+ self._tables_container = _tables_container
815
815
  return self._tables_container
816
816
 
817
- def list_tables(self, filter_types: str | None = None) -> list[str]:
817
+ @property
818
+ def tables_container(self) -> TablesContainer:
819
+ """Return the tables container."""
820
+ _table_container = self._get_tables_container()
821
+ if _table_container is None:
822
+ raise NgioValueError(
823
+ "No tables container found. Please add a tables container to the plate."
824
+ )
825
+ return _table_container
826
+
827
+ def list_tables(self, filter_types: TypedTable | str | None = None) -> list[str]:
818
828
  """List all tables in the image."""
819
829
  return self.tables_container.list(filter_types=filter_types)
820
830
 
821
831
  def list_roi_tables(self) -> list[str]:
822
832
  """List all ROI tables in the image."""
823
- return self.tables_container.list_roi_tables()
833
+ masking_roi = self.tables_container.list(
834
+ filter_types="masking_roi_table",
835
+ )
836
+ roi = self.tables_container.list(
837
+ filter_types="roi_table",
838
+ )
839
+ return masking_roi + roi
824
840
 
825
841
  def get_roi_table(self, name: str) -> RoiTable:
826
842
  """Get a ROI table from the image.
@@ -929,7 +945,7 @@ class OmeZarrPlate:
929
945
  self,
930
946
  name: str,
931
947
  table: Table,
932
- backend: TableBackend = "anndata",
948
+ backend: TableBackend = DefaultTableBackend,
933
949
  overwrite: bool = False,
934
950
  ) -> None:
935
951
  """Add a table to the image."""
ngio/images/__init__.py CHANGED
@@ -1,8 +1,8 @@
1
1
  """OME-Zarr object models."""
2
2
 
3
- from ngio.images.image import Image, ImagesContainer
4
- from ngio.images.label import Label, LabelsContainer
5
- from ngio.images.ome_zarr_container import (
3
+ from ngio.images._image import Image, ImagesContainer
4
+ from ngio.images._label import Label, LabelsContainer
5
+ from ngio.images._ome_zarr_container import (
6
6
  OmeZarrContainer,
7
7
  create_empty_ome_zarr,
8
8
  create_ome_zarr_from_array,
@@ -3,11 +3,11 @@
3
3
  from collections.abc import Collection
4
4
  from typing import Literal
5
5
 
6
- from dask import array as da
6
+ import dask.array as da
7
7
 
8
8
  from ngio.common import Dimensions
9
- from ngio.images.abstract_image import AbstractImage, consolidate_image
10
- from ngio.images.create import create_empty_image_container
9
+ from ngio.images._abstract_image import AbstractImage, consolidate_image
10
+ from ngio.images._create import create_empty_image_container
11
11
  from ngio.ome_zarr_meta import (
12
12
  ImageMetaHandler,
13
13
  NgioImageMeta,
@@ -152,31 +152,33 @@ class ImagesContainer:
152
152
 
153
153
  def set_channel_meta(
154
154
  self,
155
- labels: Collection[str] | int | None = None,
156
- wavelength_id: Collection[str] | None = None,
157
- start: Collection[float] | None = None,
158
- end: Collection[float] | None = None,
155
+ labels: Collection[str | None] | int | None = None,
156
+ wavelength_id: Collection[str | None] | None = None,
157
+ start: Collection[float | None] | None = None,
158
+ end: Collection[float | None] | None = None,
159
159
  percentiles: tuple[float, float] | None = None,
160
- colors: Collection[str] | None = None,
161
- active: Collection[bool] | None = None,
160
+ colors: Collection[str | None] | None = None,
161
+ active: Collection[bool | None] | None = None,
162
162
  **omero_kwargs: dict,
163
163
  ) -> None:
164
164
  """Create a ChannelsMeta object with the default unit.
165
165
 
166
166
  Args:
167
- labels(Collection[str] | int): The list of channels names in the image.
168
- If an integer is provided, the channels will be named "channel_i".
169
- wavelength_id(Collection[str] | None): The wavelength ID of the channel.
167
+ labels(Collection[str | None] | int): The list of channels names
168
+ in the image. If an integer is provided, the channels will
169
+ be named "channel_i".
170
+ wavelength_id(Collection[str | None]): The wavelength ID of the channel.
170
171
  If None, the wavelength ID will be the same as the channel name.
171
- start(Collection[float] | None): The start value for each channel.
172
+ start(Collection[float | None]): The start value for each channel.
172
173
  If None, the start value will be computed from the image.
173
- end(Collection[float] | None): The end value for each channel.
174
+ end(Collection[float | None]): The end value for each channel.
174
175
  If None, the end value will be computed from the image.
175
- percentiles(tuple[float, float] | None): The start and end percentiles
176
- for each channel. If None, the percentiles will not be computed.
177
- colors(Collection[str, NgioColors] | None): The list of colors for the
176
+ percentiles(tuple[float, float] | None): The start and end
177
+ percentiles for each channel. If None, the percentiles will
178
+ not be computed.
179
+ colors(Collection[str | None]): The list of colors for the
178
180
  channels. If None, the colors will be random.
179
- active (Collection[bool] | None):active(bool): Whether the channel should
181
+ active (Collection[bool | None]): Whether the channel should
180
182
  be shown by default.
181
183
  omero_kwargs(dict): Extra fields to store in the omero attributes.
182
184
  """
@@ -376,9 +378,12 @@ def compute_image_percentile(
376
378
  starts, ends = [], []
377
379
  for c in range(image.num_channels):
378
380
  if image.num_channels == 1:
379
- data = image.get_array(mode="dask").ravel()
381
+ data = image.get_array(mode="dask")
380
382
  else:
381
- data = image.get_array(c=c, mode="dask").ravel()
383
+ data = image.get_array(c=c, mode="dask")
384
+
385
+ assert isinstance(data, da.Array), "Data must be a Dask array."
386
+ data = da.ravel(data)
382
387
  # remove all the zeros
383
388
  mask = data > 1e-16
384
389
  data = data[mask]
@@ -391,7 +396,7 @@ def compute_image_percentile(
391
396
  # compute the percentiles
392
397
  _s_perc, _e_perc = da.percentile(
393
398
  data, [start_percentile, end_percentile], method="nearest"
394
- ).compute()
399
+ ).compute() # type: ignore
395
400
 
396
401
  starts.append(float(_s_perc))
397
402
  ends.append(float(_e_perc))
@@ -3,10 +3,12 @@
3
3
  from collections.abc import Collection
4
4
  from typing import Literal
5
5
 
6
+ import dask.array as da
7
+
6
8
  from ngio.common import compute_masking_roi
7
- from ngio.images.abstract_image import AbstractImage, consolidate_image
8
- from ngio.images.create import create_empty_label_container
9
- from ngio.images.image import Image
9
+ from ngio.images._abstract_image import AbstractImage, consolidate_image
10
+ from ngio.images._create import create_empty_label_container
11
+ from ngio.images._image import Image
10
12
  from ngio.ome_zarr_meta import (
11
13
  LabelMetaHandler,
12
14
  NgioLabelMeta,
@@ -309,6 +311,6 @@ def build_masking_roi_table(label: Label) -> MaskingRoiTable:
309
311
  raise NgioValueError("Time series labels are not supported.")
310
312
 
311
313
  array = label.get_array(axes_order=["z", "y", "x"], mode="dask")
312
-
314
+ assert isinstance(array, da.Array), "Array must be a Dask array."
313
315
  rois = compute_masking_roi(array, label.pixel_size)
314
316
  return MaskingRoiTable(rois, reference_label=label.meta.name)
@@ -4,8 +4,8 @@ from collections.abc import Collection, Iterable
4
4
  from typing import Literal
5
5
 
6
6
  from ngio.common import ArrayLike, get_masked_pipe, roi_to_slice_kwargs, set_masked_pipe
7
- from ngio.images.image import Image
8
- from ngio.images.label import Label
7
+ from ngio.images._image import Image
8
+ from ngio.images._label import Label
9
9
  from ngio.ome_zarr_meta import ImageMetaHandler, LabelMetaHandler
10
10
  from ngio.tables import MaskingRoiTable
11
11
  from ngio.utils import (
@@ -5,10 +5,10 @@ from collections.abc import Collection
5
5
 
6
6
  import numpy as np
7
7
 
8
- from ngio.images.create import create_empty_image_container
9
- from ngio.images.image import Image, ImagesContainer
10
- from ngio.images.label import Label, LabelsContainer
11
- from ngio.images.masked_image import MaskedImage, MaskedLabel
8
+ from ngio.images._create import create_empty_image_container
9
+ from ngio.images._image import Image, ImagesContainer
10
+ from ngio.images._label import Label, LabelsContainer
11
+ from ngio.images._masked_image import MaskedImage, MaskedLabel
12
12
  from ngio.ome_zarr_meta import (
13
13
  NgioImageMeta,
14
14
  PixelSize,
@@ -23,6 +23,7 @@ from ngio.ome_zarr_meta.ngio_specs import (
23
23
  )
24
24
  from ngio.tables import (
25
25
  ConditionTable,
26
+ DefaultTableBackend,
26
27
  FeatureTable,
27
28
  GenericRoiTable,
28
29
  MaskingRoiTable,
@@ -68,7 +69,7 @@ class OmeZarrContainer:
68
69
  group_handler: ZarrGroupHandler,
69
70
  table_container: TablesContainer | None = None,
70
71
  label_container: LabelsContainer | None = None,
71
- validate_arrays: bool = True,
72
+ validate_paths: bool = False,
72
73
  ) -> None:
73
74
  """Initialize the OmeZarrContainer."""
74
75
  self._group_handler = group_handler
@@ -77,6 +78,10 @@ class OmeZarrContainer:
77
78
  self._labels_container = label_container
78
79
  self._tables_container = table_container
79
80
 
81
+ if validate_paths:
82
+ for level_path in self._images_container.levels_paths:
83
+ self.get_image(path=level_path)
84
+
80
85
  def __repr__(self) -> str:
81
86
  """Return a string representation of the image."""
82
87
  num_labels = len(self.list_labels())
@@ -99,24 +104,40 @@ class OmeZarrContainer:
99
104
  """Return the image container."""
100
105
  return self._images_container
101
106
 
102
- @property
103
- def labels_container(self) -> LabelsContainer:
107
+ def _get_labels_container(self) -> LabelsContainer | None:
104
108
  """Return the labels container."""
105
109
  if self._labels_container is None:
106
- self._labels_container = _default_label_container(self._group_handler)
107
- if self._labels_container is None:
108
- raise NgioValidationError("No labels found in the image.")
110
+ _labels_container = _default_label_container(self._group_handler)
111
+ if _labels_container is None:
112
+ return None
113
+ self._labels_container = _labels_container
109
114
  return self._labels_container
110
115
 
111
116
  @property
112
- def tables_container(self) -> TablesContainer:
117
+ def labels_container(self) -> LabelsContainer:
118
+ """Return the labels container."""
119
+ _labels_container = self._get_labels_container()
120
+ if _labels_container is None:
121
+ raise NgioValidationError("No labels found in the image.")
122
+ return _labels_container
123
+
124
+ def _get_tables_container(self) -> TablesContainer | None:
113
125
  """Return the tables container."""
114
126
  if self._tables_container is None:
115
- self._tables_container = _default_table_container(self._group_handler)
116
- if self._tables_container is None:
117
- raise NgioValidationError("No tables found in the image.")
127
+ _tables_container = _default_table_container(self._group_handler)
128
+ if _tables_container is None:
129
+ return None
130
+ self._tables_container = _tables_container
118
131
  return self._tables_container
119
132
 
133
+ @property
134
+ def tables_container(self) -> TablesContainer:
135
+ """Return the tables container."""
136
+ _tables_container = self._get_tables_container()
137
+ if _tables_container is None:
138
+ raise NgioValidationError("No tables found in the image.")
139
+ return _tables_container
140
+
120
141
  @property
121
142
  def image_meta(self) -> NgioImageMeta:
122
143
  """Return the image metadata."""
@@ -332,7 +353,7 @@ class OmeZarrContainer:
332
353
 
333
354
  new_ome_zarr = OmeZarrContainer(
334
355
  group_handler=handler,
335
- validate_arrays=False,
356
+ validate_paths=False,
336
357
  )
337
358
 
338
359
  if copy_labels:
@@ -346,13 +367,25 @@ class OmeZarrContainer:
346
367
  )
347
368
  return new_ome_zarr
348
369
 
349
- def list_tables(self, filter_types: str | None = None) -> list[str]:
370
+ def list_tables(self, filter_types: TypedTable | str | None = None) -> list[str]:
350
371
  """List all tables in the image."""
351
- return self.tables_container.list(filter_types=filter_types)
372
+ table_container = self._get_tables_container()
373
+ if table_container is None:
374
+ return []
375
+
376
+ return table_container.list(
377
+ filter_types=filter_types,
378
+ )
352
379
 
353
380
  def list_roi_tables(self) -> list[str]:
354
381
  """List all ROI tables in the image."""
355
- return self.tables_container.list_roi_tables()
382
+ masking_roi = self.tables_container.list(
383
+ filter_types="masking_roi_table",
384
+ )
385
+ roi = self.tables_container.list(
386
+ filter_types="roi_table",
387
+ )
388
+ return masking_roi + roi
356
389
 
357
390
  def get_roi_table(self, name: str) -> RoiTable:
358
391
  """Get a ROI table from the image.
@@ -469,7 +502,7 @@ class OmeZarrContainer:
469
502
  self,
470
503
  name: str,
471
504
  table: Table,
472
- backend: TableBackend = "anndata",
505
+ backend: TableBackend = DefaultTableBackend,
473
506
  overwrite: bool = False,
474
507
  ) -> None:
475
508
  """Add a table to the image."""
@@ -479,7 +512,10 @@ class OmeZarrContainer:
479
512
 
480
513
  def list_labels(self) -> list[str]:
481
514
  """List all labels in the image."""
482
- return self.labels_container.list()
515
+ label_container = self._get_labels_container()
516
+ if label_container is None:
517
+ return []
518
+ return label_container.list()
483
519
 
484
520
  def get_label(
485
521
  self,
@@ -597,7 +633,7 @@ def open_ome_zarr_container(
597
633
  handler = ZarrGroupHandler(store=store, cache=cache, mode=mode)
598
634
  return OmeZarrContainer(
599
635
  group_handler=handler,
600
- validate_arrays=validate_arrays,
636
+ validate_paths=validate_arrays,
601
637
  )
602
638
 
603
639
 
@@ -796,7 +832,7 @@ def create_ome_zarr_from_array(
796
832
  axes_names=axes_names,
797
833
  name=name,
798
834
  chunks=chunks,
799
- dtype=array.dtype,
835
+ dtype=str(array.dtype),
800
836
  overwrite=overwrite,
801
837
  version=version,
802
838
  )
@@ -2,15 +2,12 @@
2
2
 
3
3
  from collections.abc import Collection
4
4
  from enum import Enum
5
- from logging import Logger
6
5
  from typing import Literal, TypeVar
7
6
 
8
7
  import numpy as np
9
8
  from pydantic import BaseModel, ConfigDict, Field
10
9
 
11
- from ngio.utils import NgioValidationError, NgioValueError
12
-
13
- logger = Logger(__name__)
10
+ from ngio.utils import NgioValidationError, NgioValueError, ngio_logger
14
11
 
15
12
  T = TypeVar("T")
16
13
 
@@ -102,20 +99,20 @@ class Axis(BaseModel):
102
99
  def implicit_type_cast(self, cast_type: AxisType) -> "Axis":
103
100
  unit = self.unit
104
101
  if self.axis_type != cast_type:
105
- logger.warning(
102
+ ngio_logger.warning(
106
103
  f"Axis {self.on_disk_name} has type {self.axis_type}. "
107
104
  f"Casting to {cast_type}."
108
105
  )
109
106
 
110
107
  if cast_type == AxisType.time and unit is None:
111
- logger.warning(
108
+ ngio_logger.warning(
112
109
  f"Time axis {self.on_disk_name} has unit {self.unit}. "
113
110
  f"Casting to {DefaultSpaceUnit}."
114
111
  )
115
112
  unit = DefaultTimeUnit
116
113
 
117
114
  if cast_type == AxisType.space and unit is None:
118
- logger.warning(
115
+ ngio_logger.warning(
119
116
  f"Space axis {self.on_disk_name} has unit {unit}. "
120
117
  f"Casting to {DefaultSpaceUnit}."
121
118
  )