Preprocessing EEG data is a critical step in ensuring the accuracy and reliability of subsequent analyses. EEGLAB, a widely-used MATLAB toolbox, offers a robust framework for handling various preprocessing tasks. This comprehensive guide provides an in-depth MATLAB script tailored for EEG data preprocessing using EEGLAB, incorporating best practices and customizable parameters to accommodate diverse research needs.
Before executing the script, ensure the following prerequisites are met:
The preprocessing pipeline comprises the following main steps:
Begin by clearing the workspace and initializing EEGLAB. This ensures a clean environment for preprocessing.
% Clear workspace and Command Window
clear; close all; clc;
% Initialize EEGLAB
[ALLEEG, EEG, CURRENTSET, ALLCOM] = eeglab;
Load your EEG dataset into EEGLAB. Replace 'your_eeg_file.set' and 'path_to_your_data/' with your actual file name and path.
% Load EEG dataset
EEG = pop_loadset('filename', 'your_eeg_file.set', 'filepath', 'path_to_your_data/');
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, 0);
eeglab redraw;
Apply a band-pass filter to remove unwanted frequencies. Adjust the 'locutoff' and 'hicutoff' values as needed.
% Apply band-pass filter (0.5 - 50 Hz)
EEG = pop_eegfiltnew(EEG, 'locutoff', 0.5, 'hicutoff', 50);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
Re-reference the data to the average of all electrodes to minimize noise and improve signal quality.
% Re-reference to average
EEG = pop_reref(EEG, []);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
Detect and remove artifacts such as ocular and muscular noise using Independent Component Analysis (ICA) and the ICLabel plugin.
% Run ICA
EEG = pop_runica(EEG, 'extended', 1, 'interupt', 'on');
[ALLEEG, EEG] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
% Classify components using ICLabel
EEG = pop_iclabel(EEG, 'default'); % Opens ICLabel GUI
% Automatically reject components classified as artifacts with probability > 0.8
threshold = 0.8;
artifact_components = find(EEG.etc.ic_classification.ICLabel.classifications(:,2) >= threshold | ...
EEG.etc.ic_classification.ICLabel.classifications(:,3) >= threshold);
EEG = pop_subcomp(EEG, artifact_components, 0);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
Explanation: The script runs ICA to decompose the EEG signals into independent components. The ICLabel plugin then classifies these components, and those identified as artifacts (e.g., muscle or eye movements) with a probability above 0.8 are removed.
Segment the continuous EEG data into epochs around specific events of interest. Modify the event types and time window according to your experimental design.
% Define epoch parameters
event_types = {'stimulus'}; % Replace with your event markers
epoch_window = [-0.5 1.0]; % Time window in seconds
% Epoch the data
EEG = pop_epoch(EEG, event_types, epoch_window);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
Note: Ensure that the event markers in your dataset correspond to those specified in 'event_types'.
Apply baseline correction to remove any DC offset present in the epochs.
% Baseline correction from -200 ms to 0 ms
EEG = pop_rmbase(EEG, [-200 0]);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
Identify and interpolate bad channels to maintain data integrity.
% Detect and remove bad channels
[EEG, badChannels] = pop_rejchan(EEG, 'elec', 1:EEG.nbchan, 'threshold', 5, 'norm', 'on', 'measure', 'kurtosis');
disp(['Removed channels: ', mat2str(badChannels)]);
% Interpolate removed channels
EEG = pop_interp(EEG, EEG.chanlocs, 'spherical');
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
Explanation: Channels exhibiting excessive noise or artifacts are identified based on kurtosis and removed. They are then interpolated using spherical interpolation to estimate their values based on neighboring channels.
Downsample the data to reduce computational load. Adjust the target sampling rate as necessary.
% Define target sampling rate
target_srate = 250; % Hz
% Downsample if current rate is higher
if EEG.srate > target_srate
EEG = pop_resample(EEG, target_srate);
EEG = eeg_checkset(EEG);
disp(['Data resampled to ', num2str(target_srate), ' Hz.']);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
end
Save the preprocessed EEG dataset for future analyses. Specify the desired filename and save path.
% Define output file name and path
output_file = 'preprocessed_data.set';
output_path = 'path_to_save_data/';
% Save dataset
EEG = pop_saveset(EEG, 'filename', output_file, 'filepath', output_path);
[ALLEEG, EEG] = eeg_store(ALLEEG, EEG, CURRENTSET);
disp(['Preprocessed data saved as ', fullfile(output_path, output_file)]);
Combining all the steps, here's the complete MATLAB script for preprocessing EEG data using EEGLAB:
% Clear workspace and close figures
clear; close all; clc;
% Initialize EEGLAB
[ALLEEG, EEG, CURRENTSET, ALLCOM] = eeglab;
% Load EEG dataset
EEG = pop_loadset('filename', 'your_eeg_file.set', 'filepath', 'path_to_your_data/');
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, 0);
eeglab redraw;
% Apply band-pass filter (0.5 - 50 Hz)
EEG = pop_eegfiltnew(EEG, 'locutoff', 0.5, 'hicutoff', 50);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
% Re-reference to average
EEG = pop_reref(EEG, []);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
% Run ICA for artifact detection
EEG = pop_runica(EEG, 'extended', 1, 'interupt', 'on');
[ALLEEG, EEG] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
% Classify ICA components using ICLabel
EEG = pop_iclabel(EEG, 'default');
% Remove artifact components with probability >= 0.8
threshold = 0.8;
artifact_components = find(EEG.etc.ic_classification.ICLabel.classifications(:,2) >= threshold | ...
EEG.etc.ic_classification.ICLabel.classifications(:,3) >= threshold);
EEG = pop_subcomp(EEG, artifact_components, 0);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
% Epoch the data around 'stimulus' events (-0.5 to 1.0 sec)
event_types = {'stimulus'};
epoch_window = [-0.5 1.0];
EEG = pop_epoch(EEG, event_types, epoch_window);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
% Baseline correction (-200 ms to 0 ms)
EEG = pop_rmbase(EEG, [-200 0]);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
% Detect and remove bad channels based on kurtosis
[EEG, badChannels] = pop_rejchan(EEG, 'elec', 1:EEG.nbchan, 'threshold', 5, 'norm', 'on', 'measure', 'kurtosis');
disp(['Removed channels: ', mat2str(badChannels)]);
% Interpolate bad channels
EEG = pop_interp(EEG, EEG.chanlocs, 'spherical');
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
% Optional downsampling to 250 Hz
target_srate = 250;
if EEG.srate > target_srate
EEG = pop_resample(EEG, target_srate);
EEG = eeg_checkset(EEG);
disp(['Data resampled to ', num2str(target_srate), ' Hz.']);
[ALLEEG, EEG, CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);
eeglab redraw;
end
% Save the preprocessed dataset
output_file = 'preprocessed_data.set';
output_path = 'path_to_save_data/';
EEG = pop_saveset(EEG, 'filename', output_file, 'filepath', output_path);
[ALLEEG, EEG] = eeg_store(ALLEEG, EEG, CURRENTSET);
disp(['Preprocessed data saved as ', fullfile(output_path, output_file)]);
The provided script serves as a robust foundation for EEG preprocessing. Researchers can further enhance and customize the script by:
Effective preprocessing is paramount for extracting meaningful insights from EEG data. Utilizing EEGLAB within MATLAB provides a powerful and flexible environment to implement comprehensive preprocessing pipelines. By following the structured script outlined above and adhering to best practices, researchers can ensure high-quality EEG data ready for advanced analysis and interpretation.