Note
Go to the end to download the full example code.
StreamRecorder: resting-state recordingΒΆ
A resting-state recording is a simple offline recording during which the brain
activity of a subject is measured in the absence of any stimulus or task. A
resting-state recording can be designed with a StreamRecorder.
# Authors: Mathieu Scheltienne <mathieu.scheltienne@fcbg.ch>
#
# License: LGPL-2.1
Warning
Both StreamPlayer and StreamRecorder create a new process
to stream or record data. On Windows, mutliprocessing suffers a couple of
restrictions. The entry-point of a multiprocessing program should be
protected with if __name__ == '__main__': to ensure it can safely
import and run the module. More information on the
documentation for multiprocessing on Windows.
This example will use a sample EEG resting-state dataset that can be retrieve
with bsl.datasets. The dataset is stored in the user home
directory in the folder bsl_data (e.g. C:\Users\User\bsl_data).
import os
import time
from pathlib import Path
import mne
from bsl import StreamPlayer, StreamRecorder, datasets
from bsl.triggers import MockTrigger
To simulate an actual signal coming from an LSL stream, a StreamPlayer
is used with a 40 seconds resting-state recording.
stream_name = "StreamPlayer"
fif_file = datasets.eeg_resting_state.data_path()
player = StreamPlayer(stream_name, fif_file)
player.start()
print(player)
<Player: StreamPlayer | ON | /home/runner/bsl_data/eeg_sample/resting_state-raw.fif>
For this example, the folder bsl_data/examples located in the user home
directory will be used to stored recorded files. To ensure its existence,
os.makedirs is used.
record_dir = Path("~/bsl_data/examples").expanduser()
os.makedirs(record_dir, exist_ok=True)
print(record_dir)
/home/runner/bsl_data/examples
For this simple offline recording, the goal is to start a
StreamRecorder, send an event on a trigger to mark the beginning of
the resting-state recording, wait for a defined duration, and stop the
recording.
By default, a StreamRecorder does not require any argument. The
current working directory is used to record data from all available streams
in files named based on the date/time timestamp at which the recorder is
started.
To record only a subset of the available streams with a specific file name
and in a specific directory, the arguments record_dir, fname and
stream_name must be provided.
For this example, the directory used to store recordings is
bsl_data/examples and the file name will start with
example-resting-state.
Note
By default, the start method is blocking and will
wait for the recording to start. This behavior can be changed with the
blocking argument.
recorder = StreamRecorder(record_dir, fname="example-resting-state")
recorder.start()
print(recorder)
<Recorder: All streams | ON | /home/runner/bsl_data/examples>
Now that a StreamRecorder is started and is acquiring data, a trigger
to mark the beginning of the segment of interest is created. For this
example, a MockTrigger is used, but this example
would be equally valid with a different type of trigger.
trigger = MockTrigger()
To mark the beginning of the segment of interest in the recording, a signal is sent on the trigger. For this example, the event value (1) is used.
trigger.signal(1)
Finally, after the appropriate duration, the recording is interrupted.
time.sleep(2) # 2 seconds duration
del trigger
recorder.stop()
print(recorder)
<Recorder: All streams | OFF | /home/runner/bsl_data/examples>
A StreamRecorder records data in .pcl format. This file can be
open with pickle.load, and is automatically converted to a Raw
FIF file in a subdirectory fif. The recorded files name syntax is:
If
fnameis not provided:[date/time timestamp]-[stream]-raw.fifIf
fnameis provided:[fname]-[stream]-raw.fif
Where stream is the name of the recorded LSL stream. Thus, one file is
created for each stream being recorded.
fname = record_dir / "fif" / "example-resting-state-StreamPlayer-raw.fif"
raw = mne.io.read_raw_fif(fname, preload=True)
print(raw)
events = mne.find_events(raw, stim_channel="TRIGGER")
print(events)
<Raw | example-resting-state-StreamPlayer-raw.fif, 65 x 1424 (2.8 s), ~781 kB, data loaded>
[]
As for the StreamPlayer, the StreamRecorder can be used as a
context manager. The context manager takes care of starting and stopping the
recording.
with StreamRecorder(record_dir):
time.sleep(1)
As for the StreamPlayer, the StreamRecorder can be started via
command-line when a LSL stream is accessible on the network.
Example assuming:
the current working directory is
bsl_datain the user home directorythe stream to connect to is named
MyStreamthe recorded file naming scheme is
test-[stream]-raw.fif, i.e.test-MyStream-raw.fif
$ bsl_stream_recorder -d examples -f test -s MyStream
Total running time of the script: (0 minutes 8.327 seconds)
Estimated memory usage: 204 MB