0001 function [peakHeights,baseIdxs] = peak_heights(varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
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
0042
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