• 首页
  • 栏目
  • ERP
  • 脑电分析系列[MNE-Python-20]| 脑电图处理和事件相关电位(ERP)

脑电分析系列[MNE-Python-20]| 脑电图处理和事件相关电位(ERP)

  • 2021-08-12
  • Admin

今天主要介绍一下MNE-Python中进行脑电图处理和事件相关电位(ERP)。

有后台留言问,代码是在哪里运行的。这里说明一下,案例介绍的代码均在jupyter notebook中运行的,当然这些代码也可以在PyCharm等IDE中运行(不过可能存在在不同环境下代码需要稍微改动的情况。)

Python脑电图处理案例:

  1. import mne
  2. from mne.datasets import sample
  1. # 加载数据文件
  2. data_path = sample.data_path()
  3. raw_fname = data_path + '/MEG/sample/sample_audvis_filt-0-40_raw.fif'
  4. event_fname = data_path + '/MEG/sample/sample_audvis_filt-0-40_raw-eve.fif'
  5. # 这些EEG数据已经默认有平均参考(average reference)
  6. raw = mne.io.read_raw_fif(raw_fname, preload=True)

  1. # 只筛选 EEG 和 EOG数据
  2. raw.pick_types(meg=False, eeg=True, eog=True)
  3. # 查看 raw 信息, 可以发现有59个EEG通道和1个EOG通道
  4. print(raw.info)

实际上,拥有一些EOG通道的EEG通道是很普遍的。在实际获取EEG数据时,会受到眼动等活动的影响。

如果要更改通道类型,可以使用mne.io.Raw.set_channel_types()方法。
例如,要将EOG通道视为EEG,可以使用以下方法更改其类型:

  1. raw.set_channel_types(mapping={'EOG 061': 'eeg'})
  2. print(raw.info)

比较上面前后两个打印中的红框内容,可以发现,EOG已被EEG取代了。

  1. # 更改EOG通道的名称
  2. raw.rename_channels(mapping={'EOG 061': 'EOG'})
  3. # 为了讲述案例,我们将EOG频道重设为EOG类型。
  4. raw.set_channel_types(mapping={'EOG': 'eog'})
  1. """
  2. 样本数据集中的EEG通道有对应通道位置。这些位置可在每个通道说明的"位置"中找到。
  3. 下面是获取第一个通道的位置
  4. """
  5. print(raw.info['chs'][0]['loc'])
[-0.03737009  0.10568011  0.07333875
  1. 0.00235201 0.11096951 -0.03500458
  2. 0. 1. 0. 0. 0. 1. ]
  1. """
  2. 可以使用mne.io.Raw.plot_sensors()绘制通道位置。
  3. 如果您的数据没有位置,则可以使用MNE随附的Montages来设置
  4. """
  5. raw.plot_sensors()

raw.plot_sensors('3d')  # in 3D

设置脑电图参考

首先,从原始对象中删除参考。

这显示的移除了MNE默认的EEG平均参考。

raw_no_ref, _ = mne.set_eeg_reference(raw, [])

EEG channel type selected for re-referencing

EEG data marked as already having the desired reference. Preventing automatic future re-referencing to an average reference.

Removing existing average EEG reference projection.

然后,定义了Epochs,并计算了左听觉状态的ERP。

  1. reject = dict(eeg=180e-6, eog=150e-6)
  2. event_id, tmin, tmax = {'left/auditory': 1}, -0.2, 0.5
  3. events = mne.read_events(event_fname)
  4. epochs_params = dict(events=events, event_id=event_id, tmin=tmin, tmax=tmax,
  5. reject=reject)
  6. evoked_no_ref = mne.Epochs(raw_no_ref, **epochs_params).average()
  7. del raw_no_ref # save memory
  8. title = 'EEG Original reference'
  9. evoked_no_ref.plot(titles=dict(eeg=title), time_unit='s')
  10. evoked_no_ref.plot_topomap(times=[0.1], size=3., title=title, time_unit='s')

设置平均参考电极

  1. """
  2. 平均参考:通常默认情况下添加,但也可以显式添加。
  3. """
  4. raw.del_proj()
  5. raw_car, _ = mne.set_eeg_reference(raw, 'average', projection=True)
  6. evoked_car = mne.Epochs(raw_car, **epochs_params).average()
  7. del raw_car # save memory
  8. title = 'EEG Average reference'
  9. evoked_car.plot(titles=dict(eeg=title), time_unit='s')
  10. evoked_car.plot_topomap(times=[0.1], size=3., title=title, time_unit='s')

