Files
2025-11-30 08:30:10 +08:00

14 KiB
Raw Permalink Blame History

EEG Analysis and Microstates

Overview

Analyze electroencephalography (EEG) signals for frequency band power, channel quality assessment, source localization, and microstate identification. NeuroKit2 integrates with MNE-Python for comprehensive EEG processing workflows.

Core EEG Functions

eeg_power()

Compute power across standard frequency bands for specified channels.

power = nk.eeg_power(eeg_data, sampling_rate=250, channels=['Fz', 'Cz', 'Pz'],
                     frequency_bands={'Delta': (0.5, 4),
                                     'Theta': (4, 8),
                                     'Alpha': (8, 13),
                                     'Beta': (13, 30),
                                     'Gamma': (30, 45)})

Standard frequency bands:

  • Delta (0.5-4 Hz): Deep sleep, unconscious processes
  • Theta (4-8 Hz): Drowsiness, meditation, memory encoding
  • Alpha (8-13 Hz): Relaxed wakefulness, eyes closed
  • Beta (13-30 Hz): Active thinking, focus, anxiety
  • Gamma (30-45 Hz): Cognitive processing, binding

Returns:

  • DataFrame with power values for each channel × frequency band combination
  • Columns: Channel_Band (e.g., 'Fz_Alpha', 'Cz_Beta')

Use cases:

  • Resting state analysis
  • Cognitive state classification
  • Sleep staging
  • Meditation or neurofeedback monitoring

eeg_badchannels()

Identify problematic channels using statistical outlier detection.

bad_channels = nk.eeg_badchannels(eeg_data, sampling_rate=250, bad_threshold=2)

Detection methods:

  • Standard deviation outliers across channels
  • Correlation with other channels
  • Flat or dead channels
  • Channels with excessive noise

Parameters:

  • bad_threshold: Z-score threshold for outlier detection (default: 2)

Returns:

  • List of channel names identified as problematic

Use case:

  • Quality control before analysis
  • Automatic bad channel rejection
  • Interpolation or exclusion decisions

eeg_rereference()

Re-express voltage measurements relative to different reference points.

rereferenced = nk.eeg_rereference(eeg_data, reference='average', robust=False)

Reference types:

  • 'average': Average reference (mean of all electrodes)
  • 'REST': Reference Electrode Standardization Technique
  • 'bipolar': Differential recording between electrode pairs
  • Specific channel name: Use single electrode as reference

Common references:

  • Average reference: Most common for high-density EEG
  • Linked mastoids: Traditional clinical EEG
  • Vertex (Cz): Sometimes used in ERP research
  • REST: Approximates infinity reference

Returns:

  • Re-referenced EEG data

eeg_gfp()

Compute Global Field Power - the standard deviation of all electrodes at each time point.

gfp = nk.eeg_gfp(eeg_data)

Interpretation:

  • High GFP: Strong, synchronized brain activity across regions
  • Low GFP: Weak or desynchronized activity
  • GFP peaks: Points of stable topography, used for microstate detection

Use cases:

  • Identify periods of stable topographic patterns
  • Select time points for microstate analysis
  • Event-related potential (ERP) visualization

eeg_diss()

Measure topographic dissimilarity between electric field configurations.

dissimilarity = nk.eeg_diss(eeg_data1, eeg_data2, method='gfp')

Methods:

  • GFP-based: Normalized difference
  • Spatial correlation
  • Cosine distance

Use case:

  • Compare topographies between conditions
  • Microstate transition analysis
  • Template matching

Source Localization

eeg_source()

Perform source reconstruction to estimate brain-level activity from scalp recordings.

sources = nk.eeg_source(eeg_data, method='sLORETA')

Methods:

  • 'sLORETA': Standardized Low-Resolution Electromagnetic Tomography
    • Zero localization error for point sources
    • Good spatial resolution
  • 'MNE': Minimum Norm Estimate
    • Fast, well-established
    • Bias toward superficial sources
  • 'dSPM': Dynamic Statistical Parametric Mapping
    • Normalized MNE
  • 'eLORETA': Exact LORETA
    • Improved localization accuracy

Requirements:

  • Forward model (lead field matrix)
  • Co-registered electrode positions
  • Head model (boundary element or spherical)

Returns:

  • Source space activity estimates

eeg_source_extract()

Extract activity from specific anatomical brain regions.

regional_activity = nk.eeg_source_extract(sources, regions=['PFC', 'MTL', 'Parietal'])

Region options:

  • Standard atlases: Desikan-Killiany, Destrieux, AAL
  • Custom ROIs
  • Brodmann areas

Returns:

  • Time series for each region
  • Averaged or principal component across voxels

Use cases:

  • Region-of-interest analysis
  • Functional connectivity
  • Source-level statistics

