Lab Streaming Layer (LSL) para Sincronização de Múltiplos Fluxos de Dados

Dra. Roshini Randeniya e Lucas Kleine

Atualizado em

17 de mai. de 2024

Lab Streaming Layer (LSL) para Sincronização de Múltiplos Fluxos de Dados

Dra. Roshini Randeniya e Lucas Kleine

Atualizado em

17 de mai. de 2024

Lab Streaming Layer (LSL) para Sincronização de Múltiplos Fluxos de Dados

Dra. Roshini Randeniya e Lucas Kleine

Atualizado em

17 de mai. de 2024

Bem-vindo! Neste tutorial, vamos aprender como usar o Lab Streaming Layer (LSL) em Python para coletar e sincronizar dados de EEG da Emotiv a partir de múltiplos dispositivos. Isso exigirá um conhecimento básico de trabalho da linguagem de programação Python.

O Que Você Vai Aprender

  1. O que é o Lab Streaming Layer (LSL) e por que os pesquisadores o utilizam

  2. Como coletar dados sincronizados de múltiplos dispositivos de EEG da Emotiv

  3. Como importar e inspecionar os dados coletados

1.1 O Que É LSL e Para Que Serve?

O Lab Streaming Layer (LSL) é uma caixa de ferramentas de código aberto que pode ser usada para enviar, receber e sincronizar fluxos de dados neurais, fisiológicos e comportamentais de diversos hardwares de sensores. Dispositivos de detecção cerebral e corporal cada vez mais capazes, precisos e móveis (como os sistemas de EEG da Emotiv) estão trazendo a neurociência para fora do laboratório, direto para o mundo dos dados em tempo real. Onde medições cerebrais como EEG e MEG antes estavam confinadas a laboratórios de pesquisa, os dispositivos móveis nos permitem coletar múltiplos dados em ambientes mais naturalistas e de várias pessoas ao mesmo tempo.

Um pesquisador pode estar interessado na sincronia fisiológica entre duas pessoas ouvindo a mesma música. O LSL pode nos ajudar a coletar dados de dois headsets de EEG separadamente, que também estejam sincronizados com a apresentação do som.

Alguns exemplos de outros usos para o LSL:

  1. Adicionar marcadores de eventos de um experimento a dados contínuos de EEG

  2. Alinhar no tempo dados de múltiplas fontes para um único participante (ex: frequência cardíaca, EMG, EEG)

  3. Alinhar no tempo dados de múltiplos participantes (ex: Estudos de Hiperscanning de EEG)

1.2 Como o LSL Funciona?

O Lab Streaming Layer é um protocolo para o intercâmbio em tempo real de dados de séries temporais entre múltiplos dispositivos. O LSL pode ser implementado usando bibliotecas de código aberto para linguagens de programação como Python, MATLAB, C++, Java e outras.

A funcionalidade principal gira em torno dos fluxos de dados LSL:

1. Um dispositivo/software de aquisição coleta dados e cria um fluxo de dados - Dados fisiológicos podem ser transmitidos para o LSL a partir de dispositivos de gravação de EEG, rastreadores oculares, sistemas de captura de movimento, monitores de frequência cardíaca, etc., incluindo metadados (taxa de amostragem, tipo de dados, informações de canais, etc.) - Marcadores de eventos de experimentos (ex: usando PsychoPy) também podem ser enviados como um fluxo de dados usando LSL

2. O fluxo de dados é publicado na rede - É assim que os dados são enviados usando LSL; o fluxo de dados é "transmitido" para a rede - Os fluxos publicados estão disponíveis na rede e são detectáveis por outros dispositivos compatíveis com LSL na mesma rede - O LSL atribui a cada bloco de dados ou amostra um carimbo de data/hora com base em um relógio comum (seguindo o Network Time Protocol). - O fluxo é enviado amostra por amostra (ou bloco por bloco) através de uma "saída" (outlet)

3. Os dispositivos de coleta "assinam" os fluxos de dados - É assim que os dados são recebidos usando LSL - Os dispositivos de coleta na mesma rede recebem fluxos de dados publicados por meio de "entradas" (inlets). - Cada entrada recebe as amostras do fluxo e metadados de apenas uma saída

4. Salvar dados - Ao assinar um fluxo de dados, você pode salvá-lo em uma variável na sua linguagem de programação preferida, ou usar o software LabRecorder fornecido pelo LSL para salvá-lo em um formato padrão, como .xdf.

