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

11 views (last 30 days)
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.

Accepted Answer

Star Strider
Star Strider on 13 Mar 2020
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])
  22 Comments
SHANTANU KSHIRSAGAR
SHANTANU KSHIRSAGAR on 28 May 2020
Thank it worked for the same data efficiently. I am Trying to work it out for number of signals, its a difficult thing but.

Sign in to comment.

More Answers (1)

SHANTANU KSHIRSAGAR
SHANTANU KSHIRSAGAR on 14 Mar 2020
Thanks Star Strider for quick and such an explainatory answer. It also cleared some new concepts to me other than the proposed problem in matlab.

Products


Release

R2019b

Community Treasure Hunt

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

Start Hunting!