
複数データストリーム同期のためのLab Streaming Layer (LSL)
ロシニ・ランデニヤ博士とルーカス・クライネ
更新日
2024/05/17

複数データストリーム同期のためのLab Streaming Layer (LSL)
ロシニ・ランデニヤ博士とルーカス・クライネ
更新日
2024/05/17

複数データストリーム同期のためのLab Streaming Layer (LSL)
ロシニ・ランデニヤ博士とルーカス・クライネ
更新日
2024/05/17
ようこそ!このチュートリアルでは、PythonでLab Streaming Layer(LSL)を使用して、複数のデバイスからEmotivのEEGデータを収集および同期する方法について学びます。本チュートリアルの受講には、Pythonプログラミング言語に関する基本的な知識が必要となります。
学習内容
Lab Streaming Layer(LSL)とは何か、そしてなぜ研究者がそれを使用するのか
複数のEmotiv EEGデバイスから同期されたデータを収集する方法
収集したデータのインポートと検証方法
1.1 LSLとは何か、そして何に役立つのか?
Lab Streaming Layer(LSL)は、さまざまなセンサーハードウェアからの神経、生理、行動データストリームの送信、受信、同期に使用できるオープンソースのツールボックスです。Emotiv EEGシステムのような、ますます高機能で高精度、かつモバイルな脳・身体測定ハードウェアデバイスの登場により、神経科学はラボから飛び出し、リアルタイムデータの世界へと移行しつつあります。かつて、EEGやMEGなどの脳測定は研究ラボ内に限定されていましたが、モバイルデバイスの登場により、より自然な環境下で、同時に複数人から多様なデータを収集することが可能になりました。
研究者は、同じ音楽を聴いている2人の間の生理的な同調(シンクロニー)に関心を持つかもしれません。LSLを使用すれば、音の提示に同期させながら、2つのEEGヘッドセットから個別にデータを収集できます。
LSLのその他の活用例:
実験中のイベントマーカーを、進行中のEEGデータに追加する
単一の被験者に対する複数のソース(心拍数、EMG、EEGなど)からのデータを時間調整する
複数の被験者からのデータを時間調整する(例:EEGハイパースキャニング研究)
1.2 LSLはどのように機能するのか?
Lab Streaming Layerは、複数のデバイス間で時系列データをリアルタイムで交換するためのプロトコルです。LSLは、Python、MATLAB、C++、Javaなどのプログラミング言語用のオープンソースライブラリを使用して実装できます。

主な機能は、LSLのデータストリームを中心に展開します:
1. 計測デバイス/ソフトウェアがデータを収集し、データストリームを作成する - 生理データは、EEG記録デバイス、アイトラッカー、モーションキャプチャシステム、心拍モニターなどから、メタデータ(サンプリングレート、データタイプ、チャネル情報など)とともにLSLへストリーミングできます。実験からのイベントマーカー(PsychoPyなどを使用)も、LSLを使用してデータストリームとして送信できます。
2. データストリームがネットワークに公開(パブリッシュ)される - これがLSLを使用したデータ送信方法です。データストリームはネットワークに「ブロードキャスト」されます。公開されたストリームはネットワーク上で利用可能になり、同じネットワーク上の他のLSL対応デバイスから検出できるようになります。LSLは、共通のクロック(Network Time Protocolに準拠)に基づいて、各データチャンクまたはサンプルにタイムスタンプを割り当てます。ストリームは「アウトレット(outlet)」を通じてサンプルごと(またはチャンクごと)にプッシュされます。
3. 収集デバイスがデータストリームを「購読(サブスクライブ)」する - これがLSLを使用したデータ受信方法です。同じネットワーク上の収集デバイスは、「インレット(inlet)」を介して公開されたデータストリームを受信します。各インレットは、1つのアウトレットのみからストリームのサンプルとメタデータを受信します。
4. データを保存する - データストリームを購読すると、好みのプログラミング言語の変数に保存したり、LSLが提供するソフトウェア「LabRecorder」を使用して.xdfなどの標準フォーマットに保存したりできます。
2.0 チュートリアルの概要
このチュートリアルでは、実験セットアップの例を取り上げ、PythonでLSLを使用してそれを実装するために必要な手順とコードを案内します。Pythonを使用してEmotivヘッドセットを装着した2人からEEGデータを収集しながら、音声を再生します。それぞれEmotivPROを実行している2台のコンピュータを使用してEEGデータを収集し、各ストリームを別々のLSLアウトレットからブロードキャストします。Pythonライブラリを使用してオーディオファイルを再生し、ファイルが開始されるたびに同時にトリガーを送信します。
手順:
1. EmotivPROを使用して、EEGデータ(および/またはモーション、コンタクトクオリティ、シグナルクオリティなど)を含むLSLアウトレット経由でデータをストリーミングします。2. Pythonスクリプトを使用してオーディオトラックを再生し、同時に別のLSL経由でトリガーを送信します。LabRecorderを使用して、LSLインレット経由ですべての3つのデータストリームをキャプチャして保存します。

