Lab Streaming Layer (LSL) para la sincronización de múltiples flujos de datos

Dra. Roshini Randeniya y Lucas Kleine

Actualizado el

17 may 2024

Lab Streaming Layer (LSL) para la sincronización de múltiples flujos de datos

Dra. Roshini Randeniya y Lucas Kleine

Actualizado el

17 may 2024

Lab Streaming Layer (LSL) para la sincronización de múltiples flujos de datos

Dra. Roshini Randeniya y Lucas Kleine

Actualizado el

17 may 2024

¡Bienvenido! En este tutorial aprenderemos cómo usar Lab Streaming Layer (LSL) en Python para recopilar y sincronizar datos de EEG de Emotiv desde múltiples dispositivos. Requiere un conocimiento básico de trabajo del lenguaje de programación Python.

Qué aprenderás

  1. Qué es Lab Streaming Layer (LSL) y por qué lo utilizan los investigadores

  2. Cómo recopilar datos sincronizados de múltiples dispositivos de EEG de Emotiv

  3. Cómo importar e inspeccionar los datos recopilados

1.1 ¿Qué es LSL y para qué sirve?

Lab streaming layer (LSL) es una caja de herramientas de código abierto que se puede utilizar para enviar, recibir y sincronizar flujos de datos neuronales, fisiológicos y de comportamiento de diversos componentes de hardware de sensores. Los dispositivos de hardware de detección corporal y cerebral (como los sistemas de EEG de Emotiv), cada vez más capaces, precisos y móviles, están llevando la neurociencia fuera del laboratorio al mundo de los datos en tiempo real. Donde las mediciones cerebrales como el EEG y la MEG alguna vez estuvieron confinadas a los laboratorios de investigación, los dispositivos móviles nos permiten recopilar múltiples datos en entornos más naturalistas y de varias personas a la vez.

Un investigador puede estar interesado en la sincronía fisiológica entre dos personas que escuchan la misma música. LSL puede ayudarnos a recopilar datos de dos diademas de EEG por separado que también están sincronizados con la presentación del sonido.

Algunos ejemplos de otros usos de LSL:

  1. Añadir marcadores de eventos de un experimento a datos de EEG en curso

  2. Alinear en el tiempo datos de múltiples fuentes para un solo participante (por ejemplo, frecuencia cardíaca, EMG, EEG)

  3. Alinear en el tiempo datos de múltiples participantes (por ejemplo, estudios de hiperscaneo de EEG)

1.2 ¿Cómo funciona LSL?

Lab Streaming Layer es un protocolo para el intercambio en tiempo real de datos de series temporales entre múltiples dispositivos. LSL se puede implementar utilizando bibliotecas de código abierto para lenguajes de programación como Python, MATLAB, C++, Java y otros.

La funcionalidad principal gira en torno a los flujos de datos de LSL:

1. Un dispositivo/software de adquisición recopila datos y crea un flujo de datos - Los datos fisiológicos se pueden transmitir a LSL desde dispositivos de registro de EEG, rastreadores oculares, sistemas de captura de movimiento, monitores de frecuencia cardíaca, etc., incluidos los metadatos (frecuencia de muestreo, tipo de datos, información del canal, etc.) - Los marcadores de eventos de experimentos (por ejemplo, usando PsychoPy) también se pueden enviar como un flujo de datos usando LSL

2. El flujo de datos se publica en la red - Así es como se envían los datos usando LSL; el flujo de datos se "transmite" a la red - Los flujos publicados están disponibles en la red y son detectables por otros dispositivos compatibles con LSL en la misma red - LSL asigna a cada fragmento de datos o muestra una marca de tiempo basada en un reloj común (siguiendo el Network Time Protocol). - El flujo se envía muestra por muestra (o fragmento por fragmento) a través de una "salida" (outlet)

