跳转到主要内容

一个用于读取同时记录的EEG和眼动数据的Python模块,

项目描述

Python解析结合EEG和眼动数据的工具

版权(2022-2024)Hermine Berberyan, Wouter Kruijne, Sebastiaan Mathôt, Ana Vilotijević

Publish to PyPi

目录

关于

一个用于读取同时记录的EEG和眼动数据,并将这些数据解析为便于进一步分析的方便对象的Python模块。为此,需要满足一些假设,如假设部分所述。目前,此模块主要供内部使用,并侧重于我们自己的记录环境。

主要功能

  • 眼动数据中的实验变量(例如条件)用作EEG分析的元数据。
  • 注视和瞳孔数据被添加为EEG数据的通道。
  • 眼动和EEG数据的自动预处理。

示例

解析数据。

import eeg_eyetracking_parser as eet

# eet.read_subject.clear()  # uncomment to clear the cache and reparse
raw, events, metadata = eet.read_subject(2)
raw.plot()

为了避免反复解析数据,read_subject()使用持久的记忆化,这是一种在磁盘上存储函数的返回值并在后续调用中立即返回这些返回值的方法。要清除记忆化缓存,可以调用read_subject.clear()函数或删除.memoize文件夹。

绘制锁定于提示开始三秒钟的四个枕叶电极的电压。这分别针对由cue_eccentricity定义的三个不同条件进行。函数eet.autoreject_epochs()的行为类似于mne.Epochs(),不同之处在于它应用了自动拒绝,并且像read_subject()一样,它使用持久化记忆化。

import numpy as np
import mne
from matplotlib import pyplot as plt
from datamatrix import convert as cnv

CUE_TRIGGER = 1
CHANNELS = 'O1', 'O2', 'Oz', 'P3', 'P4'

cue_epoch = eet.autoreject_epochs(raw, eet.epoch_trigger(events, CUE_TRIGGER),
                                  tmin=-.1, tmax=3, metadata=metadata,
                                  picks=CHANNELS)

我们可以将元数据(它是一个DataFrame)转换为DataMatrix,并添加cue_epoch作为多维列。

from datamatrix import convert as cnv
import time_series_test as tst

dm = cnv.from_pandas(metadata)
dm.erp = cnv.from_mne_epochs(cue_epoch)  # rows x channel x time
dm.mean_erp = dm.erp[:, ...]             # Average over channels: rows x time
tst.plot(dm, dv='mean_erp', hue_factor='cue_eccentricity')

由于常规的mne.Epoch()对象与非数据通道(如瞳孔大小)不兼容,因此您需要使用eet.PupilEpochs()类。这个类在其他方面完全相同,只是在默认情况下它会移除基线瞳孔大小与平均基线瞳孔大小相差超过2个标准差的试验。

pupil_cue_epoch = eet.PupilEpochs(raw, eet.epoch_trigger(events, CUE_TRIGGER),
                                  tmin=0, tmax=3, metadata=metadata,
                                  baseline=(0, .05))
dm.pupil = cnv.from_mne_epochs(pupil_cue_epoch, ch_avg=True)  # only 1 channel
tst.plot(dm, dv='pupil', hue_factor='cue_eccentricity')

安装

pip install eeg_eyetracking_parser

依赖

  • datamatrix >= 1.0
  • eyelinkparser
  • mne
  • autoreject
  • h5io
  • braindecode
  • python-picard
  • json_tricks

假设

数据格式

  • EEG数据应采用BrainVision格式(.vhdr),以1000 Hz的采样率记录。
  • 眼动追踪数据应采用EyeLink格式(.edf),以1000 Hz的单眼记录。

文件和文件夹结构

文件应按照BIDS进行组织。

# Container folder for all data
data/
    # Subject 2
    sub-02/
        # EEG data
        eeg/
            sub-02_task-attentionalbreadth_eeg.eeg
            sub-02_task-attentionalbreadth_eeg.vhdr
            sub-02_task-attentionalbreadth_eeg.vmrk
        # Behavioral data (usually not necessary)
        beh/
            sub-02_task-attentionalbreadth_beh.csv
        # Eye-tracking data
        eyetracking/
            sub-02_task-attentionalbreadth_physio.edf

