ngio 0.2.9__py3-none-any.whl → 0.3.0__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/common/__init__.py +16 -0
- ngio/common/_array_pipe.py +50 -27
- ngio/common/_table_ops.py +471 -0
- ngio/hcs/__init__.py +1 -1
- ngio/hcs/{plate.py → _plate.py} +451 -78
- ngio/images/__init__.py +3 -3
- ngio/images/{image.py → _image.py} +26 -21
- ngio/images/{label.py → _label.py} +6 -4
- ngio/images/{masked_image.py → _masked_image.py} +2 -2
- ngio/images/{ome_zarr_container.py → _ome_zarr_container.py} +152 -86
- ngio/ome_zarr_meta/_meta_handlers.py +16 -8
- ngio/ome_zarr_meta/ngio_specs/_channels.py +41 -29
- ngio/tables/__init__.py +14 -2
- ngio/tables/_abstract_table.py +269 -0
- ngio/tables/{tables_container.py → _tables_container.py} +186 -100
- ngio/tables/backends/__init__.py +20 -0
- ngio/tables/backends/_abstract_backend.py +58 -80
- ngio/tables/backends/{_anndata_v1.py → _anndata.py} +5 -1
- ngio/tables/backends/_csv.py +35 -0
- ngio/tables/backends/{_json_v1.py → _json.py} +4 -1
- ngio/tables/backends/{_csv_v1.py → _non_zarr_backends.py} +61 -27
- ngio/tables/backends/_parquet.py +47 -0
- ngio/tables/backends/_table_backends.py +39 -18
- ngio/tables/backends/_utils.py +147 -1
- ngio/tables/v1/__init__.py +19 -3
- ngio/tables/v1/_condition_table.py +71 -0
- ngio/tables/v1/_feature_table.py +63 -129
- ngio/tables/v1/_generic_table.py +21 -159
- ngio/tables/v1/_roi_table.py +285 -201
- ngio/utils/_fractal_fsspec_store.py +29 -0
- {ngio-0.2.9.dist-info → ngio-0.3.0.dist-info}/METADATA +4 -3
- ngio-0.3.0.dist-info/RECORD +61 -0
- ngio/tables/_validators.py +0 -108
- ngio-0.2.9.dist-info/RECORD +0 -57
- /ngio/images/{abstract_image.py → _abstract_image.py} +0 -0
- /ngio/images/{create.py → _create.py} +0 -0
- {ngio-0.2.9.dist-info → ngio-0.3.0.dist-info}/WHEEL +0 -0
- {ngio-0.2.9.dist-info → ngio-0.3.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,10 +1,24 @@
|
|
|
1
1
|
"""Module for handling the /tables group in an OME-NGFF file."""
|
|
2
2
|
|
|
3
|
-
from typing import Literal, Protocol
|
|
3
|
+
from typing import Literal, Protocol, TypeVar
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import anndata as ad
|
|
6
|
+
import pandas as pd
|
|
7
|
+
import polars as pl
|
|
8
|
+
|
|
9
|
+
from ngio.tables.backends import (
|
|
10
|
+
BackendMeta,
|
|
11
|
+
TableBackend,
|
|
12
|
+
TabularData,
|
|
13
|
+
)
|
|
14
|
+
from ngio.tables.v1 import (
|
|
15
|
+
ConditionTableV1,
|
|
16
|
+
FeatureTableV1,
|
|
17
|
+
GenericTable,
|
|
18
|
+
MaskingRoiTableV1,
|
|
19
|
+
RoiTableV1,
|
|
20
|
+
)
|
|
21
|
+
from ngio.tables.v1._roi_table import GenericRoiTableV1
|
|
8
22
|
from ngio.utils import (
|
|
9
23
|
AccessModeLiteral,
|
|
10
24
|
NgioValidationError,
|
|
@@ -13,22 +27,23 @@ from ngio.utils import (
|
|
|
13
27
|
ZarrGroupHandler,
|
|
14
28
|
)
|
|
15
29
|
|
|
16
|
-
GenericRoiTable =
|
|
30
|
+
GenericRoiTable = GenericRoiTableV1
|
|
17
31
|
RoiTable = RoiTableV1
|
|
18
32
|
MaskingRoiTable = MaskingRoiTableV1
|
|
19
33
|
FeatureTable = FeatureTableV1
|
|
34
|
+
ConditionTable = ConditionTableV1
|
|
20
35
|
|
|
21
36
|
|
|
22
37
|
class Table(Protocol):
|
|
23
38
|
"""Placeholder class for a table."""
|
|
24
39
|
|
|
25
40
|
@staticmethod
|
|
26
|
-
def
|
|
41
|
+
def table_type() -> str:
|
|
27
42
|
"""Return the type of the table."""
|
|
28
43
|
...
|
|
29
44
|
|
|
30
45
|
@staticmethod
|
|
31
|
-
def version() -> str
|
|
46
|
+
def version() -> str:
|
|
32
47
|
"""Return the version of the table."""
|
|
33
48
|
...
|
|
34
49
|
|
|
@@ -37,19 +52,72 @@ class Table(Protocol):
|
|
|
37
52
|
"""The name of the backend."""
|
|
38
53
|
...
|
|
39
54
|
|
|
55
|
+
@property
|
|
56
|
+
def meta(self) -> BackendMeta:
|
|
57
|
+
"""Return the metadata for the table."""
|
|
58
|
+
...
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def dataframe(self) -> pd.DataFrame:
|
|
62
|
+
"""Return the table as a DataFrame."""
|
|
63
|
+
...
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def lazy_frame(self) -> pl.LazyFrame:
|
|
67
|
+
"""Return the table as a LazyFrame."""
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def anndata(self) -> ad.AnnData:
|
|
72
|
+
"""Return the table as an AnnData object."""
|
|
73
|
+
...
|
|
74
|
+
|
|
75
|
+
def set_table_data(
|
|
76
|
+
self,
|
|
77
|
+
table_data: TabularData | None = None,
|
|
78
|
+
refresh: bool = False,
|
|
79
|
+
) -> None:
|
|
80
|
+
"""Make sure that the table data is set (exist in memory).
|
|
81
|
+
|
|
82
|
+
If an object is passed, it will be used as the table.
|
|
83
|
+
If None is passed, the table will be loaded from the backend.
|
|
84
|
+
|
|
85
|
+
If refresh is True, the table will be reloaded from the backend.
|
|
86
|
+
If table is not None, this will be ignored.
|
|
87
|
+
"""
|
|
88
|
+
...
|
|
89
|
+
|
|
90
|
+
def set_backend(
|
|
91
|
+
self,
|
|
92
|
+
handler: ZarrGroupHandler | None = None,
|
|
93
|
+
backend: TableBackend = "anndata",
|
|
94
|
+
) -> None:
|
|
95
|
+
"""Set the backend store and path for the table.
|
|
96
|
+
|
|
97
|
+
Either a handler or a backend must be provided.
|
|
98
|
+
|
|
99
|
+
If the hanlder in none it will be inferred from the backend.
|
|
100
|
+
If the backend is none, it will be inferred from the group attrs
|
|
101
|
+
"""
|
|
102
|
+
...
|
|
103
|
+
|
|
40
104
|
@classmethod
|
|
41
|
-
def
|
|
42
|
-
cls,
|
|
105
|
+
def from_handler(
|
|
106
|
+
cls,
|
|
107
|
+
handler: ZarrGroupHandler,
|
|
108
|
+
backend: TableBackend | None = None,
|
|
43
109
|
) -> "Table":
|
|
44
110
|
"""Create a new table from a Zarr group handler."""
|
|
45
111
|
...
|
|
46
112
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
113
|
+
@classmethod
|
|
114
|
+
def from_table_data(cls, table_data: TabularData, meta: BackendMeta) -> "Table":
|
|
115
|
+
"""Create a new table from a DataFrame."""
|
|
116
|
+
...
|
|
117
|
+
|
|
118
|
+
@property
|
|
119
|
+
def table_data(self) -> TabularData:
|
|
120
|
+
"""Return the table."""
|
|
53
121
|
...
|
|
54
122
|
|
|
55
123
|
def consolidate(self) -> None:
|
|
@@ -58,13 +126,37 @@ class Table(Protocol):
|
|
|
58
126
|
|
|
59
127
|
|
|
60
128
|
TypedTable = Literal[
|
|
61
|
-
"
|
|
129
|
+
"generic_table",
|
|
130
|
+
"roi_table",
|
|
131
|
+
"masking_roi_table",
|
|
132
|
+
"feature_table",
|
|
133
|
+
"condition_table",
|
|
62
134
|
]
|
|
63
135
|
|
|
136
|
+
TypedRoiTable = Literal[
|
|
137
|
+
"roi_table",
|
|
138
|
+
"masking_roi_table",
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
TableType = TypeVar("TableType", bound=Table)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class TableMeta(BackendMeta):
|
|
145
|
+
"""Base class for table metadata."""
|
|
146
|
+
|
|
147
|
+
table_version: str = "1"
|
|
148
|
+
type: str = "generic_table"
|
|
64
149
|
|
|
65
|
-
def
|
|
66
|
-
|
|
67
|
-
|
|
150
|
+
def unique_name(self) -> str:
|
|
151
|
+
"""Return the unique name for the table."""
|
|
152
|
+
return f"{self.type}_v{self.table_version}"
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def _get_meta(handler: ZarrGroupHandler) -> TableMeta:
|
|
156
|
+
"""Get the metadata from the handler."""
|
|
157
|
+
attrs = handler.load_attrs()
|
|
158
|
+
meta = TableMeta(**attrs)
|
|
159
|
+
return meta
|
|
68
160
|
|
|
69
161
|
|
|
70
162
|
class ImplementedTables:
|
|
@@ -86,77 +178,38 @@ class ImplementedTables:
|
|
|
86
178
|
|
|
87
179
|
def get_table(
|
|
88
180
|
self,
|
|
89
|
-
|
|
90
|
-
version: str,
|
|
181
|
+
meta: TableMeta,
|
|
91
182
|
handler: ZarrGroupHandler,
|
|
92
|
-
|
|
183
|
+
backend: TableBackend | None = None,
|
|
93
184
|
strict: bool = True,
|
|
94
185
|
) -> Table:
|
|
95
186
|
"""Try to get a handler for the given store based on the metadata version."""
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
try:
|
|
101
|
-
table = table_cls._from_handler(
|
|
102
|
-
handler=handler, backend_name=backend_name
|
|
103
|
-
)
|
|
104
|
-
return table
|
|
105
|
-
except Exception as e:
|
|
106
|
-
if strict:
|
|
107
|
-
raise NgioValidationError(
|
|
108
|
-
f"Could not load table {name} from handler. Error: {e}"
|
|
109
|
-
) from e
|
|
110
|
-
else:
|
|
111
|
-
_errors[name] = e
|
|
112
|
-
# If no table was found, we can try to load the table from a generic table
|
|
113
|
-
try:
|
|
114
|
-
table = GenericTable._from_handler(
|
|
115
|
-
handler=handler, backend_name=backend_name
|
|
116
|
-
)
|
|
117
|
-
return table
|
|
118
|
-
except Exception as e:
|
|
119
|
-
_errors["generic"] = e
|
|
187
|
+
if strict:
|
|
188
|
+
default = None
|
|
189
|
+
else:
|
|
190
|
+
default = GenericTable
|
|
120
191
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
f"
|
|
192
|
+
table_cls = self._implemented_tables.get(meta.unique_name(), default)
|
|
193
|
+
if table_cls is None:
|
|
194
|
+
raise NgioValueError(
|
|
195
|
+
f"Table handler for {meta.unique_name()} not implemented."
|
|
125
196
|
)
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
f"Could not load table from any known version. Errors: {_errors}"
|
|
129
|
-
)
|
|
197
|
+
table = table_cls.from_handler(handler=handler, backend=backend)
|
|
198
|
+
return table
|
|
130
199
|
|
|
131
200
|
def add_implementation(self, handler: type[Table], overwrite: bool = False):
|
|
132
201
|
"""Register a new table handler."""
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if version is None:
|
|
139
|
-
raise NgioValueError("Table handler must have a version.")
|
|
202
|
+
meta = TableMeta(
|
|
203
|
+
type=handler.table_type(),
|
|
204
|
+
table_version=handler.version(),
|
|
205
|
+
)
|
|
140
206
|
|
|
141
|
-
|
|
142
|
-
if table_unique_name in self._implemented_tables and not overwrite:
|
|
207
|
+
if meta.unique_name() in self._implemented_tables and not overwrite:
|
|
143
208
|
raise NgioValueError(
|
|
144
|
-
f"Table handler for {
|
|
209
|
+
f"Table handler for {meta.unique_name()} already implemented. "
|
|
145
210
|
"Use overwrite=True to replace it."
|
|
146
211
|
)
|
|
147
|
-
self._implemented_tables[
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
def _get_table_type(handler: ZarrGroupHandler) -> str:
|
|
151
|
-
"""Get the type of the table from the handler."""
|
|
152
|
-
attrs = handler.load_attrs()
|
|
153
|
-
return attrs.get("type", "None")
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
def _get_table_version(handler: ZarrGroupHandler) -> str:
|
|
157
|
-
"""Get the version of the table from the handler."""
|
|
158
|
-
attrs = handler.load_attrs()
|
|
159
|
-
return attrs.get("fractal_table_version", "None")
|
|
212
|
+
self._implemented_tables[meta.unique_name()] = handler
|
|
160
213
|
|
|
161
214
|
|
|
162
215
|
class TablesContainer:
|
|
@@ -192,14 +245,7 @@ class TablesContainer:
|
|
|
192
245
|
handler = self._group_handler.derive_handler(path=name)
|
|
193
246
|
return handler
|
|
194
247
|
|
|
195
|
-
def
|
|
196
|
-
"""List all ROI tables in the group."""
|
|
197
|
-
_tables = []
|
|
198
|
-
for _type in ["roi_table", "masking_roi_table"]:
|
|
199
|
-
_tables.extend(self.list(_type))
|
|
200
|
-
return _tables
|
|
201
|
-
|
|
202
|
-
def list(self, filter_types: str | None = None) -> list[str]:
|
|
248
|
+
def list(self, filter_types: TypedTable | str | None = None) -> list[str]:
|
|
203
249
|
"""List all labels in the group."""
|
|
204
250
|
tables = self._get_tables_list()
|
|
205
251
|
if filter_types is None:
|
|
@@ -208,34 +254,52 @@ class TablesContainer:
|
|
|
208
254
|
filtered_tables = []
|
|
209
255
|
for table_name in tables:
|
|
210
256
|
tb_handler = self._get_table_group_handler(table_name)
|
|
211
|
-
table_type =
|
|
257
|
+
table_type = _get_meta(tb_handler).type
|
|
212
258
|
if table_type == filter_types:
|
|
213
259
|
filtered_tables.append(table_name)
|
|
214
260
|
return filtered_tables
|
|
215
261
|
|
|
216
262
|
def get(
|
|
217
|
-
self,
|
|
263
|
+
self,
|
|
264
|
+
name: str,
|
|
265
|
+
backend: TableBackend | None = None,
|
|
266
|
+
strict: bool = True,
|
|
218
267
|
) -> Table:
|
|
219
268
|
"""Get a label from the group."""
|
|
220
269
|
if name not in self.list():
|
|
221
|
-
raise
|
|
270
|
+
raise NgioValueError(f"Table '{name}' not found in the group.")
|
|
222
271
|
|
|
223
272
|
table_handler = self._get_table_group_handler(name)
|
|
224
|
-
|
|
225
|
-
|
|
273
|
+
|
|
274
|
+
meta = _get_meta(table_handler)
|
|
226
275
|
return ImplementedTables().get_table(
|
|
227
|
-
|
|
228
|
-
version=table_version,
|
|
276
|
+
meta=meta,
|
|
229
277
|
handler=table_handler,
|
|
230
|
-
|
|
278
|
+
backend=backend,
|
|
231
279
|
strict=strict,
|
|
232
280
|
)
|
|
233
281
|
|
|
282
|
+
def get_as(
|
|
283
|
+
self,
|
|
284
|
+
name: str,
|
|
285
|
+
table_cls: type[TableType],
|
|
286
|
+
backend: TableBackend | None = None,
|
|
287
|
+
) -> TableType:
|
|
288
|
+
"""Get a table from the group as a specific type."""
|
|
289
|
+
if name not in self.list():
|
|
290
|
+
raise NgioValueError(f"Table '{name}' not found in the group.")
|
|
291
|
+
|
|
292
|
+
table_handler = self._get_table_group_handler(name)
|
|
293
|
+
return table_cls.from_handler(
|
|
294
|
+
handler=table_handler,
|
|
295
|
+
backend=backend,
|
|
296
|
+
) # type: ignore[return-value]
|
|
297
|
+
|
|
234
298
|
def add(
|
|
235
299
|
self,
|
|
236
300
|
name: str,
|
|
237
301
|
table: Table,
|
|
238
|
-
backend:
|
|
302
|
+
backend: TableBackend = "anndata",
|
|
239
303
|
overwrite: bool = False,
|
|
240
304
|
) -> None:
|
|
241
305
|
"""Add a table to the group."""
|
|
@@ -253,9 +317,10 @@ class TablesContainer:
|
|
|
253
317
|
if backend is None:
|
|
254
318
|
backend = table.backend_name
|
|
255
319
|
|
|
256
|
-
table.
|
|
320
|
+
table.set_table_data()
|
|
321
|
+
table.set_backend(
|
|
257
322
|
handler=table_handler,
|
|
258
|
-
|
|
323
|
+
backend=backend,
|
|
259
324
|
)
|
|
260
325
|
table.consolidate()
|
|
261
326
|
if name not in existing_tables:
|
|
@@ -266,6 +331,7 @@ class TablesContainer:
|
|
|
266
331
|
ImplementedTables().add_implementation(RoiTableV1)
|
|
267
332
|
ImplementedTables().add_implementation(MaskingRoiTableV1)
|
|
268
333
|
ImplementedTables().add_implementation(FeatureTableV1)
|
|
334
|
+
ImplementedTables().add_implementation(ConditionTableV1)
|
|
269
335
|
|
|
270
336
|
###################################################################################
|
|
271
337
|
#
|
|
@@ -289,6 +355,7 @@ def open_tables_container(
|
|
|
289
355
|
|
|
290
356
|
def open_table(
|
|
291
357
|
store: StoreOrGroup,
|
|
358
|
+
backend: TableBackend | None = None,
|
|
292
359
|
cache: bool = False,
|
|
293
360
|
mode: AccessModeLiteral = "a",
|
|
294
361
|
parallel_safe: bool = False,
|
|
@@ -297,15 +364,34 @@ def open_table(
|
|
|
297
364
|
handler = ZarrGroupHandler(
|
|
298
365
|
store=store, cache=cache, mode=mode, parallel_safe=parallel_safe
|
|
299
366
|
)
|
|
367
|
+
meta = _get_meta(handler)
|
|
300
368
|
return ImplementedTables().get_table(
|
|
301
|
-
|
|
369
|
+
meta=meta, handler=handler, backend=backend, strict=False
|
|
302
370
|
)
|
|
303
371
|
|
|
304
372
|
|
|
373
|
+
def open_table_as(
|
|
374
|
+
store: StoreOrGroup,
|
|
375
|
+
table_cls: type[TableType],
|
|
376
|
+
backend: TableBackend | None = None,
|
|
377
|
+
cache: bool = False,
|
|
378
|
+
mode: AccessModeLiteral = "a",
|
|
379
|
+
parallel_safe: bool = False,
|
|
380
|
+
) -> TableType:
|
|
381
|
+
"""Open a table from a Zarr store as a specific type."""
|
|
382
|
+
handler = ZarrGroupHandler(
|
|
383
|
+
store=store, cache=cache, mode=mode, parallel_safe=parallel_safe
|
|
384
|
+
)
|
|
385
|
+
return table_cls.from_handler(
|
|
386
|
+
handler=handler,
|
|
387
|
+
backend=backend,
|
|
388
|
+
) # type: ignore[return-value]
|
|
389
|
+
|
|
390
|
+
|
|
305
391
|
def write_table(
|
|
306
392
|
store: StoreOrGroup,
|
|
307
393
|
table: Table,
|
|
308
|
-
backend:
|
|
394
|
+
backend: TableBackend = "anndata",
|
|
309
395
|
cache: bool = False,
|
|
310
396
|
mode: AccessModeLiteral = "a",
|
|
311
397
|
parallel_safe: bool = False,
|
|
@@ -314,8 +400,8 @@ def write_table(
|
|
|
314
400
|
handler = ZarrGroupHandler(
|
|
315
401
|
store=store, cache=cache, mode=mode, parallel_safe=parallel_safe
|
|
316
402
|
)
|
|
317
|
-
table.
|
|
403
|
+
table.set_backend(
|
|
318
404
|
handler=handler,
|
|
319
|
-
|
|
405
|
+
backend=backend,
|
|
320
406
|
)
|
|
321
407
|
table.consolidate()
|
ngio/tables/backends/__init__.py
CHANGED
|
@@ -1,34 +1,54 @@
|
|
|
1
1
|
"""Ngio Tables backend implementations."""
|
|
2
2
|
|
|
3
3
|
from ngio.tables.backends._abstract_backend import AbstractTableBackend, BackendMeta
|
|
4
|
+
from ngio.tables.backends._anndata import AnnDataBackend
|
|
5
|
+
from ngio.tables.backends._csv import CsvTableBackend
|
|
6
|
+
from ngio.tables.backends._json import JsonTableBackend
|
|
7
|
+
from ngio.tables.backends._parquet import ParquetTableBackend
|
|
4
8
|
from ngio.tables.backends._table_backends import (
|
|
5
9
|
ImplementedTableBackends,
|
|
10
|
+
TableBackend,
|
|
6
11
|
TableBackendProtocol,
|
|
7
12
|
)
|
|
8
13
|
from ngio.tables.backends._utils import (
|
|
14
|
+
TabularData,
|
|
9
15
|
convert_anndata_to_pandas,
|
|
10
16
|
convert_anndata_to_polars,
|
|
11
17
|
convert_pandas_to_anndata,
|
|
12
18
|
convert_pandas_to_polars,
|
|
13
19
|
convert_polars_to_anndata,
|
|
14
20
|
convert_polars_to_pandas,
|
|
21
|
+
convert_to_anndata,
|
|
22
|
+
convert_to_pandas,
|
|
23
|
+
convert_to_polars,
|
|
15
24
|
normalize_anndata,
|
|
16
25
|
normalize_pandas_df,
|
|
17
26
|
normalize_polars_lf,
|
|
27
|
+
normalize_table,
|
|
18
28
|
)
|
|
19
29
|
|
|
20
30
|
__all__ = [
|
|
21
31
|
"AbstractTableBackend",
|
|
32
|
+
"AnnDataBackend",
|
|
22
33
|
"BackendMeta",
|
|
34
|
+
"CsvTableBackend",
|
|
23
35
|
"ImplementedTableBackends",
|
|
36
|
+
"JsonTableBackend",
|
|
37
|
+
"ParquetTableBackend",
|
|
38
|
+
"TableBackend",
|
|
24
39
|
"TableBackendProtocol",
|
|
40
|
+
"TabularData",
|
|
25
41
|
"convert_anndata_to_pandas",
|
|
26
42
|
"convert_anndata_to_polars",
|
|
27
43
|
"convert_pandas_to_anndata",
|
|
28
44
|
"convert_pandas_to_polars",
|
|
29
45
|
"convert_polars_to_anndata",
|
|
30
46
|
"convert_polars_to_pandas",
|
|
47
|
+
"convert_to_anndata",
|
|
48
|
+
"convert_to_pandas",
|
|
49
|
+
"convert_to_polars",
|
|
31
50
|
"normalize_anndata",
|
|
32
51
|
"normalize_pandas_df",
|
|
33
52
|
"normalize_polars_lf",
|
|
53
|
+
"normalize_table",
|
|
34
54
|
]
|