ngio 0.3.5__py3-none-any.whl → 0.4.0a2__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.
Files changed (61) hide show
  1. ngio/__init__.py +6 -0
  2. ngio/common/__init__.py +50 -48
  3. ngio/common/_array_io_pipes.py +554 -0
  4. ngio/common/_array_io_utils.py +508 -0
  5. ngio/common/_dimensions.py +63 -27
  6. ngio/common/_masking_roi.py +38 -10
  7. ngio/common/_pyramid.py +9 -7
  8. ngio/common/_roi.py +583 -72
  9. ngio/common/_synt_images_utils.py +101 -0
  10. ngio/common/_zoom.py +17 -12
  11. ngio/common/transforms/__init__.py +5 -0
  12. ngio/common/transforms/_label.py +12 -0
  13. ngio/common/transforms/_zoom.py +109 -0
  14. ngio/experimental/__init__.py +5 -0
  15. ngio/experimental/iterators/__init__.py +17 -0
  16. ngio/experimental/iterators/_abstract_iterator.py +170 -0
  17. ngio/experimental/iterators/_feature.py +151 -0
  18. ngio/experimental/iterators/_image_processing.py +169 -0
  19. ngio/experimental/iterators/_rois_utils.py +127 -0
  20. ngio/experimental/iterators/_segmentation.py +282 -0
  21. ngio/hcs/_plate.py +41 -36
  22. ngio/images/__init__.py +22 -1
  23. ngio/images/_abstract_image.py +247 -117
  24. ngio/images/_create.py +15 -15
  25. ngio/images/_create_synt_container.py +128 -0
  26. ngio/images/_image.py +425 -62
  27. ngio/images/_label.py +33 -30
  28. ngio/images/_masked_image.py +396 -122
  29. ngio/images/_ome_zarr_container.py +203 -66
  30. ngio/{common → images}/_table_ops.py +41 -41
  31. ngio/ome_zarr_meta/ngio_specs/__init__.py +2 -8
  32. ngio/ome_zarr_meta/ngio_specs/_axes.py +151 -128
  33. ngio/ome_zarr_meta/ngio_specs/_channels.py +55 -18
  34. ngio/ome_zarr_meta/ngio_specs/_dataset.py +7 -7
  35. ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +3 -3
  36. ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +11 -68
  37. ngio/ome_zarr_meta/v04/_v04_spec_utils.py +1 -1
  38. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png +0 -0
  39. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png +0 -0
  40. ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg +0 -0
  41. ngio/resources/__init__.py +54 -0
  42. ngio/resources/resource_model.py +35 -0
  43. ngio/tables/backends/_abstract_backend.py +5 -6
  44. ngio/tables/backends/_anndata.py +1 -1
  45. ngio/tables/backends/_anndata_utils.py +3 -3
  46. ngio/tables/backends/_non_zarr_backends.py +1 -1
  47. ngio/tables/backends/_table_backends.py +0 -1
  48. ngio/tables/backends/_utils.py +3 -3
  49. ngio/tables/v1/_roi_table.py +156 -69
  50. ngio/utils/__init__.py +2 -3
  51. ngio/utils/_logger.py +19 -0
  52. ngio/utils/_zarr_utils.py +1 -5
  53. {ngio-0.3.5.dist-info → ngio-0.4.0a2.dist-info}/METADATA +3 -1
  54. ngio-0.4.0a2.dist-info/RECORD +76 -0
  55. ngio/common/_array_pipe.py +0 -288
  56. ngio/common/_axes_transforms.py +0 -64
  57. ngio/common/_common_types.py +0 -5
  58. ngio/common/_slicer.py +0 -96
  59. ngio-0.3.5.dist-info/RECORD +0 -61
  60. {ngio-0.3.5.dist-info → ngio-0.4.0a2.dist-info}/WHEEL +0 -0
  61. {ngio-0.3.5.dist-info → ngio-0.4.0a2.dist-info}/licenses/LICENSE +0 -0
@@ -4,9 +4,7 @@ This class follows the roi_table specification at:
4
4
  https://fractal-analytics-platform.github.io/fractal-tasks-core/tables/
