Skip to content

第3章: データの読み込みと確認

この章では、EEGファイルをMNEに読み込む方法と、処理を始める前に行う価値のあるチェック項目を扱います。あなた自身のファイルに対して行ったのと同じチェックを、ここで詳しく説明します。

ファイル形式とそれぞれの読み込み関数

MNEには、ほとんどのEEG/MEGファイル形式に対応した専用のリーダーが用意されています。代表的なものをいくつか挙げます。

形式 拡張子 読み込み関数
European Data Format .edf, .bdf mne.io.read_raw_edf
BrainVision .vhdr (+ .vmrk, .eeg) mne.io.read_raw_brainvision
Neuroscan .cnt mne.io.read_raw_cnt
EEGLAB .set mne.io.read_raw_eeglab
Neuromag/Elekta/MEGIN (MEG、サンプルデータセットで使用) .fif mne.io.read_raw_fif

これらはすべて同じ種類のオブジェクト、つまり Raw を返します。そのため、一度読み込んでしまえば、元のファイル形式が何であれ、以降の処理(このチュートリアル全体)はまったく同じように動作します。だからこそ、あなた自身の .edf ファイルと、このサンプルデータセットの .fif ファイルが、同じパイプラインを通せるのです。

import mne
import matplotlib.pyplot as plt
from pathlib import Path

mne.set_log_level("WARNING")

sample_folder = Path(mne.datasets.sample.data_path()) / "MEG" / "sample"
raw = mne.io.read_raw_fif(sample_folder / "sample_audvis_raw.fif", preload=True)
raw.pick(["eeg", "eog"])
raw
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:04:38 (HH:MM:SS)
Sampling frequency 600.61 Hz
Time points 166,800
Channels
EEG and
EOG
Head & sensor digitization 146 points
Filters
Highpass 0.10 Hz
Lowpass 172.18 Hz

前処理前のチェックリスト

データに手を付ける前に、必ず以下を確認します。 1. チャンネル名とチャンネル型 — 想定通りになっているか? 2. サンプリングレートと記録時間。 3. アノテーション/イベントの有無。 4. 電極位置(モンタージュ)がすでに設定されているか。 5. 目で見て明らかに不良なチャンネルがないか。

print("チャンネル名:", raw.ch_names)
print("チャンネル型:", set(raw.get_channel_types()))
print("サンプリングレート (Hz):", raw.info["sfreq"])
print("記録時間 (秒):", raw.times[-1])
チャンネル名: ['EEG 001', 'EEG 002', 'EEG 003', 'EEG 004', 'EEG 005', 'EEG 006', 'EEG 007', 'EEG 008', 'EEG 009', 'EEG 010', 'EEG 011', 'EEG 012', 'EEG 013', 'EEG 014', 'EEG 015', 'EEG 016', 'EEG 017', 'EEG 018', 'EEG 019', 'EEG 020', 'EEG 021', 'EEG 022', 'EEG 023', 'EEG 024', 'EEG 025', 'EEG 026', 'EEG 027', 'EEG 028', 'EEG 029', 'EEG 030', 'EEG 031', 'EEG 032', 'EEG 033', 'EEG 034', 'EEG 035', 'EEG 036', 'EEG 037', 'EEG 038', 'EEG 039', 'EEG 040', 'EEG 041', 'EEG 042', 'EEG 043', 'EEG 044', 'EEG 045', 'EEG 046', 'EEG 047', 'EEG 048', 'EEG 049', 'EEG 050', 'EEG 051', 'EEG 052', 'EEG 053', 'EEG 054', 'EEG 055', 'EEG 056', 'EEG 057', 'EEG 058', 'EEG 059', 'EEG 060', 'EOG 061']
チャンネル型: {'eeg', 'eog'}
サンプリングレート (Hz): 600.614990234375
記録時間 (秒): 277.7136813300495

チャンネル型と picks

ファイルには、EEGだけでなく他の種類のチャンネル(眼球運動用のEOG、心拍用のECG、刺激/トリガーチャンネルなど)が混在していることがよくあります。MNEが、例えばトリガーチャンネルを脳の信号として扱ってしまわないようにするには、正しいチャンネル型が必要です。あるチャンネルの型が間違っている場合は、raw.set_channel_types({"chan_name": "eog"}) で修正します。

型が正しく設定されていれば、ほとんどの関数は picks 引数を受け取り、その一部のみを対象に操作できます。picks="eeg" は非常によく使われます。