2.0 Visão geral do tutorial

Neste tutorial, usaremos um exemplo de configuração experimental e guiaremos você pelas etapas e códigos necessários para implementá-lo usando LSL em Python. Usaremos o Python para reproduzir um som enquanto coletamos dados de EEG de duas pessoas usando headsets Emotiv. Usaremos dois computadores, cada um executando o EmotivPRO para coletar os dados de EEG e transmitir cada fluxo por meio de uma saída LSL separada. Usaremos uma biblioteca Python para reproduzir um arquivo de áudio e, ao mesmo tempo, enviar um gatilho toda vez que o arquivo for iniciado.

ETAPAS:

1. Use o EmotivPRO para transmitir dados por meio de saídas LSL que incluam dados de EEG (e/ou movimento, qualidade do contato, qualidade do sinal, etc.) 2. Reproduza uma faixa de áudio usando um script Python e, simultaneamente, envie um gatilho por meio de outro LSL. Use o LabRecorder para capturar e salvar todos os três fluxos de dados por meio de uma entrada LSL.

2.1 ETAPA 1 - Configuração e instalação

  1. Você precisará de dispositivos de aquisição de dados compatíveis para coletar dados
    • Todos os de dispositivos de hardware cerebral da Emotiv conectam-se ao LSL via software EmotivPRO

  2. Instale o EmotivPRO no(s) seu(s) dispositivo(s). Você precisará de uma licença do EmotivPRO válida para usar o LSL.

  3. Instale a biblioteca Python LSL com o seguinte comando:
    pip install pylsl

  4. Baixe o software LabRecorder. Trata-se de um aplicativo simples e gratuito que pode ser executado a partir do
    da linha de comando ou usando um download independente

  5. Para o nosso experimento: Instale os pacotes necessários para reproduzir áudio usando Python
    pip install sounddevice soundfile

2.2 ETAPA 3 - Enviar os dados do EmotivPRO via fluxo LSL

  1. Localize os "..." no canto superior direito do aplicativo e navegue até Configurações

  2. Encontre a seção 'Lab Streaming Layer' e a subseção 'Outlet'

  3. Selecione todos os tipos de dados que você gostaria de transmitir

  4. Selecione o formato de dados (float de 32 bits ou double de 64 bits)

  5. Selecione se deseja enviar dados amostra por amostra ou em blocos de amostras

  6. Clique em 'Iniciar' para transmitir um fluxo de dados LSL


2.3 ETAPA 4 - Usar um script Python para reproduzir áudio e enviar gatilhos

  1. Copie e cole o seguinte bloco o código em um arquivo python e salve-o no seu computador.

  2. Localize um arquivo de áudio (idealmente um arquivo .wav) que você gostaria de reproduzir e edite o script alterando a
    variável audio_filepath para o caminho do arquivo de áudio no seu computador

  3. Abra um prompt de comando para interagir com a linha de comando e navegue até a pasta onde
    seu arquivo Python está armazenado

  4. Digite: python3 nome_do_arquivo.py
    • Dependendo da instalação do seu Python, você pode usar python em vez de python3

    Nota: Substitua /path/to/audio.wav pelo local do arquivo de áudio que deseja reproduzir durante o experimento.

"""
Exemplo LSL: Reproduzir áudio e enviar um marcador de gatilho

Este script cria um fluxo de marcadores LSL, aguarda o usuário
pressionar ENTER, depois reproduz um arquivo de áudio e envia um marcador que
pode ser sincronizado com os dados de EEG coletados pelo LabRecorder.
"""

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


def wait_for_keypress():
    print("Pressione ENTER para iniciar a reprodução de áudio e enviar um marcador LSL.")
    while True:
        if input() == "":
            break


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

    print("Reproduzindo áudio e enviando marcador LSL...")

    marker_val = [1]
    outlet.push_sample(marker_val)

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

    print("Reprodução de áudio concluída.")


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
        )
"""
Exemplo LSL: Reproduzir áudio e enviar um marcador de gatilho

Este script cria um fluxo de marcadores LSL, aguarda o usuário
pressionar ENTER, depois reproduz um arquivo de áudio e envia um marcador que
pode ser sincronizado com os dados de EEG coletados pelo LabRecorder.
"""

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


