Created
June 30, 2016 17:21
-
-
Save nfoti/22158db5eb67d447e24d2d07728189a5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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