User Tools

Site Tools



EEGLAB Hackathon
Main Website


Getting cosy with EEGLAB: Batch Crews

1. Basic programming tips & loops

As we said earlier, the ultimate goal is to be able to automatise the processing pipeline. Imagine having to go through 20 participants manually and waiting for each steps to be processed to carry on, in the case of long steps like ICA, it would probably take you days to just pre-process your data. We will therefore want to write our own batch scripts to automatise some of the processes.

EEG/ERPLab commands

  • All functions corresponding to EEGLAB menus are listed here and all EEGLAB functions even those not currently attached to a GUI menu can be found here.
  • Every menu window should have the name of the function it will call, which makes it easy to know which function to call when scripting.
  • Just like with any function MATLAB will have a help file stored which gives helpful details about each function and the arguments that it requires. For example, if you typed help pop_loadset(), MATLAB would display a help text file which would tell you that the function needs a the name of a file and its path. The function would then take the following shape: EEG = pop_loadset('filename', 'S1.set');
  • Recently, EEGLAB has implemented a function to export the history of your processing session to a *.mat file. This means that for all the steps we have done so far we actually can retrieve the command line that was ran. It's not perfect, but it's a great help to quickly script stepts and customise them.
  • For example, when we loaded the *.cnt file at the beginning of our session, the menu called the function pop_loadcnt() and the function took the following form:
EEG = pop_loadcnt('/Users/pss059/Desktop/LabelsData/526.cnt' , 'dataformat', 'auto', 'memmapfile', '');

What this basically does is assign a loaded dataset into an object called EEG. EEG refers to the current dataset loaded in memory. It is a convention of EEGLAB.

Loops & hoops

The level of programming that batching requires doesn't really go much further than creating loops. Which once you've seen one you know them all.

The basic idea of a loop is to loop through a certain number of operations for a certain number of times and goes through the following logic:

  1. Declare the variable you want to loop over var=value
  2. Explain how you are looping through the variable
    1. A common one is to go through each element of the variable for length(var)
  3. List operations to be performed e.g., a=rand()
  4. end loop

Here are a few basic loops:

%lets count people
for i=1:length(people)
%lets make it harder for us to count manually
for j=1:n;
%lets count males and females
%males are labelled by a 1
&females are labelled by a 0
for k=1:length(people)
    if people(k)==1
%collect info in a loop
for l=1:n

In our case, we will want to perform a series of operations which will be repeated over participants:

  • We will first “load” our participants (say their participant number –but it could be anything)
 subject={'100' '101' '103' '104'};
  • Then we will specify how we are going through the loop. In this instance we want each instance of ppts to be passed through. The little voice in the computer goes like this: “for each instance of ppts…”
subject={'100' '101' '103' '104'};
for i=1:length(subject)
  • Last thing, we need make stuff happen. In this instance the first thing we will probably want to do is to load a *.cnt file.
subject={'100' '101'};
for i=1:length(subject)
  EEG = doSomething();

If we run this, MATLAB will doSomething() to the object EEG for all two participants.

2. Preparation of "NightCrew" script

The steps that we have taken so far, at least some operations, are pretty slow (ICA). Before we carry those out there is not much that we can do with the data in terms of analysis. So the plan is to run these steps at night when it doesn't matter whether we can use our computer or not.

For this reason we will talk of two kinds of scripts:

  • “Night Crew”, runs at night and shouldn't include steps with which we often play around.
  • “Dat Crew”, run during the day. They're usually scripts that take no more than 5 minutes to run. It will usually includes steps which we might have to re-configurate or runs steps which give us results we need to attend to directly.

Now is the time to get some serious business going on:

wait 2 seconds

We will go through each of the GUI steps again but this time look at how they can be implemented using command lines.

1. Load CNT

 EEG = pop_loadcnt([subject{i} '.cnt'], 'dataformat', 'int32'); 

