How to identify both sides of a flat peak (flat part of a signal)?

Hi all,
I have the following signal (also attached).
I am trying to find the peaks circles red. The below code does identify all the peaks circled black but i do not understand why it ommits the other side of a flat signal? Can you help please?
load 'signal'
[peak_value,peak_location]= findpeaks(-force_y_r, 'MinPeakProminence',10, 'MinPeakDistance',100);
peak_value = -peak_value;
plot(force_y_r, 'LineWidth',1.5); hold on
plot(peak_location,peak_value,'ko')

 Accepted Answer

Use the islocalmin (introduced in R2017b) function instead of findpeaks
LD = load('signal.mat');
force_y_r = LD.force_y_r;
Lv1 = islocalmin(force_y_r, 'FlatSelection','first', 'MinSeparation',500, 'MinProminence',750);
Lv2 = islocalmin(force_y_r, 'FlatSelection','last', 'MinSeparation',500, 'MinProminence',750);
x = 1:numel(force_y_r);
figure
plot(x, force_y_r)
hold on
plot(x(Lv1), force_y_r(Lv1), '^r')
plot(x(Lv2), force_y_r(Lv2), '^g')
hold off
producing:
It may be necessary to change the name-value pair parameters for other data sets. Use the find function to get numeric indices from the logical vectors.
.

6 Comments

@Star Strider Many thnaks for your help
I am struggling to execute the find function to find the columns values of force_y_r using the Lv1 and Lv2. For example:
[row_Lv1,col_Lv1] = find(size(force_y_r),Lv1)
[row_Lv2,col_Lv2] = find(size(force_y_r),Lv2)
gives me:
Error using find
Second argument must be a positive scalar integer.
I do nt understand what I do wrong. Would you mind helping?
I hae just posted the problem in a separte post:
I will of course help!
This should work:
StartIndices = find(Lv1);
EndIndices = find(Lv2);
StartForce = force_y_r(StartIndices);
EndForce = force_y_r(EndIndices);
Result = table(StartIndices, EndIndices, StartForce, EndForce);
producing:
Result =
8×4 table
StartIndices EndIndices StartForce EndForce
____________ __________ __________ ________
1283 1649 0 0
2482 2883 0 0
3628 4029 0 0
4706 5097 0 0
5852 6230 0 0
6946 7324 0 0
8036 8432 0 0
9149 9518 0 0
In this instance, the ‘StartForce’ and ‘EndForce’ values will all be zero because the data are zero at those points. (I include them here in the event that is not the situation for all the data sets.) There is no independent variable vector provided, however if one exists, index into it the same way.
.
@Star Strider Many thanks! I thought it would be more difficult than it is :]
As always, my pleasure!
I posted an answer to your follow-up question as well, complete with results, since the indexing turned out to be a bit more complicated that I thought it would be.
EDIT —
The complete revised code is now:
LD = load('signal.mat');
force_y_r = LD.force_y_r;
Lv1 = islocalmin(force_y_r, 'FlatSelection','first', 'MinSeparation',500, 'MinProminence',750);
Lv2 = islocalmin(force_y_r, 'FlatSelection','last', 'MinSeparation',500, 'MinProminence',750);
StartIndices = find(Lv2);
StartIndices = StartIndices(1:end-1);
EndIndices = find(Lv1);
EndIndices = EndIndices(2:end);
for k = 1:numel(StartIndices)
Force{k,:} = force_y_r(StartIndices(k):EndIndices(k));
end
Force
Force1 = Force{1}(1:10) % First 10 Rows
SegmentIndices = table(StartIndices, EndIndices)
x = 1:numel(force_y_r);
figure
plot(x, force_y_r)
hold on
plot(x(EndIndices), force_y_r(EndIndices), '^r')
plot(x(StartIndices), force_y_r(StartIndices), '^g')
hold off
.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!