Home > bioelectromagnetism > eeg_peaks.m

eeg_peaks

PURPOSE ^

eeg_peaks - Find peaks in EEG data

SYNOPSIS ^

function [p] = eeg_peaks(p)

DESCRIPTION ^

 eeg_peaks - Find peaks in EEG data

 Usage: [p] = eeg_peaks(p)

 The p structure is explained in eeg_toolbox_defaults.
 For this function, it must contain the field called
 'volt.data,' which is assumed to be a matrix 
 with N rows of EEG sample values from M columns 
 of electrodes.
 
 The indices to peak values are returned to
 p.volt.peaks.data (which is size(p.volt.data)).
 The values are:
                    0   no peak
                    1   a +ve peak
                   -1   a -ve peak

 This function finds all peaks in a waveform, where
 f(x) changes from an increasing to a decreasing 
 function and vice versa). These are local minima
 and maxima that have a first derivate of zero and
 satisfy the first derivative test.
 
 Thus, the +ve/-ve peak refers to peaks and troughs 
 in a waveform, regardless of the +ve/-ve value of 
 the waveform at that point. The peak values are 
 commonly +ve/-ve potentials, but they may not be.
 A +ve peak can have a -ve value where the change 
 from increasing f(x) to decreasing f(x) occurs 
 entirely in the range of negative values.
 
 All the +ve/-ve peak values are returned in:

   p.volt.peaks.all
   p.volt.peaks.pos
   p.volt.peaks.neg

 If the p.volt.timeArray is defined, then the timing
 of the peaks is returned in:

   p.volt.peaks.alltimes
   p.volt.peaks.postimes
   p.volt.peaks.negtimes

 eg,   p.volt.timeArray = linspace(-20,20,200)';
       p.volt.data = sin(linspace(-20,20,200))';
       p.volt.data(:,2) = sin(-1 .* linspace(-20,20,200))';
      [p] = eeg_peaks(p);
       scatter(p.volt.timeArray(p.volt.peaks.all),p.volt.data(p.volt.peaks.all))
       hold on
       plot(p.volt.timeArray,p.volt.data)

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function [p] = eeg_peaks(p)
0002 
0003 % eeg_peaks - Find peaks in EEG data
0004 %
0005 % Usage: [p] = eeg_peaks(p)
0006 %
0007 % The p structure is explained in eeg_toolbox_defaults.
0008 % For this function, it must contain the field called
0009 % 'volt.data,' which is assumed to be a matrix
0010 % with N rows of EEG sample values from M columns
0011 % of electrodes.
0012 %
0013 % The indices to peak values are returned to
0014 % p.volt.peaks.data (which is size(p.volt.data)).
0015 % The values are:
0016 %                    0   no peak
0017 %                    1   a +ve peak
0018 %                   -1   a -ve peak
0019 %
0020 % This function finds all peaks in a waveform, where
0021 % f(x) changes from an increasing to a decreasing
0022 % function and vice versa). These are local minima
0023 % and maxima that have a first derivate of zero and
0024 % satisfy the first derivative test.
0025 %
0026 % Thus, the +ve/-ve peak refers to peaks and troughs
0027 % in a waveform, regardless of the +ve/-ve value of
0028 % the waveform at that point. The peak values are
0029 % commonly +ve/-ve potentials, but they may not be.
0030 % A +ve peak can have a -ve value where the change
0031 % from increasing f(x) to decreasing f(x) occurs
0032 % entirely in the range of negative values.
0033 %
0034 % All the +ve/-ve peak values are returned in:
0035 %
0036 %   p.volt.peaks.all
0037 %   p.volt.peaks.pos
0038 %   p.volt.peaks.neg
0039 %
0040 % If the p.volt.timeArray is defined, then the timing
0041 % of the peaks is returned in:
0042 %
0043 %   p.volt.peaks.alltimes
0044 %   p.volt.peaks.postimes
0045 %   p.volt.peaks.negtimes
0046 %
0047 % eg,   p.volt.timeArray = linspace(-20,20,200)';
0048 %       p.volt.data = sin(linspace(-20,20,200))';
0049 %       p.volt.data(:,2) = sin(-1 .* linspace(-20,20,200))';
0050 %      [p] = eeg_peaks(p);
0051 %       scatter(p.volt.timeArray(p.volt.peaks.all),p.volt.data(p.volt.peaks.all))
0052 %       hold on
0053 %       plot(p.volt.timeArray,p.volt.data)
0054 %
0055 
0056 % $Revision: 1.1 $ $Date: 2004/11/12 01:32:33 $
0057 
0058 % Licence:  www.gnu.org GPL, no implied or express warranties
0059 % Created:  02/2002, Darren.Weber_at_radiology.ucsf.edu
0060 %                    - adapted a perl foreach loop to peaks_matrix
0061 %                      to take advantage of matlab speed.
0062 %           05/2002, Darren.Weber_at_radiology.ucsf.edu
0063 %                    - used matlab 'diff' command
0064 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0065 
0066 fprintf('EEG_PEAKS\n...calculating peaks...'); tic;
0067 
0068 p.volt.peaks.data = peaks_matrix(p.volt.data);
0069 
0070 % Find all the peak values
0071 p.volt.peaks.all = p.volt.data .* (p.volt.peaks.data ~= 0);
0072 p.volt.peaks.pos = p.volt.data .* (p.volt.peaks.data  > 0);
0073 p.volt.peaks.neg = p.volt.data .* (p.volt.peaks.data  < 0);
0074 
0075 if ~isfield(p.volt,'timeArray'),
0076     fprintf('\n...p doesn''t contain ''volt.timeArray''.\n');
0077     return
0078 elseif isempty(p.volt.timeArray),
0079     fprintf('\n...p.volt.timeArray is empty.\n');
0080     return
0081 end
0082 
0083 % make sure that volt.timeArray is same size as volt.data
0084 if ~isequal(size(p.volt.timeArray),size(p.volt.data)),
0085     p.volt.timeArray = repmat(p.volt.timeArray(:,1),1,size(p.volt.data,2));
0086 end
0087 % Find the peak timing
0088 p.volt.peaks.alltimes = p.volt.timeArray .* (p.volt.peaks.data ~= 0);
0089 p.volt.peaks.postimes = p.volt.timeArray .* (p.volt.peaks.data  > 0);
0090 p.volt.peaks.negtimes = p.volt.timeArray .* (p.volt.peaks.data  < 0);
0091 
0092 t = toc;
0093 fprintf('done (%5.2f sec)\n',t);
0094 return
0095 
0096 
0097 
0098 function [peaks] = peaks_matrix(data)
0099     
0100     % This function should be quicker than that below.
0101     % The code below remains as it has been proved to
0102     % be reliable, but this code effectively replaces it.
0103     % Both code sets produce the same results.
0104     
0105     [r,c] = size(data);
0106     % replicate data, but staggered one point
0107     data2 = zeros(1,c);
0108     data2(2:r+1,:) = data;
0109     % add zero values to end of data points
0110     data(r+1,:) = zeros(1,c);
0111     % generate boolean difference between two matrices
0112     dif = data < data2;
0113     
0114     % Now replicate this boolean matrix
0115     [br,bc] = size(dif);
0116     dif2 = zeros(1,bc);
0117     dif2(2:br+1,:) = dif;
0118     % add zeros to end of boolean dif
0119     dif(br+1,:) = 0;
0120     
0121     % Calculate the peaks
0122     peaks = dif(2:r+1,:) - dif2(2:r+1,:);
0123     
0124     % now trim peaks dif back to size of data
0125     peaks(1,:) = 0; % first point cannot be a peak
0126     peaks(r,:) = 0; % last point cannot be a peak
0127     
0128     
0129     
0130     % Could use matlab diff command, like this
0131     %[r,c] = size(data);
0132     %decdat = (diff(data)<=0) .* -1;
0133     %incdat =  diff(data)>=0;
0134     
0135     %zrow = zeros(1,c);
0136     %dirdat1 = [ zrow; decdat + incdat ];
0137     %dirdat2 = [ decdat + incdat; zrow ];
0138     
0139     %negpeaks = ((dirdat1 - dirdat2) < 0) .* -1;
0140     %pospeaks =  (dirdat1 - dirdat2) > 0;
0141     %peaks = negpeaks + pospeaks;
0142     
0143     %peaks(1,:)   = 0; % first point cannot be a peak
0144     %peaks(end,:) = 0; % last point cannot be a peak
0145     
0146     
0147 return
0148 
0149 
0150 % The function 'peaks_matrix' above replaced the
0151 % following for loop (02/2002, Darren Weber)
0152 
0153 % foreach electrode
0154 %for e = 1:size(p.volt.data,2),
0155 %    v = p.volt.data(:,e);
0156 %    n = 1;
0157 %    volt = v(n);
0158 %    while (n <= size(v,1)),
0159 %        if(volt < v(n)),
0160 %            volt = v(n); n = n + 1;
0161 %            if(volt < v(n)), p.volt.peaks.data(n-1,e) = 0;
0162 %            else             p.volt.peaks.data(n-1,e) = 1;
0163 %            end
0164 %        elseif(volt > v(n)),
0165 %            volt = v(n); n = n + 1;
0166 %            if(volt > v(n)), p.volt.peaks.data(n-1,e) = 0;
0167 %            else             p.volt.peaks.data(n-1,e) = -1;
0168 %            end
0169 %        else
0170 %            volt = v(n); n = n + 1;
0171 %           p.volt.peaks.data(n-1,e) = 0;
0172 %        end
0173 %        if isequal(n,size(v,1)),
0174 %            break;
0175 %        end
0176 %    end
0177 %    p.volt.peaks.data(1,e) = 0; % first point cannot be a peak
0178 %    p.volt.peaks.data(n,e) = 0; % last point cannot be a peak
0179 %end
0180 %p.volt.peaks.all = find(p.volt.peaks.data ~= 0);
0181 %p.volt.peaks.pos = find(p.volt.peaks.data  > 0);
0182 %p.volt.peaks.neg = find(p.volt.peaks.data  < 0);
0183 %return

Generated on Mon 15-Aug-2005 15:36:19 by m2html © 2003