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