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

使用可变时间窗自动生成 Epochs 元数据#

使用 Epochs 时,元数据非常有价值。有详细教程介绍如何自动生成元数据。下面的简短示例演示限定元数据时间窗的不同方式。

# Authors: Richard Höchenberger <richard.hoechenberger@gmail.com>
#
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.

我们使用 Eriksen flanker 任务期间的 EEG 记录,为演示起见只加载前 60 秒数据。

import mne

data_dir = mne.datasets.erp_core.data_path()
infile = data_dir / "ERP-CORE_Subject-001_Task-Flankers_eeg.fif"

raw = mne.io.read_raw(infile, preload=True)
raw.crop(tmax=60).filter(l_freq=0.1, h_freq=40)
Opening raw data file /home/circleci/mne_data/MNE-ERP-CORE-data/ERP-CORE_Subject-001_Task-Flankers_eeg.fif...
    Range : 0 ... 935935 =      0.000 ...   913.999 secs
Ready.
Reading 0 ... 935935  =      0.000 ...   913.999 secs...
Filtering raw data in 1 contiguous segment
Setting up band-pass filter from 0.1 - 40 Hz

FIR filter parameters
---------------------
Designing a one-pass, zero-phase, non-causal bandpass filter:
- Windowed time-domain design (firwin) method
- Hamming window with 0.0194 passband ripple and 53 dB stopband attenuation
- Lower passband edge: 0.10
- Lower transition bandwidth: 0.10 Hz (-6 dB cutoff frequency: 0.05 Hz)
- Upper passband edge: 40.00 Hz
- Upper transition bandwidth: 10.00 Hz (-6 dB cutoff frequency: 45.00 Hz)
- Filter length: 33793 samples (33.001 s)
General
Filename(s) ERP-CORE_Subject-001_Task-Flankers_eeg.fif
MNE object type Raw
Measurement date Unknown
Participant
Experimenter Unknown
Acquisition
Duration 00:01:01 (HH:MM:SS)
Sampling frequency 1024.00 Hz
Time points 61,441
Channels
EEG
EOG
Head & sensor digitization 33 points
Filters
Highpass 0.10 Hz
Lowpass 40.00 Hz


可视化事件#

所有实验事件都以 Annotations 形式保存在 Raw 实例中。首先需要把它们转换为事件,以及事件码到事件名称的映射(event_id),然后可视化事件。

epochs metadata
Used Annotations descriptions: ['response/left', 'response/right', 'stimulus/compatible/target_left', 'stimulus/compatible/target_right', 'stimulus/incompatible/target_left', 'stimulus/incompatible/target_right']

可以看到,共有四类刺激事件与两类反应事件。

声明“行事件”#

本示例假设分析时以刺激起始事件对齐分段,因此希望为每个刺激生成一行元数据。把所有刺激事件名称指定为 row_events 即可实现。

row_events = [
    "stimulus/compatible/target_left",
    "stimulus/compatible/target_right",
    "stimulus/incompatible/target_left",
    "stimulus/incompatible/target_right",
]

指定元数据时间窗#

下面探索在生成元数据时限定 row_events 周围时间窗的不同方式。落入同一时间窗的所有事件会加入元数据表的同一行。

固定时间窗#

指定时间窗范围的一种简单方式是给出相对于行事件的秒数。下例中时间窗从行事件(时间点 0)延伸到其后 3 秒。

event_name response/left response/right stimulus/compatible/target_left stimulus/compatible/target_right stimulus/incompatible/target_left stimulus/incompatible/target_right
2 stimulus/compatible/target_left 0.551758 NaN 0.000000 NaN NaN NaN
4 stimulus/compatible/target_left 0.434570 2.058594 0.000000 NaN NaN 1.549805
6 stimulus/incompatible/target_right 2.020508 0.508789 1.516602 NaN 2.965820 0.000000
8 stimulus/compatible/target_left 0.503906 NaN 0.000000 NaN 1.449219 NaN
10 stimulus/incompatible/target_left 0.542969 NaN NaN NaN 0.000000 NaN
12 stimulus/incompatible/target_left 0.508789 NaN NaN NaN 0.000000 NaN
14 stimulus/incompatible/target_left 0.464844 NaN NaN 2.931641 0.000000 NaN
16 stimulus/incompatible/target_left 0.524414 1.900391 NaN 1.416016 0.000000 NaN
18 stimulus/compatible/target_right 1.916992 0.484375 NaN 0.000000 1.466797 2.899414
20 stimulus/incompatible/target_left 0.450195 1.906250 2.982422 NaN 0.000000 1.432617
22 stimulus/incompatible/target_right 1.960938 0.473633 1.549805 2.965820 NaN 0.000000
24 stimulus/compatible/target_left 0.411133 1.875000 0.000000 1.416016 NaN NaN
26 stimulus/compatible/target_right NaN 0.458984 NaN 0.000000 2.982422 NaN
28 stimulus/compatible/target_right 1.977539 0.401367 NaN 0.000000 1.516602 NaN
30 stimulus/incompatible/target_left 0.460938 2.012695 NaN NaN 0.000000 1.532227
32 stimulus/incompatible/target_right 1.976562 0.480469 1.549805 NaN NaN 0.000000
34 stimulus/compatible/target_left 0.426758 2.010742 0.000000 NaN NaN 1.565430
36 stimulus/incompatible/target_right NaN 0.445312 NaN NaN NaN 0.000000


