ngio 0.1.6__py3-none-any.whl → 0.2.0a1__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 (84) hide show
  1. ngio/__init__.py +31 -5
  2. ngio/common/__init__.py +44 -0
  3. ngio/common/_array_pipe.py +160 -0
  4. ngio/common/_axes_transforms.py +63 -0
  5. ngio/common/_common_types.py +5 -0
  6. ngio/common/_dimensions.py +113 -0
  7. ngio/common/_pyramid.py +222 -0
  8. ngio/{core/roi.py → common/_roi.py} +22 -23
  9. ngio/common/_slicer.py +97 -0
  10. ngio/{pipes/_zoom_utils.py → common/_zoom.py} +2 -78
  11. ngio/hcs/__init__.py +60 -0
  12. ngio/images/__init__.py +23 -0
  13. ngio/images/abstract_image.py +240 -0
  14. ngio/images/create.py +251 -0
  15. ngio/images/image.py +383 -0
  16. ngio/images/label.py +96 -0
  17. ngio/images/omezarr_container.py +512 -0
  18. ngio/ome_zarr_meta/__init__.py +35 -0
  19. ngio/ome_zarr_meta/_generic_handlers.py +320 -0
  20. ngio/ome_zarr_meta/_meta_handlers.py +142 -0
  21. ngio/ome_zarr_meta/ngio_specs/__init__.py +63 -0
  22. ngio/ome_zarr_meta/ngio_specs/_axes.py +481 -0
  23. ngio/ome_zarr_meta/ngio_specs/_channels.py +378 -0
  24. ngio/ome_zarr_meta/ngio_specs/_dataset.py +134 -0
  25. ngio/ome_zarr_meta/ngio_specs/_ngio_hcs.py +5 -0
  26. ngio/ome_zarr_meta/ngio_specs/_ngio_image.py +434 -0
  27. ngio/ome_zarr_meta/ngio_specs/_pixel_size.py +84 -0
  28. ngio/ome_zarr_meta/v04/__init__.py +11 -0
  29. ngio/ome_zarr_meta/v04/_meta_handlers.py +54 -0
  30. ngio/ome_zarr_meta/v04/_v04_spec_utils.py +412 -0
  31. ngio/tables/__init__.py +21 -5
  32. ngio/tables/_validators.py +192 -0
  33. ngio/tables/backends/__init__.py +8 -0
  34. ngio/tables/backends/_abstract_backend.py +71 -0
  35. ngio/tables/backends/_anndata_utils.py +194 -0
  36. ngio/tables/backends/_anndata_v1.py +75 -0
  37. ngio/tables/backends/_json_v1.py +56 -0
  38. ngio/tables/backends/_table_backends.py +102 -0
  39. ngio/tables/tables_container.py +300 -0
  40. ngio/tables/v1/__init__.py +6 -5
  41. ngio/tables/v1/_feature_table.py +161 -0
  42. ngio/tables/v1/_generic_table.py +99 -182
  43. ngio/tables/v1/_masking_roi_table.py +175 -0
  44. ngio/tables/v1/_roi_table.py +226 -0
  45. ngio/utils/__init__.py +23 -10
  46. ngio/utils/_datasets.py +51 -0
  47. ngio/utils/_errors.py +10 -4
  48. ngio/utils/_zarr_utils.py +378 -0
  49. {ngio-0.1.6.dist-info → ngio-0.2.0a1.dist-info}/METADATA +18 -39
  50. ngio-0.2.0a1.dist-info/RECORD +53 -0
  51. ngio/core/__init__.py +0 -7
  52. ngio/core/dimensions.py +0 -122
  53. ngio/core/image_handler.py +0 -228
  54. ngio/core/image_like_handler.py +0 -549
  55. ngio/core/label_handler.py +0 -410
  56. ngio/core/ngff_image.py +0 -387
  57. ngio/core/utils.py +0 -287
  58. ngio/io/__init__.py +0 -19
  59. ngio/io/_zarr.py +0 -88
  60. ngio/io/_zarr_array_utils.py +0 -0
  61. ngio/io/_zarr_group_utils.py +0 -60
  62. ngio/iterators/__init__.py +0 -1
  63. ngio/ngff_meta/__init__.py +0 -27
  64. ngio/ngff_meta/fractal_image_meta.py +0 -1267
  65. ngio/ngff_meta/meta_handler.py +0 -92
  66. ngio/ngff_meta/utils.py +0 -235
  67. ngio/ngff_meta/v04/__init__.py +0 -6
  68. ngio/ngff_meta/v04/specs.py +0 -158
  69. ngio/ngff_meta/v04/zarr_utils.py +0 -376
  70. ngio/pipes/__init__.py +0 -7
  71. ngio/pipes/_slicer_transforms.py +0 -176
  72. ngio/pipes/_transforms.py +0 -33
  73. ngio/pipes/data_pipe.py +0 -52
  74. ngio/tables/_ad_reader.py +0 -80
  75. ngio/tables/_utils.py +0 -301
  76. ngio/tables/tables_group.py +0 -252
  77. ngio/tables/v1/feature_tables.py +0 -182
  78. ngio/tables/v1/masking_roi_tables.py +0 -243
  79. ngio/tables/v1/roi_tables.py +0 -285
  80. ngio/utils/_common_types.py +0 -5
  81. ngio/utils/_pydantic_utils.py +0 -52
  82. ngio-0.1.6.dist-info/RECORD +0 -44
  83. {ngio-0.1.6.dist-info → ngio-0.2.0a1.dist-info}/WHEEL +0 -0
  84. {ngio-0.1.6.dist-info → ngio-0.2.0a1.dist-info}/licenses/LICENSE +0 -0