2.1 ステップ 1 - セットアップとインストール
データを収集するためにサポートされているデータ計測デバイスが必要になります。
• すべてのEmotivのブレインウェアデバイスは、EmotivPROソフトウェアを介してLSLに接続します。デバイスにEmotivPROをインストールします。LSLを使用するには、有効なEmotivPROライセンスが必要です。
次のコマンドでPython LSLライブラリをインストールします:
pip install pylslLabRecorderソフトウェアをダウンロードします。これはコマンドラインから実行するか、スタンドアロン版をダウンロードして実行できる、シンプルで無料のアプリです。
今回の実験用:Pythonを使用してオーディオを再生するために必要なパッケージをインストールします。
pip install sounddevice soundfile
2.2 ステップ 2 (3) - EmotivPROからLSLストリーム経由でデータを送信する
アプリの右上隅にある「...」を見つけ、Settings(設定)に移動します
「Lab Streaming Layer」セクションと「Outlet」サブセクションを見つけます
ブロードキャストしたいすべてのデータタイプを選択します
データフォーマットを選択します(32ビット浮動小数点数または64ビット倍精度小数点数)
データをサンプルごとに送信するか、サンプルのチャンクごとに送信するかを選択します
「Start」をクリックして、LSLデータストリームのブロードキャストを開始します
2.3 ステップ 3 (4) - Pythonスクリプトを使用してオーディオを再生しトリガーを送信する
以下のコードブロックをコピーしてpythonファイルに貼り付け、コンピュータに保存します。
再生したいオーディオファイル(できれば.wavファイル)を用意し、変数
audio_filepathをコンピュータ上のオーディオファイルへのパスに変更して、スクリプトを編集します。コマンドプロンプトを開いてコマンドラインを操作し、Pythonファイルが保存されているフォルダに移動します
「
python3 ファイル名.py」と入力します。
• Pythonのインストール状況によっては、python3の代わりにpythonを使用する場合もあります。
重要:/path/to/audio.wavを、実験中に再生したいオーディオファイルの場所(パス)に置き換えてください。
""" LSLの実例: オーディオを再生しトリガーマーカーを送信する このスクリプトは、LSLマーカーストリームを作成し、ユーザーが ENTERキーを押すのを待ってから、オーディオファイルを再生し、 LabRecorderを介して収集されたEEGデータと同期できるマーカーを送信します。 """ import sounddevice as sd import soundfile as sf from pylsl import StreamInfo, StreamOutlet def wait_for_keypress(): print("ENTERを押すとオーディオ再生を開始し、LSLマーカーを送信します。") while True: if input() == "": break def play_audio_and_send_marker(audio_file, outlet): data, fs = sf.read(audio_file) print("オーディオを再生し、LSLマーカーを送信中...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("オーディオ再生が完了しました。") 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の実例: オーディオを再生しトリガーマーカーを送信する このスクリプトは、LSLマーカーストリームを作成し、ユーザーが ENTERキーを押すのを待ってから、オーディオファイルを再生し、 LabRecorderを介して収集されたEEGデータと同期できるマーカーを送信します。 """ import sounddevice as sd import soundfile as sf from pylsl import StreamInfo, StreamOutlet def wait_for_keypress(): print("ENTERを押すとオーディオ再生を開始し、LSLマーカーを送信します。") while True: if input() == "": break def play_audio_and_send_marker(audio_file, outlet): data, fs = sf.read(audio_file) print("オーディオを再生し、LSLマーカーを送信中...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("オーディオ再生が完了しました。") 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の実例: オーディオを再生しトリガーマーカーを送信する このスクリプトは、LSLマーカーストリームを作成し、ユーザーが ENTERキーを押すのを待ってから、オーディオファイルを再生し、 LabRecorderを介して収集されたEEGデータと同期できるマーカーを送信します。 """ import sounddevice as sd import soundfile as sf from pylsl import StreamInfo, StreamOutlet def wait_for_keypress(): print("ENTERを押すとオーディオ再生を開始し、LSLマーカーを送信します。") while True: if input() == "": break def play_audio_and_send_marker(audio_file, outlet): data, fs = sf.read(audio_file) print("オーディオを再生し、LSLマーカーを送信中...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("オーディオ再生が完了しました。") 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 ステップ 4 (5) - LabRecorderを使用して、すべてのLSLストリームを表示および保存する
LabRecorderを開きます
Updateを押します。利用可能なLSLストリームがストリームリストに表示されるはずです
• 両方のEmotivPRO(通常は「Emotiv-DataStream」と呼ばれる)からのストリームと、マーカーストリーム(「AudioMarkers」と呼ばれる)が表示されるはずですBrowseをクリックしてデータを保存する場所を選択します(他のパラメータの設定も行います)すべてのストリームを選択し、
Recordを押して録画/録音を開始します
3.0 データの操作方法
LabRecorderは、すべてのストリームからのデータを含むXDFファイル(Extensible Data Format)を出力します。XDFファイルは複数のストリームで構成されており、各ストリームには含まれる内容(デバイス名、データタイプ、サンプリングレート、チャネルなど)を説明する異なるヘッダーがあります。以下のコードブロックを使用して、XDFファイルを開き、基本情報を表示できます。
注意:/path/to/your/file.xdf を、LabRecorderで出力されたXDFファイルのパスに置き換えてください。
import pyxdf import mne import matplotlib.pyplot as plt import numpy as np # ここにLSL出力ファイルへのパスを指定します。 data_path = "/path/to/your/file.xdf" # XDFファイルを読み込みます。 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["info"]["name"][0]) print("ストリームタイプ:", stream["info"]["type"][0]) print("チャネル数:", stream["info"]["channel_count"][0]) sfreq = float(stream["info"]["nominal_srate"][0]) print("サンプリングレート:", sfreq) print("サンプル数:", len(stream["time_series"])) print("最初の5つのデータポイント:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("チャネル名:", channel_names) channel_types = "eeg"
import pyxdf import mne import matplotlib.pyplot as plt import numpy as np # ここにLSL出力ファイルへのパスを指定します。 data_path = "/path/to/your/file.xdf" # XDFファイルを読み込みます。 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["info"]["name"][0]) print("ストリームタイプ:", stream["info"]["type"][0]) print("チャネル数:", stream["info"]["channel_count"][0]) sfreq = float(stream["info"]["nominal_srate"][0]) print("サンプリングレート:", sfreq) print("サンプル数:", len(stream["time_series"])) print("最初の5つのデータポイント:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("チャネル名:", channel_names) channel_types = "eeg"
import pyxdf import mne import matplotlib.pyplot as plt import numpy as np # ここにLSL出力ファイルへのパスを指定します。 data_path = "/path/to/your/file.xdf" # XDFファイルを読み込みます。 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["info"]["name"][0]) print("ストリームタイプ:", stream["info"]["type"][0]) print("チャネル数:", stream["info"]["channel_count"][0]) sfreq = float(stream["info"]["nominal_srate"][0]) print("サンプリングレート:", sfreq) print("サンプル数:", len(stream["time_series"])) print("最初の5つのデータポイント:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("チャネル名:", channel_names) channel_types = "eeg"
4.0 その他のリソース
公式ドキュメント
オンラインドキュメントや、GitHubにある公式のREADMEファイルを確認してください
その他のリソース:
• サンプルスクリプトを含む、Emotivのデバイスを使用してLSLを実行するためのコード
• 有益なYouTube上のLSLデモ
• すべての関連ライブラリを網羅したSCCN LSL GitHubリポジトリ
• サブモジュールやアプリがまとめられたLSL GitHubリポジトリハイパースキャニング研究用のHyPyP解析パイプライン
ようこそ!このチュートリアルでは、PythonでLab Streaming Layer(LSL)を使用して、複数のデバイスからEmotivのEEGデータを収集および同期する方法について学びます。本チュートリアルの受講には、Pythonプログラミング言語に関する基本的な知識が必要となります。
学習内容
Lab Streaming Layer(LSL)とは何か、そしてなぜ研究者がそれを使用するのか
複数のEmotiv EEGデバイスから同期されたデータを収集する方法
収集したデータのインポートと検証方法
1.1 LSLとは何か、そして何に役立つのか?
Lab Streaming Layer(LSL)は、さまざまなセンサーハードウェアからの神経、生理、行動データストリームの送信、受信、同期に使用できるオープンソースのツールボックスです。Emotiv EEGシステムのような、ますます高機能で高精度、かつモバイルな脳・身体測定ハードウェアデバイスの登場により、神経科学はラボから飛び出し、リアルタイムデータの世界へと移行しつつあります。かつて、EEGやMEGなどの脳測定は研究ラボ内に限定されていましたが、モバイルデバイスの登場により、より自然な環境下で、同時に複数人から多様なデータを収集することが可能になりました。
研究者は、同じ音楽を聴いている2人の間の生理的な同調(シンクロニー)に関心を持つかもしれません。LSLを使用すれば、音の提示に同期させながら、2つのEEGヘッドセットから個別にデータを収集できます。
LSLのその他の活用例:
実験中のイベントマーカーを、進行中のEEGデータに追加する
単一の被験者に対する複数のソース(心拍数、EMG、EEGなど)からのデータを時間調整する
複数の被験者からのデータを時間調整する(例:EEGハイパースキャニング研究)
1.2 LSLはどのように機能するのか?
Lab Streaming Layerは、複数のデバイス間で時系列データをリアルタイムで交換するためのプロトコルです。LSLは、Python、MATLAB、C++、Javaなどのプログラミング言語用のオープンソースライブラリを使用して実装できます。

主な機能は、LSLのデータストリームを中心に展開します:
1. 計測デバイス/ソフトウェアがデータを収集し、データストリームを作成する - 生理データは、EEG記録デバイス、アイトラッカー、モーションキャプチャシステム、心拍モニターなどから、メタデータ(サンプリングレート、データタイプ、チャネル情報など)とともにLSLへストリーミングできます。実験からのイベントマーカー(PsychoPyなどを使用)も、LSLを使用してデータストリームとして送信できます。
2. データストリームがネットワークに公開(パブリッシュ)される - これがLSLを使用したデータ送信方法です。データストリームはネットワークに「ブロードキャスト」されます。公開されたストリームはネットワーク上で利用可能になり、同じネットワーク上の他のLSL対応デバイスから検出できるようになります。LSLは、共通のクロック(Network Time Protocolに準拠)に基づいて、各データチャンクまたはサンプルにタイムスタンプを割り当てます。ストリームは「アウトレット(outlet)」を通じてサンプルごと(またはチャンクごと)にプッシュされます。
3. 収集デバイスがデータストリームを「購読(サブスクライブ)」する - これがLSLを使用したデータ受信方法です。同じネットワーク上の収集デバイスは、「インレット(inlet)」を介して公開されたデータストリームを受信します。各インレットは、1つのアウトレットのみからストリームのサンプルとメタデータを受信します。
4. データを保存する - データストリームを購読すると、好みのプログラミング言語の変数に保存したり、LSLが提供するソフトウェア「LabRecorder」を使用して.xdfなどの標準フォーマットに保存したりできます。
2.0 チュートリアルの概要
このチュートリアルでは、実験セットアップの例を取り上げ、PythonでLSLを使用してそれを実装するために必要な手順とコードを案内します。Pythonを使用してEmotivヘッドセットを装着した2人からEEGデータを収集しながら、音声を再生します。それぞれEmotivPROを実行している2台のコンピュータを使用してEEGデータを収集し、各ストリームを別々のLSLアウトレットからブロードキャストします。Pythonライブラリを使用してオーディオファイルを再生し、ファイルが開始されるたびに同時にトリガーを送信します。
手順:
1. EmotivPROを使用して、EEGデータ(および/またはモーション、コンタクトクオリティ、シグナルクオリティなど)を含むLSLアウトレット経由でデータをストリーミングします。2. Pythonスクリプトを使用してオーディオトラックを再生し、同時に別のLSL経由でトリガーを送信します。LabRecorderを使用して、LSLインレット経由ですべての3つのデータストリームをキャプチャして保存します。

2.1 ステップ 1 - セットアップとインストール
データを収集するためにサポートされているデータ計測デバイスが必要になります。
• すべてのEmotivのブレインウェアデバイスは、EmotivPROソフトウェアを介してLSLに接続します。デバイスにEmotivPROをインストールします。LSLを使用するには、有効なEmotivPROライセンスが必要です。
次のコマンドでPython LSLライブラリをインストールします:
pip install pylslLabRecorderソフトウェアをダウンロードします。これはコマンドラインから実行するか、スタンドアロン版をダウンロードして実行できる、シンプルで無料のアプリです。
今回の実験用:Pythonを使用してオーディオを再生するために必要なパッケージをインストールします。
pip install sounddevice soundfile
2.2 ステップ 2 (3) - EmotivPROからLSLストリーム経由でデータを送信する
アプリの右上隅にある「...」を見つけ、Settings(設定)に移動します
「Lab Streaming Layer」セクションと「Outlet」サブセクションを見つけます
ブロードキャストしたいすべてのデータタイプを選択します
データフォーマットを選択します(32ビット浮動小数点数または64ビット倍精度小数点数)
データをサンプルごとに送信するか、サンプルのチャンクごとに送信するかを選択します
「Start」をクリックして、LSLデータストリームのブロードキャストを開始します
2.3 ステップ 3 (4) - Pythonスクリプトを使用してオーディオを再生しトリガーを送信する
以下のコードブロックをコピーしてpythonファイルに貼り付け、コンピュータに保存します。
再生したいオーディオファイル(できれば.wavファイル)を用意し、変数
audio_filepathをコンピュータ上のオーディオファイルへのパスに変更して、スクリプトを編集します。コマンドプロンプトを開いてコマンドラインを操作し、Pythonファイルが保存されているフォルダに移動します
「
python3 ファイル名.py」と入力します。
• Pythonのインストール状況によっては、python3の代わりにpythonを使用する場合もあります。
重要:/path/to/audio.wavを、実験中に再生したいオーディオファイルの場所(パス)に置き換えてください。
""" LSLの実例: オーディオを再生しトリガーマーカーを送信する このスクリプトは、LSLマーカーストリームを作成し、ユーザーが ENTERキーを押すのを待ってから、オーディオファイルを再生し、 LabRecorderを介して収集されたEEGデータと同期できるマーカーを送信します。 """ import sounddevice as sd import soundfile as sf from pylsl import StreamInfo, StreamOutlet def wait_for_keypress(): print("ENTERを押すとオーディオ再生を開始し、LSLマーカーを送信します。") while True: if input() == "": break def play_audio_and_send_marker(audio_file, outlet): data, fs = sf.read(audio_file) print("オーディオを再生し、LSLマーカーを送信中...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("オーディオ再生が完了しました。") 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 ステップ 4 (5) - LabRecorderを使用して、すべてのLSLストリームを表示および保存する
LabRecorderを開きます
Updateを押します。利用可能なLSLストリームがストリームリストに表示されるはずです
• 両方のEmotivPRO(通常は「Emotiv-DataStream」と呼ばれる)からのストリームと、マーカーストリーム(「AudioMarkers」と呼ばれる)が表示されるはずですBrowseをクリックしてデータを保存する場所を選択します(他のパラメータの設定も行います)すべてのストリームを選択し、
Recordを押して録画/録音を開始します
3.0 データの操作方法
LabRecorderは、すべてのストリームからのデータを含むXDFファイル(Extensible Data Format)を出力します。XDFファイルは複数のストリームで構成されており、各ストリームには含まれる内容(デバイス名、データタイプ、サンプリングレート、チャネルなど)を説明する異なるヘッダーがあります。以下のコードブロックを使用して、XDFファイルを開き、基本情報を表示できます。
注意:/path/to/your/file.xdf を、LabRecorderで出力されたXDFファイルのパスに置き換えてください。
import pyxdf import mne import matplotlib.pyplot as plt import numpy as np # ここにLSL出力ファイルへのパスを指定します。 data_path = "/path/to/your/file.xdf" # XDFファイルを読み込みます。 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["info"]["name"][0]) print("ストリームタイプ:", stream["info"]["type"][0]) print("チャネル数:", stream["info"]["channel_count"][0]) sfreq = float(stream["info"]["nominal_srate"][0]) print("サンプリングレート:", sfreq) print("サンプル数:", len(stream["time_series"])) print("最初の5つのデータポイント:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("チャネル名:", channel_names) channel_types = "eeg"
4.0 その他のリソース
公式ドキュメント
オンラインドキュメントや、GitHubにある公式のREADMEファイルを確認してください
その他のリソース:
• サンプルスクリプトを含む、Emotivのデバイスを使用してLSLを実行するためのコード
• 有益なYouTube上のLSLデモ
• すべての関連ライブラリを網羅したSCCN LSL GitHubリポジトリ
• サブモジュールやアプリがまとめられたLSL GitHubリポジトリハイパースキャニング研究用のHyPyP解析パイプライン
ようこそ!このチュートリアルでは、PythonでLab Streaming Layer(LSL)を使用して、複数のデバイスからEmotivのEEGデータを収集および同期する方法について学びます。本チュートリアルの受講には、Pythonプログラミング言語に関する基本的な知識が必要となります。
学習内容
Lab Streaming Layer(LSL)とは何か、そしてなぜ研究者がそれを使用するのか
複数のEmotiv EEGデバイスから同期されたデータを収集する方法
収集したデータのインポートと検証方法
1.1 LSLとは何か、そして何に役立つのか?
Lab Streaming Layer(LSL)は、さまざまなセンサーハードウェアからの神経、生理、行動データストリームの送信、受信、同期に使用できるオープンソースのツールボックスです。Emotiv EEGシステムのような、ますます高機能で高精度、かつモバイルな脳・身体測定ハードウェアデバイスの登場により、神経科学はラボから飛び出し、リアルタイムデータの世界へと移行しつつあります。かつて、EEGやMEGなどの脳測定は研究ラボ内に限定されていましたが、モバイルデバイスの登場により、より自然な環境下で、同時に複数人から多様なデータを収集することが可能になりました。
研究者は、同じ音楽を聴いている2人の間の生理的な同調(シンクロニー)に関心を持つかもしれません。LSLを使用すれば、音の提示に同期させながら、2つのEEGヘッドセットから個別にデータを収集できます。
LSLのその他の活用例:
実験中のイベントマーカーを、進行中のEEGデータに追加する
単一の被験者に対する複数のソース(心拍数、EMG、EEGなど)からのデータを時間調整する
複数の被験者からのデータを時間調整する(例:EEGハイパースキャニング研究)
1.2 LSLはどのように機能するのか?
Lab Streaming Layerは、複数のデバイス間で時系列データをリアルタイムで交換するためのプロトコルです。LSLは、Python、MATLAB、C++、Javaなどのプログラミング言語用のオープンソースライブラリを使用して実装できます。

主な機能は、LSLのデータストリームを中心に展開します:
1. 計測デバイス/ソフトウェアがデータを収集し、データストリームを作成する - 生理データは、EEG記録デバイス、アイトラッカー、モーションキャプチャシステム、心拍モニターなどから、メタデータ(サンプリングレート、データタイプ、チャネル情報など)とともにLSLへストリーミングできます。実験からのイベントマーカー(PsychoPyなどを使用)も、LSLを使用してデータストリームとして送信できます。
2. データストリームがネットワークに公開(パブリッシュ)される - これがLSLを使用したデータ送信方法です。データストリームはネットワークに「ブロードキャスト」されます。公開されたストリームはネットワーク上で利用可能になり、同じネットワーク上の他のLSL対応デバイスから検出できるようになります。LSLは、共通のクロック(Network Time Protocolに準拠)に基づいて、各データチャンクまたはサンプルにタイムスタンプを割り当てます。ストリームは「アウトレット(outlet)」を通じてサンプルごと(またはチャンクごと)にプッシュされます。
3. 収集デバイスがデータストリームを「購読(サブスクライブ)」する - これがLSLを使用したデータ受信方法です。同じネットワーク上の収集デバイスは、「インレット(inlet)」を介して公開されたデータストリームを受信します。各インレットは、1つのアウトレットのみからストリームのサンプルとメタデータを受信します。
4. データを保存する - データストリームを購読すると、好みのプログラミング言語の変数に保存したり、LSLが提供するソフトウェア「LabRecorder」を使用して.xdfなどの標準フォーマットに保存したりできます。
2.0 チュートリアルの概要
このチュートリアルでは、実験セットアップの例を取り上げ、PythonでLSLを使用してそれを実装するために必要な手順とコードを案内します。Pythonを使用してEmotivヘッドセットを装着した2人からEEGデータを収集しながら、音声を再生します。それぞれEmotivPROを実行している2台のコンピュータを使用してEEGデータを収集し、各ストリームを別々のLSLアウトレットからブロードキャストします。Pythonライブラリを使用してオーディオファイルを再生し、ファイルが開始されるたびに同時にトリガーを送信します。
手順:
1. EmotivPROを使用して、EEGデータ(および/またはモーション、コンタクトクオリティ、シグナルクオリティなど)を含むLSLアウトレット経由でデータをストリーミングします。2. Pythonスクリプトを使用してオーディオトラックを再生し、同時に別のLSL経由でトリガーを送信します。LabRecorderを使用して、LSLインレット経由ですべての3つのデータストリームをキャプチャして保存します。

2.1 ステップ 1 - セットアップとインストール
データを収集するためにサポートされているデータ計測デバイスが必要になります。
• すべてのEmotivのブレインウェアデバイスは、EmotivPROソフトウェアを介してLSLに接続します。デバイスにEmotivPROをインストールします。LSLを使用するには、有効なEmotivPROライセンスが必要です。
次のコマンドでPython LSLライブラリをインストールします:
pip install pylslLabRecorderソフトウェアをダウンロードします。これはコマンドラインから実行するか、スタンドアロン版をダウンロードして実行できる、シンプルで無料のアプリです。
今回の実験用:Pythonを使用してオーディオを再生するために必要なパッケージをインストールします。
pip install sounddevice soundfile
2.2 ステップ 2 (3) - EmotivPROからLSLストリーム経由でデータを送信する
アプリの右上隅にある「...」を見つけ、Settings(設定)に移動します
「Lab Streaming Layer」セクションと「Outlet」サブセクションを見つけます
ブロードキャストしたいすべてのデータタイプを選択します
データフォーマットを選択します(32ビット浮動小数点数または64ビット倍精度小数点数)
データをサンプルごとに送信するか、サンプルのチャンクごとに送信するかを選択します
「Start」をクリックして、LSLデータストリームのブロードキャストを開始します
2.3 ステップ 3 (4) - Pythonスクリプトを使用してオーディオを再生しトリガーを送信する
以下のコードブロックをコピーしてpythonファイルに貼り付け、コンピュータに保存します。
再生したいオーディオファイル(できれば.wavファイル)を用意し、変数
audio_filepathをコンピュータ上のオーディオファイルへのパスに変更して、スクリプトを編集します。コマンドプロンプトを開いてコマンドラインを操作し、Pythonファイルが保存されているフォルダに移動します
「
python3 ファイル名.py」と入力します。
• Pythonのインストール状況によっては、python3の代わりにpythonを使用する場合もあります。
重要:/path/to/audio.wavを、実験中に再生したいオーディオファイルの場所(パス)に置き換えてください。
""" LSLの実例: オーディオを再生しトリガーマーカーを送信する このスクリプトは、LSLマーカーストリームを作成し、ユーザーが ENTERキーを押すのを待ってから、オーディオファイルを再生し、 LabRecorderを介して収集されたEEGデータと同期できるマーカーを送信します。 """ import sounddevice as sd import soundfile as sf from pylsl import StreamInfo, StreamOutlet def wait_for_keypress(): print("ENTERを押すとオーディオ再生を開始し、LSLマーカーを送信します。") while True: if input() == "": break def play_audio_and_send_marker(audio_file, outlet): data, fs = sf.read(audio_file) print("オーディオを再生し、LSLマーカーを送信中...") marker_val = [1] outlet.push_sample(marker_val) sd.play(data, fs) sd.wait() print("オーディオ再生が完了しました。") 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 ステップ 4 (5) - LabRecorderを使用して、すべてのLSLストリームを表示および保存する
LabRecorderを開きます
Updateを押します。利用可能なLSLストリームがストリームリストに表示されるはずです
• 両方のEmotivPRO(通常は「Emotiv-DataStream」と呼ばれる)からのストリームと、マーカーストリーム(「AudioMarkers」と呼ばれる)が表示されるはずですBrowseをクリックしてデータを保存する場所を選択します(他のパラメータの設定も行います)すべてのストリームを選択し、
Recordを押して録画/録音を開始します
3.0 データの操作方法
LabRecorderは、すべてのストリームからのデータを含むXDFファイル(Extensible Data Format)を出力します。XDFファイルは複数のストリームで構成されており、各ストリームには含まれる内容(デバイス名、データタイプ、サンプリングレート、チャネルなど)を説明する異なるヘッダーがあります。以下のコードブロックを使用して、XDFファイルを開き、基本情報を表示できます。
注意:/path/to/your/file.xdf を、LabRecorderで出力されたXDFファイルのパスに置き換えてください。
import pyxdf import mne import matplotlib.pyplot as plt import numpy as np # ここにLSL出力ファイルへのパスを指定します。 data_path = "/path/to/your/file.xdf" # XDFファイルを読み込みます。 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["info"]["name"][0]) print("ストリームタイプ:", stream["info"]["type"][0]) print("チャネル数:", stream["info"]["channel_count"][0]) sfreq = float(stream["info"]["nominal_srate"][0]) print("サンプリングレート:", sfreq) print("サンプル数:", len(stream["time_series"])) print("最初の5つのデータポイント:", stream["time_series"][:5]) channel_names = [ chan["label"][0] for chan in stream["info"]["desc"][0]["channels"][0]["channel"] ] print("チャネル名:", channel_names) channel_types = "eeg"
4.0 その他のリソース
公式ドキュメント
オンラインドキュメントや、GitHubにある公式のREADMEファイルを確認してください
その他のリソース:
• サンプルスクリプトを含む、Emotivのデバイスを使用してLSLを実行するためのコード
• 有益なYouTube上のLSLデモ
• すべての関連ライブラリを網羅したSCCN LSL GitHubリポジトリ
• サブモジュールやアプリがまとめられたLSL GitHubリポジトリハイパースキャニング研究用のHyPyP解析パイプライン

読むのを続ける