def wait_for_keypress():
    print("Pressione ENTER para iniciar a reprodução de áudio e enviar um marcador LSL.")
    while True:
        if input() == "":
            break


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

    print("Reproduzindo áudio e enviando marcador LSL...")

    marker_val = [1]
    outlet.push_sample(marker_val)

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

    print("Reprodução de áudio concluída.")


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
        )
"""
Exemplo LSL: Reproduzir áudio e enviar um marcador de gatilho

Este script cria um fluxo de marcadores LSL, aguarda o usuário
pressionar ENTER, depois reproduz um arquivo de áudio e envia um marcador que
pode ser sincronizado com os dados de EEG coletados pelo LabRecorder.
"""

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


def wait_for_keypress():
    print("Pressione ENTER para iniciar a reprodução de áudio e enviar um marcador LSL.")
    while True:
        if input() == "":
            break


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

    print("Reproduzindo áudio e enviando marcador LSL...")

    marker_val = [1]
    outlet.push_sample(marker_val)

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

    print("Reprodução de áudio concluída.")


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 ETAPA 5 - Usar o LabRecorder para visualizar e salvar todos os fluxos LSL

  1. Abra o LabRecorder

  2. Pressione Update. Os fluxos LSL disponíveis devem estar visíveis na lista de fluxos
    • Você deverá conseguir ver os fluxos de ambos os EmotivPROs (normalmente chamados “Emotiv-
    DataStream”) e o fluxo de marcadores (chamado “AudioMarkers”)

  3. Clique em Browse para selecionar um local para armazenar os dados (e definir outros parâmetros)

  4. Selecione todos os fluxos e pressione Record para iniciar a gravação

3.0 Trabalhar com os dados

O LabRecorder gera um arquivo XDF (Extensible Data Format) que contém dados de todos os fluxos. Os arquivos XDF são estruturados em fluxos, cada um com um cabeçalho diferente que descreve o que contém (nome do dispositivo, tipo de dados, taxa de amostragem, canais e muito mais). Você pode usar o bloco de código abaixo para abrir seu arquivo XDF e exibir algumas informações básicas.

Nota: Substitua /path/to/your/file.xdf pelo caminho do arquivo de saída XDF do seu LabRecorder.

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

# Indique o caminho para o seu arquivo de saída LSL aqui.
data_path = "/path/to/your/file.xdf"

# Carrega o arquivo XDF.
streams, fileheader = pyxdf.load_xdf(data_path)

print("Cabeçalho do Arquivo XDF:", fileheader)
print("Número de fluxos encontrados:", len(streams))

for i, stream in enumerate(streams):
    print("\nFluxo", i + 1)
    print("Nome do Fluxo:", stream["info"]["name"][0])
    print("Tipo de Fluxo:", stream["info"]["type"][0])
    print("Número de Canais:", stream["info"]["channel_count"][0])

    sfreq = float(stream["info"]["nominal_srate"][0])
    print("Taxa de Amostragem:", sfreq)

    print("Número de Amostras:", len(stream["time_series"]))
    print("Primeiros 5 pontos de dados:", stream["time_series"][:5])

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

    print("Nomes dos Canais:", channel_names)

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

# Indique o caminho para o seu arquivo de saída LSL aqui.
data_path = "/path/to/your/file.xdf"

# Carrega o arquivo XDF.
streams, fileheader = pyxdf.load_xdf(data_path)

print("Cabeçalho do Arquivo XDF:", fileheader)
print("Número de fluxos encontrados:", len(streams))

for i, stream in enumerate(streams):
    print("\nFluxo", i + 1)
    print("Nome do Fluxo:", stream["info"]["name"][0])
    print("Tipo de Fluxo:", stream["info"]["type"][0])
    print("Número de Canais:", stream["info"]["channel_count"][0])

    sfreq = float(stream["info"]["nominal_srate"][0])
    print("Taxa de Amostragem:", sfreq)

    print("Número de Amostras:", len(stream["time_series"]))
    print("Primeiros 5 pontos de dados:", stream["time_series"][:5])

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

    print("Nomes dos Canais:", channel_names)

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

# Indique o caminho para o seu arquivo de saída LSL aqui.
data_path = "/path/to/your/file.xdf"

# Carrega o arquivo XDF.
streams, fileheader = pyxdf.load_xdf(data_path)

print("Cabeçalho do Arquivo XDF:", fileheader)
print("Número de fluxos encontrados:", len(streams))

