ome-arrow 0.0.4__py3-none-any.whl → 0.0.6__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.
- ome_arrow/__init__.py +8 -1
- ome_arrow/_version.py +2 -2
- ome_arrow/core.py +72 -7
- ome_arrow/export.py +302 -8
- ome_arrow/ingest.py +542 -124
- ome_arrow/meta.py +41 -0
- ome_arrow/transform.py +34 -0
- ome_arrow/view.py +20 -22
- {ome_arrow-0.0.4.dist-info → ome_arrow-0.0.6.dist-info}/METADATA +7 -2
- ome_arrow-0.0.6.dist-info/RECORD +14 -0
- {ome_arrow-0.0.4.dist-info → ome_arrow-0.0.6.dist-info}/WHEEL +1 -1
- ome_arrow-0.0.4.dist-info/RECORD +0 -14
- {ome_arrow-0.0.4.dist-info → ome_arrow-0.0.6.dist-info}/licenses/LICENSE +0 -0
- {ome_arrow-0.0.4.dist-info → ome_arrow-0.0.6.dist-info}/top_level.txt +0 -0
ome_arrow/meta.py
CHANGED
|
@@ -12,8 +12,10 @@ OME_ARROW_TAG_VERSION = ome_arrow_version
|
|
|
12
12
|
# OME_ARROW_STRUCT: ome-arrow record (describes one image/value).
|
|
13
13
|
# - type/version: quick identity & evolution.
|
|
14
14
|
# - id/name/acquisition_datetime: identity & provenance.
|
|
15
|
+
# - image_type: open-ended image kind (e.g., "image", "label").
|
|
15
16
|
# - pixels_meta: pixels struct (sizes, units, channels).
|
|
16
17
|
# - planes: list of planes struct entries, one per (t,c,z).
|
|
18
|
+
# - chunk_grid/chunks: optional chunked pixels (TCZYX-aware), stored as Arrow lists.
|
|
17
19
|
# - masks: reserved for future labels/ROIs (placeholder).
|
|
18
20
|
OME_ARROW_STRUCT: pa.StructType = pa.struct(
|
|
19
21
|
[
|
|
@@ -21,6 +23,7 @@ OME_ARROW_STRUCT: pa.StructType = pa.struct(
|
|
|
21
23
|
pa.field("version", pa.string()), # e.g., "1.0.0"
|
|
22
24
|
pa.field("id", pa.string()), # stable image identifier
|
|
23
25
|
pa.field("name", pa.string()), # human label
|
|
26
|
+
pa.field("image_type", pa.string()), # open-ended (e.g., "image", "label")
|
|
24
27
|
pa.field("acquisition_datetime", pa.timestamp("us")),
|
|
25
28
|
# PIXELS: OME-like "Pixels" header summarizing shape & scale.
|
|
26
29
|
# - dimension_order: hint like "XYZCT" (or "XYCT" when Z==1).
|
|
@@ -68,6 +71,44 @@ OME_ARROW_STRUCT: pa.StructType = pa.struct(
|
|
|
68
71
|
]
|
|
69
72
|
),
|
|
70
73
|
),
|
|
74
|
+
# CHUNK GRID: optional chunking metadata for random access.
|
|
75
|
+
# - order: axis order for the full array, e.g., "TCZYX".
|
|
76
|
+
# - chunk_*: chunk sizes for each axis (defaults to 1 for T/C).
|
|
77
|
+
# - chunk_order: order used to flatten chunk pixels (default "ZYX").
|
|
78
|
+
pa.field(
|
|
79
|
+
"chunk_grid",
|
|
80
|
+
pa.struct(
|
|
81
|
+
[
|
|
82
|
+
pa.field("order", pa.string()),
|
|
83
|
+
pa.field("chunk_t", pa.int32()),
|
|
84
|
+
pa.field("chunk_c", pa.int16()),
|
|
85
|
+
pa.field("chunk_z", pa.int32()),
|
|
86
|
+
pa.field("chunk_y", pa.int32()),
|
|
87
|
+
pa.field("chunk_x", pa.int32()),
|
|
88
|
+
pa.field("chunk_order", pa.string()),
|
|
89
|
+
]
|
|
90
|
+
),
|
|
91
|
+
),
|
|
92
|
+
# CHUNKS: list of chunk entries (Arrow-native, no binary payloads).
|
|
93
|
+
# - pixels flattened in chunk_order (default "ZYX").
|
|
94
|
+
pa.field(
|
|
95
|
+
"chunks",
|
|
96
|
+
pa.list_(
|
|
97
|
+
pa.struct(
|
|
98
|
+
[
|
|
99
|
+
pa.field("t", pa.int32()),
|
|
100
|
+
pa.field("c", pa.int16()),
|
|
101
|
+
pa.field("z", pa.int32()),
|
|
102
|
+
pa.field("y", pa.int32()),
|
|
103
|
+
pa.field("x", pa.int32()),
|
|
104
|
+
pa.field("shape_z", pa.int32()),
|
|
105
|
+
pa.field("shape_y", pa.int32()),
|
|
106
|
+
pa.field("shape_x", pa.int32()),
|
|
107
|
+
pa.field("pixels", pa.list_(pa.uint16())),
|
|
108
|
+
]
|
|
109
|
+
)
|
|
110
|
+
),
|
|
111
|
+
),
|
|
71
112
|
# PLANES: one 2D image plane for a specific (t, c, z).
|
|
72
113
|
# - pixels: flattened numeric list (Y*X) for analysis-ready computation.
|
|
73
114
|
pa.field(
|
ome_arrow/transform.py
CHANGED
|
@@ -8,6 +8,7 @@ from typing import Any, Dict, Iterable, List, Optional, Tuple
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
import pyarrow as pa
|
|
10
10
|
|
|
11
|
+
from ome_arrow.ingest import _build_chunks_from_planes, _normalize_chunk_shape
|
|
11
12
|
from ome_arrow.meta import OME_ARROW_STRUCT
|
|
12
13
|
|
|
13
14
|
|
|
@@ -179,4 +180,37 @@ def slice_ome_arrow(
|
|
|
179
180
|
rec_out["pixels_meta"] = pm_out
|
|
180
181
|
rec_out["planes"] = planes_out
|
|
181
182
|
|
|
183
|
+
chunk_grid_in = row.get("chunk_grid") or {}
|
|
184
|
+
if chunk_grid_in or row.get("chunks"):
|
|
185
|
+
chunk_shape = (
|
|
186
|
+
int(chunk_grid_in.get("chunk_z", 1)),
|
|
187
|
+
int(chunk_grid_in.get("chunk_y", 512)),
|
|
188
|
+
int(chunk_grid_in.get("chunk_x", 512)),
|
|
189
|
+
)
|
|
190
|
+
chunk_order = str(chunk_grid_in.get("chunk_order") or "ZYX")
|
|
191
|
+
chunks_out = _build_chunks_from_planes(
|
|
192
|
+
planes=planes_out,
|
|
193
|
+
size_t=new_st,
|
|
194
|
+
size_c=new_sc,
|
|
195
|
+
size_z=new_sz,
|
|
196
|
+
size_y=new_sy,
|
|
197
|
+
size_x=new_sx,
|
|
198
|
+
chunk_shape=chunk_shape,
|
|
199
|
+
chunk_order=chunk_order,
|
|
200
|
+
)
|
|
201
|
+
cz, cy, cx = _normalize_chunk_shape(chunk_shape, new_sz, new_sy, new_sx)
|
|
202
|
+
rec_out["chunk_grid"] = {
|
|
203
|
+
"order": "TCZYX",
|
|
204
|
+
"chunk_t": 1,
|
|
205
|
+
"chunk_c": 1,
|
|
206
|
+
"chunk_z": cz,
|
|
207
|
+
"chunk_y": cy,
|
|
208
|
+
"chunk_x": cx,
|
|
209
|
+
"chunk_order": chunk_order,
|
|
210
|
+
}
|
|
211
|
+
rec_out["chunks"] = chunks_out
|
|
212
|
+
else:
|
|
213
|
+
rec_out["chunk_grid"] = row.get("chunk_grid")
|
|
214
|
+
rec_out["chunks"] = row.get("chunks")
|
|
215
|
+
|
|
182
216
|
return pa.scalar(rec_out, type=OME_ARROW_STRUCT)
|
ome_arrow/view.py
CHANGED
|
@@ -23,6 +23,8 @@ except ImportError: # pragma: no cover - exercised when viz extra missing
|
|
|
23
23
|
if TYPE_CHECKING:
|
|
24
24
|
import pyvista
|
|
25
25
|
|
|
26
|
+
from ome_arrow.export import plane_from_chunks
|
|
27
|
+
|
|
26
28
|
|
|
27
29
|
def view_matplotlib(
|
|
28
30
|
data: dict[str, object] | pa.StructScalar,
|
|
@@ -33,29 +35,25 @@ def view_matplotlib(
|
|
|
33
35
|
cmap: str = "gray",
|
|
34
36
|
show: bool = True,
|
|
35
37
|
) -> tuple[Figure, Axes, AxesImage]:
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
38
|
+
"""Render a single (t, c, z) plane with Matplotlib.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
data: OME-Arrow row or dict containing pixels_meta and planes.
|
|
42
|
+
tcz: (t, c, z) indices of the plane to render.
|
|
43
|
+
autoscale: If True, infer vmin/vmax from the image data.
|
|
44
|
+
vmin: Explicit lower display limit for intensity scaling.
|
|
45
|
+
vmax: Explicit upper display limit for intensity scaling.
|
|
46
|
+
cmap: Matplotlib colormap name.
|
|
47
|
+
show: Whether to display the plot immediately.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
A tuple of (figure, axes, image) from Matplotlib.
|
|
51
|
+
|
|
52
|
+
Raises:
|
|
53
|
+
ValueError: If the requested plane is missing or pixel sizes mismatch.
|
|
54
|
+
"""
|
|
41
55
|
t, c, z = (int(x) for x in tcz)
|
|
42
|
-
|
|
43
|
-
plane = next(
|
|
44
|
-
(
|
|
45
|
-
p
|
|
46
|
-
for p in data["planes"]
|
|
47
|
-
if int(p["t"]) == t and int(p["c"]) == c and int(p["z"]) == z
|
|
48
|
-
),
|
|
49
|
-
None,
|
|
50
|
-
)
|
|
51
|
-
if plane is None:
|
|
52
|
-
raise ValueError(f"plane (t={t}, c={c}, z={z}) not found")
|
|
53
|
-
|
|
54
|
-
pix = plane["pixels"]
|
|
55
|
-
if len(pix) != sx * sy:
|
|
56
|
-
raise ValueError(f"pixels len {len(pix)} != size_x*size_y ({sx * sy})")
|
|
57
|
-
|
|
58
|
-
img = np.asarray(pix, dtype=np.uint16).reshape(sy, sx).copy()
|
|
56
|
+
img = plane_from_chunks(data, t=t, c=c, z=z, dtype=np.uint16).copy()
|
|
59
57
|
|
|
60
58
|
if (vmin is None or vmax is None) and autoscale:
|
|
61
59
|
lo, hi = int(img.min()), int(img.max())
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ome-arrow
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.6
|
|
4
4
|
Summary: Using OME specifications with Apache Arrow for fast, queryable, and language agnostic bioimage data.
|
|
5
5
|
Author: Dave Bunten
|
|
6
6
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -28,9 +28,11 @@ Requires-Dist: pyvista>=0.46.4; extra == "viz"
|
|
|
28
28
|
Requires-Dist: trame>=3.12; extra == "viz"
|
|
29
29
|
Requires-Dist: trame-vtk>=2.10; extra == "viz"
|
|
30
30
|
Requires-Dist: trame-vuetify>=3.1; extra == "viz"
|
|
31
|
+
Provides-Extra: vortex
|
|
32
|
+
Requires-Dist: vortex-data>=0.56; extra == "vortex"
|
|
31
33
|
Dynamic: license-file
|
|
32
34
|
|
|
33
|
-
<img
|
|
35
|
+
<img width="600" src="https://raw.githubusercontent.com/wayscience/ome-arrow/main/docs/src/_static/logo.png?raw=true">
|
|
34
36
|
|
|
35
37
|

|
|
36
38
|
[](https://github.com/wayscience/ome-arrow/actions/workflows/run-tests.yml?query=branch%3Amain)
|
|
@@ -104,6 +106,9 @@ oa_image.view(how="pyvista")
|
|
|
104
106
|
# Export to OME-Parquet.
|
|
105
107
|
# We can also export OME-TIFF, OME-Zarr or NumPy arrays.
|
|
106
108
|
oa_image.export(how="ome-parquet", out="your_image.ome.parquet")
|
|
109
|
+
|
|
110
|
+
# Export to Vortex (install extras: `pip install 'ome-arrow[vortex]'`).
|
|
111
|
+
oa_image.export(how="vortex", out="your_image.vortex")
|
|
107
112
|
```
|
|
108
113
|
|
|
109
114
|
## Contributing, Development, and Testing
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
ome_arrow/__init__.py,sha256=WWenJP9XxLZNGQPVOEFBDlDM1kSvj_QdHssrET6UuNQ,644
|
|
2
|
+
ome_arrow/_version.py,sha256=7MyqQ3iPP2mJruPfRYGCNCq1z7_Nk7c-eyYecYITxsY,704
|
|
3
|
+
ome_arrow/core.py,sha256=K1-jfojhqYkn3h-0AdmBQYFza0wtFqduJs6K7aw4Kuc,21303
|
|
4
|
+
ome_arrow/export.py,sha256=XbKVIeMLbPshgo_OGO3e0PRqtZ3vEx_JAGyF9oUmZJw,26024
|
|
5
|
+
ome_arrow/ingest.py,sha256=CptjVXXL8YzfHKlKqyoA-ani5SLbFlQSUVPqOXlPhXA,46931
|
|
6
|
+
ome_arrow/meta.py,sha256=peIx6NLriaFpGBx9Y3NyTHLfGAg91v9YQpoBzrveKFQ,6031
|
|
7
|
+
ome_arrow/transform.py,sha256=X3gKZkgTDNQSBcU3_YmJRav8JIBrDdYJci3PbFZ4t38,7200
|
|
8
|
+
ome_arrow/utils.py,sha256=XHovcqmjqoiBpKvXY47-_yUwf07f8zVE_F9BR_VKaPU,2383
|
|
9
|
+
ome_arrow/view.py,sha256=j9dpmSnVbiukwH6asFhCJ_WVRxwyCAdTeLiUnv_xvcE,10187
|
|
10
|
+
ome_arrow-0.0.6.dist-info/licenses/LICENSE,sha256=9-2Pyhu3vTt2RJU8DorHQtHeNO_e5RLeFJTyOU4hOi4,1508
|
|
11
|
+
ome_arrow-0.0.6.dist-info/METADATA,sha256=VWirz2ueYrPLOrsNj1EC2BGcsPtLpJU6Jay_NW_irZ8,6110
|
|
12
|
+
ome_arrow-0.0.6.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
13
|
+
ome_arrow-0.0.6.dist-info/top_level.txt,sha256=aWOtkGXo_pfU-yy82guzGhz8Zh2h2nFl8Kc5qdzMGuE,10
|
|
14
|
+
ome_arrow-0.0.6.dist-info/RECORD,,
|
ome_arrow-0.0.4.dist-info/RECORD
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
ome_arrow/__init__.py,sha256=DfQsw8l0mx1Qt3YiiMv2SUljKETP3wS5hrD5eBbjMDM,583
|
|
2
|
-
ome_arrow/_version.py,sha256=QlXZ5JTjE_pgpDaeHk0GTExkc75xUZFmd0hA7kGYCJ0,704
|
|
3
|
-
ome_arrow/core.py,sha256=pTKmzKFXF5d4nSJpXQxlS71UA23P7TLHrX2eA0IxgUg,18594
|
|
4
|
-
ome_arrow/export.py,sha256=CCTnEdHko4Z0i5LEHuNGFLznWSsPyAFcS42H5nHU22Q,14875
|
|
5
|
-
ome_arrow/ingest.py,sha256=7N-M_NYOskHjs59Yhd4j8QXnKC5ykBXM7cT9Ap2chz8,32032
|
|
6
|
-
ome_arrow/meta.py,sha256=qeD0e_ItAQyZDT7ypkBU0rBh9oHIu2ziz9MCfPpPp9g,4199
|
|
7
|
-
ome_arrow/transform.py,sha256=0275_Mn1mlGXSWJ86llch8JoJyvqEOfvG-ub1dUWFNI,5997
|
|
8
|
-
ome_arrow/utils.py,sha256=XHovcqmjqoiBpKvXY47-_yUwf07f8zVE_F9BR_VKaPU,2383
|
|
9
|
-
ome_arrow/view.py,sha256=O4sIF8CZ4if-tV-rr2-yyG8WB5jHN9jq8HKvS-Ielnw,10034
|
|
10
|
-
ome_arrow-0.0.4.dist-info/licenses/LICENSE,sha256=9-2Pyhu3vTt2RJU8DorHQtHeNO_e5RLeFJTyOU4hOi4,1508
|
|
11
|
-
ome_arrow-0.0.4.dist-info/METADATA,sha256=2al9lOlUBjuximxy-1L9TsbVkFC46o0_zR3T1EnFRtU,5908
|
|
12
|
-
ome_arrow-0.0.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
13
|
-
ome_arrow-0.0.4.dist-info/top_level.txt,sha256=aWOtkGXo_pfU-yy82guzGhz8Zh2h2nFl8Kc5qdzMGuE,10
|
|
14
|
-
ome_arrow-0.0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|