mne_rt.protocols.OperantProtocol#
- class mne_rt.protocols.OperantProtocol(base_protocol: Any, schedule: str = 'FR', ratio: int = 5, interval: float = 30.0, rng_seed: int | None = None)#
Bases:
objectOperant conditioning reinforcement-schedule wrapper.
Wraps any inner NF protocol and applies a classical operant conditioning schedule to determine whether a reward is actually delivered. The inner protocol is always evaluated so that its internal state (running statistics, adaptive threshold, etc.) advances correctly; the schedule only decides whether to pass the reward through to the caller.
Supported schedules
"FR"(Fixed Ratio)Deliver reward on every
ratio-th hit (hit = inner protocol returnedcrossed=True)."VR"(Variable Ratio)Deliver reward with probability
1 / ratioon each hit (geometric distribution; same average number of hits per reward as FR)."FI"(Fixed Interval)Deliver reward for the first hit that occurs after
intervalseconds have elapsed since the last reward."VI"(Variable Interval)Deliver reward for the first hit that occurs after a random interval sampled from an exponential distribution with mean
intervalseconds.
- Parameters:
- base_protocol
anyprotocolwithevaluate(value) -> (bool,float) The inner NF protocol whose output is filtered by the schedule.
- schedule{“FR”, “VR”, “FI”, “VI”}
Reinforcement schedule identifier.
- ratio
int Required for
"FR"and"VR"schedules. For FR: reward is delivered on everyratio-th hit. For VR: reward probability per hit is1 / ratio. Must be >= 1. Default is 5.- interval
float Required for
"FI"and"VI"schedules, in seconds. For FI: minimum fixed interval between rewards. For VI: mean interval (exponential distribution). Must be > 0. Default is 30.0.- rng_seed
int|None Seed for the NumPy random generator used by
"VR"and"VI"schedules. Default is None (non-deterministic).
- base_protocol
- Raises:
ValueErrorIf
scheduleis not one of the valid identifiers,ratio < 1, orinterval <= 0.
Notes
The internal clock is started on the first call to
evaluate()usingtime.monotonic(), not at construction time. This avoids artificially burning interval time between object creation and the start of the session.reset()resets all internal counters, hit/reward tallies, and the clock. It also callsbase_protocol.reset()if that method exists.Examples
Fixed-ratio schedule (reward every 5th hit):
from mne_rt.protocols import ZScoreProtocol from mne_rt.protocols.operant import OperantProtocol inner = ZScoreProtocol(direction="up") proto = OperantProtocol(inner, schedule="FR", ratio=5) for value in nf_stream: crossed, magnitude = proto.evaluate(value) if crossed: deliver_reward(magnitude)
Variable-interval schedule (reward at most once per ~30 s on average):
proto = OperantProtocol(inner, schedule="VI", interval=30.0, rng_seed=0)
Added in version 1.0.0.
- __init__(base_protocol: Any, schedule: str = 'FR', ratio: int = 5, interval: float = 30.0, rng_seed: int | None = None) None[source]#
Methods
__init__(base_protocol[, schedule, ratio, ...])evaluate(value)Evaluate one NF value and apply the reinforcement schedule.
reset()Reset all internal state including counters and the clock.
Attributes
Pass-through threshold from the base protocol, if available.
Total hits (crossed=True from base protocol) since init or reset.
Total rewards delivered by the schedule since init or reset.
Fraction of hits that resulted in a reward (0–1).
- property current_threshold: float | None#
Pass-through threshold from the base protocol, if available.
Returns None if the base protocol does not expose a
thresholdattribute.
- evaluate(value: float) tuple[bool, float][source]#
Evaluate one NF value and apply the reinforcement schedule.
Delegates to the inner protocol unconditionally, then applies the schedule logic to decide whether to pass the reward through.
- Parameters:
- value
float Current NF feature value.
- value
- Returns:
Notes
For interval schedules (
"FI","VI") the clock is initialised on the first call.