Photoplethysmography (PPG)
Photoplethysmography (PPG) is a non-invasive optical technique used to measure blood volume changes in the microvascular bed of tissue. PPG signals are often used to measure heart rate, heart rate variability (HRV), respiratory rate, and oxygen saturation (SpO2). In PhysioKit, we provide a variety of routines for processing PPG signals.
physiokit.ppg.clean
clean(data, lowcut=0.5, highcut=4, sample_rate=1000, order=3, axis=-1, forward_backward=True)
Clean PPG signal using biquad filter.
By default applies a 3rd order Butterworth filter between 0.5 and 4 Hz.
Parameters:
-
data
(NDArray
) –Signal
-
lowcut
(float
, default:0.5
) –Lower cutoff in Hz. Defaults to 0.5 Hz.
-
highcut
(float
, default:4
) –Upper cutoff in Hz. Defaults to 4 Hz.
-
sample_rate
(float
, default:1000
) –Sample rate in Hz. Defaults to 1000 Hz.
-
order
(int
, default:3
) –Filter order. Defaults to 3 (3rd order Butterworth filter).
-
axis
(int
, default:-1
) –Axis to apply against. Defaults to -1.
-
forward_backward
(bool
, default:True
) –Apply filter forward and backward. Defaults to True.
Returns:
-
NDArray
–npt.NDArray: Cleaned signal
Source code in physiokit/ppg/clean.py
physiokit.ppg.metrics
compute_heart_rate(data, sample_rate=1000, method='fft', **kwargs)
Compute heart rate in BPM from PPG signal.
Parameters:
-
data
(array
) –PPG signal.
-
sample_rate
(float
, default:1000
) –Sampling rate in Hz. Defaults to 1000 Hz.
-
method
(str
, default:'fft'
) –Method to compute heart rate. Defaults to 'fft'.
-
**kwargs
(dict
, default:{}
) –Keyword arguments to pass to method.
Returns:
Source code in physiokit/ppg/metrics.py
compute_heart_rate_from_fft(data, sample_rate=1000, lowcut=0.5, highcut=4.0)
Compute heart rate from FFT of PPG signal.
Parameters:
-
data
(array
) –PPG signal.
-
sample_rate
(float
, default:1000
) –Sampling rate in Hz. Defaults to 1000 Hz.
-
lowcut
(float
, default:0.5
) –Lowcut frequency in Hz. Defaults to 0.5 Hz.
-
highcut
(float
, default:4.0
) –Highcut frequency in Hz. Defaults to 4.0 Hz.
Returns:
Source code in physiokit/ppg/metrics.py
compute_heart_rate_from_peaks(data, sample_rate=1000, min_rr=0.3, max_rr=2.0, min_delta=0.3)
Compute heart rate from peaks of PPG signal.
Parameters:
-
data
(array
) –PPG signal.
-
sample_rate
(float
, default:1000
) –Sampling rate in Hz. Defaults to 1000 Hz.
-
min_rr
(float
, default:0.3
) –Minimum RR interval in seconds. Defaults to 0.3 s.
-
max_rr
(float
, default:2.0
) –Maximum RR interval in seconds. Defaults to 2.0 s.
-
min_delta
(float
, default:0.3
) –Minimum RR interval delta. Defaults to 0.3.
Returns:
Source code in physiokit/ppg/metrics.py
compute_spo2_from_perfusion(dc1, ac1, dc2, ac2, coefs=(1, 0, 0))
Compute SpO2 from ratio of perfusion indexes (AC/DC).
Device Coefficients
- MAX30101: [1.5958422, -34.6596622, 112.6898759]
- MAX8614X: [-16.666666, 8.333333, 100]
Parameters:
-
dc1
(float
) –DC component of 1st PPG signal (e.g RED).
-
ac1
(float
) –AC component of 1st PPG signal (e.g RED).
-
dc2
(float
) –DC component of 2nd PPG signal (e.g. IR).
-
ac2
(float
) –AC component of 2nd PPG signal (e.g. IR).
-
coefs
(tuple[float, float, float]
, default:(1, 0, 0)
) –Calibration coefficients. Defaults to (1, 0, 0).
Returns:
-
float
(float
) –SpO2 value clipped to [50, 100].
Source code in physiokit/ppg/metrics.py
compute_spo2_in_frequency(ppg1, ppg2, coefs=(1, 0, 0), sample_rate=1000, lowcut=0.5, highcut=4.0, order=3)
Compute SpO2 from PPG signals in frequency domain.
Parameters:
-
ppg1
(array
) –1st PPG signal (e.g RED).
-
ppg2
(array
) –2nd PPG signal (e.g. IR).
-
coefs
(tuple[float, float, float]
, default:(1, 0, 0)
) –Calibration coefficients. Defaults to (1, 0, 0).
-
sample_rate
(float
, default:1000
) –Sampling rate in Hz. Defaults to 1000 Hz.
-
lowcut
(float
, default:0.5
) –Lowcut frequency in Hz. Defaults to 0.5 Hz.
-
highcut
(float
, default:4.0
) –Highcut frequency in Hz. Defaults to 4.0 Hz.
-
order
(int
, default:3
) –Order of filter. Defaults to 3.
Returns:
-
float
(float
) –SpO2 value
Source code in physiokit/ppg/metrics.py
compute_spo2_in_time(ppg1, ppg2, coefs=(1, 0, 0), sample_rate=1000, lowcut=0.5, highcut=4, order=3)
Compute SpO2 from PPG signals in time domain.
Parameters:
-
ppg1
(array
) –1st PPG signal (e.g RED).
-
ppg2
(array
) –2nd PPG signal (e.g. IR).
-
coefs
(tuple[float, float, float]
, default:(1, 0, 0)
) –Calibration coefficients. Defaults to (1, 0, 0).
-
sample_rate
(float
, default:1000
) –Sampling rate in Hz. Defaults to 1000 Hz.
-
lowcut
(float
, default:0.5
) –Lowcut frequency in Hz. Defaults to 0.5 Hz.
-
highcut
(float
, default:4
) –Highcut frequency in Hz. Defaults to 4.0 Hz.
-
order
(int
, default:3
) –Order of filter. Defaults to 3.
Returns:
-
float
(float
) –SpO2 value
Source code in physiokit/ppg/metrics.py
derive_respiratory_rate(ppg, peaks, troughs=None, rri=None, sample_rate=1000, method='rifv', lowcut=0.1, highcut=1.0, order=3, threshold=0.85, interpolate_method='linear')
Derive respiratory rate from PPG signal using given method.
Parameters:
-
ppg
(array
) –PPG signal.
-
peaks
(array
) –Peaks of PPG signal.
-
troughs
(array
, default:None
) –Troughs of PPG signal. Defaults to None.
-
rri
(array
, default:None
) –Respiratory interval. Defaults to None.
-
sample_rate
(float
, default:1000
) –Sampling rate in Hz. Defaults to 1000 Hz.
-
method
(str
, default:'rifv'
) –Method to compute respiratory rate. Defaults to 'riav'.
-
lowcut
(float
, default:0.1
) –Lowcut frequency in Hz. Defaults to 0.1 Hz.
-
highcut
(float
, default:1.0
) –Highcut frequency in Hz. Defaults to 1.0 Hz.
-
order
(int
, default:3
) –Order of filter. Defaults to 3.
-
threshold
(float
, default:0.85
) –Threshold for peak detection. Defaults to 0.85.
-
interpolate_method
(str
, default:'linear'
) –Interpolation method. Defaults to 'linear'.
Returns:
Source code in physiokit/ppg/metrics.py
physiokit.ppg.peaks
compute_rr_intervals(peaks)
Compute RR intervals from R peaks.
Parameters:
-
peaks
(array
) –R peaks.
Returns:
-
NDArray
–npt.NDArray: RR intervals.
Source code in physiokit/ppg/peaks.py
filter_peaks(peaks, sample_rate=1000, min_rr=0.3, max_rr=2.0, min_delta=0.3)
Filter out peaks with RR intervals outside of normal range.
Parameters:
-
peaks
(array
) –Systolic peaks.
-
sample_rate
(float
, default:1000
) –Sampling rate in Hz. Defaults to 1000 Hz.
-
min_rr
(float
, default:0.3
) –Minimum RR interval in seconds. Defaults to 0.3 s.
-
max_rr
(float
, default:2.0
) –Maximum RR interval in seconds. Defaults to 2.0 s.
-
min_delta
(float
, default:0.3
) –Minimum RR interval delta. Defaults to 0.3.
Returns:
-
NDArray
–npt.NDArray: Filtered peaks.
Source code in physiokit/ppg/peaks.py
filter_rr_intervals(rr_ints, sample_rate=1000, min_rr=0.3, max_rr=2.0, min_delta=0.3)
Filter out peaks with RR intervals outside of normal range.
Parameters:
-
rr_ints
(array
) –RR intervals.
-
sample_rate
(float
, default:1000
) –Sampling rate in Hz. Defaults to 1000 Hz.
-
min_rr
(float
, default:0.3
) –Minimum RR interval in seconds. Defaults to 0.3 s.
-
max_rr
(float
, default:2.0
) –Maximum RR interval in seconds. Defaults to 2.0 s.
-
min_delta
(float
, default:0.3
) –Minimum RR interval delta. Defaults to 0.3.
Returns:
-
NDArray
–npt.NDArray: Filtered RR intervals.
Source code in physiokit/ppg/peaks.py
find_peaks(data, sample_rate=1000, peak_window=0.111, beat_window=0.667, beat_offset=0.02, peak_delay=0.3)
Find systolic peaks in PPG signal.
Implementation based on Elgendi M, Norton I, Brearley M, Abbott D, Schuurmans D (2013) Systolic Peak Detection in Acceleration Photoplethysmograms Measured from Emergency Responders in Tropical Conditions. PLoS ONE 8(10): e76585. doi:10.1371/journal.pone.0076585. Assumes input data is bandpass filtered with a lowcut of .5 Hz and a highcut of 8 Hz.
Parameters:
-
data
(array
) –PPG signal.
-
sample_rate
(float
, default:1000
) –Sampling rate in Hz. Defaults to 1000 Hz.
-
peak_window
(float
, default:0.111
) –Peak window in seconds. Defaults to 0.111 s.
-
beat_window
(float
, default:0.667
) –Beat window in seconds. Defaults to 0.667 s.
-
beat_offset
(float
, default:0.02
) –Beat offset in seconds. Defaults to 0.02 s.
-
peak_delay
(float
, default:0.3
) –Peak delay in seconds. Defaults to 0.3 s.
Returns:
-
NDArray
–npt.NDArray: Peak locations.
Source code in physiokit/ppg/peaks.py
physiokit.ppg.synthesize
synthesize(signal_length=10000, sample_rate=1000, heart_rate=60, frequency_modulation=0.3, ibi_randomness=0.1)
Generate synthetic PPG signal. Utilize pk.signal.noise methods to make more realistic.
Parameters:
-
signal_length
(int
, default:10000
) –Length of signal in samples. Defaults to 10000.
-
sample_rate
(float
, default:1000
) –Sample rate in Hz. Defaults to 1000 Hz.
-
heart_rate
(float
, default:60
) –Heart rate in BPM. Defaults to 60 BPM.
-
frequency_modulation
(float
, default:0.3
) –Frequency modulation strength [0,1]. Defaults to 0.3.
-
ibi_randomness
(float
, default:0.1
) –IBI randomness in range [0,1]. Defaults to 0.1.
Returns:
-
tuple[NDArray, NDArray, NDArray]
–npt.NDArray: Synthetic PPG, segmentation mask, fiducial mask