MATLAB: To find the FWHM and area of pulses in a signal waveform

datadata importexcelMATLAB

A = xlsread('z_data.xlsx');
z1 = A(:,1);
z2 = A(:,2);
%% finding beginning of pulse and peak
z11 = z1;
z21 = smooth(z2,10);
z3 = diff(z2);
z4 = diff(z1);
z5 = (diff(z21)./diff(z11)) > 0;
z6 = diff(z5);
z7 = logical(diff(z5));
z8 = diff(z5) < 0 ;
z9 = logical(diff(z8));
%% plots
figure
subplot(6,1,1);
plot(z11,z21);
hold on
plot(z11(z7),z21(z7),'.g','markersize',20);
hold off
subplot(6,1,2);
plot(z5);
subplot(6,1,3);
plot(z6);
subplot(6,1,4);
plot(z7);
subplot(6,1,5);
plot(z8);
subplot(6,1,6);
plot(z9);
I have made use the derivative and logical operations one after the other and hence found out the start point and peak of the pulse.
There after not able to find half maximums of each pulse, and the point where the pulses end.
Also i do not have a formula through which the area of such varing waveform could be found out.

Best Answer

Try this:
M = readmatrix('z_data.xlsx');
t = M(:,1);
A = M(:,2);
As = smoothdata(A, 'movmean',15); % Remove Noise
zci = @(v) find(v(:).*circshift(v(:), 1, 1) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector (>= R2016b)
dAdt = gradient(As)./gradient(t); % Time Derivative
zx = zci(dAdt); % Zero-Crossing Indices
[pks,locs,fwhm,prmns] = findpeaks(A, 'MinPeakDistance',50); % Return Full-Width-Half-Maximum Of Peaks
zx = [1; zx]; % Modify ‘zx’ To Include First Index
Idx = zx(1:2:end); % Beginnings Of Each Peak
TotArea = cumtrapz(t,A); % Integral
PkAreas = diff(TotArea(Idx)); % Peak Areas
PkLocs = locs(1:end-1); % Eliminate Last (Incomplete) Peak
PkTime = t(PkLocs);
Results = table(t(PkLocs), fwhm(1:end-1), PkAreas, 'VariableNames',{'PeakTime', 'FWHM', 'Area'});
Note: This code is reasonably robust, although fragile in that it may need to be modified slightly for different data sets. If there are incomplete peaks (that do not end in zero-crossings), or it begins with a complete peak (so that the initial index appears twice), those will need to be considered and corrected for in the calculation of the indices (‘zx’ and ‘locs’). It works as written for the data presented.
If you want to see graphically what the code does, plot this example:
figure % Information Plot (Not Needed In Code)
plot(t, A)
hold on
plot(t, dAdt, '-r')
plot(t(zx), dAdt(zx), '+g')
plot(t(locs), pks, '^r')
hold off
grid
legend('Data', 'Detivative', 'Zero-Crossings', 'Peaks', 'Location','N')
xlim([ 0 750])
ylim([-5 30])