for i, stream in enumerate(streams):
    print("\nFluxo", i + 1)
    print("Nome do Fluxo:", stream["info"]["name"][0])
    print("Tipo de Fluxo:", stream["info"]["type"][0])
    print("Número de Canais:", stream["info"]["channel_count"][0])

    sfreq = float(stream["info"]["nominal_srate"][0])
    print("Taxa de Amostragem:", sfreq)

    print("Número de Amostras:", len(stream["time_series"]))
    print("Primeiros 5 pontos de dados:", stream["time_series"][:5])

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

    print("Nomes dos Canais:", channel_names)

    channel_types = "eeg"


4.0 Recursos Adicionais

Documentação Oficial

  1. Confira a documentação online, incluindo o arquivo README oficial no GitHub

  2. Recursos adicionais:
    Código para executar LSL usando dispositivos Emotiv, com scripts de exemplo
    • Demonstração útil do LSL no YouTube
    Repositório LSL no GitHub do SCCN para todas as bibliotecas associadas
    Repositório LSL no GitHub para uma coleção de submódulos e aplicativos

  3. Pipeline de análise HyPyP para estudos de Hyperscanning

Bem-vindo! Neste tutorial, vamos aprender como usar o Lab Streaming Layer (LSL) em Python para coletar e sincronizar dados de EEG da Emotiv a partir de múltiplos dispositivos. Isso exigirá um conhecimento básico de trabalho da linguagem de programação Python.

O Que Você Vai Aprender

  1. O que é o Lab Streaming Layer (LSL) e por que os pesquisadores o utilizam

  2. Como coletar dados sincronizados de múltiplos dispositivos de EEG da Emotiv

  3. Como importar e inspecionar os dados coletados

1.1 O Que É LSL e Para Que Serve?

O Lab Streaming Layer (LSL) é uma caixa de ferramentas de código aberto que pode ser usada para enviar, receber e sincronizar fluxos de dados neurais, fisiológicos e comportamentais de diversos hardwares de sensores. Dispositivos de detecção cerebral e corporal cada vez mais capazes, precisos e móveis (como os sistemas de EEG da Emotiv) estão trazendo a neurociência para fora do laboratório, direto para o mundo dos dados em tempo real. Onde medições cerebrais como EEG e MEG antes estavam confinadas a laboratórios de pesquisa, os dispositivos móveis nos permitem coletar múltiplos dados em ambientes mais naturalistas e de várias pessoas ao mesmo tempo.

Um pesquisador pode estar interessado na sincronia fisiológica entre duas pessoas ouvindo a mesma música. O LSL pode nos ajudar a coletar dados de dois headsets de EEG separadamente, que também estejam sincronizados com a apresentação do som.

Alguns exemplos de outros usos para o LSL:

  1. Adicionar marcadores de eventos de um experimento a dados contínuos de EEG

  2. Alinhar no tempo dados de múltiplas fontes para um único participante (ex: frequência cardíaca, EMG, EEG)

  3. Alinhar no tempo dados de múltiplos participantes (ex: Estudos de Hiperscanning de EEG)

1.2 Como o LSL Funciona?

O Lab Streaming Layer é um protocolo para o intercâmbio em tempo real de dados de séries temporais entre múltiplos dispositivos. O LSL pode ser implementado usando bibliotecas de código aberto para linguagens de programação como Python, MATLAB, C++, Java e outras.

A funcionalidade principal gira em torno dos fluxos de dados LSL:

1. Um dispositivo/software de aquisição coleta dados e cria um fluxo de dados - Dados fisiológicos podem ser transmitidos para o LSL a partir de dispositivos de gravação de EEG, rastreadores oculares, sistemas de captura de movimento, monitores de frequência cardíaca, etc., incluindo metadados (taxa de amostragem, tipo de dados, informações de canais, etc.) - Marcadores de eventos de experimentos (ex: usando PsychoPy) também podem ser enviados como um fluxo de dados usando LSL

2. O fluxo de dados é publicado na rede - É assim que os dados são enviados usando LSL; o fluxo de dados é "transmitido" para a rede - Os fluxos publicados estão disponíveis na rede e são detectáveis por outros dispositivos compatíveis com LSL na mesma rede - O LSL atribui a cada bloco de dados ou amostra um carimbo de data/hora com base em um relógio comum (seguindo o Network Time Protocol). - O fluxo é enviado amostra por amostra (ou bloco por bloco) através de uma "saída" (outlet)

