Source code for roiextractors.extractors.tiffimagingextractors.tiffimagingextractor

"""A TIFF imaging extractor for TIFF files.

Classes
-------
TiffImagingExtractor
    A TIFF imaging extractor for TIFF files.
"""

from pathlib import Path
from warnings import warn

import numpy as np

from ...extraction_tools import (
    PathType,
    get_package,
    raise_multi_channel_or_depth_not_implemented,
)
from ...imagingextractor import ImagingExtractor


[docs] class TiffImagingExtractor(ImagingExtractor): """A ImagingExtractor for TIFF files.""" extractor_name = "TiffImaging" mode = "file" def __init__(self, file_path: PathType, sampling_frequency: float): """Create a TiffImagingExtractor instance from a TIFF file. Parameters ---------- file_path : PathType Path to the TIFF file. sampling_frequency : float The frequency at which the frames were sampled, in Hz. """ tifffile = get_package(package_name="tifffile") super().__init__() self.file_path = Path(file_path) self._sampling_frequency = sampling_frequency if self.file_path.suffix not in [".tiff", ".tif", ".TIFF", ".TIF"]: warn( "File suffix ({self.file_path.suffix}) is not one of .tiff, .tif, .TIFF, or .TIF! " "The TiffImagingExtractor may not be appropriate." ) with tifffile.TiffFile(self.file_path) as tif: self._num_channels = len(tif.series) try: self._video = tifffile.memmap(self.file_path, mode="r") except Exception as e: try: with tifffile.TiffFile(self.file_path) as tif: self._video = tif.asarray() warn( f"memmap of TIFF file could not be established due to the following error: {e}. " "Reading entire matrix into memory. Consider using the ScanImageTiffSinglePlaneImagingExtractor or ScanImageTiffMultiPlaneImagingExtractor for lazy data access.", stacklevel=2, ) except Exception as e2: raise RuntimeError( f"Memory mapping failed: {e}. \n" f"Attempt to read the TIFF file directly also failed: {e2}. \n" f"Consider using ScanImageTiffSinglePlaneImagingExtractor or ScanImageTiffMultiPlaneImagingExtractor for lazy data access, check the file integrity. \n" f"If problems persist, please report an issue at roiextractors/issues." ) shape = self._video.shape if len(shape) == 3: self._num_samples, self._num_rows, self._num_columns = shape self._num_channels = 1 else: raise_multi_channel_or_depth_not_implemented(extractor_name=self.extractor_name) self._kwargs = { "file_path": str(Path(file_path).absolute()), "sampling_frequency": sampling_frequency, }
[docs] def get_series(self, start_sample=None, end_sample=None) -> np.ndarray: return self._video[start_sample:end_sample, ...]
[docs] def get_image_shape(self) -> tuple[int, int]: """Get the shape of the video frame (num_rows, num_columns). Returns ------- image_shape: tuple Shape of the video frame (num_rows, num_columns). """ return (self._num_rows, self._num_columns)
[docs] def get_num_samples(self): return self._num_samples
[docs] def get_sampling_frequency(self): return self._sampling_frequency
[docs] def get_channel_names(self) -> list: """Return the channel names (deprecated).""" warn( "get_channel_names is deprecated and will be removed in or after October 2026.", FutureWarning, stacklevel=2, ) return [f"channel_{i}" for i in range(self._num_channels)]
[docs] def get_native_timestamps( self, start_sample: int | None = None, end_sample: int | None = None ) -> np.ndarray | None: # Basic TIFF files do not have native timestamps return None