@@ -1,285 +0,0 @@
1
- """Implementation of the ROI Table class.
2
-
3
- This class follows the roi_table specification at:
4
- https://fractal-analytics-platform.github.io/fractal-tasks-core/tables/
5
- """
6
-
7
- from collections.abc import Iterable
8
- from functools import partial
9
- from typing import Literal
10
-
11
- import pandas as pd
12
- import zarr
13
- from pydantic import BaseModel
14
-
15
- from ngio.core.roi import SpaceUnits, WorldCooROI
16
- from ngio.tables._utils import validate_columns
17
- from ngio.tables.v1._generic_table import REQUIRED_COLUMNS, BaseTable, write_table_ad
18
-
19
-
20
- class ROITableV1Meta(BaseModel):
21
- """Metadata for the ROI table."""
22
-
23
- fractal_table_version: Literal["1"] = "1"
24
- type: Literal["roi_table"] = "roi_table"
25
-
26
-
27
- ORIGIN_COLUMNS = [
28
- "x_micrometer_original",
29
- "y_micrometer_original",
30
- ]
31
- TRANSLATION_COLUMNS = ["translation_x", "translation_y", "translation_z"]
32
- OPTIONAL_COLUMNS = ORIGIN_COLUMNS + TRANSLATION_COLUMNS
33
-
34
-
35
- def create_empty_roi_table(
36
- include_origin: bool = False, include_translation: bool = False
37
- ) -> pd.DataFrame:
38
- """Create an empty ROI table."""
39
- origin_columns = ORIGIN_COLUMNS if include_origin else []
40
- translation_columns = TRANSLATION_COLUMNS if include_translation else []
41
-
42
- columns = [
43
- *REQUIRED_COLUMNS,
44
- *origin_columns,
45
- *translation_columns,
46
- ]
47
- table = pd.DataFrame(
48
- index=pd.Index([], name="FieldIndex", dtype="str"), columns=columns
49
- )
50
-
51
- return table
52
-
53
-
54
- class ROITableV1:
55
- """Class to handle fractal ROI tables.
56
-
57
- To know more about the ROI table format, please refer to the
58
- specification at:
59
- https://fractal-analytics-platform.github.io/fractal-tasks-core/tables/
60
- """
61
-
62
- def __init__(
63
- self,
64
- group: zarr.Group,
65
- name: str,
66
- validate_metadata: bool = True,
67
- validate_table: bool = True,
68
- index_key: str | None = None,
69
- ):
70
- """Initialize the class from an existing group.
71
-
72
- Args:
73
- group (zarr.Group): The group containing the
74
- ROI table.
75
- name (str): The name of the ROI table.
76
- validate_metadata (bool): If True, the metadata is validated.
77
- validate_table (bool): If True, the table is validated.
78
- index_key (str): The column name to use as the index of the DataFrame.
79
- """
80
- if validate_metadata:
81
- self._meta = ROITableV1Meta(**group.attrs)
82
- else:
83
- self._meta = ROITableV1Meta.model_construct(**group.attrs)
84
-
85
- # Validate the table is not implemented for the ROI table
86
- validators = [
87
- partial(
88
- validate_columns,
89
- required_columns=REQUIRED_COLUMNS,
90
- optional_columns=OPTIONAL_COLUMNS,
91
- )
92
- ]
93
- validators = validators if validate_table else None
94
-
95
- index_key = "FieldIndex" if index_key is None else index_key
96
-
97
- self._table_handler = BaseTable(
98
- group=group, index_key=index_key, index_type="str", validators=validators
99
- )
100
- self._name = name
101
-
102
- @classmethod
103
- def _new(
104
- cls,
105
- parent_group: zarr.Group,
106
- name: str,
107
- include_origin: bool = False,
108
- include_translation: bool = False,
109
- overwrite: bool = False,
110
- ) -> "ROITableV1":
111
- """Create a new ROI table.
112
-
113
- Note this method is not meant to be called directly.
114
- But should be called from the TablesHandler class.
115
-
116
- Args:
117
- parent_group (zarr.Group): The parent group where the ROI table
118
- will be created.
119
- name (str): The name of the ROI table.
120
- table (DataFrame): The ROI table as a DataFrame.
121
- include_origin (bool): Whether to include the origin columns in the table.
122
- include_translation (bool): Whether to include the translation columns
123
- in the table.
124
- overwrite (bool): Whether to overwrite the table if it already exists.
125
- """
126
- group = parent_group.create_group(name, overwrite=overwrite)
127
-
128
- table = create_empty_roi_table(
129
- include_origin=include_origin, include_translation=include_translation
130
- )
131
-
132
- meta = ROITableV1Meta()
133
- write_table_ad(
134
- group=group,
135
- table=table,
136
- index_key="FieldIndex",
137
- index_type="str",
138
- meta=meta,
139
- )
140
- return cls(group=group, name=name)
141
-
142
- def __repr__(self) -> str:
143
- """Return the string representation of the ROI table."""
144
- name = "ROITableV1("
145
- len_name = len(name)
146
- return (
147
- f"{name}"
148
- f"group_path={self.group_path}, \n"
149
- f"{' ':>{len_name}}name={self.name},\n"
150
- f"{' ':>{len_name}}num_rois={self.num_rois}, \n"
151
- ")"
152
- )
153
-
154
- @property
155
- def name(self) -> str:
156
- """Return the name of the ROI table."""
157
- return self._name
158
-
159
- @property
160
- def root_path(self) -> str:
161
- """Return the path of the root group."""
162
- return self._table_handler.root_path
163
-
164
- @property
165
- def group_path(self) -> str:
166
- """Return the path of the group."""
167
- return self._table_handler.group_path
168
-
169
- @property
170
- def meta(self) -> ROITableV1Meta:
171
- """Return the metadata of the ROI table."""
172
- return self._meta
173
-
174
- @property
175
- def table_handler(self) -> BaseTable:
176
- """Return the table handler."""
177
- return self._table_handler
178
-
179
- @property
180
- def table(self) -> pd.DataFrame:
181
- """Return the ROI table as a DataFrame."""
182
- return self._table_handler.table
183
-
184
- @table.setter
185
- def table(self, table: pd.DataFrame) -> None:
186
- """Set the feature table."""
187
- raise NotImplementedError(
188
- "Setting the table is not implemented. Please use the 'set_table' method."
189
- )
190
-
191
- def set_table(self, table: pd.DataFrame) -> None:
192
- """Set the feature table."""
193
- self._table_handler.set_table(table)
194
-
195
- @property
196
- def field_indexes(self) -> list[str]:
197
- """Return a list of all field indexes in the table."""
198
- return self.table.index.tolist()
199
-
200
- @property
201
- def num_rois(self) -> int:
202
- """Return the number of ROIs in the table."""
203
- return len(self.field_indexes)
204
-
205
- def set_rois(
206
- self,
207
- rois: Iterable[WorldCooROI] | WorldCooROI,
208
- overwrite: bool = False,
209
- ) -> None:
210
- """Append ROIs to the current table.
211
-
212
- Args:
213
- rois (Iterable[WorldCooROI] | WorldCooROI): The ROIs to append.
214
- overwrite (bool): Whether to overwrite the ROIs if they already exist.
215
- If False, the ROIs will be appended. If True, the ROIs will be
216
- overwritten.
217
- """
218
- if isinstance(rois, WorldCooROI):
219
- rois = [rois]
220
-
221
- rois_dict = {}
222
- for roi in rois:
223
- field_index = roi.infos.get("FieldIndex", None)
224
- if field_index is None:
225
- raise ValueError("Field index is required in the ROI infos.")
226
-
227
- rois_dict[field_index] = {
228
- "x_micrometer": roi.x,
229
- "y_micrometer": roi.y,
230
- "z_micrometer": roi.z,
231
- "len_x_micrometer": roi.x_length,
232
- "len_y_micrometer": roi.y_length,
233
- "len_z_micrometer": roi.z_length,
234
- }
235
-
236
- for column in OPTIONAL_COLUMNS:
237
- if column in roi.infos:
238
- rois_dict[field_index][column] = roi.infos[column]
239
-
240
- table_df = self.table
241
- new_table_df = pd.DataFrame.from_dict(rois_dict, orient="index")
242
-
243
- if overwrite or table_df.empty:
244
- table_df = new_table_df
245
- else:
246
- table_df = pd.concat([table_df, new_table_df], axis=0)
247
-
248
- table_df.index.name = "FieldIndex"
249
- table_df.index = table_df.index.astype(str)
250
- self.set_table(table_df)
251
-
252
- def _gater_optional_columns(self, series: pd.Series) -> dict:
253
- """Gather the optional columns from a series."""
254
- optional_dict = {}
255
- for column in OPTIONAL_COLUMNS:
256
- if column in series.index:
257
- optional_dict[column] = series[column]
258
- return optional_dict
259
-
260
- def get_roi(self, field_index: str) -> WorldCooROI:
261
- """Get an ROI from the table."""
262
- if field_index not in self.field_indexes:
263
- raise ValueError(f"Field index {field_index} is not in the table")
264
-
265
- table_df = self.table.loc[field_index]
266
- roi = WorldCooROI(
267
- x=table_df.loc["x_micrometer"],
268
- y=table_df.loc["y_micrometer"],
269
- z=table_df.loc["z_micrometer"],
270
- x_length=table_df.loc["len_x_micrometer"],
271
- y_length=table_df.loc["len_y_micrometer"],
272
- z_length=table_df.loc["len_z_micrometer"],
273
- unit=SpaceUnits.micrometer,
274
- infos={"FieldIndex": field_index, **self._gater_optional_columns(table_df)},
275
- )
276
- return roi
277
-
278
- @property
279
- def rois(self) -> list[WorldCooROI]:
280
- """List all ROIs in the table."""
281
- return [self.get_roi(field_index) for field_index in self.field_indexes]
282
-
283
- def consolidate(self) -> None:
284
- """Write the crrent state of the table to the Zarr file."""
285
- self._table_handler.consolidate(self.meta)
@@ -1,5 +0,0 @@
1
- import numpy as np
2
- import zarr
3
- from dask import array as da
4
-
5
- ArrayLike = np.ndarray | da.core.Array | zarr.Array
@@ -1,52 +0,0 @@
1
- """Utility functions for Pydantic models."""
2
-
3
- import os
4
- from collections import namedtuple
5
- from typing import Any, NamedTuple, TypeVar
6
-
7
- from pydantic import BaseModel, Field, model_serializer, model_validator
8
-
9
- # Debugging flag to skip validation of the metadata (for testing purposes only)
10
- # check if this is an environment variable
11
- SKIP_NGFF_VALIDATION = bool(os.getenv("SKIP_NGFF_VALIDATION", False))
12
-
13
-
14
- class BaseWithExtraFields(BaseModel):
15
- """Base class for all Fractal spec models.
16
-
17
- Every field that is not defined in the model will
18
- be stored in the `extra_fields` attribute.
19
- """
20
-
21
- extra_fields: dict = Field(default_factory=dict)
22
-
23
- @model_validator(mode="before")
24
- def _collect_extra_fields(cls, values: dict[str, Any]) -> dict[str, Any]:
25
- extra = {k: v for k, v in values.items() if k not in cls.model_fields}
26
- values["extra_fields"] = extra
27
- return values
28
-
29
- @model_serializer(mode="wrap")
30
- def _custom_serializer(self, handler: Any) -> dict[str, Any]:
31
- basic_dict = handler(self)
32
- extra = basic_dict.pop("extra_fields")
33
- return {**basic_dict, **extra}
34
-
35
-
36
- T = TypeVar("T")
37
-
38
-
39
- def unique_items_validator(values: list[T]) -> list[T]:
40
- """Validate that all items in the list are unique."""
41
- if SKIP_NGFF_VALIDATION:
42
- return values
43
-
44
- for ind, value in enumerate(values, start=1):
45
- if value in values[ind:]:
46
- raise ValueError(f"Non-unique values in {values}.")
47
- return values
48
-
49
-
50
- def named_tuple_from_pydantic_model(model: BaseModel) -> NamedTuple:
51
- """Create a namedtuple from a Pydantic model."""
52
- return namedtuple(name=model.__name__, field_names=model.model_fields.keys()) # type: ignore
@@ -1,44 +0,0 @@
1
- ngio/__init__.py,sha256=skYJKsIGV_Ego7QjC9CuRGJ4LVlfqqTp5vt_cXUwhtY,380
2
- ngio/core/__init__.py,sha256=j3uhGbBjyILwlXk5mu78SUepCY5g2Q1X78vHeeySD-c,212
3
- ngio/core/dimensions.py,sha256=AyiXXwgfwe1LiJ7cNhefUVTG2GQqVzDiO0ge_KePf8Q,3722
4
- ngio/core/image_handler.py,sha256=2eiklMWCSZD9ajZHEwYJHB1WoQE92YTVOy7qslrtSaw,7569
5
- ngio/core/image_like_handler.py,sha256=_k1xs3Uct_FXKoyUDTfQwG755SmiMGlztGhsQW-OtOA,18821
6
- ngio/core/label_handler.py,sha256=yBWMQbhme0j4XhXcoWuNY0x3Kt_MH3aYTu6peOfWyTc,14102
7
- ngio/core/ngff_image.py,sha256=F3TOWzL2SuQmnkilWuKjYRcpnCS67LW4z7ayCj9pfYs,13751
8
- ngio/core/roi.py,sha256=Vn9aKNxRvJs77ZfVFMAdjOzhy2I2ctpikLcbFP5aj74,2884
9
- ngio/core/utils.py,sha256=GsujsKwOJDeFhcj3DgkZO99wG_Dm0wO7nTNL-uiD78c,10161
10
- ngio/io/__init__.py,sha256=g7KmkgRcVBTZbVkqstl_FldUFzz66R-b__HV9hsLvtc,400
11
- ngio/io/_zarr.py,sha256=4AM8p7ENDPAqSuR99HaP0uosPqwY80h86GZch3l7C20,2605
12
- ngio/io/_zarr_array_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- ngio/io/_zarr_group_utils.py,sha256=ZvVQ7Z0UvLNepNyU_NmKgjKKuVXACOLPi8-OkaI6H30,1738
14
- ngio/iterators/__init__.py,sha256=-jQ5h6oNftLKtiHDru8nPOrR3x8H1rMo85hzvqkhxmw,29
15
- ngio/ngff_meta/__init__.py,sha256=HhtHzjjk55gaHYbjiHoHRyYmOs1QZgBdWeCBb7O19Vo,560
16
- ngio/ngff_meta/fractal_image_meta.py,sha256=yc97iEGj5VjaCWv0Md94b5I2p9qzx94DMu_HlyKmrmg,43353
17
- ngio/ngff_meta/meta_handler.py,sha256=YDqOl-UUzE-flqC2EXGbJc-ctqZsULsZzA0Xj6X7XkM,2588
18
- ngio/ngff_meta/utils.py,sha256=eZSlm1-XJAGiThSol8RW7a_61Crj91f9vXbBGssWnhk,7978
19
- ngio/ngff_meta/v04/__init__.py,sha256=zlIL9-R3fNT_mgrOxE51dGyhnJlZ1UX0uRNeEl8WuRM,239
20
- ngio/ngff_meta/v04/specs.py,sha256=cjdMlL8L8Sbk-cGq5J3-wgOxQ9zr3r3u2q09fDI11kM,4256
21
- ngio/ngff_meta/v04/zarr_utils.py,sha256=02ISrsAGIXB1iLfcXPpqDljDlp0vC8Y_MyL5c016FY8,11859
22
- ngio/pipes/__init__.py,sha256=Ypt9bCqrk0qSg81GTBNqH5oljMg2rQPwyOWVZRKzaYg,299
23
- ngio/pipes/_slicer_transforms.py,sha256=UyN_aeAg-mtO9wsbqcvUIvnV5PJFTbj8AUmegMsF05k,5812
24
- ngio/pipes/_transforms.py,sha256=S7PqIwyf10i1cjQ-lKcJLr7YLfW2zKJKGf6DKKP3bTA,1067
25
- ngio/pipes/_zoom_utils.py,sha256=omkaJFNeqS09qdIsBmEQaSc_xKjP8hoHwOpsx_yd5B4,7957
26
- ngio/pipes/data_pipe.py,sha256=SBe-3kTgbHyvFC2lVYyVZj12JazmHCx9QaTDZW1PNxU,1907
27
- ngio/tables/__init__.py,sha256=kedgmeeFVxBAJACoZ1yxfoyTmlmI1HCBWFhgyprbNWI,260
28
- ngio/tables/_ad_reader.py,sha256=OQJ3ZwS0wMedlSjz-wQuovIDBojnHRk2Qhq6FL29248,2677
29
- ngio/tables/_utils.py,sha256=GFOROQUubpYiZMSJ1tdqUWZGBcXAXGdf18iK2_oj8-0,10236
30
- ngio/tables/tables_group.py,sha256=DFSDVQz6dYdvI00sKXEeDG7FOX1vAWXiHDDVwEfxL9I,8633
31
- ngio/tables/v1/__init__.py,sha256=vwJwo3lSpp6feGcwbn6lWivD1MJ_A8Py7WFsL40xUs0,308
32
- ngio/tables/v1/_generic_table.py,sha256=sW9fIyfZZt7QJclFzgWrMFSnCk7gKTP5Kj2atIKi6oA,6084
33
- ngio/tables/v1/feature_tables.py,sha256=piC6_eOGOt9IyzXWYqHlR09v0z9Ywm1o8gsdEAsEWts,5892
34
- ngio/tables/v1/masking_roi_tables.py,sha256=Ght6ISs5PSORl2cUze0H8dsvDdXrMGWqhDXfz1uKO_I,8017
35
- ngio/tables/v1/roi_tables.py,sha256=0_AZLh7a_PvYDHIagjRamAZBCUazl3KC0FLKFWbGW2k,9295
36
- ngio/utils/__init__.py,sha256=cw85rtKTSrSn021A7Lq9CI4oIs-JUnTTxxbOBIB54uo,748
37
- ngio/utils/_common_types.py,sha256=ylo6RfCyKVyXPx1Mz7WAwFfz8F85R9yd2_TPlRGRUyo,113
38
- ngio/utils/_errors.py,sha256=rLy9LOFkaEmsSD0-nToKUrXY1ZuPfcpcGpmeHVSnTNg,583
39
- ngio/utils/_logger.py,sha256=zvFG-Ta3ZIJxTyY93zYoPGp2A6TTUf7mSO0zr_uFy4A,837
40
- ngio/utils/_pydantic_utils.py,sha256=uN5-76cjE3bvV8GvLX62fpxoRi8GOsZu6K5aynGH1bY,1711
41
- ngio-0.1.6.dist-info/METADATA,sha256=w4iV12bvnoiCfP6AAWMpqH0ORoh0kZxA8WeqQjKzhBI,5756
42
- ngio-0.1.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
43
- ngio-0.1.6.dist-info/licenses/LICENSE,sha256=UgN_a1QCeNh9rZWfz-wORQFxE3elQzLWPQaoK6N6fxQ,1502
44
- ngio-0.1.6.dist-info/RECORD,,
File without changes