for ch_name, ch_type in zip(raw.ch_names, raw.get_channel_types()):
    print(f"{ch_name:>8}  ->  {ch_type}")
 EEG 001  ->  eeg
 EEG 002  ->  eeg
 EEG 003  ->  eeg
 EEG 004  ->  eeg
 EEG 005  ->  eeg
 EEG 006  ->  eeg
 EEG 007  ->  eeg
 EEG 008  ->  eeg
 EEG 009  ->  eeg
 EEG 010  ->  eeg
 EEG 011  ->  eeg
 EEG 012  ->  eeg
 EEG 013  ->  eeg
 EEG 014  ->  eeg
 EEG 015  ->  eeg
 EEG 016  ->  eeg
 EEG 017  ->  eeg
 EEG 018  ->  eeg
 EEG 019  ->  eeg
 EEG 020  ->  eeg
 EEG 021  ->  eeg
 EEG 022  ->  eeg
 EEG 023  ->  eeg
 EEG 024  ->  eeg
 EEG 025  ->  eeg
 EEG 026  ->  eeg
 EEG 027  ->  eeg
 EEG 028  ->  eeg
 EEG 029  ->  eeg
 EEG 030  ->  eeg
 EEG 031  ->  eeg
 EEG 032  ->  eeg
 EEG 033  ->  eeg
 EEG 034  ->  eeg
 EEG 035  ->  eeg
 EEG 036  ->  eeg
 EEG 037  ->  eeg
 EEG 038  ->  eeg
 EEG 039  ->  eeg
 EEG 040  ->  eeg
 EEG 041  ->  eeg
 EEG 042  ->  eeg
 EEG 043  ->  eeg
 EEG 044  ->  eeg
 EEG 045  ->  eeg
 EEG 046  ->  eeg
 EEG 047  ->  eeg
 EEG 048  ->  eeg
 EEG 049  ->  eeg
 EEG 050  ->  eeg
 EEG 051  ->  eeg
 EEG 052  ->  eeg
 EEG 053  ->  eeg
 EEG 054  ->  eeg
 EEG 055  ->  eeg
 EEG 056  ->  eeg
 EEG 057  ->  eeg
 EEG 058  ->  eeg
 EEG 059  ->  eeg
 EEG 060  ->  eeg
 EOG 061  ->  eog

モンタージュ(電極位置)

一部のファイル形式・収録システムでは、実際にデジタル化された3次元の電極位置が保存されています(このサンプルデータセットもそうです。下で raw.get_montage() を確認してください)。一方、あなた自身の .edf エクスポートのように、それが保存されていないものもあり、その場合はチャンネル名を一致させることで、汎用の標準モンタージュを自分で当てはめる必要があります。これが、あなたのファイルに raw.set_montage(...) を適用する前に、チャンネル名の変更(EEG Fp1-CPzFp1)というステップが必要だった理由です。

montage = raw.get_montage()
print(montage)
montage.plot(kind="topomap", show_names=True)
plt.show()
<DigMontage | 78 extras (headshape), 4 HPIs, 3 fiducials, 60 channels>

png

イベントはどこにあるか: アノテーション 対 刺激チャンネル

イベントマーカーは、記録システムによって次の2箇所のどちらかに現れます。

  • raw.annotations — ファイルに付随する、ラベル付きの時刻のリスト(あなたのものと同様、.edf エクスポートによく見られます)。
  • 専用の刺激/トリガーチャンネル — どのイベントが起きたかを符号化するために値が変化するチャンネルで、mne.find_events() で読み取ります(このサンプルデータセットで使われており、チャンネル名は STI 014 です)。

第6章で実際に両方の方法を使います。今はまず、何が存在するかだけ確認しましょう。

print("アノテーション:", raw.annotations)
print("'stim' 型のチャンネルはあるか?", "stim" in raw.get_channel_types())
# 注: 上ですでにeeg/eogのみをpickしたため、このファイルの刺激チャンネルはここで意図的に除外されている
アノテーション: <Annotations | 0 segments>
'stim' 型のチャンネルはあるか? False

生データの可視化

補完的な2つの見方があります。時間経過に沿った生の波形と、パワースペクトル密度(各周波数にどれだけの信号パワーがあるか)です。後者は電源ノイズや過剰な高周波の筋混入をすばやく見つける手段です。

raw.plot(n_channels=20, duration=10, scalings="auto")
plt.show()

png

raw.compute_psd(picks="eeg").plot()
plt.show()

png

50 Hzまたは60 Hz付近のスパイク(電源ノイズ。第4章のノッチフィルタのターゲットです)がないか探し、高い周波数に向かってパワーがなめらかに減衰しているか、それとも不自然な盛り上がりがあるか(筋混入の可能性)を確認してください。

不良チャンネルのマーク

上の raw.plot() でスクロールしている間に、平坦だったり、ずっと極端にノイズが多かったり、周囲のチャンネルと明らかに異なっていたりするチャンネルがあれば、「不良(bad)」としてマークする候補です。不良チャンネルは、デフォルトではほとんどの解析やプロットから除外され、後で周囲の良好なチャンネルから補間して再構成することもできます(raw.interpolate_bads()。モンタージュが必要です)。

raw.info["bads"] = []  # 例えば上で不良なものを見つけたら ["EEG 053"] のように指定する

まとめ

  • どの形式にも専用の mne.io.read_raw_* 関数がありますが、いずれも同じ Raw オブジェクトを生成します。
  • 処理を始める前に、必ずチャンネル名/型、サンプリングレート、モンタージュ、イベントの所在を確認します。
  • 時間領域の確認には raw.plot()、周波数領域の確認には raw.compute_psd().plot() を使います。

次へ: 第4章 — 前処理