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
fname
is not provided:[date/time timestamp]-[stream]-raw.fif
If
fname
is 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_data
in the user home directorythe stream to connect to is named
MyStream
the recorded file naming scheme is
test-[stream]-raw.fif
, i.e.test-MyStream-raw.fif
$ bsl_stream_recorder -d examples -f test -s MyStream
![StreamRecorder](../../_images/stream_recorder_cli.gif)
Total running time of the script: (0 minutes 8.327 seconds)
Estimated memory usage: 204 MB