ngio 0.2.0b3__py3-none-any.whl → 0.2.1__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.
- ngio/__init__.py +11 -9
- ngio/common/__init__.py +3 -3
- ngio/common/_array_pipe.py +7 -1
- ngio/common/_masking_roi.py +4 -4
- ngio/common/_roi.py +12 -12
- ngio/hcs/__init__.py +2 -2
- ngio/hcs/plate.py +86 -34
- ngio/images/__init__.py +7 -7
- ngio/images/abstract_image.py +20 -10
- ngio/images/create.py +4 -3
- ngio/images/image.py +2 -2
- ngio/images/label.py +10 -6
- ngio/images/masked_image.py +19 -5
- ngio/images/{omezarr_container.py → ome_zarr_container.py} +27 -30
- ngio/ome_zarr_meta/__init__.py +3 -0
- ngio/ome_zarr_meta/ngio_specs/__init__.py +2 -0
- ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +5 -4
- ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +9 -13
- ngio/ome_zarr_meta/v04/_v04_spec_utils.py +1 -2
- ngio/tables/__init__.py +2 -2
- ngio/tables/tables_container.py +3 -3
- ngio/tables/v1/__init__.py +2 -2
- ngio/tables/v1/_feature_table.py +20 -1
- ngio/tables/v1/_generic_table.py +10 -0
- ngio/tables/v1/_roi_table.py +35 -13
- {ngio-0.2.0b3.dist-info → ngio-0.2.1.dist-info}/METADATA +8 -5
- ngio-0.2.1.dist-info/RECORD +54 -0
- ngio-0.2.0b3.dist-info/RECORD +0 -54
- {ngio-0.2.0b3.dist-info → ngio-0.2.1.dist-info}/WHEEL +0 -0
- {ngio-0.2.0b3.dist-info → ngio-0.2.1.dist-info}/licenses/LICENSE +0 -0
ngio/images/masked_image.py
CHANGED
|
@@ -7,7 +7,7 @@ from ngio.common import ArrayLike, get_masked_pipe, roi_to_slice_kwargs, set_mas
|
|
|
7
7
|
from ngio.images.image import Image
|
|
8
8
|
from ngio.images.label import Label
|
|
9
9
|
from ngio.ome_zarr_meta import ImageMetaHandler, LabelMetaHandler
|
|
10
|
-
from ngio.tables import
|
|
10
|
+
from ngio.tables import MaskingRoiTable
|
|
11
11
|
from ngio.utils import (
|
|
12
12
|
ZarrGroupHandler,
|
|
13
13
|
)
|
|
@@ -22,13 +22,13 @@ class MaskedImage(Image):
|
|
|
22
22
|
path: str,
|
|
23
23
|
meta_handler: ImageMetaHandler | None,
|
|
24
24
|
label: Label,
|
|
25
|
-
masking_roi_table:
|
|
25
|
+
masking_roi_table: MaskingRoiTable,
|
|
26
26
|
) -> None:
|
|
27
27
|
"""Initialize the Image at a single level.
|
|
28
28
|
|
|
29
29
|
Args:
|
|
30
30
|
group_handler: The Zarr group handler.
|
|
31
|
-
path: The path to the image in the
|
|
31
|
+
path: The path to the image in the ome_zarr file.
|
|
32
32
|
meta_handler: The image metadata handler.
|
|
33
33
|
label: The label image.
|
|
34
34
|
masking_roi_table: The masking ROI table.
|
|
@@ -40,6 +40,13 @@ class MaskedImage(Image):
|
|
|
40
40
|
self._label = label
|
|
41
41
|
self._masking_roi_table = masking_roi_table
|
|
42
42
|
|
|
43
|
+
def __repr__(self) -> str:
|
|
44
|
+
"""Return a string representation of the object."""
|
|
45
|
+
label_name = self._label.meta.name
|
|
46
|
+
if label_name is None:
|
|
47
|
+
label_name = self._masking_roi_table.reference_label
|
|
48
|
+
return f"MaskedImage(path={self.path}, {self.dimensions}, {label_name})"
|
|
49
|
+
|
|
43
50
|
def get_roi(
|
|
44
51
|
self,
|
|
45
52
|
label: int,
|
|
@@ -116,13 +123,13 @@ class MaskedLabel(Label):
|
|
|
116
123
|
path: str,
|
|
117
124
|
meta_handler: LabelMetaHandler | None,
|
|
118
125
|
label: Label,
|
|
119
|
-
masking_roi_table:
|
|
126
|
+
masking_roi_table: MaskingRoiTable,
|
|
120
127
|
) -> None:
|
|
121
128
|
"""Initialize the Image at a single level.
|
|
122
129
|
|
|
123
130
|
Args:
|
|
124
131
|
group_handler: The Zarr group handler.
|
|
125
|
-
path: The path to the image in the
|
|
132
|
+
path: The path to the image in the ome_zarr file.
|
|
126
133
|
meta_handler: The image metadata handler.
|
|
127
134
|
label: The label image.
|
|
128
135
|
masking_roi_table: The masking ROI table.
|
|
@@ -134,6 +141,13 @@ class MaskedLabel(Label):
|
|
|
134
141
|
self._label = label
|
|
135
142
|
self._masking_roi_table = masking_roi_table
|
|
136
143
|
|
|
144
|
+
def __repr__(self) -> str:
|
|
145
|
+
"""Return a string representation of the object."""
|
|
146
|
+
label_name = self._label.meta.name
|
|
147
|
+
if label_name is None:
|
|
148
|
+
label_name = self._masking_roi_table.reference_label
|
|
149
|
+
return f"MaskedLabel(path={self.path}, {self.dimensions}, {label_name})"
|
|
150
|
+
|
|
137
151
|
def get_roi(
|
|
138
152
|
self,
|
|
139
153
|
label: int,
|
|
@@ -13,14 +13,11 @@ from ngio.ome_zarr_meta import (
|
|
|
13
13
|
NgioImageMeta,
|
|
14
14
|
PixelSize,
|
|
15
15
|
)
|
|
16
|
-
from ngio.ome_zarr_meta.ngio_specs import
|
|
17
|
-
SpaceUnits,
|
|
18
|
-
TimeUnits,
|
|
19
|
-
)
|
|
16
|
+
from ngio.ome_zarr_meta.ngio_specs import NgffVersion, SpaceUnits, TimeUnits
|
|
20
17
|
from ngio.tables import (
|
|
21
18
|
FeatureTable,
|
|
22
19
|
GenericRoiTable,
|
|
23
|
-
|
|
20
|
+
MaskingRoiTable,
|
|
24
21
|
RoiTable,
|
|
25
22
|
Table,
|
|
26
23
|
TablesContainer,
|
|
@@ -193,7 +190,7 @@ class OmeZarrContainer:
|
|
|
193
190
|
"""Get an image at a specific level.
|
|
194
191
|
|
|
195
192
|
Args:
|
|
196
|
-
path (str | None): The path to the image in the
|
|
193
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
197
194
|
pixel_size (PixelSize | None): The pixel size of the image.
|
|
198
195
|
strict (bool): Only used if the pixel size is provided. If True, the
|
|
199
196
|
pixel size must match the image pixel size exactly. If False, the
|
|
@@ -217,7 +214,7 @@ class OmeZarrContainer:
|
|
|
217
214
|
Args:
|
|
218
215
|
masking_label_name (str): The name of the label.
|
|
219
216
|
masking_table_name (str | None): The name of the masking table.
|
|
220
|
-
path (str | None): The path to the image in the
|
|
217
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
221
218
|
pixel_size (PixelSize | None): The pixel size of the image.
|
|
222
219
|
strict (bool): Only used if the pixel size is provided. If True, the
|
|
223
220
|
pixel size must match the image pixel size exactly. If False, the
|
|
@@ -292,21 +289,21 @@ class OmeZarrContainer:
|
|
|
292
289
|
store, cache=self._group_handler.use_cache, mode=self._group_handler.mode
|
|
293
290
|
)
|
|
294
291
|
|
|
295
|
-
|
|
292
|
+
new_ome_zarr = OmeZarrContainer(
|
|
296
293
|
group_handler=handler,
|
|
297
294
|
validate_arrays=False,
|
|
298
295
|
)
|
|
299
296
|
|
|
300
297
|
if copy_labels:
|
|
301
298
|
self.labels_container._group_handler.copy_handler(
|
|
302
|
-
|
|
299
|
+
new_ome_zarr.labels_container._group_handler
|
|
303
300
|
)
|
|
304
301
|
|
|
305
302
|
if copy_tables:
|
|
306
303
|
self.tables_container._group_handler.copy_handler(
|
|
307
|
-
|
|
304
|
+
new_ome_zarr.tables_container._group_handler
|
|
308
305
|
)
|
|
309
|
-
return
|
|
306
|
+
return new_ome_zarr
|
|
310
307
|
|
|
311
308
|
def list_tables(self) -> list[str]:
|
|
312
309
|
"""List all tables in the image."""
|
|
@@ -325,7 +322,7 @@ class OmeZarrContainer:
|
|
|
325
322
|
@overload
|
|
326
323
|
def get_table(
|
|
327
324
|
self, name: str, check_type: Literal["masking_roi_table"]
|
|
328
|
-
) ->
|
|
325
|
+
) -> MaskingRoiTable: ...
|
|
329
326
|
|
|
330
327
|
@overload
|
|
331
328
|
def get_table(
|
|
@@ -348,7 +345,7 @@ class OmeZarrContainer:
|
|
|
348
345
|
)
|
|
349
346
|
return table
|
|
350
347
|
case "masking_roi_table":
|
|
351
|
-
if not isinstance(table,
|
|
348
|
+
if not isinstance(table, MaskingRoiTable):
|
|
352
349
|
raise NgioValueError(
|
|
353
350
|
f"Table '{name}' is not a masking ROI table. "
|
|
354
351
|
f"Found type: {table.type()}"
|
|
@@ -379,7 +376,7 @@ class OmeZarrContainer:
|
|
|
379
376
|
"""Compute the ROI table for an image."""
|
|
380
377
|
return self.get_image().build_image_roi_table(name=name)
|
|
381
378
|
|
|
382
|
-
def build_masking_roi_table(self, label: str) ->
|
|
379
|
+
def build_masking_roi_table(self, label: str) -> MaskingRoiTable:
|
|
383
380
|
"""Compute the masking ROI table for a label."""
|
|
384
381
|
return self.get_label(label).build_masking_roi_table()
|
|
385
382
|
|
|
@@ -410,7 +407,7 @@ class OmeZarrContainer:
|
|
|
410
407
|
|
|
411
408
|
Args:
|
|
412
409
|
name (str): The name of the label.
|
|
413
|
-
path (str | None): The path to the image in the
|
|
410
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
414
411
|
pixel_size (PixelSize | None): The pixel size of the image.
|
|
415
412
|
strict (bool): Only used if the pixel size is provided. If True, the
|
|
416
413
|
pixel size must match the image pixel size exactly. If False, the
|
|
@@ -435,7 +432,7 @@ class OmeZarrContainer:
|
|
|
435
432
|
label_name (str): The name of the label.
|
|
436
433
|
masking_label_name (str): The name of the masking label.
|
|
437
434
|
masking_table_name (str | None): The name of the masking table.
|
|
438
|
-
path (str | None): The path to the image in the
|
|
435
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
439
436
|
pixel_size (PixelSize | None): The pixel size of the image.
|
|
440
437
|
strict (bool): Only used if the pixel size is provided. If True, the
|
|
441
438
|
pixel size must match the image pixel size exactly. If False, the
|
|
@@ -507,7 +504,7 @@ class OmeZarrContainer:
|
|
|
507
504
|
)
|
|
508
505
|
|
|
509
506
|
|
|
510
|
-
def
|
|
507
|
+
def open_ome_zarr_container(
|
|
511
508
|
store: StoreOrGroup,
|
|
512
509
|
cache: bool = False,
|
|
513
510
|
mode: AccessModeLiteral = "r+",
|
|
@@ -533,7 +530,7 @@ def open_image(
|
|
|
533
530
|
|
|
534
531
|
Args:
|
|
535
532
|
store (StoreOrGroup): The Zarr store or group to create the image in.
|
|
536
|
-
path (str | None): The path to the image in the
|
|
533
|
+
path (str | None): The path to the image in the ome_zarr file.
|
|
537
534
|
pixel_size (PixelSize | None): The pixel size of the image.
|
|
538
535
|
strict (bool): Only used if the pixel size is provided. If True, the
|
|
539
536
|
pixel size must match the image pixel size exactly. If False, the
|
|
@@ -551,7 +548,7 @@ def open_image(
|
|
|
551
548
|
)
|
|
552
549
|
|
|
553
550
|
|
|
554
|
-
def
|
|
551
|
+
def create_empty_ome_zarr(
|
|
555
552
|
store: StoreOrGroup,
|
|
556
553
|
shape: Collection[int],
|
|
557
554
|
xy_pixelsize: float,
|
|
@@ -572,7 +569,7 @@ def create_empty_omezarr(
|
|
|
572
569
|
channel_colors: Collection[str] | None = None,
|
|
573
570
|
channel_active: Collection[bool] | None = None,
|
|
574
571
|
overwrite: bool = False,
|
|
575
|
-
version:
|
|
572
|
+
version: NgffVersion = "0.4",
|
|
576
573
|
) -> OmeZarrContainer:
|
|
577
574
|
"""Create an empty OME-Zarr image with the given shape and metadata.
|
|
578
575
|
|
|
@@ -611,7 +608,7 @@ def create_empty_omezarr(
|
|
|
611
608
|
active. Defaults to None.
|
|
612
609
|
overwrite (bool, optional): Whether to overwrite an existing image.
|
|
613
610
|
Defaults to True.
|
|
614
|
-
version (
|
|
611
|
+
version (NgffVersion, optional): The version of the OME-Zarr specification.
|
|
615
612
|
Defaults to "0.4".
|
|
616
613
|
"""
|
|
617
614
|
handler = _create_empty_image(
|
|
@@ -633,18 +630,18 @@ def create_empty_omezarr(
|
|
|
633
630
|
version=version,
|
|
634
631
|
)
|
|
635
632
|
|
|
636
|
-
|
|
637
|
-
|
|
633
|
+
ome_zarr = OmeZarrContainer(group_handler=handler)
|
|
634
|
+
ome_zarr.initialize_channel_meta(
|
|
638
635
|
labels=channel_labels,
|
|
639
636
|
wavelength_id=channel_wavelengths,
|
|
640
637
|
percentiles=percentiles,
|
|
641
638
|
colors=channel_colors,
|
|
642
639
|
active=channel_active,
|
|
643
640
|
)
|
|
644
|
-
return
|
|
641
|
+
return ome_zarr
|
|
645
642
|
|
|
646
643
|
|
|
647
|
-
def
|
|
644
|
+
def create_ome_zarr_from_array(
|
|
648
645
|
store: StoreOrGroup,
|
|
649
646
|
array: np.ndarray,
|
|
650
647
|
xy_pixelsize: float,
|
|
@@ -664,7 +661,7 @@ def create_omezarr_from_array(
|
|
|
664
661
|
name: str | None = None,
|
|
665
662
|
chunks: Collection[int] | None = None,
|
|
666
663
|
overwrite: bool = False,
|
|
667
|
-
version:
|
|
664
|
+
version: NgffVersion = "0.4",
|
|
668
665
|
) -> OmeZarrContainer:
|
|
669
666
|
"""Create an OME-Zarr image from a numpy array.
|
|
670
667
|
|
|
@@ -724,15 +721,15 @@ def create_omezarr_from_array(
|
|
|
724
721
|
version=version,
|
|
725
722
|
)
|
|
726
723
|
|
|
727
|
-
|
|
728
|
-
image =
|
|
724
|
+
ome_zarr = OmeZarrContainer(group_handler=handler)
|
|
725
|
+
image = ome_zarr.get_image()
|
|
729
726
|
image.set_array(array)
|
|
730
727
|
image.consolidate()
|
|
731
|
-
|
|
728
|
+
ome_zarr.initialize_channel_meta(
|
|
732
729
|
labels=channel_labels,
|
|
733
730
|
wavelength_id=channel_wavelengths,
|
|
734
731
|
percentiles=percentiles,
|
|
735
732
|
colors=channel_colors,
|
|
736
733
|
active=channel_active,
|
|
737
734
|
)
|
|
738
|
-
return
|
|
735
|
+
return ome_zarr
|
ngio/ome_zarr_meta/__init__.py
CHANGED
|
@@ -16,6 +16,7 @@ from ngio.ome_zarr_meta.ngio_specs import (
|
|
|
16
16
|
AxesMapper,
|
|
17
17
|
Dataset,
|
|
18
18
|
ImageInWellPath,
|
|
19
|
+
NgffVersion,
|
|
19
20
|
NgioImageMeta,
|
|
20
21
|
NgioLabelMeta,
|
|
21
22
|
NgioPlateMeta,
|
|
@@ -31,6 +32,8 @@ __all__ = [
|
|
|
31
32
|
"ImageMetaHandler",
|
|
32
33
|
"LabelMetaHandler",
|
|
33
34
|
"LabelMetaHandler",
|
|
35
|
+
"NgffVersion",
|
|
36
|
+
"NgffVersion",
|
|
34
37
|
"NgioImageMeta",
|
|
35
38
|
"NgioLabelMeta",
|
|
36
39
|
"NgioPlateMeta",
|
|
@@ -35,6 +35,7 @@ from ngio.ome_zarr_meta.ngio_specs._ngio_hcs import (
|
|
|
35
35
|
)
|
|
36
36
|
from ngio.ome_zarr_meta.ngio_specs._ngio_image import (
|
|
37
37
|
ImageLabelSource,
|
|
38
|
+
NgffVersion,
|
|
38
39
|
NgioImageLabelMeta,
|
|
39
40
|
NgioImageMeta,
|
|
40
41
|
NgioLabelMeta,
|
|
@@ -56,6 +57,7 @@ __all__ = [
|
|
|
56
57
|
"Dataset",
|
|
57
58
|
"ImageInWellPath",
|
|
58
59
|
"ImageLabelSource",
|
|
60
|
+
"NgffVersion",
|
|
59
61
|
"NgioColors",
|
|
60
62
|
"NgioImageLabelMeta",
|
|
61
63
|
"NgioImageMeta",
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
"""HCS (High Content Screening) specific metadata classes for NGIO."""
|
|
2
2
|
|
|
3
|
-
from typing import Literal
|
|
4
|
-
|
|
5
3
|
from ome_zarr_models.v04.hcs import HCSAttrs
|
|
6
4
|
from ome_zarr_models.v04.plate import (
|
|
7
5
|
Acquisition,
|
|
@@ -14,6 +12,7 @@ from ome_zarr_models.v04.well import WellAttrs
|
|
|
14
12
|
from ome_zarr_models.v04.well_types import WellImage, WellMeta
|
|
15
13
|
from pydantic import BaseModel
|
|
16
14
|
|
|
15
|
+
from ngio.ome_zarr_meta.ngio_specs._ngio_image import NgffVersion
|
|
17
16
|
from ngio.utils import NgioValueError
|
|
18
17
|
|
|
19
18
|
|
|
@@ -34,8 +33,10 @@ class NgioWellMeta(WellAttrs):
|
|
|
34
33
|
def default_init(
|
|
35
34
|
cls,
|
|
36
35
|
images: list[ImageInWellPath] | None = None,
|
|
37
|
-
version:
|
|
36
|
+
version: NgffVersion | None = None,
|
|
38
37
|
) -> "NgioWellMeta":
|
|
38
|
+
if version is None:
|
|
39
|
+
version = "0.4"
|
|
39
40
|
well = cls(well=WellMeta(images=[], version=version))
|
|
40
41
|
if images is None:
|
|
41
42
|
return well
|
|
@@ -164,7 +165,7 @@ class NgioPlateMeta(HCSAttrs):
|
|
|
164
165
|
cls,
|
|
165
166
|
images: list[ImageInWellPath] | None = None,
|
|
166
167
|
name: str | None = None,
|
|
167
|
-
version:
|
|
168
|
+
version: NgffVersion | None = None,
|
|
168
169
|
) -> "NgioPlateMeta":
|
|
169
170
|
plate = cls(
|
|
170
171
|
plate=Plate(
|
|
@@ -7,8 +7,7 @@ can be converted to the OME standard.
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from collections.abc import Collection
|
|
10
|
-
from
|
|
11
|
-
from typing import Any, TypeVar
|
|
10
|
+
from typing import Any, Literal, TypeVar
|
|
12
11
|
|
|
13
12
|
import numpy as np
|
|
14
13
|
from pydantic import BaseModel
|
|
@@ -22,12 +21,7 @@ from ngio.ome_zarr_meta.ngio_specs._pixel_size import PixelSize
|
|
|
22
21
|
from ngio.utils import NgioValidationError, NgioValueError
|
|
23
22
|
|
|
24
23
|
T = TypeVar("T")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class NgffVersion(str, Enum):
|
|
28
|
-
"""Allowed NGFF versions."""
|
|
29
|
-
|
|
30
|
-
v04 = "0.4"
|
|
24
|
+
NgffVersion = Literal["0.4"]
|
|
31
25
|
|
|
32
26
|
|
|
33
27
|
class ImageLabelSource(BaseModel):
|
|
@@ -45,9 +39,11 @@ class ImageLabelSource(BaseModel):
|
|
|
45
39
|
class AbstractNgioImageMeta:
|
|
46
40
|
"""Base class for ImageMeta and LabelMeta."""
|
|
47
41
|
|
|
48
|
-
def __init__(
|
|
42
|
+
def __init__(
|
|
43
|
+
self, version: NgffVersion, name: str | None, datasets: list[Dataset]
|
|
44
|
+
) -> None:
|
|
49
45
|
"""Initialize the ImageMeta object."""
|
|
50
|
-
self._version =
|
|
46
|
+
self._version = version
|
|
51
47
|
self._name = name
|
|
52
48
|
|
|
53
49
|
if len(datasets) == 0:
|
|
@@ -70,7 +66,7 @@ class AbstractNgioImageMeta:
|
|
|
70
66
|
pixel_size: PixelSize,
|
|
71
67
|
scaling_factors: Collection[float] | None = None,
|
|
72
68
|
name: str | None = None,
|
|
73
|
-
version:
|
|
69
|
+
version: NgffVersion = "0.4",
|
|
74
70
|
):
|
|
75
71
|
"""Initialize the ImageMeta object."""
|
|
76
72
|
axes = canonical_axes(
|
|
@@ -335,7 +331,7 @@ class NgioLabelMeta(AbstractNgioImageMeta):
|
|
|
335
331
|
|
|
336
332
|
def __init__(
|
|
337
333
|
self,
|
|
338
|
-
version:
|
|
334
|
+
version: NgffVersion,
|
|
339
335
|
name: str | None,
|
|
340
336
|
datasets: list[Dataset],
|
|
341
337
|
image_label: ImageLabelSource | None = None,
|
|
@@ -374,7 +370,7 @@ class NgioImageMeta(AbstractNgioImageMeta):
|
|
|
374
370
|
|
|
375
371
|
def __init__(
|
|
376
372
|
self,
|
|
377
|
-
version:
|
|
373
|
+
version: NgffVersion,
|
|
378
374
|
name: str | None,
|
|
379
375
|
datasets: list[Dataset],
|
|
380
376
|
channels: ChannelsMeta | None = None,
|
|
@@ -41,7 +41,6 @@ from ngio.ome_zarr_meta.ngio_specs import (
|
|
|
41
41
|
NgioWellMeta,
|
|
42
42
|
default_channel_name,
|
|
43
43
|
)
|
|
44
|
-
from ngio.ome_zarr_meta.ngio_specs._ngio_image import NgffVersion
|
|
45
44
|
|
|
46
45
|
|
|
47
46
|
def _is_v04_image_meta(metadata: dict) -> ImageAttrsV04 | ValidationError:
|
|
@@ -290,7 +289,7 @@ def v04_to_ngio_label_meta(
|
|
|
290
289
|
else:
|
|
291
290
|
image_label_source = source.image
|
|
292
291
|
image_label_source = ImageLabelSource(
|
|
293
|
-
version=
|
|
292
|
+
version="0.4",
|
|
294
293
|
source={"image": image_label_source},
|
|
295
294
|
)
|
|
296
295
|
name = v04_muliscale.name
|
ngio/tables/__init__.py
CHANGED
|
@@ -4,7 +4,7 @@ from ngio.tables.backends import ImplementedTableBackends
|
|
|
4
4
|
from ngio.tables.tables_container import (
|
|
5
5
|
FeatureTable,
|
|
6
6
|
GenericRoiTable,
|
|
7
|
-
|
|
7
|
+
MaskingRoiTable,
|
|
8
8
|
RoiTable,
|
|
9
9
|
Table,
|
|
10
10
|
TablesContainer,
|
|
@@ -19,7 +19,7 @@ __all__ = [
|
|
|
19
19
|
"GenericRoiTable",
|
|
20
20
|
"GenericTable",
|
|
21
21
|
"ImplementedTableBackends",
|
|
22
|
-
"
|
|
22
|
+
"MaskingRoiTable",
|
|
23
23
|
"RoiTable",
|
|
24
24
|
"Table",
|
|
25
25
|
"TablesContainer",
|
ngio/tables/tables_container.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from typing import Literal, Protocol
|
|
4
4
|
|
|
5
|
-
from ngio.tables.v1 import FeatureTableV1,
|
|
5
|
+
from ngio.tables.v1 import FeatureTableV1, MaskingRoiTableV1, RoiTableV1
|
|
6
6
|
from ngio.tables.v1._generic_table import GenericTable
|
|
7
7
|
from ngio.tables.v1._roi_table import _GenericRoiTableV1
|
|
8
8
|
from ngio.utils import (
|
|
@@ -15,7 +15,7 @@ from ngio.utils import (
|
|
|
15
15
|
|
|
16
16
|
GenericRoiTable = _GenericRoiTableV1
|
|
17
17
|
RoiTable = RoiTableV1
|
|
18
|
-
|
|
18
|
+
MaskingRoiTable = MaskingRoiTableV1
|
|
19
19
|
FeatureTable = FeatureTableV1
|
|
20
20
|
|
|
21
21
|
|
|
@@ -253,7 +253,7 @@ class TablesContainer:
|
|
|
253
253
|
|
|
254
254
|
|
|
255
255
|
ImplementedTables().add_implementation(RoiTableV1)
|
|
256
|
-
ImplementedTables().add_implementation(
|
|
256
|
+
ImplementedTables().add_implementation(MaskingRoiTableV1)
|
|
257
257
|
ImplementedTables().add_implementation(FeatureTableV1)
|
|
258
258
|
|
|
259
259
|
###################################################################################
|
ngio/tables/v1/__init__.py
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from ngio.tables.v1._feature_table import FeatureTableV1
|
|
4
4
|
from ngio.tables.v1._generic_table import GenericTable
|
|
5
|
-
from ngio.tables.v1._roi_table import
|
|
5
|
+
from ngio.tables.v1._roi_table import MaskingRoiTableV1, RoiTableV1
|
|
6
6
|
|
|
7
|
-
__all__ = ["FeatureTableV1", "GenericTable", "
|
|
7
|
+
__all__ = ["FeatureTableV1", "GenericTable", "MaskingRoiTableV1", "RoiTableV1"]
|
ngio/tables/v1/_feature_table.py
CHANGED
|
@@ -49,7 +49,6 @@ class FeatureTableV1:
|
|
|
49
49
|
path = f"../labels/{reference_label}"
|
|
50
50
|
self._meta = FeatureTableMeta(region=RegionMeta(path=path))
|
|
51
51
|
|
|
52
|
-
self._reference_label = reference_label
|
|
53
52
|
self._instance_key = "label"
|
|
54
53
|
if dataframe is None:
|
|
55
54
|
self._dataframe = None
|
|
@@ -59,6 +58,15 @@ class FeatureTableV1:
|
|
|
59
58
|
)
|
|
60
59
|
self._table_backend = None
|
|
61
60
|
|
|
61
|
+
def __repr__(self) -> str:
|
|
62
|
+
"""Return a string representation of the table."""
|
|
63
|
+
num_rows = len(self.dataframe) if self.dataframe is not None else 0
|
|
64
|
+
num_columns = len(self.dataframe.columns) if self.dataframe is not None else 0
|
|
65
|
+
properties = f"num_rows={num_rows}, num_columns={num_columns}"
|
|
66
|
+
if self.reference_label is not None:
|
|
67
|
+
properties += f", reference_label={self.reference_label}"
|
|
68
|
+
return f"FeatureTableV1({properties})"
|
|
69
|
+
|
|
62
70
|
@staticmethod
|
|
63
71
|
def type() -> str:
|
|
64
72
|
"""Return the type of the table."""
|
|
@@ -79,6 +87,17 @@ class FeatureTableV1:
|
|
|
79
87
|
return None
|
|
80
88
|
return self._table_backend.backend_name()
|
|
81
89
|
|
|
90
|
+
@property
|
|
91
|
+
def reference_label(self) -> str | None:
|
|
92
|
+
"""Return the reference label."""
|
|
93
|
+
path = self._meta.region
|
|
94
|
+
if path is None:
|
|
95
|
+
return None
|
|
96
|
+
|
|
97
|
+
path = path.path
|
|
98
|
+
path = path.split("/")[-1]
|
|
99
|
+
return path
|
|
100
|
+
|
|
82
101
|
@property
|
|
83
102
|
def dataframe(self) -> pd.DataFrame:
|
|
84
103
|
"""Return the table as a DataFrame."""
|
ngio/tables/v1/_generic_table.py
CHANGED
|
@@ -51,6 +51,16 @@ class GenericTable:
|
|
|
51
51
|
|
|
52
52
|
self._table_backend = None
|
|
53
53
|
|
|
54
|
+
def __repr__(self) -> str:
|
|
55
|
+
"""Return a string representation of the table."""
|
|
56
|
+
if self._dataframe is not None:
|
|
57
|
+
num_rows = len(self.dataframe)
|
|
58
|
+
num_columns = len(self.dataframe.columns)
|
|
59
|
+
prop = f"num_rows={num_rows}, num_columns={num_columns}, mode=dataframe"
|
|
60
|
+
else:
|
|
61
|
+
prop = "mode=anndata"
|
|
62
|
+
return f"GenericTable({prop})"
|
|
63
|
+
|
|
54
64
|
@staticmethod
|
|
55
65
|
def type() -> str:
|
|
56
66
|
"""Return the type of the table."""
|
ngio/tables/v1/_roi_table.py
CHANGED
|
@@ -12,7 +12,7 @@ from typing import Generic, Literal, TypeVar
|
|
|
12
12
|
import pandas as pd
|
|
13
13
|
from pydantic import BaseModel
|
|
14
14
|
|
|
15
|
-
from ngio.common import
|
|
15
|
+
from ngio.common import Roi
|
|
16
16
|
from ngio.tables._validators import validate_columns
|
|
17
17
|
from ngio.tables.backends import ImplementedTableBackends
|
|
18
18
|
from ngio.utils import NgioValueError, ZarrGroupHandler
|
|
@@ -37,7 +37,7 @@ TRANSLATION_COLUMNS = ["translation_x", "translation_y", "translation_z"]
|
|
|
37
37
|
OPTIONAL_COLUMNS = ORIGIN_COLUMNS + TRANSLATION_COLUMNS
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
def _dataframe_to_rois(dataframe: pd.DataFrame) -> dict[str,
|
|
40
|
+
def _dataframe_to_rois(dataframe: pd.DataFrame) -> dict[str, Roi]:
|
|
41
41
|
"""Convert a DataFrame to a WorldCooROI object."""
|
|
42
42
|
rois = {}
|
|
43
43
|
for key, row in dataframe.iterrows():
|
|
@@ -47,7 +47,7 @@ def _dataframe_to_rois(dataframe: pd.DataFrame) -> dict[str, WorldCooROI]:
|
|
|
47
47
|
translation = {col: row.get(col, None) for col in TRANSLATION_COLUMNS}
|
|
48
48
|
translation = dict(filter(lambda x: x[1] is not None, translation.items()))
|
|
49
49
|
|
|
50
|
-
roi =
|
|
50
|
+
roi = Roi(
|
|
51
51
|
name=str(key),
|
|
52
52
|
x=row["x_micrometer"],
|
|
53
53
|
y=row["y_micrometer"],
|
|
@@ -63,7 +63,7 @@ def _dataframe_to_rois(dataframe: pd.DataFrame) -> dict[str, WorldCooROI]:
|
|
|
63
63
|
return rois
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
def _rois_to_dataframe(rois: dict[str,
|
|
66
|
+
def _rois_to_dataframe(rois: dict[str, Roi], index_key: str) -> pd.DataFrame:
|
|
67
67
|
"""Convert a list of WorldCooROI objects to a DataFrame."""
|
|
68
68
|
data = []
|
|
69
69
|
for roi in rois.values():
|
|
@@ -124,7 +124,7 @@ class _GenericRoiTableV1(Generic[_roi_meta]):
|
|
|
124
124
|
_meta: _roi_meta
|
|
125
125
|
|
|
126
126
|
def __init__(
|
|
127
|
-
self, meta: _roi_meta | None = None, rois: Iterable[
|
|
127
|
+
self, meta: _roi_meta | None = None, rois: Iterable[Roi] | None = None
|
|
128
128
|
) -> None:
|
|
129
129
|
"""Create a new ROI table."""
|
|
130
130
|
if meta is None:
|
|
@@ -225,13 +225,13 @@ class _GenericRoiTableV1(Generic[_roi_meta]):
|
|
|
225
225
|
self._meta.backend = backend_name
|
|
226
226
|
self._table_backend = backend
|
|
227
227
|
|
|
228
|
-
def rois(self) -> list[
|
|
228
|
+
def rois(self) -> list[Roi]:
|
|
229
229
|
"""List all ROIs in the table."""
|
|
230
230
|
return list(self._rois.values())
|
|
231
231
|
|
|
232
|
-
def add(self, roi:
|
|
232
|
+
def add(self, roi: Roi | Iterable[Roi]) -> None:
|
|
233
233
|
"""Append ROIs to the current table."""
|
|
234
|
-
if isinstance(roi,
|
|
234
|
+
if isinstance(roi, Roi):
|
|
235
235
|
roi = [roi]
|
|
236
236
|
|
|
237
237
|
for _roi in roi:
|
|
@@ -266,10 +266,15 @@ class RoiTableV1(_GenericRoiTableV1[RoiTableV1Meta]):
|
|
|
266
266
|
https://fractal-analytics-platform.github.io/fractal-tasks-core/tables/
|
|
267
267
|
"""
|
|
268
268
|
|
|
269
|
-
def __init__(self, rois: Iterable[
|
|
269
|
+
def __init__(self, rois: Iterable[Roi] | None = None) -> None:
|
|
270
270
|
"""Create a new ROI table."""
|
|
271
271
|
super().__init__(RoiTableV1Meta(), rois)
|
|
272
272
|
|
|
273
|
+
def __repr__(self) -> str:
|
|
274
|
+
"""Return a string representation of the table."""
|
|
275
|
+
prop = f"num_rois={len(self._rois)}"
|
|
276
|
+
return f"RoiTableV1({prop})"
|
|
277
|
+
|
|
273
278
|
@staticmethod
|
|
274
279
|
def type() -> Literal["roi_table"]:
|
|
275
280
|
"""Return the type of the table."""
|
|
@@ -290,14 +295,14 @@ class RoiTableV1(_GenericRoiTableV1[RoiTableV1Meta]):
|
|
|
290
295
|
"""Return the metadata type of the table."""
|
|
291
296
|
return RoiTableV1Meta
|
|
292
297
|
|
|
293
|
-
def get(self, roi_name: str) ->
|
|
298
|
+
def get(self, roi_name: str) -> Roi:
|
|
294
299
|
"""Get an ROI from the table."""
|
|
295
300
|
if roi_name not in self._rois:
|
|
296
301
|
raise NgioValueError(f"ROI {roi_name} not found in the table.")
|
|
297
302
|
return self._rois[roi_name]
|
|
298
303
|
|
|
299
304
|
|
|
300
|
-
class
|
|
305
|
+
class MaskingRoiTableV1(_GenericRoiTableV1[MaskingRoiTableV1Meta]):
|
|
301
306
|
"""Class to handle fractal ROI tables.
|
|
302
307
|
|
|
303
308
|
To know more about the ROI table format, please refer to the
|
|
@@ -307,7 +312,7 @@ class MaskingROITableV1(_GenericRoiTableV1[MaskingRoiTableV1Meta]):
|
|
|
307
312
|
|
|
308
313
|
def __init__(
|
|
309
314
|
self,
|
|
310
|
-
rois: Iterable[
|
|
315
|
+
rois: Iterable[Roi] | None = None,
|
|
311
316
|
reference_label: str | None = None,
|
|
312
317
|
) -> None:
|
|
313
318
|
"""Create a new ROI table."""
|
|
@@ -316,6 +321,13 @@ class MaskingROITableV1(_GenericRoiTableV1[MaskingRoiTableV1Meta]):
|
|
|
316
321
|
meta.region = RegionMeta(path=reference_label)
|
|
317
322
|
super().__init__(meta, rois)
|
|
318
323
|
|
|
324
|
+
def __repr__(self) -> str:
|
|
325
|
+
"""Return a string representation of the table."""
|
|
326
|
+
prop = f"num_rois={len(self._rois)}"
|
|
327
|
+
if self.reference_label is not None:
|
|
328
|
+
prop += f", reference_label={self.reference_label}"
|
|
329
|
+
return f"MaskingRoiTableV1({prop})"
|
|
330
|
+
|
|
319
331
|
@staticmethod
|
|
320
332
|
def type() -> Literal["masking_roi_table"]:
|
|
321
333
|
"""Return the type of the table."""
|
|
@@ -336,7 +348,17 @@ class MaskingROITableV1(_GenericRoiTableV1[MaskingRoiTableV1Meta]):
|
|
|
336
348
|
"""Return the metadata type of the table."""
|
|
337
349
|
return MaskingRoiTableV1Meta
|
|
338
350
|
|
|
339
|
-
|
|
351
|
+
@property
|
|
352
|
+
def reference_label(self) -> str | None:
|
|
353
|
+
"""Return the reference label."""
|
|
354
|
+
path = self._meta.region
|
|
355
|
+
if path is None:
|
|
356
|
+
return None
|
|
357
|
+
path = path.path
|
|
358
|
+
path = path.split("/")[-1]
|
|
359
|
+
return path
|
|
360
|
+
|
|
361
|
+
def get(self, label: int) -> Roi:
|
|
340
362
|
"""Get an ROI from the table."""
|
|
341
363
|
_label = str(label)
|
|
342
364
|
if _label not in self._rois:
|