المحطة 5 · الدرس 3

رفض epochs السيئة

أساسي15 دقيقةقبل هذا الدرس: تصحيح baselineاطبع البطاقة
تبدأ من: eeglab_data.set (D1) · ما طُبّق عليه قبل هذا الدرس: فلترة high-pass و low-pass، إزالة ضوضاء الكهرباء (50 أو 60 هرتز)، القنوات السيئة، الاستيفاء (interpolation)، إعادة المرجع (re-referencing)، تشغيل ICA، فلتر 1 هرتز قبل ICA ونسخ الأوزان، ICLabel وحذف المكوّنات، استخراج epochs، تصحيح baselineتنزيل البيانات (يفتح في نافذة جديدة)
سكربت الوصول لهذه الحالة
MATLAB
% Shortcut: if you saved D1_main_clean_lp30.set in the ICLabel lesson, keep
% the first line and the last three lines, and replace every line between them with:
% EEG = pop_loadset('D1_main_clean_lp30.set', pwd);
[ALLEEG, EEG, CURRENTSET, ALLCOM] = eeglab;
eeglabRoot = fileparts(which('eeglab'));
EEG = pop_loadset('eeglab_data.set', fullfile(eeglabRoot, 'sample_data'));
fullLocs = EEG.chanlocs;

% Main dataset: high-pass at 0.1 Hz, then 60 Hz line-noise removal
EEG = pop_eegfiltnew(EEG, 'locutoff', 0.1);
EEG = pop_eegfiltnew(EEG, 'locutoff', 58, 'hicutoff', 62, 'revfilt', 1);

% Bad channels you removed earlier, e.g. {'T7'}; leave empty if none
badChans = {};
if ~isempty(badChans)
    EEG = pop_select(EEG, 'rmchannel', badChans);
    EEG = pop_interp(EEG, fullLocs, 'spherical');
end

% Average reference, EOG channels excluded
eogIdx = find(ismember({EEG.chanlocs.labels}, {'EOG1', 'EOG2'}));
EEG = pop_reref(EEG, [], 'exclude', eogIdx);

% ICA on a 1-Hz copy, then copy the weights back
EEG_ica = pop_eegfiltnew(EEG, 'locutoff', 1);
EEG_ica = pop_runica(EEG_ica, 'icatype', 'runica', 'extended', 1);
EEG.icaweights  = EEG_ica.icaweights;
EEG.icasphere   = EEG_ica.icasphere;
EEG.icachansind = EEG_ica.icachansind;
EEG.icawinv     = [];
EEG.icaact      = [];
EEG = eeg_checkset(EEG);

% Remove components ICLabel rates above 90% Eye or Muscle
EEG = pop_iclabel(EEG, 'default');
EEG = pop_icflag(EEG, [NaN NaN; 0.9 1; 0.9 1; NaN NaN; NaN NaN; NaN NaN; NaN NaN]);
artifactComps = find(EEG.reject.gcompreject);
if ~isempty(artifactComps)
    EEG = pop_subcomp(EEG, artifactComps, 0);
end

% Low-pass at 30 Hz
EEG = pop_eegfiltnew(EEG, 'hicutoff', 30);
EEG.setname = 'D1 main clean lp30';

% Epochs around 'square', baseline -200 to 0 ms
EEG = pop_epoch(EEG, {'square'}, [-1 2], 'newname', 'D1 epochs', 'epochinfo', 'yes');
EEG = pop_rmbase(EEG, [-200 0]);
EEG.setname = 'D1 epochs bl';
EEG = eeg_checkset(EEG);
EEG.filename = ''; EEG.filepath = ''; EEG.datfile = ''; EEG.saved = 'no';
[ALLEEG, EEG, CURRENTSET] = pop_newset(ALLEEG, EEG, 0, 'setname', 'D1 epochs bl', 'gui', 'off');
eeglab redraw;

الفكرة باختصار

ICAطريقة تفصل الإشارة المسجّلة إلى مصادر مستقلة، بعضها دماغي وبعضها آرتفاكت. أزال أغلب الرمش، لكن بعض الـ epochمقطع زمني قصير مقتطع حول حدث. قد تبقى فيها مشكلة: حركة مفاجئة، أو قطبelectrodeالقطعة المعدنية التي توضع على الرأس لالتقاط الإشارة. تحرّك لحظة، أو رمشة كبيرة لم يُزلها ICA كاملة. epoch واحد فيه قمة بمئات الميكروفولت يكفي ليشوّه المتوسط كله.

الحل البسيط: ارفض أي epoch تتجاوز فيه سعةamplitudeحجم الإشارة، ويُقاس في EEG بالميكروفولت (µV). حداً معيناً في أي قناةchannelالإشارة المسجّلة من قطب واحد، وهي ما يعرضه EEGLAB..

قبل وبعد

جرّب حدود رفضrejectionاستبعاد epochs أو بيانات لا تصلح للتحليل. مختلفة، ولاحظ عدد المرفوض وشكل المتوسط.

المحاكاة تحتاج JavaScript. هذه صورة ثابتة للفكرة نفسها.