3. Os dispositivos de coleta "assinam" os fluxos de dados - É assim que os dados são recebidos usando LSL - Os dispositivos de coleta na mesma rede recebem fluxos de dados publicados por meio de "entradas" (inlets). - Cada entrada recebe as amostras do fluxo e metadados de apenas uma saída

4. Salvar dados - Ao assinar um fluxo de dados, você pode salvá-lo em uma variável na sua linguagem de programação preferida, ou usar o software LabRecorder fornecido pelo LSL para salvá-lo em um formato padrão, como .xdf.

2.0 Visão geral do tutorial

Neste tutorial, usaremos um exemplo de configuração experimental e guiaremos você pelas etapas e códigos necessários para implementá-lo usando LSL em Python. Usaremos o Python para reproduzir um som enquanto coletamos dados de EEG de duas pessoas usando headsets Emotiv. Usaremos dois computadores, cada um executando o EmotivPRO para coletar os dados de EEG e transmitir cada fluxo por meio de uma saída LSL separada. Usaremos uma biblioteca Python para reproduzir um arquivo de áudio e, ao mesmo tempo, enviar um gatilho toda vez que o arquivo for iniciado.

ETAPAS:

1. Use o EmotivPRO para transmitir dados por meio de saídas LSL que incluam dados de EEG (e/ou movimento, qualidade do contato, qualidade do sinal, etc.) 2. Reproduza uma faixa de áudio usando um script Python e, simultaneamente, envie um gatilho por meio de outro LSL. Use o LabRecorder para capturar e salvar todos os três fluxos de dados por meio de uma entrada LSL.

2.1 ETAPA 1 - Configuração e instalação

  1. Você precisará de dispositivos de aquisição de dados compatíveis para coletar dados
    • Todos os de dispositivos de hardware cerebral da Emotiv conectam-se ao LSL via software EmotivPRO

  2. Instale o EmotivPRO no(s) seu(s) dispositivo(s). Você precisará de uma licença do EmotivPRO válida para usar o LSL.

  3. Instale a biblioteca Python LSL com o seguinte comando:
    pip install pylsl

  4. Baixe o software LabRecorder. Trata-se de um aplicativo simples e gratuito que pode ser executado a partir do
    da linha de comando ou usando um download independente

  5. Para o nosso experimento: Instale os pacotes necessários para reproduzir áudio usando Python
    pip install sounddevice soundfile

2.2 ETAPA 3 - Enviar os dados do EmotivPRO via fluxo LSL

  1. Localize os "..." no canto superior direito do aplicativo e navegue até Configurações

  2. Encontre a seção 'Lab Streaming Layer' e a subseção 'Outlet'

  3. Selecione todos os tipos de dados que você gostaria de transmitir

  4. Selecione o formato de dados (float de 32 bits ou double de 64 bits)

  5. Selecione se deseja enviar dados amostra por amostra ou em blocos de amostras

  6. Clique em 'Iniciar' para transmitir um fluxo de dados LSL


2.3 ETAPA 4 - Usar um script Python para reproduzir áudio e enviar gatilhos

  1. Copie e cole o seguinte bloco o código em um arquivo python e salve-o no seu computador.

  2. Localize um arquivo de áudio (idealmente um arquivo .wav) que você gostaria de reproduzir e edite o script alterando a
    variável audio_filepath para o caminho do arquivo de áudio no seu computador

  3. Abra um prompt de comando para interagir com a linha de comando e navegue até a pasta onde
    seu arquivo Python está armazenado

  4. Digite: python3 nome_do_arquivo.py
    • Dependendo da instalação do seu Python, você pode usar python em vez de python3

    Nota: Substitua /path/to/audio.wav pelo local do arquivo de áudio que deseja reproduzir durante o experimento.

"""
Exemplo LSL: Reproduzir áudio e enviar um marcador de gatilho

Este script cria um fluxo de marcadores LSL, aguarda o usuário
pressionar ENTER, depois reproduz um arquivo de áudio e envia um marcador que
pode ser sincronizado com os dados de EEG coletados pelo LabRecorder.
"""

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


