Skip to content

Commit

Permalink
feat: add write_tiff export to OME-TIFF, include full metadata as S…
Browse files Browse the repository at this point in the history
…tructuredAnnotation (tlambert03#216)

* wip export to tiff

* remove breakpoint

* working well

* cleanup

* public exports

* future import

* test more things

* remove pragma

* docs

* fix multi-point

* style(pre-commit.ci): auto fixes [...]

* fix color

* fix rgb and other things

* fix readme test

* unify changes

* add to test

* force tst

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
  • Loading branch information
tlambert03 and pre-commit-ci[bot] authored Mar 17, 2024
1 parent 256ef22 commit 7c3a64a
Show file tree
Hide file tree
Showing 15 changed files with 597 additions and 250 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ This reader provides a pure python implementation of the Nikon ND2 SDK.
> **Note:** This library is not affiliated with Nikon in any way, but we are
> grateful for assistance from the SDK developers at Laboratory Imaging.
Features good metadata retrieval, and direct `to_dask` and `to_xarray` options
for lazy and/or annotated arrays.
Features good metadata retrieval, direct `to_dask` and `to_xarray` options
for lazy and/or annotated arrays, and output to OME-TIFF.

This library is tested against many nd2 files with the goal of maximizing
compatibility and data extraction. (If you find an nd2 file that fails in some
Expand Down Expand Up @@ -101,6 +101,9 @@ f.to_dask() # delayed dask.array.Array
f.to_xarray() # in-memory xarray.DataArray, with labeled axes/coords
f.to_xarray(delayed=True) # delayed xarray.DataArray

# OME-TIFF OUTPUT (new in v0.10.0)
f.write_tiff('output.ome.tif') # write to ome-tiff file

# see below for examples of these structures
# METADATA # returns instance of ...
f.attributes # nd2.structures.Attributes
Expand Down
30 changes: 28 additions & 2 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,34 @@ ROIs, if present, can be accessed at [`ND2File.rois`][nd2.ND2File.rois].
If you're still looking for something that you don't see in the above
properties and methods, try looking through:

- [ND2File.custom_data][nd2.ND2File.custom_data]
- [ND2File.unstructured_metadata()][nd2.ND2File.unstructured_metadata]
- [`ND2File.custom_data`][nd2.ND2File.custom_data]
- [`ND2File.unstructured_metadata()`][nd2.ND2File.unstructured_metadata]

These methods parse and return more of the metadata found in the file,
but no attempt is made to extract it into a more useful form.

## Export nd2 to OME-TIFF

To convert an nd2 file to an OME-TIFF file, use [`nd2.ND2File.write_tiff`][] or
the convenience function `nd2.nd2_to_tiff`:

```python
import nd2


nd2.nd2_to_tiff('some_file.nd2', 'new_file.ome.tiff', progress=True)

# or with an ND2File object

with nd2.ND2File('some_file.nd2') as myfile:
myfile.write_tiff('my_file.ome.tiff', progress=True)
```

Note that if you simply want the OME metadata, you can use the
[`ome_metadata()`][nd2.ND2File.ome_metadata] method to retrieve an instance of
[`ome_types.OME`][]:

```python
with nd2.ND2File('some_file.nd2') as myfile:
ome_metadata = myfile.ome_metadata()
```
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ plugins:
- https://docs.python.org/3/objects.inv
- https://docs.xarray.dev/en/stable/objects.inv
- https://docs.dask.org/en/stable/objects.inv
- https://ome-types.readthedocs.io/en/latest/objects.inv

extra_css:
- styles/extra.css
28 changes: 14 additions & 14 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,38 +21,38 @@ classifiers = [
"Programming Language :: Python :: 3.12",
]
dynamic = ["version"]
dependencies = ["resource-backed-dask-array", "typing-extensions", "numpy"]
dependencies = [
"numpy",
"ome-types >=0.5.1",
"resource-backed-dask-array",
"typing-extensions",
]

[project.optional-dependencies]
legacy = ["imagecodecs"]
tiff = ["tifffile"]
test = [
"aicsimageio; python_version < '3.12'",
"nd2[legacy]",
"nd2[tiff]",
"aicsimageio",
"dask[array]",
"imagecodecs",
"lxml; python_version >= '3.9'",
"numpy >=1.26; python_version >= '3.12'",
"numpy; python_version < '3.12'",
"ome-types",
"numpy",
"psutil",
"pytest-codspeed",
"pytest-cov",
"pytest-pretty",
"pytest>=6.0",
"xarray; python_version < '3.12'",
"tifffile",
"xarray",
]
dev = [
"aicsimageio",
"dask[array]",
"imagecodecs",
"nd2[test]",
"ipython",
"mypy",
"pre-commit",
"psutil",
"pytest-cov",
"pytest",
"rich",
"ruff",
"xarray",
"types-lxml",
]
docs = ["mkdocs", "mkdocs-material", "mkdocstrings-python"]
Expand Down
18 changes: 16 additions & 2 deletions src/nd2/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
"""nd2: A Python library for reading and writing ND2 files."""

from importlib.metadata import PackageNotFoundError, version
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
# uses optional tifffile dependency
from .tiff import nd2_to_tiff # noqa: TCH004

try:
__version__ = version(__name__)
Expand All @@ -10,16 +15,17 @@
__author__ = "Talley Lambert"
__email__ = "[email protected]"
__all__ = [
"__version__",
"AXIS",
"BinaryLayer",
"BinaryLayers",
"imread",
"is_supported_file",
"is_legacy",
"is_supported_file",
"nd2_to_tiff",
"ND2File",
"rescue_nd2",
"structures",
"__version__",
]


Expand All @@ -28,3 +34,11 @@
from ._parse._chunk_decode import rescue_nd2
from ._util import AXIS, is_legacy, is_supported_file
from .nd2file import ND2File, imread


def __getattr__(name: str) -> Any:
if name == "nd2_to_tiff":
from .tiff import nd2_to_tiff

return nd2_to_tiff
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
Loading

0 comments on commit 7c3a64a

Please sign in to comment.