1. Build an ImagingExtractor:#
To build your custom ImagingExtractor to interface with a new raw image storage format from your microscope, build a custom class inheriting from a base class that enforces certain methods that need to be defined:
get_num_samples(): the number of image frames recordedget_image_shape(): the y,x dimensions of a single frameget_series(): return a continuous slice of imaging data
Additionally, if your format stores hardware timestamps, you should override:
get_native_timestamps(): return the format’s native timestamps, orNoneif unavailable (see Timestamp Handling for details)
from roiextractors import ImagingExtractor
class MyFormatImagingExtractor(ImagingExtractor):
def __init__(self, file_path, sampling_frequency: float = None):
ImagingExtractor.__init__(self)
## All file specific initialization code can go here.
self.sampling_frequency = sampling_frequency or # define your own method of extraction
self._data = self._load_data() # groups is a list or a np.array with length num_channels
def _load_data(self):
# define a function that retrieves an in memory array from your native imaging format
# returns: np.ndarray (shape: frames, image_dims)
def get_num_samples(self) -> int:
# Fill code to get the number of frames (samples) in the recordings.
# Note that if the data is volumetric, num_samples corresponds to the number of volumes, not the number of 2D images.
return num_samples
def get_sampling_frequency(self) -> float:
return self.sampling_frequency
def get_series(self, start_sample: int | None = None, end_sample: int | None = None) -> NumpyArray:
# define a method to read a continuous slice of imaging data
return self._data[start_sample:end_sample]
def get_image_shape(self) -> tuple[int, int]:
# returns the (height, width) dimensions of a single frame
# this is the abstract method that must be implemented
return self._data.shape[1:]
def get_native_timestamps(self, start_sample=None, end_sample=None):
# Optional: override this if your format has hardware timestamps.
# Return None (the default) if it does not.
timestamps = self._read_timestamps_from_file()
start = start_sample or 0
end = end_sample or len(timestamps)
return timestamps[start:end]