Find the width of a peak

6 views (last 30 days)
Samridh Jain
Samridh Jain on 3 Jul 2022
Edited: Star Strider on 3 Jul 2022
I have a csv data of an impact collected. I would like to measure the duration/width of the main peak.
The deepest peak is the main, but then there may be other peaks prior and another peak beginning before reaching the base.
As I am dealing with multiple peaks, how do I measure the width of just the beginning of deepest peak to its end?
The first image below is the graph of the impact. Second image zooms into the second peak beginning before reaching zero and the width i would like to find. Also attaching the raw csv data for reference.
Thanks a lot!

Accepted Answer

Star Strider
Star Strider on 3 Jul 2022
Try something like this —
T1 = readtable('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1053640/j1%20a30.csv', 'VariableNamingRule','preserve')
T1 = 5953×9 table
__time /leptrino_force_torque/force_torque/header/seq /leptrino_force_torque/force_torque/header/stamp /leptrino_force_torque/force_torque/wrench/force/x /leptrino_force_torque/force_torque/wrench/force/y /leptrino_force_torque/force_torque/wrench/force/z /leptrino_force_torque/force_torque/wrench/torque/x /leptrino_force_torque/force_torque/wrench/torque/y /leptrino_force_torque/force_torque/wrench/torque/z __________ ______________________________________________ ________________________________________________ __________________________________________________ __________________________________________________ __________________________________________________ ___________________________________________________ ___________________________________________________ ___________________________________________________ 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.0294 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.0294 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.0294 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.0294 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.0294 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.0294 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.03 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.03 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.03 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.03 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.03 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.03 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.9 0.066 -0.03 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.925 0.066 -0.0294 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.925 0.066 -0.0294 0.102 1.6568e+09 1.9251e+06 1.6568e+09 0.475 3.7 2.925 0.066 -0.0294 0.102
VN = T1.Properties.VariableNames.';
t = T1{:,1};
f = T1{:,[4 5 6]};
x = t;
y = f(:,3);
[pks,plocs] = findpeaks(-y, 'MinPeakProminence',20); % Desired Peak & Index
[vys,vlocs] = findpeaks(y, 'MinPeakProminence',0.1); % Valleys & Indices
[vlc,ixv] = mink(abs(vlocs-plocs),2); % Choose Two Closest Valleys To Desired Peak
vlcs = plocs + [1; -1].*vlc; % Calculate Indices
idxr = vlcs(2) : vlcs(1); % Initial Index Range
figure
plot(x(idxr), y(idxr)) % Plot Desired Peak Region
hold on
plot(t(vlcs), y(vlcs), '^r')
hold off
grid
title('Isolated')
figure
plot(t, y)
hold on
plot(t(vlcs), y(vlcs), '^r')
hold off
grid
title('In Context')
xlim([-1 1]*1E-1 + t(plocs))
text(t(plocs), -5, sprintf('\\leftarrow %.6f \\rightarrow', diff(t(vlcs))), 'Horiz','center', 'Vert','middle', 'FontSize',8)
This uses code I recently wrote to define the valleys around a peak rather than the reverse, as required here. I changed it slightly for this problem.
.
  4 Comments
Star Strider
Star Strider on 3 Jul 2022
Edited: Star Strider on 3 Jul 2022
No worries!
The positive peak code would work similarly. See: How can I get the mean data from under the graphs?
This was the original approach that I wrote this code for. I adapted it for the negative version with your data. The area code is similar as well, although it would likely need to be adapted to work with your data, similar to what I did with the negative peak areas.
EDIT — (3 Jul 2022 at 17:58)
For a specific peak, the code would be something like this —
x = (920 : 980).'; % Create Data (Column)
y = sinc((x-mean(x))/5); % Create Data (Column)
figure
plot(x, y)
grid
[pks,plocs] = findpeaks(y, 'MinPeakProminence',1); % Desired Peak & Index
[vys,vlocs] = findpeaks(-y, 'MinPeakProminence',0.1); % Valleys & Indices
[vlc,ixv] = mink(abs(vlocs-plocs),2); % Choose Two Closest Valleys To Desired Peak
vlcs = plocs + [-1; 1].*vlc; % Calculate Indices
idxr = vlcs(1) : vlcs(2); % Initial Index Range
hold on
plot(x(idxr([1 end])), y(idxr([1 end])), 'vr')
hold off
figure
plot(x(idxr), y(idxr)) % Plot Desired Peak Region
hold on
plot(x(idxr([1 end])), y(idxr([1 end])), 'vr')
hold off
grid
The area calculation would be similar to the negative peak code.
.

Sign in to comment.

More Answers (1)

Jonas
Jonas on 3 Jul 2022
do you just want to measure the peak width of this data set only? if yes, i should be telatively easy locating the peak with min() and the locating start and end of it by using e.g. islocalmax() to find last peak before main peak and first peak after main peak

Community Treasure Hunt

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

Start Hunting!

Translated by