ngio 0.2.0a2__tar.gz → 0.2.0a3__tar.gz

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 (92) hide show
  1. {ngio-0.2.0a2 → ngio-0.2.0a3}/PKG-INFO +1 -1
  2. ngio-0.2.0a3/docs/api/core.md +3 -0
  3. {ngio-0.2.0a2 → ngio-0.2.0a3}/docs/notebooks/basic_usage.ipynb +73 -10
  4. {ngio-0.2.0a2 → ngio-0.2.0a3}/docs/notebooks/image.ipynb +2 -9
  5. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/images/image.py +22 -11
  6. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/images/label.py +29 -1
  7. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/images/omezarr_container.py +47 -11
  8. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +19 -8
  9. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/utils/__init__.py +3 -0
  10. ngio-0.2.0a3/src/ngio/utils/_fractal_fsspec_store.py +12 -0
  11. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/images/test_omezarr_container.py +3 -0
  12. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/test_ome_zarr_meta/test_unit_ngio_specs.py +2 -2
  13. ngio-0.2.0a2/docs/api/core.md +0 -8
  14. {ngio-0.2.0a2 → ngio-0.2.0a3}/.copier-answers.yml +0 -0
  15. {ngio-0.2.0a2 → ngio-0.2.0a3}/.gitattributes +0 -0
  16. {ngio-0.2.0a2 → ngio-0.2.0a3}/.github/ISSUE_TEMPLATE.md +0 -0
  17. {ngio-0.2.0a2 → ngio-0.2.0a3}/.github/TEST_FAIL_TEMPLATE.md +0 -0
  18. {ngio-0.2.0a2 → ngio-0.2.0a3}/.github/dependabot.yml +0 -0
  19. {ngio-0.2.0a2 → ngio-0.2.0a3}/.github/workflows/build_docs.yml +0 -0
  20. {ngio-0.2.0a2 → ngio-0.2.0a3}/.github/workflows/ci.yml +0 -0
  21. {ngio-0.2.0a2 → ngio-0.2.0a3}/.gitignore +0 -0
  22. {ngio-0.2.0a2 → ngio-0.2.0a3}/.pre-commit-config.yaml +0 -0
  23. {ngio-0.2.0a2 → ngio-0.2.0a3}/LICENSE +0 -0
  24. {ngio-0.2.0a2 → ngio-0.2.0a3}/README.md +0 -0
  25. {ngio-0.2.0a2 → ngio-0.2.0a3}/_typos.toml +0 -0
  26. {ngio-0.2.0a2 → ngio-0.2.0a3}/docs/getting-started.md +0 -0
  27. {ngio-0.2.0a2 → ngio-0.2.0a3}/docs/index.md +0 -0
  28. {ngio-0.2.0a2 → ngio-0.2.0a3}/docs/notebooks/processing.ipynb +0 -0
  29. {ngio-0.2.0a2 → ngio-0.2.0a3}/mkdocs.yml +0 -0
  30. {ngio-0.2.0a2 → ngio-0.2.0a3}/pyproject.toml +0 -0
  31. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/__init__.py +0 -0
  32. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/common/__init__.py +0 -0
  33. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/common/_array_pipe.py +0 -0
  34. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/common/_axes_transforms.py +0 -0
  35. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/common/_common_types.py +0 -0
  36. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/common/_dimensions.py +0 -0
  37. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/common/_pyramid.py +0 -0
  38. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/common/_roi.py +0 -0
  39. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/common/_slicer.py +0 -0
  40. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/common/_zoom.py +0 -0
  41. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/hcs/__init__.py +0 -0
  42. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/images/__init__.py +0 -0
  43. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/images/abstract_image.py +0 -0
  44. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/images/create.py +0 -0
  45. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/__init__.py +0 -0
  46. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/_generic_handlers.py +0 -0
  47. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/_meta_handlers.py +0 -0
  48. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/ngio_specs/__init__.py +0 -0
  49. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/ngio_specs/_axes.py +0 -0
  50. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/ngio_specs/_channels.py +0 -0
  51. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/ngio_specs/_dataset.py +0 -0
  52. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +0 -0
  53. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +0 -0
  54. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/v04/__init__.py +0 -0
  55. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/v04/_meta_handlers.py +0 -0
  56. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/ome_zarr_meta/v04/_v04_spec_utils.py +0 -0
  57. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/__init__.py +0 -0
  58. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/_validators.py +0 -0
  59. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/backends/__init__.py +0 -0
  60. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/backends/_abstract_backend.py +0 -0
  61. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/backends/_anndata_utils.py +0 -0
  62. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/backends/_anndata_v1.py +0 -0
  63. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/backends/_json_v1.py +0 -0
  64. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/backends/_table_backends.py +0 -0
  65. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/tables_container.py +0 -0
  66. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/v1/__init__.py +0 -0
  67. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/v1/_feature_table.py +0 -0
  68. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/v1/_generic_table.py +0 -0
  69. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/v1/_masking_roi_table.py +0 -0
  70. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/tables/v1/_roi_table.py +0 -0
  71. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/utils/_datasets.py +0 -0
  72. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/utils/_errors.py +0 -0
  73. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/utils/_logger.py +0 -0
  74. {ngio-0.2.0a2 → ngio-0.2.0a3}/src/ngio/utils/_zarr_utils.py +0 -0
  75. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/conftest.py +0 -0
  76. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/data/meta_v04/base_ome_zarr_image_meta.json +0 -0
  77. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/data/meta_v04/base_ome_zarr_image_meta_wrong_axis_order.json +0 -0
  78. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/data/meta_v04/base_ome_zarr_label_meta.json +0 -0
  79. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/common/test_dimensions.py +0 -0
  80. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/common/test_pyramid.py +0 -0
  81. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/common/test_roi.py +0 -0
  82. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/tables/test_backends.py +0 -0
  83. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/tables/test_feature_table.py +0 -0
  84. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/tables/test_generic_table.py +0 -0
  85. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/tables/test_masking_roi_table_v1.py +0 -0
  86. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/tables/test_roi_table_v1.py +0 -0
  87. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/tables/test_table_group.py +0 -0
  88. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/tables/test_validators.py +0 -0
  89. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/test_ome_zarr_meta/test_image_handler.py +0 -0
  90. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/test_ome_zarr_meta/test_unit_v04_utils.py +0 -0
  91. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/utils/test_download_datasets.py +0 -0
  92. {ngio-0.2.0a2 → ngio-0.2.0a3}/tests/unit/utils/test_zarr_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ngio