自定义参考:使用通道EEG 001和EEG 002的平均值作为参考

  1. raw_custom, _ = mne.set_eeg_reference(raw, ['EEG 001', 'EEG 002'])
  2. evoked_custom = mne.Epochs(raw_custom, **epochs_params).average()
  3. del raw_custom # save memory
  4. title = 'EEG Custom reference'
  5. evoked_custom.plot(titles=dict(eeg=title), time_unit='s')
  6. evoked_custom.plot_topomap(times=[0.1], size=3.,
  7. title=title, time_unit='s')

可以使用' / '分隔的'标记'来选择Epochs中的试验子集。

首先,我们创建一个包含4个条件的Epochs对象。

  1. event_id = {'left/auditory': 1, 'right/auditory': 2,
  2. 'left/visual': 3, 'right/visual': 4}
  3. epochs_params = dict(events=events, event_id=event_id, tmin=tmin, tmax=tmax,
  4. reject=reject)
  5. epochs = mne.Epochs(raw, **epochs_params)
  6. print(epochs)

接下来,我们创建左刺激和右刺激试验的平均值。

我们可以使用基本的操作,例如,构建和绘制不同的ERP。

  1. left, right = epochs["left"].average(), epochs["right"].average()
  2. # create and plot difference ERP
  3. joint_kwargs = dict(ts_args=dict(time_unit='s'),
  4. topomap_args=dict(time_unit='s'))
  5. mne.combine_evoked([left, -right], weights='equal').plot_joint(**joint_kwargs)
  1. Rejecting epoch based on EOG : ['EOG']
  2. Rejecting epoch based on EOG : ['EOG']
  3. Rejecting epoch based on EOG : ['EOG']
  4. Rejecting epoch based on EOG : ['EOG']
  5. Rejecting epoch based on EOG : ['EOG']
  6. Rejecting epoch based on EOG : ['EOG']
  7. Rejecting epoch based on EOG : ['EOG']
  8. Rejecting epoch based on EOG : ['EOG']
  9. Rejecting epoch based on EOG : ['EOG']
  10. Rejecting epoch based on EOG : ['EOG']
  11. Rejecting epoch based on EOG : ['EOG']
  12. Rejecting epoch based on EOG : ['EOG']
  13. Rejecting epoch based on EOG : ['EOG']
  14. Rejecting epoch based on EOG : ['EOG']
  15. Rejecting epoch based on EOG : ['EOG']
  16. Rejecting epoch based on EOG : ['EOG']
  17. Rejecting epoch based on EOG : ['EOG']
  18. Rejecting epoch based on EOG : ['EOG']
  19. Rejecting epoch based on EOG : ['EOG']
  20. Rejecting epoch based on EOG : ['EOG']
  21. Rejecting epoch based on EOG : ['EOG']
  22. Rejecting epoch based on EOG : ['EOG']
  23. Rejecting epoch based on EOG : ['EOG']
  24. Rejecting epoch based on EEG : ['EEG 001']
  25. Rejecting epoch based on EOG : ['EOG']
  26. Rejecting epoch based on EOG : ['EOG']
  27. Rejecting epoch based on EOG : ['EOG']
  28. Rejecting epoch based on EOG : ['EOG']
  29. Rejecting epoch based on EOG : ['EOG']
  30. Rejecting epoch based on EOG : ['EOG']
  31. Rejecting epoch based on EOG : ['EOG']
  32. Rejecting epoch based on EOG : ['EOG']
  33. Rejecting epoch based on EOG : ['EOG']
  34. Rejecting epoch based on EOG : ['EOG']
  35. Rejecting epoch based on EOG : ['EOG']
  36. Rejecting epoch based on EOG : ['EOG']
  37. Rejecting epoch based on EOG : ['EOG']
  38. Rejecting epoch based on EOG : ['EOG']
  39. Rejecting epoch based on EOG : ['EOG']
  40. Rejecting epoch based on EOG : ['EOG']
  41. Rejecting epoch based on EOG : ['EOG']
  42. Rejecting epoch based on EOG : ['EOG']
  43. Rejecting epoch based on EOG : ['EOG']
  44. Rejecting epoch based on EOG : ['EOG']
  45. Rejecting epoch based on EOG : ['EOG']
  46. Rejecting epoch based on EOG : ['EOG']
  47. Rejecting epoch based on EOG : ['EOG']

