Skip to content

Commit 401409c

Browse files
Update readme and notebook for clarity (#7)
* update readme and notebook * Update README.md Co-authored-by: Jenna Tomkinson <107513215+jenna-tomkinson@users.noreply.github.com> * minor adjustment * structs def * Update learning_to_fly_with_ome-arrow.ipynb --------- Co-authored-by: Jenna Tomkinson <107513215+jenna-tomkinson@users.noreply.github.com>
1 parent 3400b6e commit 401409c

File tree

7 files changed

+121
-30
lines changed

7 files changed

+121
-30
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ repos:
3939
- id: yamllint
4040
exclude: pre-commit-config.yaml
4141
- repo: https://github.com/astral-sh/ruff-pre-commit
42-
rev: "v0.14.4"
42+
rev: "v0.14.5"
4343
hooks:
4444
- id: ruff-format
4545
- id: ruff-check

README.md

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,53 @@
1-
# ome-arrow
1+
<img height="200" src="https://raw.githubusercontent.com/wayscience/ome-arrow/main/docs/src/_static/logo.png?raw=true">
22

3-
OME-Arrow uses OME specifications with Apache Arrow for fast, queryable, and language agnostic bioimage data.
3+
![PyPI - Version](https://img.shields.io/pypi/v/ome-arrow)
4+
[![Build Status](https://github.com/wayscience/ome-arrow/actions/workflows/run-tests.yml/badge.svg?branch=main)](https://github.com/wayscience/ome-arrow/actions/workflows/run-tests.yml?query=branch%3Amain)
5+
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
6+
[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv)
47

5-
Images are often referenced through databases as filepath links instead of the data itself.
6-
OME-Arrow enables image data to be stored alongside metadata or derived data such as single-cell morphology features.
7-
This means you can store and query data from the same location using any system which is compatible with Apache Arrow.
8+
# Open, interoperable, and queryable microscopy images with OME Arrow
9+
10+
OME-Arrow uses [Open Microscopy Environment (OME)](https://github.com/ome) specifications through [Apache Arrow](https://arrow.apache.org/) for fast, queryable, and language agnostic bioimage data.
11+
12+
<img height="200" src="https://raw.githubusercontent.com/wayscience/ome-arrow/main/docs/src/_static/references_to_files.png">
13+
14+
__Images are often left behind from the data model, referenced but excluded from databases.__
15+
16+
<img height="200" src="https://raw.githubusercontent.com/wayscience/ome-arrow/main/docs/src/_static/various_ome_arrow_schema.png">
17+
18+
__OME-Arrow brings images back into the story.__
19+
20+
OME Arrow enables image data to be stored alongside metadata or derived data such as single-cell morphology features.
21+
Images in OME Arrow are composed of mutlilayer [structs](https://arrow.apache.org/docs/python/generated/pyarrow.struct.html) so they may be stored as values within tables.
22+
This means you can store, query, and build relationships on data from the same location using any system which is compatible with Apache Arrow (including Parquet) through common data interfaces (such as SQL and DuckDB).
23+
24+
## Installation
25+
26+
Install OME Arrow from PyPI or from source:
27+
28+
```sh
29+
# install from pypi
30+
pip install ome-arrow
31+
32+
# install directly from source
33+
pip install git+https://github.com/wayscience/ome-arrow.git
34+
```
835

936
## Quick start
1037

1138
See below for a quick start guide.
12-
Please also reference an example notebook: [Learning to fly with OME-Arrow](docs/src/examples/learning_to_fly_with_ome-arrow.ipynb).
39+
Please also reference an example notebook: [Learning to fly with OME-Arrow](https://github.com/wayscience/ome-arrow/tree/main/docs/src/examples/learning_to_fly_with_ome-arrow.ipynb).
1340

1441
```python
1542
from ome_arrow import OMEArrow
1643

17-
# Ingest a tif image through a convenient OME-Arrow class
44+
# Ingest a tif image through a convenient OME Arrow class
1845
# We can also ingest OME-Zarr or NumPy arrays.
1946
oa_image = OMEArrow(
2047
data="your_image.tif"
2148
)
2249

23-
# Access the OME-Arrow struct itself
50+
# Access the OME Arrow struct itself
2451
# (compatible with Arrow-compliant data storage).
2552
oa_image.data
2653

@@ -38,3 +65,16 @@ oa_image.view(how="pyvista")
3865
# We can also export OME-TIFF, OME-Zarr or NumPy arrays.
3966
oa_image.export(how="ome-parquet", out="your_image.ome.parquet")
4067
```
68+
69+
## Contributing, Development, and Testing
70+
71+
Please see our [contributing documentation](https://github.com/wayscience/ome-arrow/tree/main/CONTRIBUTING.md) for more details on contributions, development, and testing.
72+
73+
## Related projects
74+
75+
OME Arrow is used or inspired by the following projects, check them out!
76+
77+
- [`napari-ome-arrow`](https://github.com/WayScience/napari-ome-arrow): enables you to view OME Arrow and related images.
78+
- [`nViz`](https://github.com/WayScience/nViz): focuses on ingesting and visualizing various 3D image data.
79+
- [`CytoDataFrame`](https://github.com/cytomining/CytoDataFrame): provides a DataFrame-like experience for viewing feature and microscopy image data within Jupyter notebook interfaces.
80+
- [`coSMicQC`](https://github.com/cytomining/coSMicQC): performs quality control on microscopy feature datasets, visualized using CytoDataFrames.

docs/src/_static/logo.png

71.9 KB
Loading
83.2 KB
Loading
36.7 KB
Loading

docs/src/examples/learning_to_fly_with_ome-arrow.ipynb

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
"id": "d778aece-5867-49b6-8890-f5a387f22c44",
66
"metadata": {},
77
"source": [
8-
"# Learning to fly with OME-Arrow\n"
8+
"# Learning to fly with OME-Arrow\n",
9+
"\n",
10+
"This notebook provides a quick demonstration of what you can do with OME Arrow."
911
]
1012
},
1113
{
@@ -15,6 +17,8 @@
1517
"metadata": {},
1618
"outputs": [],
1719
"source": [
20+
"# we import a single class, OMEArrow\n",
21+
"# which handles all data I/O and manipulation\n",
1822
"from ome_arrow import OMEArrow"
1923
]
2024
},
@@ -30,7 +34,7 @@
3034
"2D image, single-channel - shape (T=1, C=1, Z=1, Y=512, X=512)"
3135
],
3236
"text/plain": [
33-
"<ome_arrow.core.OMEArrow at 0x169de7d90>"
37+
"<ome_arrow.core.OMEArrow at 0x162d227d0>"
3438
]
3539
},
3640
"execution_count": 2,
@@ -49,9 +53,11 @@
4953
}
5054
],
5155
"source": [
56+
"# read a TIFF file and convert it to OME-Arrow\n",
5257
"oa_image = OMEArrow(\n",
5358
" data=\"../../../tests/data/examplehuman/AS_09125_050116030001_D03f00d0.tif\"\n",
5459
")\n",
60+
"# by default, the image and metadata are shown\n",
5561
"oa_image"
5662
]
5763
},
@@ -77,6 +83,7 @@
7783
}
7884
],
7985
"source": [
86+
"# we can also get a summary of the OME-Arrow object\n",
8087
"oa_image.info()"
8188
]
8289
},
@@ -105,6 +112,8 @@
105112
}
106113
],
107114
"source": [
115+
"# we can export the data into a number\n",
116+
"# of different formats, e.g. numpy\n",
108117
"oa_image.export(how=\"numpy\")"
109118
]
110119
},
@@ -120,7 +129,7 @@
120129
"3D image (z-stack), multi-channel (2 channels) - shape (T=1, C=2, Z=22, Y=128, X=128)"
121130
],
122131
"text/plain": [
123-
"<ome_arrow.core.OMEArrow at 0x31d2e8550>"
132+
"<ome_arrow.core.OMEArrow at 0x1662b2810>"
124133
]
125134
},
126135
"execution_count": 5,
@@ -139,28 +148,31 @@
139148
}
140149
],
141150
"source": [
151+
"# We can also read in TIFF stacks following OME bfconvert API conventions\n",
142152
"stack = OMEArrow(\n",
143153
" data=\"../../../tests/data/nviz-artificial-4d-dataset/E99_C<111,222>_ZS<000-021>.tif\",\n",
154+
" # this is an optional for which\n",
155+
" # timepoint, channel, and z-slice to show by default\n",
144156
" tcz=(0, 0, 20),\n",
145157
")\n",
146158
"stack"
147159
]
148160
},
149161
{
150162
"cell_type": "code",
151-
"execution_count": 10,
163+
"execution_count": 6,
152164
"id": "383e1f10-b32f-47cb-9906-15dd9947b09a",
153165
"metadata": {},
154166
"outputs": [
155167
{
156168
"data": {
157169
"application/vnd.jupyter.widget-view+json": {
158-
"model_id": "cf00f3c09cc340f792d8811b76cc739b",
170+
"model_id": "e644f91c4e3843c39f130f05b628277e",
159171
"version_major": 2,
160172
"version_minor": 0
161173
},
162174
"text/plain": [
163-
"Widget(value='<iframe src=\"http://localhost:65381/index.html?ui=P_0x3620ef510_0&reconnect=auto\" class=\"pyvista…"
175+
"Widget(value='<iframe src=\"http://localhost:55867/index.html?ui=P_0x1663cf990_0&reconnect=auto\" class=\"pyvista…"
164176
]
165177
},
166178
"metadata": {},
@@ -186,21 +198,22 @@
186198
{
187199
"data": {
188200
"text/plain": [
189-
"<pyvista.plotting.plotter.Plotter at 0x3620ef510>"
201+
"<pyvista.plotting.plotter.Plotter at 0x1663cf990>"
190202
]
191203
},
192-
"execution_count": 10,
204+
"execution_count": 6,
193205
"metadata": {},
194206
"output_type": "execute_result"
195207
}
196208
],
197209
"source": [
210+
"# we can visualize the stack using pyvista for 3D rendering\n",
198211
"stack.view(how=\"pyvista\")"
199212
]
200213
},
201214
{
202215
"cell_type": "code",
203-
"execution_count": 6,
216+
"execution_count": 7,
204217
"id": "d041ba28-bb16-4833-9661-9c9da2ff3a9c",
205218
"metadata": {},
206219
"outputs": [
@@ -210,10 +223,10 @@
210223
"3D image (z-stack), multi-channel (2 channels) - shape (T=1, C=2, Z=22, Y=128, X=128)"
211224
],
212225
"text/plain": [
213-
"<ome_arrow.core.OMEArrow at 0x31d3a9790>"
226+
"<ome_arrow.core.OMEArrow at 0x10aae1ad0>"
214227
]
215228
},
216-
"execution_count": 6,
229+
"execution_count": 7,
217230
"metadata": {},
218231
"output_type": "execute_result"
219232
},
@@ -229,13 +242,16 @@
229242
}
230243
],
231244
"source": [
245+
"# here we demonstrate that the data can be exported again\n",
246+
"# into numpy format and re-imported\n",
247+
"# into a new OME-Arrow object (from numpy data).\n",
232248
"stack_np = stack.export(how=\"numpy\")\n",
233249
"OMEArrow(data=stack_np, tcz=(0, 0, 20))"
234250
]
235251
},
236252
{
237253
"cell_type": "code",
238-
"execution_count": 7,
254+
"execution_count": 8,
239255
"id": "013baec4-0fed-452c-b200-cfd3b5f04d3e",
240256
"metadata": {},
241257
"outputs": [
@@ -245,10 +261,10 @@
245261
"3D image (z-stack), multi-channel (2 channels) - shape (T=1, C=2, Z=22, Y=128, X=128)"
246262
],
247263
"text/plain": [
248-
"<ome_arrow.core.OMEArrow at 0x31d3e1710>"
264+
"<ome_arrow.core.OMEArrow at 0x1662019d0>"
249265
]
250266
},
251-
"execution_count": 7,
267+
"execution_count": 8,
252268
"metadata": {},
253269
"output_type": "execute_result"
254270
},
@@ -264,13 +280,16 @@
264280
}
265281
],
266282
"source": [
283+
"# here we demonstrate that the data can be exported again\n",
284+
"# into OME-TIFF format and re-imported\n",
285+
"# into a new OME-Arrow object (from OME-TIFF data).\n",
267286
"stack.export(how=\"ome-tiff\", out=\"example.ome.tiff\")\n",
268287
"OMEArrow(data=\"example.ome.tiff\", tcz=(0, 0, 20))"
269288
]
270289
},
271290
{
272291
"cell_type": "code",
273-
"execution_count": 8,
292+
"execution_count": 9,
274293
"id": "ebaab572-f820-4402-9dd7-2ad5ce657e05",
275294
"metadata": {},
276295
"outputs": [
@@ -280,10 +299,10 @@
280299
"3D image (z-stack), multi-channel (2 channels) - shape (T=1, C=2, Z=22, Y=128, X=128)"
281300
],
282301
"text/plain": [
283-
"<ome_arrow.core.OMEArrow at 0x31d3521d0>"
302+
"<ome_arrow.core.OMEArrow at 0x1663adad0>"
284303
]
285304
},
286-
"execution_count": 8,
305+
"execution_count": 9,
287306
"metadata": {},
288307
"output_type": "execute_result"
289308
},
@@ -299,13 +318,16 @@
299318
}
300319
],
301320
"source": [
321+
"# here we demonstrate that the data can be exported again\n",
322+
"# into OME-ZARR format and re-imported\n",
323+
"# into a new OME-Arrow object (from OME-ZARR data).\n",
302324
"stack.export(how=\"ome-zarr\", out=\"example.ome.zarr\")\n",
303325
"OMEArrow(data=\"example.ome.zarr\", tcz=(0, 0, 20))"
304326
]
305327
},
306328
{
307329
"cell_type": "code",
308-
"execution_count": 9,
330+
"execution_count": 10,
309331
"id": "11b5c23c-d4b1-4170-ad0c-64c358b0cfe6",
310332
"metadata": {},
311333
"outputs": [
@@ -315,10 +337,10 @@
315337
"3D image (z-stack), multi-channel (2 channels) - shape (T=1, C=2, Z=22, Y=128, X=128)"
316338
],
317339
"text/plain": [
318-
"<ome_arrow.core.OMEArrow at 0x31d349d50>"
340+
"<ome_arrow.core.OMEArrow at 0x38064c810>"
319341
]
320342
},
321-
"execution_count": 9,
343+
"execution_count": 10,
322344
"metadata": {},
323345
"output_type": "execute_result"
324346
},
@@ -334,6 +356,9 @@
334356
}
335357
],
336358
"source": [
359+
"# here we demonstrate that the data can be exported again\n",
360+
"# into OME-Parquet format and re-imported\n",
361+
"# into a new OME-Arrow object (from OME-Parquet data).\n",
337362
"stack.export(how=\"ome-parquet\", out=\"example.ome.parquet\")\n",
338363
"OMEArrow(data=\"example.ome.parquet\", tcz=(0, 0, 20))"
339364
]
@@ -350,7 +375,7 @@
350375
"2D image, single-channel - shape (T=1, C=1, Z=1, Y=30, X=30)"
351376
],
352377
"text/plain": [
353-
"<ome_arrow.core.OMEArrow at 0x31d385f10>"
378+
"<ome_arrow.core.OMEArrow at 0x167243690>"
354379
]
355380
},
356381
"execution_count": 11,
@@ -369,6 +394,7 @@
369394
}
370395
],
371396
"source": [
397+
"# we can also slice the data to get a smaller region of interest\n",
372398
"stack.slice(\n",
373399
" x_min=40,\n",
374400
" y_min=80,\n",

0 commit comments

Comments
 (0)