您可以使用该包中的data2bids命令自动将数据文件组织成上述结构。

假设

  • 所有EEG文件(.eeg, .vhdr, .vmrk)应按“Subject-00X-timestamp”格式命名(例如,Subject-002-[2022.06.12-14.35.46].eeg)。
  • 眼动追踪文件(.edf)应按“sub_X”格式命名(例如,sub_2.edf)。

例如,要将参与者1、2、3和4进行名为“attentional-breadth”的任务重新组织,您可以运行以下命令。这假设未组织好的文件位于名为data的子文件夹中,而重新组织的(BIDS兼容)文件也位于此子文件夹中,即如上所示。

data2bids --source-path=data --target-path=data -s=1,2,3,4 -t=attentional-breadth

触发代码

每个试验的开始由一个计数器表示,该计数器对于第一个试验从128开始,并在255后循环,因此试验129再次由128表示。这个触发不需要发送给眼动追踪器,因为眼动追踪器使用自己的start_trial消息。眼动追踪器的start_trial消息和EEG的开始试验触发器之间的时间偏移是可以接受的,并且将在解析时进行补偿。

EE.PulseLines(128 + trialid % 128, 10)  # EE is the EventExchange object

每个周期的开始由一个计数器表示,该计数器对于第一个周期从1开始,然后对后续周期递增。换句话说,如果目标呈现是试验的第二周期,那么这对应于以下示例中的触发2。这个触发需要同时发送给EEG和眼动追踪器(时间偏移可以接受)。

target_trigger = 2
eyetracker.log(f'start_phase {target_trigger}')  # eyetracker is created by PyGaze
EE.PulseLines(target_trigger, 10)

触发器仅用于时间信息。条件仅在眼动追踪数据中记录。

函数参考

autoreject_epochs(*args, ar_kwargs=None, **kwargs)

一个工厂函数,用于创建Epochs()对象,应用自动拒绝,然后返回它。

重要:此函数使用持久化记忆化,这意味着对于给定的一组参数,结果将存储在磁盘上,并在后续调用中立即返回。有关更多信息,请参阅https://pydatamatrix.eu/memoization/

参数

  • *args: 可迭代对象

    传递给mne.Epochs()的参数。

  • ar_kwargs: 字典或None,可选

    传递给AutoReject()的关键字。如果没有指定n_interpolate,则使用默认值[1, 4, 8, 16]。

  • **kwargs: 字典

    传递给mne.Epochs()的关键字。

返回

  • Epochs

    一个应用了自动拒绝的mne.Epochs()对象。

epoch_trigger(events, trigger)

从一个包含事件信息的元组中选取单个周期触发器。周期触发器具有1到127(包含)之间的值。

参数

  • events: 元组

    read_subject()返回的事件信息。

  • trigger: int

    触发代码,它是一个正数。

返回

  • array

    一个numpy数组,其中包含mne.Epochs()所期望的事件。

PupilEpochs(*args, baseline_trim=(-2, 2), channel='PupilSize', **kwargs)

这是一个针对PupilSize通道的Epochs类。即使该通道不是常规数据通道,此类也允许对瞳孔大小应用基线校正。此外,该类允许根据异常基线值排除瞳孔大小,这在瞳孔分析中是推荐的(但通常不用于EEG)。

参数

  • *args: 可迭代对象

    传递给mne.Epochs()的参数。

  • baseline_trim: 整数元组,可选

    可接受基线值的范围。这指的是Z分数。

  • channel: 字符串,可选

    包含瞳孔大小数据的通道名称

  • **kwargs: 字典

    传递给mne.Epochs()的关键字。

返回

  • Epochs

    一个应用了自动拒绝的mne.Epochs()对象。

read_subject(subject_nr, folder='data/', trigger_parser=None, eeg_margin=30, min_sacc_dur=10, min_sacc_size=100, min_blink_dur=10, blink_annotation='BLINK', saccade_annotation='SACCADE', eeg_preprocessing=True, save_preprocessing_output=True, plot_preprocessing=False, eye_kwargs={}, downsample_data_kwargs={}, drop_unused_channels_kwargs={}, rereference_channels_kwargs={}, create_eog_channels_kwargs={}, set_montage_kwargs={}, annotate_emg_kwargs={}, band_pass_filter_kwargs={}, autodetect_bad_channels_kwargs={}, run_ica_kwargs={}, auto_select_ica_kwargs={}, interpolate_bads_kwargs={})

