Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
61 changes: 41 additions & 20 deletions bioio_ome_tiled_tiff/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@
import dask.array as da
import xarray as xr
from bfio import BioReader
from bioio_base import constants, dimensions, exceptions, io, reader, transforms, types
from bioio_base import (
constants,
dimensions,
exceptions,
io,
reader,
transforms,
types,
)
from fsspec.implementations.local import LocalFileSystem
from fsspec.spec import AbstractFileSystem
from ome_types import OME
from tifffile.tifffile import TiffFileError, TiffTags
from tifffile import TiffFileError, TiffTags

from . import utils

Expand All @@ -32,22 +40,24 @@ class Reader(reader.Reader):
chunk_dims: List[str]
Which dimensions to create chunks for.
Default: DEFAULT_CHUNK_DIMS
Note: Dimensions.SpatialY, and Dimensions.SpatialX will always be added to the
list if not present during dask array construction.
Note: Dimensions.SpatialY, and Dimensions.SpatialX will always be
added to the list if not present during dask array construction.
out_order: List[str]
The output dimension ordering.
Default: DEFAULT_DIMENSION_ORDER
fs_kwargs: Dict[str, Any]
Any specific keyword arguments to pass down to the fsspec created filesystem.
Any specific keyword arguments to pass down to the fsspec created
filesystem.
Default: {}

Notes
-----
If the OME metadata in your file isn't OME schema compliant or does not validate
this will fail to read your file and raise an exception.
If the OME metadata in your file isn't OME schema compliant or does not
validate this will fail to read your file and raise an exception.

If the OME metadata in your file doesn't use the latest OME schema (2016-06),
this reader will make a request to the referenced remote OME schema to validate.
If the OME metadata in your file doesn't use the latest OME schema
(2016-06), this reader will make a request to the referenced remote OME
schema to validate.
"""

_xarray_dask_data: Optional["xr.DataArray"] = None
Expand All @@ -59,7 +69,8 @@ class Reader(reader.Reader):
_scenes: Optional[Tuple[str, ...]] = None
_current_scene_index: int = 0
# Do not provide default value because
# they may not need to be used by your reader (i.e. input param is an array)
# they may not need to be used by your reader
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this comment actually saying? Wouldn't defaults be overwritten by new params regardless?

# (i.e. input param is an array)
_fs: "AbstractFileSystem"
_path: str

Expand All @@ -76,8 +87,8 @@ def _is_supported_image(fs: AbstractFileSystem, path: str, **kwargs: Any) -> boo
if len(br.metadata.images) > 1:
raise exceptions.UnsupportedFileFormatError(
path,
"This file contains more than one scene and only the first "
+ "scene can be read by the OmeTiledTiffReader. "
"This file contains more than one scene and only the "
+ "first scene can be read by the OmeTiledTiffReader. "
+ "To read additional scenes, use the TiffReader, "
+ "OmeTiffReader, or BioformatsReader.",
)
Expand Down Expand Up @@ -106,11 +117,18 @@ def __init__(
if not isinstance(self._fs, LocalFileSystem):
raise ValueError(
"Cannot read .ome.tif from non-local file system. "
f"Received URI: {self._path}, which points to {type(self._fs)}."
f"Received URI: {self._path}, which points to {type(self._fs)}"
)

try:
self._rdr = BioReader(self._path, backend="python")
# limit reader to only tiled images
if self._rdr._backend_name != "python":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the python backend is the one that supports tiled reading? does it support other things that have changed? Essentially Im asking is this restriction exact?

Copy link
Contributor Author

@kmitcham kmitcham Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The python backend is the one that does tiled reading. I don't know what it does allow, but it blocks lif and ome.tiff

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might opt to try for a tighter assessment here. Do I know that's possible? No

# while bfio supports other formats, bio has specialized
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like this comment would be useful to the user

# readers for them which should be used instead.
raise exceptions.UnsupportedFileFormatError(
self.__class__.__name__, self._path
)
except (TypeError, ValueError, TiffFileError):
raise exceptions.UnsupportedFileFormatError(
self.__class__.__name__, self._path
Expand All @@ -127,9 +145,7 @@ def __init__(

# Currently do not support custom chunking, throw a warning.
if chunk_dims is not None:
log.warning(
"OmeTiledTiffReader does not currently support custom chunking."
)
log.warning("OmeTiledTiffReader does not currently support custom chunking")

@property
def scenes(self) -> Tuple[str, ...]:
Expand Down Expand Up @@ -158,10 +174,15 @@ def _read_delayed(self) -> xr.DataArray:
)

def _tiff_tags(self) -> Optional[Dict[str, str]]:
return {
code: tag.value
for code, tag in self._rdr._backend._rdr.pages[0].tags.items()
}
try:
tag_dict = {
str(tag.code): str(tag.value)
for tag in self._rdr._backend._rdr.pages[0].tags
}
return tag_dict
except (AttributeError, IndexError, KeyError, TiffFileError, TypeError) as e:
log.warning(f"Could not extract TIFF tags: {e}; no tags.")
return None

def _read_immediate(self) -> xr.DataArray:
return self._general_data_array_constructor(
Expand Down
9 changes: 5 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,14 @@ classifiers = [
]
dynamic = ["version"]
dependencies = [
"bfio==2.3.0",
"bfio",
"bioio-base>=0.2.0",
"dask[array]>=2021.4.1",
"dask[array]",
"fsspec>=2022.8.0",
"numpy>=1.21",
"ome-types[lxml]>=0.4.0",
"tifffile>=2021.8.30,<2022.4.22",
"tifffile[zarr]>=2022.4.22,<2025.1.10; python_version < '3.11'",
"tifffile[zarr]>=2025.5.21; python_version >= '3.11'",
"xarray>=0.16.1",
"xmlschema", # no pin because it's pulled in from OME types
]
Expand Down Expand Up @@ -115,4 +116,4 @@ ignore = "E203,E402,W291,W503"
min-python-version = "3.10.0"
per-file-ignores = [
"__init__.py:F401",
]
]