Respiratory (RSP)
Respiratory rate is often measured on the chest using a respiration belt or a respiratory inductance plethysmography (RIP) sensor. physioKIT provides a set of functions to process RSP signals. The functions can be used to generate synthetic RSP signals, clean noisy RSP signals, extract respiratory peaks, compute respiratory rate, and compute dual band metrics.
The snippets below form a walkthrough: later snippets may reuse variables from earlier ones. The plots are saved example outputs. For a standalone runnable example, start with the quickstart.
Synthetic RSP
Section titled “Synthetic RSP”We can generate a synthetic RSP signal using the rsp.synthesize function. The function returns three NumPy arrays: the RSP waveform, segmentation mask, and fiducial mask. The signal_length parameter specifies the number of samples. The sample_rate parameter specifies the sampling rate in Hz. The respiratory_rate parameter specifies the respiratory rate in breaths per minute (BPM).
In the following snippet, we generate a synthetic RSP inductance band signal with a respiratory rate of 12 BPM sampled at 1000 Hz.
import physiokit as pk
sample_rate = 1000 # Hzrespiratory_rate = 12 # BPMsignal_length = 10 * sample_rate # 10 seconds
rsp, segs, fids = pk.rsp.synthesize( signal_length=signal_length, sample_rate=sample_rate, respiratory_rate=respiratory_rate,)Noise Injection
Section titled “Noise Injection”We can additionally add noise to generate a more realistic RSP signal.
Below adds baseline wander, powerline noise, and custom noise sources to the synthetic RSP signal.
# Add baseline wanderrsp_noise = pk.signal.add_baseline_wander( data=rsp, amplitude=2, frequency=.05, sample_rate=sample_rate)
# Add powerline noisersp_noise = pk.signal.add_powerline_noise( data=rsp_noise, amplitude=0.05, frequency=60, sample_rate=sample_rate)
# Add additional noise sourcesrsp_noise = pk.signal.add_noise_sources( data=rsp_noise, amplitudes=[0.05, 0.05], frequencies=[10, 20], noise_shapes=["laplace", "laplace"], sample_rate=sample_rate)Sanitize RSP
Section titled “Sanitize RSP”We can clean the RSP signal using the rsp.clean function. By default, the routine implements a bandpass filter with cutoff frequencies of 0.05 Hz and 3 Hz. The lowcut and highcut parameters can be used to specify the cutoff frequencies. The order parameter specifies the order of the filter. The sample_rate parameter specifies the sampling rate in Hz. The function returns a numpy array with the cleaned RSP signal.
In the following snippet, we clean the noisy RSP signal using a bandpass filter with cutoff frequencies of 0.05 Hz and 3 Hz.
...
# Clean RSP signalrsp_clean = pk.rsp.clean( data=rsp_noise, lowcut=0.05, highcut=3, order=3, sample_rate=sample_rate)Extract Respiratory Peaks
Section titled “Extract Respiratory Peaks”A common task in RSP processing is to extract respiratory peaks. The rsp.find_peaks function implements a simple peak detection algorithm. The function returns a numpy array with the indices of the peaks.
In the following snippet, we extract respiratory peaks from the cleaned RSP signal.
...
# Extract respiratory cyclespeaks = pk.rsp.find_peaks(data=rsp_clean, sample_rate=sample_rate)
# Compute RR-intervalsrri = pk.rsp.compute_rr_intervals(peaks=peaks)
# Filter RR-intervalsmask = pk.rsp.filter_rr_intervals(rr_ints=rri, sample_rate=sample_rate)
# Keep normal RR-intervalspeaks_clean = peaks[mask == 0]rri_clean = rri[mask == 0]Compute Respiratory Rate
Section titled “Compute Respiratory Rate”The rsp.compute_respiratory_rate function computes the respiratory rate in breaths per minute (BPM) based on the selected method. The peak method computes respiratory rate based on identified respiratory peaks whereas fft method uses FFT to compute the respiratory rate. The function returns the respiratory rate in breaths per minute (BPM) along with a “quality of signal” (QoS) metric. The QoS metric is based on the selected method.
In the following snippet, we compute the respiratory rate from the cleaned waveform using the FFT method.
# Compute respiratory raterr_bpm, rr_qos = pk.rsp.compute_respiratory_rate( data=rsp_clean, method="fft", sample_rate=sample_rate, lowcut=0.05, highcut=1)Example output:
Respiratory rate: 12 BPM
Compute Dual Band Metrics
Section titled “Compute Dual Band Metrics”Using dual RIP bands, a ribcage (RC) band and an abdominal (AB) band, we can compute additional respiratory metrics. The rsp.compute_dual_band_metrics function computes the following metrics:
| Metric | Description |
|---|---|
| rc_rr | RC respiratory rate (BPM) |
| ab_rr | AB respiratory rate (BPM) |
| vt_rr | VT respiratory rate (BPM) |
| phase | Phase angle (degrees) |
| lbi | Labored breathing index |
| rc_lead | RC leads AB |
| rc_percent | Percent RC contribution |
| qos | Quality of signal (0-1) |
| rc_pk_freq | RC peak frequency (Hz) |
| rc_pk_pwr | RC peak power |
| ab_pk_freq | AB peak frequency (Hz) |
| ab_pk_pwr | AB peak power |
| vt_pk_freq | VT peak frequency (Hz) |
| vt_pk_pwr | VT peak power |
In the following example, we generate synthetic RC and AB band data, compute the dual band metrics, and plot the results. We compute the metrics over a sliding window with a length of 10 seconds and an overlap of 1 second.
sample_rate = 1000respiratory_rate = 12.2rc_amp = 1.5ab_amp = 1.0dur_sec = 60win_len = 10*sample_rateovl_len = 1*sample_rate
# Synthesize RC and AB band datarc, segs, fids = pk.rsp.synthesize( signal_length=dur_sec*sample_rate, sample_rate=sample_rate, respiratory_rate=respiratory_rate)rc = rc * rc_amp
ab, segs, fids = pk.rsp.synthesize( signal_length=dur_sec*sample_rate, sample_rate=sample_rate, respiratory_rate=respiratory_rate)ab = ab * ab_amp
# Compute metrics over sliding windowts_metrics, dual_metrics = [], []for i in range(0, rc.size - win_len, ovl_len): rc_win = rc[i:i+win_len] ab_win = ab[i:i+win_len] ts_metrics.append((i+win_len/2)/sample_rate) dual_metrics.append(pk.rsp.compute_dual_band_metrics( rc=rc_win, ab=ab_win, sample_rate=sample_rate, pwr_threshold=0.9 ))