
Lab Streaming Layer (LSL) voor het synchroniseren van meerdere gegevensstromen
Dr. Roshini Randeniya en Lucas Kleine
Bijgewerkt op
17 mei 2024

Lab Streaming Layer (LSL) voor het synchroniseren van meerdere gegevensstromen
Dr. Roshini Randeniya en Lucas Kleine
Bijgewerkt op
17 mei 2024

Lab Streaming Layer (LSL) voor het synchroniseren van meerdere gegevensstromen
Dr. Roshini Randeniya en Lucas Kleine
Bijgewerkt op
17 mei 2024
Welkom! In deze handleiding leren we hoe we Lab Streaming Layer (LSL) in Python kunnen gebruiken om Emotiv EEG-gegevens van meerdere apparaten te verzamelen en te synchroniseren. Hiervoor is een basiskennis van de programmeertaal Python vereist.
Wat u zult leren
Wat Lab Streaming Layer (LSL) is en waarom onderzoekers het gebruiken
Hoe u gesynchroniseerde gegevens van meerdere Emotiv EEG-apparaten kunt verzamelen
Hoe u verzamelde gegevens kunt importeren en inspecteren
1.1 Wat is LSL en waar is het goed voor?
Lab streaming layer (LSL) is een open-source toolbox die kan worden gebruikt voor het verzenden, ontvangen en synchroniseren van neurale, fysiologische en gedragsmatige gegevensstromen van diverse sensorhardware. Steeds krachtigere, nauwkeurigere en mobielere hersen- en lichaamssensoren (zoals Emotiv EEG-systemen) brengen neurowetenschap buiten het lab naar de wereld van realtime gegevens. Waar hersenmetingen zoals EEG en MEG ooit beperkt waren tot onderzoekslaboratoria, stellen mobiele apparaten ons in staat om meerdere gegevensstromen te verzamelen in meer natuurlijke omgevingen, en van meerdere mensen tegelijk.
Een onderzoeker kan geïnteresseerd zijn in fysiologische synchroniciteit tussen twee mensen die naar dezelfde muziek luisteren. LSL kan ons helpen om gegevens van twee EEG-headsets afzonderlijk te verzamelen die ook gesynchroniseerd zijn met de presentatie van geluid.
Enkele voorbeelden van andere toepassingen voor LSL:
Gebeurtenismarkeringen (event markers) van een experiment toevoegen aan lopende EEG-gegevens
Gegevens uit meerdere bronnen in de tijd uitlijnen voor een enkele deelnemer (bijv. hartslag, EMG, EEG)
Gegevens van meerdere deelnemers in de tijd uitlijnen (bijv. EEG Hyperscanning-onderzoeken)
1.2 Hoe werkt LSL?
Lab Streaming Layer is een protocol voor de realtime uitwisseling van tijdreeksgegevens tussen meerdere apparaten. LSL kan worden geïmplementeerd met behulp van open-source bibliotheken voor programmeertalen zoals Python, MATLAB, C++, Java and andere.

De kernfunctionaliteit draait om LSL-gegevensstromen:
1. Een acquisitie-apparaat/software verzamelt gegevens en creëert een gegevensstroom - Fysiologische gegevens kunnen naar LSL worden gestreamd vanaf EEG-registratieapparaten, eye-trackers, motion capture-systemen, hartslagmeters, enz., inclusief metadata (bemonsteringsfrequentie, datatype, kanaalinformatie, enz.) - Gebeurtenismarkeringen van experimenten (bijv. met PsychoPy) kunnen ook als een gegevensstroom worden verzonden met behulp van LSL
2. De gegevensstroom wordt op het netwerk gepubliceerd - Dit is hoe gegevens worden verzonden via LSL; de gegevensstroom wordt "uitgezonden" naar het netwerk - Gepubliceerde stromen zijn beschikbaar op het netwerk en vindbaar door andere LSL-ondersteunde apparaten op hetzelfde netwerk - LSL kent aan elk gegevenssegment of monster een tijdstempel toe op basis van een gemeenschappelijke klok (volgens het Network Time Protocol). - De stroom wordt monster-voor-monster (of segment-voor-segment) door een "outlet" geduwd
3. Verzamelapparaat/apparaten "abonneren" op gegevensstroom/stromen - Dit is hoe gegevens worden ontvangen met behulp van LSL - Verzamelapparaten op hetzelfde netwerk ontvangen gepubliceerde gegevensstromen via "inlets". - Elke inlet ontvangt de stroommonsters en metadata van slechts één outlet
4. Gegevens opslaan - Na het abonneren op een gegevensstroom kunt u deze opslaan in een variabele in uw favoriete programmeertaal, of de meegeleverde software LabRecorder van LSL gebruiken om deze op te slaan in een standaardformaat zoals .xdf.
2.0 Overzicht van de handleiding
In deze handleiding nemen we een voorbeeld van een experimentele opstelling en leiden we u door de nodige stappen en code om deze te implementeren met behulp van LSL in Python. We gebruiken Python om een geluid af te spelen terwijl we EEG-gegevens verzamelen van twee mensen die Emotiv-headsets dragen. We gebruiken twee computers die elk EmotivPRO draaien om de EEG-gegevens te verzamelen, en zenden elke stroom uit via een aparte LSL-outlet. We gebruiken een Python-bibliotheek om een audiobestand af te spelen en tegelijkertijd een trigger te verzenden telkens wanneer het bestand start.
STAPPEN:
1. Gebruik EmotivPRO om gegevens te streamen via LSL-outlets, inclusief EEG-gegevens (en/of beweging, contactkwaliteit, signaalkwaliteit, enz.) 2. Speel een audiotrack af met een Python-script en stuur tegelijkertijd een trigger via een andere LSL. Gebruik LabRecorder om alle drie de gegevensstromen vast te leggen en op te slaan via een LSL-inlet.