Microstate Analysis

Microstates are brief (80-120 ms) periods of stable brain topography, representing coordinated neural networks. Typically 4-7 microstate classes (often labeled A, B, C, D) with distinct functions.

microstates_segment()

Identify and extract microstates using clustering algorithms.

microstates = nk.microstates_segment(eeg_data, n_microstates=4, sampling_rate=250,
                                      method='kmod', normalize=True)

Methods:

  • 'kmod' (default): Modified k-means optimized for EEG topographies
    • Polarity-invariant clustering
    • Most common in microstate literature
  • 'kmeans': Standard k-means clustering
  • 'kmedoids': K-medoids (more robust to outliers)
  • 'pca': Principal component analysis
  • 'ica': Independent component analysis
  • 'aahc': Atomize and agglomerate hierarchical clustering

Parameters:

  • n_microstates: Number of microstate classes (typically 4-7)
  • normalize: Normalize topographies (recommended: True)
  • n_inits: Number of random initializations (increase for stability)

Returns:

  • Dictionary with:
    • 'maps': Microstate template topographies
    • 'labels': Microstate label at each time point
    • 'gfp': Global field power
    • 'gev': Global explained variance

microstates_findnumber()

Estimate the optimal number of microstates.

optimal_k = nk.microstates_findnumber(eeg_data, show=True)

Criteria:

  • Global Explained Variance (GEV): Percentage of variance explained
    • Elbow method: find "knee" in GEV curve
    • Typically 70-80% GEV achieved
  • Krzanowski-Lai (KL) Criterion: Statistical measure balancing fit and parsimony
    • Maximum KL indicates optimal k

Typical range: 4-7 microstates

  • 4 microstates: Classic A, B, C, D states
  • 5-7 microstates: Finer-grained decomposition

microstates_classify()

Reorder microstates based on anterior-posterior and left-right channel values.

classified = nk.microstates_classify(microstates)

Purpose:

  • Standardize microstate labels across subjects
  • Match conventional A, B, C, D topographies:
    • A: Left-right orientation, parieto-occipital
    • B: Right-left orientation, fronto-temporal
    • C: Anterior-posterior orientation, frontal-central
    • D: Fronto-central, anterior-posterior (inverse of C)

Returns:

  • Reordered microstate maps and labels

microstates_clean()

Preprocess EEG data for microstate extraction.

cleaned_eeg = nk.microstates_clean(eeg_data, sampling_rate=250)

Preprocessing steps:

  • Bandpass filtering (typically 2-20 Hz)
  • Artifact rejection
  • Bad channel interpolation
  • Re-referencing to average

Rationale:

  • Microstates reflect large-scale network activity
  • High-frequency and low-frequency artifacts can distort topographies

microstates_peaks()

Identify GFP peaks for microstate analysis.

peak_indices = nk.microstates_peaks(eeg_data, sampling_rate=250)

Purpose:

  • Microstates typically analyzed at GFP peaks
  • Peaks represent moments of maximal, stable topographic activity
  • Reduces computational load and noise sensitivity

Returns:

  • Indices of GFP local maxima

microstates_static()

Compute temporal properties of individual microstates.

static_metrics = nk.microstates_static(microstates)

Metrics:

  • Duration (ms): Mean time spent in each microstate
    • Typical: 80-120 ms
    • Reflects stability and persistence
  • Occurrence (per second): Frequency of microstate appearances
    • How often each state is entered
  • Coverage (%): Percentage of total time in each microstate
    • Relative dominance
  • Global Explained Variance (GEV): Variance explained by each class
    • Quality of template fit

Returns:

  • DataFrame with metrics for each microstate class

Interpretation:

  • Changes in duration: altered network stability
  • Changes in occurrence: shifting state dynamics
  • Changes in coverage: dominance of specific networks

microstates_dynamic()

Analyze transition patterns between microstates.

dynamic_metrics = nk.microstates_dynamic(microstates)

Metrics:

  • Transition matrix: Probability of transitioning from state i to state j
    • Reveals preferential sequences
  • Transition rate: Overall transition frequency
    • Higher rate: more rapid switching
  • Entropy: Randomness of transitions
    • High entropy: unpredictable switching
    • Low entropy: stereotyped sequences
  • Markov test: Are transitions history-dependent?

Returns:

  • Dictionary with transition statistics

Use cases:

  • Identify abnormal microstate sequences in clinical populations
  • Network dynamics and flexibility
  • State-dependent information processing

microstates_plot()

Visualize microstate topographies and time course.

nk.microstates_plot(microstates, eeg_data)

Displays:

  • Topographic maps for each microstate class
  • GFP trace with microstate labels
  • Transition plot showing state sequences
  • Statistical summary