读取单个参与者的EEG、眼动和行为数据。这些数据应根据BIDS规范组织。

假设EEG数据为BrainVision数据格式(.vhdr.vmrk.eeg)。假设眼动数据为EyeLink数据格式(.edf.asc)。假设行为数据为.csv格式。

如果存在,则从行为.csv文件中获取元数据,如果没有,则从眼动数据中获取。

重要:此函数使用持久化记忆化,这意味着对于给定的一组参数,结果将存储在磁盘上,并在后续调用中立即返回。有关更多信息,请参阅https://pydatamatrix.eu/memoization/

参数

  • subject_nr: int或sr

    要解析的受试者编号。如果传递整数值,则假设受试者编号为零填充到长度为两(例如,'01')。如果传递字符串,则直接使用该字符串。

  • folder: 字符串,可选

    存储数据所在的文件夹。

  • trigger_parser: 可调用对象,可选

    将注释转换为事件的函数。如果没有指定函数,则假设触发器由OpenVibe采集软件编码,并遵循readme中描述的表示试验编号和事件开始的约定。

  • eeg_margin: 整数,可选

    在最后触发器后的秒数。其余数据将被裁剪以节省内存(以防记录了过多的额外数据)。

  • min_sacc_dur: 整数,可选

    在将其注释为BAD_SACCADE之前,眼跳的最小持续时间。

  • min_sacc_size: 整数,可选

    在将其注释为眼跳之前,眼跳的最小大小(以像素为单位)。

  • min_blink_dur: 整数,可选

    在将其注释为眨眼之前,眨眼的最小持续时间。

  • blink_annotation: 字符串,可选

    用于眨眼的注释标签。使用BAD_后缀以使用眨眼作为不良注释。

  • saccade_annotation: 字符串,可选

    用于眼跳的注释标签。使用BAD_后缀以使用眼跳作为不良注释。

  • eeg_preprocessing: 布尔值或列表,可选

    表示是否应执行EEG预处理。如果为True,则执行所有预处理步骤。如果传递列表,则仅执行列表中具有对应函数名称的步骤(例如,['downsample_data', 'set_montage'])。

  • save_preprocessing_output: 布尔值,可选

    表示在EEG预处理期间生成的输出是否应保存。

  • plot_preprocessing: 布尔值,可选

    表示在EEG预处理期间是否应显示绘图。

  • eye_kwargs: 字典,可选

    传递给EyeLink解析器的可选关键字参数。如果提供了traceprocessor,则使用具有高级眨眼重建和10倍降采样的默认traceprocessor。

  • downsample_data_kwargs: 字典,可选

    作为关键字参数传递给相应的预处理函数。

  • drop_unused_channels_kwargs: 字典,可选

    作为关键字参数传递给相应的预处理函数。

  • rereference_channels_kwargs: 字典,可选

    作为关键字参数传递给相应的预处理函数。

  • create_eog_channels_kwargs: 字典,可选

    作为关键字参数传递给相应的预处理函数。

  • set_montage_kwargs: 字典,可选

    作为关键字参数传递给相应的预处理函数。

  • annotate_emg_kwargs: 字典,可选

    作为关键字参数传递给相应的预处理函数。

  • band_pass_filter_kwargs: 字典,可选

    作为关键字参数传递给相应的预处理函数。

  • autodetect_bad_channels_kwargs: 字典,可选

    作为关键字参数传递给相应的预处理函数。

  • run_ica_kwargs: 字典,可选

    作为关键字参数传递给相应的预处理函数。

  • auto_select_ica_kwargs: dict, 可选

    作为关键字参数传递给相应的预处理函数。

  • interpolate_bads_kwargs: dict, 可选

    作为关键字参数传递给相应的预处理函数。

返回

  • 元组

    一个包含原始(脑电图数据),事件(脑电图触发器),元数据(包含实验变量的表格)的元组。

trial_trigger(事件)

