Station 3 · Lesson 5
clean_rawdata & ASR
eeglab_data.set (D1) · Already applied: High-pass & low-pass filtering, Removing line noise (50/60 Hz)Download the data (opens in a new tab)Script to reach this state
[ALLEEG, EEG, CURRENTSET, ALLCOM] = eeglab;
eeglabRoot = fileparts(which('eeglab'));
EEG = pop_loadset('eeglab_data.set', fullfile(eeglabRoot, 'sample_data'));
% 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);
EEG.filename = ''; EEG.filepath = ''; EEG.datfile = ''; EEG.saved = 'no';
[ALLEEG, EEG, CURRENTSET] = pop_newset(ALLEEG, EEG, 0, 'setname', 'D1 hp0.1 notch60', 'gui', 'off');
eeglab redraw;Your browser's back button takes you to the exact place you were, so open anything you like.
The idea in brief
Some artifacts are short and huge: a cable pulled, the participantThe person whose data were recorded in the study. moved, a sudden jump in all channels. They are not like blinks, which repeat with the same shape and which ICAA method that separates the recording into independent sources, some brain and some artifact. isolates well. A one-of-a-kind burst confuses ICA instead. On our path you try ASRA method that detects high-noise bursts and reconstructs them from clean data. on D1 only for comparison, and do not save the result.
Before and after
Image coming soon.
The window that opens after clean_rawdata, from vis_artifacts, on D1: the original data and the cleaned data overlaid in two colours, with the removed portions marked. Choose a segment that contains a removed portion. If D1 has no clear removed portion with these settings, use one participant from D3, high-pass filtered at 0.1 Hz, with the same settings except the ignored channels: type the eye channel names from that file’s channel list instead of EOG1 EOG2. Say so under the image. Source: an EEGLAB screenshot.
Your next questions, each answered in its own section:
Why do I need this step?
The reasons in detail, and the terms you need
artifactA non-brain signal mixed into the recording, such as blinks or muscle activity. Subspace Reconstruction (ASR) finds these bursts automatically. It is part of the clean_rawdata pluginA package that adds new functions or menus to EEGLAB., which ships with EEGLAB. As the official tutorial explains, it works in two stages:
- It finds clean portions of the recording, the calibration data, and learns how large normal activity is.
- It marks every short window whose activity is many times larger than the calibration data. The default is 20 standard deviations.
For recorded data the official tutorial advises removing the marked portions rather than correcting them. Correction was designed for real-time use, and its effect on offline analysis is not clearly understood.
Why do I need this step?
Artifact Subspace Reconstruction (ASR) finds these bursts automatically. It is part of the clean_rawdata plugin, which ships with EEGLAB. As the official tutorial explains, it works in two stages:
- It finds clean portions of the recording, the calibration data, and learns how large normal activity is.
- It marks every short window whose activity is many times larger than the calibration data. The default is 20 standard deviations.
For recorded data the official tutorial advises removing the marked portions rather than correcting them. Correction was designed for real-time use, and its effect on offline analysis is not clearly understood.
How do I do it in EEGLAB?
11 steps in the menus
Start with D1 hp0.1 notch60 loaded, as in the Starting point. It is already high-passA filter that passes high frequencies and weakens slow drifts. filtered.
- Open Tools then Reject data using Clean Rawdata and ASR.
- Leave Remove channel drift (data not already high-pass filtered) unchecked, because the data are already filtered at 0.1 Hz.
- Keep Process/remove channels checked, check Ignore these channels (ECG, EMG, …), and type
EOG1 EOG2next to it. - Uncheck the three channelThe signal recorded from one electrode, as shown in EEGLAB. criteria: Remove channel if it is flat for more than (seconds), Max acceptable high-frequency noise std dev, and Min acceptable correlation with nearby chans [0-1]. Bad channels belong to their own lesson.
- Keep Perform Artifact Subspace Reconstruction bad burst correction/rejection checked, with
20in Max acceptable 0.5 second window std dev. - Keep Remove bad data periods (when uncheck, correct using ASR) checked, and leave Use Riemanian distance metric (not Euclidean) - beta unchecked.
- Keep Additional removal of bad data periods checked, with
-Inf 7in Acceptable [min max] channel RMS range (+/- std dev) and25in Maximum out-of-bound channels (%). - Keep Pop up scrolling data window with rejected data highlighted checked and press OK.
- A scrolling window shows the original and cleaned data together. Scroll through it and look at what was removed.
- Name the new datasetOne EEG data file loaded in EEGLAB together with its information.
D1 asr. In the main window, compare Frames per epoch and Events withD1 hp0.1 notch60. The extra events are the boundary events. - Do not save
D1 asr. The main path continues fromD1 hp0.1 notch60.
How do I do it in EEGLAB?
Start with D1 hp0.1 notch60 loaded, as in the Starting point. It is already high-pass filtered.
- Open Tools then Reject data using Clean Rawdata and ASR.
- Leave Remove channel drift (data not already high-pass filtered) unchecked, because the data are already filtered at 0.1 Hz.
- Keep Process/remove channels checked, check Ignore these channels (ECG, EMG, …), and type
EOG1 EOG2next to it. - Uncheck the three channel criteria: Remove channel if it is flat for more than (seconds), Max acceptable high-frequency noise std dev, and Min acceptable correlation with nearby chans [0-1]. Bad channels belong to their own lesson.
- Keep Perform Artifact Subspace Reconstruction bad burst correction/rejection checked, with
20in Max acceptable 0.5 second window std dev. - Keep Remove bad data periods (when uncheck, correct using ASR) checked, and leave Use Riemanian distance metric (not Euclidean) - beta unchecked.
- Keep Additional removal of bad data periods checked, with
-Inf 7in Acceptable [min max] channel RMS range (+/- std dev) and25in Maximum out-of-bound channels (%). - Keep Pop up scrolling data window with rejected data highlighted checked and press OK.
- A scrolling window shows the original and cleaned data together. Scroll through it and look at what was removed.
- Name the new dataset
D1 asr. In the main window, compare Frames per epoch and Events withD1 hp0.1 notch60. The extra events are the boundary events. - Do not save
D1 asr. The main path continues fromD1 hp0.1 notch60.
How do I write it as code?
The same steps in 16 lines of MATLAB
% ASR on a copy: no channel criteria (bad channels lesson), EOG channels ignored
EEG_asr = pop_clean_rawdata(EEG, 'FlatlineCriterion', 'off', 'ChannelCriterion', 'off', ...
'LineNoiseCriterion', 'off', 'Highpass', 'off', 'BurstCriterion', 20, ...
'WindowCriterion', 0.25, 'BurstRejection', 'on', 'Distance', 'Euclidian', ...
'WindowCriterionTolerances', [-Inf 7], 'channels_ignore', {'EOG1', 'EOG2'});
EEG_asr.setname = 'D1 asr';
% How much data was kept, and how many boundary events were added
fprintf('Data kept: %.1f of %.1f s (%.1f%%)\n', EEG_asr.pnts / EEG_asr.srate, ...
EEG.pnts / EEG.srate, 100 * EEG_asr.pnts / EEG.pnts);
fprintf('Boundary events: %d\n', sum(strcmp({EEG_asr.event.type}, 'boundary')));
% Effect on epochs: pop_epoch drops every epoch that contains a boundary event
epBefore = pop_epoch(EEG, {'square'}, [-0.2 0.8]);
epAfter = pop_epoch(EEG_asr, {'square'}, [-0.2 0.8]);
fprintf('Epochs around square: %d before ASR, %d after\n', epBefore.trials, epAfter.trials);
% Original and cleaned data in one scrolling window
vis_artifacts(EEG_asr, EEG);The scriptA MATLAB file of commands that runs processing steps in order. prints how many seconds were kept, how many boundary events were added, and how many epochs around square survive. pop_epoch is from station 5; here it only counts the epochs lost.
How do I write it as code?
% ASR on a copy: no channel criteria (bad channels lesson), EOG channels ignored
EEG_asr = pop_clean_rawdata(EEG, 'FlatlineCriterion', 'off', 'ChannelCriterion', 'off', ...
'LineNoiseCriterion', 'off', 'Highpass', 'off', 'BurstCriterion', 20, ...
'WindowCriterion', 0.25, 'BurstRejection', 'on', 'Distance', 'Euclidian', ...
'WindowCriterionTolerances', [-Inf 7], 'channels_ignore', {'EOG1', 'EOG2'});
EEG_asr.setname = 'D1 asr';
% How much data was kept, and how many boundary events were added
fprintf('Data kept: %.1f of %.1f s (%.1f%%)\n', EEG_asr.pnts / EEG_asr.srate, ...
EEG.pnts / EEG.srate, 100 * EEG_asr.pnts / EEG.pnts);
fprintf('Boundary events: %d\n', sum(strcmp({EEG_asr.event.type}, 'boundary')));
% Effect on epochs: pop_epoch drops every epoch that contains a boundary event
epBefore = pop_epoch(EEG, {'square'}, [-0.2 0.8]);
epAfter = pop_epoch(EEG_asr, {'square'}, [-0.2 0.8]);
fprintf('Epochs around square: %d before ASR, %d after\n', epBefore.trials, epAfter.trials);
% Original and cleaned data in one scrolling window
vis_artifacts(EEG_asr, EEG);The script prints how many seconds were kept, how many boundary events were added, and how many epochs around square survive. pop_epoch is from station 5; here it only counts the epochs lost.
Which value should I choose?
Suitable values for your analysis goal
| Setting | Value | Why |
|---|---|---|
| ASR threshold (Max acceptable 0.5 second window std dev) | 20 | The default, and quite conservative according to the plugin page. |
| A stricter threshold | 5 | The plugin calls 5 reasonably conservative, but notes that some extreme EEG bursts, such as sleep spindles, can cross even 5. |
| The most aggressive value | 3 | The plugin says it is the most aggressive value that can be used without losing much EEG. |
| Remove or correct | Remove | Official tutorial: correction was designed for real-time use. |
| Remove channel drift (data not already high-pass filtered) | Unchecked if you already filtered | Otherwise the data are filtered twice. |
| Non-brain channels (EOG, ECG) | Ignored | Their large signal is not a fault, and the bad channels lesson ignores them for the same reason. |
When to use ASR, and when to avoid it:
| Use it | Avoid it |
|---|---|
| Data with rare, huge bursts, such as movement or cable artifacts | Data that are already clean, such as D1 |
| Before ICA, to give ICA cleaner training data | When every epoch matters and the bursts are few: remove them by eye instead |
| With a conservative threshold such as 20 | With a low threshold that removes blinks, which ICA can correct |
Which value should I choose?
| Setting | Value | Why |
|---|---|---|
| ASR threshold (Max acceptable 0.5 second window std dev) | 20 | The default, and quite conservative according to the plugin page. |
| A stricter threshold | 5 | The plugin calls 5 reasonably conservative, but notes that some extreme EEG bursts, such as sleep spindles, can cross even 5. |
| The most aggressive value | 3 | The plugin says it is the most aggressive value that can be used without losing much EEG. |
| Remove or correct | Remove | Official tutorial: correction was designed for real-time use. |
| Remove channel drift (data not already high-pass filtered) | Unchecked if you already filtered | Otherwise the data are filtered twice. |
| Non-brain channels (EOG, ECG) | Ignored | Their large signal is not a fault, and the bad channels lesson ignores them for the same reason. |
When to use ASR, and when to avoid it:
| Use it | Avoid it |
|---|---|
| Data with rare, huge bursts, such as movement or cable artifacts | Data that are already clean, such as D1 |
| Before ICA, to give ICA cleaner training data | When every epoch matters and the bursts are few: remove them by eye instead |
| With a conservative threshold such as 20 | With a low threshold that removes blinks, which ICA can correct |
How do I check it worked?
4 quick checks
- The scrolling window showed the original and cleaned data, and you saw what was removed.
- The script check: it prints the seconds kept, the number of boundary events, and the epochs before and after.
- The events increased in the main window by the number of boundary events.
- The path is unchanged:
D1 asris not saved, and the next lesson starts fromD1 hp0.1 notch60.
How do I check it worked?
- The scrolling window showed the original and cleaned data, and you saw what was removed.
- The script check: it prints the seconds kept, the number of boundary events, and the epochs before and after.
- The events increased in the main window by the number of boundary events.
- The path is unchanged:
D1 asris not saved, and the next lesson starts fromD1 hp0.1 notch60.
What mistakes do people make?
5 mistakes and how to avoid them
- Using correction instead of removal on recorded data. Keep Remove bad data periods (when uncheck, correct using ASR) checked.
- A threshold that is too low. At 3 or 5, ASR may remove blinks and large but normal brain activity. Start at 20, look at what was removed, then decide.
- Forgetting the boundary events. Each removed portion becomes a boundary event, and every epoch that contains one is dropped. Count the epochs before and after.
- Running ASR on data with a slow drift. ASR needs high-pass filtered data, as the plugin page notes. Filter first, or check Remove channel drift (data not already high-pass filtered).
- Not looking at the result. The official plugin page recommends that new users compare the original and cleaned data by eye. The scrolling window is there for that.
What mistakes do people make?
- Using correction instead of removal on recorded data. Keep Remove bad data periods (when uncheck, correct using ASR) checked.
- A threshold that is too low. At 3 or 5, ASR may remove blinks and large but normal brain activity. Start at 20, look at what was removed, then decide.
- Forgetting the boundary events. Each removed portion becomes a boundary event, and every epoch that contains one is dropped. Count the epochs before and after.
- Running ASR on data with a slow drift. ASR needs high-pass filtered data, as the plugin page notes. Filter first, or check Remove channel drift (data not already high-pass filtered).
- Not looking at the result. The official plugin page recommends that new users compare the original and cleaned data by eye. The scrolling window is there for that.
Your browser doesn't allow saving progress. All lessons are open, but completion marks won't be saved.
Done. Your progress is saved in this browser.UndoHow do I write it in my paper?
A Methods template: edit the data, settings and versions to match what you ran
A template: edit the data, settings and versions to match what you ran.
High-amplitude bursts were identified with Artifact Subspace Reconstruction (burst criterion 20 SD; clean_rawdata plugin 2.11, EEGLAB 2026.1), and the affected periods were removed together with windows in which more than 25% of channels exceeded 7 SD ([N] s, [P]% of the data); EOG channels were excluded.How do I write it in my paper?
A template: edit the data, settings and versions to match what you ran.
High-amplitude bursts were identified with Artifact Subspace Reconstruction (burst criterion 20 SD; clean_rawdata plugin 2.11, EEGLAB 2026.1), and the affected periods were removed together with windows in which more than 25% of channels exceeded 7 SD ([N] s, [P]% of the data); EOG channels were excluded.Where can I read more?
4 sources, official docs first
- EEGLAB TutorialDocumentation6. Reject artifacts > c. Automated rejection
- EEGLAB pluginDocumentationclean_rawdata
- EEGLAB TutorialDocumentationIssues associated with aggressive automated artifact removal before ICA
- EEGLAB preprocessing #7: Removing bad data segmentsVideoFull video · 11:06
Written for EEGLAB 2026.1 · 2026-10-29
Going further
- EEGLAB Tutorial: https://eeglab.org/tutorials/06_RejectArtifacts/cleanrawdata.html (6. Reject artifacts > c. Automated rejection)
- EEGLAB plugin: https://eeglab.org/plugins/clean_rawdata/ (clean_rawdata)
- EEGLAB Tutorial: https://eeglab.org/tutorials/06_RejectArtifacts/RunICA.html (Issues associated with aggressive automated artifact removal before ICA)
- EEGLAB preprocessing #7: Removing bad data segments: https://www.youtube.com/watch?v=ZvbRiX84mgc (Full video)
Need help?
Ask, share feedback, or report an error
- Report a scientific error · Needs a GitHub account. Don't have one? Use "Share your thoughts".