3. Los dispositivos de recopilación se "suscriben" a los flujos de datos - Así es como se reciben los datos usando LSL - Los dispositivos de recopilación en la misma red reciben flujos de datos publicados a través de "entradas" (inlets). - Cada entrada recibe las muestras de flujo y los metadatos de una sola salida

4. Guardar datos - Al suscribirse a un flujo de datos, puede guardarlo en una variable en su lenguaje de programación preferido o usar el software LabRecorder provisto por LSL para guardarlo en un formato estándar como .xdf.

2.0 Descripción general del tutorial

In este tutorial, tomaremos un ejemplo de configuración experimental y lo guiaremos a través de los pasos y el código necesarios para implementarlo usando LSL en Python. Usaremos un script de Python para reproducir un sonido mientras recopilamos datos de EEG de dos personas que usan diademas de Emotiv. Usaremos dos computadoras, cada una ejecutando EmotivPRO para recopilar los datos de EEG, y transmitiremos cada flujo a través de una salida de LSL independiente. Utilizaremos una biblioteca de Python para reproducir un archivo de audio y enviar simultáneamente un activador cada vez que comience el archivo.

PASOS:

1. Use EmotivPRO para transmitir datos a través de salidas LSL que incluyan datos de EEG (y/o movimiento, calidad de contacto, calidad de señal, etc.) 2. Reproduzca una pista de audio usando un script de Python y, simultáneamente, envíe un activador a través de otro LSL. Use LabRecorder para capturar y guardar los tres flujos de datos a través de una entrada de LSL.

2.1 PASO 1 - Configuración e instalación

  1. Necesitará dispositivos de adquisición de datos compatibles para recopilar datos
    • Todos los dispositivos de hardware cerebral de Emotiv se conectan a LSL a través del software EmotivPRO

  2. Instale EmotivPRO en su(s) dispositivo(s). Necesitará una licencia válida de EmotivPRO para usar LSL.

  3. Instale la biblioteca de LSL para Python con el siguiente comando:
    pip install pylsl

  4. Descargue el software LabRecorder. Esta es una aplicación sencilla y gratuita que se puede ejecutar desde
    la línea de comandos o utilizando una descarga independiente

  5. Para nuestro experimento: Instale los paquetes necesarios para reproducir audio con Python
    pip install sounddevice soundfile

2.2 PASO 3 - Enviar los datos desde EmotivPRO a través de un flujo de LSL

  1. Busque los "..." en la esquina superior derecha de la aplicación y vaya a Configuración (Settings)

  2. Busque la sección "Lab Streaming Layer" y la subsección "Outlet"

  3. Seleccione todos los tipos de datos que desea transmitir

  4. Seleccione el formato de datos (flotante de 32 bits o doble de 64 bits)

  5. Seleccione si desea enviar datos muestra por muestra o en fragmentos de muestras

  6. Haga clic en "Iniciar" (Start) para transmitir un flujo de datos de LSL


2.3 PASO 4 - Usar un script de Python para reproducir audio y enviar activadores

  1. Copie y pegue el siguiente bloque de código en un archivo de Python y guárdelo en su computadora.

  2. Busque un archivo de audio (idealmente un archivo .wav) que desee reproducir y edite el script cambiando la
    variable audio_filepath por la ruta del archivo de audio en su computadora

  3. Abra un símbolo del sistema para interactuar con la línea de comandos y navegue hasta la carpeta donde
    está guardado su archivo de Python

  4. Ingrese: python3 nombre_archivo.py
    • Según su instalación de Python, puede usar python en lugar de python3

    Nota: Reemplace /path/to/audio.wav con la ubicación del archivo de audio que le gustaría reproducir durante su experimento.

"""
LSL Example: Play audio and send a trigger marker

This script creates an LSL marker stream, waits for the user to
press ENTER, then plays an audio file and sends a marker that
can be synchronized with EEG data collected through LabRecorder.
"""

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


