非官方中文翻译 本页译自 MNE-Python 官方文档: 查看英文原文 ↗。 文档版权归 MNE Developers 所有(BSD-3-Clause)。

处理事件#

本教程介绍事件的表示方式,以及如何使用 Events 数组来筛选数据。

与往常一样,我们先导入所需的模块、加载一些示例数据,并在将 Raw 对象载入 RAM 之前先将其裁剪到仅 60 秒,以节省内存:

# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import os

import numpy as np

import mne

sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = os.path.join(
    sample_data_folder, "MEG", "sample", "sample_audvis_raw.fif"
)
raw = mne.io.read_raw_fif(sample_data_raw_file, verbose=False)
raw.crop(tmax=60).load_data()
Reading 0 ... 36037  =      0.000 ...    60.000 secs...
General
Filename(s) sample_audvis_raw.fif
MNE object type Raw
Measurement date 2002-12-03 at 19:01:10 UTC
Participant Unknown
Experimenter MEG
Acquisition
Duration 00:01:01 (HH:MM:SS)
Sampling frequency 600.61 Hz
Time points 36,038
Channels
Magnetometers
Gradiometers and
EEG and
EOG
Stimulus
Head & sensor digitization 146 points
Filters
Highpass 0.10 Hz
Lowpass 172.18 Hz
Projections PCA-v1 (off)
PCA-v2 (off)
PCA-v3 (off)


教程“从原始数据中解析事件”详细介绍了从 Raw 对象获取 Events 数组的各种方法(详见“检测实验事件”一节)。由于示例数据集包含记录在 stim 通道 STI 014 上的实验事件,我们将通过 mne.find_events() 从该通道解析事件,以此开始本教程:

events = mne.find_events(raw, stim_channel="STI 014")
Finding events on: STI 014
86 events found on stim channel STI 014
Event IDs: [ 1  2  3  4  5 32]

从文件读写事件#

事件数组是 NumPy array 对象,因此可以用 numpy.save() 将其以二进制 .npy 文件的形式保存到磁盘。不过,MNE-Python 提供了便捷函数 mne.read_events() 和 mne.write_events(),可将事件数组读写为文本文件(常见扩展名为 .eve、.lst 和 .txt)或二进制 .fif 文件。示例数据集在某个 .fif 文件中包含了 mne.find_events(raw) 的结果。由于我们已对 Raw 对象做了截断,它包含的事件数会少于从磁盘加载的事件文件(后者包含整个记录的事件),但前 60 秒的事件应当是一致的:

将事件数组写入磁盘时,格式会根据你提供的文件扩展名推断。按照惯例,MNE-Python 要求事件文件的扩展名为 .eve,或者文件基名以 -eve 或 _eve 结尾(例如 my_experiment_eve.fif);如果不遵守这一惯例,将会发出警告。

筛选与合并事件#

上面 find_events() 的输出(此处再次显示)告诉了我们找到的事件数量,以及其中出现的唯一整数事件 ID:

mne.find_events(raw, stim_channel="STI 014")
Finding events on: STI 014
86 events found on stim channel STI 014
Event IDs: [ 1  2  3  4  5 32]

如果其中某些事件并不需要,可以使用 mne.pick_events() 轻松筛选事件,它有 include 和 exclude 参数。例如,在示例数据中 Event ID 32 对应被试按键,可以这样将其排除:

也可以使用 mne.merge_events() 合并两个 Event ID;下面的示例将 Event ID 1、2 和 3 合并为一个标记为 1 的事件:

[ 1  4  5 32]

但请注意,如果你只是想在分析时合并试次类型,则无需合并事件;下一节将介绍 MNE-Python 如何使用事件字典将整数 Event ID 映射为更具描述性的标签字符串。

将 Event ID 映射到试次描述符#

到目前为止,本教程只涉及整数 Event ID,它们是根据直流电压脉冲幅度分配的(最终取决于实验者选择向 STIM 通道发送何种信号)。跟踪哪个 Event ID 对应哪个实验条件可能十分繁琐,而在分析过程中通常希望合并实验条件。你可能还记得,入门教程中的这个表格给出了示例数据集中整数 Event ID 到有意义描述的映射。这里我们只是将该映射重现为一个事件字典:

event_dict = {
    "auditory/left": 1,
    "auditory/right": 2,
    "visual/left": 3,
    "visual/right": 4,
    "smiley": 5,
    "buttonpress": 32,
}

像这样的事件字典会在从连续数据中提取 epochs 时使用,得到的 Epochs 对象允许通过请求部分试次描述符来合并试次。例如,如果我们想合并所有听觉试次,不必使用 merge_events() 函数合并 Event ID 1 和 2,而可以利用 event_dict 的键包含以 / 字符分隔的多个试次描述符这一特点:请求 'auditory' 试次将选中所有 Event ID 为 1 和 2 的 epochs;请求 'left' 试次将选中所有 Event ID 为 1 和 3 的 epochs。教程“Epochs 数据结构:不连续数据”的“筛选 epochs”一节稍后给出了这方面的示例。

绘制事件#

事件字典的另一个用途是在绘制事件时使用,这有助于检查事件信号是否已正确发送到 STIM 通道,以及 MNE-Python 是否成功找到了它们。函数 mne.viz.plot_events() 会绘制每个事件与其采样点编号的关系(如果提供采样频率,则绘制它们与时间(秒)的关系)。它还可以通过 first_samp 参数处理 Neuromag 系统中采样点编号与采样索引之间的偏移。如果提供了事件字典,将用它生成图例:

fig = mne.viz.plot_events(
    events, sfreq=raw.info["sfreq"], first_samp=raw.first_samp, event_id=event_dict
)
20 event arrays

同时绘制事件与原始数据#

也可以将 Events 数组作为 raw.plot 的 events 参数传入,从而将事件与提取它们的 Raw 对象一起绘制:

raw.plot(
    events=events,
    start=5,
    duration=10,
    color="gray",
    event_color={1: "r", 2: "g", 3: "b", 4: "m", 5: "y", 32: "k"},
)
Raw plot

生成等间隔 Events 数组#

对于某些实验(例如打算分析静息态活动的实验),原始记录中可能不包含任何实验事件。在这种情况下,可以使用 mne.make_fixed_length_events() 生成由等间隔事件组成的 Events 数组:

new_events = mne.make_fixed_length_events(raw, start=5, stop=50, duration=2.0)

默认情况下,所有事件都会被赋予整数 Event ID 1,但你可以通过 id 参数更改。也可以指定重叠时长——也就是说,如果你最终想要 2.5 秒长的 epochs,但希望它们彼此重叠 0.5 秒,可以在调用 make_fixed_length_events() 时指定 duration=2.5, overlap=0.5(这样得到的事件间隔与 duration=2, overlap=0 相同)。

图库由 Sphinx-Gallery 生成