5
5
  """
6
6
 
7
- # Import _type to avoid name conflict with table.type
8
7
  from collections.abc import Iterable
9
- from functools import cache
10
8
  from typing import Literal
11
9
 
12
10
  import pandas as pd
@@ -27,7 +25,7 @@ from ngio.utils import (
27
25
  NgioTableValidationError,
28
26
  NgioValueError,
29
27
  ZarrGroupHandler,
30
- ngio_logger,
28
+ ngio_warn,
31
29
  )
32
30
 
33
31
  REQUIRED_COLUMNS = [
@@ -44,6 +42,11 @@ REQUIRED_COLUMNS = [
44
42
  # only a warning is raised if non optional columns are present
45
43
  #####################
46
44
 
45
+ TIME_COLUMNS = [
46
+ "t_second",
47
+ "len_t_second",
48
+ ]
49
+
47
50
  ORIGIN_COLUMNS = [
48
51
  "x_micrometer_original",
49
52
  "y_micrometer_original",
@@ -70,24 +73,17 @@ INDEX_COLUMNS = [
70
73
  OPTIONAL_COLUMNS = ORIGIN_COLUMNS + TRANSLATION_COLUMNS + PLATE_COLUMNS + INDEX_COLUMNS
71
74
 
72
75
 
73
- @cache
74
76
  def _check_optional_columns(col_name: str) -> None:
75
77
  """Check if the column name is in the optional columns."""
76
- if col_name not in OPTIONAL_COLUMNS:
77
- ngio_logger.warning(
78
- f"Column {col_name} is not in the optional columns. "
79
- f"Standard optional columns are: {OPTIONAL_COLUMNS}."
80
- )
78
+ if col_name not in OPTIONAL_COLUMNS + TIME_COLUMNS:
79
+ ngio_warn(f"Column {col_name} is not in the optional columns.")
81
80
 
82
81
 
83
82
  def _dataframe_to_rois(
84
83
  dataframe: pd.DataFrame,
85
- required_columns: list[str] | None = None,
84
+ required_columns: list[str] = REQUIRED_COLUMNS,
86
85
  ) -> dict[str, Roi]:
87
86
  """Convert a DataFrame to a WorldCooROI object."""
88
- if required_columns is None:
89
- required_columns = REQUIRED_COLUMNS
90
-
91
87
  # Validate the columns of the DataFrame
92
88
  _required_columns = set(dataframe.columns).intersection(set(required_columns))
93
89
  if len(_required_columns) != len(required_columns):
@@ -95,11 +91,15 @@ def _dataframe_to_rois(
95
91
  f"Could not find required columns: {_required_columns} in the table."
96
92
  )
97
93
 
98
- extra_columns = set(dataframe.columns).difference(set(required_columns))
94
+ extra_columns = set(dataframe.columns).difference(
95
+ set(required_columns + TIME_COLUMNS)
96
+ )
99
97
 
100
98
  for col in extra_columns:
101
99
  _check_optional_columns(col)
102
100
 
101
+ label_is_index = True if dataframe.index.name == "label" else False
102
+
103
103
  extras = {}
104
104
 
105
105
  rois = {}
@@ -108,85 +108,166 @@ def _dataframe_to_rois(
108
108
  if len(extra_columns) > 0:
109
109
  extras = {col: getattr(row, col, None) for col in extra_columns}
110
110
 
111
+ z_micrometer = getattr(row, "z_micrometer", None)
112
+ z_length_micrometer = getattr(row, "len_z_micrometer", None)
113
+
114
+ t_second = getattr(row, "t_second", None)
115
+ t_length_second = getattr(row, "len_t_second", None)
116
+
117
+ if label_is_index:
118
+ label = int(row.Index) # type: ignore (type can not be known here, but should be castable to int)
119
+ else:
120
+ label = getattr(row, "label", None)
121
+
111
122
  roi = Roi(
112
123
  name=str(row.Index),
113
- x=row.x_micrometer, # type: ignore
114
- y=row.y_micrometer, # type: ignore
115
- z=row.z_micrometer, # type: ignore
116
- x_length=row.len_x_micrometer, # type: ignore
117
- y_length=row.len_y_micrometer, # type: ignore
118
- z_length=row.len_z_micrometer, # type: ignore
119
- unit="micrometer", # type: ignore
124
+ x=row.x_micrometer, # type: ignore (type can not be known here)
125
+ y=row.y_micrometer, # type: ignore (type can not be known here)
126
+ z=z_micrometer,
127
+ t=t_second,
128
+ x_length=row.len_x_micrometer, # type: ignore (type can not be known here)
129
+ y_length=row.len_y_micrometer, # type: ignore (type can not be known here)
130
+ z_length=z_length_micrometer,
131
+ t_length=t_length_second,
132
+ unit="micrometer",
133
+ label=label,
120
134
  **extras,
121
135
  )
122
136
  rois[roi.name] = roi
123
137
  return rois
124
138
 
125
139
 
126
- def _table_to_rois(
127
- table: TabularData,
128
- index_key: str | None = None,
129
- index_type: Literal["int", "str"] | None = None,
130
- required_columns: list[str] | None = None,
131
- ) -> tuple[pd.DataFrame, dict[str, Roi]]:
132
- """Convert a table to a dictionary of ROIs.
133
-
134
- Args:
135
- table: The table to convert.
136
- index_key: The column name to use as the index of the DataFrame.
137
- index_type: The type of the index column in the DataFrame.
138
- required_columns: The required columns in the DataFrame.
139
-
140
- Returns:
141
- A dictionary of ROIs.
142
- """
143
- dataframe = convert_to_pandas(
144
- table,
145
- index_key=index_key,
146
- index_type=index_type,
147
- )
148
- return dataframe, _dataframe_to_rois(dataframe, required_columns=required_columns)
149
-
150
-
151
140
  def _rois_to_dataframe(rois: dict[str, Roi], index_key: str | None) -> pd.DataFrame:
152
141
  """Convert a list of WorldCooROI objects to a DataFrame."""
153
142
  data = []
154
143
  for roi in rois.values():
144
+ # This normalization is necessary for backward compatibility
145
+ z_micrometer = roi.z if roi.z is not None else 0.0
146
+ len_z_micrometer = roi.z_length if roi.z_length is not None else 1.0
147
+
155
148
  row = {
156
149
  index_key: roi.name,
157
150
  "x_micrometer": roi.x,
158
151
  "y_micrometer": roi.y,
159
- "z_micrometer": roi.z,
152
+ "z_micrometer": z_micrometer,
160
153
  "len_x_micrometer": roi.x_length,
161
154
  "len_y_micrometer": roi.y_length,
162
- "len_z_micrometer": roi.z_length,
155
+ "len_z_micrometer": len_z_micrometer,
163
156
  }
164
157
 
158
+ if roi.t is not None:
159
+ row["t_second"] = roi.t
160
+
161
+ if roi.t_length is not None:
162
+ row["len_t_second"] = roi.t_length
163
+
164
+ if roi.label is not None and index_key != "label":
165
+ row["label"] = roi.label
166
+
165
167
  extra = roi.model_extra or {}
166
168
  for col in extra:
167
169
  _check_optional_columns(col)
168
170
  row[col] = extra[col]
169
171
  data.append(row)
172
+
170
173
  dataframe = pd.DataFrame(data)
171
174
  dataframe = normalize_pandas_df(dataframe, index_key=index_key)
172
175
  return dataframe
173
176
 
174
177
 
178
+ class RoiDictWrapper:
179
+ """A wrapper for a dictionary of ROIs to provide a consistent interface."""
180
+
181
+ def __init__(self, rois: Iterable[Roi]) -> None:
182
+ self._rois_by_name = {roi.name: roi for roi in rois}
183
+ self._rois_by_label = {roi.label: roi for roi in rois if roi.label is not None}
184
+
185
+ def get_by_name(self, name: str, default: Roi | None = None) -> Roi | None:
186
+ """Get an ROI by its name."""
187
+ return self._rois_by_name.get(name, default)
188
+
189
+ def get_by_label(self, label: int, default: Roi | None = None) -> Roi | None:
190
+ """Get an ROI by its label."""
191
+ return self._rois_by_label.get(label, default)
192
+
193
+ def _add_roi(self, roi: Roi, overwrite: bool = False) -> None:
194
+ """Add an ROI to the wrapper."""
195
+ if roi.name in self._rois_by_name and not overwrite:
196
+ raise NgioValueError(f"ROI with name {roi.name} already exists.")
197
+
198
+ self._rois_by_name[roi.name] = roi
199
+ if roi.label is not None:
200
+ self._rois_by_label[roi.label] = roi
201
+
202
+ def add_rois(self, rois: Roi | Iterable[Roi], overwrite: bool = False) -> None:
203
+ """Add ROIs to the wrapper."""
204
+ if isinstance(rois, Roi):
205
+ rois = [rois]
206
+
207
+ for roi in rois:
208
+ self._add_roi(roi, overwrite=overwrite)
209
+
210
+ def to_list(self) -> list[Roi]:
211
+ """Return the list of ROIs."""
212
+ return list(self._rois_by_name.values())
213
+
214
+ def to_dataframe(self, index_key: str | None = None) -> pd.DataFrame:
215
+ """Convert the ROIs to a DataFrame."""
216
+ return _rois_to_dataframe(self._rois_by_name, index_key=index_key)
217
+
218
+ @classmethod
219
+ def from_dataframe(
220
+ cls, dataframe: pd.DataFrame, required_columns: list[str] = REQUIRED_COLUMNS
221
+ ) -> "RoiDictWrapper":
222
+ """Create a RoiDictWrapper from a DataFrame."""
223
+ rois = _dataframe_to_rois(dataframe, required_columns=required_columns)
224
+ return cls(rois.values())
225
+
226
+
227
+ def _table_to_rois(
228
+ table: TabularData,
229
+ index_key: str | None = None,
230
+ index_type: Literal["int", "str"] | None = None,
231
+ required_columns: list[str] = REQUIRED_COLUMNS,
232
+ ) -> tuple[pd.DataFrame, RoiDictWrapper]:
233
+ """Convert a table to a dictionary of ROIs.
234
+
235
+ Args:
236
+ table: The table to convert.
237
+ index_key: The column name to use as the index of the DataFrame.
238
+ index_type: The type of the index column in the DataFrame.
239
+ required_columns: The required columns in the DataFrame.
240
+
241
+ Returns:
242
+ A tuple containing the DataFrame and a RoiDictWrapper with the ROIs.
243
+ """
244
+ dataframe = convert_to_pandas(
245
+ table,
246
+ index_key=index_key,
247
+ index_type=index_type,
248
+ )
249
+ roi_dict_wrapper = RoiDictWrapper.from_dataframe(
250
+ dataframe, required_columns=required_columns
251
+ )
252
+ return dataframe, roi_dict_wrapper
253
+
254
+
175
255
  class GenericRoiTableV1(AbstractBaseTable):
176
256
  def __init__(
177
257
  self,
178
258
  *,
179
259
  rois: Iterable[Roi] | None = None,
180
260
  meta: BackendMeta,
261
+ required_columns: list[str] = REQUIRED_COLUMNS,
181
262
  ) -> None:
182
263
  table = None
183
264
 
184
- self._rois: dict[str, Roi] | None = None
265
+ self._rois: RoiDictWrapper | None = None
185
266
  if rois is not None:
186
- self._rois = {}
187
- self.add(rois)
188
- table = _rois_to_dataframe(self._rois, index_key=meta.index_key)
267
+ self._rois = RoiDictWrapper(rois)
268
+ table = self._rois.to_dataframe(index_key=meta.index_key)
189
269
 
270
+ self._required_columns = required_columns
190
271
  super().__init__(table_data=table, meta=meta)
191
272
 
192
273
  def __repr__(self) -> str:
@@ -213,7 +294,7 @@ class GenericRoiTableV1(AbstractBaseTable):
213
294
  return super().table_data
214
295
 
215
296
  if len(self.rois()) > 0:
216
- self._table_data = _rois_to_dataframe(self._rois, index_key=self.index_key)
297
+ self._table_data = self._rois.to_dataframe(index_key=self.meta.index_key)
217
298
  return super().table_data
218
299
 
219
300
  def set_table_data(
@@ -260,14 +341,16 @@ class GenericRoiTableV1(AbstractBaseTable):
260
341
  If the ROIs are not loaded, load them from the table.
261
342
  """
