def _simulate_data(fwd, idx): # Somewhere on the frontal lobe by default """Simulate an oscillator on the cortex.""" source_vertno = fwd['src'][0]['vertno'][idx] sfreq = 50. # Hz. times = np.arange(10 * sfreq) / sfreq # 10 seconds of data signal = np.sin(20 * 2 * np.pi * times) # 20 Hz oscillator signal[:len(times) // 2] *= 2 # Make signal louder at the beginning signal *= 1e-9 # Scale to be in the ballpark of MEG data # Construct a SourceEstimate object that describes the signal at the # cortical level. stc = mne.SourceEstimate( signal[np.newaxis, :], vertices=[[source_vertno], []], tmin=0, tstep=1 / sfreq, subject='sample', ) # Create an info object that holds information about the sensors info = mne.create_info(fwd['info']['ch_names'], sfreq, ch_types='grad') info.update(fwd['info']) # Merge in sensor position information # heavily decimate sensors to make it much faster info = mne.pick_info(info, np.arange(info['nchan'])[::5]) fwd = mne.pick_channels_forward(fwd, info['ch_names']) # Run the simulated signal through the forward model, obtaining # simulated sensor data. raw = mne.apply_forward_raw(fwd, stc, info) # Add a little noise random = np.random.RandomState(42) noise = random.randn(*raw._data.shape) * 1e-14 raw._data += noise # Define a single epoch (weird baseline but shouldn't matter) epochs = mne.Epochs(raw, [[0, 0, 1]], event_id=1, tmin=0, tmax=raw.times[-1], baseline=(0., 0.), preload=True) evoked = epochs.average() # Compute the cross-spectral density matrix csd = csd_morlet(epochs, frequencies=[10, 20], n_cycles=[5, 10], decim=10) labels = mne.read_labels_from_annot('sample', hemi='lh', subjects_dir=subjects_dir) label = [ label for label in labels if np.in1d(source_vertno, label.vertices)[0] ] assert len(label) == 1 label = label[0] vertices = np.intersect1d(label.vertices, fwd['src'][0]['vertno']) source_ind = vertices.tolist().index(source_vertno) assert vertices[source_ind] == source_vertno return epochs, evoked, csd, source_vertno, label, vertices, source_ind
def test_apply_forward(): """Test projection of source space data to sensor space.""" start = 0 stop = 5 n_times = stop - start - 1 sfreq = 10.0 t_start = 0.123 fwd = read_forward_solution(fname_meeg) fwd = convert_forward_solution(fwd, surf_ori=True, force_fixed=True, use_cps=True) fwd = pick_types_forward(fwd, meg=True) assert isinstance(fwd, Forward) vertno = [fwd['src'][0]['vertno'], fwd['src'][1]['vertno']] stc_data = np.ones((len(vertno[0]) + len(vertno[1]), n_times)) stc = SourceEstimate(stc_data, vertno, tmin=t_start, tstep=1.0 / sfreq) gain_sum = np.sum(fwd['sol']['data'], axis=1) # Evoked evoked = read_evokeds(fname_evoked, condition=0) evoked.pick_types(meg=True) with pytest.warns(RuntimeWarning, match='only .* positive values'): evoked = apply_forward(fwd, stc, evoked.info, start=start, stop=stop) data = evoked.data times = evoked.times # do some tests assert_array_almost_equal(evoked.info['sfreq'], sfreq) assert_array_almost_equal(np.sum(data, axis=1), n_times * gain_sum) assert_array_almost_equal(times[0], t_start) assert_array_almost_equal(times[-1], t_start + (n_times - 1) / sfreq) # vector stc_vec = VectorSourceEstimate( fwd['source_nn'][:, :, np.newaxis] * stc.data[:, np.newaxis], stc.vertices, stc.tmin, stc.tstep) with pytest.warns(RuntimeWarning, match='very large'): evoked_2 = apply_forward(fwd, stc_vec, evoked.info) assert np.abs(evoked_2.data).mean() > 1e-5 assert_allclose(evoked.data, evoked_2.data, atol=1e-10) # Raw with pytest.warns(RuntimeWarning, match='only .* positive values'): raw_proj = apply_forward_raw(fwd, stc, evoked.info, start=start, stop=stop) data, times = raw_proj[:, :] # do some tests assert_array_almost_equal(raw_proj.info['sfreq'], sfreq) assert_array_almost_equal(np.sum(data, axis=1), n_times * gain_sum) atol = 1. / sfreq assert_allclose(raw_proj.first_samp / sfreq, t_start, atol=atol) assert_allclose(raw_proj.last_samp / sfreq, t_start + (n_times - 1) / sfreq, atol=atol)
def _simulate_data(fwd_fixed, source_vertno1, source_vertno2): """Simulate two oscillators on the cortex.""" sfreq = 50. # Hz. base_freq = 10 t_rand = 0.001 std = 0.1 times = np.arange(10. * sfreq) / sfreq # 10 seconds of data n_times = len(times) # Generate an oscillator with varying frequency and phase lag. iflaw = base_freq / sfreq + t_rand * np.random.randn(n_times) signal1 = np.exp(1j * 2.0 * np.pi * np.cumsum(iflaw)) signal1 *= np.conj(signal1[0]) signal1 = signal1.real # Add some random fluctuations to the signal. signal1 += std * np.random.randn(n_times) signal1 *= 1e-7 # Make identical signal signal2 = signal1.copy() # Add random fluctuations signal1 += 1e-8 * np.random.randn(len(times)) signal2 += 1e-8 * np.random.randn(len(times)) # Construct a SourceEstimate object stc = mne.SourceEstimate( np.vstack((signal1[np.newaxis, :], signal2[np.newaxis, :])), vertices=[np.array([source_vertno1]), np.array([source_vertno2])], tmin=0, tstep=1 / sfreq, subject='sample', ) # Create an info object that holds information about the sensors info = mne.create_info(fwd_fixed['info']['ch_names'], sfreq, ch_types='grad') info.update(fwd_fixed['info']) # Merge in sensor position information # Simulated sensor data. raw = mne.apply_forward_raw(fwd_fixed, stc, info) # Add noise noise = random.randn(*raw._data.shape) * 1e-14 raw._data += noise # Define a single epoch epochs = mne.Epochs(raw, np.array([[0, 0, 1]]), event_id=1, tmin=0, tmax=raw.times[-1], preload=True, baseline=(0, 0)) # Compute the cross-spectral density matrix csd = csd_morlet(epochs, frequencies=[10, 20]) return csd
def test_apply_forward(): """Test projection of source space data to sensor space """ start = 0 stop = 5 n_times = stop - start - 1 sfreq = 10.0 t_start = 0.123 fwd = read_forward_solution(fname_meeg) fwd = convert_forward_solution(fwd, surf_ori=True, force_fixed=True, use_cps=True) fwd = pick_types_forward(fwd, meg=True) assert_true(isinstance(fwd, Forward)) vertno = [fwd['src'][0]['vertno'], fwd['src'][1]['vertno']] stc_data = np.ones((len(vertno[0]) + len(vertno[1]), n_times)) stc = SourceEstimate(stc_data, vertno, tmin=t_start, tstep=1.0 / sfreq) gain_sum = np.sum(fwd['sol']['data'], axis=1) # Evoked with warnings.catch_warnings(record=True) as w: evoked = read_evokeds(fname_evoked, condition=0) evoked.pick_types(meg=True) evoked = apply_forward(fwd, stc, evoked.info, start=start, stop=stop) assert_equal(len(w), 2) data = evoked.data times = evoked.times # do some tests assert_array_almost_equal(evoked.info['sfreq'], sfreq) assert_array_almost_equal(np.sum(data, axis=1), n_times * gain_sum) assert_array_almost_equal(times[0], t_start) assert_array_almost_equal(times[-1], t_start + (n_times - 1) / sfreq) # Raw raw_proj = apply_forward_raw(fwd, stc, evoked.info, start=start, stop=stop) data, times = raw_proj[:, :] # do some tests assert_array_almost_equal(raw_proj.info['sfreq'], sfreq) assert_array_almost_equal(np.sum(data, axis=1), n_times * gain_sum) atol = 1. / sfreq assert_allclose(raw_proj.first_samp / sfreq, t_start, atol=atol) assert_allclose(raw_proj.last_samp / sfreq, t_start + (n_times - 1) / sfreq, atol=atol)
def _simulate_data(fwd): """Simulate an oscillator on the cortex.""" source_vertno = 146374 # Somewhere on the frontal lobe sfreq = 50. # Hz. times = np.arange(10 * sfreq) / sfreq # 10 seconds of data signal = np.sin(20 * 2 * np.pi * times) # 20 Hz oscillator signal[:len(times) // 2] *= 2 # Make signal louder at the beginning signal *= 1e-9 # Scale to be in the ballpark of MEG data # Construct a SourceEstimate object that describes the signal at the # cortical level. stc = mne.SourceEstimate( signal[np.newaxis, :], vertices=[[source_vertno], []], tmin=0, tstep=1 / sfreq, subject='sample', ) # Create an info object that holds information about the sensors info = mne.create_info(fwd['info']['ch_names'], sfreq, ch_types='grad') info.update(fwd['info']) # Merge in sensor position information # heavily decimate sensors to make it much faster info = mne.pick_info(info, np.arange(info['nchan'])[::5]) fwd = mne.pick_channels_forward(fwd, info['ch_names']) # Run the simulated signal through the forward model, obtaining # simulated sensor data. raw = mne.apply_forward_raw(fwd, stc, info) # Add a little noise random = np.random.RandomState(42) noise = random.randn(*raw._data.shape) * 1e-14 raw._data += noise # Define a single epoch epochs = mne.Epochs(raw, [[0, 0, 1]], event_id=1, tmin=0, tmax=raw.times[-1], preload=True) evoked = epochs.average() # Compute the cross-spectral density matrix csd = csd_morlet(epochs, frequencies=[10, 20], n_cycles=[5, 10], decim=10) return epochs, evoked, csd, source_vertno
def test_apply_forward(): """Test projection of source space data to sensor space """ start = 0 stop = 5 n_times = stop - start - 1 sfreq = 10.0 t_start = 0.123 fwd = read_forward_solution(fname, force_fixed=True) fwd = pick_types_forward(fwd, meg=True) vertno = [fwd['src'][0]['vertno'], fwd['src'][1]['vertno']] stc_data = np.ones((len(vertno[0]) + len(vertno[1]), n_times)) stc = SourceEstimate(stc_data, vertno, tmin=t_start, tstep=1.0 / sfreq) gain_sum = np.sum(fwd['sol']['data'], axis=1) # Evoked with warnings.catch_warnings(record=True) as w: evoked = Evoked(fname_evoked, setno=0) evoked = apply_forward(fwd, stc, evoked, start=start, stop=stop) assert_equal(len(w), 2) data = evoked.data times = evoked.times # do some tests assert_array_almost_equal(evoked.info['sfreq'], sfreq) assert_array_almost_equal(np.sum(data, axis=1), n_times * gain_sum) assert_array_almost_equal(times[0], t_start) assert_array_almost_equal(times[-1], t_start + (n_times - 1) / sfreq) # Raw raw = Raw(fname_raw) raw_proj = apply_forward_raw(fwd, stc, raw, start=start, stop=stop) data, times = raw_proj[:, :] # do some tests assert_array_almost_equal(raw_proj.info['sfreq'], sfreq) assert_array_almost_equal(np.sum(data, axis=1), n_times * gain_sum) assert_array_almost_equal(times[0], t_start) assert_array_almost_equal(times[-1], t_start + (n_times - 1) / sfreq)
# Use only gradiometers fwd = mne.pick_types_forward(fwd, meg='grad', eeg=False, exclude='bads') # Create an info object that holds information about the sensors (their # location, etc.). info = mne.create_info(fwd['info']['ch_names'], sfreq, ch_types='grad') info.update(fwd['info']) # To simulate the data, we need a version of the forward solution where each # source has a "fixed" orientation, i.e. pointing orthogonally to the surface # of the cortex. fwd_fixed = mne.convert_forward_solution(fwd, force_fixed=True) # Now we can run our simulated signal through the forward model, obtaining # simulated sensor data. sensor_data = mne.apply_forward_raw(fwd_fixed, stc, info).get_data() # We're going to add some noise to the sensor data noise = np.random.randn(*sensor_data.shape) # Scale the noise to be in the ballpark of MEG data noise_scaling = np.linalg.norm(sensor_data) / np.linalg.norm(noise) noise *= noise_scaling # Mix noise and signal with the given signal-to-noise ratio. sensor_data = SNR * sensor_data + noise ############################################################################### # We create an :class:`mne.EpochsArray` object containing two trials: one with # just noise and one with both noise and signal. The techniques we'll be # using in this tutorial depend on being able to contrast data that contains