diff --git a/docs/api/devices/wirefree.md b/docs/api/devices/wirefree.md new file mode 100644 index 00000000..e00b283a --- /dev/null +++ b/docs/api/devices/wirefree.md @@ -0,0 +1,7 @@ +# wirefree + +```{eval-rst} +.. automodule:: miniscope_io.devices.wirefree + :members: + :undoc-members: +``` \ No newline at end of file diff --git a/mio/devices/__init__.py b/mio/devices/__init__.py index 3887aad7..6afddbcd 100644 --- a/mio/devices/__init__.py +++ b/mio/devices/__init__.py @@ -2,8 +2,15 @@ Devices! """ -from miniscope_io.devices.camera import Camera, Miniscope -from miniscope_io.devices.device import Device +from miniscope_io.devices.camera import Camera, Miniscope, RecordingCameraMixin +from miniscope_io.devices.device import Device, DeviceConfig from miniscope_io.devices.wirefree import WireFreeMiniscope -__all__ = ["Camera", "Device", "Miniscope", "WireFreeMiniscope"] +__all__ = [ + "Camera", + "Device", + "DeviceConfig", + "Miniscope", + "RecordingCameraMixin", + "WireFreeMiniscope", +] diff --git a/mio/devices/camera.py b/mio/devices/camera.py index 33af53c4..7033f743 100644 --- a/mio/devices/camera.py +++ b/mio/devices/camera.py @@ -2,7 +2,7 @@ ABCs for Camera and Miniscope source classes """ -from abc import abstractmethod +from abc import ABC, abstractmethod from typing import Optional, Union from miniscope_io.devices.device import Device, DeviceConfig @@ -210,6 +210,47 @@ def roi(self, value: BBox) -> None: raise NotImplementedError("roi setter is not implemented") +class RecordingCameraMixin(ABC): + """ + A mixin for cameras that record their videos, rather than stream them, + like the :class:`.WireFreeMiniscope` + """ + + @property + @abstractmethod + def frame(self) -> int: + """ + When reading, the number of the frame that would be read if we were to call + :meth:`.read` + + Returns: + int: + """ + + @frame.setter + @abstractmethod + def frame(self, value: int) -> None: + """ + Seek to a specific frame + + Arguments: + frame (int): The frame to seek to! + """ + + @property + @abstractmethod + def frame_count(self) -> int: + """ + Total number of frames in recording. + """ + + @abstractmethod + def skip(self) -> None: + """ + Skip a frame + """ + + class MiniscopeConfig(CameraConfig): """Configuration of a miniscope""" diff --git a/mio/devices/wirefree.py b/mio/devices/wirefree.py index 0e6b3176..d072bc5f 100644 --- a/mio/devices/wirefree.py +++ b/mio/devices/wirefree.py @@ -11,14 +11,21 @@ from tqdm import tqdm from miniscope_io import init_logger +from miniscope_io.devices import DeviceConfig, Miniscope, RecordingCameraMixin from miniscope_io.exceptions import EndOfRecordingException, ReadHeaderException from miniscope_io.models.data import Frame from miniscope_io.models.sdcard import SDBufferHeader, SDConfig, SDLayout -class WireFreeMiniscope: +class WireFreeConfig(DeviceConfig): + """Configuration for wire free miniscope""" + + pass + + +class WireFreeMiniscope(Miniscope, RecordingCameraMixin): """ - I/O for data on an WireFreeMiniscope + I/O for data on an SD Card recorded with a WireFree Miniscope an instance of :class:`.sdcard.SDLayout` (typically in :mod:`.formats` ) configures how the data is laid out on the SD card. This class makes the i/o @@ -30,7 +37,13 @@ class WireFreeMiniscope: """ - def __init__(self, drive: Union[str, Path], layout: SDLayout): + drive: Path + """The path to the SD card drive""" + config: WireFreeConfig + """Configuration """ + # layout: + + def __post_init__(self, drive: Union[str, Path], layout: SDLayout): self.drive = drive self.layout = layout self.logger = init_logger("WireFreeMiniscope") diff --git a/mio/sources/file.py b/mio/sources/file.py new file mode 100644 index 00000000..b6a412ed --- /dev/null +++ b/mio/sources/file.py @@ -0,0 +1,34 @@ +""" +File-based data sources +""" + +from miniscope_io.models.pipeline import Source + + +class FileSource(Source): + """ + Generic parent class for file sources + """ + + +class BinaryLayout: + """Layout for binary files""" + + pass + + +class BinaryFileSource(FileSource): + """ + Structured binary file that has + + * a global header with config values + * a series of buffers, each containing a + + * buffer header - with metadata for that buffer and + * buffer data - the data for that buffer + + The source thus has two configurations + + * the ``config`` - getter and setter for the actual configuration values of the source + * the ``layout`` - how the configuration and data are laid out within the file. + """