A3. Adding capabilities to EEGLAB
Please send us (eeglab@sccn.ucsd.edu) any EEGLAB-compatible functions you think would be of interest to other researchers. Include, best in the help message (or in a comment following), a brief explanations and/or references for the signal processing methods used.
A3.1. Open source policy
1 - EEGLAB is distributed under the GPL GNU license, which states that the software cannot be modified for commercial purposes. Any contributed functions we add to EEGLAB will be made available for free non-commercial use under this license.
2 - We will credit your authorship of the functions on the function help pages. The authors will retain all commercial rights to the functions.
3 - Functions that we find to be accurate, stable, of some general interest and complementary to existing EEGLAB functions will first be included in a 'contributed' directory distributed as a part of EEGLAB. If a contributed function proves to be stable and of widespread interest, we may integrate it into the main EEGLAB menu.
A3.2. How to write EEGLAB functions
Adding new functionality to EEGLAB requires a pair of functions, a signal processing function (Ex: sample.m) and an accompanying pop_function (Ex: pop_sample.m). The pop_function pops up a text input window allowing the user to specify arguments to the signal processing function. The Matlab help messages for each function should state clearly what input arguments the functions require and what they output, using the help message format explained below.
A3.2.1. The signal processing function
This function should comply with the EEGLAB help-message syntax to allow the header to be converted into an .html help page by (functions makehtml() and help2html() ). We propose this sample header. Below is the GNU license disclaimer to include in the function header.
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USAA3.2.2. The associated pop_ function
The pop_function creates a graphic interface to the signal processing function. It should include the same disclaimer as the signal processing function and
1 - It must take the EEGLAB data structure 'EEG' as a first input. The second parameter may specify whether the signal processing function will be applied to ICA component activations or to the raw EEG data channels.Writing the pop_function is easy and can usually be done in a few minutes if you just modify the pop_sample.m function source.2 - Additional parameters should be optional. If they are left blank in the pop_function call, a window should pop-up to ask for their values.
3 - The pop_function must return a 'string' containing the resulting call to the signal processing function (or in some cases to the pop_function). When this string is evaluated (using the Matlab function 'eval)'), the result must be the same as that of the pop_function itself, e.g. including all the parameters the user may enter into the pop window. This string will be pushed into the EEGLAB command history stack.
4 - By convention, if the function draws a figure, calling the function without enough arguments should pop up a new figure. However, with enough arguments (macro call), the function should directly draw the output graphic in the current figure (thus allowing the user to build multi-part figures, e.g. using 'sbplot()' commands).
A3.3. How to write an EEGLAB plugin
EEGLAB will automatically incorporate any appropriately named "plugin" functions (Ex: 'eegplugin_myfunc.m') that EEGLAB finds in the same directory as 'eeglab.m'. Creating an EEGLAB plugin will add a menu item with the menu label(s) specified in your plugin to the bottom of an EEGLAB menu (the top menu label possibly linked to an unlimited number of sub-menus). These menu item(s) can call standard or custom data processing and "pop" functions (see examples below). When a user downloads an EEGLAB plugin (either from the main EEGLAB site or from any other site), he or she simply has to uncompress the plugin files into the plugin sub-directory or into the main EEGLAB directory (where eeglab.m is located). The plugin will be detected by EEGLAB at startup by looking for a file or directory name beginning with "eegplugin_" in the main EEGLAB directory (i.e., the same directory as 'eeglab.m'). You may also place this file in a sub-directory of the EEGLAB plugin directory.
A3.3.1. The plugin function
To create a new EEGLAB plugin, simply create a Matlab function file whose name begins with "eegplugin_" and place it into the plugin subdirecotry or your main EEGLAB directory. This function must take three arguments, as in the 'test' plugin below:
eegplugin_test( fig, try_strings, catch_strings);The three arguments above are provided to the plugin by eeglab(). The first argument ('fig') is the handle of the main EEGLAB window. The second and third arguments are structures passed by EEGLAB that allow the plugin to check parameters, detect errors, etc. (see below). If you do not want your plugin to alter EEGLAB history and error message handling, you can ignore the latter two parameters (although the plugin function definition still must list all three arguments).
A3.3.2. Adding a sub-menu
To create a new submenu under a top-level EEGLAB menu, simply add a command like this to your plugin function:
uimenu( fig, 'label', 'My function', 'callback', ...
[ 'EEG = pop_myfunc(EEG, ...); [ALLEEG EEG CURRENTSET] ...
= eeg_store(ALLEEG, EEG, CURRENTSET);' ]);The statement "[ALLEEG EEG CURRENTSET] = eeg_store(ALLEEG, EEG, CURRENTSET);" above insures that your modified EEG dataset will be stored in the EEGLAB "ALLEEG" structure.
A3.3.3. Plugins and EEGLAB history
If you want your plugin to interact with the EEGLAB history mechanism, you should take advantage of the second ('try_strings') and third ('catch_strings') arguments to your plugin function. The second argument (see eegplugin_test() above) contains commands (organized into a Matlab structure) that check the input dataset and attempt to execute your command. The third argument ('catch_strings') contains commands to handle errors and add the contents of the LASTCOM (i.e., last command) variable to the EEGLAB history.
Plugin functions should declare one or more EEGLAB menu items. Each menu declaration should look like this:
uimenu( submenu, 'label', 'My function', 'callback', ...
[ try_strings.anyfield '[EEG LASTCOM] ...
= pop_myfunc(EEG, ...);' arg3.anyfield ]);Possible fields for 'try_strings' (above) are:
- try_strings.no_check : check for the presence of a non-empty EEG dataset only
- try_strings.check_ica : check that the dataset includes ICA weights
- try_strings.check_cont : check that the dataset is continuous
- try_strings.check_epoch : check that the dataset is epoched
- try_strings.check_event : check that the dataset contains events
- try_strings.check_epoch_ica : check that the dataset is epoched and includes ICA weights
- try_strings.check_chanlocs : check that the dataset contains a channel location file
- try_strings.check_epoch_chanlocs : check that the dataset is epoched and includes a channel location file
- try_strings.check_epoch_ica_chanlocs : check that the dataset is epoched and includes ICA weights and a channel location file.
Possible fields for 'catch_strings' are:
- catch_strings.add_to_hist : add the LASTCOM variable content (if not empty) to the EEGLAB history
- catch_strings.store_and_hist : add the LASTCOM variable content (if not empty) to the EEGLAB history and store the EEG dataset in the ALLEEG variable.
- catch_strings.new_and_hist : add the LASTCOM variable content (if not empty) to the EEGLAB history and pop up a window for a new dataset.
A3.3.4. Plugin examples
A simplest type of plugin function might only call a plotting function. For instance, to write a simple plugin to plot the ERP trial average at every channel in a different color (without performing any data checking):
% eegplugin_erp() - plot ERP plugin
function eegplugin_erp( fig, try_strings, catch_strings);
% create menu
plotmenu = findobj(fig, 'tag', 'plot');
uimenu( plotmenu, 'label', 'ERP plugin', ...
'callback', 'figure; plot(EEG.times, mean(EEG.data,3));');
Save the text above as a file, 'eegplugin_erp.m'
into the plugin sub-directory of EEGLAB (or the EEGLAB directory where eeglab.m is located) and restart EEGLAB
(click here
to download this .m file).
Then select the menu item
Plot > ERP plugin
to plot the ERP of an epoched dataset.
Another, more complete example: To create a plugin named 'PCA' that would apply PCA to your data
and store the PCA weights in place of the ICA weights,
save the Matlab commands below as file 'eegplugin_pca.m'
into the plugin sub-directory of EEGLAB (or the EEGLAB directory where eeglab.m is located) and restart EEGLAB
(click here
to download this .m file).
% eegplugin_pca() - pca plugin
function eegplugin_pca( fig, try_strings, catch_strings);
% create menu
toolsmenu = findobj(fig, 'tag', 'tools');
submenu = uimenu( toolsmenu, 'label', 'PCA plugin');
% build command for menu callback
cmd = [ '[tmp1 EEG.icawinv] = runpca(EEG.data(:,:));' ];
cmd = [ cmd 'EEG.icaweights = pinv(EEG.icawinv);' ];
cmd = [ cmd 'EEG.icasphere = eye(EEG.nbchan);' ];
cmd = [ cmd 'clear tmp1;' ];
finalcmd = [ try_strings.no_check cmd ];
finalcmd = [ finalcmd 'LASTCOM = ''' cmd ''';' ];
finalcmd = [ finalcmd catch_strings.store_and_hist ];
% add new submenu
uimenu( submenu, 'label', 'Run PCA', 'callback', finalcmd);
Note that as of EEGLAB v4.3 you may add plugin menu items
to different EEGLAB menus. Above,
we add a sub-menu to the Tools
menu by specifying "'tag','tools'" in the findobj() call.
If the specified tag were "import data",
EEGLAB would add the plugin to the
File > Import data menu.
Using the tag "import epoch" would add the plugin to the
File > Import epoch info menu.
The tag "import event" would add the plugin to
the File > Import event info
menu.
The tag "export" would add the plugin to the File > Export data menu.
Finally,
the tag "plot" would add the plugin to the Plot menu. (Note that the tag call
should be in lower case).
After installing the plugin above, a new EEGLAB menu item
Tools > PCA plugin will be created.
Use this menu item to run PCA on the current EEG dataset.
The resulting PCA decomposition will be stored in place of the
ICA decomposition.
(Note: This is possible since both PCA and ICA are linear decompositions).
See the EEGLAB DIPFIT plugin eegplugin_dipfit() for an example of a more elaborate plugin.
Note: In EEGLAB4.3
we slightly modified how EEGLAB handles plugins.
As a result, EEGLAB might not be compatible
with earlier plugin functions.
Subsequent versions of EEGLAB have and will support backwards compatibility
of the plugin conventions.