% ICADEMO - a sample ICA analysis script using the ICA/ERP package 
%             of Matlab functions distributed via
%             http://www.sccn.ucsd.edu/eeglab
%
% Notes:
%   Reads ascii ERP data file:            pnas.adt
%   Reads example ascii ERP data files:   chan.nam   chan14.locs (=chan_locs)
%
% Author: Scott Makeig, SCCN/INC/UCSD, La Jolla, 5-18-97 
%
% See also: RUNICA, ICAVAR, ICAPROJ, ICAACT

% Copyright (C) 5-18-97 Scott Makeig, SCCN/INC/UCSD, scott@sccn.ucsd.edu
%
% This file is part of EEGLAB, see http://www.eeglab.org
% for the documentation and details.
%
% Redistribution and use in source and binary forms, with or without
% modification, are permitted provided that the following conditions are met:
%
% 1. Redistributions of source code must retain the above copyright notice,
% this list of conditions and the following disclaimer.
%
% 2. Redistributions in binary form must reproduce the above copyright notice,
% this list of conditions and the following disclaimer in the documentation
% and/or other materials provided with the distribution.
%
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
% THE POSSIBILITY OF SUCH DAMAGE.

% This version tested on package version
% Added ENVPROJ, used maxmap in COMPPLOT 6-18-97 -sm
% Reworked to use actual sample ERP data 6-27-97 -sm
% Pruned again 7/18/97 -sm
% Adjusted envproj, plotproj, icaproj to remove datamean, distributing 
%     mean offset (if any) among component projections 7/23/97 -sm
% Fixed PLOTPROJ call - it can't label arbitrry channel lists -sm 
% Adjusted envproj etc. 12/08/97 -sm
% Added TIMTOPO 1-16-98 -sm
% Added more formatting, fixed compplot and eegmovie plotting 10-9-99 -sm
% 12-19-00 revised icaproj args -sm
% 01-05-01 advertised the web tutorial, fixed CHANPROJ, improved EEGMOVIE -sm
% 01-12-01 removed 'sphere' arg from PLOTPROJ, ICAACT -sm
% 01-25-02 reformated help & license, added links -ad 

   chans  = 14;  % data channels (rows in data matrix)
   frames = 312; % frames per data epoch (columns in data submatrix)
   epochs = 2;   % epochs in simulated data
   srate  = 312.5; % data sampling rate in Hz
   limits = [0 995 0 0]; % epoch time limits in msec, y limits unspecified
   off    = [25 -25 0 0];   % successive figure offset in pixels
   icadefs  % run icadefs to see whether the user has changed the XXX reference.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Begin
%
fprintf('\n *************************************************************\n');
  fprintf(' * Demonstration script showing several ICA package analysis *\n')
  fprintf(' * and plotting routines applied to sample lowpass ERP data  *\n');
  fprintf(' *                                                           *\n');
  fprintf(' * Note: Use of these and other toolbox functions is now     *\n');
  fprintf(' *           documented in an online tutorial at:            *\n');
  fprintf(' *         http://www.cnl.salk.edu/~scott/tutorial/          *\n');
fprintf(' *************************************************************\n\n');

v=version;
if v(1) < '5'
  fprintf('Not all segments may work for Matlab version 4.\n')
end

% add path to access 
if ~exist('pnas.flt')
    p = which('eeglab');
    p = p(1:findstr(p,'eeglab.m')-1);
    addpath([ p 'sample_data' ] );
end

% name of channel locations file
chan_locs  = 'pnas_chan14.locs';
chan_locs2 = 'pnas_chan.locs';