أسئلتك بعد هذا، كل جواب في قسمه:

لماذا أحتاج هذه الخطوة؟

السبب بالتفصيل، والمصطلحات التي تحتاجها

لكن الرفض له ثمن: كل epoch ترفضه محاولةtrialتكرار واحد للمهمة في التجربة، غالباً حول مثير واحد. أقل في المتوسط، والمتوسط من محاولات أقل فيه ضوضاءnoiseأي جزء من التسجيل لا يحمل المعلومة التي نقيسها. أكثر. الهدف إذن ليس رفض كل ما يبدو غريباً، بل رفض ما يضر المتوسط فعلاً.

كيف أطبّقها في EEGLAB؟

16 خطوة من القوائم

ابدأ داتاستdatasetملف بيانات EEG واحد محمّل في EEGLAB مع معلوماته. D1 epochs bl مفتوحة، كما في “نقطة البداية”.

لماذا legacy؟

EEGLAB يسمّي هذه قائمةmenuمجموعة أوامر تظهر عند الضغط على اسمها في أعلى النافذة. legacy، لأنه يفضّل تنظيف البيانات المستمرة قبل التقطيع (مثل clean_rawdata). لكن رفض الـ epochs حدthresholdقيمة إذا تجاوزتها الإشارة اعتُبرت مشكلة. سعة بعد ICA ما زال خطوة شائعة في تحليل ERPمتوسط استجابة الدماغ لحدث معيّن عبر محاولات كثيرة.، وهي التي يشرحها كتاب Luck.

أولاً: علّم الـ epochs المتطرفة وارفضها بالسكربت

قائمة رفض الـ epochs مخفية افتراضياً في EEGLAB 2026.1، لذلك نبدأ بالسكربت.

  1. انسخ كتلة “السكربت المقابل” أدناه كاملة إلى نافذة الأوامر.
  2. تطبع نافذة الأوامر عدد المعلّم، مثل Marked 1 of 80 epochs. السكربت يحذف الـ epochs المعلّمة، ويسمّي الداتاست D1 epochs clean، ويحفظها باسم D1_epochs_clean.set، ويضيفها إلى قائمة Datasets. دروس المحطتين 6 و 7 تبدأ منها.
  3. إذا طُبع Marked 0 of 80 epochs فلا يوجد ما يُرفض. الداتاست الجديدة نسخة من السابقة بالاسم الجديد، وهذا صحيح.

ثانياً (اختياري): نفس الخطوة من القائمة

هذا طريق بديل للسكربت، لا خطوة إضافية. القائمة هي Tools ثم Reject data epochs ثم Reject extreme values، لكنها مخفية افتراضياً: تحت قائمة Tools ستجد سطراً رمادياً يقول (Expand tool choices via “File > Preferences”). لإظهارها:

  1. اختر D1 epochs bl من قائمة Datasets، واحفظها من File ثم Save current dataset as باسم D1_epochs_bl.set.
  2. افتح File ثم Preferences، وفعّل If set, show all menu items from previous EEGLAB versions. You must restart EEGLAB for this to take effect.، ثم Ok.
  3. أعد تشغيل EEGLAB: اكتب eeglab في نافذة الأوامر، ثم افتح الملف من File ثم Load existing dataset.

هذا الخيار يبقى محفوظاً، ويغيّر شكل كل القوائم عن صور هذه الدروس، فأطفئه بعد هذه الخطوة. بعد إظهار القائمة:

  1. افتح Tools ثم Reject data epochs ثم Reject extreme values.
  2. تظهر نافذة Rejection abnormal elec. values — pop_eegthresh(). اترك Electrode (indices(s), Ex: 2 4 5): على 1:32، أي كل القنوات.
  3. في Minimum rejection threshold(s) (uV, Ex:-20 -10 -15): اكتب -100 مكان الافتراضي -10.
  4. في Maximum rejection threshold(s) (uV, Ex: 20 10 15): اكتب 100 مكان الافتراضي 10.
  5. اترك Start time limit(s) (seconds, Ex -0.1 0.3): وEnd time limit(s) (seconds, Ex 0.2): على قيمتيهما، أي كامل الـ epoch.
  6. فعّل Reject marked trial(s) واضغط Ok.
  7. تفتح نافذة عرض الـ epochs، والمعلّمة للرفض ملوّنة. راجعها بعينك: تستطيع الضغط على epoch لإلغاء علامته أو إضافتها.
    • إذا طبعت نافذة الأوامر 0/80 trials marked for rejection فلا يوجد ما يُرفض، والزر REJECT لن يفعل شيئاً. أغلق نافذة العرض، وافتح Edit ثم Dataset info، واكتب في Dataset name الاسم D1 epochs clean، ثم Ok، وانتقل للخطوة 10.
  8. اضغط REJECT، ثم أكّد بـ YES.
  9. في نافذة الداتاست الجديدة اكتب في Name it: الاسم D1 epochs clean، ثم Ok.
  10. احفظها من File ثم Save current dataset as باسم D1_epochs_clean.set. دروس المحطتين 6 و 7 تبدأ منها.
