mouseportal#

MousePortal corridor loader.

Aligns the MousePortal per-frame CSV (*_mouseportal.csv) to the camera timeline using the treadmill microsecond clock as the shared master.

MousePortal logs the treadmill device_us of the most recent forwarded sample on every frame. The same device_us values are recorded in the central *_dataqueue.csv (fanned out into a device_us column for the treadmill device, alongside queue_elapsed). We fit an affine map device_us -> queue_elapsed from those dataqueue rows, apply it to each corridor frame, and shift onto the experiment window so corridor position / gain condition land on the same clock as the widefield + pupil frames.

This mirrors the dataqueue alignment strategy of mesofield.datakit.sources.behavior.treadmill.TreadmillSource, but reads the treadmill’s device_us column rather than parsing EncoderData(...) payload strings – the producer pushes a dict payload, so the queue logger stores its fields as columns.

class mesofield.datakit.sources.behavior.mouseportal.MousePortalSource[source]#

Bases: TimeseriesSource

Load MousePortal corridor frames aligned to the experiment window.

requires: ClassVar[Tuple[str, ...]] = ('dataqueue',)#

Tag names of upstream sources whose loaded streams should be made available via LoadContext.dependencies. Soft contract: a missing or failed dependency yields None in dependencies[tag]; sources are responsible for either degrading gracefully or raising.

build_timeseries(path, *, context=None)[source]#

Return (timeline, value, meta).

Parameters:
Return type:

tuple[ndarray, DataFrame, dict]

class mesofield.datakit.sources.behavior.mouseportal.MousePortalTrials[source]#

Bases: IntervalSeriesSource

Per-trial intervals from the MousePortal log, on the camera clock.

Collapses the per-frame state == "TRIAL_RUNNING" runs into one row per (block, trial) with start_s/stop_s already aligned to the master (camera) timeline via MousePortalSource. This makes event-triggered analyses trivial: each row’s start_s is a trial onset on the same clock as the widefield/pupil frames, so a peri-event window is a direct time slice (see mesofield.datakit.epoch.event_triggered_average).

Emits the inter-trial intervals too (phase column: trial | iti) so stops/ITIs are available as events as well.

requires: ClassVar[Tuple[str, ...]] = ('dataqueue',)#

Tag names of upstream sources whose loaded streams should be made available via LoadContext.dependencies. Soft contract: a missing or failed dependency yields None in dependencies[tag]; sources are responsible for either degrading gracefully or raising.

build_intervals(path, *, context=None)[source]#

Return an intervals table with start/stop columns and meta.

Parameters:
Return type:

tuple[DataFrame, dict]