base#
Authorable base classes for non-Qt hardware devices.
Layered hierarchy that lets a user write a new device with as little boilerplate as possible:
BaseDeviceLifecycle skeleton,
self.signals(DeviceSignals), logger, cfg storage,is_primary/is_runningtracking, defaultstatus/metadata.BaseDataProducer(BaseDevice)Adds the DataProducer surface:
output_path/metadata_path, a thread-safe in-memory buffer, arecord(payload, ts=None)helper that timestamps + buffers + emitssignals.datain one call, and a default CSVsave_data/get_data.BaseSerialDevice(BaseDataProducer)Specialization for line-oriented serial protocols (Teensy / Arduino). Owns its own daemon read thread; subclasses only need to override
parse_line(line). Adevelopment_modeflag skips opening the port so authors can iterate without hardware connected.
Qt devices (QThread subclasses) cannot inherit from these due to
metaclass conflicts; they continue to duck-type the contract by
instantiating self.signals = DeviceSignals() directly.
- class mesofield.devices.base.BaseDevice[source]#
Bases:
objectDefault lifecycle skeleton for non-Qt hardware devices.
Constructor accepts an optional
cfgmapping (the YAML stanza for this device). Common keys are auto-extracted:id/device_id->self.device_idprimary: true->self.is_primary
A logger is created automatically as
f"{module}.{class}[{device_id}]".- arm(config)[source]#
Per-run preparation. No-op by default.
- Parameters:
config (ExperimentConfig)
- Return type:
None
- property calibration: Dict[str, Any]#
Device-specific constants worth recording with the data.
Default: everything in cfg that isn’t an orchestration key. Override on a subclass to curate the list explicitly.
- sidecars()[source]#
Auxiliary files this device writes alongside its primary output.
Default: none. Override to declare extra sidecars (masks, regions, derived parameter files) so they ride in the manifest with a role and schema_version instead of being discovered by glob.
The camera classes’ per-frame metadata JSON is the primary sidecar and lives on self.metadata_path – not here. Use this method for the extra files only.
Returns a list of mesokit_schema.SidecarEntry-shaped mappings or instances. The Procedure relativises any absolute paths.
- Return type:
- class mesofield.devices.base.BaseDataProducer[source]#
Bases:
BaseDeviceBase class for devices that stream samples to the DataQueue.
Subclasses produce data by calling
record(), which timestamps, appends to an in-memory buffer, and emitssignals.data(payload, ts)in one step.The default
save_data()writes the buffer as a two-column CSV (timestamp,payload). Override for binary or domain-specific formats.- arm(config)[source]#
Default
arm: clear buffer and resolveoutput_path.configis expected to exposemake_path(name, ext, bids)(seemesofield.config.ExperimentConfig).- Parameters:
config (ExperimentConfig)
- Return type:
None
- class mesofield.devices.base.BaseSerialDevice[source]#
Bases:
BaseDataProducerPolling device for line-based serial protocols (Arduino/Teensy/etc.).
Subclasses override
parse_line(). Optionally overridesetup_serial()for post-open initialisation (handshakes, buffer drain, configuring device-side parameters).Configuration keys read from
cfg:port(str, required whendevelopment_mode=False)baudrate(int, default 115200)timeout(float, default 0.1) — pyserial readline timeout.dtr(bool | None, default None) — set toFalseto suppress Arduino auto-reset on connect.Nonekeeps the OS default.connect_delay(float, default 0.0) — seconds to wait after opening the port before reads begin; common Arduinos need ~2.0. The input buffer is flushed after the delay.development_mode(bool, default False) — skip opening the port so the GUI / Procedure can launch without hardware.send_linebecomes a no-op; the polling thread idles.
- setup_serial()[source]#
Hook called once after the port is opened. Default no-op.
Override to send a handshake, query firmware version, configure device-side parameters, etc.
- Return type:
None
- send_line(payload, *, newline=b'\n')[source]#
Write a command to the device. Thread-safe with the reader.
Accepts
str(UTF-8 encoded) orbytes.newlineis appended unlesspayloadalready ends with it. Indevelopment_modethe bytes are logged and discarded. Returns the bytes that were written (or would have been).