Source code for neurokit2.rsp.rsp_amplitude

# -*- coding: utf-8 -*-

import numpy as np

from ..signal import signal_interpolate
from .rsp_fixpeaks import _rsp_fixpeaks_retrieve


[docs] def rsp_amplitude( rsp_cleaned, peaks, troughs=None, method="standard", interpolation_method="monotone_cubic" ): """**Compute respiratory amplitude** Compute respiratory amplitude given the raw respiration signal and its extrema. The **standard** method computes the amplitude as the difference between a peak and its preceding trough, while the **prepost** method computes the amplitude as the average of the differences of peak to its preceding and succeeding troughs (Cole, 2019). Parameters ---------- rsp_cleaned : Union[list, np.array, pd.Series] The cleaned respiration channel as returned by :func:`.rsp_clean`. peaks : list or array or DataFrame or Series or dict The samples at which the respiration peaks (exhalation onsets) occur. If a dict or a DataFrame is passed, it is assumed that these containers were obtained with :func:`rsp_findpeaks`. troughs : list or array or DataFrame or Series or dict The samples at which the respiration troughs (inhalation onsets) occur. If a dict or a is passed, it is assumed that these containers were obtained with :func:`.rsp_findpeaks`. method : str The method to use to compute the amplitude. Can be ``"standard"`` or ``"prepost"``. interpolation_method : str Method used to interpolate the amplitude between peaks. See :func:`.signal_interpolate`. ``"monotone_cubic"`` is chosen as the default interpolation method since it ensures monotone interpolation between data point (i.e., it prevents physiologically implausible "overshoots" or "undershoots" in the y-direction). In contrast, the widely used cubic spline 'interpolation does not ensure monotonicity. Returns ------- array A vector containing the respiratory amplitude. See Also -------- rsp_clean, rsp_peaks, signal_rate, rsp_process, rsp_plot, rsp_symmetry Examples -------- .. ipython:: python import neurokit2 as nk rsp = nk.rsp_simulate(duration=90, respiratory_rate=15) cleaned = nk.rsp_clean(rsp, sampling_rate=1000) peak_signals, info = nk.rsp_peaks(cleaned) amplitude = nk.rsp_amplitude(cleaned, peak_signals) @savefig p_rsp_amp1.png scale=100% fig = nk.signal_plot([rsp, amplitude], labels=["RSP", "Amplitude"], subplots=True) @suppress plt.close() .. ipython:: python amp2 = nk.rsp_amplitude(cleaned, peak_signals, method="prepost") @savefig p_rsp_amp2.png scale=100% fig = nk.signal_plot([amplitude, amp2], labels=["Standard", "Prepost"]) @suppress plt.close() References ---------- * Cole, S., & Voytek, B. (2019). Cycle-by-cycle analysis of neural oscillations. Journal of neurophysiology, 122(2), 849-861. """ # Format input. peaks, troughs = _rsp_fixpeaks_retrieve(peaks, troughs) # To consistently calculate amplitude, peaks and troughs must have the same # number of elements, and the first trough must precede the first peak. if (peaks.size != troughs.size) or (peaks[0] <= troughs[0]): raise TypeError( "NeuroKit error: Please provide one of the containers ", "returned by `rsp_findpeaks()` as `extrema` argument and do ", "not modify its content.", ) # Calculate amplitude in units of the raw signal, based on vertical # difference of each peak to the preceding trough. amplitude = rsp_cleaned[peaks] - rsp_cleaned[troughs] # The above is the standard amplitude (each peak height to the preceding trough). if method in ["prepost"]: # Alternative amplitude calculation that corresponds to the average of # the peak height to the preceding and following troughs. # https://twitter.com/bradleyvoytek/status/1591495571269124096/photo/1 # (Note that it cannot be done for the last peak) amplitude[0:-1] += rsp_cleaned[peaks[0:-1]] - rsp_cleaned[troughs[1::]] amplitude[0:-1] /= 2 # Interpolate amplitude to length of rsp_cleaned. if len(peaks) == 1: amplitude = np.full(rsp_cleaned.shape, amplitude[0]) else: amplitude = signal_interpolate( peaks, amplitude, x_new=np.arange(len(rsp_cleaned)), method=interpolation_method ) return amplitude