3
- Version: 0.2.0a2
3
+ Version: 0.2.0a3
4
4
  Summary: Next Generation file format IO
5
5
  Project-URL: homepage, https://github.com/lorenzocerrone/ngio
6
6
  Project-URL: repository, https://github.com/lorenzocerrone/ngio
@@ -0,0 +1,3 @@
1
+ # ngio
2
+
3
+ Work in progress! Sorry!
@@ -10,15 +10,6 @@
10
10
  "\n",
11
11
  "For this example we will use a small example image that can be downloaded from the following link: [example ome-zarr](https://zenodo.org/records/13305156)\n",
12
12
  "\n",
13
- "## Setup\n",
14
- "\n",
15
- "You can download the example image (on Linux and Mac os) by running the following command:\n",
16
- "\n",
17
- "```bash\n",
18
- "bash setup_data.sh\n",
19
- "```\n",
20
- "from the root of the repository.\n",
21
- "\n",
22
13
  "## OmeZarr Container\n",
23
14
  "\n",
24
15
  "The `OmeZarr Container` provides a high-level interface to read, write and manipulate NGFF images.\n",
@@ -95,7 +86,9 @@
95
86
  "print(image)\n",
96
87
  "\n",
97
88
  "# 3. Get image from a specific pixel size using the pixel_size keyword\n",
98
- "image = omezarr_container.get_image(pixel_size=PixelSize(x=0.65, y=0.65, z=1))\n",
89
+ "image = omezarr_container.get_image(\n",
90
+ " pixel_size=PixelSize(x=0.65, y=0.65, z=1000), strict=True\n",
91
+ ")\n",
99
92
  "print(image)"