从事件信息中选择所有试验触发器。试验触发器的值在128到255之间(含)。

参数

  • events: 元组

    read_subject()返回的事件信息。

返回

  • array

    一个numpy数组,其中包含mne.Epochs()所期望的事件。

braindecode_utils.decode_subject(read_subject_kwargs, factors, epochs_kwargs, trigger, epochs_query='practice == "no"', epochs=4, window_size=200, window_stride=1, n_fold=4, crossdecode_read_subject_kwargs=None, crossdecode_factors=None, patch_data_func=None, read_subject_func=None, cuda=True, balance=True)

解码受试者数据的主要入口点。

参数

  • read_subject_kwargs: dict

    一个字典,包含传递给eet.read_subject()的键值对,用于加载数据。之后应用preprocess_raw()中指定的额外预处理。

  • factors: str 或 str 的列表

    要解码的因素或因素列表。因素应该是 str,并且与元数据中的列名匹配。

  • epochs_kwargs: dict, 可选

    一个字典,包含传递给mne.Epochs()的键值对,以提取待解码的epoch。

  • trigger: int

    定义待解码epoch的触发码。

  • epochs_query: str, 可选

    一个pandas风格的查询,用于从待解码epoch中选择试验。默认情况下,假设存在一个practice列,我们只想选择'no'值,即我们想排除练习试验。

  • epochs: int, 可选

    训练epoch的数量,即数据被输入到模型中的次数。这应该至少为2。

  • window_size_samples: int, 可选

    从Epochs对象中采样的窗口长度。这应该略短于实际的Epochs,以便从'裁剪解码'的目的中获取抖动的样本。

  • window_stride_samples: int, 可选

    围绕窗口进行抖动的样本数,用于裁剪解码。

  • n_fold: int, 可选

    总分割(或折叠)数。这应该至少为2。

  • crossdecode_read_subject_kwargs: dict 或 None, 可选

    当提供时,这些read_subject_kwargs被传递给read_subject_func以读取待解码的测试数据集。

  • crossdecode_factors: str 或 str 的列表 或 None, 可选

    在测试期间要解码的因素或因素列表。如果提供,分类器使用factors中指定的因素进行训练,使用crossdecode_factors中指定的因素进行测试。换句话说,指定此关键字允许交叉解码。

  • patch_data_func: 可调用或 None, 可选

    如果提供,这应该是一个函数,它接受(raw, events, metadata)元组作为read_subject()返回的结果,并返回一个(raw, events, metadata)元组。此函数可以在解码应用之前修改数据的某些方面。

  • read_subject_func: 可调用或 None, 可选

    如果提供,这应该是一个函数,它接受通过read_subject_kwargs参数提供的键,并返回一个(raw, events, metadata)元组。如果没有提供,则使用默认的read_subject()函数。

  • cuda: bool, 可选

    如果为True,如果可用,则使用cuda进行GPU处理。如果为False,则不会使用cuda,即使它可用。

  • balance: bool, 可选

    确保数据集为每个标签包含相同数量的观察值,通过随机复制具有观察值过少的标签的观察值来实现。

返回

  • 数据矩阵

    包含原始元数据加四个附加列

    • braindecode_label是与待解码因素相对应的数值标签,即真实值
    • braindecode_prediction是预测的标签
    • braindecode_correct 对于正确的预测为1,否则为0
    • braindecode_probabilities 是一个SeriesColumn,包含每个标签的预测概率。预测本身对应于具有最高概率的索引。

许可证

eeg_eyetracking_parser 使用GNU通用公共许可证v3

项目详情


下载文件

下载您平台对应的文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

eeg_eyetracking_parser-0.16.1.tar.gz (25.8 kB 查看哈希值)

上传时间

构建分发

eeg_eyetracking_parser-0.16.1-py3-none-any.whl (30.2 kB 查看哈希值)

上传时间 Python 3

由以下机构支持

AWSAWS 云计算和安全赞助商 DatadogDatadog 监控 FastlyFastly CDN GoogleGoogle 下载分析 MicrosoftMicrosoft PSF 赞助商 PingdomPingdom 监控 SentrySentry 错误日志 StatusPageStatusPage 状态页面