2.1 STAP 1 - Installatie en configuratie
U hebt ondersteunde gegevensacquisitie-apparaten nodig om gegevens te verzamelen
• Alle brainware-apparaten van Emotiv maken verbinding met LSL via de EmotivPRO-softwareInstalleer EmotivPRO op uw apparaat/apparaten. U hebt een geldige EmotivPRO-licentie nodig om LSL te gebruiken.
Installeer de Python LSL-bibliotheek met de volgende opdracht:
pip install pylslDownload de LabRecorder-software. Dit is een eenvoudige, gratis app die kan worden uitgevoerd vanaf
de opdrachtregel of met behulp van een zelfstandige downloadVoor ons experiment: Installeer de benodigde pakketten voor het afspelen van audio met Python
pip install sounddevice soundfile
2.2 STAP 3 - Verzend de gegevens van EmotivPRO via een LSL-stroom
Zoek de "..." in de rechterbovenhoek van de app, navigeer naar Instellingen
Zoek de sectie 'Lab Streaming Layer' en de subsectie 'Outlet'
Selecteer alle datatypes die u wilt uitzenden
Selecteer het gegevensformaat (32-bits float of 64-bits double)
Selecteer of u de gegevens monster-voor-monster of in segmenten van monsters wilt verzenden
Klik op 'Start' om een LSL-gegevensstroom uit te zenden
2.3 STAP 4 - Gebruik een Python-script om audio af te spelen en triggers te verzenden
Kopieer en plak het volgende codeblok in een Python-bestand en sla het op uw computer op.
Zoek een audiobestand (bij voorkeur een .wav-bestand) dat u wilt afspelen en bewerk het script door de
variabeleaudio_filepathte wijzigen in het bestandspad naar uw audiobestand op uw computerOpen een opdrachtprompt om de opdrachtregel te gebruiken en navigeer naar de map waar
uw Python-bestand is opgeslagenVoer in:
python3 bestandsnaam.py
• Afhankelijk van uw Python-installatie gebruikt u mogelijkpythonin plaats vanpython3
Opmerking: Vervang/path/to/audio.wavdoor de locatie van het audiobestand dat u tijdens uw experiment wilt afspelen.
""" LSL Example: Play audio and send a trigger marker <p>This script creates an LSL marker stream, waits for the user to<br>press ENTER, then plays an audio file and sends a marker that<br>can be synchronized with EEG data collected through LabRecorder.<br>"""</p> <p>import sounddevice as sd<br>import soundfile as sf<br>from pylsl import StreamInfo, StreamOutlet</p> <p>def wait_for_keypress():<br>print("Press ENTER to start audio playback and send an LSL marker.")<br>while True:<br>if input() == "":<br>break</p> <p>def play_audio_and_send_marker(audio_file, outlet):<br>data, fs = sf.read(audio_file)</p> <pre><code>print("Playing audio and sending LSL marker...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("Audio playback finished.") </code></pre> <p>if <strong>name</strong> == "<strong>main</strong>":</p> <pre><code>info = StreamInfo( name="AudioMarkers", type="Markers", channel_count=1, nominal_srate=0, channel_format="int32", source_id="uniqueMarkerID12345" ) outlet = StreamOutlet(info) while True: wait_for_keypress() audio_filepath = "/path/to/audio.wav" play_audio_and_send_marker( audio_filepath, outlet )</code></pre><h2 dir="auto">2.4 STEP 5 - Use LabRecorder to view and save all LSL streams</h2><ol dir="auto"><li data-preset-tag="p"><p>Open LabRecorder</p></li><li data-preset-tag="p"><p>Press <code>Update</code>. The available LSL streams should be visible in the stream list<br>• You should be able to see streams from both EmotivPROs (usually called “Emotiv-<br>DataStream”) and the marker stream (called “AudioMarkers”)</p></li><li data-preset-tag="p"><p>Click <code>Browse</code> to select a location to store data (and set other parameters)</p></li><li data-preset-tag="p"><p>Select all streams and press <code>Record</code> to start recording</p></li></ol><h2 dir="auto">3.0 Working with the data</h2><p dir="auto">LabRecorder outputs an XDF file (Extensible Data Format) that contains data from all the streams. XDF files are structured into, streams, each with a different header that describes what it contains (device name, data type, sampling rate, channels, and more). You can use the below codeblock to open your XDF file and display some basic information.</p><p dir="auto"><strong>Note: Replace </strong><code><strong>/path/to/your/file.xdf</strong></code><strong> with the filepath for your LabRecorder XDF output file.</strong></p><pre data-language="JSX"><code>import pyxdf </code></pre> <p>import mne<br>import matplotlib.pyplot as plt<br>import numpy as np</p> <h1>Give the path to your LSL output file here.</h1> <p>data_path = "/path/to/your/file.xdf"</p> <h1>Load the XDF file.</h1> <p>streams, fileheader = pyxdf.load_xdf(data_path)</p> <p>print("XDF File Header:", fileheader)<br>print("Number of streams found:", len(streams))</p> <p>for i, stream in enumerate(streams):<br>print("\nStream", i + 1)<br>print("Stream Name:", stream["info"]["name"][0])<br>print("Stream Type:", stream["info"]["type"][0])<br>print("Number of Channels:", stream["info"]["channel_count"][0])</p> <pre><code>sfreq = float(stream["info"]["nominal_srate"][0]) print("Sampling Rate:", sfreq) print("Number of Samples:", len(stream["time_series"])) print("First 5 data points:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("Channel Names:", channel_names) channel_types = "eeg"</code></pre><h3 dir="auto"><br></h3><h2 dir="auto">4.0 Additional Resources</h2><h4 dir="auto">Official Documentation</h4><ol dir="auto"><li data-preset-tag="p"><p>Check out the <a href="1. Check out the online documentation, including the official README file on GitHub 2. Additional resources: • Code to run LSL using Emotiv’s devices, with example scripts • Useful LSL demo on YouTube • SCCN LSL GitHub repository for all associated libraries • LSL GitHub repository for a collection a submodules and apps 3. HyPyP analysis pipeline for Hyperscanning studies" target="_blank">online documentation</a>, including the <a href="https://github.com/sccn/labstreaminglayer/" target="_blank">official README file on GitHub</a></p></li><li data-preset-tag="p"><p>Additional resources:<br>• <a href="https://github.com/Emotiv/labstreaminglayer" target="_blank">Code</a> to run LSL using Emotiv’s devices, with example scripts<br>• Useful <a href="https://www.youtube.com/watch?v=Y1at7yrcFW0&list=PLVnr33MP5RMRhGwY36zHHDOmAaYTB138D" target="_blank">LSL demo on YouTube</a><br>• <a href="https://github.com/sccn/labstreaminglayer" target="_blank">SCCN LSL GitHub repository</a> for all associated libraries<br>• <a href="https://github.com/labstreaminglayer" target="_blank">LSL GitHub repository</a> for a collection a submodules and apps</p></li><li data-preset-tag="p"><p><a href="https://academic.oup.com/scan/article/16/1-2/72/5919711?login=false" target="_blank">HyPyP analysis pipeline</a> for Hyperscanning studies</p></li></ol> </code></pre
""" LSL Example: Play audio and send a trigger marker <p>This script creates an LSL marker stream, waits for the user to<br>press ENTER, then plays an audio file and sends a marker that<br>can be synchronized with EEG data collected through LabRecorder.<br>"""</p> <p>import sounddevice as sd<br>import soundfile as sf<br>from pylsl import StreamInfo, StreamOutlet</p> <p>def wait_for_keypress():<br>print("Press ENTER to start audio playback and send an LSL marker.")<br>while True:<br>if input() == "":<br>break</p> <p>def play_audio_and_send_marker(audio_file, outlet):<br>data, fs = sf.read(audio_file)</p> <pre><code>print("Playing audio and sending LSL marker...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("Audio playback finished.") </code></pre> <p>if <strong>name</strong> == "<strong>main</strong>":</p> <pre><code>info = StreamInfo( name="AudioMarkers", type="Markers", channel_count=1, nominal_srate=0, channel_format="int32", source_id="uniqueMarkerID12345" ) outlet = StreamOutlet(info) while True: wait_for_keypress() audio_filepath = "/path/to/audio.wav" play_audio_and_send_marker( audio_filepath, outlet )</code></pre><h2 dir="auto">2.4 STEP 5 - Use LabRecorder to view and save all LSL streams</h2><ol dir="auto"><li data-preset-tag="p"><p>Open LabRecorder</p></li><li data-preset-tag="p"><p>Press <code>Update</code>. The available LSL streams should be visible in the stream list<br>• You should be able to see streams from both EmotivPROs (usually called “Emotiv-<br>DataStream”) and the marker stream (called “AudioMarkers”)</p></li><li data-preset-tag="p"><p>Click <code>Browse</code> to select a location to store data (and set other parameters)</p></li><li data-preset-tag="p"><p>Select all streams and press <code>Record</code> to start recording</p></li></ol><h2 dir="auto">3.0 Working with the data</h2><p dir="auto">LabRecorder outputs an XDF file (Extensible Data Format) that contains data from all the streams. XDF files are structured into, streams, each with a different header that describes what it contains (device name, data type, sampling rate, channels, and more). You can use the below codeblock to open your XDF file and display some basic information.</p><p dir="auto"><strong>Note: Replace </strong><code><strong>/path/to/your/file.xdf</strong></code><strong> with the filepath for your LabRecorder XDF output file.</strong></p><pre data-language="JSX"><code>import pyxdf </code></pre> <p>import mne<br>import matplotlib.pyplot as plt<br>import numpy as np</p> <h1>Give the path to your LSL output file here.</h1> <p>data_path = "/path/to/your/file.xdf"</p> <h1>Load the XDF file.</h1> <p>streams, fileheader = pyxdf.load_xdf(data_path)</p> <p>print("XDF File Header:", fileheader)<br>print("Number of streams found:", len(streams))</p> <p>for i, stream in enumerate(streams):<br>print("\nStream", i + 1)<br>print("Stream Name:", stream["info"]["name"][0])<br>print("Stream Type:", stream["info"]["type"][0])<br>print("Number of Channels:", stream["info"]["channel_count"][0])</p> <pre><code>sfreq = float(stream["info"]["nominal_srate"][0]) print("Sampling Rate:", sfreq) print("Number of Samples:", len(stream["time_series"])) print("First 5 data points:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("Channel Names:", channel_names) channel_types = "eeg"</code></pre><h3 dir="auto"><br></h3><h2 dir="auto">4.0 Additional Resources</h2><h4 dir="auto">Official Documentation</h4><ol dir="auto"><li data-preset-tag="p"><p>Check out the <a href="1. Check out the online documentation, including the official README file on GitHub 2. Additional resources: • Code to run LSL using Emotiv’s devices, with example scripts • Useful LSL demo on YouTube • SCCN LSL GitHub repository for all associated libraries • LSL GitHub repository for a collection a submodules and apps 3. HyPyP analysis pipeline for Hyperscanning studies" target="_blank">online documentation</a>, including the <a href="https://github.com/sccn/labstreaminglayer/" target="_blank">official README file on GitHub</a></p></li><li data-preset-tag="p"><p>Additional resources:<br>• <a href="https://github.com/Emotiv/labstreaminglayer" target="_blank">Code</a> to run LSL using Emotiv’s devices, with example scripts<br>• Useful <a href="https://www.youtube.com/watch?v=Y1at7yrcFW0&list=PLVnr33MP5RMRhGwY36zHHDOmAaYTB138D" target="_blank">LSL demo on YouTube</a><br>• <a href="https://github.com/sccn/labstreaminglayer" target="_blank">SCCN LSL GitHub repository</a> for all associated libraries<br>• <a href="https://github.com/labstreaminglayer" target="_blank">LSL GitHub repository</a> for a collection a submodules and apps</p></li><li data-preset-tag="p"><p><a href="https://academic.oup.com/scan/article/16/1-2/72/5919711?login=false" target="_blank">HyPyP analysis pipeline</a> for Hyperscanning studies</p></li></ol> </code></pre
""" LSL Example: Play audio and send a trigger marker <p>This script creates an LSL marker stream, waits for the user to<br>press ENTER, then plays an audio file and sends a marker that<br>can be synchronized with EEG data collected through LabRecorder.<br>"""</p> <p>import sounddevice as sd<br>import soundfile as sf<br>from pylsl import StreamInfo, StreamOutlet</p> <p>def wait_for_keypress():<br>print("Press ENTER to start audio playback and send an LSL marker.")<br>while True:<br>if input() == "":<br>break</p> <p>def play_audio_and_send_marker(audio_file, outlet):<br>data, fs = sf.read(audio_file)</p> <pre><code>print("Playing audio and sending LSL marker...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("Audio playback finished.") </code></pre> <p>if <strong>name</strong> == "<strong>main</strong>":</p> <pre><code>info = StreamInfo( name="AudioMarkers", type="Markers", channel_count=1, nominal_srate=0, channel_format="int32", source_id="uniqueMarkerID12345" ) outlet = StreamOutlet(info) while True: wait_for_keypress() audio_filepath = "/path/to/audio.wav" play_audio_and_send_marker( audio_filepath, outlet )</code></pre><h2 dir="auto">2.4 STEP 5 - Use LabRecorder to view and save all LSL streams</h2><ol dir="auto"><li data-preset-tag="p"><p>Open LabRecorder</p></li><li data-preset-tag="p"><p>Press <code>Update</code>. The available LSL streams should be visible in the stream list<br>• You should be able to see streams from both EmotivPROs (usually called “Emotiv-<br>DataStream”) and the marker stream (called “AudioMarkers”)</p></li><li data-preset-tag="p"><p>Click <code>Browse</code> to select a location to store data (and set other parameters)</p></li><li data-preset-tag="p"><p>Select all streams and press <code>Record</code> to start recording</p></li></ol><h2 dir="auto">3.0 Working with the data</h2><p dir="auto">LabRecorder outputs an XDF file (Extensible Data Format) that contains data from all the streams. XDF files are structured into, streams, each with a different header that describes what it contains (device name, data type, sampling rate, channels, and more). You can use the below codeblock to open your XDF file and display some basic information.</p><p dir="auto"><strong>Note: Replace </strong><code><strong>/path/to/your/file.xdf</strong></code><strong> with the filepath for your LabRecorder XDF output file.</strong></p><pre data-language="JSX"><code>import pyxdf </code></pre> <p>import mne<br>import matplotlib.pyplot as plt<br>import numpy as np</p> <h1>Give the path to your LSL output file here.</h1> <p>data_path = "/path/to/your/file.xdf"</p> <h1>Load the XDF file.</h1> <p>streams, fileheader = pyxdf.load_xdf(data_path)</p> <p>print("XDF File Header:", fileheader)<br>print("Number of streams found:", len(streams))</p> <p>for i, stream in enumerate(streams):<br>print("\nStream", i + 1)<br>print("Stream Name:", stream["info"]["name"][0])<br>print("Stream Type:", stream["info"]["type"][0])<br>print("Number of Channels:", stream["info"]["channel_count"][0])</p> <pre><code>sfreq = float(stream["info"]["nominal_srate"][0]) print("Sampling Rate:", sfreq) print("Number of Samples:", len(stream["time_series"])) print("First 5 data points:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("Channel Names:", channel_names) channel_types = "eeg"</code></pre><h3 dir="auto"><br></h3><h2 dir="auto">4.0 Additional Resources</h2><h4 dir="auto">Official Documentation</h4><ol dir="auto"><li data-preset-tag="p"><p>Check out the <a href="1. Check out the online documentation, including the official README file on GitHub 2. Additional resources: • Code to run LSL using Emotiv’s devices, with example scripts • Useful LSL demo on YouTube • SCCN LSL GitHub repository for all associated libraries • LSL GitHub repository for a collection a submodules and apps 3. HyPyP analysis pipeline for Hyperscanning studies" target="_blank">online documentation</a>, including the <a href="https://github.com/sccn/labstreaminglayer/" target="_blank">official README file on GitHub</a></p></li><li data-preset-tag="p"><p>Additional resources:<br>• <a href="https://github.com/Emotiv/labstreaminglayer" target="_blank">Code</a> to run LSL using Emotiv’s devices, with example scripts<br>• Useful <a href="https://www.youtube.com/watch?v=Y1at7yrcFW0&list=PLVnr33MP5RMRhGwY36zHHDOmAaYTB138D" target="_blank">LSL demo on YouTube</a><br>• <a href="https://github.com/sccn/labstreaminglayer" target="_blank">SCCN LSL GitHub repository</a> for all associated libraries<br>• <a href="https://github.com/labstreaminglayer" target="_blank">LSL GitHub repository</a> for a collection a submodules and apps</p></li><li data-preset-tag="p"><p><a href="https://academic.oup.com/scan/article/16/1-2/72/5919711?login=false" target="_blank">HyPyP analysis pipeline</a> for Hyperscanning studies</p></li></ol> </code></pre
Welkom! In deze handleiding leren we hoe we Lab Streaming Layer (LSL) in Python kunnen gebruiken om Emotiv EEG-gegevens van meerdere apparaten te verzamelen en te synchroniseren. Hiervoor is een basiskennis van de programmeertaal Python vereist.
Wat u zult leren
Wat Lab Streaming Layer (LSL) is en waarom onderzoekers het gebruiken
Hoe u gesynchroniseerde gegevens van meerdere Emotiv EEG-apparaten kunt verzamelen
Hoe u verzamelde gegevens kunt importeren en inspecteren
1.1 Wat is LSL en waar is het goed voor?
Lab streaming layer (LSL) is een open-source toolbox die kan worden gebruikt voor het verzenden, ontvangen en synchroniseren van neurale, fysiologische en gedragsmatige gegevensstromen van diverse sensorhardware. Steeds krachtigere, nauwkeurigere en mobielere hersen- en lichaamssensoren (zoals Emotiv EEG-systemen) brengen neurowetenschap buiten het lab naar de wereld van realtime gegevens. Waar hersenmetingen zoals EEG en MEG ooit beperkt waren tot onderzoekslaboratoria, stellen mobiele apparaten ons in staat om meerdere gegevensstromen te verzamelen in meer natuurlijke omgevingen, en van meerdere mensen tegelijk.
Een onderzoeker kan geïnteresseerd zijn in fysiologische synchroniciteit tussen twee mensen die naar dezelfde muziek luisteren. LSL kan ons helpen om gegevens van twee EEG-headsets afzonderlijk te verzamelen die ook gesynchroniseerd zijn met de presentatie van geluid.
Enkele voorbeelden van andere toepassingen voor LSL:
Gebeurtenismarkeringen (event markers) van een experiment toevoegen aan lopende EEG-gegevens
Gegevens uit meerdere bronnen in de tijd uitlijnen voor een enkele deelnemer (bijv. hartslag, EMG, EEG)
Gegevens van meerdere deelnemers in de tijd uitlijnen (bijv. EEG Hyperscanning-onderzoeken)
1.2 Hoe werkt LSL?
Lab Streaming Layer is een protocol voor de realtime uitwisseling van tijdreeksgegevens tussen meerdere apparaten. LSL kan worden geïmplementeerd met behulp van open-source bibliotheken voor programmeertalen zoals Python, MATLAB, C++, Java and andere.

De kernfunctionaliteit draait om LSL-gegevensstromen:
1. Een acquisitie-apparaat/software verzamelt gegevens en creëert een gegevensstroom - Fysiologische gegevens kunnen naar LSL worden gestreamd vanaf EEG-registratieapparaten, eye-trackers, motion capture-systemen, hartslagmeters, enz., inclusief metadata (bemonsteringsfrequentie, datatype, kanaalinformatie, enz.) - Gebeurtenismarkeringen van experimenten (bijv. met PsychoPy) kunnen ook als een gegevensstroom worden verzonden met behulp van LSL
2. De gegevensstroom wordt op het netwerk gepubliceerd - Dit is hoe gegevens worden verzonden via LSL; de gegevensstroom wordt "uitgezonden" naar het netwerk - Gepubliceerde stromen zijn beschikbaar op het netwerk en vindbaar door andere LSL-ondersteunde apparaten op hetzelfde netwerk - LSL kent aan elk gegevenssegment of monster een tijdstempel toe op basis van een gemeenschappelijke klok (volgens het Network Time Protocol). - De stroom wordt monster-voor-monster (of segment-voor-segment) door een "outlet" geduwd
3. Verzamelapparaat/apparaten "abonneren" op gegevensstroom/stromen - Dit is hoe gegevens worden ontvangen met behulp van LSL - Verzamelapparaten op hetzelfde netwerk ontvangen gepubliceerde gegevensstromen via "inlets". - Elke inlet ontvangt de stroommonsters en metadata van slechts één outlet
4. Gegevens opslaan - Na het abonneren op een gegevensstroom kunt u deze opslaan in een variabele in uw favoriete programmeertaal, of de meegeleverde software LabRecorder van LSL gebruiken om deze op te slaan in een standaardformaat zoals .xdf.
2.0 Overzicht van de handleiding
In deze handleiding nemen we een voorbeeld van een experimentele opstelling en leiden we u door de nodige stappen en code om deze te implementeren met behulp van LSL in Python. We gebruiken Python om een geluid af te spelen terwijl we EEG-gegevens verzamelen van twee mensen die Emotiv-headsets dragen. We gebruiken twee computers die elk EmotivPRO draaien om de EEG-gegevens te verzamelen, en zenden elke stroom uit via een aparte LSL-outlet. We gebruiken een Python-bibliotheek om een audiobestand af te spelen en tegelijkertijd een trigger te verzenden telkens wanneer het bestand start.
STAPPEN:
1. Gebruik EmotivPRO om gegevens te streamen via LSL-outlets, inclusief EEG-gegevens (en/of beweging, contactkwaliteit, signaalkwaliteit, enz.) 2. Speel een audiotrack af met een Python-script en stuur tegelijkertijd een trigger via een andere LSL. Gebruik LabRecorder om alle drie de gegevensstromen vast te leggen en op te slaan via een LSL-inlet.

2.1 STAP 1 - Installatie en configuratie
U hebt ondersteunde gegevensacquisitie-apparaten nodig om gegevens te verzamelen
• Alle brainware-apparaten van Emotiv maken verbinding met LSL via de EmotivPRO-softwareInstalleer EmotivPRO op uw apparaat/apparaten. U hebt een geldige EmotivPRO-licentie nodig om LSL te gebruiken.
Installeer de Python LSL-bibliotheek met de volgende opdracht:
pip install pylslDownload de LabRecorder-software. Dit is een eenvoudige, gratis app die kan worden uitgevoerd vanaf
de opdrachtregel of met behulp van een zelfstandige downloadVoor ons experiment: Installeer de benodigde pakketten voor het afspelen van audio met Python
pip install sounddevice soundfile
2.2 STAP 3 - Verzend de gegevens van EmotivPRO via een LSL-stroom
Zoek de "..." in de rechterbovenhoek van de app, navigeer naar Instellingen
Zoek de sectie 'Lab Streaming Layer' en de subsectie 'Outlet'
Selecteer alle datatypes die u wilt uitzenden
Selecteer het gegevensformaat (32-bits float of 64-bits double)
Selecteer of u de gegevens monster-voor-monster of in segmenten van monsters wilt verzenden
Klik op 'Start' om een LSL-gegevensstroom uit te zenden
2.3 STAP 4 - Gebruik een Python-script om audio af te spelen en triggers te verzenden
Kopieer en plak het volgende codeblok in een Python-bestand en sla het op uw computer op.
Zoek een audiobestand (bij voorkeur een .wav-bestand) dat u wilt afspelen en bewerk het script door de
variabeleaudio_filepathte wijzigen in het bestandspad naar uw audiobestand op uw computerOpen een opdrachtprompt om de opdrachtregel te gebruiken en navigeer naar de map waar
uw Python-bestand is opgeslagenVoer in:
python3 bestandsnaam.py
• Afhankelijk van uw Python-installatie gebruikt u mogelijkpythonin plaats vanpython3
Opmerking: Vervang/path/to/audio.wavdoor de locatie van het audiobestand dat u tijdens uw experiment wilt afspelen.
""" LSL Example: Play audio and send a trigger marker <p>This script creates an LSL marker stream, waits for the user to<br>press ENTER, then plays an audio file and sends a marker that<br>can be synchronized with EEG data collected through LabRecorder.<br>"""</p> <p>import sounddevice as sd<br>import soundfile as sf<br>from pylsl import StreamInfo, StreamOutlet</p> <p>def wait_for_keypress():<br>print("Press ENTER to start audio playback and send an LSL marker.")<br>while True:<br>if input() == "":<br>break</p> <p>def play_audio_and_send_marker(audio_file, outlet):<br>data, fs = sf.read(audio_file)</p> <pre><code>print("Playing audio and sending LSL marker...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("Audio playback finished.") </code></pre> <p>if <strong>name</strong> == "<strong>main</strong>":</p> <pre><code>info = StreamInfo( name="AudioMarkers", type="Markers", channel_count=1, nominal_srate=0, channel_format="int32", source_id="uniqueMarkerID12345" ) outlet = StreamOutlet(info) while True: wait_for_keypress() audio_filepath = "/path/to/audio.wav" play_audio_and_send_marker( audio_filepath, outlet )</code></pre><h2 dir="auto">2.4 STEP 5 - Use LabRecorder to view and save all LSL streams</h2><ol dir="auto"><li data-preset-tag="p"><p>Open LabRecorder</p></li><li data-preset-tag="p"><p>Press <code>Update</code>. The available LSL streams should be visible in the stream list<br>• You should be able to see streams from both EmotivPROs (usually called “Emotiv-<br>DataStream”) and the marker stream (called “AudioMarkers”)</p></li><li data-preset-tag="p"><p>Click <code>Browse</code> to select a location to store data (and set other parameters)</p></li><li data-preset-tag="p"><p>Select all streams and press <code>Record</code> to start recording</p></li></ol><h2 dir="auto">3.0 Working with the data</h2><p dir="auto">LabRecorder outputs an XDF file (Extensible Data Format) that contains data from all the streams. XDF files are structured into, streams, each with a different header that describes what it contains (device name, data type, sampling rate, channels, and more). You can use the below codeblock to open your XDF file and display some basic information.</p><p dir="auto"><strong>Note: Replace </strong><code><strong>/path/to/your/file.xdf</strong></code><strong> with the filepath for your LabRecorder XDF output file.</strong></p><pre data-language="JSX"><code>import pyxdf </code></pre> <p>import mne<br>import matplotlib.pyplot as plt<br>import numpy as np</p> <h1>Give the path to your LSL output file here.</h1> <p>data_path = "/path/to/your/file.xdf"</p> <h1>Load the XDF file.</h1> <p>streams, fileheader = pyxdf.load_xdf(data_path)</p> <p>print("XDF File Header:", fileheader)<br>print("Number of streams found:", len(streams))</p> <p>for i, stream in enumerate(streams):<br>print("\nStream", i + 1)<br>print("Stream Name:", stream["info"]["name"][0])<br>print("Stream Type:", stream["info"]["type"][0])<br>print("Number of Channels:", stream["info"]["channel_count"][0])</p> <pre><code>sfreq = float(stream["info"]["nominal_srate"][0]) print("Sampling Rate:", sfreq) print("Number of Samples:", len(stream["time_series"])) print("First 5 data points:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("Channel Names:", channel_names) channel_types = "eeg"</code></pre><h3 dir="auto"><br></h3><h2 dir="auto">4.0 Additional Resources</h2><h4 dir="auto">Official Documentation</h4><ol dir="auto"><li data-preset-tag="p"><p>Check out the <a href="1. Check out the online documentation, including the official README file on GitHub 2. Additional resources: • Code to run LSL using Emotiv’s devices, with example scripts • Useful LSL demo on YouTube • SCCN LSL GitHub repository for all associated libraries • LSL GitHub repository for a collection a submodules and apps 3. HyPyP analysis pipeline for Hyperscanning studies" target="_blank">online documentation</a>, including the <a href="https://github.com/sccn/labstreaminglayer/" target="_blank">official README file on GitHub</a></p></li><li data-preset-tag="p"><p>Additional resources:<br>• <a href="https://github.com/Emotiv/labstreaminglayer" target="_blank">Code</a> to run LSL using Emotiv’s devices, with example scripts<br>• Useful <a href="https://www.youtube.com/watch?v=Y1at7yrcFW0&list=PLVnr33MP5RMRhGwY36zHHDOmAaYTB138D" target="_blank">LSL demo on YouTube</a><br>• <a href="https://github.com/sccn/labstreaminglayer" target="_blank">SCCN LSL GitHub repository</a> for all associated libraries<br>• <a href="https://github.com/labstreaminglayer" target="_blank">LSL GitHub repository</a> for a collection a submodules and apps</p></li><li data-preset-tag="p"><p><a href="https://academic.oup.com/scan/article/16/1-2/72/5919711?login=false" target="_blank">HyPyP analysis pipeline</a> for Hyperscanning studies</p></li></ol> </code></pre
Welkom! In deze handleiding leren we hoe we Lab Streaming Layer (LSL) in Python kunnen gebruiken om Emotiv EEG-gegevens van meerdere apparaten te verzamelen en te synchroniseren. Hiervoor is een basiskennis van de programmeertaal Python vereist.
Wat u zult leren
Wat Lab Streaming Layer (LSL) is en waarom onderzoekers het gebruiken
Hoe u gesynchroniseerde gegevens van meerdere Emotiv EEG-apparaten kunt verzamelen
Hoe u verzamelde gegevens kunt importeren en inspecteren
1.1 Wat is LSL en waar is het goed voor?
Lab streaming layer (LSL) is een open-source toolbox die kan worden gebruikt voor het verzenden, ontvangen en synchroniseren van neurale, fysiologische en gedragsmatige gegevensstromen van diverse sensorhardware. Steeds krachtigere, nauwkeurigere en mobielere hersen- en lichaamssensoren (zoals Emotiv EEG-systemen) brengen neurowetenschap buiten het lab naar de wereld van realtime gegevens. Waar hersenmetingen zoals EEG en MEG ooit beperkt waren tot onderzoekslaboratoria, stellen mobiele apparaten ons in staat om meerdere gegevensstromen te verzamelen in meer natuurlijke omgevingen, en van meerdere mensen tegelijk.
Een onderzoeker kan geïnteresseerd zijn in fysiologische synchroniciteit tussen twee mensen die naar dezelfde muziek luisteren. LSL kan ons helpen om gegevens van twee EEG-headsets afzonderlijk te verzamelen die ook gesynchroniseerd zijn met de presentatie van geluid.
Enkele voorbeelden van andere toepassingen voor LSL:
Gebeurtenismarkeringen (event markers) van een experiment toevoegen aan lopende EEG-gegevens
Gegevens uit meerdere bronnen in de tijd uitlijnen voor een enkele deelnemer (bijv. hartslag, EMG, EEG)
Gegevens van meerdere deelnemers in de tijd uitlijnen (bijv. EEG Hyperscanning-onderzoeken)
1.2 Hoe werkt LSL?
Lab Streaming Layer is een protocol voor de realtime uitwisseling van tijdreeksgegevens tussen meerdere apparaten. LSL kan worden geïmplementeerd met behulp van open-source bibliotheken voor programmeertalen zoals Python, MATLAB, C++, Java and andere.

De kernfunctionaliteit draait om LSL-gegevensstromen:
1. Een acquisitie-apparaat/software verzamelt gegevens en creëert een gegevensstroom - Fysiologische gegevens kunnen naar LSL worden gestreamd vanaf EEG-registratieapparaten, eye-trackers, motion capture-systemen, hartslagmeters, enz., inclusief metadata (bemonsteringsfrequentie, datatype, kanaalinformatie, enz.) - Gebeurtenismarkeringen van experimenten (bijv. met PsychoPy) kunnen ook als een gegevensstroom worden verzonden met behulp van LSL
2. De gegevensstroom wordt op het netwerk gepubliceerd - Dit is hoe gegevens worden verzonden via LSL; de gegevensstroom wordt "uitgezonden" naar het netwerk - Gepubliceerde stromen zijn beschikbaar op het netwerk en vindbaar door andere LSL-ondersteunde apparaten op hetzelfde netwerk - LSL kent aan elk gegevenssegment of monster een tijdstempel toe op basis van een gemeenschappelijke klok (volgens het Network Time Protocol). - De stroom wordt monster-voor-monster (of segment-voor-segment) door een "outlet" geduwd
3. Verzamelapparaat/apparaten "abonneren" op gegevensstroom/stromen - Dit is hoe gegevens worden ontvangen met behulp van LSL - Verzamelapparaten op hetzelfde netwerk ontvangen gepubliceerde gegevensstromen via "inlets". - Elke inlet ontvangt de stroommonsters en metadata van slechts één outlet
4. Gegevens opslaan - Na het abonneren op een gegevensstroom kunt u deze opslaan in een variabele in uw favoriete programmeertaal, of de meegeleverde software LabRecorder van LSL gebruiken om deze op te slaan in een standaardformaat zoals .xdf.
2.0 Overzicht van de handleiding
In deze handleiding nemen we een voorbeeld van een experimentele opstelling en leiden we u door de nodige stappen en code om deze te implementeren met behulp van LSL in Python. We gebruiken Python om een geluid af te spelen terwijl we EEG-gegevens verzamelen van twee mensen die Emotiv-headsets dragen. We gebruiken twee computers die elk EmotivPRO draaien om de EEG-gegevens te verzamelen, en zenden elke stroom uit via een aparte LSL-outlet. We gebruiken een Python-bibliotheek om een audiobestand af te spelen en tegelijkertijd een trigger te verzenden telkens wanneer het bestand start.
STAPPEN:
1. Gebruik EmotivPRO om gegevens te streamen via LSL-outlets, inclusief EEG-gegevens (en/of beweging, contactkwaliteit, signaalkwaliteit, enz.) 2. Speel een audiotrack af met een Python-script en stuur tegelijkertijd een trigger via een andere LSL. Gebruik LabRecorder om alle drie de gegevensstromen vast te leggen en op te slaan via een LSL-inlet.

2.1 STAP 1 - Installatie en configuratie
U hebt ondersteunde gegevensacquisitie-apparaten nodig om gegevens te verzamelen
• Alle brainware-apparaten van Emotiv maken verbinding met LSL via de EmotivPRO-softwareInstalleer EmotivPRO op uw apparaat/apparaten. U hebt een geldige EmotivPRO-licentie nodig om LSL te gebruiken.
Installeer de Python LSL-bibliotheek met de volgende opdracht:
pip install pylslDownload de LabRecorder-software. Dit is een eenvoudige, gratis app die kan worden uitgevoerd vanaf
de opdrachtregel of met behulp van een zelfstandige downloadVoor ons experiment: Installeer de benodigde pakketten voor het afspelen van audio met Python
pip install sounddevice soundfile
2.2 STAP 3 - Verzend de gegevens van EmotivPRO via een LSL-stroom
Zoek de "..." in de rechterbovenhoek van de app, navigeer naar Instellingen
Zoek de sectie 'Lab Streaming Layer' en de subsectie 'Outlet'
Selecteer alle datatypes die u wilt uitzenden
Selecteer het gegevensformaat (32-bits float of 64-bits double)
Selecteer of u de gegevens monster-voor-monster of in segmenten van monsters wilt verzenden
Klik op 'Start' om een LSL-gegevensstroom uit te zenden
2.3 STAP 4 - Gebruik een Python-script om audio af te spelen en triggers te verzenden
Kopieer en plak het volgende codeblok in een Python-bestand en sla het op uw computer op.
Zoek een audiobestand (bij voorkeur een .wav-bestand) dat u wilt afspelen en bewerk het script door de
variabeleaudio_filepathte wijzigen in het bestandspad naar uw audiobestand op uw computerOpen een opdrachtprompt om de opdrachtregel te gebruiken en navigeer naar de map waar
uw Python-bestand is opgeslagenVoer in:
python3 bestandsnaam.py
• Afhankelijk van uw Python-installatie gebruikt u mogelijkpythonin plaats vanpython3
Opmerking: Vervang/path/to/audio.wavdoor de locatie van het audiobestand dat u tijdens uw experiment wilt afspelen.
""" LSL Example: Play audio and send a trigger marker <p>This script creates an LSL marker stream, waits for the user to<br>press ENTER, then plays an audio file and sends a marker that<br>can be synchronized with EEG data collected through LabRecorder.<br>"""</p> <p>import sounddevice as sd<br>import soundfile as sf<br>from pylsl import StreamInfo, StreamOutlet</p> <p>def wait_for_keypress():<br>print("Press ENTER to start audio playback and send an LSL marker.")<br>while True:<br>if input() == "":<br>break</p> <p>def play_audio_and_send_marker(audio_file, outlet):<br>data, fs = sf.read(audio_file)</p> <pre><code>print("Playing audio and sending LSL marker...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("Audio playback finished.") </code></pre> <p>if <strong>name</strong> == "<strong>main</strong>":</p> <pre><code>info = StreamInfo( name="AudioMarkers", type="Markers", channel_count=1, nominal_srate=0, channel_format="int32", source_id="uniqueMarkerID12345" ) outlet = StreamOutlet(info) while True: wait_for_keypress() audio_filepath = "/path/to/audio.wav" play_audio_and_send_marker( audio_filepath, outlet )</code></pre><h2 dir="auto">2.4 STEP 5 - Use LabRecorder to view and save all LSL streams</h2><ol dir="auto"><li data-preset-tag="p"><p>Open LabRecorder</p></li><li data-preset-tag="p"><p>Press <code>Update</code>. The available LSL streams should be visible in the stream list<br>• You should be able to see streams from both EmotivPROs (usually called “Emotiv-<br>DataStream”) and the marker stream (called “AudioMarkers”)</p></li><li data-preset-tag="p"><p>Click <code>Browse</code> to select a location to store data (and set other parameters)</p></li><li data-preset-tag="p"><p>Select all streams and press <code>Record</code> to start recording</p></li></ol><h2 dir="auto">3.0 Working with the data</h2><p dir="auto">LabRecorder outputs an XDF file (Extensible Data Format) that contains data from all the streams. XDF files are structured into, streams, each with a different header that describes what it contains (device name, data type, sampling rate, channels, and more). You can use the below codeblock to open your XDF file and display some basic information.</p><p dir="auto"><strong>Note: Replace </strong><code><strong>/path/to/your/file.xdf</strong></code><strong> with the filepath for your LabRecorder XDF output file.</strong></p><pre data-language="JSX"><code>import pyxdf </code></pre> <p>import mne<br>import matplotlib.pyplot as plt<br>import numpy as np</p> <h1>Give the path to your LSL output file here.</h1> <p>data_path = "/path/to/your/file.xdf"</p> <h1>Load the XDF file.</h1> <p>streams, fileheader = pyxdf.load_xdf(data_path)</p> <p>print("XDF File Header:", fileheader)<br>print("Number of streams found:", len(streams))</p> <p>for i, stream in enumerate(streams):<br>print("\nStream", i + 1)<br>print("Stream Name:", stream["info"]["name"][0])<br>print("Stream Type:", stream["info"]["type"][0])<br>print("Number of Channels:", stream["info"]["channel_count"][0])</p> <pre><code>sfreq = float(stream["info"]["nominal_srate"][0]) print("Sampling Rate:", sfreq) print("Number of Samples:", len(stream["time_series"])) print("First 5 data points:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("Channel Names:", channel_names) channel_types = "eeg"</code></pre><h3 dir="auto"><br></h3><h2 dir="auto">4.0 Additional Resources</h2><h4 dir="auto">Official Documentation</h4><ol dir="auto"><li data-preset-tag="p"><p>Check out the <a href="1. Check out the online documentation, including the official README file on GitHub 2. Additional resources: • Code to run LSL using Emotiv’s devices, with example scripts • Useful LSL demo on YouTube • SCCN LSL GitHub repository for all associated libraries • LSL GitHub repository for a collection a submodules and apps 3. HyPyP analysis pipeline for Hyperscanning studies" target="_blank">online documentation</a>, including the <a href="https://github.com/sccn/labstreaminglayer/" target="_blank">official README file on GitHub</a></p></li><li data-preset-tag="p"><p>Additional resources:<br>• <a href="https://github.com/Emotiv/labstreaminglayer" target="_blank">Code</a> to run LSL using Emotiv’s devices, with example scripts<br>• Useful <a href="https://www.youtube.com/watch?v=Y1at7yrcFW0&list=PLVnr33MP5RMRhGwY36zHHDOmAaYTB138D" target="_blank">LSL demo on YouTube</a><br>• <a href="https://github.com/sccn/labstreaminglayer" target="_blank">SCCN LSL GitHub repository</a> for all associated libraries<br>• <a href="https://github.com/labstreaminglayer" target="_blank">LSL GitHub repository</a> for a collection a submodules and apps</p></li><li data-preset-tag="p"><p><a href="https://academic.oup.com/scan/article/16/1-2/72/5919711?login=false" target="_blank">HyPyP analysis pipeline</a> for Hyperscanning studies</p></li></ol> </code></pre

Lees verder