필터 지우기
필터 지우기

Find peaks and valley of sinusoidal curve

조회 수: 21 (최근 30일)
Maria Inês
Maria Inês 2023년 4월 12일
댓글: Mathieu NOE 2023년 6월 14일
Hello, I have a code that reads a file and converts it into a graph which, in turn, applies the detrend filter. However, it is not enough and I needed to know the peaks and valleys of this new graph and then subtract the values from the peaks to the valleys in order to normalize the curves. I tried to find it with findpeaks but it didn't work. How can I do it?
TY
function startupFcn(app)
data=readmatrix('ensaios_controlo.xlsx','sheet','analise');
time_control=data(:,2);
strain_control=data(:,3);
t_control=seconds(time_control);
t_control.Format = 'hh:mm:ss';
plot(app.UIAxes,t_control,strain_control)
s=rms(strain_control);
app.RMS_controlEditField.Value=s;
end
% Button pushed function: FileButton
function FileButtonPushed(app, event)
[name,path]=uigetfile('.xlsx','Select a file');
app.file=fullfile(path,name);
data_2=readmatrix(app.file,"Sheet",'Untitled');
time=data_2(:,2);
strain=data_2(:,3);
x=seconds(time);
x.Format = 'hh:mm:ss';
d=rms(strain);
app.RMSEditField.Value=d;
if (1342<d)&&(d<1483)
msgbox("Don't need analyse.","non-modal");
else
app.TabGroup.SelectedTab=app.DataTab;
plot(app.UIAxes3,x,strain,"r");
yline(app.UIAxes2,0)
yline(app.UIAxes2,-2800);
end
end
% Button pushed function: AnalyseButton
function AnalyseButtonPushed(app, event)
data_2=readmatrix(app.file,"Sheet",'Untitled');
time=data_2(:,2);
strain=data_2(:,3);
strain_2 = detrend(strain,6);
x=seconds(time);
x.Format = 'hh:mm:ss';
d=rms(strain);
app.RMSEditField.Value=d;
pks = findpeaks(strain);
findpeaks(strain);
pks_v= findpeaks(-strain);
findpeaks(-strain);
if (1342<d)&&(d<1483)
msgbox("Don't need analyse.","non-modal");
else
app.TabGroup.SelectedTab=app.AnalyseTab;
plot(app.UIAxes2,x,strain,"r");
hold(app.UIAxes2,'on');
plot(app.UIAxes2,x,strain_2,"b");
yline(app.UIAxes2,0)
yline(app.UIAxes2,-2800);
end
end
  댓글 수: 5
Maria Inês
Maria Inês 2023년 4월 12일
I apologize, I have now attached the files. The file to normalize the values that will have to be chosen in the "file" button is "test_15_seco". In the Data tab, the graph corresponding to the values in the file appears and I want to transform the maximum value into zero.
dpb
dpb 2023년 4월 13일
app.file='https://www.mathworks.com/matlabcentral/answers/uploaded_files/1353474/provete_15_seco.xlsx';
data_2=readmatrix(app.file,"Sheet",'Untitled');
time=data_2(:,2);
strain=data_2(:,3);
strain_2 = detrend(strain,6);
x=seconds(time);
x.Format = 'hh:mm:ss';
d=rms(strain);
app.RMSEditField.Value=d;
pks = findpeaks(strain);
findpeaks(strain);
pks_v= findpeaks(-strain);
findpeaks(-strain);
if (1342<d)&&(d<1483)
msgbox("Don't need analyse.","non-modal");
else
%app.TabGroup.SelectedTab=app.AnalyseTab;
plot(x,strain,"r");
hold on
plot(x,strain_2,"b");
yline(0)
yline(-2800);
end
What are we to make of that???
Now explain what, specifically, you're trying to do here. It would certainly help to supply some context to the problem so folks have at least a half-chance of understanding the rationale behind the machinations--generally that is a help in devising a solution; to know the end goal and why.

댓글을 달려면 로그인하십시오.

채택된 답변

Mathieu NOE
Mathieu NOE 2023년 4월 13일
So far I understand you want the strain plot have all top peaks being on y = 0 line , like in your reference data file (ensaios_controlo.xlsx)
so this is my suggestion, and no I am not using findpeaks this time... I prefer peakseek which is simpler and faster and does the job very well here ( a no brainer almost)
you can access at the FEX page here ,
or simply use the code provided below
also , no need to do any preliminary detrending, you can skip that.
Result is the new magenta line , see it has all top peaks aligned with y = 0
Zoom :
Code :
data_2=readmatrix("provete_15_seco.xlsx","Sheet",'Untitled');
time=data_2(:,2);
strain=data_2(:,3);
x=seconds(time);
x.Format = 'hh:mm:ss';
d=rms(strain);
app.RMSEditField.Value=d;
if (1342<d)&&(d<1483)
msgbox("Don't need analyse.","non-modal");
else
%app.TabGroup.SelectedTab=app.AnalyseTab;
% plot(x,strain,"r");
% hold on
plot(x,strain,"b");
yline(0)
yline(-2800);
hold on
% shift strain so that it positive peaks are on the y = 0 line
[locs, pks]=peakseek(strain);
x_peaks = x(locs);
yshift = interp1(x_peaks,pks,x);
plot(x,yshift,"r");
strain_3 = strain - yshift;
plot(x,strain_3,"m");
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [locs, pks]=peakseek(x,minpeakdist,minpeakh)
% FEX : https://fr.mathworks.com/matlabcentral/fileexchange/26581-peakseek?s_tid=srchtitle
% x is a vector input (generally a timecourse)
% minpeakdist is the minimum desired distance between peaks (optional, defaults to 1)
% minpeakh is the minimum height of a peak (optional)
%
% (c) 2010
% Peter O'Connor
% peter<dot>ed<dot>oconnor .AT. gmail<dot>com
if size(x,2)==1, x=x'; end
% Find all maxima and ties
locs=find(x(2:end-1)>=x(1:end-2) & x(2:end-1)>=x(3:end))+1;
if nargin<2, minpeakdist=1; end % If no minpeakdist specified, default to 1.
if nargin>2 % If there's a minpeakheight
locs(x(locs)<=minpeakh)=[];
end
if minpeakdist>1
while 1
del=diff(locs)<minpeakdist;
if ~any(del), break; end
pks=x(locs);
[garb, mins]=min([pks(del) ; pks([false del])]); %#ok<ASGLU>
deln=find(del);
deln=[deln(mins==1) deln(mins==2)+1];
locs(deln)=[];
end
end
if nargout>1
pks=x(locs);
end
end
  댓글 수: 7
