Peter H Charlton's Pulsewave Analyse and ppg-beat tools are not working well.

32 views (last 30 days)
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)

Answers (2)

Star Strider
Star Strider on 3 Apr 2024 at 10:57
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
민섭 김
민섭 김 on 4 Apr 2024 at 8:29
The bandpass applied signal was strange, so the LPF signal was applied to the Pulse analysis tool.
But it still doesn't work. please help me
Star Strider
Star Strider on 4 Apr 2024 at 10:24
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.

Sign in to comment.


Angelo Yeo
Angelo Yeo on 3 Apr 2024 at 0:14
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
Angelo Yeo on 3 Apr 2024 at 6:15
What's your issue? It looks like your code works. Can you elaborate your issue?
민섭 김
민섭 김 on 3 Apr 2024 at 6:37
The picture at the top is a ppg signal with good signal processing. When this signal is applied to Pulseallyse, features such as sis peak, dic notch, di peak are pulled out well in units of 1 segment, and onset is also well detected.(In the case of this signal, I got it from the Internet and don't know the exact way to process it.)
The picture at the top shows me directly applying hpf (fc=0.5hz) and lpf (fc=10hz) to raw ppg signals and using them for Pulseanalyse tool. The peak is not detected correctly, and the onset is also not being able to measure correctly. In the above picture, the high quality ppg signal is measured well, while the ppg signal I processed is not detecting the high quality signal either.

Sign in to comment.

Products


Release

R2023b

Community Treasure Hunt

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

Start Hunting!