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 tutorial 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 je zult leren

  1. Wat Lab Streaming Layer (LSL) is en waarom onderzoekers het gebruiken

  2. Hoe gesynchroniseerde gegevens van meerdere Emotiv EEG-apparaten kunnen worden verzameld

  3. Hoe verzamelde gegevens kunnen worden geïmporteerd en geïnspecteerd

1.1 Wat is LSL en waar is het goed voor?

Lab streaming layer (LSL) is een open-source toolbox die kan worden gebruikt om neurale, fysiologische en gedragsgegevensstromen van diverse sensorhardware te verzenden, te ontvangen en te synchroniseren. Steeds capabele, preciezere en mobiele 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 gegevens 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:

  1. Voeg gebeurtenismarkeringen van een experiment toe aan lopende EEG-gegevens

  2. Gegevens uit meerdere bronnen in de tijd uitlijnen voor een enkele deelnemer (bijv. hartslag, EMG, EEG)

  3. 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 others.

De kernfunctionaliteit draait om LSL-gegevensstromen:

1. Een acquisitieapparaat/software verzamelt gegevens en creëert een gegevensstroom - Fysiologische gegevens kunnen naar LSL worden gestreamd vanaf EEG-opnameapparaten, eye-trackers, bewegingsregistratiesystemen, hartslagmeters, enz., inclusief metadata (bemonsteringsfrequentie, gegevenstype, kanaalinformatie, enz.) - Gebeurtenismarkeringen van experimenten (bijv. met behulp van 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 met behulp van LSL; de gegevensstroom wordt naar het netwerk "uitgezonden" - Gepubliceerde stromen zijn beschikbaar op het netwerk en vindbaar door andere door 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. Verzamelappara(a)t(en) "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 and 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 door LSL geleverde software LabRecorder gebruiken om deze op te slaan in een standaardformaat zoals .xdf.

2.0 Tutorialoverzicht

In deze tutorial nemen we een voorbeeld van een experimentele opstelling en leiden we u door de nodige stappen en code om deze te implementeren met 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 elke stroom via een aparte LSL-outlet uit te zenden. 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 die EEG-gegevens bevatten (en/of beweging, contactkwaliteit, signaalkwaliteit, enz.) 2. Speel een audiotrack af met een Python-script en verzend 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

  1. U hebt ondersteunde gegevensacquisitieapparaten nodig voor het verzamelen van gegevens
    • Alle brainware-apparaten van Emotiv maken verbinding met LSL via EmotivPRO-software

  2. Installeer EmotivPRO op uw appara(a)t(en). U hebt een geldige EmotivPRO-licentie nodig om LSL te gebruiken.

  3. Installeer de Python LSL-bibliotheek met de volgende opdracht:
    pip install pylsl

  4. Download de LabRecorder-software. Dit is een eenvoudige, gratis app die kan worden uitgevoerd vanaf
    de opdrachtregel of met een standalone download

  5. Voor 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

  1. Zoek de "..." in de rechterbovenhoek van de app, ga naar Instellingen

  2. Zoek de sectie 'Lab Streaming Layer' en de subsectie 'Outlet'

  3. Selecteer alle gegevenstypen die u wilt uitzenden

  4. Selecteer het gegevensformaat (32-bits float of 64-bits double)

  5. Selecteer of u gegevens monster-voor-monster of in segmenten van monsters wilt verzenden

  6. 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

  1. Kopieer en plak het volgende codeblok in een python-bestand en sla het op uw computer op.

  2. Zoek een audiobestand (bij voorkeur een .wav-bestand) dat u wilt afspelen en bewerk het script door de
    variabele audio_filepath te wijzigen in het bestandspad naar uw audiobestand op uw computer

  3. Open een opdrachtprompt om te communiceren met de opdrachtregel en navigeer naar de map waar
    uw Python-bestand is opgeslagen

  4. Voer in: python3 filename.py
    • Afhankelijk van uw Python-installatie kunt u python gebruiken in plaats van python3

    Opmerking: Vervang /path/to/audio.wav door de locatie van het audiobestand dat u tijdens uw experiment wilt afspelen.

"""
Python-voorbeeld LSL: audio afspelen en een triggermarkering verzenden

Dit script maakt een LSL-markeringsstroom aan, wacht tot de gebruiker op
ENTER drukt, speelt vervolgens een audiobestand af en verzendt een markering die
gesynchroniseerd kan worden met EEG-gegevens verzameld via LabRecorder.
"""

import sounddevice as sd
import soundfile as sf
from pylsl import StreamInfo, StreamOutlet


def wait_for_keypress():
    print("Druk op ENTER om het afspelen van de audio te starten en een LSL-markering te verzenden.")
    while True:
        if input() == "":
            break


def play_audio_and_send_marker(audio_file, outlet):
    data, fs = sf.read(audio_file)

    print("Audio wordt afgespeeld en LSL-markering wordt verzonden...")

    marker_val = [1]
    outlet.push_sample(marker_val)

    sd.play(data, fs)
    sd.wait()

    print("Afspelen audio voltooid.")


if __name__ == "__main__":

    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
        )