Mathieu NOE
Mathieu NOE 2023년 6월 14일
hello again
I have some trouble unzipping your file - does it work on your side ?
Mathieu NOE
Mathieu NOE 2023년 6월 14일
maybe you could reduce the amount of data and send me only the first half , so you don't have to zip it
that should be enough data to fix the code

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Maria Inês
Maria Inês 2023년 6월 14일
Hi,
I had no problems but I attach a file with less data.
  댓글 수: 1
Mathieu NOE
Mathieu NOE 2023년 6월 14일
I am tryng to find a robust method that works both for the first data file you provided and then this new one - but they show very different look
your first file (provete_15_seco.xlsx) was a clean almost triangular shape signal with no artifacts or noise. also we can see the distance between peaks are only a few samples (blue dots on the curve).
with such a clean signal peakseek would work nicely even without to give any extra parameter values about minimal peak distance and height.
the "new" data file (5x250_CF_alterado.xlsx) gives a very different figure :
  • lots of data points between peaks - if I look at the negative peaks that are a bit more evident to recognize , I will see more than 1000 samples between 2 successive negative peaks, like this measurement has been made with a much higher sampling rate (or the test is done at a lower frequency)
  • signal quite a bit noisy and distorded on the positive side
  • peakseek will have trouble selecting the only valid peaks if we do not help him by defining an appropriate value for minpeakdist,minpeakh - now the risk is that we may have to tune those parameters depending of what signal we have , for example what distance between peaks we have and if the signal quality is like the first file or the second data file
  • so it's going to be messy to tweak too many parameters depending of what the data looks like , we need something simple and robust
a zoom on the top
so my job now is to find the "magic" tool that can deal with both data sets without requiring to "tune" too many parameters....

댓글을 달려면 로그인하십시오.


Maria Inês
Maria Inês 2023년 6월 14일
Hi,
Okay, I understand. I can't put the filter of the first data file I sent in this second file because the data is different.
How can I help? What kind of parameters do you need to know to get the magic formula?
If it's simpler, you can just find the magic formula for these data (5x250_CF_alterado.xlsx) but with the same goal, ie take the peaks and set them to zero.
There is another issue that I don't know if you've seen, Ch2 will have symmetrical values to that of CH1. The filter must also be able to make this adjustment when the peak values are negative and positive.
I don't know if I made myself clear...
Any questions, just say.
  댓글 수: 2
Mathieu NOE
Mathieu NOE 2023년 6월 14일
I was about to ask if you have some more data files to share , so I can see what kind of signals we have , but in the mean time i figured out / tested other options and , at least for the two files we have today , I could find a simple and more robust solution
basically you only need to replace peakseek with another function that is better working on noisy signals (here comes peakfinder , see attachment)
so it seems to work for both data files , and or the last file, I tested on channel 2 and 3 and it's ok
sorry if I have a bit messed up your code , but I think you can easily copy / paste the new lines , or simply uncomment your lines I have commented
also I beleive it is better to remove NaN values (they are generated by readmatrix when you have header lines in your excel file but you don't ask readmatrix to ignore them)
ok, so finally this is the new code , please have a ook and try it and let me know !
if you want to send me some more data files , I can also continue to test the code on my side
% [name,path]=uigetfile('.xlsx','Select a file'); % your code
% my code for fast testing
path = pwd;
% files i want to test
% name = 'provete_15_secoB.xlsx'; % 1st file
name = '5x250_CF_alterado.xlsx'; % 2 nd file (test Channel 2 and 3 !)
% main code
file=fullfile(path,name);
data_2=readmatrix(file,"Sheet","Untitled");
x=data_2(:,1);
strain=data_2(:,2); % choose which strain channel you want
% better remove NaN's first (they come from excel file header lines)
i1 = ~isnan(x);
i2 = ~isnan(strain);
i3 = i1&i2;
x=x(i3);
strain=strain(i3);
% plot(app.UIAxes,x,strain,"b"); % your code
plot(x,strain,"b");
% yline(0); % your code
% yline(-2800); % your code
hold on
% shift strain so that it positive peaks are on the y = 0 line
[locs] = peakfinder(strain); % more noise resistant than peakseek
yshift = interp1(x(locs),strain(locs),x);
plot(x,yshift,"k"); % just for fun (debug)
strain_3 = strain - yshift;
% plot(app.UIAxes_2,x,strain_3,"b", x,yshift,"r"); % your code
plot(x,strain_3,"r");
hold off
Mathieu NOE
Mathieu NOE 2023년 6월 14일
forgot the attachment (peakfinder )
now you have it !

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Spectral Analysis에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by