mne_rt.ArrayStream#

class mne_rt.ArrayStream(data: ndarray, info: Info, *, bufsize: float = 3.0, chunk_size: int = 10, n_repeat: int | float = 1)[source]#

Bases: object

Simulate a live LSL stream from an in-memory numpy array.

Duck-types the subset of mne_lsl.stream.StreamLSL’s public interface that RTStream relies on (get_data, n_new_samples, connected, info, disconnect, pick, filter, notch_filter, set_montage, set_meas_date), so an RTStream session can be driven by a plain numpy array instead of live hardware or a recorded file replayed over LSL. Returned by RTStream.connect_to_array() — not normally instantiated directly.

Parameters:
dataarray of shape (n_channels, n_samples)

The full recording to stream.

infomne.Info

Channel/sampling-rate metadata; info["nchan"] must equal data.shape[0].

bufsizefloat, default 3.0

Ring-buffer size in seconds, mirroring StreamLSL(bufsize=...).

chunk_sizeint, default 10

Number of samples released into the buffer per acquisition tick, mirroring mne_lsl.player.PlayerLSL’s chunk_size.

n_repeatint | float, default 1

Number of times to loop over data once exhausted. Use np.inf for an open-ended session.

Notes

Because the entire recording is already available in memory, filter() and notch_filter() apply a single zero-phase FIR pass over the whole array (via mne.filter.filter_data() / mne.filter.notch_filter()) rather than a causal online filter — there is no “future data” constraint to respect as there would be for a genuinely live stream. If called while already streaming (as record_main() does), samples already pushed into the ring buffer stay unfiltered until they age out — the buffer is fully refreshed, and the transient gone, within one bufsize window.

If n_repeat is exhausted before the caller stops requesting data, streaming simply stops advancing: n_new_samples stays at 0 and get_data() keeps returning the final buffered window.

__init__(data: ndarray, info: Info, *, bufsize: float = 3.0, chunk_size: int = 10, n_repeat: int | float = 1) None[source]#

Methods

__init__(data, info, *[, bufsize, ...])

connect()

Start the simulated real-time acquisition thread.

disconnect()

Stop the acquisition thread.

filter(l_freq, h_freq)

Zero-phase FIR band-pass over the entire underlying array.

get_data([winsize, picks, exclude])

Retrieve the latest data from the buffer.

notch_filter(freqs)

Zero-phase FIR notch filter over the entire underlying array.

pick([picks, exclude])

Restrict the stream to a subset of channels, in-place.

set_meas_date(meas_date)

set_montage(montage[, on_missing])

Attributes

connected

info

n_new_samples

Number of new samples available since the last get_data() call.

connect() ArrayStream[source]#

Start the simulated real-time acquisition thread.

disconnect() ArrayStream[source]#

Stop the acquisition thread.

property connected: bool#
property info: Info#
property n_new_samples: int#

Number of new samples available since the last get_data() call.

get_data(winsize: float | None = None, picks: str | list | None = None, exclude: str | list | tuple = 'bads') tuple[ndarray, ndarray][source]#

Retrieve the latest data from the buffer.

Mirrors mne_lsl.stream.StreamLSL.get_data(): resets n_new_samples to 0 on every call.

set_montage(montage: Any, on_missing: str = 'warn') ArrayStream[source]#
set_meas_date(meas_date: Any) ArrayStream[source]#
pick(picks: Any = None, exclude: Any = ()) ArrayStream[source]#

Restrict the stream to a subset of channels, in-place.

Must be called before connect() — picking after the acquisition thread has started would change the channel count out from under it mid-stream.

filter(l_freq: float | None, h_freq: float | None) ArrayStream[source]#

Zero-phase FIR band-pass over the entire underlying array.

Computed outside the buffer lock so the acquisition thread is only blocked for the final (near-instant) reference swap, not the full filtering pass.

notch_filter(freqs: float | list) ArrayStream[source]#

Zero-phase FIR notch filter over the entire underlying array.

See filter() for why the computation happens outside the lock.