mne_rt.RTEpochs#
- class mne_rt.RTEpochs(event_id: dict[str, int], event_channels: str | list[str], tmin: float = -0.2, tmax: float = 0.8, baseline: tuple | None = (None, 0), picks: str | list | None = None, reject: dict | None = None, bufsize: int = 200, on_trial: Callable | None = None, verbose: bool | str | None = None)[source]#
Bases:
objectEvent-triggered epoch accumulator backed by
mne_lsl.stream.EpochsStream.Connects a
StreamLSLto anEpochsStream, polls for new epochs, and optionally drives anTopoPlotthat redraws after every new trial.- Parameters:
- event_id
dict[str,int] Condition label → marker integer, e.g.
{"target": 1, "standard": 2}.- event_channels
strorlistofstr Channel(s) carrying the event codes. Without an event stream these must be
"stim"-type channels of the M/EEG stream itself (e.g."STI 014"). Whenconnect_to_lsl()is given an event stream they name channels of that stream instead – see its Notes.- tmin
float, default -0.2 Epoch start in seconds relative to the event.
- tmax
float, default 0.8 Epoch end in seconds relative to the event.
- baseline
tupleorNone, default (None, 0) Baseline interval passed to
EpochsStream.Nonedisables correction.- picks
strorlistorNone, defaultNone Channel selection forwarded to
EpochsStream.- reject
dictorNone, defaultNone Peak-to-peak rejection thresholds, e.g.
{"eeg": 150e-6}.- bufsize
int, default 200 Number of epochs to keep in the
EpochsStreaminternal ring buffer.- on_trial
callable()orNone, defaultNone Optional callback fired after every accepted epoch:
def on_trial(n_accepted, data, event_code, condition): ...
datais the single accepted epoch,(n_channels, n_times);event_codeis its integer marker andconditionthe matchingevent_idlabel.- verbosebool or
strorNone, defaultNone
- event_id
- Attributes:
- epochs_stream_
mne_lsl.stream.EpochsStreamorNone The underlying
EpochsStreamafterconnect_to_lsl()has been called.- event_stream_
mne_lsl.stream.StreamLSLorNone The separate marker stream, when
connect_to_lsl()was asked for one.Nonewhen the events come from a stim channel of the M/EEG stream.- n_accepted_
int Running count of accepted epochs since
run()started.
- epochs_stream_
See also
mne_rt.viz.TopoPlotLive scalp-layout ERP display driven by this class.
mne_rt.viz.EpochPlotScrolling raw viewer with trigger/epoch overlays.
mne_rt.RTStreamContinuous sliding-window stream processor.
Examples
>>> rt = RTEpochs( ... event_id={"auditory": 1, "visual": 2}, ... event_channels="STI 014", ... tmin=-0.2, tmax=0.5, ... ) >>> rt.connect_to_lsl(mock_lsl=True, fname="sample_raw.fif") >>> rt.run(n_trials=20, show_erp=True)
Added in version 1.0.0.
- __init__(event_id: dict[str, int], event_channels: str | list[str], tmin: float = -0.2, tmax: float = 0.8, baseline: tuple | None = (None, 0), picks: str | list | None = None, reject: dict | None = None, bufsize: int = 200, on_trial: Callable | None = None, verbose: bool | str | None = None) None[source]#
Methods
__init__(event_id, event_channels[, tmin, ...])connect_to_lsl([stream_name, mock_lsl, ...])Connect to an LSL stream and set up the EpochsStream.
Disconnect EpochsStream, both StreamLSLs, and stop any mock player.
Return accumulated epochs as
mne.EpochsArray.Return per-condition grand-average as
mne.EvokedArrayobjects.get_source(inverse_operator[, lambda2, method])Apply a pre-computed inverse operator to the current grand averages.
run([n_trials, show_erp, erp_update_every, ...])Run the epoch accumulation loop.
save(path[, overwrite])Save accumulated epochs to a
-epo.fiffile mid-run.stop()Signal the run loop to stop after the current poll.
- connect_to_lsl(stream_name: str | None = None, mock_lsl: bool = False, fname: str | None = None, timeout: float = 10.0, event_stream_name: str | None = None, event_source_id: str | None = None, event_stream_bufsize: int = 200, processing_flags: str | Sequence[str] | None = None, verbose: bool | str | None = None) RTEpochs[source]#
Connect to an LSL stream and set up the EpochsStream.
- Parameters:
- stream_name
strorNone LSL stream name.
Nonepicks the first available stream.- mock_lslbool
Replay
fnameviaPlayerLSL.- fname
strorNone Path to a
.fiffile (required whenmock_lsl=True).- timeout
float LSL connection timeout in seconds.
- event_stream_name
strorNone, defaultNone Name of a separate LSL stream carrying the event codes – the marker outlet of a PsychoPy paradigm, for instance. Leaving both this and
event_source_idasNonekeeps the events on a stim channel of the M/EEG stream itself, which is the behaviour of earlier versions.- event_source_id
strorNone, defaultNone Source ID of the event stream. May be given instead of, or together with,
event_stream_name; the two must together identify exactly one stream.- event_stream_bufsize
int, default 200 Event-stream buffer size in samples. A marker outlet is irregularly sampled, so a duration would carry no meaning.
- processing_flags
stror sequenceofstrorNone, defaultNone Forwarded to
mne_lsl.stream.StreamLSL.connect()for every stream opened here.Noneselects"all"when an event stream is requested, and no flags otherwise – see Notes.- verbosebool or
strorNone
- stream_name
- Returns:
- self
RTEpochs
- self
Notes
Clock synchronisation. Two LSL streams share a time base only once their clocks are synchronised, so when an event stream is requested both streams are connected with
processing_flags="all"(clocksync,dejitter,monotize). Without it, markers published from a second machine sit at an arbitrary offset from the M/EEG data and every epoch is cut in the wrong place, silently. Passprocessing_flagsexplicitly to override.Publishing the markers. The outlet must satisfy three constraints, each of which otherwise fails confusingly or not at all:
it must be numeric. mne-lsl refuses string streams outright, and
channel_format="string"is what most PsychoPy marker examples use – publish"int32"instead;it should label its channel, since an outlet that does not is exposed as
"0","1", … andevent_channelshas to match;the codes must be positive integers no greater than 32767, matching the values of
event_id.
A minimal publisher, which doubles as the reference for the paradigm side:
from mne_lsl.lsl import StreamInfo, StreamOutlet sinfo = StreamInfo( "psychopy_markers", "Markers", 1, 0.0, "int32", "psychopy_uid" ) sinfo.set_channel_names(["markers"]) outlet = StreamOutlet(sinfo) outlet.push_sample([1]) # a "go" trial
Examples
Events from a stim channel of the M/EEG stream itself:
rt = RTEpochs(event_id={"target": 1}, event_channels="STI 014") rt.connect_to_lsl(mock_lsl=True, fname="sample_raw.fif")
Events from a PsychoPy marker outlet:
rt = RTEpochs(event_id={"go": 1, "stop": 2}, event_channels="markers") rt.connect_to_lsl( stream_name="ANT", event_stream_name="psychopy_markers" )
- run(n_trials: int = 100, show_erp: bool = False, erp_update_every: int = 1, poll_interval: float = 0.05, verbose: bool | str | None = None) RTEpochs[source]#
Run the epoch accumulation loop.
Polls
n_new_epochsand retrieves data in batches. Blocks untiln_trialsaccepted epochs have been collected orstop()is called.- Parameters:
- n_trials
int, default 100 Stop after this many accepted epochs.
- show_erpbool, default
False Open an
TopoPlotthat redraws everyerp_update_everyaccepted epochs.- erp_update_every
int, default 1 ERP redraw cadence in number of accepted epochs.
- poll_interval
float, default 0.05 Seconds to sleep between polling
n_new_epochs.- verbosebool or
strorNone
- n_trials
- Returns:
- self
RTEpochs
- self
- get_epochs() EpochsArray[source]#
Return accumulated epochs as
mne.EpochsArray.Can be called mid-run or after
run()completes. The returned object contains all epochs accepted so far and uses the realmne.Infofrom the underlying stream (including channel positions and digitisation points).- Returns:
- epochs
mne.EpochsArray Shape
(n_accepted, n_channels, n_times).
- epochs
- Raises:
RuntimeErrorIf called before
connect_to_lsl().
Examples
>>> rt.run(n_trials=50, show_erp=True) >>> epochs = rt.get_epochs() >>> epochs.plot_image()
- get_evoked() dict[str, EvokedArray][source]#
Return per-condition grand-average as
mne.EvokedArrayobjects.Useful for immediate offline analysis, plotting with
mne.viz.plot_evoked(), or source localisation viaget_source().- Returns:
- evoked
dict[str,mne.EvokedArray] Mapping
condition_label → EvokedArray. Conditions with zero accepted epochs are omitted.
- evoked
Examples
>>> evoked = rt.get_evoked() >>> mne.viz.plot_evoked(evoked["auditory/left"])
- save(path: str, overwrite: bool = False) None[source]#
Save accumulated epochs to a
-epo.fiffile mid-run.The file can be reloaded offline with
mne.read_epochs(path)and the full MNE analysis pipeline applied.- Parameters:
Examples
>>> rt.run(n_trials=30) >>> rt.save("session01-epo.fif", overwrite=True)
- get_source(inverse_operator, lambda2: float = 0.1111111111111111, method: str = 'dSPM') dict[str, SourceEstimate][source]#
Apply a pre-computed inverse operator to the current grand averages.
Wraps
mne.minimum_norm.apply_inverse()— load an existing inverse operator withmne.minimum_norm.read_inverse_operator(fname).- Parameters:
- inverse_operator
mne.minimum_norm.InverseOperator Pre-computed inverse operator matching the stream’s Info (same channels, same channel order).
- lambda2
float, default 1/9 Regularisation parameter (
1 / SNR²). Use1/9for SNR ≈ 3 (typical ERP),1.0for noisy single-trial data.- method
str, default “dSPM” Inverse method:
"MNE","dSPM","sLORETA", or"eLORETA".
- inverse_operator
- Returns:
- stc_dict
dict[str,mne.SourceEstimate] Condition label → source estimate (vertex × time).
- stc_dict
Examples
>>> inv_op = mne.minimum_norm.read_inverse_operator("sample-inv.fif") >>> stc = rt.get_source(inv_op) >>> brain = mne_rt.BrainPlot(subject="sample", subjects_dir=sd) >>> brain.update(stc["auditory/left"].data.mean(-1))