def wait_for_keypress():
    print("Press ENTER to start audio playback and send an LSL marker.")
    while True:
        if input() == "":
            break


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

    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.")


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
        )
"""
LSL Example: Play audio and send a trigger marker

This script creates an LSL marker stream, waits for the user to
press ENTER, then plays an audio file and sends a marker that
can be synchronized with EEG data collected through LabRecorder.
"""

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


def wait_for_keypress():
    print("Press ENTER to start audio playback and send an LSL marker.")
    while True:
        if input() == "":
            break


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

    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.")


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
        )
"""
LSL Example: Play audio and send a trigger marker

This script creates an LSL marker stream, waits for the user to
press ENTER, then plays an audio file and sends a marker that
can be synchronized with EEG data collected through LabRecorder.
"""

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


def wait_for_keypress():
    print("Press ENTER to start audio playback and send an LSL marker.")
    while True:
        if input() == "":
            break


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

    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.")


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 PASO 5 - Usar LabRecorder para ver y guardar todos los flujos de LSL

  1. Abra LabRecorder

  2. Presione Update. Los flujos de LSL disponibles deberían estar visibles en la lista de flujos
    • Debería poder ver los flujos de ambos EmotivPRO (generalmente llamados "Emotiv-DataStream") y el flujo del marcador (llamado "AudioMarkers")

  3. Haga clic en Browse para seleccionar una ubicación para guardar los datos (y configurar otros parámetros)

  4. Seleccione todos los flujos y presione Record para comenzar a grabar

3.0 Trabajar con los datos

LabRecorder genera un archivo XDF (Extensible Data Format) que contiene datos de todos los flujos. Los archivos XDF están estructurados en flujos, cada uno con una cabecera diferente que describe lo que contiene (nombre del dispositivo, tipo de datos, frecuencia de muestreo, canales y más). Puede utilizar el siguiente bloque de código para abrir su archivo XDF y mostrar información básica.

Nota: Reemplace /path/to/your/file.xdf con la ruta para su archivo de salida XDF de LabRecorder.

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

# Give the path to your LSL output file here.
data_path = "/path/to/your/file.xdf"

# Load the XDF file.
streams, fileheader = pyxdf.load_xdf(data_path)

print("XDF File Header:", fileheader)
print("Number of streams found:", len(streams))

for i, stream in enumerate(streams):
    print("\nStream", i + 1)
    print("Stream Name:", stream["info"]["name"][0])
    print("Stream Type:", stream["info"]["type"][0])
    print("Number of Channels:", stream["info"]["channel_count"][0])

    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"
import pyxdf
import mne
import matplotlib.pyplot as plt
import numpy as np

# Give the path to your LSL output file here.
data_path = "/path/to/your/file.xdf"

# Load the XDF file.
streams, fileheader = pyxdf.load_xdf(data_path)

print("XDF File Header:", fileheader)
print("Number of streams found:", len(streams))

for i, stream in enumerate(streams):
    print("\nStream", i + 1)
    print("Stream Name:", stream["info"]["name"][0])
    print("Stream Type:", stream["info"]["type"][0])
    print("Number of Channels:", stream["info"]["channel_count"][0])

    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"
import pyxdf
import mne
import matplotlib.pyplot as plt
import numpy as np

# Give the path to your LSL output file here.
data_path = "/path/to/your/file.xdf"

# Load the XDF file.
streams, fileheader = pyxdf.load_xdf(data_path)

print("XDF File Header:", fileheader)
print("Number of streams found:", len(streams))

for i, stream in enumerate(streams):
    print("\nStream", i + 1)
    print("Stream Name:", stream["info"]["name"][0])
    print("Stream Type:", stream["info"]["type"][0])
    print("Number of Channels:", stream["info"]["channel_count"][0])

    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"


4.0 Recursos adicionales

