You are now following this question
- You will see updates in your followed content feed.
- You may receive emails, depending on your communication preferences.
How to calculate the peak-to-peak amplitude of a waveform?
88 views (last 30 days)
Show older comments
Hi All,
Sorry if I’m asking about the obvious, but could somebody please tell me how to calculate the peak-to-peak voltage of the following signal? I would like to know what the peak-to-peak amplitude of this signal is, and if I add random noise to it, how much the peak-to-peak amplitude will change. (fig file is attached)
Many thanks in advance.
Accepted Answer
Star Strider
on 28 Aug 2022
Edited: Star Strider
on 28 Aug 2022
Fortunately, there are complete P-T complexes in thei record, making the calculations easier.
Detrending is important here in order to get uniform values. This requires a degree polynomial to detrend it adequately, something that to me is a bit extreme, however I could not get any other detrending approach (highpass filtering for example_ to give a satisfactory result. As a general rule, the R-wave is measured from the previous P-R interval, since that is considdered to be an isoelectric reference. This measures the peak-to-peak amplitude between the R-deflection and the following S-deflection, since that is the greatest difference —
LD = openfig(websave('Fig','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1110230/Fig.fig'));
Lines = findobj(LD, 'Type','line');
Xv = Lines.XData
Yv = Lines.YData
Fs = 1/(Xv(2)-Xv(1))
Yvf = detrend(Yv, 9);
Smin = islocalmin(Yvf, 'MinProminence',4000, 'MinSeparation',100);
Rmax = islocalmax(Yvf, 'MinProminence',5500);
Sdef = Yvf(Smin);
Rdef =Yvf(Rmax);
PtoP = Rdef - Sdef
figure
plot(Xv, Yvf, 'DisplayName','Filtered EKG')
hold on
plot(Xv(Rmax), PtoP,'r+', 'DisplayName','P-P Values')
% plot(Xv(Rmax), Yvf(Rmax),'r^', 'DisplayName','R-Deflections')
% plot(Xv(Smin), Yvf(Smin), 'rv', 'DisplayName','S-Deflections')
hold off
grid
legend('Location','best')
xlim([0 5])
Make appropriate changes to get different results.
.
16 Comments
Susan
on 28 Aug 2022
@Star Strider Thank you so much for your response. Appreciate it.
Could you please tell me how you selected 4000, 100, and 5500 in the islocalmax function? If I know that I can apply a bandpass filter with LP=0.05Hz and HP = 60Hz to this EKG signal, should I first apply the bandpass filter and then deternd the signal or vice versa? Does the order matter at all? Could you please tell me how I can use a bandpass filter with known corner frequencies for this signal?
Many many thanks in advance
Star Strider
on 28 Aug 2022
My pleasure!
‘Could you please tell me how you selected 4000, 100, and 5500 in the islocalmax function?’
Sure! I began with an appropriate initial estimate of 500, and then just experimented until I got the result I wanted. There may be more efficient ways, however this approach generally works for me, especially with long signals.
‘If I know that I can apply a bandpass filter with LP=0.05Hz and HP = 60Hz to this EKG signal, should I first apply the bandpass filter and then deternd the signal or vice versa?’
I would not recommend that approach with this EKG. I tried a highpass filter and was not able to get what I consider to be an acceptable result, that being the reason I went with detrend instead. (This signal is not noisy, so a bandpass filter to remove high-frequency noise is not necessary, however if you want to add band-limited noise to it, a bandpass filter would then be required.) If you have a noisy signal (instead of the one provided here), always filter first (the filter design being guided by the signal characteristics, and the fft or pspectrum can help determine those), then detrend as necesary after filtering.
‘Does the order matter at all?’
The order always matters! I am not certain what you are referring to here, however. If you want to use a bandpass filter, and use the bandpass function, specifying an IIR filter with 'ImpulseResponse','iir' will result in a very efficient elliptic filter that will not be restricted by short signals, as would a FIR filter. The order will be calculated automatically as part of the design process. You can see the filter characteristics if you ask for the second output from the function.
‘Could you please tell me how I can use a bandpass filter with known corner frequencies for this signal?’
If you have the Signal Processing Toolbox, the bandpass function documentation explains all that in detail. If you have the Signal Processing Toolbox and do not have the bandpass function, I can design an efficient elliptical filter and explain the steps involved in designing and implementing it. That only requires a few lines of code, and some comments.
.
Susan
on 29 Aug 2022
Thank you again for your thorough response. I truly appreciate your detailed reply.
You mentioned that "you began with an appropriate initial estimate of 500, and then just experimented until you got the result I wanted. ". Sorry if I'm asking about the obvious, but could you please tell me what kind of results you expected and why?
If I have two EKG signals with different amplitudes and want to know the scale between these signals, does it make sense to calculate the peak-to-peak values for two signals the way you taught me above and compare these values to figure out the scale/gain?
If I add noise to this EKG signal and my goal is to figure out if the amplitude of the added noise value is greater or less than a peak-to-peak voltage threshold, is it correct to calculate the peak-to-peak amplitude of the EKG signal with and without the noise and compare the difference of these two with the given threshold?
Star Strider
on 29 Aug 2022
My pleasure!
‘Sorry if I'm asking about the obvious, but could you please tell me what kind of results you expected and why?’
I wanted to find the correct ‘valley’ (local minimum) given by ‘Smin’ in my code, and the R deflection maximum (local maximum) given by ‘Rmax’. You can see those if you un-comment the two plot calls I commented-out. They will then also appear in the legend.
‘If I have two EKG signals with different amplitudes and want to know the scale between these signals, does it make sense to calculate the peak-to-peak values for two signals the way you taught me above and compare these values to figure out the scale/gain?’
That depends on what you want to do. They need to have appropriate (and preferably similar) scales for any of it to make sense. The R-deflection amplitude is characteristically between and so it’s best to normalise them by whatever scaling factor applies to them first so that the amplitudes are correct.
‘If I add noise to this EKG signal and my goal is to figure out if the amplitude of the added noise value is greater or less than a peak-to-peak voltage threshold, is it correct to calculate the peak-to-peak amplitude of the EKG signal with and without the noise and compare the difference of these two with the given threshold?’
Again, ‘correct’ is relative. Adding noise will affect the absolute and P-P amplitudes. It also depends on the noise, since Gaussian noise (produced by randn and some other functions) will be different than uniformly-distributed random noise (produced by rand and some other functions). What you describe is certainly possible. I always suggest doing the experiment and then examine the results. Added noise will certainly affect the threshold crossing (and the probability of crossing it) if a threshold is used, and again that depends on the type of noise.
.
Susan
on 29 Aug 2022
@Star Strider thank you very much for your detailed response. It helps alot. Appreciate it!
Susan
on 29 Aug 2022
@Star Strider I applied your code to different sets of data (data with varying sampling rates), and it works perfectly; I mean, I didn't even make appropriate changes in the parameters value of the "islocalmin" and "islocalmin" functions to get satisfactory results (I expected to change the parameters accordingly though). However, I've noticed that the "islocalmin" function with the current parameter values doesn't work correctly if the signal's sampling rate is equal to 128 Hz. I've changed the parameters but have had no success so far. I don't know why the "islocalmin" function cannot determine all local mins and just some of them and wasn't able to find any relations between those that it can. I attached this data. Could you please kindly take a look and let me know what is going on?
Many thanks in advance!
Star Strider
on 29 Aug 2022
Changing the sampling frequency does not necessarily require a change in the 'MinProminence' parameters, however it does require a change (specifically decrease for a lower samplling frequency and higher for a higher sampling frequency) in the 'MinSeparation' value, since with a lower sampling frequency there are fewer samples between peaks, so keeping it at the value necessary for a higher sampling frequency will result in missing some valid peaks at a lower sampling frequency, and using that value with a higher sampling frequency may allow some peaks to be detected that would not otherwise be detected. Other that that (and perhaps similar name-value pairs such as 'ProminenceWindow'), islocalmax and islocalmin are insensitive to the sampling frequency.
I changed it from 100 to 50 here with acceptable results —
LD = openfig(websave('Fs128','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1111240/Fs128.fig'));
Lines = findobj(LD, 'Type','line')
Lines =
3×1 Line array:
Line (S-Deflections)
Line (R-Deflections)
Line (Filtered EKG)
Xv = Lines(3).XData;
Yv = Lines(3).YData;
Fs = 1/(Xv(2)-Xv(1))
Fs = 128
Yvf = detrend(Yv, 9);
Smin = islocalmin(Yvf, 'MinProminence',4000, 'MinSeparation',50);
Rmax = islocalmax(Yvf, 'MinProminence',5500);
Sdef = Yvf(Smin);
Rdef = Yvf(Rmax);
PtoP = Rdef - Sdef;
figure
plot(Xv, Yvf, 'DisplayName','Filtered EKG')
hold on
% plot(Xv, Yv, 'DisplayName','Unfiltered EKG')
plot(Xv(Rmax), PtoP,'r+', 'DisplayName','P-P Values')
plot(Xv(Rmax), Yvf(Rmax),'r^', 'DisplayName','R-Deflections')
plot(Xv(Smin), Yvf(Smin), 'rv', 'DisplayName','S-Deflections')
hold off
grid
legend('Location','best')
xlim([0 10])
I had not considered that you might use it with a different sampling frequency.
.
Susan
on 29 Aug 2022
Edited: Susan
on 29 Aug 2022
@Star Strider Thank you so much for your detailed response. Truly appreciate it. It makes sense.
I've got one more question for you. It's related to finding the peak-to-peak value, but please let me know if I need to start a new thread.
I collected three sets of data with different recording gains. I'm wondering about the relation between the recording gain on the recorder system and the peak-to-peak amplitude of the collected signals. This relation can be linear/non-linear. I see an amplitude change and signal shift by plotting the waveforms (Fig: Gain2 attached here). I try to do peak alignment to see if there is any phase shift in the signals or if it is just because of the start time of recording signals.
[chl,lagshl] = xcorr(data3(:,5),data1(:,5));
shl = lagshl(chl==max(chl));
yhl = circshift(data1(:,5),shl);
[chm,lagshm] = xcorr(data3(:,5),data2(:,5));
shm = lagshm(chm==max(chm));
yhm = circshift(data2(:,5),shm);
tmax1 = numel(data1)/Fs1/8;
tmax2 = numel(data2)/Fs2/8;
tmax3 = numel(data3)/Fs3/8
t1 = 0 : 1/Fs1 : tmax1-1/Fs1;
t2 = 0 : 1/Fs2 : tmax2-1/Fs2;
t3 = 0 : 1/Fs3 : tmax3-1/Fs3;
figure
plot(t1, yhl);
hold on
plot(t2, yhm);
hold on
plot(t3, data3(:,5));
grid on
grid minor
legend('0.5mV', '1mV', '2mV')
xlabel('t (sec)')
ylabel('Amplitude')
xlim([0 5])
The result is attached here, too (Fig:Gain1). It seems that the recording gain has a linear effect on signals. Could you please let me know if my conclusion and the way I made this conclusion are correct or not?
Then I planed to calculate the Peak-to-peak amplitude for three signals and compare them to determine how much the recording gain would change the EKG signal's amplitude. I run into an error that the number of Sdef and Rdef are not equal that I guess it's because of shifting the signals. Could you kindly tell me if my approach is correct or not and if it is how to deal with this error?
Again, thank you so much for your time!
Star Strider
on 29 Aug 2022
If the amplitude changes, the values for 'MinProminence' wiil have to be scaled accordingly. If the amplitude scaling is constant, just multiply the 'MinProminence' values by the same scaling factor, and the code should work correctly.
Susan
on 29 Aug 2022
@Star Strider That makes sense. But if we don't know the amplitude scaling, can we calculate this scale based on the Peak-to_peak values?
Star Strider
on 29 Aug 2022
If they are not scaled and have the same approximate amplitudes, leave them as they are.
If they have different amplitudes, get the mean maximum (or range, calculated as mean(maximum)-mean(minimum)) amplitude of one record and divide it by the same measure of the other to scale both to the same approximate amplitudes.
Then (if necessary), scale the 'MinProminence' values using the same scaling factor so that it applies to both (or multiple) records.
I am guessing here, because I do not know what the records are, or their characteristics. (So this is a general , rather than specific, approach.)
Susan
on 30 Aug 2022
Thanks again for your response. In the attached fig, there are three EKG signals. They have different amplitudes, and it seems there are shifted in time (I used the above matlab lines to align the peaks first). They are scaled, but I can't say if the scale is just because of the recorder gain or not. I would like to know how much their peak-to-peak amplitude is different and whether it is linearly associated with the recorder gain. Could you please let me know what you think?
Star Strider
on 30 Aug 2022
This detects the approximate ranges of the original EKGs, then adapts my previous code to analyse each of them scaling the islocalmin and islocalmax parameters using the initial ‘Rng’ value —
Uz = unzip('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1111445/Gain2.zip')
Uz = 1×1 cell array
{'Gain2.fig'}
LD = openfig(Uz{1});
Lines = findobj(LD, 'Type','line')
Lines =
3×1 Line array:
Line (2mV)
Line (1mV)
Line (0.5mV)
EKGs = numel(Lines)
EKGs = 3
figure
for k = 1:EKGs
Xv{k} = Lines(k).XData;
Yv{k} = Lines(k).YData;
Fs = 1/(Xv{k}(2)-Xv{k}(1));
Yvf{k} = detrend(Yv{k}, 9);
Rng{k} = max(Yv{k} - min(Yv{k}));
Smin = islocalmin(Yvf{k}, 'MinProminence',0.4*Rng{k}, 'MinSeparation',fix(Fs/10));
Rmax = islocalmax(Yvf{k}, 'MinProminence',0.5*Rng{k});
Sdef{k} = Yvf{k}(Smin);
Rdef{k} = Yvf{k}(Rmax);
PtoP{k} = Rdef{k} - Sdef{k};
PtoPstats{k} = [mean(PtoP{k}) median(PtoP{k}) std(PtoP{k}) min(PtoP{k}) max(PtoP{k})];
subplot(EKGs,1,k)
plot(Xv{k}, Yvf{k}, 'DisplayName','Filtered EKG')
hold on
% plot(Xv, Yv, 'DisplayName','Unfiltered EKG')
plot(Xv{k}(Rmax), PtoP{k},'r+', 'DisplayName','P-P Values')
plot(Xv{k}(Rmax), Yvf{k}(Rmax),'r^', 'DisplayName','R-Deflections')
plot(Xv{k}(Smin), Yvf{k}(Smin), 'rv', 'DisplayName','S-Deflections')
hold off
grid
legend('Location','best')
title(Lines(k).DisplayName)
xlim([0 10])
ylim([1 1]*1.25.*ylim)
end
Rng{:}
ans = 52214
ans = 26263
ans = 13219
for k = 1:EKGs
fprintf('P-P %7s: Mean = %9.3f Median = %9.3f StDev = %9.3f Min = %9.3f Max = %9.3f\n', Lines(k).DisplayName, PtoPstats{k})
end
P-P 2mV: Mean = 44122.383 Median = 44128.985 StDev = 158.645 Min = 43788.078 Max = 44442.114
P-P 1mV: Mean = 22091.341 Median = 22099.056 StDev = 78.268 Min = 21950.784 Max = 22243.890
P-P 0.5mV: Mean = 11039.118 Median = 11040.005 StDev = 39.930 Min = 10951.222 Max = 11118.941
for k = 1:EKGs
fprintf('Scaled P-P %7s: Mean = %5.3f\tMedian = %5.3f\tStDev = %8.6f\tMin = %5.3f\tMax = %5.3f\n', Lines(k).DisplayName, PtoPstats{k}/Rng{k})
end
Scaled P-P 2mV: Mean = 0.845 Median = 0.845 StDev = 0.003038 Min = 0.839 Max = 0.851
Scaled P-P 1mV: Mean = 0.841 Median = 0.841 StDev = 0.002980 Min = 0.836 Max = 0.847
Scaled P-P 0.5mV: Mean = 0.835 Median = 0.835 StDev = 0.003021 Min = 0.828 Max = 0.841
The second result scales the statistics by the value of ‘Rng’ for each EKG.
.
Susan
on 30 Aug 2022
@Star Strider Thank you so much for your time. I sincerely appreciate your help.
More Answers (1)
Abderrahim. B
on 28 Aug 2022
Hi!
Use peak2peak function. Demo below:
load('ecgSignals.mat')
t = (1:length(ecgl))';
plot(t, ecgl)
peak2peak(ecgl)
ans = 2.1751
% You may need to detrend the ecg signal before finding peak to peak
% amplitude.
dt_ecgl = detrend(ecgl);
plot(t, dt_ecgl)
peak2peak(dt_ecgl)
ans = 2.0302
See Also
Categories
Find more on Signal Generation and Preprocessing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!An Error Occurred
Unable to complete the action because of changes made to the page. Reload the page to see its updated state.
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
Asia Pacific
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)