Hi all,
I want to forwad model EEG data from simulated source activity. I have two questions
- My intuition would be to average-reference the simulated EEG but in your tutorial you apply set_eeg_reference(projection=True), which I believe makes the simulated EEG reference-free. Is there a particular reason why you’d do that?
- My simulation has 1000 cortical regions. So far, I have assigned the same simulated cortical activity to several sources per region and fixed the dipole orientation. Testing this looks fine but the simulate_raw() function takes ages, which makes me wonder if there’s a good way to reduce my source space to 1000 simulated regions/sources?
This is how I prepare the forward model:
# Download fsaverage files
fs_dir = Path(mne.datasets.fetch_fsaverage(verbose=True))
trans = "fsaverage"
src = fs_dir / "bem" / "fsaverage-ico-5-src.fif"
bem = fs_dir / "bem" / "fsaverage-5120-5120-5120-bem-sol.fif"
# get the montage
easycap_montage = mne.channels.make_standard_montage("easycap-M1")
# Create info of EEG data
info = mne.create_info(easycap_montage.ch_names, sfreq=sfreq, ch_types='eeg')
info.set_montage(easycap_montage)
# Get regions from parcellation
subject_path = os.path.join(project_root, derivatives_path, 'structural_connectivity/Schaefer1000')
regions = np.array(mne.read_labels_from_annot('fsaverage', 'Schaefer2018_1000Parcels_17Networks_order', 'both', surf_name='pial', subjects_dir=subject_path, sort=False))
regions = list(regions[["background" not in r.name.lower() for r in regions]]) # remove background
# Create forward model
fwd = mne.make_forward_solution(info, trans=trans, src=src, bem=bem, eeg=True, n_jobs=None)
fwd = mne.forward.restrict_forward_to_label(fwd, regions)
mne.write_forward_solution(os.path.join(project_root, fwd_path), fwd, overwrite=True)
This is how I use it for the simulations:
# Get montage
easycap_montage = mne.channels.make_standard_montage(montage)
# Create info for simulated EEG data
info = mne.create_info(easycap_montage.ch_names, sfreq=sfreq, ch_types='eeg')
info.set_montage(easycap_montage)
# Prepare forward model
fwd = mne.read_forward_solution(fwd_path)
fwd = mne.convert_forward_solution(fwd, force_fixed=True, surf_ori=True, use_cps=True)
subject_path = os.path.join(project_root, derivatives_path, 'structural_connectivity/Schaefer1000')
regions = np.array(mne.read_labels_from_annot('fsaverage', 'Schaefer2018_1000Parcels_17Networks_order', 'both', surf_name='pial', subjects_dir=subject_path, sort=False))
regions = list(regions[["background" not in r.name.lower() for r in regions]]) # remove medial wall
# Prepare source space
src_space = fwd['src']
# Assign simulations to source space
source_simulator = mne.simulation.SourceSimulator(src_space, tstep=time_step_in_seconds)
events = np.array([[ 0, 0, 1]])
for i, s in enumerate(regions):
source_simulator.add_data(s, simulated_lfp[i], events)
# Simulate raw EEG
info["dev_head_t"] = fwd["info"]["dev_head_t"] # throws error if they don't match
raw = mne.simulation.simulate_raw(info, source_simulator, forward=fwd, n_jobs=1)
raw.set_eeg_reference(projection=True)
Thanks for your help!
Setup
MNE 1.11.0
MacOS 15.6