Documentación oficial

  1. Consulte la documentación en línea, incluido el archivo README oficial en GitHub

  2. Recursos adicionales:
    Código para ejecutar LSL utilizando dispositivos de Emotiv, con scripts de ejemplo
    • Util demostración de LSL en YouTube
    Repositorio de GitHub SCCN LSL para todas las bibliotecas asociadas
    Repositorio de GitHub de LSL para una colección de submódulos y aplicaciones

  3. Canal de análisis HyPyP para estudios de hiperscaneo

¡Bienvenido! En este tutorial aprenderemos cómo usar Lab Streaming Layer (LSL) en Python para recopilar y sincronizar datos de EEG de Emotiv desde múltiples dispositivos. Requiere un conocimiento básico de trabajo del lenguaje de programación Python.

Qué aprenderás

  1. Qué es Lab Streaming Layer (LSL) y por qué lo utilizan los investigadores

  2. Cómo recopilar datos sincronizados de múltiples dispositivos de EEG de Emotiv

  3. Cómo importar e inspeccionar los datos recopilados

1.1 ¿Qué es LSL y para qué sirve?

Lab streaming layer (LSL) es una caja de herramientas de código abierto que se puede utilizar para enviar, recibir y sincronizar flujos de datos neuronales, fisiológicos y de comportamiento de diversos componentes de hardware de sensores. Los dispositivos de hardware de detección corporal y cerebral (como los sistemas de EEG de Emotiv), cada vez más capaces, precisos y móviles, están llevando la neurociencia fuera del laboratorio al mundo de los datos en tiempo real. Donde las mediciones cerebrales como el EEG y la MEG alguna vez estuvieron confinadas a los laboratorios de investigación, los dispositivos móviles nos permiten recopilar múltiples datos en entornos más naturalistas y de varias personas a la vez.

Un investigador puede estar interesado en la sincronía fisiológica entre dos personas que escuchan la misma música. LSL puede ayudarnos a recopilar datos de dos diademas de EEG por separado que también están sincronizados con la presentación del sonido.

Algunos ejemplos de otros usos de LSL:

  1. Añadir marcadores de eventos de un experimento a datos de EEG en curso

  2. Alinear en el tiempo datos de múltiples fuentes para un solo participante (por ejemplo, frecuencia cardíaca, EMG, EEG)

  3. Alinear en el tiempo datos de múltiples participantes (por ejemplo, estudios de hiperscaneo de EEG)

1.2 ¿Cómo funciona LSL?

Lab Streaming Layer es un protocolo para el intercambio en tiempo real de datos de series temporales entre múltiples dispositivos. LSL se puede implementar utilizando bibliotecas de código abierto para lenguajes de programación como Python, MATLAB, C++, Java y otros.

La funcionalidad principal gira en torno a los flujos de datos de LSL:

1. Un dispositivo/software de adquisición recopila datos y crea un flujo de datos - Los datos fisiológicos se pueden transmitir a LSL desde dispositivos de registro de EEG, rastreadores oculares, sistemas de captura de movimiento, monitores de frecuencia cardíaca, etc., incluidos los metadatos (frecuencia de muestreo, tipo de datos, información del canal, etc.) - Los marcadores de eventos de experimentos (por ejemplo, usando PsychoPy) también se pueden enviar como un flujo de datos usando LSL

2. El flujo de datos se publica en la red - Así es como se envían los datos usando LSL; el flujo de datos se "transmite" a la red - Los flujos publicados están disponibles en la red y son detectables por otros dispositivos compatibles con LSL en la misma red - LSL asigna a cada fragmento de datos o muestra una marca de tiempo basada en un reloj común (siguiendo el Network Time Protocol). - El flujo se envía muestra por muestra (o fragmento por fragmento) a través de una "salida" (outlet)

3. Los dispositivos de recopilación se "suscriben" a los flujos de datos - Así es como se reciben los datos usando LSL - Los dispositivos de recopilación en la misma red reciben flujos de datos publicados a través de "entradas" (inlets). - Cada entrada recibe las muestras de flujo y los metadatos de una sola salida