100
93
  ]
101
94
  },
@@ -253,6 +246,32 @@
253
246
  "print(new_omezarr_image)"
254
247
  ]
255
248
  },
249
+ {
250
+ "cell_type": "markdown",
251
+ "metadata": {},
252
+ "source": [
253
+ "# Create an OmeZarr From a Numpy Array\n"
254
+ ]
255
+ },
256
+ {
257
+ "cell_type": "code",
258
+ "execution_count": null,
259
+ "metadata": {},
260
+ "outputs": [],
261
+ "source": [
262
+ "import numpy as np\n",
263
+ "\n",
264
+ "from ngio import create_omezarr_from_array\n",
265
+ "\n",
266
+ "x = np.random.randint(0, 255, (16, 128, 128), dtype=np.uint8)\n",
267
+ "\n",
268
+ "new_omezarr_image = create_omezarr_from_array(\n",
269
+ " store=\"random_ome.zarr\", array=x, xy_pixelsize=0.65, z_spacing=1.0\n",
270
+ ")\n",
271
+ "print(new_omezarr_image)\n",
272
+ "print(new_omezarr_image.get_image())"
273
+ ]
274
+ },
256
275
  {
257
276
  "cell_type": "markdown",
258
277
  "metadata": {},
@@ -284,6 +303,50 @@
284
303
  "omezarr"
285
304
  ]
286
305
  },
306
+ {
307
+ "cell_type": "markdown",
308
+ "metadata": {},
309
+ "source": [
310
+ "# Streaming an OmeZarr from a Fractal Server\n",
311
+ "\n",
312
+ "Example:\n",
313
+ "\n",
314
+ "```python\n",
315
+ "from ngio.utils import fractal_fsspec_store\n",
316
+ "\n",
317
+ "store = fractal_fsspec_store(url=\"https://fracral_url...\", fractal_token=\"**your_secret_token**\")\n",
318
+ "omezarr = open_omezarr_container(store)\n",
319
+ "omezarr\n",
320
+ "```"
321
+ ]
322
+ },
323
+ {
324
+ "cell_type": "code",
325
+ "execution_count": null,
326
+ "metadata": {},
327
+ "outputs": [],
328
+ "source": [
329
+ "from ngio import open_omezarr_container\n",
330
+ "from ngio.utils import fractal_fsspec_store\n",
331
+ "\n",
332
+ "store = fractal_fsspec_store(\n",
333
+ " url=\"https://fractal.mls.uzh.ch/vizarr/data/data/active/lorcerr/fractal/104_altmeyer_10097/443_experiment3/AP411_U2OS.zarr/A/1/0\",\n",
334
+ " fractal_token=\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MCIsImF1ZCI6WyJmYXN0YXBpLXVzZXJzOmF1dGgiXSwiZXhwIjoxNzQxMzY1NzY2fQ.wnpJSL6rtkKIoFeW7D31sVpEXeDcD0VrahwbF4CGbNI\",\n",
335
+ ")\n",
336
+ "omezarr = open_omezarr_container(store)\n",
337
+ "print(omezarr)\n",
338
+ "print(omezarr.get_image(path=\"3\").get_array())"
339
+ ]
340
+ },
341
+ {
342
+ "cell_type": "code",
343
+ "execution_count": null,
344
+ "metadata": {},
345
+ "outputs": [],
346
+ "source": [
347
+ "omezarr.get_image(path=\"3\").get_array()"
348
+ ]
349
+ },
287
350
  {
288
351
  "cell_type": "code",
289
352
  "execution_count": null,
@@ -216,7 +216,7 @@
216
216
  "outputs": [],
217
217
  "source": [
218
218
  "# Create a a new label object and set it to a simple segmentation\n",
219
- "new_label = omezarr.derive_label(\"new_label_2\", overwrite=True)\n",
219
+ "new_label = omezarr.derive_label(\"new_label\", overwrite=True)\n",
220
220
  "\n",
221
221
  "simple_segmentation = image.get_array(c=0) > 100\n",
222
222
  "simple_segmentation = simple_segmentation[0]\n",
@@ -225,7 +225,7 @@
225
225
  "# make a subplot with two image show side by side\n",
226
226
  "fig, axs = plt.subplots(1, 2, figsize=(10, 5))\n",
227
227
  "axs[0].imshow(image.get_array()[0, 0], cmap=\"gray\")\n",
228
- "axs[1].imshow(new_label.get_array()[0], cmap=\"gray\")\n",
228
+ "axs[1].imshow(new_label.get_array()[0])\n",
229
229
  "for ax in axs:\n",
230
230
  " ax.axis(\"off\")\n",
231
231
  "plt.tight_layout()\n",
@@ -327,13 +327,6 @@
327
327
  "feat_table = omezarr.get_table(\"new_feature_table\")\n",
328
328
  "feat_table.dataframe"
329
329
  ]
330
- },
331
- {
332
- "cell_type": "code",
333
- "execution_count": null,
334
- "metadata": {},
335
- "outputs": [],
336
- "source": []
337
330
  }