"""
Python-voorbeeld LSL: audio afspelen en een triggermarkering verzenden

Dit script maakt een LSL-markeringsstroom aan, wacht tot de gebruiker op
ENTER drukt, speelt vervolgens een audiobestand af en verzendt een markering die
gesynchroniseerd kan worden met EEG-gegevens verzameld via LabRecorder.
"""

import sounddevice as sd
import soundfile as sf
from pylsl import StreamInfo, StreamOutlet


def wait_for_keypress():
    print("Druk op ENTER om het afspelen van de audio te starten en een LSL-markering te verzenden.")
    while True:
        if input() == "":
            break


def play_audio_and_send_marker(audio_file, outlet):
    data, fs = sf.read(audio_file)

    print("Audio wordt afgespeeld en LSL-markering wordt verzonden...")

    marker_val = [1]
    outlet.push_sample(marker_val)

    sd.play(data, fs)
    sd.wait()

    print("Afspelen audio voltooid.")


if __name__ == "__main__":

    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
        )
"""
Python-voorbeeld LSL: audio afspelen en een triggermarkering verzenden

Dit script maakt een LSL-markeringsstroom aan, wacht tot de gebruiker op
ENTER drukt, speelt vervolgens een audiobestand af en verzendt een markering die
gesynchroniseerd kan worden met EEG-gegevens verzameld via LabRecorder.
"""

import sounddevice as sd
import soundfile as sf
from pylsl import StreamInfo, StreamOutlet


def wait_for_keypress():
    print("Druk op ENTER om het afspelen van de audio te starten en een LSL-markering te verzenden.")
    while True:
        if input() == "":
            break


def play_audio_and_send_marker(audio_file, outlet):
    data, fs = sf.read(audio_file)

    print("Audio wordt afgespeeld en LSL-markering wordt verzonden...")

    marker_val = [1]
    outlet.push_sample(marker_val)

    sd.play(data, fs)
    sd.wait()

    print("Afspelen audio voltooid.")


if __name__ == "__main__":

    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
        )

