Try this:
M = readmatrix('z_data.xlsx');
t = M(:,1);
A = M(:,2);
As = smoothdata(A, 'movmean',15);
zci = @(v) find(v(:).*circshift(v(:), 1, 1) <= 0);
dAdt = gradient(As)./gradient(t);
zx = zci(dAdt);
[pks,locs,fwhm,prmns] = findpeaks(A, 'MinPeakDistance',50);
zx = [1; zx];
Idx = zx(1:2:end);
TotArea = cumtrapz(t,A);
PkAreas = diff(TotArea(Idx));
PkLocs = locs(1:end-1);
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
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])
Best Answer