sdcard

Data model for configuring an SD card. Will be instantiated in the constants module with specific values. This allows for the model to be reused across different miniscopes, and for consuming code to use a consistent, introspectable API

class mio.models.sdcard.ConfigPositions(*, width: int = 0, height: int = 1, fs: int = 2, buffer_size: int = 3, n_buffers_recorded: int = 4, n_buffers_dropped: int = 5)

Image acquisition configuration positions

buffer_size: int
fs: int
height: int
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

n_buffers_dropped: int
n_buffers_recorded: int
width: int
class mio.models.sdcard.SDBufferHeader(*, linked_list: int, frame_num: int, buffer_count: int, frame_buffer_count: int, write_buffer_count: int, dropped_buffer_count: int, timestamp: int, write_timestamp: int | None = None, length: int, data_length: int, battery_voltage: int | None = None)

Header data at the start of each frame

battery_voltage: int | None
data_length: int
dropped_buffer_count: int
length: int
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

write_buffer_count: int
write_timestamp: int | None
class mio.models.sdcard.SDBufferHeaderFormat(*, id: str = 'sd-buffer-header', mio_model: Annotated[str, AfterValidator(func=_is_identifier)] = None, mio_version: str = '0.10.1.dev6+g8c206e3', linked_list: int = 1, frame_num: int = 2, buffer_count: int = 3, frame_buffer_count: int = 4, write_buffer_count: int = 5, dropped_buffer_count: int = 6, timestamp: int = 7, write_timestamp: int | None = None, length: int = 0, data_length: int = 8, battery_voltage: int | None = None)

Positions in the header for each frame

battery_voltage: int | None
buffer_count: int
data_length: int
dropped_buffer_count: int
frame_buffer_count: int
frame_num: int
id: str
length: int
linked_list: int
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

timestamp: int
write_buffer_count: int
write_timestamp: int | None
class mio.models.sdcard.SDConfig(*, width: int, height: int, fs: int, buffer_size: int, n_buffers_recorded: int, n_buffers_dropped: int)

The configuration of a recording taken on this SD card.

Read from the locations given in ConfigPositions for an SD card with a given SDLayout

buffer_size: int
fs: int
height: int
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

n_buffers_dropped: int
n_buffers_recorded: int
width: int
class mio.models.sdcard.SDHeaderPositions(*, gain: int = 4, led: int = 5, ewl: int = 6, record_length: int = 7, fs: int = 8, delay_start: int | None = None, battery_cutoff: int | None = None)

Positions in the header for the whole SD card

battery_cutoff: int | None
delay_start: int | None
ewl: int
fs: int

Frame rate

gain: int
led: int
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

record_length: int
class mio.models.sdcard.SDLayout(*, id: Annotated[str, _PydanticGeneralMetadata(pattern='[\\w\\-\\/#]+')], mio_model: Annotated[str, AfterValidator(func=_is_identifier)] = None, mio_version: str = '0.10.1.dev6+g8c206e3', sectors: SectorConfig, write_key0: int = 226277911, write_key1: int = 226277911, write_key2: int = 226277911, write_key3: int = 226277911, word_size: int = 4, header: SDHeaderPositions = SDHeaderPositions(gain=4, led=5, ewl=6, record_length=7, fs=8, delay_start=None, battery_cutoff=None), config: ConfigPositions = ConfigPositions(width=0, height=1, fs=2, buffer_size=3, n_buffers_recorded=4, n_buffers_dropped=5), buffer: SDBufferHeaderFormat = SDBufferHeaderFormat(id='sd-buffer-header', mio_model='mio.models.sdcard.SDBufferHeaderFormat', mio_version='0.10.1.dev6+g8c206e3', linked_list=1, frame_num=2, buffer_count=3, frame_buffer_count=4, write_buffer_count=5, dropped_buffer_count=6, timestamp=7, write_timestamp=None, length=0, data_length=8, battery_voltage=None))

Data layout of an SD Card.

Used by the io.SDCard class to tell it how data on the SD card is laid out.

buffer: SDBufferHeaderFormat
config: ConfigPositions
header: SDHeaderPositions
model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

sectors: SectorConfig
word_size: int

I’m actually not sure what this is, but 4 is hardcoded a few times in the existing notebook and it appears to be used as a word size when reading from the SD card.

write_key0: int
write_key1: int
write_key2: int
write_key3: int

These don’t seem to actually be used in the existing reading/writing code, but we will leave them here for continuity’s sake :)

class mio.models.sdcard.SectorConfig(*, header: int = 1023, config: int = 1024, data: int = 1025, size: int = 512)

Configuration of sector layout on the SD card.

For each sector, one can retrieve the position with the attribute _pos,

Examples

>>> sectors = SectorConfig(header=1023, config=1024, data=1025, size=512)
>>> sectors.header
1023
>>> # should be 1023 * 512
>>> sectors.header_pos
523776
__getattr__(item: str) int

Get positions by multiplying by sector size (__getattr__ is only called if the name can’t be found, so we don’t need to handle the base case of the existing attributes)

config: int

Holds final settings of the actual recording

data: int

Recording data starts here

header: int

Holds user settings to configure Miniscope and recording

model_config = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

size: int

The size of an individual sector