Source code for neurokit2.eeg.eeg_simulate

import numpy as np

from ..misc import check_random_state


[docs] def eeg_simulate(duration=1, length=None, sampling_rate=1000, noise=0.1, random_state=None): """**EEG Signal Simulation** Simulate an artificial EEG signal. This is a crude implementation based on the MNE-Python raw simulation example. Help is needed to improve this function. Parameters ---------- duration : int Desired recording length in seconds. length : int The desired length of the signal (in samples). sampling_rate : int The desired sampling rate (in Hz, i.e., samples/second). noise : float Noise level. 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. Examples ---------- .. ipython:: python import neurokit2 as nk eeg = nk.eeg_simulate(duration=3, sampling_rate=500, noise=0.2) @savefig p_eeg_simulate1.png scale=100% _ = nk.signal_psd(eeg, sampling_rate=500, show=True, max_frequency=100) @suppress plt.close() """ # Try loading mne try: import mne import mne.datasets import mne.simulation except ImportError as e: raise ImportError( "The 'mne' module is required for this function to run. ", "Please install it first (`pip install mne`).", ) from e # Seed the random generator for reproducible results rng = check_random_state(random_state) # Generate number of samples automatically if length is unspecified if length is None: length = duration * sampling_rate if duration is None: duration = length / sampling_rate # Get paths to data path = mne.datasets.sample.data_path() / "MEG" / "sample" raw_file = path / "sample_audvis_raw.fif" fwd_file = path / "sample_audvis-meg-eeg-oct-6-fwd.fif" # Load real data as the template raw = mne.io.read_raw_fif(raw_file, preload=True, verbose=False) raw = raw.set_eeg_reference(projection=True, verbose=False) n_dipoles = 4 # number of dipoles to create def data_fun(times, n_dipoles=4): """Generate time-staggered sinusoids at harmonics of 10Hz""" n = 0 # harmonic number n_samp = len(times) window = np.zeros(n_samp) start, stop = [int(ii * float(n_samp) / (2 * n_dipoles)) for ii in (2 * n, 2 * n + 1)] window[start:stop] = 1.0 n += 1 data = 25e-9 * np.sin(2.0 * np.pi * 10.0 * n * times) data *= window return data times = raw.times[: int(raw.info["sfreq"] * 2)] fwd = mne.read_forward_solution(fwd_file, verbose=False) stc = mne.simulation.simulate_sparse_stc( fwd["src"], n_dipoles=n_dipoles, times=times, data_fun=data_fun, random_state=rng, ) # Repeat the source activation multiple times. raw_sim = mne.simulation.simulate_raw(raw.info, [stc] * int(np.ceil(duration / 2)), forward=fwd, verbose=False) cov = mne.make_ad_hoc_cov(raw_sim.info, std=noise / 1000000) raw_sim = mne.simulation.add_noise(raw_sim, cov, iir_filter=[0.2, -0.2, 0.04], verbose=False, random_state=rng) # Resample raw_sim = raw_sim.resample(sampling_rate, verbose=False) # Add artifacts # mne.simulation.add_ecg(raw_sim, verbose=False) # mne.simulation.add_eog(raw_sim, verbose=False) eeg = raw_sim.pick_types(eeg=True, verbose=False).get_data() return eeg[0, 0 : int(duration * sampling_rate)]