figure
set(gcf,'Color',BACKCOLOR);
plot([-4 -4 4 4 -4],[-4.5 3 3 -4.5 -4.5],'w','Linewidth',3);hold on;
axis([-4 4 -5 5]);
t=text(0,2,'icademo()');
set(t,'FontSize',14,'HorizontalAlignment','center');
t=text(0,1,' Demonstration script showing several ICA toolbox ');
set(t,'FontSize',14,'HorizontalAlignment','center');
t=text(0,0,'analysis and plotting routines'); 
set(t,'FontSize',14,'HorizontalAlignment','center');
t=text(0,-1,'applied to sample lowpass ERP data');
set(t,'FontSize',14,'HorizontalAlignment','center');
t=text(0,-2.5,'See http://www.cnl.salk.edu/~scott/tutorial/');
set(t,'FontSize',14,'HorizontalAlignment','center');
t=text(0,-3.5,'for more details.');
set(t,'FontSize',14,'HorizontalAlignment','center');
axis('off')

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Load an ascii ERP data matrix 
%
fprintf('Loading sample data...\n');
   load('pnas.adt','-ascii');
fprintf('Reshaping sample data...\n');
   data = [pnas(15:28,:) pnas(1:14,:)]; % lapses (will plot red), hits (blue)
   clear pnas
% Scale to uV
data = data/24.2;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Lowpass filter (if available)
%
lowpass = 30; % filter band lowpass freq in Hz
if exist('firls')  % if signal processing toolbox is installed . . .
  fprintf('Lowpass filtering the data using eegfilt()...\n');
  % data = eegfilt(data,srate,lowpassHz,highpassHz,frames); 
   [data,filtwts] = eegfilt(data,srate,0,lowpass,frames); 
                                        % lowpass filter below 30 Hz
else                                    % filter each epoch similarly
  fprintf('Script eegfilt() requires the Matlab signal processing toolbox.\n');
end
pos = get(gcf,'Position'); % record figure position to use as a base for later figures

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Overplot the 2 312-point data epochs at each channel using plotdata.m
% Assume that the epoch timebase is 0 to 995 msec.
% Read 4-character channel identifiers from the file 'chan.nam'
% Use the default color order.
%
fprintf('\nOverplotting the two sample auditory ERP target responses\n')
fprintf('        of %d chans by %d frames using plotdata()...\n\n', ...
                               size(data,1),size(data,2));
figure('Position',pos+off/2); % #2a

plotdata(data,frames,[0 995 -10 10],'ERP Data', chan_locs2 ,0,'(2 conditions)');

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
fprintf('\nOverplotting the two sample auditory ERP target responses\n')
fprintf('        of %d chans by %d frames using plottopo()...\n\n', ...
                               size(data,1),size(data,2));
%
figure('Position',pos+off); % #2b

% plotttopo(data,chan_locs,frames,limits,title,axsize,colors) 

plottopo(data,chan_locs,frames,[0 995 -10 10],'ERP Data');

if ~exist('icademoauto')  
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% run timtopo.m
%
fprintf('\nPlotting the Hit responses with topo maps at specified times ...\n')
figure('Position',pos+off*3/2); % #2c