262
343
  if self._rois is None:
263
- self._rois = _dataframe_to_rois(self.dataframe)
344
+ self._rois = RoiDictWrapper.from_dataframe(
345
+ self.dataframe, required_columns=self._required_columns
346
+ )
264
347
 
265
348
  def rois(self) -> list[Roi]:
266
349
  """List all ROIs in the table."""
267
350
  self._check_rois()
268
351
  if self._rois is None:
269
352
  return []
270
- return list(self._rois.values())
353
+ return self._rois.to_list()
271
354
 
272
355
  def add(self, roi: Roi | Iterable[Roi], overwrite: bool = False) -> None:
273
356
  """Append ROIs to the current table.
@@ -281,22 +364,20 @@ class GenericRoiTableV1(AbstractBaseTable):
281
364
 
282
365
  self._check_rois()
283
366
  if self._rois is None:
284
- self._rois = {}
367
+ self._rois = RoiDictWrapper([])
285
368
 
286
- for _roi in roi:
287
- if not overwrite and _roi.name in self._rois:
288
- raise NgioValueError(f"ROI {_roi.name} already exists in the table.")
289
- self._rois[_roi.name] = _roi
369
+ self._rois.add_rois(roi, overwrite=overwrite)
290
370
 
291
371
  def get(self, roi_name: str) -> Roi:
292
372
  """Get an ROI from the table."""
293
373
  self._check_rois()
294
374
  if self._rois is None:
295
- self._rois = {}
375
+ self._rois = RoiDictWrapper([])
296
376
 
297
- if roi_name not in self._rois:
298
- raise NgioValueError(f"ROI {roi_name} not found in the table.")
299
- return self._rois[roi_name]
377
+ roi = self._rois.get_by_name(roi_name)
378
+ if roi is None:
379
+ raise NgioValueError(f"ROI with name {roi_name} not found in the table.")
380
+ return roi
300
381
 
301
382
  @classmethod
302
383
  def from_table_data(
@@ -309,7 +390,7 @@ class GenericRoiTableV1(AbstractBaseTable):
309
390
  index_type=meta.index_type,
310
391
  required_columns=REQUIRED_COLUMNS,
311
392
  )
312
- return cls(rois=rois.values(), meta=meta)
393
+ return cls(rois=rois.to_list(), meta=meta)
313
394
 
314
395
 
315
396
  class RoiTableV1Meta(BackendMeta):
@@ -457,7 +538,13 @@ class MaskingRoiTableV1(GenericRoiTableV1):
457
538
  path = path.split("/")[-1]
458
539
  return path
459
540
 
460
- def get(self, label: int | str) -> Roi: # type: ignore
461
- """Get an ROI from the table."""
462
- roi_name = str(label)
463
- return super().get(roi_name)
541
+ def get_label(self, label: int) -> Roi:
542
+ """Get an ROI by label."""
543
+ self._check_rois()
544
+ if self._rois is None:
545
+ self._rois = RoiDictWrapper([])
546
+ roi = self._rois.get_by_label(label)
547
+
548
+ if roi is None:
549
+ raise NgioValueError(f"ROI with label {label} not found.")
550
+ return roi
ngio/utils/__init__.py CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  import os
4
4
 
5
- from ngio.common._common_types import ArrayLike
6
5
  from ngio.utils._datasets import (
7
6
  download_ome_zarr_dataset,
8
7
  list_ome_zarr_datasets,
@@ -16,7 +15,7 @@ from ngio.utils._errors import (
16
15
  NgioValueError,
17
16
  )
18
17
  from ngio.utils._fractal_fsspec_store import fractal_fsspec_store
19
- from ngio.utils._logger import ngio_logger, set_logger_level
18
+ from ngio.utils._logger import ngio_logger, ngio_warn, set_logger_level
20
19
  from ngio.utils._zarr_utils import (
21
20
  AccessModeLiteral,
22
21
  StoreOrGroup,
@@ -29,7 +28,6 @@ set_logger_level(os.getenv("NGIO_LOGGER_LEVEL", "WARNING"))
29
28
  __all__ = [
30
29
  # Zarr
31
30
  "AccessModeLiteral",
32
- "ArrayLike",
33
31
  # Errors
34
32
  "NgioFileExistsError",
35
33
  "NgioFileNotFoundError",
@@ -44,6 +42,7 @@ __all__ = [
44
42
  "list_ome_zarr_datasets",
45
43
  # Logger
46
44
  "ngio_logger",
45
+ "ngio_warn",
47
46
  "open_group_wrapper",
48
47
  "print_datasets_infos",
49
48
  "set_logger_level",
ngio/utils/_logger.py CHANGED
@@ -1,4 +1,6 @@
1
1
  import logging
2
+ import time
3
+ from functools import cache
2
4
 
3
5
  from ngio.utils._errors import NgioValueError
4
6
 
@@ -29,3 +31,20 @@ def set_logger_level(level: str) -> None:
29
31
  raise NgioValueError(f"Invalid log level: {level}")
30
32
 
31
33
  ngio_logger.setLevel(level)
34
+
35
+
36
+ @cache
37
+ def _warn(message: str, ttl_hash: int) -> None:
38
+ """Log a warning message with a time-to-live (TTL) hash."""
39
+ ngio_logger.warning(message, stacklevel=3)
40
+
41
+
42
+ def ngio_warn(message: str, cooldown: int = 2) -> None:
43
+ """Log a warning message.
44
+
45
+ Args:
46
+ message: The warning message to log.
47
+ cooldown: The cooldown period in seconds to avoid repeated logging.
48
+ """
49
+ ttl_hash = time.time() // cooldown
50
+ _warn(message, ttl_hash)
ngio/utils/_zarr_utils.py CHANGED
@@ -1,6 +1,5 @@
1
1
  """Common utilities for working with Zarr groups in consistent ways."""
2
2
 
3
- # %%
4
3
  from pathlib import Path
5
4
  from typing import Literal
6
5
 
@@ -164,7 +163,7 @@ class ZarrGroupHandler:
164
163
  @property
165
164
  def mode(self) -> AccessModeLiteral:
166
165
  """Return the mode of the group."""
167
- return self._mode # type: ignore
166
+ return self._mode # type: ignore (return type is Literal)
168
167
 
169
168
  @property
170
169
  def lock(self) -> BaseFileLock:
@@ -410,6 +409,3 @@ class ZarrGroupHandler:
410
409
  f"Error copying group to {handler.full_url}, "
411
410
  f"#{n_skipped} files where skipped."
412
411
  )
413
-
414
-
415
- # %%
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ngio
3
- Version: 0.3.5
3
+ Version: 0.4.0a2
4
4
  Summary: Next Generation file format IO
5
5
  Project-URL: homepage, https://github.com/BioVisionCenter/ngio
6
6
  Project-URL: repository, https://github.com/BioVisionCenter/ngio
@@ -38,11 +38,13 @@ Requires-Dist: napari; extra == 'dev'
38
38
  Requires-Dist: notebook; extra == 'dev'
39
39
  Requires-Dist: pdbpp; extra == 'dev'
40
40
  Requires-Dist: pre-commit; extra == 'dev'
41
+ Requires-Dist: pympler; extra == 'dev'
41
42
  Requires-Dist: pyqt5; extra == 'dev'
42
43
  Requires-Dist: rich; extra == 'dev'
43
44
  Requires-Dist: ruff; extra == 'dev'
44
45
  Requires-Dist: scikit-image; extra == 'dev'
45
46
  Provides-Extra: docs
47
+ Requires-Dist: griffe-typingdoc; extra == 'docs'
46
48
  Requires-Dist: markdown-exec[ansi]; extra == 'docs'
47
49
  Requires-Dist: matplotlib; extra == 'docs'
48
50
  Requires-Dist: mike; extra == 'docs'
@@ -0,0 +1,76 @@
1
+ ngio/__init__.py,sha256=clqwRwmkalSwXvmNLGwtI-385gwvBTnJjohEk3Xp5cE,1463
2
+ ngio/common/__init__.py,sha256=t5FUH7kSTqTT1jHmL_qYiEUCHHwMEKNfcZ6EbrkcpNg,1958
3
+ ngio/common/_array_io_pipes.py,sha256=zxZIVRtPjWUQ8J09_s5RcwoTgCOHDGmYYrkdPQbOPlM,18221
4
+ ngio/common/_array_io_utils.py,sha256=LktLM2_2LkjYkwzyJXHZ0LyuwrQN4GYTqgpByBxNmlg,16303
5
+ ngio/common/_dimensions.py,sha256=ubBSmnQmZOmen1jUn3LWZlNXCjUuV9FTjZWzUYidOwk,4852
6
+ ngio/common/_masking_roi.py,sha256=ZZTXordEZoq_ADk0OzADvq-5dPOwUBSuNobzFR8fpTw,5697
7
+ ngio/common/_pyramid.py,sha256=ElY_nBcchN3eeD9obLZ31IIo42HVlDn8R-legQpNxzQ,7503
8
+ ngio/common/_roi.py,sha256=SJ_YJx5hR35T_OIx7ev9Y-rXInu7B4VEh8VKgcsdkcg,21166
9
+ ngio/common/_synt_images_utils.py,sha256=B6uYOW1NyrM06YMR-csca3_YnAAkPRTbvnbLdy9tk9E,3188
10
+ ngio/common/_zoom.py,sha256=p_trkLLrNM6hYvchJQJOHfYpzSlzzdDJmcyTx6K5J1M,6030
11
+ ngio/common/transforms/__init__.py,sha256=Dn8SpMw_e_bg9kx4ZVPrGHJIu_yOK1FkIlePlN_C7FQ,120
12
+ ngio/common/transforms/_label.py,sha256=_bTK_E0BCWTno-qg3cf4voAB8OLJuEZ-4l0YgEXgl44,424
13
+ ngio/common/transforms/_zoom.py,sha256=mbnPnJZsCCms5x1Tq2akvsRDbsDYomiNRGqiF6KY2nI,3751
14
+ ngio/experimental/__init__.py,sha256=3pmBtHi-i8bKjTsvrOJM56ZyRX3Pv_dceCdt88-8COQ,147
15
+ ngio/experimental/iterators/__init__.py,sha256=on_sUvuRhHBb7-r5u3Ojvu6K9FGjUOrWGUkLQ4aRzbs,556
16
+ ngio/experimental/iterators/_abstract_iterator.py,sha256=p8ZxQuoqPGLZCp79FprhgV-QsN5uuqadffoXnEqSdys,5533
17
+ ngio/experimental/iterators/_feature.py,sha256=6uONbB527SS2NLlpiFtL3AVOazH-QpGhETLEt8pykgU,5987
18
+ ngio/experimental/iterators/_image_processing.py,sha256=4U2FCS5pyDes9VJAGbQn7_e8YMs2TU0ocVr2m1QZhYA,6639
19
+ ngio/experimental/iterators/_rois_utils.py,sha256=LfBKk2XEY-UuomT_9uOg-0b0_GUo6IX5h0OJmrbMs4g,4375
20
+ ngio/experimental/iterators/_segmentation.py,sha256=pCR2eR5LUMV5nouw6vRDjIyIabnvfxp7cE6sukW4GZc,11220
21
+ ngio/hcs/__init__.py,sha256=G8j9vD-liLeB_UeGtKYIgshWvJnUA6ks9GwjvWBLdHs,357
22
+ ngio/hcs/_plate.py,sha256=qfRwbCKaoz_AWTi8RDFFwOxy5geSknfJrPcqFVno9zI,44288
23
+ ngio/images/__init__.py,sha256=9Whvt7GTiCgT_vXaEEqGnDaY1-UsRk3dhLTv091F_g4,1211
24
+ ngio/images/_abstract_image.py,sha256=AmulSId7WMpKke1ROshxX1hYLHHNQMBy_4F4aPkE-Jw,15601
25
+ ngio/images/_create.py,sha256=X0EalQgrcdh_RVgSxIkv0YNQydKXNRpCXHlgn1oVpI0,9445
26
+ ngio/images/_create_synt_container.py,sha256=XjsQjBEnEGiqrfyKBdp_h4dJmScBMpMg1yUEqObo7Nw,5004
27
+ ngio/images/_image.py,sha256=4PwHsD0KiiJwcyuVX4-iuLCv6V05N6JlCDlEggyLJkw,31742
28
+ ngio/images/_label.py,sha256=rv6-oigkpa5mUTdogdPhfC3JYkEbdjXxY6Y6f1oD-RI,10603
29
+ ngio/images/_masked_image.py,sha256=oFApCcPejfapzilh3ecO2NmI_FReU1FJPc-8XJqsYYU,19619
30
+ ngio/images/_ome_zarr_container.py,sha256=uMQcvfwKj1uL3LG6k7pBQuPfG0KiM94fcf3kP7fu9eg,36705
31
+ ngio/images/_table_ops.py,sha256=jFv_AMqoB4JBpoWsMtZppZVW7dAOC_u-JpfNm8b33kY,15292
32
+ ngio/ome_zarr_meta/__init__.py,sha256=oZ8PEsWM7U0KwzpsnvVfX9k4UfuTz5sZ8B6B9eY5hyY,1193
33
+ ngio/ome_zarr_meta/_meta_handlers.py,sha256=ctknNDT8jxwyvxQf9on5gW31H1tRRsnneO38GT2UXoE,25880
34
+ ngio/ome_zarr_meta/ngio_specs/__init__.py,sha256=9mYKQ-1LqIa20dN_cuUuUf_w-V39Y0HdeB8UKqSrpfQ,1660
35
+ ngio/ome_zarr_meta/ngio_specs/_axes.py,sha256=S10x-8yObaGD6HEirkfMjrVGWnIHlDd52_RdYBTfjY0,17498
36
+ ngio/ome_zarr_meta/ngio_specs/_channels.py,sha256=CVsbG52U31TaMdTj8XqvClUdBya2Ar3qBjDo_xhP-NM,16967
37
+ ngio/ome_zarr_meta/ngio_specs/_dataset.py,sha256=bYbqBneOmASGiV_D1sgng3odtbo0ICWdqDs7au99PSU,5844
38
+ ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py,sha256=N1CGPOubwf0pvm8tiTnh-C1cOu9lToyDe3WagnEnPN4,17207
39
+ ngio/ome_zarr_meta/ngio_specs/_ngio_image.py,sha256=Q4bJjU_53-Lw2qrVaw07PKwjaHLmHZy7JIwM8dkqFeg,15689
40
+ ngio/ome_zarr_meta/ngio_specs/_pixel_size.py,sha256=5TT8250XdCKUnk3OwZeyXIMNFKOg_jx4NnoCo9RLsXI,4079
41
+ ngio/ome_zarr_meta/v04/__init__.py,sha256=dJRzzxyYc81kf-0Hip_bqvbdManaM8XTdQX2meWyCSs,583
42
+ ngio/ome_zarr_meta/v04/_custom_models.py,sha256=5GxiDERvLuvq4QvApcA6EiKLS6hLFX1R0R_9rSaa85A,530
43
+ ngio/ome_zarr_meta/v04/_v04_spec_utils.py,sha256=YKBVVWb3mnuE-5L5k1i85WpHmcrbKl9k5KU2jNqt5yg,15868
44
+ ngio/resources/__init__.py,sha256=Hry2odzDaC471_qgVfAQVnWDMK0Io9F8m9_JBNNm4e0,1633
45
+ ngio/resources/resource_model.py,sha256=0Egs0QAJ5PNknqECHuBd_-ZTdi8EDNirt5VyuPdbg30,835
46
+ ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/mask.png,sha256=g3QmxQdmeciAtBe5cTCRfR6yw3keG9cBYfjizMo6EGo,11890
47
+ ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/nuclei.png,sha256=QhZ4XiFX7r-8-fbX8wSeUymktX85Ap3Nw1MqeOfRrF8,21649
48
+ ngio/resources/20200812-CardiomyocyteDifferentiation14-Cycle1_B03/raw.jpg,sha256=82lejQAIokj5w9g-qqhysDTWpHtNvJTkdURG_BjqIxQ,37743
49
+ ngio/tables/__init__.py,sha256=_BV3sclNMLITu_J8_3DkkUrCB6Kro0HzeWLDCD1ivKM,877
50
+ ngio/tables/_abstract_table.py,sha256=rwGa47TzbFmosucBWVfFq6JEXtgGvOdUVtU9DIelV88,8204
51
+ ngio/tables/_tables_container.py,sha256=3xmpREaN671l40MPprnl1BD-VoOb6xfjECb5mNoMW0w,12173
52
+ ngio/tables/backends/__init__.py,sha256=MwSRXNF1rWQBFOTDA_vT3oGoNZpviVgytsL5Txnu08I,1619
53
+ ngio/tables/backends/_abstract_backend.py,sha256=54Vh9yPfLx1NixGVfFkW4msD51nsim0zIfHRnO80Xt8,7276
54
+ ngio/tables/backends/_anndata.py,sha256=97RWG4Hjc42JBxm-YxjHEU8HHd14NiayelKlI1PTsCo,2868
55
+ ngio/tables/backends/_anndata_utils.py,sha256=HsmP27fm7JW1kjahl4lUnnViK_iqmu2bnsu86z43U98,3116
56
+ ngio/tables/backends/_csv.py,sha256=Ev61D-AUKo4LIhXRmWPJgYbHI7eQdxiajQR574DevEM,932
57
+ ngio/tables/backends/_json.py,sha256=1ZsEuXDJm1rOZV_KjFm8CB0qhv7L1W7L2EGWPf4q_p0,3137
58
+ ngio/tables/backends/_non_zarr_backends.py,sha256=BybUl800pqCdqJJmsGnUi4jsH1ibpQSUl0ZnumkFDwY,7298
59
+ ngio/tables/backends/_parquet.py,sha256=ic-p86h8lce8q9luBJGRzy6vxlWyJvA0-2l5cUD6OqY,1398
60
+ ngio/tables/backends/_table_backends.py,sha256=ksP2NAosXZkNMZf-IMrLx7bjQgp_eKfvPYK4vMdT1A8,7250
61
+ ngio/tables/backends/_utils.py,sha256=YFB7u2_l8lLAK_jrmlSfzH-2sOAFaDP1bmeUfuNo7YM,19719
62
+ ngio/tables/v1/__init__.py,sha256=Wr1_9RZFpaN8FYMTnxT9Yjkw4AS7y9FMWailmB_uj5g,617
63
+ ngio/tables/v1/_condition_table.py,sha256=T0Uq5BKkmMoEspt_Rx0U99Ow6S9GAMZDHqvUO5obCAM,1780
64
+ ngio/tables/v1/_feature_table.py,sha256=n9uMHwoBh-_dlOhUXCFbmAjXFVXncNCR3SjE2qzXI68,3821
65
+ ngio/tables/v1/_generic_table.py,sha256=1ktJHeuv7U1g5Z8PFUuTkCjOzcYMQd8xegKHKUedJB8,1240
66
+ ngio/tables/v1/_roi_table.py,sha256=szhtLzHWW-DaDz_OsGK89ur-WpNufCSMvEc66DRzv8g,16867
67
+ ngio/utils/__init__.py,sha256=XPYh8ehC7uXNU2cFFXZAw-S3DpWpX1Yq2xGkffZv5vI,1142
68
+ ngio/utils/_datasets.py,sha256=2g-Neg78dNcqyDz39QQw-Ifp9GITHjVHisdqgvvDNDE,5475
69
+ ngio/utils/_errors.py,sha256=pKQ12LUjQLYE1nUawemA5h7HsgznjaSvV1n2PQU33N0,759
70
+ ngio/utils/_fractal_fsspec_store.py,sha256=RdcCFOgHexRKX9zZvJV5RI-5OPc7VOPS6q_IeRxm24I,1548
71
+ ngio/utils/_logger.py,sha256=N5W0a_xwze4blS1MolidBkTMbjTbg8GPguJZNun3mAE,1392
72
+ ngio/utils/_zarr_utils.py,sha256=aYHhjHWGy5Jx7IkPb4nt9N0-HgyvJnyvK9GGqnccZkE,13606
73
+ ngio-0.4.0a2.dist-info/METADATA,sha256=Wd5zLtu8OLbjEbgV9Lb5FDlBP9dFT9QU4S8h2358jKc,5868
74
+ ngio-0.4.0a2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
75
+ ngio-0.4.0a2.dist-info/licenses/LICENSE,sha256=UgN_a1QCeNh9rZWfz-wORQFxE3elQzLWPQaoK6N6fxQ,1502
76
+ ngio-0.4.0a2.dist-info/RECORD,,