def wait_for_keypress():
    print("Pressione ENTER para iniciar a reprodução de áudio e enviar um marcador LSL.")
    while True:
        if input() == "":
            break


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

    print("Reproduzindo áudio e enviando marcador LSL...")

    marker_val = [1]
    outlet.push_sample(marker_val)

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

    print("Reprodução de áudio concluída.")


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 ETAPA 5 - Usar o LabRecorder para visualizar e salvar todos os fluxos LSL

  1. Abra o LabRecorder

  2. Pressione Update. Os fluxos LSL disponíveis devem estar visíveis na lista de fluxos
    • Você deverá conseguir ver os fluxos de ambos os EmotivPROs (normalmente chamados “Emotiv-
    DataStream”) e o fluxo de marcadores (chamado “AudioMarkers”)

  3. Clique em Browse para selecionar um local para armazenar os dados (e definir outros parâmetros)

  4. Selecione todos os fluxos e pressione Record para iniciar a gravação

3.0 Trabalhar com os dados

O LabRecorder gera um arquivo XDF (Extensible Data Format) que contém dados de todos os fluxos. Os arquivos XDF são estruturados em fluxos, cada um com um cabeçalho diferente que descreve o que contém (nome do dispositivo, tipo de dados, taxa de amostragem, canais e muito mais). Você pode usar o bloco de código abaixo para abrir seu arquivo XDF e exibir algumas informações básicas.

Nota: Substitua /path/to/your/file.xdf pelo caminho do arquivo de saída XDF do seu LabRecorder.

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

# Indique o caminho para o seu arquivo de saída LSL aqui.
data_path = "/path/to/your/file.xdf"

# Carrega o arquivo XDF.
streams, fileheader = pyxdf.load_xdf(data_path)

print("Cabeçalho do Arquivo XDF:", fileheader)
print("Número de fluxos encontrados:", len(streams))

for i, stream in enumerate(streams):
    print("\nFluxo", i + 1)
    print("Nome do Fluxo:", stream["info"]["name"][0])
    print("Tipo de Fluxo:", stream["info"]["type"][0])
    print("Número de Canais:", stream["info"]["channel_count"][0])

    sfreq = float(stream["info"]["nominal_srate"][0])
    print("Taxa de Amostragem:", sfreq)

    print("Número de Amostras:", len(stream["time_series"]))
    print("Primeiros 5 pontos de dados:", stream["time_series"][:5])

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

    print("Nomes dos Canais:", channel_names)

    channel_types = "eeg"


4.0 Recursos Adicionais

Documentação Oficial

  1. Confira a documentação online, incluindo o arquivo README oficial no GitHub

  2. Recursos adicionais:
    Código para executar LSL usando dispositivos Emotiv, com scripts de exemplo
    • Demonstração útil do LSL no YouTube
    Repositório LSL no GitHub do SCCN para todas as bibliotecas associadas
    Repositório LSL no GitHub para uma coleção de submódulos e aplicativos

  3. Pipeline de análise HyPyP para estudos de Hyperscanning

Bem-vindo! Neste tutorial, vamos aprender como usar o Lab Streaming Layer (LSL) em Python para coletar e sincronizar dados de EEG da Emotiv a partir de múltiplos dispositivos. Isso exigirá um conhecimento básico de trabalho da linguagem de programação Python.

O Que Você Vai Aprender

  1. O que é o Lab Streaming Layer (LSL) e por que os pesquisadores o utilizam

  2. Como coletar dados sincronizados de múltiplos dispositivos de EEG da Emotiv

  3. Como importar e inspecionar os dados coletados

1.1 O Que É LSL e Para Que Serve?

O Lab Streaming Layer (LSL) é uma caixa de ferramentas de código aberto que pode ser usada para enviar, receber e sincronizar fluxos de dados neurais, fisiológicos e comportamentais de diversos hardwares de sensores. Dispositivos de detecção cerebral e corporal cada vez mais capazes, precisos e móveis (como os sistemas de EEG da Emotiv) estão trazendo a neurociência para fora do laboratório, direto para o mundo dos dados em tempo real. Onde medições cerebrais como EEG e MEG antes estavam confinadas a laboratórios de pesquisa, os dispositivos móveis nos permitem coletar múltiplos dados em ambientes mais naturalistas e de várias pessoas ao mesmo tempo.

Um pesquisador pode estar interessado na sincronia fisiológica entre duas pessoas ouvindo a mesma música. O LSL pode nos ajudar a coletar dados de dois headsets de EEG separadamente, que também estejam sincronizados com a apresentação do som.