الحدود الافتراضية

الحدود الافتراضية في النافذة (من -10 إلى 10 ميكروفولت) أمثلة للصيغة لا توصية. بهذه القيمة ستُرفض تقريباً كل الـ epochs.

كيف أكتبها بالكود؟

نفس الخطوات في 14 أسطر MATLAB
MATLAB
% Mark epochs where any channel goes beyond +/-100 uV anywhere in the epoch
EEG = pop_eegthresh(EEG, 1, 1:EEG.nbchan, -100, 100, EEG.xmin, EEG.xmax, 0, 0);
badEpochs = find(EEG.reject.rejthresh);
fprintf('Marked %d of %d epochs\n', numel(badEpochs), EEG.trials);

% Remove the marked epochs
if ~isempty(badEpochs)
    EEG = pop_rejepoch(EEG, EEG.reject.rejthresh, 0);
end
EEG.setname = 'D1 epochs clean';
EEG = eeg_checkset(EEG);
EEG = pop_saveset(EEG, 'filename', 'D1_epochs_clean.set', 'filepath', pwd);

% Add the clean dataset to the EEGLAB window
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG);
eeglab redraw

آخر رقم في pop_eegthresh يساوي 0، أي “علّم فقط ولا ترفض”. الرفض يتم في السطر التالي، حتى تطبع العدد قبله.

أي قيمة أختار؟

القيم المناسبة حسب هدف تحليلك
الإعدادالقيمةلماذا
حد السعة بعد تنظيف ICA±100 ميكروفولتقاعدة بداية شائعة. النشاط الدماغي في EEG عادة عشرات الميكروفولت، فما فوق 100 غالباً آرتفاكت.
حد صارم±50 ميكروفولت أو أقليرفض epochs نظيفة بسبب الضوضاء العادية والموجات البطيئة. جرّبه في التمرين أعلاه.
القنواتكل القنوات، ومنها EOGقنوات EOG بعد ICA نظيفة من الرمش، فإذا بقيت فيها قمة كبيرة في epoch، فهذا epoch يستحق الرفض.
النافذة الزمنيةكامل الـ epochأبسط اختيار. يمكن تضييقها للفترة التي تقيس فيها الـ ERP فقط.
الحد الأدنى لعدد المحاولاتلا رقم عاميعتمد على حجم مكوّن ERP. إذا رُفض أكثر من ربع المحاولات تقريباً، راجع البيانات قبل أن ترفع الحد.

القاعدة: نفس الحد لكل المشاركين ولكل الشروط، وتقرّره قبل رؤية النتائج. واذكر في ورقتك عدد المرفوض لكل شرط.

كيف أتأكد أنها نجحت؟

4 فحوص سريعة
  • نافذة الأوامر تطبع عدد المعلّم، مثل 1/80 trials marked for rejection. المتوقع في D1 بعد تنظيف ICA عدد قليل، بين 0 و 3 تقريباً، ويختلف قليلاً بين تشغيل وآخر لأن نتيجة ICA تختلف.
  • Epochs في النافذة الرئيسية تساوي 80 ناقص عدد المرفوض.
  • max(abs(EEG.data(:))) أصغر من 100.
  • الملف D1_epochs_clean.set موجود في مجلد العمل.

ما الأخطاء التي يقع فيها كثيرون؟

5 أخطاء، وكيف تتجنّبها
  • حد صارم جداً. يرمي بيانات جيدة، فيصير المتوسط من محاولات قليلة وأكثر ضوضاء. الحد الأمثل ليس أصغر رقم ممكن.
  • الرفض قبل تصحيح baseline. epoch مزاح كله عن الصفر قد يتجاوز الحد بلا آرتفاكت. صحّح baseline أولاً، كما في مسارنا.
  • الرفض بدل ICA. لو رفضت كل epoch فيه رمشة دون ICA، قد تخسر جزءاً كبيراً من بياناتك، كما ترى في المكوّن التفاعلي بحد ±50. ICA يصلح الرمش، والرفض للمشاكل النادرة.
  • عدد مختلف جداً بين الشروط. إذا رُفض 40% من شرط و 5% من آخر، فالمقارنة بينهما غير عادلة. افحص العدد لكل شرط.
  • نسيان الحفظ بعد الرفض. في الواجهة، الرفض ينشئ داتاست جديدة في الذاكرة فقط. احفظها قبل إغلاق EEGLAB.

كيف أكتبها في ورقتي؟

قالب Methods: عدّل البيانات والإعدادات والإصدارات لتطابق ما نفّذته

قالب: عدّل البيانات والإعدادات والإصدارات لتطابق ما نفّذته.

Epochs in which the voltage at any channel exceeded ±100 µV were rejected (pop_eegthresh, EEGLAB 2026.1), leaving [N] of 80 epochs.

أين أقرأ أكثر؟

3 مراجع: التوثيق الرسمي أولاً

مكتوب لـ EEGLAB 2026.1 · 2026-10-28

تحتاج مساعدة؟

اسأل، أو شاركنا رأيك، أو بلّغ عن خطأ