bioimage_py.io
Native file-format IO layer: array-like handles for hdf5, zarr, n5, mrc, nifti, msr, tif, knossos.
Indexing contract: the assemble-from-pieces wrappers (nifti, knossos, msr, image-stack) accept only
integer, slice (step 1), and ellipsis indices -- non-trivial steps (e.g. src[::2]) are rejected,
unlike numpy / zarr / mrc which support them. Index these formats with contiguous slices.
1"""Native file-format IO layer: array-like handles for hdf5, zarr, n5, mrc, nifti, msr, tif, knossos. 2 3Indexing contract: the assemble-from-pieces wrappers (nifti, knossos, msr, image-stack) accept only 4integer, slice (step 1), and ellipsis indices -- non-trivial steps (e.g. ``src[::2]``) are rejected, 5unlike numpy / zarr / mrc which support them. Index these formats with contiguous slices. 6""" 7from .files import infer_format, open_file 8from .registry import ( 9 constructor_for_format, 10 format_for_extension, 11 is_writable_format, 12 register_format, 13 supported_extensions, 14 supported_formats, 15) 16 17__all__ = [ 18 "open_file", 19 "infer_format", 20 "register_format", 21 "supported_extensions", 22 "supported_formats", 23 "format_for_extension", 24 "constructor_for_format", 25 "is_writable_format", 26]
58def open_file( 59 path: PathLike, 60 mode: str = "r", 61 ext: Optional[str] = None, 62 format: Optional[str] = None, 63 **kwargs: Any, 64) -> Any: 65 """Open a file as an array-like handle, dispatching on the (inferred) format. 66 67 Args: 68 path: Path to the file or folder to open. 69 mode: Mode in which to open the file. ``"r"`` (read) is supported by all formats; some 70 formats also support write modes (``"a"``, ``"w"``). 71 ext: Force a specific extension when it cannot be inferred from ``path``. 72 format: Force a specific (registered) format name, overriding extension inference. 73 kwargs: Extra keyword arguments forwarded to the backend constructor. 74 75 Returns: 76 A file handle (a mapping of datasets, or an array-like dataset). 77 """ 78 fmt = format if format is not None else infer_format(path, ext) 79 constructor = constructor_for_format(fmt) 80 return constructor(path, mode=mode, **kwargs)
Open a file as an array-like handle, dispatching on the (inferred) format.
Args:
path: Path to the file or folder to open.
mode: Mode in which to open the file. "r" (read) is supported by all formats; some
formats also support write modes ("a", "w").
ext: Force a specific extension when it cannot be inferred from path.
format: Force a specific (registered) format name, overriding extension inference.
kwargs: Extra keyword arguments forwarded to the backend constructor.
Returns: A file handle (a mapping of datasets, or an array-like dataset).
34def infer_format(path: PathLike, ext: Optional[str] = None) -> str: 35 """Infer the format name for a path (optionally with an explicit extension). 36 37 Args: 38 path: The path to open. 39 ext: An explicit extension to force, overriding inference from ``path``. 40 41 Returns: 42 The registered format name. 43 44 Raises: 45 ValueError: If no installed backend handles the (inferred) extension. 46 """ 47 ext = infer_extension(path) if ext is None else ext.lower() 48 fmt = format_for_extension(ext) 49 if fmt is None: 50 raise ValueError( 51 f"Could not infer a file format from extension {ext!r}; " 52 f"it is not among the supported extensions: {sorted(supported_extensions())}. " 53 "You may need to install an additional dependency (h5py, z5py, zarr, mrcfile, nibabel, ...)." 54 ) 55 return fmt
Infer the format name for a path (optionally with an explicit extension).
Args:
path: The path to open.
ext: An explicit extension to force, overriding inference from path.
Returns: The registered format name.
Raises: ValueError: If no installed backend handles the (inferred) extension.
17def register_format( 18 name: str, 19 extensions: Sequence[str], 20 constructor: Callable, 21 *, 22 writable: bool = False, 23) -> None: 24 """Register a file-format backend. 25 26 Args: 27 name: The format name, recorded in the source spec (e.g. ``"hdf5"``, ``"mrc"``). 28 extensions: The file extensions this format claims (lower-case; ``""`` for folders). 29 constructor: A callable ``(path, mode="r", **kwargs)`` returning an array-like file handle. 30 writable: Whether the format supports writing. 31 """ 32 _FORMAT_TO_CONSTRUCTOR[name] = constructor 33 _FORMAT_WRITABLE[name] = writable 34 for ext in extensions: 35 _EXT_TO_FORMAT.setdefault(ext.lower(), name)
Register a file-format backend.
Args:
name: The format name, recorded in the source spec (e.g. "hdf5", "mrc").
extensions: The file extensions this format claims (lower-case; "" for folders).
constructor: A callable (path, mode="r", **kwargs) returning an array-like file handle.
writable: Whether the format supports writing.
43def supported_extensions() -> List[str]: 44 """Return all file extensions for which a backend is installed.""" 45 return list(_EXT_TO_FORMAT.keys())
Return all file extensions for which a backend is installed.
38def supported_formats() -> List[str]: 39 """Return the names of all registered (i.e. installed) formats.""" 40 return list(_FORMAT_TO_CONSTRUCTOR.keys())
Return the names of all registered (i.e. installed) formats.
48def format_for_extension(ext: str) -> Optional[str]: 49 """Return the format name registered for ``ext``, or ``None``.""" 50 return _EXT_TO_FORMAT.get(ext.lower())
Return the format name registered for ext, or None.
53def constructor_for_format(name: str) -> Callable: 54 """Return the file constructor for a registered format, raising a clear error otherwise.""" 55 try: 56 return _FORMAT_TO_CONSTRUCTOR[name] 57 except KeyError: 58 raise ValueError( 59 f"Unknown or unavailable format {name!r}. Supported formats: {sorted(supported_formats())}. " 60 "You may need to install the corresponding optional dependency." 61 )
Return the file constructor for a registered format, raising a clear error otherwise.
64def is_writable_format(name: str) -> bool: 65 """Return whether a registered format supports writing.""" 66 return _FORMAT_WRITABLE.get(name, False)
Return whether a registered format supports writing.