乍看没问题。但在第 2、3 行中列出了两个反应(左与右),因为 3 秒时间窗显然过宽,捕获了不止一个试次。可以把它收窄,但若窗口太窄又可能丢失事件。归根结底,问题在于反应时逐试次变化,很难设定固定的时间窗上界。

使用 keep_first 的固定时间窗#

一种变通方法是使用 keep_first 参数,它会新建一列,包含指定类型的第一个事件。

metadata_tmin = 0.0
metadata_tmax = 3.0
keep_first = "response"  # <-- new

metadata, events, event_id = mne.epochs.make_metadata(
    events=all_events,
    event_id=all_event_id,
    tmin=metadata_tmin,
    tmax=metadata_tmax,
    sfreq=raw.info["sfreq"],
    row_events=row_events,
    keep_first=keep_first,  # <-- new
)

metadata
event_name response/left response/right stimulus/compatible/target_left stimulus/compatible/target_right stimulus/incompatible/target_left stimulus/incompatible/target_right response first_response
2 stimulus/compatible/target_left 0.551758 NaN 0.000000 NaN NaN NaN 0.551758 left
4 stimulus/compatible/target_left 0.434570 2.058594 0.000000 NaN NaN 1.549805 0.434570 left
6 stimulus/incompatible/target_right 2.020508 0.508789 1.516602 NaN 2.965820 0.000000 0.508789 right
8 stimulus/compatible/target_left 0.503906 NaN 0.000000 NaN 1.449219 NaN 0.503906 left
10 stimulus/incompatible/target_left 0.542969 NaN NaN NaN 0.000000 NaN 0.542969 left
12 stimulus/incompatible/target_left 0.508789 NaN NaN NaN 0.000000 NaN 0.508789 left
14 stimulus/incompatible/target_left 0.464844 NaN NaN 2.931641 0.000000 NaN 0.464844 left
16 stimulus/incompatible/target_left 0.524414 1.900391 NaN 1.416016 0.000000 NaN 0.524414 left
18 stimulus/compatible/target_right 1.916992 0.484375 NaN 0.000000 1.466797 2.899414 0.484375 right
20 stimulus/incompatible/target_left 0.450195 1.906250 2.982422 NaN 0.000000 1.432617 0.450195 left
22 stimulus/incompatible/target_right 1.960938 0.473633 1.549805 2.965820 NaN 0.000000 0.473633 right
24 stimulus/compatible/target_left 0.411133 1.875000 0.000000 1.416016 NaN NaN 0.411133 left
26 stimulus/compatible/target_right NaN 0.458984 NaN 0.000000 2.982422 NaN 0.458984 right
28 stimulus/compatible/target_right 1.977539 0.401367 NaN 0.000000 1.516602 NaN 0.401367 right
30 stimulus/incompatible/target_left 0.460938 2.012695 NaN NaN 0.000000 1.532227 0.460938 left
32 stimulus/incompatible/target_right 1.976562 0.480469 1.549805 NaN NaN 0.000000 0.480469 right
34 stimulus/compatible/target_left 0.426758 2.010742 0.000000 NaN NaN 1.565430 0.426758 left
36 stimulus/incompatible/target_right NaN 0.445312 NaN NaN NaN 0.000000 0.445312 right


可以看到新建了 response 列,记录落入时间窗的第一个反应事件的时间;first_response 列则指明哪个反应先发生(左或右)。

可变时间窗#

另一种应对可变时间窗、且无需新建列的方法,是把 tmin 与 tmax 指定为事件名称。本例中 tmin=row_events,因为希望时间窗从锁时事件开始;tmax 则是反应事件:tmin 之后的第一个反应事件将决定时间窗长度。

metadata_tmin = row_events
metadata_tmax = ["response/left", "response/right"]

