Peter H Charlton's Pulsewave Analyse and ppg-beat tools are not working well.
6 views (last 30 days)
Show older comments
I am currently using Peter H charlton's Pulse tool and ppg-beat tool to extract the feature and fiducial point of Raw ppg data. For signals that are very well signal-processed, the tool works well, but if I apply the raw signal I have to the 10hz LPF filtered signal to the tool, it doesn't work well. Why is that? fs = 1000. I have experience applying the 4th chebyshev instead of the 10hz LPF, but in this case, the filtered signal was very strange, so I used the LPF.
-my raw signal
-use pulseanalysetool to my rawsignal
-use pulseanalysetool to my rawsignal(remove front)
-a well-applied case
-my weired signal used by 4 chebyshev
chebyshevcode
% Chebyshev 필터 설계
% sampling frequency
fs = 1000; % 1000Hz
% set parameter for 4th chebyshev
N = 4;
Wn = [0.5/(fs/2), 5/(fs/2)];
% design filter
[b, a] = cheby1(N, 0.5, Wn, 'bandpass');
% filtering
filtered_ppg = filtfilt(b, a, rawdata);
% normalization
filtered_ppg_normalized = (filtered_ppg - mean(filtered_ppg)) / std(filtered_ppg);
my code(The raw data is attached to the writing)
fs = 1000; % 1000Hz
fc = 10; % 10Hz
N = 4; % order
[b, a] = butter(N, fc/(fs/2), 'low');
% filtering
filtered_ppg = filtfilt(b, a, rawdata);
% remove front
increase_idx = find(diff(filtered_ppg) > 0, 1);
filtered_ppg(1:increase_idx - 1) = [];
% setup using the code provided in the question
ppg_head = filtered_ppg ;
fs = 1000;
S.v = ppg_head;
S.fs = fs;
[cv_inds, fid_pts, pulses] = PulseAnalyse(S)
0 Comments
Accepted Answer
Star Strider
on 3 Apr 2024
The best way to design a filter is to first calculate the Fourier transform of the signal, and then use that to design the frequency passbands and stopbands.
This approach first calculates the Fourier transform and then uses the lowpass (and optionally bandpass) functions to design the filters. They design very efficient elliptic filters (with 'ImpulseResponse','iir'), and usually with good results. (I generally prefer elliptic filters for their computational efficiency.)
Try something like this ‘—
ppg = readmatrix('rawppgdata.csv');
Fs = 1000;
L = numel(ppg);
t = linspace(0, L-1, L)/Fs;
[FTs1,Fv] = FFT1(ppg,t);
figure
plot(Fv, abs(FTs1)*2)
grid
xlabel('Frequency (Hz)')
ylabel('Magnitde')
xlim([0 10])
ppg_LPF = lowpass(ppg, 5.8, Fs, 'ImpulseResponse','iir');
ppg_BPF = bandpass(ppg, [0.7 5.8], Fs, 'ImpulseResponse','iir');
figure
tiledlayout(3,1)
nexttile
plot(t, ppg)
grid
xlabel('Time (s)')
ylabel('Amplitude')
title('Original Signal')
nexttile
plot(t, ppg_LPF)
grid
xlabel('Time (s)')
ylabel('Amplitude')
title('Lowpass-Filtered Signal')
nexttile
plot(t, ppg_BPF)
grid
xlabel('Time (s)')
ylabel('Amplitude')
title('Bandpass-Filtered Signal')
function [FTs1,Fv] = FFT1(s,t)
t = t(:);
L = numel(t);
if size(s,2) == L
s = s.';
end
Fs = 1/mean(diff(t));
Fn = Fs/2;
NFFT = 2^nextpow2(L);
FTs = fft((s - mean(s)) .* hann(L).*ones(1,size(s,2)), NFFT)/sum(hann(L));
Fv = linspace(0, 1, NFFT/2+1)*Fn;
Iv = 1:numel(Fv);
FTs1 = FTs(Iv,:);
end
The lowpass filter neatly eliminates the high-frequency noise without distorting the signal. The bandpass filter also eliminiates the D-C (constant baseline) bias if that is desired, however it slightly distorts the signal. It is possible to design elliptid filters using command-line functions, however using the respective functions is easier.
.
2 Comments
Star Strider
on 4 Apr 2024
First, what does ‘doesn’t work’ mean?
I have a reasonable amount of experience with PPG and other physiological signals, however I do not have that specific ttoolbox (and I have no reason to use it because the code I use works foo me).
Second, what information do you want from that signal?
I notice that in contrast to PPG traces that I am used to, the dicrotic notch seems to be missing. That indicates to me that there could be aortic insufficiency, or that the PPG is taken suitably distally that the vascular system dynamics filter it out.
More Answers (1)
Angelo Yeo
on 3 Apr 2024
Well, it's not a issue of Peter H Charlton's PulseAnalyze. It's about how you design filters.
(1) Did you check the frequency response? The passband condition is hard to be met for Chebyshev Type I.
rawdata = load("rawppgdata.csv");
% Chebyshev 필터 설계
% sampling frequency
fs = 1000; % 1000Hz
% set parameter for 4th chebyshev
N = 4;
Wn = [0.5/(fs/2), 5/(fs/2)];
% design filter
[b, a] = cheby1(N, 0.5, Wn, 'bandpass');
freqz(b, a, [], fs)
subplot(2,1,1)
xlim([0 10])
ylim([-25 20])
(2) I would recommend to apply lowpass filter and highpass filter separately instead of bandpass filtering especially when the passband is small like in this situation.
4 Comments
Angelo Yeo
on 3 Apr 2024
What's your issue? It looks like your code works. Can you elaborate your issue?
See Also
Categories
Find more on Frequency Transformations 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!