% timtopo(data,chan_locs,[limits],[plottimes]','title',[plotchans],[voffsets]);

timtopo(data(:,1:frames),chan_locs,[0 995 -10 10],[250 320 390 500],'Target Hits');

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% run eegplot.m
%
fprintf(...
'Plotting the same data as two consecutive 1-sec epochs using eegplot().\n');
fprintf('Try using the on-screen and menu control elements...\n')

%  >> eegplot(data,srate,spacing,eloc_file,windowlength,title)

     %eegplotold(data,srate,0,chan_locs,1,'Two data epochs using eegplot()')
     eegplot(data,'srate',srate, 'spacing', 0,'eloc_file',readlocs(chan_locs), ...
				'winlength',1,'title','Two data epochs using eegplot()')
     %set(gcf,'Position',pos+2*off); % #3 - eegplot() makes its own figure

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
fprintf(...
'Plotting the same data as two consecutive 1-sec epochs using eegplotold()...\n');
fprintf('Thus, eegplotold() can be used to embed plots in larger figures.\n')
%
% >> eegplot('noui',data,srate,spacing,eloc_file,startsec,color)
%
figure('Position',pos+2.5*off); 
subplot(1,2,1)
  %eegplot('noui',data(:,1:312),'srate',srate,'spacing', 0,'eloc_file', chan_locs, 'color', {{'b'}} );
  eegplotold('noui',data(:,1:312),srate,0,chan_locs,0,'b');
  title('Lapses')
subplot(1,2,2)
  %eegplot('noui',data(:,1:313:624),'srate',srate,'spacing', 0,'eloc_file', chan_locs, 'color', {{'b'}} );
  eegplotold('noui',data(:,313:624),srate,0,chan_locs,0,'r');
  title('Hits')

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% run the ICA decomposition using runica.m
%
% Decompose the data using the ICA algorithm
% Specify the baseline vector to be sure that the baselines are zeroed.
%         data       = input data (size(data) = [chans,frames*epochs])
%         frames     = number of data points in each data epoch 
%         basevector = data point vector to use in zeroing baseline 
%
fprintf('Now decompose both epochs at once using the ICA algorithm, runica() ...\n\n');

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end

[weights,sphere,activations,bias,signs,lrates] = runica(data);

fprintf('\nDone!\n');

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Compute the activation waveforms for the resulting ICA components using icaact.m
%
  datamean = mean(data')';
  activations = icaact(data,weights*sphere,datamean);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Reorder the first 10 components by increasing in-epoch latency to the
% point of maximum variance accounted for. Do not take into account 
% channel 14 in the variance calculation; only use channels 1:13.
%
fprintf('Re-sorting the resulting components by LATENCY ')
fprintf('          using compsort() ...\n\n');
fprintf('Note: runica() orders components by size - comport() not commonly needed!!\n')

% [windex,maxvar,maxframe,maxepoch,maxmap] ...
%                = compsort(data,weights,sphere,datamean, ...
%                                         frames,nlargest,chanlist);

  [windex,maxvar,maxframe,maxepoch,maxmap] = ...
                   compsort(data,weights,sphere,1,...
                                          frames,10,[1:13]);

fprintf('\nDone!\n');

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Plot the activation waveforms of all the components 
%        as reordered by COMPSORT
% Identify the components using the original component numbers.
%
fprintf('Plotting the component activation waveforms using plotdata()')
fprintf('using plotdata() ....\n\n');
figure('Position',pos+3*off); 

  plotdata(activations(windex,:),frames,limits,...
                 'ICA Component Activations', ...
                          windex,0,'(2 conditions)');

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Plot the contributions to the first epoch of data by the first reordered 
% 10 ICA components. Superimpose their projections on the original data.
%
fprintf('Plotting contributions of the 1st 10 ICA components ');
fprintf('using plotproj()...\n\n');
figure('Position',pos+4*off); 

%   [projdata] = plotproj(data,weights,compnums, ...
%                            title,limits,chanlist,channames,colors);
 [projdata] = plotproj(data(:,1:frames),weights*sphere,windex(1:10), ...
               'First epoch (comps. 1-10)',limits,[1:10], chan_locs2 );

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Plot the contributions to the first epoch of data by the 5 largest
% ICA components. Superimpose their projections on the original data.
%
fprintf('Plotting contributions of the 5 largest ICA components ');
fprintf('(windex order) using projtopo()...\n\n');
figure('Position',pos+4*off); 

%       >> [projdata] = projtopo(data,weights,[compnums],chan_locs,...
%                                 'title',[limits],colors,chans);

 [projdata] = projtopo(data(:,1:frames),weights*sphere,1:5,chan_locs,...
               'First epoch',limits);

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Plot the envelopes of the data epoch 1 and the first 10 components
%
fprintf('Plotting the [min,max] "envelopes" of the data ');
fprintf('and largest 6 components using envproj().\n(Data envelope is in white).\n\n');
figure('Position',pos+5*off); 

% >> [envdata] = envproj(data,weights,compnums, ...
%                        title,limits,chanlist,compnames,colors);
  [envdata] = envproj(data(:,1:floor(0.6*frames)),weights*sphere,1:6, ...
                  'Envelopes of data and largest 6 components (cond. 1)',...
                     [0 995*0.6 0 0]);

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
fprintf('Now plotting envelopes PLUS scalp maps using envtopo().\n');
figure('Position',pos+5.5*off); 
%
%  >> envtopo(data,weights,chan_locs,[limits],[compnums],...
%                                   'title',[plotchans],[voffsets]);

  envtopo(data(:,1:floor(0.6*frames)),weights*sphere,'chanlocs',readlocs(chan_locs),...
         'limits', [0 995*0.6],'compnums',[2 3 4 6],'title', 'Largest Components');

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Plot a close-up of the decomposition of epoch 2, channel 2.
% Focus on the time interval 250 to 400 msec.
%
  startframe = fix(0.250*srate)+1; % start 250 msec after epoch start
  endframe   = fix(0.400*srate);   % end 400 msec after epoch start

fprintf('Plotting contributions of the 1st 5 ICA components ');
fprintf('at Cz using chanproj().\nData is in white.\n\n');
figure('Position',pos+6*off); 

% [chandata] = chanproj(projdata,chan,ncomps,framelist,limits,titl,clrs);

  [chandata] = chanproj(projdata,1,5,startframe:endframe,...
                                 [0 995 0 0],'Epoch 1, channel Fz',0);
fprintf('\n Note that two components make up most of the response peak.\n');

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Plot the scalp maps of the first four reordered components 
% Read the electrode location file chan_locs
%
fprintf('Plotting 1st 4 ICA component scalp maps using compmap()...\n');
figure('Position',pos+7*off); 

% compmap (winv,eloc_file,index,title,pagesize,labels,printflag)
  compmap(maxmap,chan_locs,1:4,'Maps of 1st 4 ICA Components',...
                                                   [2 2],windex(1:4));

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Display the projected epoch-1 data for reordered ICA component windex(7) 
% together with a scalp map at its point of max variance
%
fprintf('Plotting the scalp maps and 1st-epoch projection of\n');
fprintf('   the button press component using compplot()...\n\n');
figure('Position',pos+8*off); 

% compplot(data,plotframe,chan_file,xstart,srate,title);

  frame = maxframe(7);
  projp3 = icaproj(data(:,frames+1:2*frames),weights*sphere,windex(7));

  compplot(projp3,frame,chan_locs,0,srate,'ICA Button Press Component');

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Make and display a brief movie of a small segment of the first data epoch
%
fprintf('Making a brief movie of an N200 portion of the 1st data epoch\n')
fprintf('            using eegmovie() & seemovie()...\n\n');
figure('Position',pos+9*off); 

% [Movie,Colormap] = eegmovie(data,srate,elec_locs,title,movieframes,minmax);

try,
  [Movie,Colormap] = eegmovie(data(:,313:412),srate,chan_locs,...
                                              'Demo of eegmovie()',75:85,0);
% Display the movie slowly, then 5 times forward/back
%
  seemovie(Movie,-5,Colormap); 
catch,
    disp('Problem generating movie');
end

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Run testica script using optimum parameters 
%    (nsources = ncomponents to separate)
% Sources are super-Gaussian 
%
fprintf('Last, running testica() - a simulation script for estimating the accuracy\n')
fprintf('         of ICA separation for a given data size and source distribution ...\n\n');

fprintf('Perfect separation would produce an identity matrix.\n');
fprintf('This is not possible here, since 14 sources are mixed into only 6 channels.\n');
fprintf('The figure will show that the 6 largest sources are still recovered clearly ...\n');

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%
    testica(chans,epochs*frames,14,-0.05,1.4);
else 
    [testresult] = testica(chans,epochs*frames,14,-0.05,1.4);
end

% model 14 sources with a wide range of sizes & positive kurtosis

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

set(gcf,'Position',pos+10*off); 

if ~exist('icademoauto')
    fprintf('\n****> Hit any key to continue: '); pause; fprintf('\n\n'); %%%    
end; 
fprintf('\n *************************************************************\n');
fprintf(' *               For a tutorial on the toolbox:                *\n');
fprintf(' *                                                             *\n');
fprintf(' *          http://www.cnl.salk.edu/~scott/tutorial/           *\n');
fprintf(' *                                                             *\n');
fprintf(' *      For an overview of available scripts  >> help ica      *\n');
fprintf(' *      For information about using ICA, see  icafaq.html      *\n');
fprintf(' *      For further details and examples, see icabib.html      *\n');
fprintf(' *************************************************************\n\n')

return