4. Guardar datos - Al suscribirse a un flujo de datos, puede guardarlo en una variable en su lenguaje de programación preferido o usar el software LabRecorder provisto por LSL para guardarlo en un formato estándar como .xdf.

2.0 Descripción general del tutorial

In este tutorial, tomaremos un ejemplo de configuración experimental y lo guiaremos a través de los pasos y el código necesarios para implementarlo usando LSL en Python. Usaremos un script de Python para reproducir un sonido mientras recopilamos datos de EEG de dos personas que usan diademas de Emotiv. Usaremos dos computadoras, cada una ejecutando EmotivPRO para recopilar los datos de EEG, y transmitiremos cada flujo a través de una salida de LSL independiente. Utilizaremos una biblioteca de Python para reproducir un archivo de audio y enviar simultáneamente un activador cada vez que comience el archivo.

PASOS:

1. Use EmotivPRO para transmitir datos a través de salidas LSL que incluyan datos de EEG (y/o movimiento, calidad de contacto, calidad de señal, etc.) 2. Reproduzca una pista de audio usando un script de Python y, simultáneamente, envíe un activador a través de otro LSL. Use LabRecorder para capturar y guardar los tres flujos de datos a través de una entrada de LSL.

2.1 PASO 1 - Configuración e instalación

  1. Necesitará dispositivos de adquisición de datos compatibles para recopilar datos
    • Todos los dispositivos de hardware cerebral de Emotiv se conectan a LSL a través del software EmotivPRO

  2. Instale EmotivPRO en su(s) dispositivo(s). Necesitará una licencia válida de EmotivPRO para usar LSL.

  3. Instale la biblioteca de LSL para Python con el siguiente comando:
    pip install pylsl

  4. Descargue el software LabRecorder. Esta es una aplicación sencilla y gratuita que se puede ejecutar desde
    la línea de comandos o utilizando una descarga independiente

  5. Para nuestro experimento: Instale los paquetes necesarios para reproducir audio con Python
    pip install sounddevice soundfile

2.2 PASO 3 - Enviar los datos desde EmotivPRO a través de un flujo de LSL

  1. Busque los "..." en la esquina superior derecha de la aplicación y vaya a Configuración (Settings)

  2. Busque la sección "Lab Streaming Layer" y la subsección "Outlet"

  3. Seleccione todos los tipos de datos que desea transmitir

  4. Seleccione el formato de datos (flotante de 32 bits o doble de 64 bits)

  5. Seleccione si desea enviar datos muestra por muestra o en fragmentos de muestras

  6. Haga clic en "Iniciar" (Start) para transmitir un flujo de datos de LSL


2.3 PASO 4 - Usar un script de Python para reproducir audio y enviar activadores

  1. Copie y pegue el siguiente bloque de código en un archivo de Python y guárdelo en su computadora.

  2. Busque un archivo de audio (idealmente un archivo .wav) que desee reproducir y edite el script cambiando la
    variable audio_filepath por la ruta del archivo de audio en su computadora

  3. Abra un símbolo del sistema para interactuar con la línea de comandos y navegue hasta la carpeta donde
    está guardado su archivo de Python

  4. Ingrese: python3 nombre_archivo.py
    • Según su instalación de Python, puede usar python en lugar de python3

    Nota: Reemplace /path/to/audio.wav con la ubicación del archivo de audio que le gustaría reproducir durante su experimento.

"""
LSL Example: Play audio and send a trigger marker

This script creates an LSL marker stream, waits for the user to
press ENTER, then plays an audio file and sends a marker that
can be synchronized with EEG data collected through LabRecorder.
"""

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