Alguns exemplos de outros usos para o LSL:

  1. Adicionar marcadores de eventos de um experimento a dados contínuos de EEG

  2. Alinhar no tempo dados de múltiplas fontes para um único participante (ex: frequência cardíaca, EMG, EEG)

  3. Alinhar no tempo dados de múltiplos participantes (ex: Estudos de Hiperscanning de EEG)

1.2 Como o LSL Funciona?

O Lab Streaming Layer é um protocolo para o intercâmbio em tempo real de dados de séries temporais entre múltiplos dispositivos. O LSL pode ser implementado usando bibliotecas de código aberto para linguagens de programação como Python, MATLAB, C++, Java e outras.

A funcionalidade principal gira em torno dos fluxos de dados LSL:

1. Um dispositivo/software de aquisição coleta dados e cria um fluxo de dados - Dados fisiológicos podem ser transmitidos para o LSL a partir de dispositivos de gravação de EEG, rastreadores oculares, sistemas de captura de movimento, monitores de frequência cardíaca, etc., incluindo metadados (taxa de amostragem, tipo de dados, informações de canais, etc.) - Marcadores de eventos de experimentos (ex: usando PsychoPy) também podem ser enviados como um fluxo de dados usando LSL

2. O fluxo de dados é publicado na rede - É assim que os dados são enviados usando LSL; o fluxo de dados é "transmitido" para a rede - Os fluxos publicados estão disponíveis na rede e são detectáveis por outros dispositivos compatíveis com LSL na mesma rede - O LSL atribui a cada bloco de dados ou amostra um carimbo de data/hora com base em um relógio comum (seguindo o Network Time Protocol). - O fluxo é enviado amostra por amostra (ou bloco por bloco) através de uma "saída" (outlet)

3. Os dispositivos de coleta "assinam" os fluxos de dados - É assim que os dados são recebidos usando LSL - Os dispositivos de coleta na mesma rede recebem fluxos de dados publicados por meio de "entradas" (inlets). - Cada entrada recebe as amostras do fluxo e metadados de apenas uma saída

4. Salvar dados - Ao assinar um fluxo de dados, você pode salvá-lo em uma variável na sua linguagem de programação preferida, ou usar o software LabRecorder fornecido pelo LSL para salvá-lo em um formato padrão, como .xdf.

2.0 Visão geral do tutorial

Neste tutorial, usaremos um exemplo de configuração experimental e guiaremos você pelas etapas e códigos necessários para implementá-lo usando LSL em Python. Usaremos o Python para reproduzir um som enquanto coletamos dados de EEG de duas pessoas usando headsets Emotiv. Usaremos dois computadores, cada um executando o EmotivPRO para coletar os dados de EEG e transmitir cada fluxo por meio de uma saída LSL separada. Usaremos uma biblioteca Python para reproduzir um arquivo de áudio e, ao mesmo tempo, enviar um gatilho toda vez que o arquivo for iniciado.

ETAPAS:

1. Use o EmotivPRO para transmitir dados por meio de saídas LSL que incluam dados de EEG (e/ou movimento, qualidade do contato, qualidade do sinal, etc.) 2. Reproduza uma faixa de áudio usando um script Python e, simultaneamente, envie um gatilho por meio de outro LSL. Use o LabRecorder para capturar e salvar todos os três fluxos de dados por meio de uma entrada LSL.

2.1 ETAPA 1 - Configuração e instalação

  1. Você precisará de dispositivos de aquisição de dados compatíveis para coletar dados
    • Todos os de dispositivos de hardware cerebral da Emotiv conectam-se ao LSL via software EmotivPRO

  2. Instale o EmotivPRO no(s) seu(s) dispositivo(s). Você precisará de uma licença do EmotivPRO válida para usar o LSL.

  3. Instale a biblioteca Python LSL com o seguinte comando:
    pip install pylsl

  4. Baixe o software LabRecorder. Trata-se de um aplicativo simples e gratuito que pode ser executado a partir do
    da linha de comando ou usando um download independente

  5. Para o nosso experimento: Instale os pacotes necessários para reproduzir áudio usando Python
    pip install sounddevice soundfile

2.2 ETAPA 3 - Enviar os dados do EmotivPRO via fluxo LSL

  1. Localize os "..." no canto superior direito do aplicativo e navegue até Configurações

  2. Encontre a seção 'Lab Streaming Layer' e a subseção 'Outlet'

  3. Selecione todos os tipos de dados que você gostaria de transmitir

  4. Selecione o formato de dados (float de 32 bits ou double de 64 bits)

  5. Selecione se deseja enviar dados amostra por amostra ou em blocos de amostras

  6. Clique em 'Iniciar' para transmitir um fluxo de dados LSL


