Station 4 · Lesson 4

1-Hz filtering for ICA & copying weights

Core12 minBefore this lesson: Running ICAPrint the card
Starts from: eeglab_data.set (D1) · Already applied: High-pass & low-pass filtering, Removing line noise (50/60 Hz), Bad channels, Channel interpolation, Re-referencing, Running ICADownload the data (opens in a new tab)
Script to reach this state
MATLAB
[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);
EEG.setname = 'D1 main';
EEG_main = EEG;

% ICA copy: same data, high-pass at 1 Hz, with ICA weights
EEG_ica = pop_eegfiltnew(EEG_main, 'locutoff', 1);
EEG_ica.setname = 'D1 ica1hz';
EEG_ica = pop_runica(EEG_ica, 'icatype', 'runica', 'extended', 1);

% Dataset 1: main dataset; dataset 2: ICA copy
EEG_main.filename = ''; EEG_main.filepath = ''; EEG_main.datfile = ''; EEG_main.saved = 'no';
[ALLEEG, EEG, CURRENTSET] = pop_newset(ALLEEG, EEG_main, 0, 'setname', 'D1 main', 'gui', 'off');
EEG_ica.filename = ''; EEG_ica.filepath = ''; EEG_ica.datfile = ''; EEG_ica.saved = 'no';
[ALLEEG, EEG, CURRENTSET] = pop_newset(ALLEEG, EEG_ica, CURRENTSET, 'setname', 'D1 ica1hz', 'gui', 'off');
eeglab redraw;

The idea in brief

In the Running ICAA method that separates the recording into independent sources, some brain and some artifact. lesson you followed one rule: ICA is computed on a copy filtered at 1 Hz, not on the ERPThe brain's average response to a given event across many trials. data filtered at 0.1 Hz. This lesson explains why the rule works, and how to check that the weights moved correctly.

Before and after

Two copies of the same data: the main dataset with a 0.1 Hz high-pass and the ICA copy with a 1 Hz high-pass. ICA runs on the copy, then the weights are copied back to the main dataset, which continues to ICLabel and the ERP; the copy is used only to compute ICA.
What does this show?
The Pz ERP from -200 to 800 ms with two curves: the main data (0.1 Hz) in blue and the 1 Hz ICA copy in red. The positive wave between 300 and 600 ms is lower in the 1 Hz copy.
Data: EEGLAB sample data (eeglab_data.set)

Your next questions, each answered in its own section:

Why do I need this step?

The reasons in detail, and the terms you need

Why 1 Hz helps ICA. Slow drift is large, and it changes over the whole recording. ICA then spends part of its effort on it, and the components become less clear. The official tutorial says ICA decompositions are notably higher quality, with less ambiguous components, when the data are high-passA filter that passes high frequencies and weakens slow drifts. filtered above 1 Hz, sometimes even 2 Hz.

Why 1 Hz harms the ERP. Slow ERP components such as P3 contain low frequencies. A 1 Hz filterA tool that weakens some frequencies in a signal and keeps others. removes part of them, so P3 becomes smaller. You will measure this yourself in this lesson’s scriptA MATLAB file of commands that runs processing steps in order..

Why copying is valid. ICA does not learn a signalValues that change over time, such as the voltage recorded on a channel.. It learns a fixed way to combine the channels, which the official tutorial calls a spatial filter. The two copies have the same channels and the same mixing in the head; only their frequencies differ. So the same weights separate the same sources in both copies.

The only limit

, as the official tutorial says: an artifactA non-brain signal mixed into the recording, such as blinks or muscle activity. that lives only below 1 Hz is not learned by ICA, so ICA does not remove it. In practice the tutorial has not found this to be a problem, because artifacts below 2 Hz usually appear above 2 Hz too.

How do I do it in EEGLAB?

9 steps in the menus

Start with the two copies from the Starting point. Its script puts the main datasetOne EEG data file loaded in EEGLAB together with its information. in dataset 1 and the ICA copy in dataset 2.

First: check the two copies

  1. Open the Datasets menuA list of commands that opens from its name at the top of the window.. You see D1 main as dataset 1 and D1 ica1hz as dataset 2.
  2. Choose dataset 2. In the main window, ICA weights shows Yes.
  3. Choose dataset 1. ICA weights shows No, and Channels per frame is the same as in dataset 2: 32 in D1.

Second: copy the weights

  1. With dataset 1 current, open Edit then Dataset info.
  2. Next to ICA weights array or text/binary file (if any):, press from other dataset, type 2, then OK. Three fields fill in automatically: ALLEEG(2).icaweights, ALLEEG(2).icasphere, and ALLEEG(2).icachansind.
  3. Press OK to close the window. ICA weights now shows Yes for dataset 1.

Third: compare the maps

  1. With dataset 1 current, open Plot then Component maps then In 2-D.
  2. Choose dataset 2 and open the same window. The maps are identical, in the same order. The blinkClosing and opening the eye; seen as large peaks on frontal channels. component is in the same place in both.
  3. Save dataset 1, the 0.1 Hz main copy and not the 1 Hz ICA copy, with File then Save current dataset as as D1_main_ica.set. The ICLabelA tool that classifies each ICA component into seven classes with a probability for each. lesson starts from it.