MNE Integration Utilities

mne_data()

Access sample datasets from MNE-Python.

raw = nk.mne_data(dataset='sample', directory=None)

Available datasets:

  • 'sample': Multi-modal (MEG/EEG) example
  • 'ssvep': Steady-state visual evoked potentials
  • 'eegbci': Motor imagery BCI dataset

mne_to_df() / mne_to_dict()

Convert MNE objects to NeuroKit-compatible formats.

df = nk.mne_to_df(raw)
data_dict = nk.mne_to_dict(epochs)

Use case:

  • Work with MNE-processed data in NeuroKit2
  • Convert between formats for analysis

mne_channel_add() / mne_channel_extract()

Manage individual channels in MNE objects.

# Extract specific channels
subset = nk.mne_channel_extract(raw, ['Fz', 'Cz', 'Pz'])

# Add derived channels
raw_with_eog = nk.mne_channel_add(raw, new_channel_data, ch_name='EOG')

mne_crop()

Trim recordings by time or samples.

cropped = nk.mne_crop(raw, tmin=10, tmax=100)

mne_templateMRI()

Provide template anatomy for source localization.

subjects_dir = nk.mne_templateMRI()

Use case:

  • Source analysis without individual MRI
  • Group-level source localization
  • fsaverage template brain

eeg_simulate()

Generate synthetic EEG signals for testing.

synthetic_eeg = nk.eeg_simulate(duration=60, sampling_rate=250, n_channels=32)

Practical Considerations

Sampling Rate Recommendations

  • Minimum: 100 Hz for basic power analysis
  • Standard: 250-500 Hz for most applications
  • High-resolution: 1000+ Hz for detailed temporal dynamics

Recording Duration

  • Power analysis: ≥2 minutes for stable estimates
  • Microstates: ≥2-5 minutes, longer preferred
  • Resting state: 3-10 minutes typical
  • Event-related: Depends on trial count (≥30 trials per condition)

Artifact Management

  • Eye blinks: Remove with ICA or regression
  • Muscle artifacts: High-pass filter (≥1 Hz) or manual rejection
  • Bad channels: Detect and interpolate before analysis
  • Line noise: Notch filter at 50/60 Hz

Best Practices

Power analysis:

# 1. Clean data
cleaned = nk.signal_filter(eeg_data, sampling_rate=250, lowcut=0.5, highcut=45)

# 2. Identify and interpolate bad channels
bad = nk.eeg_badchannels(cleaned, sampling_rate=250)
# Interpolate bad channels using MNE

# 3. Re-reference
rereferenced = nk.eeg_rereference(cleaned, reference='average')

# 4. Compute power
power = nk.eeg_power(rereferenced, sampling_rate=250, channels=channel_list)

Microstate workflow:

# 1. Preprocess
cleaned = nk.microstates_clean(eeg_data, sampling_rate=250)

# 2. Determine optimal number of states
optimal_k = nk.microstates_findnumber(cleaned, show=True)

# 3. Segment microstates
microstates = nk.microstates_segment(cleaned, n_microstates=optimal_k,
                                     sampling_rate=250, method='kmod')

# 4. Classify to standard labels
microstates = nk.microstates_classify(microstates)

# 5. Compute temporal metrics
static = nk.microstates_static(microstates)
dynamic = nk.microstates_dynamic(microstates)

# 6. Visualize
nk.microstates_plot(microstates, cleaned)

Clinical and Research Applications

Cognitive neuroscience:

  • Attention, working memory, executive function
  • Language processing
  • Sensory perception

Clinical populations:

  • Epilepsy: seizure detection, localization
  • Alzheimer's disease: slowing of EEG, microstate alterations
  • Schizophrenia: altered microstates, especially state C
  • ADHD: increased theta/beta ratio
  • Depression: frontal alpha asymmetry

Consciousness research:

  • Anesthesia monitoring
  • Disorders of consciousness
  • Sleep staging

Neurofeedback:

  • Real-time frequency band training
  • Alpha enhancement for relaxation
  • Beta enhancement for focus

References

  • Michel, C. M., & Koenig, T. (2018). EEG microstates as a tool for studying the temporal dynamics of whole-brain neuronal networks: A review. Neuroimage, 180, 577-593.
  • Pascual-Marqui, R. D., Michel, C. M., & Lehmann, D. (1995). Segmentation of brain electrical activity into microstates: model estimation and validation. IEEE Transactions on Biomedical Engineering, 42(7), 658-665.
  • Gramfort, A., Luessi, M., Larson, E., Engemann, D. A., Strohmeier, D., Brodbeck, C., ... & Hämäläinen, M. (2013). MEG and EEG data analysis with MNE-Python. Frontiers in neuroscience, 7, 267.