Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.11", "3.12", "3.13",]
python-version: ["3.12", "3.13",]
platform: [ubuntu-latest, macos-latest, windows-latest]

steps:
Expand Down Expand Up @@ -86,7 +86,7 @@ jobs:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- uses: hynek/build-and-inspect-python-package@v2
- uses: hynek/build-and-inspect-python-package@2abe76da66d0a6a4a227101f9348ee855797cfa5 # v3.0.1

upload-to-pypi:
name: Upload package to PyPI
Expand Down
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ You can load a v0.4 or v0.5 OME-Zarr file into a single-canvas 2d/3d viewer usin
oz-viewer view path/to/image.ome.zarr
```

Note that some OME-Zarr files do not provide the necessary translation in the multiscale transforms to keep the downscaled voxels centered. `oz-viewer` provides a flag to infer the translations based on the shapes and downscale factors of the multiscale levels. Use the `--infer-multiscale-translations` flag to enable this behavior.

```sh
oz-viewer view path/to/image.ome.zarr --infer-multiscale-translations`
```

Example viewing a https://livingobjects.ebi.ac.uk/idr/zarr/v0.5/idr0066/ExpA_VIP_ASLM_on.zarr (1937, 2048, 2048), anisotropic voxels (file was on local SSD).

https://github.com/user-attachments/assets/59c31e89-db42-4cec-ae4f-373d997c227f
Expand All @@ -45,11 +51,18 @@ You can load a v0.4 or v0.5 OME-Zarr file into an orthoviewer using the `oz-view
oz-viewer ortho path/to/image.ome.zarr
```

Note that some OME-Zarr files do not provide the necessary translation in the multiscale transforms to keep the downscaled voxels centered. `oz-viewer` provides a flag to infer the translations based on the shapes and downscale factors of the multiscale levels. Use the `--infer-multiscale-translations` flag to enable this behavior.

```sh
oz-viewer ortho path/to/image.ome.zarr --infer-multiscale-translations`
```


Example viewing https://livingobjects.ebi.ac.uk/idr/zarr/v0.5/idr0066/ExpA_VIP_ASLM_on.zarr (1937, 2048, 2048), anisotropic voxels (file was on local SSD).

https://github.com/user-attachments/assets/a6c0cab9-0cd9-4fe0-80c2-c77207b4fd77

You can click the multichannel button in the upper left-hand corner to toggle between single/multichannel rendering. Example viewing the scikit-image cells3d (converted to ome-zarr) multichannel image
Images with a channel axis open as a composite of their channels (up to 4). Use the "Composite channels" checkbox in the image controls on the left to switch between the composite and single-channel rendering, where a slider steps through the channels. Example viewing the scikit-image cells3d (converted to ome-zarr) multichannel image

https://github.com/user-attachments/assets/b6655863-b8fb-4eea-be84-eb031283494e

Expand Down
14 changes: 2 additions & 12 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,14 @@ name = "oz-viewer"
dynamic = ["version"]
description = "A viewer for ome-zarr images."
readme = "README.md"
requires-python = ">=3.11"
requires-python = ">=3.12"
license = { text = "BSD-3-Clause" }
authors = [{ name = "Kevin Yamauchi", email = "kevin.yamauchi@gmail.com" }]
# https://pypi.org/classifiers/
classifiers = [
"Development Status :: 3 - Alpha",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Typing :: Typed",
Expand All @@ -38,7 +37,7 @@ dependencies = [
"typer >= 0.12",
"rich >= 13",
"numpy >= 1.24",
"cellier[pyside,anywidget]>=0.0.26",
"cellier[pyside,anywidget]>=0.0.27",
"aiohttp >= 3.9",
"zarr >= 3.0",
"s3fs",
Expand All @@ -49,15 +48,6 @@ dependencies = [
# https://peps.python.org/pep-0621/#dependencies-optional-dependencies
# add dependencies for "extra" features here. Not dev dependencies.
[project.optional-dependencies]
# Dependencies for the notebook examples under examples/. Install with
# `pip install -e '.[examples]'`. cellier[anywidget] adds the anywidget
# front-end (notebook rendering); scikit-image + pooch provide the cells3d
# sample dataset used by examples/viewer.ipynb.
#
# NOTE: the anywidget canvas backend currently requires rendercanvas from git
# main, which cannot be expressed as a version pin here -- install it
# separately:
# uv pip install "rendercanvas @ git+https://github.com/pygfx/rendercanvas.git"
examples = [
"jupyterlab>=4.5.6",
"scikit-image>=0.24",
Expand Down
42 changes: 40 additions & 2 deletions src/oz_viewer/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,19 @@ def ortho(
show_default=False,
),
] = None,
infer_multiscale_translations: Annotated[
bool,
typer.Option(
"--infer-multiscale-translations",
help=(
"Assume the coarser pyramid levels were downsampled centre-aligned"
" (e.g. block averages) and add the half-voxel offsets that implies"
" when the store declares no level translations. Wrong for"
" pyramids made by striding. Ignored, with a warning, when the"
" store declares translations."
),
),
] = False,
theme: Annotated[
str,
typer.Option(
Expand Down Expand Up @@ -237,7 +250,13 @@ def ortho(
perf.mark("cli.ortho.uri_resolved", zarr_uri=zarr_uri)

perf.mark("cli.ortho.launch")
launch_orthoviewer(zarr_uri, channel_axis=multichannel, theme=theme, perf=perf)
launch_orthoviewer(
zarr_uri,
channel_axis=multichannel,
infer_multiscale_translations=infer_multiscale_translations,
theme=theme,
perf=perf,
)


@app.command()
Expand Down Expand Up @@ -279,6 +298,19 @@ def view(
show_default=False,
),
] = None,
infer_multiscale_translations: Annotated[
bool,
typer.Option(
"--infer-multiscale-translations",
help=(
"Assume the coarser pyramid levels were downsampled centre-aligned"
" (e.g. block averages) and add the half-voxel offsets that implies"
" when the store declares no level translations. Wrong for"
" pyramids made by striding. Ignored, with a warning, when the"
" store declares translations."
),
),
] = False,
theme: Annotated[
str,
typer.Option(
Expand Down Expand Up @@ -359,7 +391,13 @@ def view(
perf.mark("cli.view.uri_resolved", zarr_uri=zarr_uri)

perf.mark("cli.view.launch")
launch_viewer(zarr_uri, channel_axis=multichannel, theme=theme, perf=perf)
launch_viewer(
zarr_uri,
channel_axis=multichannel,
infer_multiscale_translations=infer_multiscale_translations,
theme=theme,
perf=perf,
)


@app.command(name="theme")
Expand Down
Loading
Loading