### Install MEEGkit from source Source: https://github.com/nbara/python-meegkit/blob/master/README.md Install MEEGkit by cloning the repository and installing requirements and the package itself. Use developer mode for easier source code modification. ```bash pip install -r requirements.txt pip install . ``` -------------------------------- ### Install MEEGkit Source: https://context7.com/nbara/python-meegkit/llms.txt Install MEEGkit using pip. Use `[extra]` for optional dependencies like ASR variants. For development, clone the repository and use `pip install -e .`. ```bash pip install meegkit ``` ```bash pip install meegkit[extra] ``` ```bash git clone https://github.com/nbara/python-meegkit cd python-meegkit pip install -e . ``` -------------------------------- ### Install MEEGkit with pip Source: https://github.com/nbara/python-meegkit/blob/master/README.md Install the MEEGkit package using pip. This is the standard method for installing Python packages. ```bash pip install meegkit ``` -------------------------------- ### Install MEEGkit with extra dependencies Source: https://github.com/nbara/python-meegkit/blob/master/README.md Install MEEGkit with optional dependencies like pymanopt for certain ASR variants. Use the '[extra]' option. ```bash pip install -e '.[extra]' ``` ```bash pip install meegkit[extra] ``` -------------------------------- ### Import Libraries and Setup Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_star.ipynb Imports necessary libraries for plotting, numerical operations, and the STAR algorithm. Sets up a random number generator for data simulation. ```python %matplotlib inline import matplotlib.pyplot as plt import numpy as np from meegkit import star from meegkit.utils import demean, normcol rng = np.random.default_rng(9) ``` -------------------------------- ### Import necessary libraries Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_ress.ipynb Imports required libraries for data manipulation, signal processing, and plotting. Ensure these libraries are installed. ```python %matplotlib inline ``` ```python import matplotlib.pyplot as plt import numpy as np import scipy.signal as ss from meegkit import ress from meegkit.utils import fold, matmul3d, snr_spectrum, unfold # import config rng = np.random.default_rng(9) ``` -------------------------------- ### Import necessary libraries Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_dss_line.ipynb Imports required libraries for data manipulation, signal processing, and plotting. Ensure these are installed before running the code. ```python %matplotlib inline ``` ```python # Authors: Maciej Szul # Nicolas Barascud import os import matplotlib.pyplot as plt import numpy as np from scipy import signal from meegkit import dss from meegkit.utils import create_line_data, unfold ``` -------------------------------- ### Generate Toy Data for mCCA Example Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_mcca_2.ipynb Generates synthetic data matrices with a sinusoidal target signal embedded in Gaussian noise. This involves creating noise matrices, mixing matrices, a sinusoidal target, and a signal mixing matrix. The signal power is adjusted to achieve a specified Signal-to-Noise Ratio (SNR). ```python num_matrices = 10 num_samples = 10000 num_channels = 10 noise_rank = 9 signal_rank = 1 unfavorable_SNR_dB = -20 # SNR in decibels # Generate noise matrices and mixing matrices noise_matrices = [rng.normal(size=(num_samples, noise_rank)) for _ in range(num_matrices)] mixing_matrices = [rng.normal(size=(noise_rank, num_channels)) for _ in range(num_matrices)] # Generate sinusoidal target t = np.linspace(0, 1, num_samples) target_signal = np.sin(2 * np.pi * t) # 1 Hz sinusoidal signal # Generate signal mixing matrix signal_mixing_matrix = rng.normal(size=(signal_rank, num_channels)) # Prepare data matrices data_matrices = [] for i in range(num_matrices): # Create noise for current data matrix noise = np.matmul(noise_matrices[i], mixing_matrices[i]) # Create signal for current data matrix signal = np.matmul(target_signal.reshape(-1, 1), signal_mixing_matrix) # Adjust the power of signal to achieve the desired SNR noise_power = np.mean(noise**2) signal_power = 10**(unfavorable_SNR_dB / 10) * noise_power signal = np.sqrt(signal_power / np.mean(signal**2)) * signal # Add signal and noise data_matrix = signal + noise data_matrices.append(data_matrix) # Concatenate data matrices x = np.concatenate(data_matrices, axis=-1) ``` -------------------------------- ### Perform Robust Detrending Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.detrend.md Examples of fitting and removing trends using different orders, weights, and thresholds. ```python >> y = detrend(x, 1) ``` ```python >> y = detrend(x, 5, w, ‘polynomial’, 4) ``` ```python >> [y, w]= detrend(x, 1) >> [yy, ww] = detrend(y, 3) ``` -------------------------------- ### LOF for Bad Channel Detection Source: https://context7.com/nbara/python-meegkit/llms.txt This example demonstrates using Local Outlier Factor (LOF) to detect bad EEG channels. Synthetic data is created with artificially noisy or flat channels. The LOF detector identifies these channels based on their local density. ```python import numpy as np from meegkit.lof import LOF # Generate EEG data with some bad channels n_chans = 64 n_samples = 10000 # Normal channels data = np.random.randn(n_chans, n_samples) # Make some channels "bad" (high noise or flat) data[5, :] *= 10 # Very noisy channel data[20, :] = 0 # Flat channel data[45, :] = np.random.randn(n_samples) * 0.01 + 100 # DC offset + low amplitude # Initialize LOF detector lof = LOF( n_neighbors=20, # Neighbors for local density metric="euclidean", # Distance metric threshold=1.5 # Outlier threshold (>= 1.0) ) # Detect bad channels bad_channel_mask = lof.predict(data) print(f"Data shape: {data.shape}") print(f"Bad channels detected: {np.where(bad_channel_mask)[0].tolist()}") print(f"Number of bad channels: {bad_channel_mask.sum()}") ``` -------------------------------- ### Import dependencies and initialize environment Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_phase_estimation.ipynb Sets up the necessary libraries and paths for the phase estimation analysis. ```python import os import sys import matplotlib.pyplot as plt import numpy as np from scipy.signal import hilbert from meegkit.phase import NonResOscillator, ResOscillator, locking_based_phase sys.path.append(os.path.join(".", "tests")) from test_filters import generate_multi_comp_data, phase_difference # noqa:E402 rng = np.random.default_rng(5) ``` -------------------------------- ### Import dependencies and configure environment Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_echt.ipynb Initializes the environment with necessary libraries and sets plotting parameters. ```python import matplotlib.pyplot as plt import numpy as np from scipy.signal import hilbert from meegkit.phase import ECHT rng = np.random.default_rng(38872) plt.rcParams["axes.grid"] = True plt.rcParams["grid.linestyle"] = ":" ``` -------------------------------- ### meegkit.utils.stats.snr_spectrum Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.utils.md Computes the Signal-to-Noise-corrected spectrum, replicating examples from provided references. ```APIDOC ## meegkit.utils.stats.snr_spectrum ### Description Compute Signal-to-Noise-corrected spectrum. The implementation tries to replicate examples in [1; 2; 3]_. ### Parameters #### Parameters - **X** (ndarray) - One-sided power spectral density estimate, specified as a real-valued, nonnegative array. The power spectral density must be expressed in linear units, not decibels. - **freqs** (array) - Frequency bins. - **n_avg** (int) - Number of neighbour bins to estimate noise over. Make sure that this value doesn’t overlap with neighbouring target frequencies. - **n_harm** (int) - Compute SNR at each frequency bin as a pooled RMS over this bin and n_harm harmonics (see references below). - **skipbins** (int) - Number of bins skipped to estimate noise of neighbouring bins. ### Returns - **SNR** (ndarray) - Signal-to-Noise-corrected spectrum. ### Return type ndarray, shape=(n_freqs, n_chans, n_trials) or (n_freqs, n_chans) ### References - [1] Cottereau, B. R., McKee, S. P., Ales, J. M., & Norcia, A. M. (2011). Disparity-tuned population responses from human visual cortex. The Journal of Neuroscience, 31(3), 954-965. - [2] Cottereau, B. R., McKee, S. P., & Norcia, A. M. (2014). Dynamics and cortical distribution of neural responses to 2D and 3D motion in human. Journal of neurophysiology, 111(3), 533-543. - [3] de Heering, A., & Rossion, B. (2015). Rapid categorization of natural face images in the infant right hemisphere. Elife, 4. ``` -------------------------------- ### Initialize Environment and Imports Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_star_dss.ipynb Imports necessary libraries and sets the random seed for reproducibility. ```python import matplotlib.pyplot as plt import numpy as np from scipy.optimize import leastsq from meegkit import dss, star from meegkit.utils import demean, normcol, tscov # import config # noqa rng = np.random.default_rng(9) ``` -------------------------------- ### Define filterbank frequencies Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.trca.md Example structure for defining passband and stopband frequencies for the filterbank parameter in the TRCA class. ```python [[(6, 90), (4, 100)], [(14, 90), (10, 100)], [(22, 90), (16, 100)]] ``` -------------------------------- ### Initialize Environment and Imports Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_detrend.ipynb Imports necessary libraries and initializes the random number generator. ```python import matplotlib.pyplot as plt import numpy as np from matplotlib.gridspec import GridSpec from meegkit.detrend import detrend, regress # import config # plotting utils rng = np.random.default_rng(9) ``` -------------------------------- ### Import dependencies and initialize timer Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_trca.ipynb Imports necessary libraries for data processing and initializes a timer for performance tracking. ```python # Authors: Giuseppe Ferraro # Nicolas Barascud import os import time import matplotlib.pyplot as plt import numpy as np import scipy.io from meegkit.trca import TRCA from meegkit.utils.trca import itr, normfit, round_half_up t = time.time() ``` -------------------------------- ### Create uncorrelated datasets and calculate covariance Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_mcca.ipynb Generates three uncorrelated datasets and concatenates them. Then, it computes the aggregated covariance matrix of the combined data. This setup is used to demonstrate mCCA when no common structure is expected. ```python x1 = rng.standard_normal((10000, 10)) x2 = rng.standard_normal((10000, 10)) x3 = rng.standard_normal((10000, 10)) x = np.hstack((x1, x2, x3)) C = np.dot(x.T, x) print(f"Aggregated data covariance shape: {C.shape}") ``` -------------------------------- ### Initialize and Fit RESS Model Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.ress.md Instantiate the RESS class with specified parameters and fit it to the data. The `compute_unmixing` parameter should be set to True if you intend to project data back to sensor space. ```python r = ress.RESS(sfreq, peak_freq, compute_unmixing=True) out = r.fit_transform(data) ``` -------------------------------- ### Plot comparative results Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_phase_estimation.ipynb Visualizes the comparison between Hilbert-based ground truth and the causal estimation algorithms. ```python f, ax = plt.subplots(4, 2, sharex=True, sharey=True, figsize=(12, 8)) ax[0, 0].plot(time, s, time, ht_phase, lw=.75) ax[0, 0].set_ylabel(r"$s,\phi_H$") ax[0, 0].set_title("Signal and its Hilbert phase") ax[1, 0].plot(time, lb_phi_dif, lw=.75) ax[1, 0].axhline(0, color="k", ls=":", zorder=-1) ax[1, 0].set_ylabel(r"$\phi_H - \phi_L$") ax[1, 0].set_ylim([-np.pi, np.pi]) ax[1, 0].set_title("Phase locking approach") ax[2, 0].plot(time, nr_phi_dif, lw=.75) ax[2, 0].axhline(0, color="k", ls=":", zorder=-1) ax[2, 0].set_ylabel(r"$\phi_H - \phi_N$") ax[2, 0].set_ylim([-np.pi, np.pi]) ax[2, 0].set_title("Nonresonant oscillator") ax[3, 0].plot(time, r_phi_dif, lw=.75) ax[3, 0].axhline(0, color="k", ls=":", zorder=-1) ax[3, 0].set_ylim([-np.pi, np.pi]) ax[3, 0].set_ylabel(r"$\phi_H - \phi_R$") ax[3, 0].set_xlabel("Time") ax[3, 0].set_title("Resonant oscillator") ax[0, 1].plot(time, s, time, ht_ampl, lw=.75) ax[0, 1].set_ylabel(r"$s,a_H$") ax[0, 1].set_title("Signal and its Hilbert amplitude") ax[1, 1].axis("off") ax[2, 1].plot(time, s, time, nr_ampl, lw=.75) ax[2, 1].set_ylabel(r"$s,a_N$") ax[2, 1].set_title("Amplitudes") ax[2, 1].set_title("Nonresonant oscillator") ax[3, 1].plot(time, s, time, r_ampl, lw=.75) ax[3, 1].set_xlabel("Time") ax[3, 1].set_ylabel(r"$s,a_R$") ax[3, 1].set_title("Resonant oscillator") plt.suptitle("Amplitude (right) and phase (left) estimation algorithms") plt.tight_layout() plt.show() ``` -------------------------------- ### Visualize signal and phase results Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_echt.ipynb Plots the test signal, its power spectral density, and a comparison of the true, ECHT, and Hilbert phases. ```python fig, ax = plt.subplots(3, 1, figsize=(8, 6)) ax[0].plot(time, X) ax[0].set_xlabel("Time (s)") ax[0].set_title("Test signal") ax[0].set_ylabel("Amplitude") ax[1].psd(X, Fs=sfreq, NFFT=2048*4, noverlap=sfreq) ax[1].set_ylabel("PSD (dB/Hz)") ax[1].set_title("Test signal's Fourier spectrum") ax[2].plot(time, phase_true, label="True phase", ls=":") ax[2].plot(time, phase_echt, label="ECHT phase", lw=.5, alpha=.8) ax[2].plot(time, phase_hilbert, label="Hilbert phase", lw=.5, alpha=.8) ax[2].set_title("Phase") ax[2].set_ylabel("Amplitude") ax[2].set_xlabel("Time (s)") ax[2].legend(loc="upper right", fontsize="small") plt.tight_layout() plt.show() ``` -------------------------------- ### Load EEG data for ASR Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_asr.ipynb Initializes the environment and loads raw EEG data from a NumPy file. ```python import os import matplotlib.pyplot as plt import numpy as np from meegkit.asr import ASR from meegkit.utils.matrix import sliding_window # THIS_FOLDER = os.path.dirname(os.path.abspath(__file__)) raw = np.load(os.path.join(".", "tests", "data", "eeg_raw.npy")) sfreq = 250 ``` -------------------------------- ### meegkit.phase.init_coefs Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.phase.md Compute coefficients for solving oscillator’s equations. ```APIDOC ## Function: init_coefs ### Description Compute coefficients for solving oscillator’s equations. ### Parameters * **om0** (*float*) – Oscillator frequency (estimation). * **dt** (*float*) – Sampling interval. * **alpha** (*float*) – Half of the damping. ### Returns * **C1** (*float*) – Coefficient C1. * **C2** (*float*) – Coefficient C2. * **C3** (*float*) – Coefficient C3. * **eetadel** (*complex*) – Exponential term for amplitude device. * **ealdel** (*float*) – Exponential term for amplitude device. * **eta** (*float*) – Square root of the difference of oscillator frequency squared and damping squared. ``` -------------------------------- ### Derive Phase and Amplitude from Analytic Signal Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.utils.md Demonstrates how to obtain phase and amplitude from a time series using the Hilbert transform to compute the analytic signal. ```python from meegkit.utils.sig import hilbert # Assuming hilbert is available or imported elsewhere # Example usage: # analytic_signal = hilbert(filtered_data) # phase = np.phase(analytic_signal) # amplitude = np.abs(analytic_signal) ``` -------------------------------- ### Configure TRCA parameters Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_trca.ipynb Sets up the experimental parameters and stimulus frequencies for the TRCA analysis. ```python dur_gaze = 0.5 # data length for target identification [s] delay = 0.13 # visual latency being considered in the analysis [s] n_bands = 5 # number of sub-bands in filter bank analysis is_ensemble = True # True = ensemble TRCA method; False = TRCA method alpha_ci = 0.05 # 100*(1-alpha_ci): confidence interval for accuracy sfreq = 250 # sampling rate [Hz] dur_shift = 0.5 # duration for gaze shifting [s] list_freqs = np.array( [[x + 8.0 for x in range(8)], [x + 8.2 for x in range(8)], [x + 8.4 for x in range(8)], [x + 8.6 for x in range(8)], [x + 8.8 for x in range(8)]]).T # list of stimulus frequencies n_targets = list_freqs.size # The number of stimuli # Useful variables (no need to modify) dur_gaze_s = round_half_up(dur_gaze * sfreq) # data length [samples] delay_s = round_half_up(delay * sfreq) # visual latency [samples] dur_sel_s = dur_gaze + dur_shift # selection time [s] ci = 100 * (1 - alpha_ci) # confidence interval ``` -------------------------------- ### Import Dependencies and Initialize RNG Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_dss.ipynb Imports necessary libraries for data manipulation and DSS processing, and initializes the random number generator. ```python import matplotlib.pyplot as plt import numpy as np from meegkit import dss from meegkit.utils import fold, rms, tscov, unfold rng = np.random.default_rng(5) ``` -------------------------------- ### Import necessary libraries Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_dering.ipynb Imports matplotlib for plotting, numpy for numerical operations, and specific functions from scipy.signal and meegkit.detrend. ```python %matplotlib inline ``` ```python import matplotlib.pyplot as plt import numpy as np from scipy.signal import butter, lfilter from meegkit.detrend import reduce_ringing ``` -------------------------------- ### Import necessary libraries Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_mcca.ipynb Imports matplotlib for plotting, numpy for numerical operations, and the cca module from meegkit. Sets up a random number generator for reproducible results. ```python %matplotlib inline ``` ```python import matplotlib.pyplot as plt import numpy as np from meegkit import cca rng = np.random.default_rng(5) ``` -------------------------------- ### RESS Class Initialization Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.ress.md Initializes the RESS estimator with parameters for frequency filtering and regularization. ```APIDOC ## Class: RESS ### Description Initializes the Rhythmic Entrainment Source Separation estimator. ### Parameters - **sfreq** (int) - Required - Sampling frequency. - **peak_freq** (float) - Required - Peak frequency. - **neig_freq** (float) - Optional - Distance of neighbouring frequencies away from peak frequency (default=1). - **peak_width** (float) - Optional - FWHM of the peak frequency (default=.5). - **neig_width** (float) - Optional - FWHM of the neighboring frequencies (default=1). - **n_keep** (int) - Optional - Number of components to keep (default=1). - **gamma** (float) - Optional - Regularization coefficient (default=0.01). - **compute_unmixing** (bool) - Optional - If True, computes unmixing matrices (default=False). ``` -------------------------------- ### Detrend Data with Artifact Weights Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_detrend.ipynb Demonstrates how downweighting artifactual periods improves detrending performance. ```python x = np.linspace(0, 100, 1000)[:, None] x = x + 3 * rng.standard_normal(x.shape) # introduce some strong artifact on the first 100 samples x[:100, :] = 100 # Detrend y, _, _ = detrend(x, 3, None, threshold=np.inf) # Same process but this time downweight artifactual window w = np.ones(x.shape) w[:100, :] = 0 z, _, _ = detrend(x, 3, w) plt.figure(7) plt.plot(x, label="original") plt.plot(y, label="detrended - no weights") plt.plot(z, label="detrended - weights") plt.legend() plt.show() ``` -------------------------------- ### Visualize Results Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_star_dss.ipynb Plots the target signal, raw signal with artifacts, DSS output, and STAR+DSS output for comparison. ```python f, (ax0, ax1, ax2, ax3) = plt.subplots(4, 1, figsize=(7, 9)) ax0.plot(target, lw=.5) ax0.set_title("Target") ax1.plot(x, lw=.5) ax1.set_title(f"Signal + Artifacts (SNR = {SNR})") ax2.plot(z1[:, 0], lw=.5, label="Best DSS component") ax2.set_title("DSS") ax2.legend(loc="lower right") ax3.plot(z2[:, 0], lw=.5, label="Best DSS component") ax3.set_title("STAR + DSS") ax3.legend(loc="lower right") f.set_tight_layout(True) plt.show() ``` -------------------------------- ### Smooth a signal Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.utils.md Demonstrates smoothing a signal using a window of a specified size. ```python >> t = linspace(-2, 2, 0.1) >> x = sin(t) + randn(len(t)) * 0.1 >> y = smooth(x, 2) ``` -------------------------------- ### Project RESS Components Back to Sensor Space Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.ress.md After fitting the RESS model with `compute_unmixing=True`, use the `from_ress` attribute to project the separated components back into the original sensor space. ```python from meegkit.ress import RESS from numpy import matmul r = RESS(sfreq, peak_freq, compute_unmixing=True) out = r.fit_transform(data) from_RESS = r.from_ress proj = matmul(out, from_RESS) ``` -------------------------------- ### Initialize ECHT Transform Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.phase.md Initializes the Endpoint Corrected Hilbert Transform (ECHT) with specified frequency cutoffs and sampling rate. The filter order can also be adjusted. ```python f0 = 2 filt_BW = f0 / 2 N = 1000 sfreq = N / (2 * np.pi) t = np.arange(-2 * np.pi, 0, 1 / sfreq) X = np.cos(2 * np.pi * f0 * t - np.pi / 4) l_freq = f0 - filt_BW / 2 h_freq = f0 + filt_BW / 2 Xf = echt(X, l_freq, h_freq, sfreq) ``` -------------------------------- ### meegkit.phase.rk Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.phase.md Calculates phase using the Runge-Kutta method. ```APIDOC ## meegkit.phase.rk(phi, dt, n_steps, omega, epsilon, s_prev, s, s_new) ### Description Runge-Kutta method for phase calculation. ### Parameters #### Arguments - **phi** (float) - Required - Initial phase value. - **dt** (float) - Required - Time step size. - **n_steps** (int) - Required - Number of steps to iterate. - **omega** (float) - Required - Angular frequency. - **epsilon** (float) - Required - Amplitude of the oscillation. - **s_prev** (float) - Required - Previous phase value. - **s** (float) - Required - Current phase value. - **s_new** (float) - Required - New phase value. ### Response - **phi** (float) - The calculated phase value. ``` -------------------------------- ### Compute phase and amplitude estimates Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_phase_estimation.ipynb Calculates phase and amplitude using Hilbert transform, locking-based, non-resonant, and resonant oscillator methods. ```python ht_ampl = np.abs(hilbert(s)) # Hilbert amplitude ht_phase = np.angle(hilbert(s)) # Hilbert phase lb_phase = locking_based_phase(s, dt, npt) lb_phi_dif = phase_difference(ht_phase, lb_phase) osc = NonResOscillator(fs, 1.1) nr_phase, nr_ampl = osc.transform(s) nr_phase = nr_phase[:, 0] nr_phi_dif = phase_difference(ht_phase, nr_phase) osc = ResOscillator(fs, 1.1) r_phase, r_ampl = osc.transform(s) r_phase = r_phase[:, 0] r_phi_dif = phase_difference(ht_phase, r_phase) ``` -------------------------------- ### Class: meegkit.lof.LOF Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.lof.md Initializes the Local Outlier Factor detector for M/EEG data. ```APIDOC ## Class: meegkit.lof.LOF ### Description Initializes the Local Outlier Factor (LOF) object for automatic, density-based outlier detection. ### Parameters - **n_neighbors** (int) - Optional - Number of neighbors defining the local neighborhood. Default is 20. - **metric** (str) - Optional - Metric to use for distance computation. Options: 'euclidean', 'nan_euclidean', 'cosine', 'cityblock', 'manhattan'. Default is 'euclidean'. - **threshold** (float) - Optional - Threshold to define outliers. Theoretical range is between 1.0 and any integer. Default is 1.5. ``` -------------------------------- ### Visualize signal spectrum Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_phase_estimation.ipynb Plots the time-domain signal and its power spectral density. ```python f, ax = plt.subplots(2, 1) ax[0].plot(time, s) ax[0].set_xlabel("Time (s)") ax[0].set_title("Test signal") ax[1].psd(s, Fs=fs, NFFT=2048*4, noverlap=fs) ax[1].set_title("Test signal's Fourier spectrum") plt.tight_layout() ``` -------------------------------- ### Visualize ASR results Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_asr.ipynb Plots the raw and cleaned EEG signals, highlighting the calibration and selected windows. ```python times = np.arange(raw.shape[-1]) / sfreq f, ax = plt.subplots(8, sharex=True, figsize=(8, 5)) for i in range(8): ax[i].fill_between(train_idx / sfreq, 0, 1, color="grey", alpha=.3, transform=ax[i].get_xaxis_transform(), label="calibration window") ax[i].fill_between(train_idx / sfreq, 0, 1, where=sample_mask.flat, transform=ax[i].get_xaxis_transform(), facecolor="none", hatch="...", edgecolor="k", label="selected window") ax[i].plot(times, raw[i], lw=.5, label="before ASR") ax[i].plot(times, clean[i], label="after ASR", lw=.5) ax[i].set_ylim([-50, 50]) ax[i].set_ylabel(f"ch{i}") ax[i].set_yticks([]) ax[i].set_xlabel("Time (s)") ax[0].legend(fontsize="small", bbox_to_anchor=(1.04, 1), borderaxespad=0) plt.subplots_adjust(hspace=0, right=0.75) plt.suptitle("Before/after ASR") plt.show() ``` -------------------------------- ### Calculate Sliding Windows Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.utils.md Creates a sliding window view of an array. Setting copy=False may lead to side effects when modifying the output. ```pycon >>> a = numpy.array([1, 2, 3, 4, 5]) >>> sliding_window(a, size=3) array([[1, 2, 3], [2, 3, 4], [3, 4, 5]]) ``` ```pycon >>> sliding_window(a, size=3, stepsize=2) array([[1, 2, 3], [3, 4, 5]]) ``` -------------------------------- ### Create Simulated Data Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_star.ipynb Generates simulated data with a target sinusoidal signal, noise sources, and temporally local artifacts. The SNR parameter controls the signal-to-noise ratio of the artifacts. ```python # Create simulated data nchans = 10 n_samples = 1000 f = 2 target = np.sin(np.arange(n_samples) / n_samples * 2 * np.pi * f) target = target[:, np.newaxis] noise = rng.standard_normal((n_samples, nchans - 3)) # Create artifact signal SNR = np.sqrt(1) x0 = normcol(np.dot(noise, rng.standard_normal((noise.shape[1], nchans)))) + \ SNR * target * rng.standard_normal((1, nchans)) x0 = demean(x0) artifact = np.zeros(x0.shape) for k in np.arange(nchans): artifact[k * 100 + np.arange(20), k] = 1 x = x0 + 10 * artifact ``` -------------------------------- ### Apply STAR Algorithm Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_star.ipynb Applies the Sparse Time Artifact Removal (STAR) algorithm to the simulated data `x`. The second argument `2` specifies the number of artifact components to estimate. ```python y, w, _ = star.star(x, 2) ``` -------------------------------- ### Visualize Results Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_dss.ipynb Plots the original source, the noisy data, and the recovered signal component. ```python f, (ax1, ax2, ax3) = plt.subplots(3, 1) ax1.plot(source, label="source") ax2.plot(np.mean(data, 2), label="data") ax3.plot(best_comp, label="recovered") plt.legend() plt.show() ``` -------------------------------- ### POST /asr/process Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.asr.md Applies the Artifact Subspace Reconstruction (ASR) method to clean multi-channel signals. ```APIDOC ## POST /asr/process ### Description Apply Artifact Subspace Reconstruction method to clean multi-channel signal. ### Parameters #### Request Body - **X** (array) - Required - Raw data (shape: [n_trials, ]n_channels, n_samples) - **X_filt** (array) - Optional - Yulewalk-filtered epochs to estimate covariance - **state** (dict) - Required - Initial ASR parameters (M, T, R) - **cov** (array) - Optional - Covariance matrix - **detrend** (bool) - Optional - If True, detrend filtered data (default=False) - **method** (string) - Optional - Metric to compute covariance average ('euclid' or 'riemann') ### Response #### Success Response (200) - **clean** (array) - Clean data - **state** (3-tuple) - Output ASR parameters ``` -------------------------------- ### Compute CCA with nt_cca Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.cca.md Demonstrates various ways to compute CCA, including direct data input, lagged analysis, and covariance-based computation for large datasets. ```python >> A, B, R = nt_cca(X, Y) # noqa ``` ```python >> A, B, R = nt_cca(X, Y, lags) # noqa ``` ```python >> C = [X, Y].T * [X, Y] # noqa >> A, B, R = nt_cca(None, None, None, C=C, m=X.shape[1]) # noqa ``` -------------------------------- ### Compute Hilbert and ECHT phase Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_echt.ipynb Calculates the standard Hilbert phase and the ECHT-filtered phase. ```python phase_hilbert = np.angle(hilbert(X)) # Hilbert phase # Compute ECHT-filtered signal filt_BW = f0 / 2 l_freq = f0 - filt_BW / 2 h_freq = f0 + filt_BW / 2 echt = ECHT(l_freq, h_freq, sfreq) Xf = echt.fit_transform(X) phase_echt = np.angle(Xf) ``` -------------------------------- ### Generate multi-component test data Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_phase_estimation.ipynb Creates a synthetic signal with amplitude and phase modulations for testing. ```python npt = 100000 fs = 100 s = generate_multi_comp_data(npt, fs) # Generate test data dt = 1 / fs time = np.arange(npt) * dt ``` -------------------------------- ### Visualize Denoising Results Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_star.ipynb Plots the original signal with artifacts, the denoised signal, and the residual after artifact removal. This helps in visually assessing the effectiveness of the STAR algorithm. ```python f, (ax1, ax2, ax3) = plt.subplots(3, 1) ax1.plot(x, lw=.5) ax1.set_title(f"Signal + Artifacts (SNR = {SNR})") ax2.plot(y, lw=.5) ax2.set_title("Denoised") ax3.plot(demean(y) - x0, lw=.5) ax3.set_title("Residual") f.set_tight_layout(True) plt.show() ``` -------------------------------- ### Apply DSS on Raw Data Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_star_dss.ipynb Computes DSS components directly on the raw signal. ```python c0, _ = tscov(x) c1, _ = tscov(x - _sine_fit(x)) [todss, _, pwr0, pwr1] = dss.dss0(c0, c1) z1 = normcol(np.dot(x, todss)) ``` -------------------------------- ### meegkit.phase.one_step_integrator Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.phase.md Performs a single integration step for the oscillator equations. ```APIDOC ## meegkit.phase.one_step_integrator(z, edelmu, mu, dt, spp, sp, s) ### Description Perform one step of the integrator in the oscillator equations. ### Parameters #### Arguments - **z** (float) - Required - State variable z. - **edelmu** (float) - Required - Exponential term for integrator. - **mu** (float) - Required - Integrator parameter. - **dt** (float) - Required - Sampling interval. - **spp** (float) - Required - Second previous measurement. - **sp** (float) - Required - Previous measurement. - **s** (float) - Required - Current measurement. ### Response - **z** (float) - Updated state variable z. ``` -------------------------------- ### POST /asr/clean_windows Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.asr.md Removes periods with abnormally high-power content from continuous data. ```APIDOC ## POST /asr/clean_windows ### Description Cuts segments from the data which contain high-power artifacts based on channel power thresholds. ### Parameters #### Request Body - **X** (array) - Required - Continuous data set (shape: n_channels, n_samples) - **sfreq** (float) - Required - Sampling frequency - **max_bad_chans** (float) - Optional - Max fraction of bad channels allowed (default=0.2) - **zthresholds** (2-tuple) - Optional - Min/max standard deviations for power (default=[-3.5, 5]) - **win_len** (float) - Optional - Window length for artifact check (default=0.5) - **win_overlap** (float) - Optional - Window overlap fraction (default=0.66) - **min_clean_fraction** (float) - Optional - Minimum fraction of clean time windows (default=0.25) - **max_dropout_fraction** (float) - Optional - Maximum fraction of dropouts (default=0.1) ### Response #### Success Response (200) - **clean** (array) - Dataset with bad time periods removed - **sample_mask** (boolean array) - Mask of retained samples ``` -------------------------------- ### meegkit.phase.ResOscillator Source: https://github.com/nbara/python-meegkit/blob/master/doc/modules/meegkit.phase.md Real-time measurement of phase and amplitude using a resonant oscillator. This method exploits the known relation between the resonant oscillator’s phase and amplitude and those of the input. It also acts as a bandpass filter and includes a frequency-adaptation algorithm. ```APIDOC ## Class: ResOscillator ### Description Real-time measurement of phase and amplitude using a resonant oscillator. In this version, the corresponding “device” consists of a linear oscillator in resonance with the measured signal and of an integrating unit. It also provides both phase and amplitude of the input signal. The method exploits the known relation between the resonant oscillator’s phase and amplitude and those of the input. Additionally, the resonant oscillator acts as a bandpass filter for experimental data. This filter also includes a frequency-adaptation algorithm, and removes low-frequency trend (baseline fluctuations). For a detailed description, refer to [1]_. ### Parameters * **fs** (*float*) – Sampling frequency in Hz. * **nu** (*float*) – Rough estimate of the tremor frequency. * **update_factor** (*int*) – Default value is 5. * **freq_adaptation** (*bool*) – Whether to use the frequency adaptation algorithm (default=True). * **assume_centered** (*bool*) – Default value is False. ### Methods #### transform(X) Transform the input signal into phase and amplitude estimates. * **Parameters:** **X** (*ndarray* *,* *shape* *(**n_samples* *,* [*n_channels*](meegkit.utils.md#meegkit.utils.buffer.Buffer.n_channels) *)*) – The input signal to be transformed. * **Returns:** * **phase** (*float*) – Current phase estimate. * **ampl** (*float*) – Current amplitude estimate. ``` -------------------------------- ### Estimate Phase and Amplitude with Resonant Oscillators and ECHT Source: https://context7.com/nbara/python-meegkit/llms.txt Uses ResOscillator for real-time phase/amplitude tracking or ECHT for endpoint-corrected Hilbert transforms. Suitable for closed-loop neurostimulation. ```python import numpy as np from meegkit.phase import ResOscillator, ECHT # Generate oscillatory signal sfreq = 1000 # High sampling rate for real-time applications duration = 5 # seconds n_samples = int(sfreq * duration) t = np.arange(n_samples) / sfreq # Simulated neural oscillation at 10 Hz freq = 10 signal = np.sin(2 * np.pi * freq * t) + np.random.randn(n_samples) * 0.3 signal = signal[:, None] # Shape: (n_samples, n_channels) # Initialize resonant oscillator oscillator = ResOscillator( fs=sfreq, nu=freq, # Estimated frequency freq_adaptation=True # Enable automatic frequency tracking ) # Process signal (can be done sample-by-sample in real-time) phase, amplitude = oscillator.transform(signal) print(f"Input shape: {signal.shape}") print(f"Phase shape: {phase.shape}") print(f"Amplitude shape: {amplitude.shape}") print(f"Phase range: [{phase.min():.2f}, {phase.max():.2f}] radians") # Alternative: ECHT (Endpoint Corrected Hilbert Transform) echt = ECHT( l_freq=freq - 2, # Bandpass low cutoff h_freq=freq + 2, # Bandpass high cutoff sfreq=sfreq, filt_order=2 ) # Fit and transform analytic_signal = echt.fit_transform(signal) echt_phase = np.angle(analytic_signal) echt_amplitude = np.abs(analytic_signal) print(f"\nECHT analytic signal shape: {analytic_signal.shape}") ``` -------------------------------- ### Create datasets with shared parts and calculate covariance Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_mcca.ipynb Generates four datasets, with one dataset (x1) appearing multiple times among the concatenated data. This creates shared structure. The aggregated covariance matrix is then computed. ```python x1 = rng.standard_normal((10000, 5)) x2 = rng.standard_normal((10000, 5)) x3 = rng.standard_normal((10000, 5)) x4 = rng.standard_normal((10000, 5)) x = np.hstack((x2, x1, x3, x1, x4, x1)) C = np.dot(x.T, x) print(f"Aggregated data covariance shape: {C.shape}") ``` -------------------------------- ### Generate Synthetic Multichannel Data Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_dss.ipynb Creates synthetic signal and noise components to simulate multichannel data with trials. ```python # Data are time * channel * trials. n_samples = 100 * 3 n_chans = 30 n_trials = 100 noise_dim = 20 # dimensionality of noise # Source signal source = np.hstack(( np.zeros((n_samples // 3,)), np.sin(2 * np.pi * np.arange(n_samples // 3) / (n_samples / 3)).T, np.zeros((n_samples // 3,))))[np.newaxis].T s = source * rng.standard_normal((1, n_chans)) # 300 * 30 s = s[:, :, np.newaxis] s = np.tile(s, (1, 1, 100)) # Noise noise = np.dot( unfold(rng.standard_normal((n_samples, noise_dim, n_trials))), rng.standard_normal((noise_dim, n_chans))) noise = fold(noise, n_samples) # Mix signal and noise SNR = 0.1 data = noise / rms(noise.flatten()) + SNR * s / rms(s.flatten()) ``` -------------------------------- ### Sparse Time Artifact Removal (STAR) Source: https://context7.com/nbara/python-meegkit/llms.txt Detects and interpolates transient channel-specific artifacts. ```python import numpy as np from meegkit.star import star from meegkit.utils import demean, normcol # Create data with sparse artifacts n_samples = 1000 n_chans = 10 ``` -------------------------------- ### Apply STAR for Artifact Removal Source: https://context7.com/nbara/python-meegkit/llms.txt This snippet shows how to apply the STAR algorithm to clean EEG data by removing transient artifacts. Ensure data is preprocessed (demeaned) before applying STAR. ```python noise_sources = np.random.randn(n_samples, n_chans - 3) mixing = np.random.randn(n_chans - 3, n_chans) clean_data = normcol(noise_sources @ mixing) artifact = np.zeros((n_samples, n_chans)) for ch in range(n_chans): start = ch * 100 artifact[start:start + 20, ch] = 10 # Artifact on each channel data = demean(clean_data + artifact) denois ed, sample_weights, channel_weights = star( data, thresh=1, # Eccentricity threshold depth=1, # Max channels to fix per sample n_iter=3, # Iterations to refine covariance min_prop=0.5, # Min proportion artifact-free verbose=True ) print(f"\nInput shape: {data.shape}") print(f"Denoised shape: {denoised.shape}") print(f"Samples flagged as artifact: {(sample_weights == 0).sum()}") ``` -------------------------------- ### Perform Split-wise Regression with Weights Source: https://github.com/nbara/python-meegkit/blob/master/examples/example_detrend.ipynb Restricts the regression fit to the second half of the data by setting weights to zero for the first 500 samples. ```python x = np.cumsum(rng.standard_normal((1000, 1)), axis=0) + 1000 w = np.ones(y.shape[0]) w[:500] = 0 b, y = regress(x, r, w) f = plt.figure(3) gs = GridSpec(4, 1, figure=f) ax1 = f.add_subplot(gs[:3, 0]) ax1.plot(x, label="data") ax1.plot(y, label="fit") ax1.set_xticklabels("") ax1.set_title("Split-wise regression") ax1.legend() ax2 = f.add_subplot(gs[3, 0]) ll, = ax2.plot(np.arange(1000), np.zeros(1000)) ax2.stackplot(np.arange(1000), w, labels=["weights"], color=ll.get_color()) ax2.legend(loc=2) ```