Source code for neurokit2.signal.signal_simulate

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

import numpy as np

from ..misc import NeuroKitWarning, check_random_state, listify


[docs] def signal_simulate( duration=10, sampling_rate=1000, frequency=1, amplitude=0.5, noise=0, silent=False, random_state=None, ): """**Simulate a continuous signal** Parameters ---------- duration : float Desired length of duration (s). sampling_rate : int The desired sampling rate (in Hz, i.e., samples/second). frequency : float or list Oscillatory frequency of the signal (in Hz, i.e., oscillations per second). amplitude : float or list Amplitude of the oscillations. noise : float Noise level (amplitude of the laplace noise). silent : bool If ``False`` (default), might print warnings if impossible frequencies are queried. random_state : None, int, numpy.random.RandomState or numpy.random.Generator Seed for the random number generator. See for ``misc.check_random_state`` for further information. Returns ------- array The simulated signal. Examples -------- .. ipython:: python import pandas as pd import neurokit2 as nk @savefig p_signal_simulate1.png scale=100% pd.DataFrame({ "1Hz": nk.signal_simulate(duration=5, frequency=1), "2Hz": nk.signal_simulate(duration=5, frequency=2), "Multi": nk.signal_simulate(duration=5, frequency=[0.5, 3], amplitude=[0.5, 0.2]) }).plot() @suppress plt.close() """ n_samples = int(np.rint(duration * sampling_rate)) period = 1 / sampling_rate seconds = np.arange(n_samples) * period signal = np.zeros(seconds.size) params = listify(frequency=frequency, amplitude=amplitude) for i in range(len(params["frequency"])): freq = params["frequency"][i] amp = params["amplitude"][i] # Apply a very conservative Nyquist criterion in order to ensure # sufficiently sampled signals. nyquist = sampling_rate * 0.1 if freq > nyquist: if not silent: warn( f"Skipping requested frequency" f" of {freq} Hz since it cannot be resolved at the" f" sampling rate of {sampling_rate} Hz. Please increase" f" sampling rate to {freq * 10} Hz or choose frequencies" f" smaller than or equal to {nyquist} Hz.", category=NeuroKitWarning, ) continue # Also make sure that at leat one period of the frequency can be # captured over the duration of the signal. if (1 / freq) > duration: if not silent: warn( f"Skipping requested frequency" f" of {freq} Hz since its period of {1 / freq} seconds" f" exceeds the signal duration of {duration} seconds." f" Please choose frequencies larger than" f" {1 / duration} Hz or increase the duration of the" f" signal above {1 / freq} seconds.", category=NeuroKitWarning, ) continue signal += _signal_simulate_sinusoidal(x=seconds, frequency=freq, amplitude=amp) # Add random noise if noise > 0: rng = check_random_state(random_state) signal += rng.laplace(0, noise, len(signal)) return signal
# ============================================================================= # Simple Sinusoidal Model # ============================================================================= def _signal_simulate_sinusoidal(x, frequency=100, amplitude=0.5): signal = amplitude * np.sin(2 * np.pi * frequency * x) return signal