pop_loadcnt() loads a CNT file, makes an EEG structure and write it into the EEG object. [subject{i} '.cnt'] is the filename (it can contain a path as well. Instead of manually writing the file name 101.cnt we replace this by passing through the current value of the array subject. The {i} instructs MATLAB to pull out the value equal to the cell the loop is currently reading. 'dataformat', 'int32' are optional parameters. Here they indicate MATLAB that the file format is in 32bits.

2. Load electrode positions, append channel for online reference, label appended channel as the reference

%add electrode positions, and specify online ref
EEG = pop_chanedit(EEG,'append',66,'changefield',{67 'labels' 'Cz'},...
'setref',{'1:67' 'Cz'});

This one line (although it looks slightly long) condenses the cumbersome first steps of re-referenceing: 'append',66 appends a channel after channel number 66.
'changefield', {67 'labels' 'Cz'} changes information about channel 67 namely, its label.
'lookup', '/Users…cap385.elp' looks-up locations for all electrodes in the BESA file.
'setref',{'1:67' 'Cz'} labels Cz as the current reference to all channels.

One final step in that part is needed: referencing to the common average:

%add electrode positions, and specify online ref
EEG = pop_chanedit(EEG,'append',66,'changefield',{67 'labels' 'Cz'},...
'setref',{'1:67' 'Cz'});
%re-reference to common average & reconstruct signal at current reference
EEG = pop_reref( EEG, [],'refloc',struct('labels',{'Cz'},'type',{''},'theta',{0},'radius',{0},'X',{5.2047e-15},'Y',{0},'Z',{85},'sph_theta',{0},'sph_phi',{90},'sph_radius',{85},'urchan',{67},'ref',{'Cz'},'datachan',{0}), 'exclude',[65 66]);

Again this looks like a long one but we don't need to worry much: [] means “all channels” and therefore computes an average reference 'refloc instructs to reconstruct the signal of the online reference electrode. It takes the long struc() as input, which contains the name of the channel, the location and the fact that it is the current reference. 'exlude', [65 66] makes sure channels 65 66 (VEOG & HEOG) do not take part in the average reference, since these channels are not part of the scalp and would add noise to the data.

3. Pre-epoching (file size reduction)

%make epochs for the following triggers
EEG = pop_epoch( EEG, {  '111'  '112'  '113'  '114'  '121'  '122'  '123'  '124'  '131'  '132'  '133'  '134'  '141'  '142'  '143'  '144'  '151'  '152'  '153'  '154'  '211'  '212'  '213'  '214'  '221'  '222'  '223'  '224'  '231'  '232'  '233'  '234'  '241'  '242'  '243'  '244'  '251'  '252'  '253'  '254'  }, [-0.1 1], 'epochinfo', 'yes');
%remove baseline
EEG = pop_rmbase( EEG, [-100 0]);

This one is easy: {'111' '112' … '245'} lists all trigger types for which we want to create epochs. [-0.1 1] min max limits (in seconds) of your epochs 'epochinfo' is set to true and will populate the data set with the even info (you want this on).

We also want to baseline correct those epochs that is what pop_rmbase does. [-100 0] sets the min max limites in MILLIseconds this time.

4. Filtering

  EEG  = pop_basicfilter( EEG,  1:67 , 'Cutoff', [ 0.1 30], 'Design', 'butter', 'Filter', 'bandpass', 'Order',  4 );

5. ICA decomposition

EEG = pop_runica(EEG, 'extended',1,'interupt','on');

6. Other useful commands

Here are some useful commands that you may want to use after some operations, like save intermediary sets for some sets (to which you think you might want to go back), or check that the set contains no problem (especially useful after modifying events and epochs).

  • change the name of a set
EEG.setname = 'NewSetName';
  • save a set
EEG = pop_saveset(EEG, 'filename','101.set','filepath', '/User.../setfolder/');
  • check set consistency
EEG = pop_checkset(EEG);


Now that we have brushed up a few things about loops and now that we have seen a few useful commands for EEGLAB.
Let's see if we can write a simple routine that loads a *.cnt file and exports it (or save it) as an EEGLAB dataset.


One last very handy piece of code to know is the try-catch “loop”

Whenever something goes wrong between the try and catch MATLAB will jump to the statement just after catch and will continue. You can use that to jump over a buggy dataset for example:

  • Here would be the implementation that avoids banging your head on the table 10 times because you've lost a night of processing
subject={'100' '101' '103' '104'};
for i=1:length(subject)
    EEG = pop_loadcnt([subject{i} '.cnt'], 'dataformat', 'int32');
    disp([‘Something went wrong with participant’ subject{i} ‘ Skipping to next participant’]);


Now that we have brushed up a few things about loops and now that we have every command line corresponding to our processing pipeline your task is to write a fully functional Night Crew batch.

  • Making sure that it cycles over participants and
  • that it saves the a set after epoching/baseline, and after filtering in case the filter or ICA step crash.
  • make sure your loop doesn't get stuck because of a buggy dataset.
  • save final dataset. (NOTE. when saving datasets you might want to think of a way to name the dataset with the subject information)
% This script runs the initial and time consuming routines which
% are usually ran at night especially if ICA decomposition is included
% Author: Bastien Boutonnet,
subject={'505', '510'};
for i=1:length(subject)
   fprintf('Processing Subject #%g : %s...\n', i, subject{i});
%creates the destination folder assuming you have not created it manually before
%if test makes sure the folder only gets created once.
    if isequal(exist(pathname_write, 'dir'),7) %7 = directory
        display('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Destination folder exists. All Good to go!');
        [mdirstatus, mdirmessage]=mkdir(pathname_write)
        display('%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Destination folder does not exist. Chillax! Will be created');
    %add electrode positions, and specify online ref
	EEG = pop_loadcnt([pathname_read subject{i} '.cnt'] , 'dataformat', 'int32');
	EEG = pop_chanedit(EEG, 'append',66,'changefield',{67 'labels' 'Cz'},'lookup','/Users/pss059/Documents/MATLAB/eeglab12_0_2_5b/plugins/dipfit2.2/standard_BESA/standard-10-5-cap385.elp','setref',{'1:67' 'Cz'});
    %re-reference to common average & reconstruct signal at current reference
    EEG = pop_reref( EEG, [],'refloc',struct('labels',{'Cz'},'type',{''},'theta',{0},'radius',{0},'X',{5.2047e-15},'Y',{0},'Z',{85},'sph_theta',{0},'sph_phi',{90},'sph_radius',{85},'urchan',{67},'ref',{'Cz'},'datachan',{0}), 'exclude',[65 66]);
    %make epochs (all triggers of interest individually
    %we will in fact comment the remove baseline step since at the minute
    %we just want to cut the file to reduce dimensions.
    EEG = pop_epoch( EEG, {  '111'  '112'  '113'  '114'  '121'  '122'  '123'  '124'  '131'  '132'  '133'  '134'  '141'  '142'  '143'  '144'  '151'  '152'  '153'  '154'  '211'  '212'  '213'  '214'  '221'  '222'  '223'  '224'  '231'  '232'  '233'  '234'  '241'  '242'  '243'  '244'  '251'  '252'  '253'  '254'  }, [-0.1 1], 'epochinfo', 'yes');
    %EEG = pop_rmbase( EEG, [-100    0]);
    %We could already delete epochs which are followed by an incorrect
    %response. Although I prefer to keep this for the subsequent Day Crews
    %EEG = pop_selectevent( EEG, 'type',1,'deleteevents','off','deleteepochs','on','invertepochs','off');
    %Save set prior to filtering (in case of crash)
    EEG.setname = [subject{i} 'RREP'];
    EEG = pop_saveset( EEG,  'filename', [pathname_write subject{i} '_RREP.set']);
    EEG = eeg_checkset(EEG);
    %filter the data
    EEG  = pop_basicfilter( EEG,  1:67 , 'Cutoff', [ 0.1 30], 'Design', 'butter', 'Filter', 'bandpass', 'Order',  4 );
    %Save intermediary set in case ICA crashes
    EEG.setname = [subject{i} 'RREPF'];
    EEG = pop_saveset( EEG,  'filename', [pathname_write subject{i} '_RREPF.set']);
    %run ICA decomposition
    EEG = pop_runica(EEG, 'extended',1,'interupt','on');
    %Save final set
    EEG.setname = [subject{i} 'RREPFICA'];
    EEG = pop_saveset( EEG,  'filename', [pathname_write subject{i} '_RREPFICA.set']);
    %Once you have fully debugged your script and that you know it goes
    %through without problems (Due to scripting) uncomment the following
    %lines. It allows you to jump participants if the sets are buggy but
    %won't give you error messages.
    %   disp(['%%%%%%%%%%%%%%%%%%%%%%%%%Something went wrong with participant ' subject{i} ' ! Skipping to next participant %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%']);

DISCLAIMER: The tutorials provided on this wiki are not intended to compete with the tutorials written by the EEGLAB's (and other toolboxes) developers (EEGLAB website). It intends to be a condensed version for educational/reference purposes for members of the lab/department to which this workshop was given.

eeglabsessh1b.txt · Last modified: 2014/10/08 03:14 (external edit)