When to use 2 Hz instead of 1

If many components stay ambiguous, with mixed or scattered maps, start again from dataset 1: filter a new copy at 2 Hz, run ICA on it, and copy its weights the same way. Dataset 1 stays at 0.1 Hz every time.

How do I write it as code?

The same steps in 26 lines of MATLAB
MATLAB
% EEG_main: main dataset (0.1 Hz); EEG_ica: ICA copy (1 Hz) with weights
% Copy the decomposition back to the main dataset
EEG_main.icaweights  = EEG_ica.icaweights;
EEG_main.icasphere   = EEG_ica.icasphere;
EEG_main.icachansind = EEG_ica.icachansind;
EEG_main.icawinv     = [];   % recomputed by eeg_checkset
EEG_main.icaact      = [];
EEG = eeg_checkset(EEG_main);

% Check: same weights and scalp maps in both copies
fprintf('Same weights: %d\n', isequal(EEG.icaweights, EEG_ica.icaweights));
fprintf('Largest scalp map difference: %g\n', max(abs(EEG.icawinv(:) - EEG_ica.icawinv(:))));
fprintf('ICA components: %d\n', size(EEG.icawinv, 2));

% Why two copies: ERP at Pz around 'square' events in each copy
epMain = pop_rmbase(pop_epoch(EEG, {'square'}, [-0.2 0.8]), [-200 0]);
epIca  = pop_rmbase(pop_epoch(EEG_ica, {'square'}, [-0.2 0.8]), [-200 0]);
pz  = find(strcmp({EEG.chanlocs.labels}, 'Pz'));
win = epMain.times >= 300 & epMain.times <= 600;
erpMain = mean(epMain.data(pz, :, :), 3);
erpIca  = mean(epIca.data(pz, :, :), 3);
fprintf('Mean at Pz, 300-600 ms: 0.1 Hz copy %.2f uV, 1 Hz copy %.2f uV\n', ...
    mean(erpMain(win)), mean(erpIca(win)));
figure;
plot(epMain.times, erpMain, epIca.times, erpIca);
legend('Main dataset (0.1 Hz)', 'ICA copy (1 Hz)');
xlabel('Time (ms)'); ylabel('Amplitude (uV)');

EEG = pop_saveset(EEG, 'filename', 'D1_main_ica.set', 'filepath', pwd);

The first block is the same weight-copy lines as in the Running ICA lesson. The check prints Same weights: 1, a scalp mapA top-down picture showing how a value is spread over the head. difference close to zero, and 31 components in D1.

The ERP block uses pop_epoch, which you will learn in station 5. Here it only shows the difference: in D1 the mean at Pz between 300 and 600 ms is about 4.3 µV in the main dataset, and about 3.1 µV in the 1 Hz copy. That is about 30% of the P3 lost if you continued on the ICA copy.

Which value should I choose?

Suitable values for your analysis goal
SettingValueWhy
High-pass for the ICA copy1 HzOfficial tutorial: ICA quality is notably higher above 1 Hz.
If components stay ambiguous2 HzThe official tutorial mentions 2 Hz as well. It costs nothing, because the ERP stays on the main dataset.
High-pass for the main dataset0.1 Hz, unchangedIt keeps slow ERP components such as P3 (the filtering lesson).
What you copyicaweights, icasphere, and icachansindThese three define the decomposition. icawinv and icaact are recomputed from the main data.
Channels in the two copiesExactly the same, in the same orderThe weights are tied to the channels.

How do I check it worked?

4 quick checks
  1. Main window: with dataset 1 current, ICA weights shows Yes.
  2. Same maps: the component maps of dataset 1 and dataset 2 are identical and in the same order.
  3. The script check: it prints Same weights: 1 and ICA components: 31 in D1.
  4. The ERP stays whole: the mean at Pz between 300 and 600 ms is larger in the main dataset than in the 1 Hz copy, about 4.3 against 3.1 µV in D1.

What mistakes do people make?

5 mistakes and how to avoid them
  • Continuing the ERP on the 1 Hz copy. P3 shrinks, as the script shows. The ICA copy is only for computing the weights; the analysis continues on the main dataset.
  • Copying only two of the three fields. The official tutorial mentions icaweights and icasphere. Copy icachansind too, or EEGLAB does not know which channels the weights belong to. The from other dataset button copies all three.
  • Different channels in the two copies. If you remove or interpolate a channel in one copy only, the weights no longer match. Do every channel step before you make the copy.
  • Copying icaact from the ICA copy. Those are the time courses of the 1 Hz data. Leave icawinv and icaact empty and let eeg_checkset recompute them from the main dataset.
  • Choosing a dataset number by guess. In from other dataset type the number of the ICA copy as shown in the Datasets menu. A wrong number copies other weights without an error.

How 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.

Independent component analysis (extended Infomax; Lee et al., 1999) was computed with runica ([31] components after PCA reduction to the data rank) on a copy of the data high-pass filtered at 1 Hz, and the resulting weights were applied to the 0.1 Hz high-pass filtered data.

Where can I read more?

4 sources, official docs first

Written for EEGLAB 2026.1 · 2026-10-29

Need help?

Ask, share feedback, or report an error