Finding max peaks and full width/half max for both curves in the given plot

Trying to find the peak values and full width/half max from the generated gaussian fit. I tried using findpeak (signal processing toolbox) but the documentation is not very clear on how I could use that in this instance.

 Accepted Answer

It would help to have the data.
Calculating the statistics of the peaks depends on how the peaks are defined. This defines them with respect to their individual baselines, so without smoothing the data or detrending the baselines, it returns reasonable results —
Fs = 1000;
tlen = 10;
x = linspace(0, tlen*Fs, tlen*Fs+1).'/Fs; % Assume Column Vectors
data = sin(2*pi*x*0.5) + cos(2*pi*x*0.1) + randn(size(x))*0.025;
figure
plot(x, data)
grid
title('Original')
[pks,plocs] = findpeaks(data, 'MinPeakProminence',0.5);
[vys,vlocs] = findpeaks(-data, 'MinPeakProminence',0.5);
vlocs = [1; vlocs; numel(x)];
vys = data(vlocs);
for k = 1:numel(pks)
[~,idx] = mink(abs(plocs(k)-vlocs),2); % Indices Of Two Nearest Valleys To Peak
idxv(:,k) = sort(vlocs(idx)); % Sort Them
idxrng = idxv(1,k) : idxv(2,k); % Index Range
midpt(k) = x(plocs(k)); % 'x' Value For Peak
ymp(k) = [midpt(k), 1] * ([x(idxv(:,k)) ones(2,1)] \ data(idxv(:,k))); % 'y' Value Of Interpolated Baseline For This Peak
pkamp(k) = pks(k) - ymp(k); % Peak Value With Respect To Baseline
idxr1 = idxv(1,k) : plocs(k);
hw(1,k) = interp1(data(idxr1), x(idxr1), median(data(idxr1))); % 'Rising' Half-Width X-Value
idxr2 = plocs(k) : idxv(2,k);
hw(2,k) = interp1(data(idxr2), x(idxr2), median(data(idxr2))); % 'Falling' Half-Width X-Value
hwv(:,k) = [median(data(idxr1)); median(data(idxr2))]; % Half-Width Y-Values
end
PeakStats = table(x(plocs), diff(hw).', diff(x(idxv)).', pkamp.', 'VariableNames',{'Peak','FWHM','Base Width','Peak Height'})
PeakStats = 5×4 table
Peak FWHM Base Width Peak Height _____ ______ __________ ___________ 0.512 0.825 1.637 1.4992 2.448 0.9635 1.935 2.0757 4.493 0.9225 1.859 1.9508 6.525 1.009 2.011 2.0009 8.532 0.992 1.989 2.1915
figure
hp{1} = plot(x, data, 'DisplayName','Data');
hold on
for k = 1:numel(pkamp)
hp{2} = plot(x(idxv(:,k)), data(idxv(:,k)), '--k', 'DisplayName','Baselines');
hp{3} = plot([1 1]*midpt(k), [ymp(k) pks(k)], '-r', 'DisplayName','Peak Amplitudes Above Inter-Peak Baseline');
hp{4} = plot(hw(:,k), hwv(:,k), ':k', 'DisplayName','Half-Width Lines');
end
hold off
grid
title('Original With Peak Heights Above Baselilne')
legend([hp{1} hp{2}(1) hp{3}(1) hp{4}(1)], 'Location','best')
text(midpt, ymp+pkamp/2, compose('\\leftarrow %.2f',pkamp))
Other ways of defining peak widths are to use zero as the peak baseline reference. Since I do mostly biomediical data processing, that does not work, and I define the peaks with respect to their individual baselilnes, as in this code. To use findpeaks to define the peak width values, define the appropriate vallue for WidthReference.
.

More Answers (1)

Does the curve fitter give you the equation of the curve? You should be able to figure it out. Just take each Gaussian and set the value equal to half the peak and compute the two 2 values.
(0.5 * a1) = a1 * exp(-((x - b1)/c1) ^2);
ln(0.5) = - ((x-b1)/c1) ^2
sqrt(-ln(0.5)) = (x-b1)/c1
(+/-)c1 * sqrt(-ln(0.5)) + b1 = x (both x1 for the -sqrt and x2 for the +sqrt)

3 Comments

Just to clarify, the coefficients are given in the original screenshot:
OK, since you accepted @Star Strider's answer it looks like you really wanted the FWHM from the empirical raw data rather than "the generated gaussian fit" as you said originally. Hence, I'm not going to do anything more. Glad it's working for you.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!