2.4 STAP 5 - Gebruik LabRecorder om alle LSL-stromen te bekijken en op te slaan

  1. Open LabRecorder

  2. Druk op Update. De beschikbare LSL-stromen moeten zichtbaar zijn in de stroomlijst
    • U zou stromen moeten kunnen zien van beide EmotivPROs (meestal "Emotiv-
    DataStream" genoemd) en de markeringsstroom (genaamd "AudioMarkers")

  3. Klik op Browse om een locatie te selecteren om gegevens op te slaan (en stel andere parameters in)

  4. Selecteer alle stromen en druk op Record om de opname te starten

3.0 Werken met de gegevens

LabRecorder produceert een XDF-bestand (Extensible Data Format) dat gegevens van alle stromen bevat. XDF-bestanden zijn gestructureerd in stromen, elk met een andere header die beschrijft wat het bevat (apparaatnaam, gegevenstype, bemonsteringsfrequentie, kanalen en meer). U kunt het onderstaande codeblok gebruiken om uw XDF-bestand te openen en enkele basisgegevens weer te geven.

Opmerking: Vervang /path/to/your/file.xdf door het bestandspad voor uw LabRecorder XDF-uitvoerbestand.

import pyxdf
import mne
import matplotlib.pyplot as plt
import numpy as np

# Geef hier het pad naar uw LSL-uitvoerbestand op.
data_path = "/path/to/your/file.xdf"

# Laad het XDF-bestand.
streams, fileheader = pyxdf.load_xdf(data_path)

print("XDF-bestandsheader:", fileheader)
print("Aantal gevonden stromen:", len(streams))

for i, stream in enumerate(streams):
    print("\nStroom", i + 1)
    print("Stroomnaam:", stream["info"]["name"][0])
    print("Stroomtype:", stream["info"]["type"][0])
    print("Aantal kanalen:", stream["info"]["channel_count"][0])

    sfreq = float(stream["info"]["nominal_srate"][0])
    print("Bemonsteringsfrequentie:", sfreq)

    print("Aantal monsters:", len(stream["time_series"]))
    print("Eerste 5 gegevenspunten:", stream["time_series"][:5])

    channel_names = [
        chan["label"][0]
        for chan in stream["info"]["desc"][0]["channels"][0]["channel"]
    ]

    print("Kanaalnamen:", channel_names)

    channel_types = "eeg"
import pyxdf
import mne
import matplotlib.pyplot as plt
import numpy as np

# Geef hier het pad naar uw LSL-uitvoerbestand op.
data_path = "/path/to/your/file.xdf"

# Laad het XDF-bestand.
streams, fileheader = pyxdf.load_xdf(data_path)

print("XDF-bestandsheader:", fileheader)
print("Aantal gevonden stromen:", len(streams))

for i, stream in enumerate(streams):
    print("\nStroom", i + 1)
    print("Stroomnaam:", stream["info"]["name"][0])
    print("Stroomtype:", stream["info"]["type"][0])
    print("Aantal kanalen:", stream["info"]["channel_count"][0])

    sfreq = float(stream["info"]["nominal_srate"][0])
    print("Bemonsteringsfrequentie:", sfreq)

    print("Aantal monsters:", len(stream["time_series"]))
    print("Eerste 5 gegevenspunten:", stream["time_series"][:5])

    channel_names = [
        chan["label"][0]
        for chan in stream["info"]["desc"][0]["channels"][0]["channel"]
    ]

    print("Kanaalnamen:", channel_names)

    channel_types = "eeg"
import pyxdf
import mne
import matplotlib.pyplot as plt
import numpy as np

# Geef hier het pad naar uw LSL-uitvoerbestand op.
data_path = "/path/to/your/file.xdf"

# Laad het XDF-bestand.
streams, fileheader = pyxdf.load_xdf(data_path)

print("XDF-bestandsheader:", fileheader)
print("Aantal gevonden stromen:", len(streams))

for i, stream in enumerate(streams):
    print("\nStroom", i + 1)
    print("Stroomnaam:", stream["info"]["name"][0])
    print("Stroomtype:", stream["info"]["type"][0])
    print("Aantal kanalen:", stream["info"]["channel_count"][0])

    sfreq = float(stream["info"]["nominal_srate"][0])
    print("Bemonsteringsfrequentie:", sfreq)

    print("Aantal monsters:", len(stream["time_series"]))
    print("Eerste 5 gegevenspunten:", stream["time_series"][:5])

    channel_names = [
        chan["label"][0]
        for chan in stream["info"]["desc"][0]["channels"][0]["channel"]
    ]

    print("Kanaalnamen:", channel_names)

    channel_types = "eeg"


4.0 Aanvullende bronnen

Officiële documentatie

  1. Bekijk de online documentatie, inclusief het officiële README-bestand op GitHub

  2. Aanvullende bronnen:
    Code om LSL uit te voeren met de apparaten van Emotiv, met voorbeeldscripts
    • Handige LSL-demo op YouTube
    SCCN LSL GitHub-repository for all associated libraries
    LSL GitHub-repository voor een verzameling submodules en apps

  3. HyPyP analyse-pipeline voor Hyperscanning-onderzoeken

Welkom! In deze tutorial 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 je zult leren

  1. Wat Lab Streaming Layer (LSL) is en waarom onderzoekers het gebruiken

  2. Hoe gesynchroniseerde gegevens van meerdere Emotiv EEG-apparaten kunnen worden verzameld

  3. Hoe verzamelde gegevens kunnen worden geïmporteerd en geïnspecteerd

1.1 Wat is LSL en waar is het goed voor?

Lab streaming layer (LSL) is een open-source toolbox die kan worden gebruikt om neurale, fysiologische en gedragsgegevensstromen van diverse sensorhardware te verzenden, te ontvangen en te synchroniseren. Steeds capabele, preciezere en mobiele 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 gegevens 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:

  1. Voeg gebeurtenismarkeringen van een experiment toe aan lopende EEG-gegevens

  2. Gegevens uit meerdere bronnen in de tijd uitlijnen voor een enkele deelnemer (bijv. hartslag, EMG, EEG)

  3. 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 others.

De kernfunctionaliteit draait om LSL-gegevensstromen:

1. Een acquisitieapparaat/software verzamelt gegevens en creëert een gegevensstroom - Fysiologische gegevens kunnen naar LSL worden gestreamd vanaf EEG-opnameapparaten, eye-trackers, bewegingsregistratiesystemen, hartslagmeters, enz., inclusief metadata (bemonsteringsfrequentie, gegevenstype, kanaalinformatie, enz.) - Gebeurtenismarkeringen van experimenten (bijv. met behulp van 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 met behulp van LSL; de gegevensstroom wordt naar het netwerk "uitgezonden" - Gepubliceerde stromen zijn beschikbaar op het netwerk en vindbaar door andere door 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. Verzamelappara(a)t(en) "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 and 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 door LSL geleverde software LabRecorder gebruiken om deze op te slaan in een standaardformaat zoals .xdf.

2.0 Tutorialoverzicht

In deze tutorial nemen we een voorbeeld van een experimentele opstelling en leiden we u door de nodige stappen en code om deze te implementeren met 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 elke stroom via een aparte LSL-outlet uit te zenden. 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 die EEG-gegevens bevatten (en/of beweging, contactkwaliteit, signaalkwaliteit, enz.) 2. Speel een audiotrack af met een Python-script en verzend 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

  1. U hebt ondersteunde gegevensacquisitieapparaten nodig voor het verzamelen van gegevens
    • Alle brainware-apparaten van Emotiv maken verbinding met LSL via EmotivPRO-software

  2. Installeer EmotivPRO op uw appara(a)t(en). U hebt een geldige EmotivPRO-licentie nodig om LSL te gebruiken.

  3. Installeer de Python LSL-bibliotheek met de volgende opdracht:
    pip install pylsl

  4. Download de LabRecorder-software. Dit is een eenvoudige, gratis app die kan worden uitgevoerd vanaf
    de opdrachtregel of met een standalone download

  5. Voor 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

  1. Zoek de "..." in de rechterbovenhoek van de app, ga naar Instellingen

  2. Zoek de sectie 'Lab Streaming Layer' en de subsectie 'Outlet'

  3. Selecteer alle gegevenstypen die u wilt uitzenden

  4. Selecteer het gegevensformaat (32-bits float of 64-bits double)

  5. Selecteer of u gegevens monster-voor-monster of in segmenten van monsters wilt verzenden

  6. 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

  1. Kopieer en plak het volgende codeblok in een python-bestand en sla het op uw computer op.

  2. Zoek een audiobestand (bij voorkeur een .wav-bestand) dat u wilt afspelen en bewerk het script door de
    variabele audio_filepath te wijzigen in het bestandspad naar uw audiobestand op uw computer

  3. Open een opdrachtprompt om te communiceren met de opdrachtregel en navigeer naar de map waar
    uw Python-bestand is opgeslagen

  4. Voer in: python3 filename.py
    • Afhankelijk van uw Python-installatie kunt u python gebruiken in plaats van python3

    Opmerking: Vervang /path/to/audio.wav door de locatie van het audiobestand dat u tijdens uw experiment wilt afspelen.

"""
Python-voorbeeld LSL: audio afspelen en een triggermarkering verzenden

Dit script maakt een LSL-markeringsstroom aan, wacht tot de gebruiker op
ENTER drukt, speelt vervolgens een audiobestand af en verzendt een markering die
gesynchroniseerd kan worden met EEG-gegevens verzameld via LabRecorder.
"""

import sounddevice as sd
import soundfile as sf
from pylsl import StreamInfo, StreamOutlet


def wait_for_keypress():
    print("Druk op ENTER om het afspelen van de audio te starten en een LSL-markering te verzenden.")
    while True:
        if input() == "":
            break


def play_audio_and_send_marker(audio_file, outlet):
    data, fs = sf.read(audio_file)

    print("Audio wordt afgespeeld en LSL-markering wordt verzonden...")

    marker_val = [1]
    outlet.push_sample(marker_val)

    sd.play(data, fs)
    sd.wait()

    print("Afspelen audio voltooid.")


if __name__ == "__main__":

    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
        )

2.4 STAP 5 - Gebruik LabRecorder om alle LSL-stromen te bekijken en op te slaan

  1. Open LabRecorder

  2. Druk op Update. De beschikbare LSL-stromen moeten zichtbaar zijn in de stroomlijst
    • U zou stromen moeten kunnen zien van beide EmotivPROs (meestal "Emotiv-
    DataStream" genoemd) en de markeringsstroom (genaamd "AudioMarkers")

  3. Klik op Browse om een locatie te selecteren om gegevens op te slaan (en stel andere parameters in)

  4. Selecteer alle stromen en druk op Record om de opname te starten

3.0 Werken met de gegevens

LabRecorder produceert een XDF-bestand (Extensible Data Format) dat gegevens van alle stromen bevat. XDF-bestanden zijn gestructureerd in stromen, elk met een andere header die beschrijft wat het bevat (apparaatnaam, gegevenstype, bemonsteringsfrequentie, kanalen en meer). U kunt het onderstaande codeblok gebruiken om uw XDF-bestand te openen en enkele basisgegevens weer te geven.

Opmerking: Vervang /path/to/your/file.xdf door het bestandspad voor uw LabRecorder XDF-uitvoerbestand.

import pyxdf
import mne
import matplotlib.pyplot as plt
import numpy as np

# Geef hier het pad naar uw LSL-uitvoerbestand op.
data_path = "/path/to/your/file.xdf"

# Laad het XDF-bestand.
streams, fileheader = pyxdf.load_xdf(data_path)

print("XDF-bestandsheader:", fileheader)
print("Aantal gevonden stromen:", len(streams))

for i, stream in enumerate(streams):
    print("\nStroom", i + 1)
    print("Stroomnaam:", stream["info"]["name"][0])
    print("Stroomtype:", stream["info"]["type"][0])
    print("Aantal kanalen:", stream["info"]["channel_count"][0])

    sfreq = float(stream["info"]["nominal_srate"][0])
    print("Bemonsteringsfrequentie:", sfreq)

    print("Aantal monsters:", len(stream["time_series"]))
    print("Eerste 5 gegevenspunten:", stream["time_series"][:5])

    channel_names = [
        chan["label"][0]
        for chan in stream["info"]["desc"][0]["channels"][0]["channel"]
    ]

    print("Kanaalnamen:", channel_names)

    channel_types = "eeg"


4.0 Aanvullende bronnen

Officiële documentatie

  1. Bekijk de online documentatie, inclusief het officiële README-bestand op GitHub

  2. Aanvullende bronnen:
    Code om LSL uit te voeren met de apparaten van Emotiv, met voorbeeldscripts
    • Handige LSL-demo op YouTube
    SCCN LSL GitHub-repository for all associated libraries
    LSL GitHub-repository voor een verzameling submodules en apps

  3. HyPyP analyse-pipeline voor Hyperscanning-onderzoeken

Welkom! In deze tutorial 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 je zult leren

  1. Wat Lab Streaming Layer (LSL) is en waarom onderzoekers het gebruiken

  2. Hoe gesynchroniseerde gegevens van meerdere Emotiv EEG-apparaten kunnen worden verzameld

  3. Hoe verzamelde gegevens kunnen worden geïmporteerd en geïnspecteerd

1.1 Wat is LSL en waar is het goed voor?

Lab streaming layer (LSL) is een open-source toolbox die kan worden gebruikt om neurale, fysiologische en gedragsgegevensstromen van diverse sensorhardware te verzenden, te ontvangen en te synchroniseren. Steeds capabele, preciezere en mobiele 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 gegevens 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:

  1. Voeg gebeurtenismarkeringen van een experiment toe aan lopende EEG-gegevens

  2. Gegevens uit meerdere bronnen in de tijd uitlijnen voor een enkele deelnemer (bijv. hartslag, EMG, EEG)

  3. 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 others.

De kernfunctionaliteit draait om LSL-gegevensstromen:

1. Een acquisitieapparaat/software verzamelt gegevens en creëert een gegevensstroom - Fysiologische gegevens kunnen naar LSL worden gestreamd vanaf EEG-opnameapparaten, eye-trackers, bewegingsregistratiesystemen, hartslagmeters, enz., inclusief metadata (bemonsteringsfrequentie, gegevenstype, kanaalinformatie, enz.) - Gebeurtenismarkeringen van experimenten (bijv. met behulp van 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 met behulp van LSL; de gegevensstroom wordt naar het netwerk "uitgezonden" - Gepubliceerde stromen zijn beschikbaar op het netwerk en vindbaar door andere door 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. Verzamelappara(a)t(en) "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 and 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 door LSL geleverde software LabRecorder gebruiken om deze op te slaan in een standaardformaat zoals .xdf.

2.0 Tutorialoverzicht

In deze tutorial nemen we een voorbeeld van een experimentele opstelling en leiden we u door de nodige stappen en code om deze te implementeren met 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 elke stroom via een aparte LSL-outlet uit te zenden. 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 die EEG-gegevens bevatten (en/of beweging, contactkwaliteit, signaalkwaliteit, enz.) 2. Speel een audiotrack af met een Python-script en verzend 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

  1. U hebt ondersteunde gegevensacquisitieapparaten nodig voor het verzamelen van gegevens
    • Alle brainware-apparaten van Emotiv maken verbinding met LSL via EmotivPRO-software

  2. Installeer EmotivPRO op uw appara(a)t(en). U hebt een geldige EmotivPRO-licentie nodig om LSL te gebruiken.

  3. Installeer de Python LSL-bibliotheek met de volgende opdracht:
    pip install pylsl

  4. Download de LabRecorder-software. Dit is een eenvoudige, gratis app die kan worden uitgevoerd vanaf
    de opdrachtregel of met een standalone download

  5. Voor 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

  1. Zoek de "..." in de rechterbovenhoek van de app, ga naar Instellingen

  2. Zoek de sectie 'Lab Streaming Layer' en de subsectie 'Outlet'

  3. Selecteer alle gegevenstypen die u wilt uitzenden

  4. Selecteer het gegevensformaat (32-bits float of 64-bits double)

  5. Selecteer of u gegevens monster-voor-monster of in segmenten van monsters wilt verzenden

  6. 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

  1. Kopieer en plak het volgende codeblok in een python-bestand en sla het op uw computer op.

  2. Zoek een audiobestand (bij voorkeur een .wav-bestand) dat u wilt afspelen en bewerk het script door de
    variabele audio_filepath te wijzigen in het bestandspad naar uw audiobestand op uw computer

  3. Open een opdrachtprompt om te communiceren met de opdrachtregel en navigeer naar de map waar
    uw Python-bestand is opgeslagen

  4. Voer in: python3 filename.py
    • Afhankelijk van uw Python-installatie kunt u python gebruiken in plaats van python3

    Opmerking: Vervang /path/to/audio.wav door de locatie van het audiobestand dat u tijdens uw experiment wilt afspelen.

"""
Python-voorbeeld LSL: audio afspelen en een triggermarkering verzenden

Dit script maakt een LSL-markeringsstroom aan, wacht tot de gebruiker op
ENTER drukt, speelt vervolgens een audiobestand af en verzendt een markering die
gesynchroniseerd kan worden met EEG-gegevens verzameld via LabRecorder.
"""

import sounddevice as sd
import soundfile as sf
from pylsl import StreamInfo, StreamOutlet


def wait_for_keypress():
    print("Druk op ENTER om het afspelen van de audio te starten en een LSL-markering te verzenden.")
    while True:
        if input() == "":
            break


def play_audio_and_send_marker(audio_file, outlet):
    data, fs = sf.read(audio_file)

    print("Audio wordt afgespeeld en LSL-markering wordt verzonden...")

    marker_val = [1]
    outlet.push_sample(marker_val)

    sd.play(data, fs)
    sd.wait()

    print("Afspelen audio voltooid.")


if __name__ == "__main__":

    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
        )

2.4 STAP 5 - Gebruik LabRecorder om alle LSL-stromen te bekijken en op te slaan

  1. Open LabRecorder

  2. Druk op Update. De beschikbare LSL-stromen moeten zichtbaar zijn in de stroomlijst
    • U zou stromen moeten kunnen zien van beide EmotivPROs (meestal "Emotiv-
    DataStream" genoemd) en de markeringsstroom (genaamd "AudioMarkers")

  3. Klik op Browse om een locatie te selecteren om gegevens op te slaan (en stel andere parameters in)

  4. Selecteer alle stromen en druk op Record om de opname te starten

3.0 Werken met de gegevens

LabRecorder produceert een XDF-bestand (Extensible Data Format) dat gegevens van alle stromen bevat. XDF-bestanden zijn gestructureerd in stromen, elk met een andere header die beschrijft wat het bevat (apparaatnaam, gegevenstype, bemonsteringsfrequentie, kanalen en meer). U kunt het onderstaande codeblok gebruiken om uw XDF-bestand te openen en enkele basisgegevens weer te geven.

Opmerking: Vervang /path/to/your/file.xdf door het bestandspad voor uw LabRecorder XDF-uitvoerbestand.

import pyxdf
import mne
import matplotlib.pyplot as plt
import numpy as np

# Geef hier het pad naar uw LSL-uitvoerbestand op.
data_path = "/path/to/your/file.xdf"

# Laad het XDF-bestand.
streams, fileheader = pyxdf.load_xdf(data_path)

print("XDF-bestandsheader:", fileheader)
print("Aantal gevonden stromen:", len(streams))

for i, stream in enumerate(streams):
    print("\nStroom", i + 1)
    print("Stroomnaam:", stream["info"]["name"][0])
    print("Stroomtype:", stream["info"]["type"][0])
    print("Aantal kanalen:", stream["info"]["channel_count"][0])

    sfreq = float(stream["info"]["nominal_srate"][0])
    print("Bemonsteringsfrequentie:", sfreq)

    print("Aantal monsters:", len(stream["time_series"]))
    print("Eerste 5 gegevenspunten:", stream["time_series"][:5])

    channel_names = [
        chan["label"][0]
        for chan in stream["info"]["desc"][0]["channels"][0]["channel"]
    ]

    print("Kanaalnamen:", channel_names)

    channel_types = "eeg"


4.0 Aanvullende bronnen

Officiële documentatie

  1. Bekijk de online documentatie, inclusief het officiële README-bestand op GitHub

  2. Aanvullende bronnen:
    Code om LSL uit te voeren met de apparaten van Emotiv, met voorbeeldscripts
    • Handige LSL-demo op YouTube
    SCCN LSL GitHub-repository for all associated libraries
    LSL GitHub-repository voor een verzameling submodules en apps

  3. HyPyP analyse-pipeline voor Hyperscanning-onderzoeken

A technician fits an Emotiv saline EEG headset on a test participant.

Lees verder

Basics of Neural Oscillations