def wait_for_keypress():
    print("Press ENTER to start audio playback and send an LSL marker.")
    while True:
        if input() == "":
            break


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

    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.")


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 PASO 5 - Usar LabRecorder para ver y guardar todos los flujos de LSL

  1. Abra LabRecorder

  2. Presione Update. Los flujos de LSL disponibles deberían estar visibles en la lista de flujos
    • Debería poder ver los flujos de ambos EmotivPRO (generalmente llamados "Emotiv-DataStream") y el flujo del marcador (llamado "AudioMarkers")

  3. Haga clic en Browse para seleccionar una ubicación para guardar los datos (y configurar otros parámetros)

  4. Seleccione todos los flujos y presione Record para comenzar a grabar

3.0 Trabajar con los datos

LabRecorder genera un archivo XDF (Extensible Data Format) que contiene datos de todos los flujos. Los archivos XDF están estructurados en flujos, cada uno con una cabecera diferente que describe lo que contiene (nombre del dispositivo, tipo de datos, frecuencia de muestreo, canales y más). Puede utilizar el siguiente bloque de código para abrir su archivo XDF y mostrar información básica.

Nota: Reemplace /path/to/your/file.xdf con la ruta para su archivo de salida XDF de LabRecorder.

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

# Give the path to your LSL output file here.
data_path = "/path/to/your/file.xdf"

# Load the XDF file.
streams, fileheader = pyxdf.load_xdf(data_path)

print("XDF File Header:", fileheader)
print("Number of streams found:", len(streams))

for i, stream in enumerate(streams):
    print("\nStream", i + 1)
    print("Stream Name:", stream["info"]["name"][0])
    print("Stream Type:", stream["info"]["type"][0])
    print("Number of Channels:", stream["info"]["channel_count"][0])

    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"


4.0 Recursos adicionales

Documentación oficial

  1. Consulte la documentación en línea, incluido el archivo README oficial en GitHub

  2. Recursos adicionales:
    Código para ejecutar LSL utilizando dispositivos de Emotiv, con scripts de ejemplo
    • Util demostración de LSL en YouTube
    Repositorio de GitHub SCCN LSL para todas las bibliotecas asociadas
    Repositorio de GitHub de LSL para una colección de submódulos y aplicaciones

  3. Canal de análisis HyPyP para estudios de hiperscaneo

¡Bienvenido! En este tutorial aprenderemos cómo usar Lab Streaming Layer (LSL) en Python para recopilar y sincronizar datos de EEG de Emotiv desde múltiples dispositivos. Requiere un conocimiento básico de trabajo del lenguaje de programación Python.

Qué aprenderás

  1. Qué es Lab Streaming Layer (LSL) y por qué lo utilizan los investigadores

  2. Cómo recopilar datos sincronizados de múltiples dispositivos de EEG de Emotiv

  3. Cómo importar e inspeccionar los datos recopilados

1.1 ¿Qué es LSL y para qué sirve?

Lab streaming layer (LSL) es una caja de herramientas de código abierto que se puede utilizar para enviar, recibir y sincronizar flujos de datos neuronales, fisiológicos y de comportamiento de diversos componentes de hardware de sensores. Los dispositivos de hardware de detección corporal y cerebral (como los sistemas de EEG de Emotiv), cada vez más capaces, precisos y móviles, están llevando la neurociencia fuera del laboratorio al mundo de los datos en tiempo real. Donde las mediciones cerebrales como el EEG y la MEG alguna vez estuvieron confinadas a los laboratorios de investigación, los dispositivos móviles nos permiten recopilar múltiples datos en entornos más naturalistas y de varias personas a la vez.

Un investigador puede estar interesado en la sincronía fisiológica entre dos personas que escuchan la misma música. LSL puede ayudarnos a recopilar datos de dos diademas de EEG por separado que también están sincronizados con la presentación del sonido.

Algunos ejemplos de otros usos de LSL:

  1. Añadir marcadores de eventos de un experimento a datos de EEG en curso

  2. Alinear en el tiempo datos de múltiples fuentes para un solo participante (por ejemplo, frecuencia cardíaca, EMG, EEG)

  3. Alinear en el tiempo datos de múltiples participantes (por ejemplo, estudios de hiperscaneo de EEG)

