PIA-Group / BioSPPy

Biosignal Processing in Python
Other
569 stars 273 forks source link

Issues finding the onsets of PPG #88

Closed abhinandanpanda closed 2 years ago

abhinandanpanda commented 2 years ago

Hi Sir, I was trying to find the onsets of PPG using the this tool for one of my work. Even though the methods name starts with onset detection but its finding the peaks of the PPG. Also the onset detection method mentioned in documentations based on the approach by Zong et al. is missing.

As I am new to signal processing, I am in bare need of such tool. Kindly suggest.

Regards Abhinandan

afonsocraposo commented 2 years ago

Hi @abhinandanpanda, Thank you for reaching out! We provide two methods for onset detection in PPG signals: https://github.com/PIA-Group/BioSPPy/blob/8f982642ecba4278d5c7bd5bb801b200503e72d0/biosppy/signals/ppg.py#L105 https://github.com/PIA-Group/BioSPPy/blob/8f982642ecba4278d5c7bd5bb801b200503e72d0/biosppy/signals/ppg.py#L230 Both these methods receive a PPG signal, signal, and an optional sampling rate, sampling_rate (default value is 1000 Hz).

Below is a working example:

from biosppy.signals.ppg import *
import biosppy.signals.tools as st
import numpy as np
import matplotlib.pyplot as plt

signal = np.loadtxt("examples/ppg.txt")

# filter signal
filtered, _, _ = st.filter_signal(
    signal=signal,
    ftype="butter",
    band="bandpass",
    order=4,
    frequency=[1, 8],
)

onsets_elgendi2013, _ = find_onsets_elgendi2013(-filtered)

onsets_kavsaoglu2016, _, _ = find_onsets_kavsaoglu2016(signal)

plt.subplot(211)
plt.plot(filtered, label="filtered")
plt.scatter(onsets_elgendi2013, filtered[onsets_elgendi2013], c="orange")
plt.title("find_onsets_elgendi2013")
plt.legend()

plt.subplot(212)
plt.plot(signal, label="raw")
plt.scatter(onsets_kavsaoglu2016, signal[onsets_kavsaoglu2016], c="orange")
plt.title("find_onsets_kavsaoglu2016")
plt.legend()

plt.show()

Output: Figure_1

Notice that the find_onsets_elgendi2013 method requires a filtered signal and it detects the PPG peaks. Since the PPG signal is filtered, it has no static component (DC), which means you can obtain the onsets by simply inverting the signal:

onsets_elgendi2013, _ = find_onsets_elgendi2013(-filtered)

Regarding the onset detection method based on the approach by Zong et al. it is part of the ABP (Arterial Blood Pressure) package: https://github.com/PIA-Group/BioSPPy/blob/8f982642ecba4278d5c7bd5bb801b200503e72d0/biosppy/signals/abp.py#L104

abhinandanpanda commented 2 years ago

Thank you so much sir. I am sorry for late reply. I believe if I want to find the peaks using find_onsets_elgendi2013(), I need to pass the filtered signal.

Thank you again.

Regards Abhinandan

afonsocraposo commented 2 years ago

Yes @abhinandanpanda , to use the find_onsets_elgendi2013 you'll need to filter the signal first. Please see the example I wrote above :)