Skip to content

Instantly share code, notes, and snippets.

@nfoti
Created June 30, 2016 17:21
Show Gist options
  • Save nfoti/22158db5eb67d447e24d2d07728189a5 to your computer and use it in GitHub Desktop.
Save nfoti/22158db5eb67d447e24d2d07728189a5 to your computer and use it in GitHub Desktop.
import os.path as op
import numpy as np
import mne
from mne.datasets import sample
from mne.minimum_norm import read_inverse_operator, apply_inverse
from mne.simulation import simulate_stc, simulate_evoked
###############################################################################
# First, we set some parameters.
seed = 42
# regularization parameter for inverse method
method = 'sLORETA'
snr = 3.
lambda2 = 1.0 / snr ** 2
# signal simulation parameters
# Works fine for `evoked_snr = np.inf`, errors out for `evoked_snr = 3.`.
evoked_snr = 3. #np.inf
T = 100
times = np.linspace(0, 1, T)
dt = times[1] - times[0]
# Paths to MEG data
data_path = sample.data_path()
subjects_dir = op.join(data_path, 'subjects/')
fname_fwd = op.join(data_path, 'MEG', 'sample',
'sample_audvis-meg-oct-6-fwd.fif')
fname_inv = op.join(data_path, 'MEG', 'sample',
'sample_audvis-meg-oct-6-meg-fixed-inv.fif')
fname_evoked = op.join(data_path, 'MEG', 'sample',
'sample_audvis-ave.fif')
subject_dir = op.join(data_path, 'subjects/')
###############################################################################
# Load the MEG data
# -----------------
fwd = mne.read_forward_solution(fname_fwd, force_fixed=True,
surf_ori=True)
inv_op = read_inverse_operator(fname_inv)
raw = mne.io.RawFIF(op.join(data_path, 'MEG', 'sample',
'sample_audvis_raw.fif'))
events = mne.find_events(raw)
event_id = {'Auditory/Left': 1, 'Auditory/Right': 2}
epochs = mne.Epochs(raw, events, event_id,
baseline=(None, 0),
preload=True)
evoked = epochs.average()
labels = mne.read_labels_from_annot('sample', subjects_dir=subject_dir)
label_names = [l.name for l in labels]
n_labels = len(labels)
###############################################################################
# Estimate the background noise covariance from the baseline period
# -----------------------------------------------------------------
cov = mne.compute_covariance(epochs, tmin=None, tmax=0.)
###############################################################################
# Generate sinusoids in two spatially distant labels
# --------------------------------------------------
# The known signal is all zero-s off of the two labels of interest
signal = np.zeros((n_labels, T))
idx = label_names.index('inferiorparietal-lh')
signal[idx, :] = 1e-7 * np.sin(5 * 2 * np.pi * times)
###############################################################################
# Find the center vertices in source space of each label
# ------------------------------------------------------
#
# We want the known signal in each label to only be active at the center. We
# create a mask for each label that is 1 at the center vertex and 0 at all
# other vertices in the label. This mask is then used when simulating
# source-space data.
hemi_to_ind = {'lh': 0, 'rh': 1}
for i, label in enumerate(labels):
# The `center_of_mass` function needs labels to have values.
labels[i].values.fill(1.)
# Restrict the eligible vertices to be those on the surface under
# consideration and within the label.
surf_vertices = fwd['src'][hemi_to_ind[label.hemi]]['vertno']
restrict_verts = np.intersect1d(surf_vertices, label.vertices)
com = labels[i].center_of_mass(subject='sample',
subjects_dir=subject_dir,
restrict_vertices=restrict_verts,
surf='white')
# Convert the center of vertex index from surface vertex list to Label's
# vertex list.
cent_idx = np.where(label.vertices == com)[0][0]
# Create a mask with 1 at center vertex and zeros elsewhere.
labels[i].values.fill(0.)
labels[i].values[cent_idx] = 1.
###############################################################################
# Create source-space data with known signals
# -------------------------------------------
#
# Put known signals onto surface vertices using the array of signals and
# the label masks (stored in labels[i].values).
stc_gen = simulate_stc(fwd['src'], labels, signal, times[0], dt,
value_fun=lambda x: x)
###############################################################################
# Simulate sensor-space signals
# -----------------------------
#
# Use the foward solution and add Gaussian noise to simulate sensor-space
# (evoked) data from the known source-space signals. The amount of noise is
# controlled by `evoked_snr` (higher values imply less noise).
#
evoked_gen = simulate_evoked(fwd, stc_gen, evoked.info, cov, evoked_snr,
tmin=0., tmax=1., random_state=seed)
# Map the simulated sensor-space data to source-space using the inverse
# operator.
stc_inv = apply_inverse(evoked_gen, inv_op, lambda2, method=method)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment