def test_source_simulator(_get_fwd_labels): """Test Source Simulator.""" fwd, _ = _get_fwd_labels src = fwd['src'] hemi_to_ind = {'lh': 0, 'rh': 1} tstep = 1. / 6. label_vertices = [[], [], []] label_vertices[0] = np.arange(1000) label_vertices[1] = np.arange(500, 1500) label_vertices[2] = np.arange(1000) hemis = ['lh', 'lh', 'rh'] mylabels = [] src_vertices = [] for i, vert in enumerate(label_vertices): new_label = Label(vertices=vert, hemi=hemis[i]) mylabels.append(new_label) src_vertices.append(np.intersect1d( src[hemi_to_ind[hemis[i]]]['vertno'], new_label.vertices)) wfs = [[], [], []] wfs[0] = np.array([0, 1., 0]) # 1d array wfs[1] = [np.array([0, 1., 0]), # list np.array([0, 1.5, 0])] wfs[2] = np.array([[1, 1, 1.]]) # 2d array events = [[], [], []] events[0] = np.array([[0, 0, 1], [3, 0, 1]]) events[1] = np.array([[0, 0, 1], [3, 0, 1]]) events[2] = np.array([[0, 0, 1], [2, 0, 1]]) verts_lh = np.intersect1d(range(1500), src[0]['vertno']) verts_rh = np.intersect1d(range(1000), src[1]['vertno']) diff_01 = len(np.setdiff1d(src_vertices[0], src_vertices[1])) diff_10 = len(np.setdiff1d(src_vertices[1], src_vertices[0])) inter_10 = len(np.intersect1d(src_vertices[1], src_vertices[0])) output_data_lh = np.zeros([len(verts_lh), 6]) tmp = np.array([0, 1., 0, 0, 1, 0]) output_data_lh[:diff_01, :] = np.tile(tmp, (diff_01, 1)) tmp = np.array([0, 2, 0, 0, 2.5, 0]) output_data_lh[diff_01:diff_01 + inter_10, :] = np.tile(tmp, (inter_10, 1)) tmp = np.array([0, 1, 0, 0, 1.5, 0]) output_data_lh[diff_01 + inter_10:, :] = np.tile(tmp, (diff_10, 1)) data_rh_wf = np.array([1., 1, 2, 1, 1, 0]) output_data_rh = np.tile(data_rh_wf, (len(src_vertices[2]), 1)) output_data = np.vstack([output_data_lh, output_data_rh]) ss = SourceSimulator(src, tstep) for i in range(3): ss.add_data(mylabels[i], wfs[i], events[i]) stc = ss.get_stc() stim_channel = ss.get_stim_channel() # Stim channel data must have the same size as stc time samples assert len(stim_channel) == stc.data.shape[1] stim_channel = ss.get_stim_channel(0, 0) assert len(stim_channel) == 0 assert np.all(stc.vertices[0] == verts_lh) assert np.all(stc.vertices[1] == verts_rh) assert_array_almost_equal(stc.lh_data, output_data_lh) assert_array_almost_equal(stc.rh_data, output_data_rh) assert_array_almost_equal(stc.data, output_data) counter = 0 for stc, stim in ss: assert stc.data.shape[1] == 6 counter += 1 assert counter == 1 half_ss = SourceSimulator(src, tstep, duration=0.5) for i in range(3): half_ss.add_data(mylabels[i], wfs[i], events[i]) half_stc = half_ss.get_stc() assert_array_almost_equal(stc.data[:, :3], half_stc.data) ss = SourceSimulator(src) with pytest.raises(ValueError, match='No simulation parameters'): ss.get_stc() with pytest.raises(ValueError, match='label must be a Label'): ss.add_data(1, wfs, events) with pytest.raises(ValueError, match='Number of waveforms and events ' 'should match'): ss.add_data(mylabels[0], wfs[:2], events) # Verify that the chunks have the correct length. source_simulator = SourceSimulator(src, tstep=tstep, duration=10 * tstep) source_simulator.add_data(mylabels[0], np.array([1, 1, 1]), [[0, 0, 0]]) source_simulator._chk_duration = 6 # Quick hack to get short chunks. stcs = [stc for stc, _ in source_simulator] assert len(stcs) == 2 assert stcs[0].data.shape[1] == 6 assert stcs[1].data.shape[1] == 4
def test_source_simulator(): """Test Source Simulator.""" fwd = read_forward_solution_meg(fname_fwd, force_fixed=True, use_cps=True) src = fwd['src'] hemi_to_ind = {'lh': 0, 'rh': 1} tmin = 0 tstep = 1. / 6. label_vertices = [[], [], []] label_vertices[0] = np.arange(1000) label_vertices[1] = np.arange(500, 1500) label_vertices[2] = np.arange(1000) hemis = ['lh', 'lh', 'rh'] mylabels = [] src_vertices = [] for i, vert in enumerate(label_vertices): new_label = Label(vertices=vert, hemi=hemis[i]) mylabels.append(new_label) src_vertices.append( np.intersect1d(src[hemi_to_ind[hemis[i]]]['vertno'], new_label.vertices)) wfs = [[], [], []] wfs[0] = np.array([0, 1., 0]) wfs[1] = [np.array([0, 1., 0]), np.array([0, 1.5, 0])] wfs[2] = np.array([1, 1, 1.]) events = [[], [], []] events[0] = np.array([[0, 0, 1], [3, 0, 1]]) events[1] = np.array([[0, 0, 1], [3, 0, 1]]) events[2] = np.array([[0, 0, 1], [2, 0, 1]]) verts_lh = np.intersect1d(range(1500), src[0]['vertno']) verts_rh = np.intersect1d(range(1000), src[1]['vertno']) diff_01 = len(np.setdiff1d(src_vertices[0], src_vertices[1])) diff_10 = len(np.setdiff1d(src_vertices[1], src_vertices[0])) inter_10 = len(np.intersect1d(src_vertices[1], src_vertices[0])) output_data_lh = np.zeros([len(verts_lh), 6]) tmp = np.array([0, 1., 0, 0, 1, 0]) output_data_lh[:diff_01, :] = np.tile(tmp, (diff_01, 1)) tmp = np.array([0, 2, 0, 0, 2.5, 0]) output_data_lh[diff_01:diff_01 + inter_10, :] = np.tile(tmp, (inter_10, 1)) tmp = np.array([0, 1, 0, 0, 1.5, 0]) output_data_lh[diff_01 + inter_10:, :] = np.tile(tmp, (diff_10, 1)) data_rh_wf = np.array([1., 1, 2, 1, 1, 0]) output_data_rh = np.tile(data_rh_wf, (len(src_vertices[2]), 1)) output_data = np.vstack([output_data_lh, output_data_rh]) ss = SourceSimulator(src, tmin, tstep) for i in range(3): ss.add_data(mylabels[i], wfs[i], events[i]) stc = ss.get_stc() stim_channel = ss.get_stim_channel() # Stim channel data must have the same size as stc time samples assert (len(stim_channel) == stc.data.shape[1]) stim_channel = ss.get_stim_channel(0., 0.) assert (len(stim_channel) == 0) assert (np.all(stc.vertices[0] == verts_lh)) assert (np.all(stc.vertices[1] == verts_rh)) assert_array_almost_equal(stc.lh_data, output_data_lh) assert_array_almost_equal(stc.rh_data, output_data_rh) assert_array_almost_equal(stc.data, output_data) counter = 0 for stc, stim in ss: counter += 1 assert counter == 1 half_ss = SourceSimulator(src, tmin, tstep, duration=0.5) for i in range(3): half_ss.add_data(mylabels[i], wfs[i], events[i]) half_stc = half_ss.get_stc() assert_array_almost_equal(stc.data[:, :3], half_stc.data) ss = SourceSimulator(src) with pytest.raises(ValueError, match='No simulation parameters'): ss.get_stc() with pytest.raises(ValueError, match='label must be a Label'): ss.add_data(1, wfs, events) with pytest.raises(ValueError, match='Number of waveforms and events ' 'should match'): ss.add_data(mylabels[0], wfs[:2], events)
def test_simulate_raw_bem(raw_data): """Test simulation of raw data with BEM.""" raw, src_ss, stc, trans, sphere = raw_data src = setup_source_space('sample', 'oct1', subjects_dir=subjects_dir) for s in src: s['nuse'] = 3 s['vertno'] = src[1]['vertno'][:3] s['inuse'].fill(0) s['inuse'][s['vertno']] = 1 # use different / more complete STC here vertices = [s['vertno'] for s in src] stc = SourceEstimate(np.eye(sum(len(v) for v in vertices)), vertices, 0, 1. / raw.info['sfreq']) stcs = [stc] * 15 raw_sim_sph = simulate_raw(raw.info, stcs, trans, src, sphere) raw_sim_bem = simulate_raw(raw.info, stcs, trans, src, bem_fname) # some components (especially radial) might not match that well, # so just make sure that most components have high correlation assert_array_equal(raw_sim_sph.ch_names, raw_sim_bem.ch_names) picks = pick_types(raw.info, meg=True, eeg=True) n_ch = len(picks) corr = np.corrcoef(raw_sim_sph[picks][0], raw_sim_bem[picks][0]) assert_array_equal(corr.shape, (2 * n_ch, 2 * n_ch)) med_corr = np.median(np.diag(corr[:n_ch, -n_ch:])) assert med_corr > 0.65 # do some round-trip localization for s in src: transform_surface_to(s, 'head', trans) locs = np.concatenate([s['rr'][s['vertno']] for s in src]) tmax = (len(locs) - 1) / raw.info['sfreq'] cov = make_ad_hoc_cov(raw.info) # The tolerance for the BEM is surprisingly high (28) but I get the same # result when using MNE-C and Xfit, even when using a proper 5120 BEM :( for use_raw, bem, tol in ((raw_sim_sph, sphere, 2), (raw_sim_bem, bem_fname, 31)): events = find_events(use_raw, 'STI 014') assert len(locs) == 6 evoked = Epochs(use_raw, events, 1, 0, tmax, baseline=None).average() assert len(evoked.times) == len(locs) fits = fit_dipole(evoked, cov, bem, trans, min_dist=1.)[0].pos diffs = np.sqrt(np.sum((locs - fits)**2, axis=-1)) * 1000 med_diff = np.median(diffs) assert med_diff < tol, '%s: %s' % (bem, med_diff) # also test event timings with SourceSimulator first_samp = raw.first_samp events = find_events(raw, initial_event=True, verbose=False) evt_times = events[:, 0] assert len(events) == 3 labels_sim = [[], [], []] # random l+r hemisphere points labels_sim[0] = Label([src_ss[0]['vertno'][1]], hemi='lh') labels_sim[1] = Label([src_ss[0]['vertno'][4]], hemi='lh') labels_sim[2] = Label([src_ss[1]['vertno'][2]], hemi='rh') wf_sim = np.array([2, 1, 0]) for this_fs in (0, first_samp): ss = SourceSimulator(src_ss, 1. / raw.info['sfreq'], first_samp=this_fs) for i in range(3): ss.add_data(labels_sim[i], wf_sim, events[np.newaxis, i]) assert ss.n_times == evt_times[-1] + len(wf_sim) - this_fs raw_sim = simulate_raw(raw.info, ss, src=src_ss, bem=bem_fname, first_samp=first_samp) data = raw_sim.get_data() amp0 = data[:, evt_times - first_samp].max() amp1 = data[:, evt_times + 1 - first_samp].max() amp2 = data[:, evt_times + 2 - first_samp].max() assert_allclose(amp0 / amp1, wf_sim[0] / wf_sim[1], rtol=1e-5) assert amp2 == 0 assert raw_sim.n_times == ss.n_times