338
331
  ],
339
332
  "metadata": {
@@ -170,17 +170,20 @@ class ImagesContainer:
170
170
  be shown by default.
171
171
  omero_kwargs(dict): Extra fields to store in the omero attributes.
172
172
  """
173
- ref = self.get()
173
+ low_res_dataset = self.meta.get_lowest_resolution_dataset()
174
+ ref_image = self.get(path=low_res_dataset.path)
174
175
 
175
176
  if percentiles is not None:
176
177
  start, end = compute_image_percentile(
177
- ref, start_percentile=percentiles[0], end_percentile=percentiles[1]
178
+ ref_image,
179
+ start_percentile=percentiles[0],
180
+ end_percentile=percentiles[1],
178
181
  )
179
182
  else:
180
183
  start, end = None, None
181
184
 
182
185
  if labels is None:
183
- labels = ref.num_channels
186
+ labels = ref_image.num_channels
184
187
 
185
188
  channel_meta = ChannelsMeta.default_init(
186
189
  labels=labels,
@@ -189,7 +192,7 @@ class ImagesContainer:
189
192
  start=start,
190
193
  end=end,
191
194
  active=active,
192
- data_type=ref.dtype,
195
+ data_type=ref_image.dtype,
193
196
  **omero_kwargs,
194
197
  )
195
198
 
@@ -206,9 +209,10 @@ class ImagesContainer:
206
209
  if self.meta._channels_meta is None:
207
210
  raise NgioValidationError("The channels meta is not initialized.")
208
211
 
209
- image = self.get()
212
+ low_res_dataset = self.meta.get_lowest_resolution_dataset()
213
+ ref_image = self.get(path=low_res_dataset.path)
210
214
  starts, ends = compute_image_percentile(
211
- image, start_percentile=start_percentile, end_percentile=end_percentile
215
+ ref_image, start_percentile=start_percentile, end_percentile=end_percentile
212
216
  )
213
217
 
214
218
  channels = []
@@ -256,13 +260,20 @@ class ImagesContainer:
256
260
  self,
257
261
  path: str | None = None,
258
262
  pixel_size: PixelSize | None = None,
259
- highest_resolution: bool = True,
263
+ strict: bool = False,
260
264
  ) -> Image:
261
- """Get an image at a specific level."""
262
- if path is not None or pixel_size is not None:
263
- highest_resolution = False
265
+ """Get an image at a specific level.
266
+
267
+ Args:
268
+ path (str | None): The path to the image in the omezarr file.
269
+ pixel_size (PixelSize | None): The pixel size of the image.
270
+ strict (bool): Only used if the pixel size is provided. If True, the
271
+ pixel size must match the image pixel size exactly. If False, the
272
+ closest pixel size level will be returned.
273
+
274
+ """
264
275
  dataset = self._meta_handler.meta.get_dataset(
265
- path=path, pixel_size=pixel_size, highest_resolution=highest_resolution
276
+ path=path, pixel_size=pixel_size, strict=strict
266
277
  )
267
278
  return Image(
268
279
  group_handler=self._group_handler,
@@ -10,6 +10,7 @@ from ngio.ome_zarr_meta import (
10
10
  ImplementedLabelMetaHandlers,
11
11
  LabelMetaHandler,
12
12
  NgioLabelMeta,
13
+ PixelSize,
13
14
  )
14
15
  from ngio.ome_zarr_meta.ngio_specs import SpaceUnits, TimeUnits
15
16
  from ngio.utils import (
@@ -86,11 +87,38 @@ class LabelsContainer:
86
87
  attrs = self._group_handler.load_attrs()
87
88
  return attrs.get("labels", [])
88
89
 
89
- def get(self, name: str, path: str) -> Label:
90
+ def _get(self, name: str, path: str) -> Label:
90
91
  """Get a label from the group."""
91
92
  group_handler = self._group_handler.derive_handler(name)
92
93
  return Label(group_handler, path, None)
93
94
 
95
+ def get(
96
+ self,
97
+ name: str,
98
+ path: str | None = None,
99
+ pixel_size: PixelSize | None = None,
100
+ strict: bool = False,
101
+ ) -> Label:
102
+ """Get a label from the group.
103
+
104
+ Args:
105
+ name (str): The name of the label.
106
+ path (str | None): The path to the image in the omezarr file.
107
+ pixel_size (PixelSize | None): The pixel size of the image.
108
+ strict (bool): Only used if the pixel size is provided. If True, the
109
+ pixel size must match the image pixel size exactly. If False, the
110
+ closest pixel size level will be returned.
111
+
112
+ """
113
+ group_handler = self._group_handler.derive_handler(name)
114
+ label_meta_handler = ImplementedLabelMetaHandlers().find_meta_handler(
115
+ group_handler
116
+ )
117
+ path = label_meta_handler.meta.get_dataset(
118
+ path=path, pixel_size=pixel_size, strict=strict
119
+ ).path
120
+ return Label(group_handler, path, label_meta_handler)
121
+
94
122
  def derive(
95
123
  self,
96
124
  name: str,
@@ -160,13 +160,20 @@ class OmeZarrContainer:
160
160
  self,
161
161
  path: str | None = None,
162
162
  pixel_size: PixelSize | None = None,
163
- highest_resolution: bool = True,
163
+ strict: bool = False,
164
164
  ) -> Image:
165
- """Get an image at a specific level."""
165
+ """Get an image at a specific level.
166
+
167
+ Args:
168
+ path (str | None): The path to the image in the omezarr file.
169
+ pixel_size (PixelSize | None): The pixel size of the image.
170
+ strict (bool): Only used if the pixel size is provided. If True, the
171
+ pixel size must match the image pixel size exactly. If False, the
172
+ closest pixel size level will be returned.
173
+
174
+ """
166
175
  return self._images_container.get(
167
- path=path,
168
- pixel_size=pixel_size,
169
- highest_resolution=highest_resolution,
176
+ path=path, pixel_size=pixel_size, strict=strict
170
177
  )
171
178
 
172
179
  def derive_image(
@@ -279,11 +286,28 @@ class OmeZarrContainer:
279
286
  return []
280
287
  return self._labels_container.list()
281
288
 
282
- def get_label(self, name: str, path: str) -> Label:
283
- """Get a label from the image."""
289
+ def get_label(
290
+ self,
291
+ name: str,
292
+ path: str | None = None,
293
+ pixel_size: PixelSize | None = None,
294
+ strict: bool = False,
295
+ ) -> Label:
296
+ """Get a label from the group.
297
+
298
+ Args:
299
+ name (str): The name of the label.
300
+ path (str | None): The path to the image in the omezarr file.
301
+ pixel_size (PixelSize | None): The pixel size of the image.
302
+ strict (bool): Only used if the pixel size is provided. If True, the
303
+ pixel size must match the image pixel size exactly. If False, the
304
+ closest pixel size level will be returned.
305
+ """
284
306
  if self._labels_container is None:
285
307
  raise NgioValidationError("No labels found in the image.")
286
- return self._labels_container.get(name=name, path=path)
308
+ return self._labels_container.get(
309
+ name=name, path=path, pixel_size=pixel_size, strict=strict
310
+ )
287
311
 
288
312
  def derive_label(
289
313
  self,
@@ -334,17 +358,29 @@ def open_image(
334
358
  store: StoreOrGroup,
335
359
  path: str | None = None,
336
360
  pixel_size: PixelSize | None = None,
337
- highest_resolution: bool = False,
361
+ strict: bool = True,
338
362
  cache: bool = False,
339
363
  mode: AccessModeLiteral = "r+",
340
364
  ) -> Image:
341
- """Open a single level image from an OME-Zarr image."""
365
+ """Open a single level image from an OME-Zarr image.
366
+
367
+ Args:
368
+ store (StoreOrGroup): The Zarr store or group to create the image in.
369
+ path (str | None): The path to the image in the omezarr file.
370
+ pixel_size (PixelSize | None): The pixel size of the image.
371
+ strict (bool): Only used if the pixel size is provided. If True, the
372
+ pixel size must match the image pixel size exactly. If False, the
373
+ closest pixel size level will be returned.
374
+ cache (bool): Whether to use a cache for the zarr group metadata.
375
+ mode (AccessModeLiteral): The
376
+ access mode for the image. Defaults to "r+".
377
+ """
342
378
  group_handler = ZarrGroupHandler(store, cache, mode)
343
379
  images_container = ImagesContainer(group_handler)
344
380
  return images_container.get(
345
381
  path=path,
346
382
  pixel_size=pixel_size,
347
- highest_resolution=highest_resolution,
383
+ strict=strict,
348
384
  )
349
385
 
350
386
 
@@ -138,16 +138,16 @@ class AbstractNgioImageMeta:
138
138
  path: str | None = None,
139
139
  idx: int | None = None,
140
140
  pixel_size: PixelSize | None = None,
141
- highest_resolution: bool = False,
142
141
  strict: bool = False,
143
142
  ) -> Dataset:
144
143
  """Get a dataset by its path, index or pixel size.
145
144
 
145
+ If all arguments are None, the dataset with the highest resolution is returned.
146
+
146
147
  Args:
147
148
  path(str): The path of the dataset.
148
149
  idx(int): The index of the dataset.
149
150
  pixel_size(PixelSize): The pixel size to search for.
150
- highest_resolution(bool): If True, the dataset with the highest resolution
151
151
  strict(bool): If True, the pixel size must be exactly the same.
152
152
  If pixel_size is None, strict is ignored.
153
153
  """
@@ -158,12 +158,11 @@ class AbstractNgioImageMeta:
158
158
  path is not None,
159
159
  idx is not None,
160
160
  pixel_size is not None,
161
- highest_resolution,
162
161
  ]
163
162
  )
164
- != 1
163
+ > 1
165
164
  ):
166
- raise NgioValueError("get_dataset must receive only one argument.")
165
+ raise NgioValueError("get_dataset must receive only one argument or None.")
167
166
 
168
167
  if path is not None:
169
168
  return self._get_dataset_by_path(path)
@@ -171,10 +170,8 @@ class AbstractNgioImageMeta:
171
170
  return self._get_dataset_by_index(idx)
172
171
  elif pixel_size is not None:
173
172
  return self._get_dataset_by_pixel_size(pixel_size, strict=strict)
174
- elif highest_resolution:
175
- return self.get_highest_resolution_dataset()
176
173
  else:
177
- raise NgioValueError("get_dataset has no valid arguments.")
174
+ return self.get_highest_resolution_dataset()
178
175
 
179
176
  @classmethod
180
177
  def default_init(
@@ -237,6 +234,20 @@ class AbstractNgioImageMeta:
237
234
  strict=False,
238
235
  )
239
236
 
237
+ def get_lowest_resolution_dataset(self) -> Dataset:
238
+ """Get the dataset with the lowest resolution."""
239
+ return self._get_dataset_by_pixel_size(
240
+ pixel_size=PixelSize(
241
+ x=1000.0,
242
+ y=1000.0,
243
+ z=1000.0,
244
+ t=1000.0,
245
+ space_unit=SpaceUnits.micrometer,
246
+ time_unit=TimeUnits.s,
247
+ ),
248
+ strict=False,
249
+ )
250
+
240
251
  def get_scaling_factor(self, axis_name: str) -> float:
241
252
  """Get the scaling factors of the dataset."""
242
253
  scaling_factors = []
@@ -11,6 +11,7 @@ from ngio.utils._errors import (
11
11
  NgioValidationError,
12
12
  NgioValueError,
13
13
  )
14
+ from ngio.utils._fractal_fsspec_store import fractal_fsspec_store
14
15
  from ngio.utils._logger import ngio_logger, set_logger_level
15
16
  from ngio.utils._zarr_utils import (
16
17
  AccessModeLiteral,
@@ -35,6 +36,8 @@ __all__ = [
35
36
  "ZarrGroupHandler",
36
37
  # Datasets
37
38
  "download_ome_zarr_dataset",
39
+ # Fractal
40
+ "fractal_fsspec_store",
38
41
  "list_ome_zarr_datasets",
39
42
  # Logger
40
43
  "ngio_logger",
@@ -0,0 +1,12 @@
1
+ import fsspec.implementations.http
2
+
3
+
4
+ def fractal_fsspec_store(
5
+ url: str, fractal_token: str, client_kwargs: dict | None = None
6
+ ) -> fsspec.mapping.FSMap:
7
+ """Simple function to get an http fsspec store from a url."""
8
+ client_kwargs = {} if client_kwargs is None else client_kwargs
9
+ client_kwargs["headers"] = {"Authorization": f"Bearer {fractal_token}"}
10
+ fs = fsspec.implementations.http.HTTPFileSystem(client_kwargs=client_kwargs)
11
+ store = fs.get_mapper(url)
12
+ return store
@@ -26,10 +26,13 @@ def test_omezarr_container(tmp_path: Path, array_mode: str):
26
26
  assert omezarr.levels_paths == ["0", "1", "2"]
27
27
 
28
28
  image = omezarr.get_image()
29
+
29
30
  assert image.shape == (10, 20, 30)
30
31
  assert image.dtype == "uint8"
31
32
  assert image.chunks == (1, 20, 30)
32
33
  assert image.pixel_size.x == 0.5
34
+ assert image.meta.get_highest_resolution_dataset().path == "0"
35
+ assert image.meta.get_lowest_resolution_dataset().path == "2"
33
36
 
34
37
  array = image.get_array(
35
38
  x=slice(None), axes_order=["c", "z", "y", "x"], mode=array_mode
@@ -380,7 +380,7 @@ def test_image_meta():
380
380
  assert np.isclose(image_meta.z_scaling_factor, 1.0)
381
381
  assert image_meta.get_dataset(path="0").path == "0"
382
382
  assert image_meta.get_dataset(path="1").path == "1"
383
- assert image_meta.get_dataset(highest_resolution=True).path == "0"
383
+ assert image_meta.get_dataset().path == "0"
384
384
  assert image_meta.get_dataset(pixel_size=datasets[-1].pixel_size).path == "3"
385
385
  assert image_meta.get_channel_idx(label="DAPI") == 0
386
386
  assert image_meta.get_channel_idx(wavelength_id="DAPI") == 0
@@ -426,7 +426,7 @@ def test_label_meta():
426
426
  assert np.isclose(label_meta.z_scaling_factor, 1.0)
427
427
  assert label_meta.get_dataset(path="0").path == "0"
428
428
  assert label_meta.get_dataset(path="1").path == "1"
429
- assert label_meta.get_dataset(highest_resolution=True).path == "0"
429
+ assert label_meta.get_dataset().path == "0"
430
430
  assert label_meta.get_dataset(pixel_size=datasets[-1].pixel_size).path == "3"
431
431
 
432
432
 
@@ -1,8 +0,0 @@
1
- # ngio.core
2
-
3
- ::: ngio.core
4
- options:
5
- members: no
6
-
7
- ## NGFFImage
8
- ::: ngio.core.NgffImage
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes