def test_to_epochs(self): """Test oxi_peaks function""" ppg = import_ppg('1')[0, :] # Import PPG recording events = import_ppg('1')[1, :] # Import events events[2] = 1 epochs = to_epochs(ppg, events, sfreq=75, verbose=True, apply_baseline=(-1, 0)) assert epochs.ndim == 2 epochs = to_epochs(list(ppg), list(events), sfreq=75, apply_baseline=None) reject = np.arange(0, len(ppg)) reject[50:55] = 1 epochs = to_epochs(ppg, events, sfreq=75, apply_baseline=-1, reject=reject, verbose=True) with pytest.raises(ValueError): epochs = to_epochs(ppg[1:], events, sfreq=75)
def test_to_rr(self): ppg = import_ppg().ppg.to_numpy() signal, peaks = oxi_peaks(ppg) rr = to_rr(peaks) assert rr.mean() == 874.2068965517242 rr = to_rr(np.where(peaks)[0]) assert rr.mean() == 874.2068965517242
def test_interpolate_clipping(self): df = import_ppg() clean_signal = interpolate_clipping(df.ppg.to_numpy()) assert clean_signal.mean().round() == 100 clean_signal = interpolate_clipping(list(df.ppg.to_numpy())) assert clean_signal.mean().round() == 100 clean_signal = interpolate_clipping(df.ppg.to_numpy()) df.ppg.iloc[0], df.ppg.iloc[-1] = 255, 255 clean_signal = interpolate_clipping(df.ppg.to_numpy())
def test_interpolate_clipping(self): ppg = import_ppg('1')[0] clean_signal = interpolate_clipping(ppg) assert clean_signal.mean().round() == 100 clean_signal = interpolate_clipping(list(ppg)) assert clean_signal.mean().round() == 100 clean_signal = interpolate_clipping(ppg) ppg[0], ppg[-1] = 255, 255 clean_signal = interpolate_clipping(ppg)
def test_norm_triggers(self): ppg = import_ppg('1')[0, :] # Import PPG recording signal, peaks = oxi_peaks(ppg) peaks[np.where(peaks)[0] + 1] = 1 peaks[np.where(peaks)[0] + 2] = 1 y = norm_triggers(peaks) assert sum(y) == 378 peaks = -peaks y = norm_triggers(peaks, threshold=-1, direction='lower') assert sum(y) == 378
def test_to_angle(self): """Test to_angles function""" rr = import_rr().rr.values # Create event vector events = rr + np.random.normal(500, 100, len(rr)) ang = to_angles(list(np.cumsum(rr)), list(np.cumsum(events))) assert ~np.any(np.asarray(ang) < 0) assert ~np.any(np.asarray(ang) > np.pi * 2) ppg = import_ppg('1')[0, :] # Import PPG recording signal, peaks = oxi_peaks(ppg) ang = to_angles(peaks, peaks)
def test_heart_rate(self): """Test heart_rate function""" ppg = import_ppg('1')[0, :] # Import PPG recording signal, peaks = oxi_peaks(ppg) heartrate, time = heart_rate(peaks) assert len(heartrate) == len(time) heartrate, time = heart_rate(list(peaks)) assert len(heartrate) == len(time) heartrate, time = heart_rate(peaks, unit='bpm', kind='cubic', sfreq=500) assert len(heartrate) == len(time)
def test_norm_triggers(self): ppg = import_ppg('1')[0, :] # Import PPG recording signal, peaks = oxi_peaks(ppg) peaks[np.where(peaks)[0] + 1] = 1 peaks[np.where(peaks)[0] + 2] = 1 peaks[-1:] = 1 y = norm_triggers(peaks) assert sum(y) == 379 peaks = -peaks.astype(int) y = norm_triggers(peaks, threshold=-1, direction='lower') assert sum(y) == 379 with pytest.raises(ValueError): norm_triggers(None) with pytest.raises(ValueError): norm_triggers(peaks, direction='invalid')
def test_heart_rate(self): """Test heart_rate function""" ppg = import_ppg().ppg.to_numpy() # Import PPG recording signal, peaks = oxi_peaks(ppg) heartrate, time = heart_rate(peaks) assert len(heartrate) == len(time) heartrate, time = heart_rate(list(peaks)) assert len(heartrate) == len(time) heartrate, time = heart_rate(peaks, unit='bpm', kind='cubic', sfreq=500) assert len(heartrate) == len(time) with pytest.raises(ValueError): heartrate, time = heart_rate([1, 2, 3])
# Author: Nicolas Legrand <*****@*****.**> # Licence: GPL v3 #%% import plotly from systole.detection import rr_artefacts from systole import import_rr, import_ppg from systole.plotly import plot_subspaces, plot_frequency, plot_raw,\ plot_timedomain, plot_nonlinear #%% # Raw data # -------- # ppg = import_ppg()[0] plot_raw(ppg) #%% # HRV analyses # ------------ rr = import_rr().rr.values #%% # Frequency domain # ---------------- plot1 = plot_timedomain(rr) plotly.io.show(plot1) #%%
def test_to_epochs(self): """Test oxi_peaks function""" ppg = import_ppg('1')[0, :] # Import PPG recording events = import_ppg('1')[1, :] # Import events epochs = to_epochs(ppg, events, sfreq=75) assert epochs.ndim == 2
import matplotlib.pyplot as plt from systole import import_ppg from systole.detection import interpolate_clipping df = import_ppg() clean_signal = interpolate_clipping(df.ppg.to_numpy()) plt.plot(df.time, clean_signal, color='#F15854') plt.plot(df.time, df.ppg, color='#5DA5DA') plt.axhline(y=255, linestyle='--', color='k') plt.xlabel('Time (s)') plt.ylabel('PPG level (a.u)')
def report_oxi(signal, file_name='report.png', dpi=600): """Generate HRV report. Parameters ---------- signal : 1d array-like PPG singal. file_name : str Output file name. dpi : int Image quality. """ from systole import import_ppg signal = import_ppg('1')[0] plot_oximeter(signal) # Find peaks signal, peaks = oxi_peaks(signal) # Extract instantaneous heartrate sfreq = 1000 noisy_hr, time = heart_rate(peaks, sfreq=sfreq, unit='bpm', kind='cubic') time = np.arange(0, len(signal) / sfreq, 1 / sfreq) fig = plt.figure(figsize=(8, 13)) gs = fig.add_gridspec(4, 3) fig_ax1 = fig.add_subplot(gs[0, :]) fig_ax1.plot(time, signal, linewidth=.2) fig_ax1.set_ylabel('PPG level') fig_ax1.set_xlim(0, time[-1]) fig_ax1.set_title('Signal', fontweight='bold') fig_ax2 = fig.add_subplot(gs[1, :]) fig_ax2.plot(time, noisy_hr, linewidth=.8, color='r') fig_ax2.set_ylabel('BPM') fig_ax2.set_xlabel('Time (s)') fig_ax2.set_xlim(0, time[-1]) fig_ax2.set_title('RR time-course', fontweight='bold') # HRV rr = np.diff(np.where(peaks)[0]) fig_ax3 = fig.add_subplot(gs[2, 0]) fig_ax3.hist(rr, bins=30, alpha=.5) fig_ax3.hist(rr[(rr <= 400) | (rr >= 1500)], bins=30, color='r') fig_ax3.set_title('Distribution', fontweight='bold') fig_ax3.set_ylabel('Count') fig_ax3.set_xlabel('RR(s)') fig_ax4 = fig.add_subplot(gs[2, 1]) plot_psd(rr, show=True, ax=fig_ax4) fig_ax5 = fig.add_subplot(gs[2, 2]) fig_ax5.plot(rr[:-1], rr[1:], color='gray', markersize=1, alpha=0.8) fig_ax5.set_title('Pointcare Plot', fontweight='bold') fig_ax5.set_ylabel('$RR_{n+1}$') fig_ax5.set_xlabel('$RR_n$') plt.tight_layout(h_pad=0.05) if file_name is not None: plt.savefig(file_name, dpi=dpi) plt.close()
import pandas as pd import unittest import pytest import matplotlib from unittest import TestCase from systole.plotting import plot_hr, plot_events, plot_oximeter,\ plot_subspaces, circular, plot_circular, plot_psd from systole import import_ppg, import_rr, serialSim from systole.recording import Oximeter serial = serialSim() oxi = Oximeter(serial=serial, add_channels=1).setup().read(10) oxi.channels['Channel_0'][100] = 1 # Simulate oximeter instance from recorded signal ppg = import_ppg().ppg.to_numpy() oxi = Oximeter(serial=None, add_channels=1) oxi.threshold = [0] * 75 oxi.peaks = [0] * 75 oxi.instant_rr = [0] * 75 oxi.recording = list(ppg[:75]) for i in range(len(ppg[75:750])): oxi.add_paquet(ppg[75 + i]) oxi.channels['Channel_0'] = np.zeros(750, dtype=int) oxi.channels['Channel_0'][np.random.choice(np.arange(0, 750), 5)] = 1 oxi.times = list(np.arange(0, 10, 1 / 75)) # Create angular data x = np.random.normal(np.pi, 0.5, 100) y = np.random.uniform(0, np.pi * 2, 100) z = np.concatenate([
def test_report_oxi(self): ppg = import_ppg('1')[0, :] # Import PPG recording report_oxi(ppg, file_name=None)
def test_oxi_peaks(self): """Test oxi_peaks function""" ppg = import_ppg('1')[0, :] # Import PPG recording signal, peaks = oxi_peaks(ppg) assert len(signal) == len(peaks) assert np.all(np.unique(peaks) == [0, 1])
def test_oxi_peaks(self): """Test oxi_peaks function""" df = import_ppg() # Import PPG recording signal, peaks = oxi_peaks(df.ppg.to_numpy()) assert len(signal) == len(peaks) assert np.all(np.unique(peaks) == [0, 1])