1.2 ¿Cómo funciona LSL?

Lab Streaming Layer es un protocolo para el intercambio en tiempo real de datos de series temporales entre múltiples dispositivos. LSL se puede implementar utilizando bibliotecas de código abierto para lenguajes de programación como Python, MATLAB, C++, Java y otros.

La funcionalidad principal gira en torno a los flujos de datos de LSL:

1. Un dispositivo/software de adquisición recopila datos y crea un flujo de datos - Los datos fisiológicos se pueden transmitir a LSL desde dispositivos de registro de EEG, rastreadores oculares, sistemas de captura de movimiento, monitores de frecuencia cardíaca, etc., incluidos los metadatos (frecuencia de muestreo, tipo de datos, información del canal, etc.) - Los marcadores de eventos de experimentos (por ejemplo, usando PsychoPy) también se pueden enviar como un flujo de datos usando LSL

2. El flujo de datos se publica en la red - Así es como se envían los datos usando LSL; el flujo de datos se "transmite" a la red - Los flujos publicados están disponibles en la red y son detectables por otros dispositivos compatibles con LSL en la misma red - LSL asigna a cada fragmento de datos o muestra una marca de tiempo basada en un reloj común (siguiendo el Network Time Protocol). - El flujo se envía muestra por muestra (o fragmento por fragmento) a través de una "salida" (outlet)

3. Los dispositivos de recopilación se "suscriben" a los flujos de datos - Así es como se reciben los datos usando LSL - Los dispositivos de recopilación en la misma red reciben flujos de datos publicados a través de "entradas" (inlets). - Cada entrada recibe las muestras de flujo y los metadatos de una sola salida

4. Guardar datos - Al suscribirse a un flujo de datos, puede guardarlo en una variable en su lenguaje de programación preferido o usar el software LabRecorder provisto por LSL para guardarlo en un formato estándar como .xdf.

2.0 Descripción general del tutorial

In este tutorial, tomaremos un ejemplo de configuración experimental y lo guiaremos a través de los pasos y el código necesarios para implementarlo usando LSL en Python. Usaremos un script de Python para reproducir un sonido mientras recopilamos datos de EEG de dos personas que usan diademas de Emotiv. Usaremos dos computadoras, cada una ejecutando EmotivPRO para recopilar los datos de EEG, y transmitiremos cada flujo a través de una salida de LSL independiente. Utilizaremos una biblioteca de Python para reproducir un archivo de audio y enviar simultáneamente un activador cada vez que comience el archivo.

PASOS:

1. Use EmotivPRO para transmitir datos a través de salidas LSL que incluyan datos de EEG (y/o movimiento, calidad de contacto, calidad de señal, etc.) 2. Reproduzca una pista de audio usando un script de Python y, simultáneamente, envíe un activador a través de otro LSL. Use LabRecorder para capturar y guardar los tres flujos de datos a través de una entrada de LSL.

2.1 PASO 1 - Configuración e instalación

  1. Necesitará dispositivos de adquisición de datos compatibles para recopilar datos
    • Todos los dispositivos de hardware cerebral de Emotiv se conectan a LSL a través del software EmotivPRO

  2. Instale EmotivPRO en su(s) dispositivo(s). Necesitará una licencia válida de EmotivPRO para usar LSL.

  3. Instale la biblioteca de LSL para Python con el siguiente comando:
    pip install pylsl

  4. Descargue el software LabRecorder. Esta es una aplicación sencilla y gratuita que se puede ejecutar desde
    la línea de comandos o utilizando una descarga independiente

  5. Para nuestro experimento: Instale los paquetes necesarios para reproducir audio con Python
    pip install sounddevice soundfile

