Tutorial#
This tutorial shows how to use this package.
First, we import some modules and functions that come in handy later:
import numpy as np
from matplotlib import pyplot as plt
from scipy.stats import pearsonr
import mne
from invert import Solver
from invert.forward import get_info, create_forward_model
from invert.util import pos_from_forward
pp = dict(surface='white', hemi='both', verbose=0)
Next, we create a generic forward model using the freesurfer template fsaverage:
# Use a 64 channel EEG montage
info = get_info(kind='biosemi64')
# Create generic forward model
fwd = create_forward_model(info=info, sampling='ico3')
# Get the leadfield matrix for later use
leadfield = fwd["sol"]["data"]
n_chans, n_dipoles = leadfield.shape
# Get vertices (required for plotting later)
source_model = fwd['src']
vertices = [source_model[0]['vertno'], source_model[1]['vertno']]
Next, we simulate some EEG data. This is accomplished using the data generator function as follows:
from invert.solvers.esinet import generator
sim_params = dict(
use_cov=False,
return_mask=False,
batch_repetitions=1,
batch_size=1,
n_sources=7, # This controls the maximum number of sources/ source patches
n_orders=(0, 1), # This controls smoothness
snr_range=(10, 12), # This controls signal-to-noise ratio
n_timepoints=200, # This controls the number of time points
scale_data=False)
# initialize data generator
gen = generator(fwd, **sim_params)
# Generate a new batch:
x, y = gen.__next__()
# Some helper variables
tmin = 0
tstep = 1/info["sfreq"]
subject = "fsaverage"
# Create Evoked structure from simulated data
evoked = mne.EvokedArray(x[0].T, info, tmin=tmin)
# Create source estimate structure from simulated data
stc = mne.SourceEstimate(y[0].T, vertices, tmin=tmin, tstep=tstep,
subject=subject, verbose=0)
# Plot source and EEG
brain = stc.plot(**pp)
brain.add_text(0.1, 0.9, "Ground Truth", 'title',
font_size=14)
evoked.plot_joint(title="Ground Truth")
Now it is time to calculate an inverse solution of the EEG data (mne.Evoked object):
# Initialize a solver object:
solver = Solver("LCMV")
# Pre-compute inverse operator:
solver.make_inverse_operator(fwd, evoked, alpha="auto")
# Apply the pre-computed inverse operator:
stc_ = solver.apply_inverse_operator(evoked)
# Plot
brain = stc_.plot(**pp)
brain.add_text(0.1, 0.9, solver.name, 'title',
font_size=14)
# Plot the forward-projected EEG data
evoked_ = mne.EvokedArray(fwd["sol"]["data"] @ stc_.data, info).set_eeg_reference("average", projection=True)
evoked_.plot_joint()
The advantage of the invertmeeg package is that you can use a multitude of solvers to calculate inverse solutions and compare them. Let’s do this!
solver_names = ["HOCMCMV", "sLORETA", "MM Champagne", "FLEX-MUSIC"]
for solver_name in solver_names:
# Initialize a solver object:
solver = Solver(solver_name)
# Pre-compute inverse operator:
solver.make_inverse_operator(fwd, evoked, alpha="auto")
# Apply the pre-computed inverse operator:
stc_ = solver.apply_inverse_operator(evoked)
# Plot
brain = stc_.plot(**pp)
brain.add_text(0.1, 0.9, solver.name, 'title',
font_size=14)
# Plot the forward-projected EEG data
evoked_ = mne.EvokedArray(fwd["sol"]["data"] @ stc_.data, info).set_eeg_reference("average", projection=True)
evoked_.plot_joint()
You can find the solver_names for all solvers in the Solvers page in parantheses.