Labrecorder Clibatch Version
Problem
Currently, we don’t know if we can use the CLI or Python API version of LabRecorder to record and/or save EEG data.
Solution
The short answer is yes, we can use Labrecorder’s Python API to record/save data and Labrecorder’s CLI to create EEG streams and open .xdf files. we can either save data as singular entries, chunks, ring buffers or entire sessions using python API. I’ll explain some use cases below:
Using Python API:
install liesl stable version using pip:
pip install liesl
find available LSL streams using print_available_streams() and you can obtain a specific stream’s info using its stream name (get_streams_matching(name="StreamName")):
streams = liesl.print_available_streams() # list of available streams
desired_stream = liesl.get_streams_matching(name="UnityMarkerStream") # get specific stream based on the stream name
to constantly read data from a stream and save it into a ring_buffer (a buffer with a fixed size. When it fills up, adding another element overwrites the oldest one that was still being kept). if we decide to save data into a ring buffer, we need to make sure it doesn’t go over the size of the buffer or we empty the buffer (rb.reset()) and save each time before emptying.
sinfo = liesl.get_streaminfos_matching(name="UnityMarkerStream")[0]
s_rate = 100 # sampling rate: change to specific value for EEG - can be obtained from stream info
rb = liesl.RingBuffer(streaminfo=sinfo, duration_in_ms=1000) # duration_in_ms defines size of the ring buffer.
rb.await_running()
run_time = 5
time.sleep(run_time) # record 5 seconds of data
chunk, tstamps = rb.get()
assert chunk.shape == [run_time* s_rate, 8] # for run_time duration and 8 channels
a better method for saving continuous data without worrying about the ring buffer size and overpour is to use liesl built-in session recording that saves data into a .xdf file format for the duration of a session (session start and ending are defined by the starting and ending of task function) :
localhostname= 'DESKTOP-Q0FNADP' #find this from liesl.inlet_to_dict(stream)
streamargs = [{'name':"UnityMarkerStream", "hostname": localhostname}]
session = liesl.Session(prefix="LSL_data", streamargs=streamargs)
with session("unity_marker_recordings"):
run_task()
# run your task, and while it runs, the streams are recorded
# to ~/labrecording/LSL_data/unity_marker_recordings_R001.xdf
prefix="LSL_data" is the folder name where data gets stored and session() defines file names: ~/labrecording/LSL_data/unity_marker_recordings_R001.xdf
run_task() is the main funtion that runs for the duration of data recording. data recording stops after run_task() stops.
Proposed integration into bessy_python
add this function within EEG_data.py
def _save_stream_data(self, session_name: str, task_func, *args):
streamargs = [{'name': self.stream_name, "hostname": self.local_host_name}]
session = liesl.Session(prefix="bessy_stream_data", streamargs=streamargs)
with session(session_name):
task_func(*args) #this can be self.main(*args)
# the streams are recorded to ~/labrecording/bessy_stream_data/session_name_R001.xdf
Using CLI:
install liesl using pip:
pip install liesl
create mock streams:
liesl mock --type EEG
list available LSL streams:
liesl list
visualize specific streams:
liesl show [-h] [--name NAME] [--type TYPE] [--channel CHANNEL]
[--backend {mpl,ascii}] [--frate FRATE]
read xdf file:
liesl xdf [-h] [-a AT_MOST] [-t TIMEOUT] filename