Home > home > fbarrett > svn > jlmt > utils > peak_heights.m

peak_heights

PURPOSE ^

calculates peak heights given a signal, peak indices

SYNOPSIS ^

function [peakHeights,baseIdxs] = peak_heights(varargin)

DESCRIPTION ^

 calculates peak heights given a signal, peak indices
 
 INPUTS (param/value pairs)
                  signal: the input signal
                peakIdxs: indices of the peaks
                  params: parameter structure (see below)
                   xVals: x-axis values of the signal

 PARAMS:
   params.transformation: 'proportion','none'
                          'proportion' is the default
         params.calcFrom:  Which side to calculate the height from ('left','right',or 'higher')
                           'higher' (the default) indicates the higher of the two peaks

 Copyright (c) 2006-2012 The Regents of the University of California
 All Rights Reserved.

 ST - original code
 FB 2009.04.28 - added transformation switching

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 function [peakHeights,baseIdxs] = peak_heights(varargin)
0002 % calculates peak heights given a signal, peak indices
0003 %
0004 % INPUTS (param/value pairs)
0005 %                  signal: the input signal
0006 %                peakIdxs: indices of the peaks
0007 %                  params: parameter structure (see below)
0008 %                   xVals: x-axis values of the signal
0009 %
0010 % PARAMS:
0011 %   params.transformation: 'proportion','none'
0012 %                          'proportion' is the default
0013 %         params.calcFrom:  Which side to calculate the height from ('left','right',or 'higher')
0014 %                           'higher' (the default) indicates the higher of the two peaks
0015 %
0016 % Copyright (c) 2006-2012 The Regents of the University of California
0017 % All Rights Reserved.
0018 %
0019 % ST - original code
0020 % FB 2009.04.28 - added transformation switching
0021 
0022 peakHeights = [];
0023 baseIdxs = [];
0024 
0025 for iarg = 1:2:nargin
0026 
0027   switch varargin{iarg}
0028    case 'signal'
0029     sig = varargin{iarg+1};
0030    case 'peakIdxs'
0031     peakIdxs = varargin{iarg+1};
0032    case 'params'
0033     params = varargin{iarg+1};
0034    case 'xVals'
0035     xVals = varargin{iarg+1};
0036   end
0037 
0038 end
0039 
0040 try
0041     %params.calcFrom can be 'left', 'right', or 'higher'
0042     %default is 'higher'
0043     calcFrom = params.calcFrom;
0044 catch
0045     calcFrom = 'higher';
0046 end
0047 
0048 try
0049     trans = params.transformation;
0050 catch
0051     trans = 'proportion';
0052 end
0053 
0054 if isempty(strmatch(trans,{'proportion','none'}))
0055   error('unknown transformation: %s\n',trans);
0056 end
0057 
0058 if((size(sig,2) > 1) && size(sig,1) == 1)
0059   sig = sig';
0060 elseif((size(sig,1) > 1) && (size(sig,2) > 1))
0061   error('Must input a vector');
0062 end
0063 
0064 
0065 diffSig = [0 ; diff(sig)];
0066 
0067 nPeaks = length(peakIdxs);
0068 
0069 leftBorder = 1;
0070 for iPeak = 1:nPeaks
0071 
0072   if(iPeak == 1)
0073     leftBorder(iPeak) = 1;
0074   else
0075     leftBorder(iPeak) = rightBorder(iPeak-1);
0076   end
0077 
0078   if(iPeak ~= nPeaks)
0079     rightBorder(iPeak) = peakIdxs(iPeak+1);
0080   else
0081     rightBorder(iPeak) = length(sig);
0082   end
0083 
0084   idxsLeft  = [leftBorder(iPeak):peakIdxs(iPeak)];
0085   idxsRight = [peakIdxs(iPeak)+1:rightBorder(iPeak)];
0086   lChangeSign = find(diffSig(idxsLeft) < 0,1,'last');
0087   rChangeSign = find(diffSig(idxsRight) > 0,1,'first');
0088   
0089   if(isempty(lChangeSign))
0090     lChangeSign = 1;
0091   end
0092 
0093   if(isempty(rChangeSign))
0094     rChangeSign = length(idxsRight) + 1;
0095   end
0096   
0097   leftBorder(iPeak) = leftBorder(iPeak) + lChangeSign - 1;
0098   rightBorder(iPeak) = peakIdxs(iPeak) + rChangeSign - 1;
0099   
0100   
0101   switch (calcFrom)
0102       case 'left'
0103           base = sig(leftBorder(iPeak));
0104           baseIdx = leftBorder(iPeak);
0105       case 'right'
0106           base = sig(rightBorder(iPeak));
0107           baseIdx = rightBorder(iPeak);
0108       case 'higher'
0109   
0110           if((rightBorder(iPeak) == peakIdxs(iPeak)) && ~(leftBorder(iPeak) == peakIdxs(iPeak)))
0111             base = sig(leftBorder(iPeak));
0112             baseIdx = leftBorder(iPeak);
0113           elseif((leftBorder(iPeak) == peakIdxs(iPeak)) && ~(rightBorder(iPeak) == peakIdxs(iPeak)))
0114             base = sig(rightBorder(iPeak));
0115             baseIdx = rightBorder(iPeak);
0116           else
0117             base = max([sig(leftBorder(iPeak)) sig(rightBorder(iPeak))]);
0118             baseValues = [sig(leftBorder(iPeak)) sig(rightBorder(iPeak))];
0119             maxValueIdx = find(baseValues==max(baseValues));
0120             if maxValueIdx == 1
0121               baseIdx = leftBorder(iPeak);
0122             elseif maxValueIdx == 2
0123               baseIdx = rightBorder(iPeak);
0124             else
0125               baseIdx = leftBorder(iPeak);
0126               warning(...
0127                 'peak is symetrical, therefore two base indices exist, the first one has been chosen arbitarily')
0128             end
0129           end
0130   end
0131   switch trans
0132     case 'proportion'
0133       if((max(sig) - min(sig)) ~= 0)
0134         peakHeights(iPeak,1) = abs((sig(peakIdxs(iPeak)) - base)./(max(sig) - min(sig)));
0135       else
0136         peakHeights(iPeak,1) = 0;
0137       end
0138     case 'none'
0139       peakHeights(iPeak,1) = abs(sig(peakIdxs(iPeak)) - base);
0140     otherwise
0141       error('unknown transformation: %s\n',trans);        
0142   end
0143   baseIdxs(iPeak,1) = baseIdx;
0144   
0145 end
0146 
0147 return

Generated on Mon 18-Mar-2013 10:43:33 by m2html © 2003