Send LSL triggers with PsychoPy and mobile EEG

If you wish to keep track of the time each stimulus appears in PsychoPy during your experiment, and align each of them to your EEG recording, you would need to automatically send triggers each time a stimulus appears. This is possible with LSL. In this blog, we will explain how to precisely send triggers with PsychoPy and mobile EEG using Smarting PRO for this specific example.

How To

  1. Windows 10, 64bit (in this example we used Windows 10 but check if it applies to other platforms)
  2. PsychoPy
  3. Pylsl (Python)
  4. Smarting Pro amplifier

Let’s take a well-known Stroop experiment, follow this tutorial: Build your first PsychoPy experiment (Stroop task)

In Stroop, words are appearing one after the other in different colors, e.g., RED then RED, the participant should note the color of the word ignoring the word itself.

Open or Create your experiment in the Builder (example from tutorial above), then compile to Python script.

Fig 1. Compile the experiment to Python

Then open the Coder window and add at the end of section called # — Import packages —:

from pylsl import StreamInfo, StreamOutlet
# Set up LabStreamingLayer stream.
info = StreamInfo(name='PsychoPy_LSL', type='Markers', channel_count=1, nominal_srate=0, channel_format='string', source_id='psy_marker')
outlet = StreamOutlet(info)  # Broadcast the stream.

Obviously, you need to install pylsl (pip install pylsl) in order to make this code (LSL) work.

If you want to send continuous data, the nominal_sampling rate should change from 0 (irregular sampling rate) to some regular value. We are sending each word as a “string” of letters the participant is seeing on screen. If in some cases you wish to send numbers then instead of “string” write “int32” or “float32”. LSL will automatically associate timestamps for each marker’s appearance.

Now, you want to send a marker whenever a word appears on the screen, and whenever the user responds with a keyboard press.

In the code you will find a section called # *response* updates, write:

# Send LSL Marker : Response as string
resp = "ResponseKey: " + response.keys
print("Response: [%s]" % resp)    
outlet.push_sample([resp])  # Push event marker.

I am printing in the console of PsychoPy for debugging but you can comment it. If you are using only one screen, to see the console output during the experiment, you must change in section # — Setup the Window — , fullscreen=False instead of True.

In the section called # *text* updates, write:

# Send LSL Marker : word and its colour as string
mark = word +"_"+ colour
print("Word_color: [%s]" % mark)    
outlet.push_sample([mark])  # Push event marker.

Word and colour are the names of my variables (in the .csv conditions file), so if you wrote other names, you should change them. I wanted to send not only the word that is appearing on the screen but its respective color as well. 

WARNING: Whenever you Compile to Python from the Builder it will erase your code in the Coder, so don’t forget to Save your python code from the Coder.

At the same time, you wish to record brain activity, e.g. to measure workload levels during the experiment, or some error related potentials, or EEG coherence sensitive to congruent and incongruent words-colors etc.

Open mbt Streamer and Run the PsychoPy experiment from the Coder (as the Builder did not integrate your new code). Once you press run, you can refresh the LSL streams in mbt Streamer and see your markers stream, as below.

Then simply press Record in mbt streamer to save the all Markers and EEG into one .xdf file, with automatically synced streams and you’re good to go!

Fig 2. After pressing Run in the Coder, and pressing Stream in mbt Streamer, you can see 2 LSL streams in the mbt Streamer. One coming from PsychoPy, and the other from the EEG Smarting PRO; all received on 1 computer (called “kama”)

Conclusion

Let us know how it goes and if you have any questions feel free to reach out to us on our contact page.

*Conclusion written by mbt team

Recommended reading