bpod_core.bpod.threads.ReadThread

class bpod_core.bpod.threads.ReadThread

Bases: Thread

Serial reader thread for one Bpod trial.

Runs for the lifetime of a single trial. Reads the hardware confirmation, then enters a tight loop parsing the two-byte opcode packets the Bpod streams over serial:

  • Opcode 1 – hardware events: reads param event bytes followed by a 4-byte uInt32 cycle count. Timestamps are derived as start_micros_us + n_cycles * cycle_period_us and each event is pushed to queue_events as a RawEvent. An EXIT byte (255) triggers stop().

  • Opcode 2 – softcodes: the param byte (1-indexed) is forwarded to queue_softcodes.

Hot-loop optimisations:

  • Two fixed bytearray buffers (opcode_buf: 2 bytes, event_data_buf: 259 bytes) are allocated once before the loop. serial.readinto() writes directly into them — no per-packet allocation.

  • A memoryview over event_data_buf allows zero-copy slicing for both the variable-length event payload and the trailing cycle-count word.

  • struct.unpack_from() unpacks the cycle count in-place from the memoryview without creating an intermediate bytes object.

  • Frequently accessed instance attributes (serial, queues, cycle_period_us) are cached as locals before the loop to avoid repeated LOAD_ATTR bytecode overhead.

After the loop, the thread reads the 12-byte end-of-trial packet (uInt32 cycle count + uInt64 µs timestamp, unpacked via _struct_exit) and enqueues END_FSM_CYCLES and END_FSM_MICROS. A STOP_SENTINEL is always enqueued in finally so EventThread can detect termination regardless of how the trial ended.

__init__(*, serial, state_machine_hash, trial, cycle_period_us, queue_events, queue_softcodes) None

Initialize the ReadThread.

Parameters:
  • serial (ExtendedSerial) – The serial connection to the Bpod device.

  • state_machine_hash (bytes) – The hash of the state machine.

  • trial (int) – Zero-based trial index.

  • cycle_period_us (int) – The cycle period of the Bpod device in microseconds.

  • queue_events (SimpleQueue[RawEvent]) – Queue for storing events.

  • queue_softcodes (SimpleQueue[RawSoftcode]) – Queue for storing softcodes.

Return type:

None

run() None

Execute the ReadThread.

Return type:

None

stop() None

Signal the FSM thread to stop after the current state cycle.

Return type:

None

property trial_number: int

The zero-based trial number.