2.3 ETAPA 4 - Usar um script Python para reproduzir áudio e enviar gatilhos

  1. Copie e cole o seguinte bloco o código em um arquivo python e salve-o no seu computador.

  2. Localize um arquivo de áudio (idealmente um arquivo .wav) que você gostaria de reproduzir e edite o script alterando a
    variável audio_filepath para o caminho do arquivo de áudio no seu computador

  3. Abra um prompt de comando para interagir com a linha de comando e navegue até a pasta onde
    seu arquivo Python está armazenado

  4. Digite: python3 nome_do_arquivo.py
    • Dependendo da instalação do seu Python, você pode usar python em vez de python3

    Nota: Substitua /path/to/audio.wav pelo local do arquivo de áudio que deseja reproduzir durante o experimento.

"""
Exemplo LSL: Reproduzir áudio e enviar um marcador de gatilho

Este script cria um fluxo de marcadores LSL, aguarda o usuário
pressionar ENTER, depois reproduz um arquivo de áudio e envia um marcador que
pode ser sincronizado com os dados de EEG coletados pelo LabRecorder.
"""

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


def wait_for_keypress():
    print("Pressione ENTER para iniciar a reprodução de áudio e enviar um marcador LSL.")
    while True:
        if input() == "":
            break


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

    print("Reproduzindo áudio e enviando marcador LSL...")

    marker_val = [1]
    outlet.push_sample(marker_val)

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

    print("Reprodução de áudio concluída.")


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 ETAPA 5 - Usar o LabRecorder para visualizar e salvar todos os fluxos LSL

  1. Abra o LabRecorder

  2. Pressione Update. Os fluxos LSL disponíveis devem estar visíveis na lista de fluxos
    • Você deverá conseguir ver os fluxos de ambos os EmotivPROs (normalmente chamados “Emotiv-
    DataStream”) e o fluxo de marcadores (chamado “AudioMarkers”)

  3. Clique em Browse para selecionar um local para armazenar os dados (e definir outros parâmetros)

  4. Selecione todos os fluxos e pressione Record para iniciar a gravação

3.0 Trabalhar com os dados

O LabRecorder gera um arquivo XDF (Extensible Data Format) que contém dados de todos os fluxos. Os arquivos XDF são estruturados em fluxos, cada um com um cabeçalho diferente que descreve o que contém (nome do dispositivo, tipo de dados, taxa de amostragem, canais e muito mais). Você pode usar o bloco de código abaixo para abrir seu arquivo XDF e exibir algumas informações básicas.

Nota: Substitua /path/to/your/file.xdf pelo caminho do arquivo de saída XDF do seu LabRecorder.

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

# Indique o caminho para o seu arquivo de saída LSL aqui.
data_path = "/path/to/your/file.xdf"

# Carrega o arquivo XDF.
streams, fileheader = pyxdf.load_xdf(data_path)

print("Cabeçalho do Arquivo XDF:", fileheader)
print("Número de fluxos encontrados:", len(streams))

for i, stream in enumerate(streams):
    print("\nFluxo", i + 1)
    print("Nome do Fluxo:", stream["info"]["name"][0])
    print("Tipo de Fluxo:", stream["info"]["type"][0])
    print("Número de Canais:", stream["info"]["channel_count"][0])

    sfreq = float(stream["info"]["nominal_srate"][0])
    print("Taxa de Amostragem:", sfreq)

    print("Número de Amostras:", len(stream["time_series"]))
    print("Primeiros 5 pontos de dados:", stream["time_series"][:5])

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

    print("Nomes dos Canais:", channel_names)

    channel_types = "eeg"


4.0 Recursos Adicionais

Documentação Oficial

  1. Confira a documentação online, incluindo o arquivo README oficial no GitHub

  2. Recursos adicionais:
    Código para executar LSL usando dispositivos Emotiv, com scripts de exemplo
    • Demonstração útil do LSL no YouTube
    Repositório LSL no GitHub do SCCN para todas as bibliotecas associadas
    Repositório LSL no GitHub para uma coleção de submódulos e aplicativos

  3. Pipeline de análise HyPyP para estudos de Hyperscanning

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

Continue lendo

Basics of Neural Oscillations