这是权重相等的差异。 如果试验编号不平衡,则也可以考虑使每个条件的事件数相等(使用epochs.equalize_event_counts)。 例如,首先,我们为每种情况创建单独的ERP。

  1. aud_l = epochs["auditory", "left"].average()
  2. aud_r = epochs["auditory", "right"].average()
  3. vis_l = epochs["visual", "left"].average()
  4. vis_r = epochs["visual", "right"].average()
  5. all_evokeds = [aud_l, aud_r, vis_l, vis_r]
  6. print(all_evokeds)
  1. """
  2. 这可以通过Python列表理解来简化
  3. """
  4. all_evokeds = [epochs[cond].average() for cond in sorted(event_id.keys())]
  5. print(all_evokeds)
  6. # 然后,我们也以这种方式构造和绘制左右试验的未加权平均值:
  7. mne.combine_evoked(
  8. [aud_l, -aud_r, vis_l, -vis_r], weights='equal').plot_joint(**joint_kwargs)
  1. Rejecting epoch based on EOG : ['EOG']
  2. Rejecting epoch based on EOG : ['EOG']
  3. Rejecting epoch based on EOG : ['EOG']
  4. Rejecting epoch based on EOG : ['EOG']
  5. Rejecting epoch based on EOG : ['EOG']
  6. Rejecting epoch based on EOG : ['EOG']
  7. Rejecting epoch based on EOG : ['EOG']
  8. Rejecting epoch based on EOG : ['EOG']
  9. Rejecting epoch based on EOG : ['EOG']
  10. Rejecting epoch based on EOG : ['EOG']
  11. Rejecting epoch based on EOG : ['EOG']
  12. Rejecting epoch based on EOG : ['EOG']
  13. Rejecting epoch based on EOG : ['EOG']
  14. Rejecting epoch based on EOG : ['EOG']
  15. Rejecting epoch based on EOG : ['EOG']
  16. Rejecting epoch based on EOG : ['EOG']
  17. Rejecting epoch based on EOG : ['EOG']
  18. Rejecting epoch based on EOG : ['EOG']
  19. Rejecting epoch based on EOG : ['EOG']
  20. Rejecting epoch based on EOG : ['EOG']
  21. Rejecting epoch based on EOG : ['EOG']
  22. Rejecting epoch based on EOG : ['EOG']
  23. Rejecting epoch based on EOG : ['EOG']
  24. Rejecting epoch based on EEG : ['EEG 001']
  25. Rejecting epoch based on EOG : ['EOG']
  26. Rejecting epoch based on EOG : ['EOG']
  27. Rejecting epoch based on EOG : ['EOG']
  28. Rejecting epoch based on EOG : ['EOG']
  29. Rejecting epoch based on EOG : ['EOG']
  30. Rejecting epoch based on EOG : ['EOG']
  31. Rejecting epoch based on EOG : ['EOG']
  32. Rejecting epoch based on EOG : ['EOG']
  33. Rejecting epoch based on EOG : ['EOG']
  34. Rejecting epoch based on EOG : ['EOG']
  35. Rejecting epoch based on EOG : ['EOG']
  36. Rejecting epoch based on EOG : ['EOG']
  37. Rejecting epoch based on EOG : ['EOG']
  38. Rejecting epoch based on EOG : ['EOG']
  39. Rejecting epoch based on EOG : ['EOG']
  40. Rejecting epoch based on EOG : ['EOG']
  41. Rejecting epoch based on EOG : ['EOG']
  42. Rejecting epoch based on EOG : ['EOG']
  43. Rejecting epoch based on EOG : ['EOG']
  44. Rejecting epoch based on EOG : ['EOG']
  45. Rejecting epoch based on EOG : ['EOG']
  46. Rejecting epoch based on EOG : ['EOG']
  47. Rejecting epoch based on EOG : ['EOG']
  48. ['left/auditory' (average, N=56), [-0.1998, 0.49949] sec, 59 ch, ~3.1 MB>, 'left/visual' (average, N=67), [-0.1998, 0.49949] sec, 59 ch, ~3.1 MB>, 'right/auditory' (average, N=62), [-0.1998, 0.49949] sec, 59 ch, ~3.1 MB>, 'right/visual' (average, N=56), [-0.1998, 0.49949] sec, 59 ch, ~3.1 MB>]

通常,在字典或列表中存储诱发对象是有意义的——无论是不同的条件,还是不同的主题。

  1. """
  2. 如果将它们存储在一个列表中,就可以很容易地对它们求平均值,例如,跨主题(或条件)的总平均值。
  3. """
  4. grand_average = mne.grand_average(all_evokeds)
  5. mne.write_evokeds('tmp\\tmp-ave.fif', all_evokeds)
  6. # 如果“诱发对象”对象存储在词典中,则可以按名称检索它们。
  7. all_evokeds = dict((cond, epochs[cond].average()) for cond in event_id)
  8. print(all_evokeds['left/auditory'])
  9. # 除了显式访问外,还可以用于设置标题。
  10. for cond in all_evokeds:
  11. all_evokeds[cond].plot_joint(title=cond, **joint_kwargs)

免费ERP

61ebf17978942.jpg

 注册    登录 

用户名: demo; 密码: 123456

联系站长

QQ:769220720

Copyright © SibooSoft All right reserved 津ICP备19011444号