metadata, events, event_id = mne.epochs.make_metadata(
    events=all_events,
    event_id=all_event_id,
    tmin=metadata_tmin,
    tmax=metadata_tmax,
    sfreq=raw.info["sfreq"],
    row_events=row_events,
)

metadata
event_name response/left response/right stimulus/compatible/target_left stimulus/compatible/target_right stimulus/incompatible/target_left stimulus/incompatible/target_right
2 stimulus/compatible/target_left 0.551758 NaN 0.0 NaN NaN NaN
4 stimulus/compatible/target_left 0.434570 NaN 0.0 NaN NaN NaN
6 stimulus/incompatible/target_right NaN 0.508789 NaN NaN NaN 0.0
8 stimulus/compatible/target_left 0.503906 NaN 0.0 NaN NaN NaN
10 stimulus/incompatible/target_left 0.542969 NaN NaN NaN 0.0 NaN
12 stimulus/incompatible/target_left 0.508789 NaN NaN NaN 0.0 NaN
14 stimulus/incompatible/target_left 0.464844 NaN NaN NaN 0.0 NaN
16 stimulus/incompatible/target_left 0.524414 NaN NaN NaN 0.0 NaN
18 stimulus/compatible/target_right NaN 0.484375 NaN 0.0 NaN NaN
20 stimulus/incompatible/target_left 0.450195 NaN NaN NaN 0.0 NaN
22 stimulus/incompatible/target_right NaN 0.473633 NaN NaN NaN 0.0
24 stimulus/compatible/target_left 0.411133 NaN 0.0 NaN NaN NaN
26 stimulus/compatible/target_right NaN 0.458984 NaN 0.0 NaN NaN
28 stimulus/compatible/target_right NaN 0.401367 NaN 0.0 NaN NaN
30 stimulus/incompatible/target_left 0.460938 NaN NaN NaN 0.0 NaN
32 stimulus/incompatible/target_right NaN 0.480469 NaN NaN NaN 0.0
34 stimulus/compatible/target_left 0.426758 NaN 0.0 NaN NaN NaN
36 stimulus/incompatible/target_right NaN 0.445312 NaN NaN NaN 0.0


可变时间窗(简化写法)#

上面的代码可以略微简化:既然 tmin 应设为 row_events,可以传入 tmin=None,这是表达 tmin=row_events 更简便的方式。得到的元数据与上例相同。

metadata_tmin = None  # <-- new
metadata_tmax = ["response/left", "response/right"]

metadata, events, event_id = mne.epochs.make_metadata(
    events=all_events,
    event_id=all_event_id,
    tmin=metadata_tmin,
    tmax=metadata_tmax,
    sfreq=raw.info["sfreq"],
    row_events=row_events,
)

metadata
event_name response/left response/right stimulus/compatible/target_left stimulus/compatible/target_right stimulus/incompatible/target_left stimulus/incompatible/target_right
2 stimulus/compatible/target_left 0.551758 NaN 0.0 NaN NaN NaN
4 stimulus/compatible/target_left 0.434570 NaN 0.0 NaN NaN NaN
6 stimulus/incompatible/target_right NaN 0.508789 NaN NaN NaN 0.0
8 stimulus/compatible/target_left 0.503906 NaN 0.0 NaN NaN NaN
10 stimulus/incompatible/target_left 0.542969 NaN NaN NaN 0.0 NaN
12 stimulus/incompatible/target_left 0.508789 NaN NaN NaN 0.0 NaN
14 stimulus/incompatible/target_left 0.464844 NaN NaN NaN 0.0 NaN
16 stimulus/incompatible/target_left 0.524414 NaN NaN NaN 0.0 NaN
18 stimulus/compatible/target_right NaN 0.484375 NaN 0.0 NaN NaN
20 stimulus/incompatible/target_left 0.450195 NaN NaN NaN 0.0 NaN
22 stimulus/incompatible/target_right NaN 0.473633 NaN NaN NaN 0.0
24 stimulus/compatible/target_left 0.411133 NaN 0.0 NaN NaN NaN
26 stimulus/compatible/target_right NaN 0.458984 NaN 0.0 NaN NaN
28 stimulus/compatible/target_right NaN 0.401367 NaN 0.0 NaN NaN
30 stimulus/incompatible/target_left 0.460938 NaN NaN NaN 0.0 NaN
32 stimulus/incompatible/target_right NaN 0.480469 NaN NaN NaN 0.0
34 stimulus/compatible/target_left 0.426758 NaN 0.0 NaN NaN NaN
36 stimulus/incompatible/target_right NaN 0.445312 NaN NaN NaN 0.0


脚本总运行时间:(0 分 1.627 秒)

图库由 Sphinx-Gallery 生成