2.2 PASO 3 - Enviar los datos desde EmotivPRO a través de un flujo de LSL

  1. Busque los "..." en la esquina superior derecha de la aplicación y vaya a Configuración (Settings)

  2. Busque la sección "Lab Streaming Layer" y la subsección "Outlet"

  3. Seleccione todos los tipos de datos que desea transmitir

  4. Seleccione el formato de datos (flotante de 32 bits o doble de 64 bits)

  5. Seleccione si desea enviar datos muestra por muestra o en fragmentos de muestras

  6. Haga clic en "Iniciar" (Start) para transmitir un flujo de datos de LSL


2.3 PASO 4 - Usar un script de Python para reproducir audio y enviar activadores

  1. Copie y pegue el siguiente bloque de código en un archivo de Python y guárdelo en su computadora.

  2. Busque un archivo de audio (idealmente un archivo .wav) que desee reproducir y edite el script cambiando la
    variable audio_filepath por la ruta del archivo de audio en su computadora

  3. Abra un símbolo del sistema para interactuar con la línea de comandos y navegue hasta la carpeta donde
    está guardado su archivo de Python

  4. Ingrese: python3 nombre_archivo.py
    • Según su instalación de Python, puede usar python en lugar de python3

    Nota: Reemplace /path/to/audio.wav con la ubicación del archivo de audio que le gustaría reproducir durante su experimento.

"""
LSL Example: Play audio and send a trigger marker

This script creates an LSL marker stream, waits for the user to
press ENTER, then plays an audio file and sends a marker that
can be synchronized with EEG data collected through LabRecorder.
"""

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


def wait_for_keypress():
    print("Press ENTER to start audio playback and send an LSL marker.")
    while True:
        if input() == "":
            break


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

    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.")


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 PASO 5 - Usar LabRecorder para ver y guardar todos los flujos de LSL

  1. Abra LabRecorder

  2. Presione Update. Los flujos de LSL disponibles deberían estar visibles en la lista de flujos
    • Debería poder ver los flujos de ambos EmotivPRO (generalmente llamados "Emotiv-DataStream") y el flujo del marcador (llamado "AudioMarkers")

  3. Haga clic en Browse para seleccionar una ubicación para guardar los datos (y configurar otros parámetros)

  4. Seleccione todos los flujos y presione Record para comenzar a grabar

3.0 Trabajar con los datos

LabRecorder genera un archivo XDF (Extensible Data Format) que contiene datos de todos los flujos. Los archivos XDF están estructurados en flujos, cada uno con una cabecera diferente que describe lo que contiene (nombre del dispositivo, tipo de datos, frecuencia de muestreo, canales y más). Puede utilizar el siguiente bloque de código para abrir su archivo XDF y mostrar información básica.

Nota: Reemplace /path/to/your/file.xdf con la ruta para su archivo de salida XDF de LabRecorder.

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

# Give the path to your LSL output file here.
data_path = "/path/to/your/file.xdf"

# Load the XDF file.
streams, fileheader = pyxdf.load_xdf(data_path)

print("XDF File Header:", fileheader)
print("Number of streams found:", len(streams))

for i, stream in enumerate(streams):
    print("\nStream", i + 1)
    print("Stream Name:", stream["info"]["name"][0])
    print("Stream Type:", stream["info"]["type"][0])
    print("Number of Channels:", stream["info"]["channel_count"][0])

    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"


4.0 Recursos adicionales

Documentación oficial

  1. Consulte la documentación en línea, incluido el archivo README oficial en GitHub

  2. Recursos adicionales:
    Código para ejecutar LSL utilizando dispositivos de Emotiv, con scripts de ejemplo
    • Util demostración de LSL en YouTube
    Repositorio de GitHub SCCN LSL para todas las bibliotecas asociadas
    Repositorio de GitHub de LSL para una colección de submódulos y aplicaciones

  3. Canal de análisis HyPyP para estudios de hiperscaneo

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

Continúa leyendo

Basics of Neural Oscillations