Source code for neurokit2.signal.signal_period

# -*- coding: utf-8 -*-
from warnings import warn

import numpy as np

from ..misc import NeuroKitWarning
from .signal_formatpeaks import _signal_formatpeaks_sanitize
from .signal_interpolate import signal_interpolate


[docs] def signal_period( peaks, sampling_rate=1000, desired_length=None, interpolation_method="monotone_cubic", ): """**Calculate signal period from a series of peaks** Calculate the period of a signal from a series of peaks. The period is defined as the time in seconds between two consecutive peaks. Parameters ---------- peaks : Union[list, np.array, pd.DataFrame, pd.Series, dict] The samples at which the peaks occur. If an array is passed in, it is assumed that it was obtained with :func:`.signal_findpeaks`. If a DataFrame is passed in, it is assumed it is of the same length as the input signal in which occurrences of R-peaks are marked as "1", with such containers obtained with e.g., :func:`.ecg_findpeaks` or :func:`.rsp_findpeaks`. sampling_rate : int The sampling frequency of the signal that contains peaks (in Hz, i.e., samples/second). Defaults to 1000. desired_length : int If left at the default ``None``, the returned period will have the same number of elements as ``peaks``. If set to a value larger than the sample at which the last peak occurs in the signal (i.e., ``peaks[-1]``), the returned period will be interpolated between peaks over ``desired_length`` samples. To interpolate the period over the entire duration of the signal, set ``desired_length`` to the number of samples in the signal. Cannot be smaller than or equal to the sample at which the last peak occurs in the signal. Defaults to ``None``. interpolation_method : str Method used to interpolate the rate between peaks. See :func:`.signal_interpolate`. ``"monotone_cubic"`` is chosen as the default interpolation method since it ensures monotone interpolation between data points (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 period. See Also -------- signal_findpeaks, signal_fixpeaks, signal_plot Examples -------- .. ipython:: python import neurokit2 as nk # Generate 2 signals (with fixed and variable period) sig1 = nk.signal_simulate(duration=20, sampling_rate=200, frequency=1) sig2 = nk.ecg_simulate(duration=20, sampling_rate=200, heart_rate=60) # Find peaks info1 = nk.signal_findpeaks(sig1) info2 = nk.ecg_findpeaks(sig2, sampling_rate=200) # Compute period period1 = nk.signal_period(peaks=info1["Peaks"], desired_length=len(sig1), sampling_rate=200) period2 = nk.signal_period(peaks=info2["ECG_R_Peaks"], desired_length=len(sig2), sampling_rate=200) @savefig p_signal_period.png scale=100% nk.signal_plot([period1, period2], subplots=True) @suppress plt.close() """ peaks = _signal_formatpeaks_sanitize(peaks) # Sanity checks. if np.size(peaks) <= 3: warn( "Too few peaks detected to compute the rate. Returning empty vector.", category=NeuroKitWarning, ) return np.full(desired_length, np.nan) if isinstance(desired_length, (int, float)): if desired_length <= peaks[-1]: raise ValueError( "NeuroKit error: desired_length must be None or larger than the index of the last peak." ) # Calculate period in sec, based on peak to peak difference and make sure # that rate has the same number of elements as peaks (important for # interpolation later) by prepending the mean of all periods. period = np.ediff1d(peaks, to_begin=0) / sampling_rate period[0] = np.mean(period[1:]) # Interpolate all statistics to desired length. if desired_length is not None: period = signal_interpolate( peaks, period, x_new=np.arange(desired_length), method=interpolation_method ) return period