def test_rsp_rrv(): rsp90 = nk.rsp_simulate(duration=60, sampling_rate=1000, respiratory_rate=90, random_state=42) rsp110 = nk.rsp_simulate(duration=60, sampling_rate=1000, respiratory_rate=110, random_state=42) cleaned90 = nk.rsp_clean(rsp90, sampling_rate=1000) _, peaks90 = nk.rsp_peaks(cleaned90) rsp_rate90 = nk.rsp_rate(peaks90, desired_length=len(rsp90)) cleaned110 = nk.rsp_clean(rsp110, sampling_rate=1000) _, peaks110 = nk.rsp_peaks(cleaned110) rsp_rate110 = nk.rsp_rate(peaks110, desired_length=len(rsp110)) rsp90_rrv = nk.rsp_rrv(rsp_rate90, peaks90) rsp110_rrv = nk.rsp_rrv(rsp_rate110, peaks110) assert np.array(rsp90_rrv["RRV_SDBB"]) < np.array(rsp110_rrv["RRV_SDBB"]) assert np.array(rsp90_rrv["RRV_RMSSD"]) < np.array(rsp110_rrv["RRV_RMSSD"]) assert np.array(rsp90_rrv["RRV_SDSD"]) < np.array(rsp110_rrv["RRV_SDSD"]) # assert np.array(rsp90_rrv["RRV_pNN50"]) == np.array(rsp110_rrv["RRV_pNN50"]) == np.array(rsp110_rrv["RRV_pNN20"]) == np.array(rsp90_rrv["RRV_pNN20"]) == 0 # assert np.array(rsp90_rrv["RRV_TINN"]) < np.array(rsp110_rrv["RRV_TINN"]) # assert np.array(rsp90_rrv["RRV_HTI"]) > np.array(rsp110_rrv["RRV_HTI"]) assert np.array(rsp90_rrv["RRV_HF"]) < np.array(rsp110_rrv["RRV_HF"]) assert np.array(rsp90_rrv["RRV_LF"]) < np.array(rsp110_rrv["RRV_LF"])
def test_rsp_clean(): sampling_rate = 100 duration = 120 rsp = nk.rsp_simulate(duration=duration, sampling_rate=sampling_rate, respiratory_rate=15, noise=0.1, random_state=42) # Add linear drift (to test baseline removal). rsp += nk.signal_distort(rsp, sampling_rate=sampling_rate, linear_drift=True) khodadad2018 = nk.rsp_clean(rsp, sampling_rate=sampling_rate, method="khodadad2018") assert len(rsp) == len(khodadad2018) rsp_biosppy = nk.rsp_clean(rsp, sampling_rate=sampling_rate, method="biosppy") assert len(rsp) == len(rsp_biosppy) # Check if filter was applied. fft_raw = np.abs(np.fft.rfft(rsp)) fft_khodadad2018 = np.abs(np.fft.rfft(khodadad2018)) fft_biosppy = np.abs(np.fft.rfft(rsp_biosppy)) freqs = np.fft.rfftfreq(len(rsp), 1 / sampling_rate) assert np.sum(fft_raw[freqs > 3]) > np.sum(fft_khodadad2018[freqs > 3]) assert np.sum(fft_raw[freqs < 0.05]) > np.sum( fft_khodadad2018[freqs < 0.05]) assert np.sum(fft_raw[freqs > 0.35]) > np.sum(fft_biosppy[freqs > 0.35]) assert np.sum(fft_raw[freqs < 0.1]) > np.sum(fft_biosppy[freqs < 0.1]) # Comparison to biosppy (https://github.com/PIA-Group/BioSPPy/blob/master/biosppy/signals/resp.py#L62) rsp_biosppy = nk.rsp_clean(rsp, sampling_rate=sampling_rate, method="biosppy") original, _, _ = biosppy.tools.filter_signal(signal=rsp, ftype="butter", band="bandpass", order=2, frequency=[0.1, 0.35], sampling_rate=sampling_rate) original = nk.signal_detrend(original, order=0) assert np.allclose((rsp_biosppy - original).mean(), 0, atol=1e-6)
def test_signal_rate(): # since singal_rate wraps signal_period, the latter is tested as well # Test with array. duration = 10 sampling_rate = 1000 signal = nk.signal_simulate(duration=duration, sampling_rate=sampling_rate, frequency=1) info = nk.signal_findpeaks(signal) rate = nk.signal_rate(peaks=info["Peaks"], sampling_rate=1000, desired_length=len(signal)) assert rate.shape[0] == duration * sampling_rate # Test with dictionary.produced from signal_findpeaks. assert info[list(info.keys())[0]].shape == (info["Peaks"].shape[0],) # Test with DataFrame. duration = 120 sampling_rate = 1000 rsp = nk.rsp_simulate( duration=duration, sampling_rate=sampling_rate, respiratory_rate=15, method="sinuosoidal", noise=0 ) rsp_cleaned = nk.rsp_clean(rsp, sampling_rate=sampling_rate) signals, info = nk.rsp_peaks(rsp_cleaned) rate = nk.signal_rate(signals, sampling_rate=sampling_rate, desired_length=duration * sampling_rate) assert rate.shape == (signals.shape[0],) # Test with dictionary.produced from rsp_findpeaks. rate = nk.signal_rate(info, sampling_rate=sampling_rate, desired_length=duration * sampling_rate) assert rate.shape == (duration * sampling_rate,)
def test_signal_rate(): # Test with array. signal = nk.signal_simulate(duration=10, sampling_rate=1000, frequency=1) info = nk.signal_findpeaks(signal) rate = nk.signal_rate(peaks=info["Peaks"], sampling_rate=1000, desired_length=None) assert rate.shape[0] == len(info["Peaks"]) # Test with dictionary.produced from signal_findpeaks. assert info[list(info.keys())[0]].shape == (info["Peaks"].shape[0], ) # Test with DataFrame. rsp = nk.rsp_simulate(duration=120, sampling_rate=1000, respiratory_rate=15, method="sinuosoidal", noise=0) rsp_cleaned = nk.rsp_clean(rsp, sampling_rate=1000) signals, info = nk.rsp_peaks(rsp_cleaned) rate = nk.signal_rate(signals, sampling_rate=1000) assert rate.shape == (signals.shape[0], ) # Test with dictionary.produced from rsp_findpeaks. test_length = 30 rate = nk.signal_rate(info, sampling_rate=1000, desired_length=test_length) assert rate.shape == (test_length, )
def test_rsp_rrv(): rsp90 = nk.rsp_simulate(duration=60, sampling_rate=1000, respiratory_rate=90, random_state=42) rsp110 = nk.rsp_simulate(duration=60, sampling_rate=1000, respiratory_rate=110, random_state=42) cleaned90 = nk.rsp_clean(rsp90, sampling_rate=1000) _, peaks90 = nk.rsp_peaks(cleaned90) rsp_rate90 = nk.signal_rate(peaks90, desired_length=len(rsp90)) cleaned110 = nk.rsp_clean(rsp110, sampling_rate=1000) _, peaks110 = nk.rsp_peaks(cleaned110) rsp_rate110 = nk.signal_rate(peaks110, desired_length=len(rsp110)) rsp90_rrv = nk.rsp_rrv(rsp_rate90, peaks90) rsp110_rrv = nk.rsp_rrv(rsp_rate110, peaks110) assert np.array(rsp90_rrv["RRV_SDBB"]) < np.array(rsp110_rrv["RRV_SDBB"]) assert np.array(rsp90_rrv["RRV_RMSSD"]) < np.array(rsp110_rrv["RRV_RMSSD"]) assert np.array(rsp90_rrv["RRV_SDSD"]) < np.array(rsp110_rrv["RRV_SDSD"]) # assert np.array(rsp90_rrv["RRV_pNN50"]) == np.array(rsp110_rrv["RRV_pNN50"]) == np.array(rsp110_rrv["RRV_pNN20"]) == np.array(rsp90_rrv["RRV_pNN20"]) == 0 # assert np.array(rsp90_rrv["RRV_TINN"]) < np.array(rsp110_rrv["RRV_TINN"]) # assert np.array(rsp90_rrv["RRV_HTI"]) > np.array(rsp110_rrv["RRV_HTI"]) assert np.array(rsp90_rrv["RRV_HF"]) < np.array(rsp110_rrv["RRV_HF"]) assert np.isnan(rsp90_rrv["RRV_LF"][0]) assert np.isnan(rsp110_rrv["RRV_LF"][0]) # Test warning on too short duration with pytest.warns(nk.misc.NeuroKitWarning, match=r"The duration of recording is too short.*"): short_rsp90 = nk.rsp_simulate(duration=10, sampling_rate=1000, respiratory_rate=90, random_state=42) short_cleaned90 = nk.rsp_clean(short_rsp90, sampling_rate=1000) _, short_peaks90 = nk.rsp_peaks(short_cleaned90) short_rsp_rate90 = nk.signal_rate(short_peaks90, desired_length=len(short_rsp90)) nk.rsp_rrv(short_rsp_rate90, short_peaks90)
def test_rsp_clean(): sampling_rate = 1000 rsp = nk.rsp_simulate(duration=120, sampling_rate=sampling_rate, respiratory_rate=15, random_state=42) khodadad2018 = nk.rsp_clean(rsp, sampling_rate=1000, method="khodadad2018") assert len(rsp) == len(khodadad2018) rsp_biosppy = nk.rsp_clean(rsp, sampling_rate=1000, method="biosppy") assert len(rsp) == len(rsp_biosppy) # Check if filter was applied. fft_raw = np.fft.rfft(rsp) fft_khodadad2018 = np.fft.rfft(khodadad2018) fft_biosppy = np.fft.rfft(rsp_biosppy) freqs = np.fft.rfftfreq(len(rsp), 1 / sampling_rate) # assert np.sum(fft_raw[freqs > 2]) > np.sum(fft_khodadad2018[freqs > 2]) assert np.sum(fft_raw[freqs > 2]) > np.sum(fft_biosppy[freqs > 2]) assert np.sum(fft_khodadad2018[freqs > 2]) > np.sum(fft_biosppy[freqs > 2]) # Check if detrending was applied. assert np.mean(rsp) > np.mean(khodadad2018) # Comparison to biosppy (https://github.com/PIA-Group/BioSPPy/blob/master/biosppy/signals/resp.py#L62) rsp_biosppy = nk.rsp_clean(rsp, sampling_rate=sampling_rate, method="biosppy") original, _, _ = biosppy.tools.filter_signal(signal=rsp, ftype='butter', band='bandpass', order=2, frequency=[0.1, 0.35], sampling_rate=sampling_rate) original = nk.signal_detrend(original, order=0) assert np.allclose((rsp_biosppy - original).mean(), 0, atol=1e-6)
def test_rsp_findpeaks(): rsp = nk.rsp_simulate(duration=120, sampling_rate=1000, respiratory_rate=15) rsp_cleaned = nk.rsp_clean(rsp, sampling_rate=1000) signals, info = nk.rsp_findpeaks(rsp_cleaned, sampling_rate=1000) assert signals.shape == (120000, 2) assert signals["RSP_Peaks"].sum() == 28 assert signals["RSP_Troughs"].sum() == 28 assert info["RSP_Peaks"].shape[0] == 28 assert info["RSP_Troughs"].shape[0] == 28 # assert that extrema start with a trough and end with a peak assert info["RSP_Peaks"][0] > info["RSP_Troughs"][0] assert info["RSP_Peaks"][-1] > info["RSP_Troughs"][-1]
def test_rsp_peaks(): rsp = nk.rsp_simulate(duration=120, sampling_rate=1000, respiratory_rate=15, random_state=42) rsp_cleaned = nk.rsp_clean(rsp, sampling_rate=1000) signals, info = nk.rsp_peaks(rsp_cleaned) assert signals.shape == (120000, 2) assert signals["RSP_Peaks"].sum() == 28 assert signals["RSP_Troughs"].sum() == 28 assert info["RSP_Peaks"].shape[0] == 28 assert info["RSP_Troughs"].shape[0] == 28 assert np.allclose(info["RSP_Peaks"].sum(), 1643817) assert np.allclose(info["RSP_Troughs"].sum(), 1586588) # Assert that extrema start with a trough and end with a peak. assert info["RSP_Peaks"][0] > info["RSP_Troughs"][0] assert info["RSP_Peaks"][-1] > info["RSP_Troughs"][-1]
def test_rsp_amplitude(): rsp = nk.rsp_simulate(duration=120, sampling_rate=1000, respiratory_rate=15, method="sinusoidal", noise=0) rsp_cleaned = nk.rsp_clean(rsp, sampling_rate=1000) signals, info = nk.rsp_peaks(rsp_cleaned) # Test with dictionary. amplitude = nk.rsp_amplitude(rsp, signals) assert amplitude.shape == (rsp.size, ) assert np.abs(amplitude.mean() - 1) < 0.01 # Test with DataFrame. amplitude = nk.rsp_amplitude(rsp, info) assert amplitude.shape == (rsp.size, ) assert np.abs(amplitude.mean() - 1) < 0.01
def respiration_clean(data, column='PZT'): ''' # todo: does this function belong to dsu? Parameters ---------- data column Returns ------- ''' sampling_rate = estimate_rate(data) data.loc[:, column] = nk.rsp_clean(data[column], sampling_rate, method='BioSPPy') return data
def test_rsp_clean(): sampling_rate = 1000 rsp = nk.rsp_simulate(duration=120, sampling_rate=sampling_rate, respiratory_rate=15) signals = nk.rsp_clean(rsp, sampling_rate=1000) assert signals.shape == (120000, 2) # check if filter was applied raw = signals["RSP_Raw"] clean = signals["RSP_Filtered"] fft_raw = np.fft.rfft(raw) fft_clean = np.fft.rfft(clean) freqs = np.fft.rfftfreq(len(raw), 1/sampling_rate) assert np.sum(fft_raw[freqs > 2]) > np.sum(fft_clean[freqs > 2]) # check if detrending was applied assert np.mean(raw) > np.mean(clean)
def test_rsp_rate(): rsp = nk.rsp_simulate(duration=120, sampling_rate=1000, respiratory_rate=15, method="sinusoidal", noise=0) rsp_cleaned = nk.rsp_clean(rsp, sampling_rate=1000) signals, info = nk.rsp_peaks(rsp_cleaned) # Test with dictionary. test_length = 30 rate = nk.rsp_rate(peaks=info, sampling_rate=1000, desired_length=test_length) assert rate.shape == (test_length, ) assert np.abs(rate.mean() - 15) < 0.2 # Test with DataFrame. rate = nk.rsp_rate(signals, sampling_rate=1000) assert rate.shape == (signals.shape[0], ) assert np.abs(rate.mean() - 15) < 0.2
def test_rsp_rate(): rsp = nk.rsp_simulate(duration=120, sampling_rate=1000, respiratory_rate=15) rsp_cleaned = nk.rsp_clean(rsp, sampling_rate=1000) signals, info = nk.rsp_findpeaks(rsp_cleaned, sampling_rate=1000) # vary desired_lenght over tests # test with peaks only test_length = 30 data = nk.rsp_rate(info["RSP_Peaks"], sampling_rate=1000, desired_length=test_length) assert data.shape == (test_length, 2) assert np.abs(data["RSP_Rate"].mean() - 15) < 0.2 assert np.abs(data["RSP_Period"].mean() - 4) < 0.1 # test with peaks and troughs passed in separately test_length = 300 data = nk.rsp_rate(peaks=info["RSP_Peaks"], troughs=info["RSP_Troughs"], sampling_rate=1000, desired_length=test_length) assert data.shape == (test_length, 3) assert np.abs(data["RSP_Rate"].mean() - 15) < 0.2 assert np.abs(data["RSP_Period"].mean() - 4) < 0.1 assert np.abs(data["RSP_Amplitude"].mean() - 2086) < 0.5 # test with DataFrame containing peaks and troughs data = nk.rsp_rate(signals, sampling_rate=1000) assert data.shape == (signals.shape[0], 3) assert np.abs(data["RSP_Rate"].mean() - 15) < 0.2 assert np.abs(data["RSP_Period"].mean() - 4) < 0.1 assert np.abs(data["RSP_Amplitude"].mean() - 2087) < 0.5 # test with dict containing peaks and troughs test_length = 30000 data = nk.rsp_rate(info, sampling_rate=1000, desired_length=test_length) assert data.shape == (test_length, 3) assert np.abs(data["RSP_Rate"].mean() - 15) < 0.2 assert np.abs(data["RSP_Period"].mean() - 4) < 0.1 assert np.abs(data["RSP_Amplitude"].mean() - 2087) < 0.5