stimulus_base#
Base class for stimulus devices that launch an external app subprocess.
Captures the lifecycle shared by every “launch an external stimulus program,
wait for a stdout readiness handshake, terminate on stop” device (MousePortal
today; PsychoPy is a candidate to adopt this later). Subclasses implement a few
hooks; the base wires the mesofield device contract
(StimulusDevice): DeviceSignals,
initialize/arm/start/stop/shutdown, status/metadata, and a
GUI-safe readiness wait.
A stimulus device is not a DataProducer: it
never emits on signals.data. signals.started fires on the readiness
handshake; signals.finished fires on stop or subprocess exit.
Required subclass surface#
ready_token(class attr) – stdout substring the child prints when ready.build_command()– the argv to launch.
Optional hooks#
launch_phase(class attr,"arm"or"start") – when to launch."arm"guarantees the stimulus is up before recording starts, since a Procedure runs allarm_allbeforestart_all.prepare()– per-run prep (generate config, open side channels) before launch.preflight()– return an error string to abort launch with a clear message.launch_cwd()/launch_env()– subprocess working dir / environment.on_stop()– teardown of any side channels opened inprepare().require_ready(class attr) – treat a missing readiness handshake as a failure even if the child is still alive (PsychoPy); default False.enabled(instance attr) – per-run gate; a Procedure may set it False to record a stimulus-free task.
Operator presentation hooks (no-op/log by default, so automatic stimuli are
unaffected; a GUI subclass overrides them to drive modal dialogs):
present_launching() / dismiss_launching(), present_failure(),
and confirm_ready_to_record() (the post-readiness “press to record” gate).
- class mesofield.devices.stimulus_base.SubprocessStimulusDevice[source]#
Bases:
objectLifecycle skeleton for subprocess-backed stimulus devices.
- serves_task(task, config)[source]#
Whether this stimulus participates in task.
Drives per-run gating: before arming, a Procedure enables only the stimulus device(s) that serve the selected task (see
Procedure._gate_stimuli_by_task), so a rig with several stimulus apps launches only what the task needs. The default serves every task – correct for a single-stimulus rig or a device with no task binding. Subclasses that bind to specific tasks override this.
- prepare(config)[source]#
Per-run prep before launch (config files, side channels). No-op.
- Parameters:
config (Any)
- Return type:
None
- preflight()[source]#
Return an actionable error string to abort launch, or None to proceed.
- Return type:
str | None
- present_launching()[source]#
Show a non-blocking ‘launching, waiting for readiness’ indicator.
Called right after the subprocess is spawned and before the readiness wait (which pumps Qt events, so a shown-but-not-
exec’d dialog stays responsive). Pair withdismiss_launching(). No-op by default.- Return type:
None
- dismiss_launching()[source]#
Dismiss the indicator shown by
present_launching(). No-op default.- Return type:
None
- present_failure(message, detail='')[source]#
Surface a launch/handshake failure to the operator.
detailcarries the child’s last output (seeSubprocessSupervisor.output_tail). Logs by default; a GUI subclass shows a dialog.
- confirm_ready_to_record()[source]#
Operator gate after the stimulus reports ready;
Falsecancels.Runs inside
start()forlaunch_phase == "start"devices once the readiness handshake has fired. Default proceeds immediately (automatic stimuli); PsychoPy shows a focused “press to start recording” dialog over its full-screen window.- Return type: