def test_io_dipoles(tmpdir): """Test IO for .dip files.""" dipole = read_dipole(fname_dip) assert 'Dipole ' in repr(dipole) # test repr out_fname = op.join(str(tmpdir), 'temp.dip') dipole.save(out_fname) dipole_new = read_dipole(out_fname) _compare_dipoles(dipole, dipole_new)
def test_io_dipoles(): """Test IO for .dip files.""" tempdir = _TempDir() dipole = read_dipole(fname_dip) print(dipole) # test repr out_fname = op.join(tempdir, 'temp.dip') dipole.save(out_fname) dipole_new = read_dipole(out_fname) _compare_dipoles(dipole, dipole_new)
def test_dipole_fixed(): """Test reading a fixed-position dipole (from Xfit).""" dip = read_dipole(fname_xfit_dip) _check_roundtrip_fixed(dip) with warnings.catch_warnings(record=True) as w: # unused fields dip_txt = read_dipole(fname_xfit_dip_txt) assert_true(any('extra fields' in str(ww.message) for ww in w)) assert_allclose(dip.info['chs'][0]['loc'][:3], dip_txt.pos[0]) assert_allclose(dip_txt.amplitude[0], 12.1e-9) with warnings.catch_warnings(record=True): # unused fields dip_txt_seq = read_dipole(fname_xfit_seq_txt) assert_allclose(dip_txt_seq.gof, [27.3, 46.4, 43.7, 41., 37.3, 32.5])
def test_dipole_fixed(): """Test reading a fixed-position dipole (from Xfit).""" dip = read_dipole(fname_xfit_dip) # print the representation of the object DipoleFixed print(dip) _check_roundtrip_fixed(dip) with pytest.warns(RuntimeWarning, match='extra fields'): dip_txt = read_dipole(fname_xfit_dip_txt) assert_allclose(dip.info['chs'][0]['loc'][:3], dip_txt.pos[0]) assert_allclose(dip_txt.amplitude[0], 12.1e-9) with pytest.warns(RuntimeWarning, match='extra fields'): dip_txt_seq = read_dipole(fname_xfit_seq_txt) assert_allclose(dip_txt_seq.gof, [27.3, 46.4, 43.7, 41., 37.3, 32.5])
def test_dipole_fixed(): """Test reading a fixed-position dipole (from Xfit)""" tempdir = _TempDir() dip = read_dipole(fname_xfit_dip) dip.save(op.join(tempdir, 'test-dip.fif.gz')) dip_read = read_dipole(op.join(tempdir, 'test-dip.fif.gz')) assert_allclose(dip_read.data, dip_read.data) assert_allclose(dip_read.times, dip.times) assert_equal(dip_read.info['xplotter_layout'], dip.info['xplotter_layout']) assert_equal(dip_read.ch_names, dip.ch_names) for ch_1, ch_2 in zip(dip_read.info['chs'], dip.info['chs']): assert_equal(ch_1['ch_name'], ch_2['ch_name']) for key in ('loc', 'kind', 'unit_mul', 'range', 'coord_frame', 'unit', 'cal', 'coil_type', 'scanno', 'logno'): assert_allclose(ch_1[key], ch_2[key], err_msg=key)
def test_plot_dipole_locations(): """Test plotting dipole locations.""" dipoles = read_dipole(dip_fname) trans = read_trans(trans_fname) dipoles.plot_locations(trans, 'sample', subjects_dir, fig_name='foo') assert_raises(ValueError, dipoles.plot_locations, trans, 'sample', subjects_dir, mode='foo')
def test_plot_dipole_locations(): """Test plotting dipole locations """ dipoles = read_dipole(dip_fname) trans = read_trans(trans_fname) dipoles.plot_locations(trans, 'sample', subjects_dir, fig_name='foo') assert_raises(ValueError, dipoles.plot_locations, trans, 'sample', subjects_dir, mode='foo')
def test_confidence(tmpdir): """Test confidence limits.""" evoked = read_evokeds(fname_evo_full, 'Left Auditory', baseline=(None, 0)) evoked.crop(0.08, 0.08).pick_types() # MEG-only cov = make_ad_hoc_cov(evoked.info) sphere = make_sphere_model((0., 0., 0.04), 0.08) dip_py = fit_dipole(evoked, cov, sphere)[0] fname_test = op.join(str(tmpdir), 'temp-dip.txt') dip_py.save(fname_test) dip_read = read_dipole(fname_test) with pytest.warns(RuntimeWarning, match="'noise/ft/cm', 'prob'"): dip_xfit = read_dipole(fname_dip_xfit) for dip_check in (dip_py, dip_read): assert_allclose(dip_check.pos, dip_xfit.pos, atol=5e-4) # < 0.5 mm assert_allclose(dip_check.gof, dip_xfit.gof, atol=5e-1) # < 0.5% assert_array_equal(dip_check.nfree, dip_xfit.nfree) # exact match assert_allclose(dip_check.khi2, dip_xfit.khi2, rtol=2e-2) # 2% miss assert set(dip_check.conf.keys()) == set(dip_xfit.conf.keys()) for key in sorted(dip_check.conf.keys()): assert_allclose(dip_check.conf[key], dip_xfit.conf[key], rtol=1.5e-1, err_msg=key)
def test_len_index_dipoles(): """Test len and indexing of Dipole objects.""" dipole = read_dipole(fname_dip) d0 = dipole[0] d1 = dipole[:1] _check_dipole(d0, 1) _check_dipole(d1, 1) _compare_dipoles(d0, d1) mask = dipole.gof > 15 idx = np.where(mask)[0] d_mask = dipole[mask] _check_dipole(d_mask, 4) _compare_dipoles(d_mask, dipole[idx])
def _check_roundtrip_fixed(dip): """Helper to test roundtrip IO for fixed dipoles.""" tempdir = _TempDir() dip.save(op.join(tempdir, 'test-dip.fif.gz')) dip_read = read_dipole(op.join(tempdir, 'test-dip.fif.gz')) assert_allclose(dip_read.data, dip_read.data) assert_allclose(dip_read.times, dip.times) assert_equal(dip_read.info['xplotter_layout'], dip.info['xplotter_layout']) assert_equal(dip_read.ch_names, dip.ch_names) for ch_1, ch_2 in zip(dip_read.info['chs'], dip.info['chs']): assert_equal(ch_1['ch_name'], ch_2['ch_name']) for key in ('loc', 'kind', 'unit_mul', 'range', 'coord_frame', 'unit', 'cal', 'coil_type', 'scanno', 'logno'): assert_allclose(ch_1[key], ch_2[key], err_msg=key)
def _check_roundtrip_fixed(dip): """Check roundtrip IO for fixed dipoles.""" tempdir = _TempDir() dip.save(op.join(tempdir, 'test-dip.fif.gz')) dip_read = read_dipole(op.join(tempdir, 'test-dip.fif.gz')) assert_allclose(dip_read.data, dip_read.data) assert_allclose(dip_read.times, dip.times) assert_equal(dip_read.info['xplotter_layout'], dip.info['xplotter_layout']) assert_equal(dip_read.ch_names, dip.ch_names) for ch_1, ch_2 in zip(dip_read.info['chs'], dip.info['chs']): assert_equal(ch_1['ch_name'], ch_2['ch_name']) for key in ('loc', 'kind', 'unit_mul', 'range', 'coord_frame', 'unit', 'cal', 'coil_type', 'scanno', 'logno'): assert_allclose(ch_1[key], ch_2[key], err_msg=key)
def test_confidence(): """Test confidence limits.""" tempdir = _TempDir() evoked = read_evokeds(fname_evo_full, 'Left Auditory', baseline=(None, 0)) evoked.crop(0.08, 0.08).pick_types() # MEG-only cov = make_ad_hoc_cov(evoked.info) sphere = make_sphere_model((0., 0., 0.04), 0.08) dip_py = fit_dipole(evoked, cov, sphere)[0] fname_test = op.join(tempdir, 'temp-dip.txt') dip_py.save(fname_test) dip_read = read_dipole(fname_test) with warnings.catch_warnings(record=True) as w: dip_xfit = read_dipole(fname_dip_xfit) assert_equal(len(w), 1) assert_true("['noise/ft/cm', 'prob']" in str(w[0].message)) for dip_check in (dip_py, dip_read): assert_allclose(dip_check.pos, dip_xfit.pos, atol=5e-4) # < 0.5 mm assert_allclose(dip_check.gof, dip_xfit.gof, atol=5e-1) # < 0.5% assert_array_equal(dip_check.nfree, dip_xfit.nfree) # exact match assert_allclose(dip_check.khi2, dip_xfit.khi2, rtol=2e-2) # 2% miss assert_equal(set(dip_check.conf.keys()), set(dip_xfit.conf.keys())) for key in sorted(dip_check.conf.keys()): assert_allclose(dip_check.conf[key], dip_xfit.conf[key], rtol=1.5e-1, err_msg=key)
def test_plot_dipole_mri_orthoview(coord_frame, idx, show_all, title): """Test mpl dipole plotting.""" dipoles = read_dipole(dip_fname) trans = read_trans(trans_fname) fig = dipoles.plot_locations(trans=trans, subject='sample', subjects_dir=subjects_dir, coord_frame=coord_frame, idx=idx, show_all=show_all, title=title, mode='orthoview') fig.canvas.scroll_event(0.5, 0.5, 1) # scroll up fig.canvas.scroll_event(0.5, 0.5, -1) # scroll down fig.canvas.key_press_event('up') fig.canvas.key_press_event('down') fig.canvas.key_press_event('a') # some other key ax = fig.add_subplot(211) with pytest.raises(TypeError, match='instance of Axes3D'): dipoles.plot_locations(trans, 'sample', subjects_dir, ax=ax)
def read_mixn_dipoles(name, save_dir, highpass, lowpass, event_id): dipoles = dict() for trial in event_id: idx = 0 dip_list = list() try: while True: mixn_dip_name = name + filter_string( highpass, lowpass) + '_' + trial + '-mixn-dip-' + str(idx) mixn_dip_path = join(save_dir, 'dipoles', mixn_dip_name) dip_list.append(mne.read_dipole(mixn_dip_path)) idx += 1 except OSError: dipoles.update({trial: dip_list}) print(f'{idx + 1} dipoles read for {trial}') return dipoles
def test_plot_dipole_mri_orthoview(): """Test mpl dipole plotting.""" dipoles = read_dipole(dip_fname) trans = read_trans(trans_fname) for coord_frame, idx, show_all in zip(['head', 'mri'], ['gof', 'amplitude'], [True, False]): fig = dipoles.plot_locations(trans, 'sample', subjects_dir, coord_frame=coord_frame, idx=idx, show_all=show_all, mode='orthoview') fig.canvas.scroll_event(0.5, 0.5, 1) # scroll up fig.canvas.scroll_event(0.5, 0.5, -1) # scroll down fig.canvas.key_press_event('up') fig.canvas.key_press_event('down') fig.canvas.key_press_event('a') # some other key ax = plt.subplot(111) pytest.raises(TypeError, dipoles.plot_locations, trans, 'sample', subjects_dir, ax=ax) plt.close('all')
def load_mixn_dipoles(self): if self._mixn_dips is None: self._mixn_dips = dict() for trial in self.sel_trials: idx = 0 dip_list = list() try: for idx in range( len(listdir(join(self.save_dir, 'mixn_dipoles')))): mixn_dip_path = join( self.save_dir, 'mixn_dipoles', f'{self.name}_{trial}_{self.p_preset}-mixn-dip{idx}.dip' ) dip_list.append(mne.read_dipole(mixn_dip_path)) idx += 1 except FileNotFoundError: pass self._mixn_dips[trial] = dip_list print(f'{idx + 1} dipoles read for {self.name}-{trial}') return self._mixn_dips
def test_io_dipoles(): """Test IO for .dip files """ tempdir = _TempDir() out_fname = op.join(tempdir, 'temp.dip') with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') times, pos, amplitude, ori, gof = read_dip(fname_dip) assert_true(len(w) >= 1) assert_true(pos.shape[1] == 3) assert_true(ori.shape[1] == 3) assert_true(len(times) == len(pos)) assert_true(len(times) == gof.size) assert_true(len(times) == amplitude.size) dipole = Dipole(times, pos, amplitude, ori, gof, 'ALL') print(dipole) # test repr dipole.save(out_fname) dipole_new = read_dipole(out_fname) _compare_dipoles(dipole, dipole_new)
def test_plot_dipole_mri_outlines(surf, coord_frame, ax, title): """Test mpl dipole plotting.""" dipoles = read_dipole(dip_fname) trans = read_trans(trans_fname) if ax is not None: assert isinstance(ax, str) and ax == 'mpl', ax _, ax = plt.subplots(3, 1) ax = list(ax) with pytest.raises(ValueError, match='but the length is 2'): dipoles.plot_locations(trans, 'sample', subjects_dir, ax=ax[:2], mode='outlines') fig = dipoles.plot_locations(trans=trans, subject='sample', subjects_dir=subjects_dir, mode='outlines', coord_frame=coord_frame, surf=surf, ax=ax, title=title) assert isinstance(fig, Figure)
def test_make_forward_dipole(): """Test forward-projecting dipoles.""" rng = np.random.RandomState(0) evoked = read_evokeds(fname_evo)[0] cov = read_cov(fname_cov) cov['projs'] = [] # avoid proj warning dip_c = read_dipole(fname_dip) # Only use magnetometers for speed! picks = pick_types(evoked.info, meg='mag', eeg=False)[::8] evoked.pick_channels([evoked.ch_names[p] for p in picks]) evoked.info.normalize_proj() info = evoked.info # Make new Dipole object with n_test_dipoles picked from the dipoles # in the test dataset. n_test_dipoles = 3 # minimum 3 needed to get uneven sampling in time dipsel = np.sort(rng.permutation(np.arange(len(dip_c)))[:n_test_dipoles]) dip_test = Dipole(times=dip_c.times[dipsel], pos=dip_c.pos[dipsel], amplitude=dip_c.amplitude[dipsel], ori=dip_c.ori[dipsel], gof=dip_c.gof[dipsel]) sphere = make_sphere_model(head_radius=0.1) # Warning emitted due to uneven sampling in time with pytest.warns(RuntimeWarning, match='unevenly spaced'): fwd, stc = make_forward_dipole(dip_test, sphere, info, trans=fname_trans) # stc is list of VolSourceEstimate's assert isinstance(stc, list) for n_dip in range(n_test_dipoles): assert isinstance(stc[n_dip], VolSourceEstimate) # Now simulate evoked responses for each of the test dipoles, # and fit dipoles to them (sphere model, MEG and EEG) times, pos, amplitude, ori, gof = [], [], [], [], [] nave = 200 # add a tiny amount of noise to the simulated evokeds for s in stc: evo_test = simulate_evoked(fwd, s, info, cov, nave=nave, random_state=rng) # evo_test.add_proj(make_eeg_average_ref_proj(evo_test.info)) dfit, resid = fit_dipole(evo_test, cov, sphere, None) times += dfit.times.tolist() pos += dfit.pos.tolist() amplitude += dfit.amplitude.tolist() ori += dfit.ori.tolist() gof += dfit.gof.tolist() # Create a new Dipole object with the dipole fits dip_fit = Dipole(times, pos, amplitude, ori, gof) # check that true (test) dipoles and fits are "close" # cf. mne/tests/test_dipole.py diff = dip_test.pos - dip_fit.pos corr = np.corrcoef(dip_test.pos.ravel(), dip_fit.pos.ravel())[0, 1] dist = np.sqrt(np.mean(np.sum(diff * diff, axis=1))) gc_dist = 180 / np.pi * \ np.mean(np.arccos(np.sum(dip_test.ori * dip_fit.ori, axis=1))) amp_err = np.sqrt(np.mean((dip_test.amplitude - dip_fit.amplitude) ** 2)) # Make sure each coordinate is close to reference # NB tolerance should be set relative to snr of simulated evoked! assert_allclose(dip_fit.pos, dip_test.pos, rtol=0, atol=1e-2, err_msg='position mismatch') assert dist < 1e-2 # within 1 cm assert corr > 0.985 assert gc_dist < 20 # less than 20 degrees assert amp_err < 10e-9 # within 10 nAm # Make sure rejection works with BEM: one dipole at z=1m # NB _make_forward.py:_prepare_for_forward will raise a RuntimeError # if no points are left after min_dist exclusions, hence 2 dips here! dip_outside = Dipole(times=[0., 0.001], pos=[[0., 0., 1.0], [0., 0., 0.040]], amplitude=[100e-9, 100e-9], ori=[[1., 0., 0.], [1., 0., 0.]], gof=1) pytest.raises(ValueError, make_forward_dipole, dip_outside, fname_bem, info, fname_trans) # if we get this far, can safely assume the code works with BEMs too # -> use sphere again below for speed # Now make an evenly sampled set of dipoles, some simultaneous, # should return a VolSourceEstimate regardless times = [0., 0., 0., 0.001, 0.001, 0.002] pos = np.random.rand(6, 3) * 0.020 + \ np.array([0., 0., 0.040])[np.newaxis, :] amplitude = np.random.rand(6) * 100e-9 ori = np.eye(6, 3) + np.eye(6, 3, -3) gof = np.arange(len(times)) / len(times) # arbitrary dip_even_samp = Dipole(times, pos, amplitude, ori, gof) fwd, stc = make_forward_dipole(dip_even_samp, sphere, info, trans=fname_trans) assert isinstance(stc, VolSourceEstimate) assert_allclose(stc.times, np.arange(0., 0.003, 0.001))
import numpy as np from config import fname # Handle command line arguments parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('subject', metavar='sub###', type=int, help='The subject to process') args = parser.parse_args() subject = args.subject print('Processing subject:', subject) epochs = mne.read_epochs(fname.epochs(subject=subject)) noise_cov = mne.compute_covariance(epochs, tmin=-0.2, tmax=0, method='shrunk') fwd = mne.read_forward_solution(fname.fwd(subject=subject)) inv = mne.minimum_norm.make_inverse_operator(epochs.info, fwd, noise_cov, depth=None) stc = mne.minimum_norm.apply_inverse(epochs.average(), inv) stc.save(fname.stc_mne(subject=subject)) # Find the time point that corresponds to the best dipole fit dip = mne.read_dipole(fname.ecd(subject=subject)) peak_time = dip[int(np.argmax(dip.gof))].times[0] stc_peak = abs(stc.copy().crop(peak_time, peak_time).mean()) stc_peak.save(fname.stc_mne(subject=subject)) stc_peak.save_as_volume(fname.nii_mne(subject=subject), src=fwd['src']) fig = stc.plot(initial_time=peak_time, subject=fname.subject_id(subject=subject), subjects_dir=fname.subjects_dir, src=fwd['src'], clim=dict(kind='percent', lims=[99.9, 99.95, 100])) with mne.open_report(fname.report(subject=subject)) as report: report.add_figs_to_section(fig, f'MNE Source estimate at {peak_time}', 'Source level', replace=True) report.save(fname.report_html(subject=subject), overwrite=True, open_browser=False)
def test_dipole_fitting(): """Test dipole fitting.""" amp = 10e-9 tempdir = _TempDir() rng = np.random.RandomState(0) fname_dtemp = op.join(tempdir, 'test.dip') fname_sim = op.join(tempdir, 'test-ave.fif') fwd = convert_forward_solution(read_forward_solution(fname_fwd), surf_ori=False, force_fixed=True) evoked = read_evokeds(fname_evo)[0] cov = read_cov(fname_cov) n_per_hemi = 5 vertices = [np.sort(rng.permutation(s['vertno'])[:n_per_hemi]) for s in fwd['src']] nv = sum(len(v) for v in vertices) stc = SourceEstimate(amp * np.eye(nv), vertices, 0, 0.001) evoked = simulate_evoked(fwd, stc, evoked.info, cov, snr=20, random_state=rng) # For speed, let's use a subset of channels (strange but works) picks = np.sort(np.concatenate([ pick_types(evoked.info, meg=True, eeg=False)[::2], pick_types(evoked.info, meg=False, eeg=True)[::2]])) evoked.pick_channels([evoked.ch_names[p] for p in picks]) evoked.add_proj(make_eeg_average_ref_proj(evoked.info)) write_evokeds(fname_sim, evoked) # Run MNE-C version run_subprocess([ 'mne_dipole_fit', '--meas', fname_sim, '--meg', '--eeg', '--noise', fname_cov, '--dip', fname_dtemp, '--mri', fname_fwd, '--reg', '0', '--tmin', '0', ]) dip_c = read_dipole(fname_dtemp) # Run mne-python version sphere = make_sphere_model(head_radius=0.1) dip, residuals = fit_dipole(evoked, fname_cov, sphere, fname_fwd) # Sanity check: do our residuals have less power than orig data? data_rms = np.sqrt(np.sum(evoked.data ** 2, axis=0)) resi_rms = np.sqrt(np.sum(residuals ** 2, axis=0)) factor = 1. # XXX weird, inexplicable differenc for 3.5 build we'll assume is due to # Anaconda bug for now... if os.getenv('TRAVIS', 'false') == 'true' and \ sys.version[:3] in ('3.5', '2.7'): factor = 0.8 assert_true((data_rms > factor * resi_rms).all(), msg='%s (factor: %s)' % ((data_rms / resi_rms).min(), factor)) # Compare to original points transform_surface_to(fwd['src'][0], 'head', fwd['mri_head_t']) transform_surface_to(fwd['src'][1], 'head', fwd['mri_head_t']) src_rr = np.concatenate([s['rr'][v] for s, v in zip(fwd['src'], vertices)], axis=0) src_nn = np.concatenate([s['nn'][v] for s, v in zip(fwd['src'], vertices)], axis=0) # MNE-C skips the last "time" point :( dip.crop(dip_c.times[0], dip_c.times[-1]) src_rr, src_nn = src_rr[:-1], src_nn[:-1] # check that we did at least as well corrs, dists, gc_dists, amp_errs, gofs = [], [], [], [], [] for d in (dip_c, dip): new = d.pos diffs = new - src_rr corrs += [np.corrcoef(src_rr.ravel(), new.ravel())[0, 1]] dists += [np.sqrt(np.mean(np.sum(diffs * diffs, axis=1)))] gc_dists += [180 / np.pi * np.mean(np.arccos(np.sum(src_nn * d.ori, axis=1)))] amp_errs += [np.sqrt(np.mean((amp - d.amplitude) ** 2))] gofs += [np.mean(d.gof)] assert_true(dists[0] >= dists[1] * factor, 'dists: %s' % dists) assert_true(corrs[0] <= corrs[1] / factor, 'corrs: %s' % corrs) assert_true(gc_dists[0] >= gc_dists[1] * factor, 'gc-dists (ori): %s' % gc_dists) assert_true(amp_errs[0] >= amp_errs[1] * factor, 'amplitude errors: %s' % amp_errs) assert_true(gofs[0] <= gofs[1] / factor, 'gof: %s' % gofs)
def test_dipole_fitting(): """Test dipole fitting.""" amp = 100e-9 tempdir = _TempDir() rng = np.random.RandomState(0) fname_dtemp = op.join(tempdir, 'test.dip') fname_sim = op.join(tempdir, 'test-ave.fif') fwd = convert_forward_solution(read_forward_solution(fname_fwd), surf_ori=False, force_fixed=True, use_cps=True) evoked = read_evokeds(fname_evo)[0] cov = read_cov(fname_cov) n_per_hemi = 5 vertices = [np.sort(rng.permutation(s['vertno'])[:n_per_hemi]) for s in fwd['src']] nv = sum(len(v) for v in vertices) stc = SourceEstimate(amp * np.eye(nv), vertices, 0, 0.001) evoked = simulate_evoked(fwd, stc, evoked.info, cov, nave=evoked.nave, random_state=rng) # For speed, let's use a subset of channels (strange but works) picks = np.sort(np.concatenate([ pick_types(evoked.info, meg=True, eeg=False)[::2], pick_types(evoked.info, meg=False, eeg=True)[::2]])) evoked.pick_channels([evoked.ch_names[p] for p in picks]) evoked.add_proj(make_eeg_average_ref_proj(evoked.info)) write_evokeds(fname_sim, evoked) # Run MNE-C version run_subprocess([ 'mne_dipole_fit', '--meas', fname_sim, '--meg', '--eeg', '--noise', fname_cov, '--dip', fname_dtemp, '--mri', fname_fwd, '--reg', '0', '--tmin', '0', ]) dip_c = read_dipole(fname_dtemp) # Run mne-python version sphere = make_sphere_model(head_radius=0.1) with pytest.warns(RuntimeWarning, match='projection'): dip, residual = fit_dipole(evoked, cov, sphere, fname_fwd) assert isinstance(residual, Evoked) # Sanity check: do our residuals have less power than orig data? data_rms = np.sqrt(np.sum(evoked.data ** 2, axis=0)) resi_rms = np.sqrt(np.sum(residual.data ** 2, axis=0)) assert (data_rms > resi_rms * 0.95).all(), \ '%s (factor: %s)' % ((data_rms / resi_rms).min(), 0.95) # Compare to original points transform_surface_to(fwd['src'][0], 'head', fwd['mri_head_t']) transform_surface_to(fwd['src'][1], 'head', fwd['mri_head_t']) assert_equal(fwd['src'][0]['coord_frame'], FIFF.FIFFV_COORD_HEAD) src_rr = np.concatenate([s['rr'][v] for s, v in zip(fwd['src'], vertices)], axis=0) src_nn = np.concatenate([s['nn'][v] for s, v in zip(fwd['src'], vertices)], axis=0) # MNE-C skips the last "time" point :( out = dip.crop(dip_c.times[0], dip_c.times[-1]) assert (dip is out) src_rr, src_nn = src_rr[:-1], src_nn[:-1] # check that we did about as well corrs, dists, gc_dists, amp_errs, gofs = [], [], [], [], [] for d in (dip_c, dip): new = d.pos diffs = new - src_rr corrs += [np.corrcoef(src_rr.ravel(), new.ravel())[0, 1]] dists += [np.sqrt(np.mean(np.sum(diffs * diffs, axis=1)))] gc_dists += [180 / np.pi * np.mean(np.arccos(np.sum(src_nn * d.ori, axis=1)))] amp_errs += [np.sqrt(np.mean((amp - d.amplitude) ** 2))] gofs += [np.mean(d.gof)] # XXX possibly some OpenBLAS numerical differences make # things slightly worse for us factor = 0.7 assert dists[0] / factor >= dists[1], 'dists: %s' % dists assert corrs[0] * factor <= corrs[1], 'corrs: %s' % corrs assert gc_dists[0] / factor >= gc_dists[1] * 0.8, \ 'gc-dists (ori): %s' % gc_dists assert amp_errs[0] / factor >= amp_errs[1],\ 'amplitude errors: %s' % amp_errs # This one is weird because our cov/sim/picking is weird assert gofs[0] * factor <= gofs[1] * 2, 'gof: %s' % gofs
def test_plot_dipole_amplitudes(): """Test plotting dipole amplitudes.""" dipoles = read_dipole(dip_fname) dipoles.plot_amplitudes(show=False)
def test_plot_dipole_amplitudes(): """Test plotting dipole amplitudes """ dipoles = read_dipole(dip_fname) dipoles.plot_amplitudes(show=False)
def test_dipole_fitting(): """Test dipole fitting.""" amp = 100e-9 tempdir = _TempDir() rng = np.random.RandomState(0) fname_dtemp = op.join(tempdir, 'test.dip') fname_sim = op.join(tempdir, 'test-ave.fif') fwd = convert_forward_solution(read_forward_solution(fname_fwd), surf_ori=False, force_fixed=True, use_cps=True) evoked = read_evokeds(fname_evo)[0] cov = read_cov(fname_cov) n_per_hemi = 5 vertices = [ np.sort(rng.permutation(s['vertno'])[:n_per_hemi]) for s in fwd['src'] ] nv = sum(len(v) for v in vertices) stc = SourceEstimate(amp * np.eye(nv), vertices, 0, 0.001) evoked = simulate_evoked(fwd, stc, evoked.info, cov, nave=evoked.nave, random_state=rng) # For speed, let's use a subset of channels (strange but works) picks = np.sort( np.concatenate([ pick_types(evoked.info, meg=True, eeg=False)[::2], pick_types(evoked.info, meg=False, eeg=True)[::2] ])) evoked.pick_channels([evoked.ch_names[p] for p in picks]) evoked.add_proj(make_eeg_average_ref_proj(evoked.info)) write_evokeds(fname_sim, evoked) # Run MNE-C version run_subprocess([ 'mne_dipole_fit', '--meas', fname_sim, '--meg', '--eeg', '--noise', fname_cov, '--dip', fname_dtemp, '--mri', fname_fwd, '--reg', '0', '--tmin', '0', ]) dip_c = read_dipole(fname_dtemp) # Run mne-python version sphere = make_sphere_model(head_radius=0.1) with pytest.warns(RuntimeWarning, match='projection'): dip, residuals = fit_dipole(evoked, cov, sphere, fname_fwd) # Sanity check: do our residuals have less power than orig data? data_rms = np.sqrt(np.sum(evoked.data**2, axis=0)) resi_rms = np.sqrt(np.sum(residuals**2, axis=0)) assert (data_rms > resi_rms * 0.95).all(), \ '%s (factor: %s)' % ((data_rms / resi_rms).min(), 0.95) # Compare to original points transform_surface_to(fwd['src'][0], 'head', fwd['mri_head_t']) transform_surface_to(fwd['src'][1], 'head', fwd['mri_head_t']) assert_equal(fwd['src'][0]['coord_frame'], FIFF.FIFFV_COORD_HEAD) src_rr = np.concatenate([s['rr'][v] for s, v in zip(fwd['src'], vertices)], axis=0) src_nn = np.concatenate([s['nn'][v] for s, v in zip(fwd['src'], vertices)], axis=0) # MNE-C skips the last "time" point :( out = dip.crop(dip_c.times[0], dip_c.times[-1]) assert (dip is out) src_rr, src_nn = src_rr[:-1], src_nn[:-1] # check that we did about as well corrs, dists, gc_dists, amp_errs, gofs = [], [], [], [], [] for d in (dip_c, dip): new = d.pos diffs = new - src_rr corrs += [np.corrcoef(src_rr.ravel(), new.ravel())[0, 1]] dists += [np.sqrt(np.mean(np.sum(diffs * diffs, axis=1)))] gc_dists += [ 180 / np.pi * np.mean(np.arccos(np.sum(src_nn * d.ori, axis=1))) ] amp_errs += [np.sqrt(np.mean((amp - d.amplitude)**2))] gofs += [np.mean(d.gof)] if os.getenv('TRAVIS', 'false').lower() == 'true' and \ 'OPENBLAS_NUM_THREADS' in os.environ: # XXX possibly some OpenBLAS numerical differences make # things slightly worse for us factor = 0.7 else: factor = 0.8 assert dists[0] / factor >= dists[1], 'dists: %s' % dists assert corrs[0] * factor <= corrs[1], 'corrs: %s' % corrs assert gc_dists[0] / factor >= gc_dists[1] * 0.8, \ 'gc-dists (ori): %s' % gc_dists assert amp_errs[0] / factor >= amp_errs[1],\ 'amplitude errors: %s' % amp_errs # This one is weird because our cov/sim/picking is weird assert gofs[0] * factor <= gofs[1] * 2, 'gof: %s' % gofs
def test_plot_dipole_amplitudes(): """Test plotting dipole amplitudes.""" import matplotlib.pyplot as plt dipoles = read_dipole(dip_fname) dipoles.plot_amplitudes(show=False) plt.close('all')
Plot somatosensory dipole timecourses with GOF """ import mne import matplotlib.pyplot as plt import os.path as op import numpy as np path = '/Users/ashdrew/Soma_Data/TWA/dips/' dips = ['408_0', '409_1'] # enter subject numbers for dipoles you want plotted here for d in dips: dip_fname = op.join(path, 'soma3_%s.dip' % d) dip = mne.read_dipole(dip_fname) gof = dip.gof np.set_printoptions(formatter={'float_kind': '{:f}'.format}) best_dip_idx = gof.argmax() max_gof = gof[best_dip_idx] best_dip_time = dip.times[best_dip_idx] # plot each dipole as a function of time with latency of highest GOF% dip.plot_amplitudes() plt.plot(dip.times, gof, color='red', alpha=0.5, label='GOF', linewidth=1) plt.axvline(x=best_dip_time, color='b', label='Max GOF: %d' % max_gof + '%', alpha=0.5, linestyle='dashed')
def test_dipole_fixed(): """Test reading a fixed-position dipole (from Xfit)""" dip = read_dipole(fname_xfit_dip) _check_roundtrip_fixed(dip)
def test_make_forward_dipole(tmp_path): """Test forward-projecting dipoles.""" rng = np.random.RandomState(0) evoked = read_evokeds(fname_evo)[0] cov = read_cov(fname_cov) cov['projs'] = [] # avoid proj warning dip_c = read_dipole(fname_dip) # Only use magnetometers for speed! picks = pick_types(evoked.info, meg='mag', eeg=False)[::8] evoked.pick_channels([evoked.ch_names[p] for p in picks]) evoked.info.normalize_proj() info = evoked.info # Make new Dipole object with n_test_dipoles picked from the dipoles # in the test dataset. n_test_dipoles = 3 # minimum 3 needed to get uneven sampling in time dipsel = np.sort(rng.permutation(np.arange(len(dip_c)))[:n_test_dipoles]) dip_test = Dipole(times=dip_c.times[dipsel], pos=dip_c.pos[dipsel], amplitude=dip_c.amplitude[dipsel], ori=dip_c.ori[dipsel], gof=dip_c.gof[dipsel]) sphere = make_sphere_model(head_radius=0.1) # Warning emitted due to uneven sampling in time with pytest.warns(RuntimeWarning, match='unevenly spaced'): fwd, stc = make_forward_dipole(dip_test, sphere, info, trans=fname_trans) # stc is list of VolSourceEstimate's assert isinstance(stc, list) for n_dip in range(n_test_dipoles): assert isinstance(stc[n_dip], VolSourceEstimate) # Now simulate evoked responses for each of the test dipoles, # and fit dipoles to them (sphere model, MEG and EEG) times, pos, amplitude, ori, gof = [], [], [], [], [] nave = 200 # add a tiny amount of noise to the simulated evokeds for s in stc: evo_test = simulate_evoked(fwd, s, info, cov, nave=nave, random_state=rng) # evo_test.add_proj(make_eeg_average_ref_proj(evo_test.info)) dfit, resid = fit_dipole(evo_test, cov, sphere, None) times += dfit.times.tolist() pos += dfit.pos.tolist() amplitude += dfit.amplitude.tolist() ori += dfit.ori.tolist() gof += dfit.gof.tolist() # Create a new Dipole object with the dipole fits dip_fit = Dipole(times, pos, amplitude, ori, gof) # check that true (test) dipoles and fits are "close" # cf. mne/tests/test_dipole.py diff = dip_test.pos - dip_fit.pos corr = np.corrcoef(dip_test.pos.ravel(), dip_fit.pos.ravel())[0, 1] dist = np.sqrt(np.mean(np.sum(diff * diff, axis=1))) gc_dist = 180 / np.pi * \ np.mean(np.arccos(np.sum(dip_test.ori * dip_fit.ori, axis=1))) amp_err = np.sqrt(np.mean((dip_test.amplitude - dip_fit.amplitude)**2)) # Make sure each coordinate is close to reference # NB tolerance should be set relative to snr of simulated evoked! assert_allclose(dip_fit.pos, dip_test.pos, rtol=0, atol=1e-2, err_msg='position mismatch') assert dist < 1e-2 # within 1 cm assert corr > 0.985 assert gc_dist < 20 # less than 20 degrees assert amp_err < 10e-9 # within 10 nAm # Make sure rejection works with BEM: one dipole at z=1m # NB _make_forward.py:_prepare_for_forward will raise a RuntimeError # if no points are left after min_dist exclusions, hence 2 dips here! dip_outside = Dipole(times=[0., 0.001], pos=[[0., 0., 1.0], [0., 0., 0.040]], amplitude=[100e-9, 100e-9], ori=[[1., 0., 0.], [1., 0., 0.]], gof=1) with pytest.raises(ValueError, match='outside the inner skull'): make_forward_dipole(dip_outside, fname_bem, info, fname_trans) # if we get this far, can safely assume the code works with BEMs too # -> use sphere again below for speed # Now make an evenly sampled set of dipoles, some simultaneous, # should return a VolSourceEstimate regardless times = [0., 0., 0., 0.001, 0.001, 0.002] pos = np.random.rand(6, 3) * 0.020 + \ np.array([0., 0., 0.040])[np.newaxis, :] amplitude = np.random.rand(6) * 100e-9 ori = np.eye(6, 3) + np.eye(6, 3, -3) gof = np.arange(len(times)) / len(times) # arbitrary dip_even_samp = Dipole(times, pos, amplitude, ori, gof) # I/O round-trip fname = str(tmp_path / 'test-fwd.fif') with pytest.warns(RuntimeWarning, match='free orientation'): write_forward_solution(fname, fwd) fwd_read = convert_forward_solution(read_forward_solution(fname), force_fixed=True) assert_forward_allclose(fwd, fwd_read, rtol=1e-6) fwd, stc = make_forward_dipole(dip_even_samp, sphere, info, trans=fname_trans) assert isinstance(stc, VolSourceEstimate) assert_allclose(stc.times, np.arange(0., 0.003, 0.001)) # Test passing a list of Dipoles instead of a single Dipole object fwd2, stc2 = make_forward_dipole([dip_even_samp[0], dip_even_samp[1:]], sphere, info, trans=fname_trans) assert_array_equal(fwd['sol']['data'], fwd2['sol']['data']) assert_array_equal(stc.data, stc2.data)
Find peak within a window for dipole moment, then compute area under the curve (AUC) """ import mne from os import path as op import numpy as np import matplotlib.pyplot as plt ### define time window of interest window_min = 0.07 window_max = 0.14 path = '/storage/Maggie/' fname = op.join(path, 'soma2_387_hand_100window_xfit_waves.fif') dip = mne.read_dipole(fname) data = dip.data[0] times = dip.times assert len(data) == len(times) time_mask = (times > window_min) & (times <= window_max) data_mask = data[time_mask] # Find index of maximum value idx peak_idx = np.where(data == np.amax(data_mask)) # time around peak for AUC calculation tmin = times[peak_idx] - 0.015 tmax = times[peak_idx] + 0.015 auc = np.sum(np.abs(data)) * len(data) * (1. / dip.info['sfreq']) print('AUC value: %s' % auc)
def test_dipole_fitting(tmp_path): """Test dipole fitting.""" amp = 100e-9 tempdir = str(tmp_path) rng = np.random.RandomState(0) fname_dtemp = op.join(tempdir, 'test.dip') fname_sim = op.join(tempdir, 'test-ave.fif') fwd = convert_forward_solution(read_forward_solution(fname_fwd), surf_ori=False, force_fixed=True, use_cps=True) evoked = read_evokeds(fname_evo)[0] cov = read_cov(fname_cov) n_per_hemi = 5 vertices = [ np.sort(rng.permutation(s['vertno'])[:n_per_hemi]) for s in fwd['src'] ] nv = sum(len(v) for v in vertices) stc = SourceEstimate(amp * np.eye(nv), vertices, 0, 0.001) evoked = simulate_evoked(fwd, stc, evoked.info, cov, nave=evoked.nave, random_state=rng) # For speed, let's use a subset of channels (strange but works) picks = np.sort( np.concatenate([ pick_types(evoked.info, meg=True, eeg=False)[::2], pick_types(evoked.info, meg=False, eeg=True)[::2] ])) evoked.pick_channels([evoked.ch_names[p] for p in picks]) evoked.add_proj(make_eeg_average_ref_proj(evoked.info)) write_evokeds(fname_sim, evoked) # Run MNE-C version run_subprocess([ 'mne_dipole_fit', '--meas', fname_sim, '--meg', '--eeg', '--noise', fname_cov, '--dip', fname_dtemp, '--mri', fname_fwd, '--reg', '0', '--tmin', '0', ]) dip_c = read_dipole(fname_dtemp) # Run mne-python version sphere = make_sphere_model(head_radius=0.1) with pytest.warns(RuntimeWarning, match='projection'): dip, residual = fit_dipole(evoked, cov, sphere, fname_fwd, rank='info') # just to test rank support assert isinstance(residual, Evoked) # Test conversion of dip.pos to MNI coordinates. dip_mni_pos = dip.to_mni('sample', fname_trans, subjects_dir=subjects_dir) head_to_mni_dip_pos = head_to_mni(dip.pos, 'sample', fwd['mri_head_t'], subjects_dir=subjects_dir) assert_allclose(dip_mni_pos, head_to_mni_dip_pos, rtol=1e-3, atol=0) # Test finding label for dip.pos in an aseg, also tests `to_mri` target_labels = [ 'Left-Cerebral-Cortex', 'Unknown', 'Left-Cerebral-Cortex', 'Right-Cerebral-Cortex', 'Left-Cerebral-Cortex', 'Unknown', 'Unknown', 'Unknown', 'Right-Cerebral-White-Matter', 'Right-Cerebral-Cortex' ] labels = dip.to_volume_labels(fname_trans, subject='fsaverage', aseg="aseg", subjects_dir=subjects_dir) assert labels == target_labels # Sanity check: do our residuals have less power than orig data? data_rms = np.sqrt(np.sum(evoked.data**2, axis=0)) resi_rms = np.sqrt(np.sum(residual.data**2, axis=0)) assert (data_rms > resi_rms * 0.95).all(), \ '%s (factor: %s)' % ((data_rms / resi_rms).min(), 0.95) # Compare to original points transform_surface_to(fwd['src'][0], 'head', fwd['mri_head_t']) transform_surface_to(fwd['src'][1], 'head', fwd['mri_head_t']) assert fwd['src'][0]['coord_frame'] == FIFF.FIFFV_COORD_HEAD src_rr = np.concatenate([s['rr'][v] for s, v in zip(fwd['src'], vertices)], axis=0) src_nn = np.concatenate([s['nn'][v] for s, v in zip(fwd['src'], vertices)], axis=0) # MNE-C skips the last "time" point :( out = dip.crop(dip_c.times[0], dip_c.times[-1]) assert (dip is out) src_rr, src_nn = src_rr[:-1], src_nn[:-1] # check that we did about as well corrs, dists, gc_dists, amp_errs, gofs = [], [], [], [], [] for d in (dip_c, dip): new = d.pos diffs = new - src_rr corrs += [np.corrcoef(src_rr.ravel(), new.ravel())[0, 1]] dists += [np.sqrt(np.mean(np.sum(diffs * diffs, axis=1)))] gc_dists += [ 180 / np.pi * np.mean(np.arccos(np.sum(src_nn * d.ori, axis=1))) ] amp_errs += [np.sqrt(np.mean((amp - d.amplitude)**2))] gofs += [np.mean(d.gof)] # XXX possibly some OpenBLAS numerical differences make # things slightly worse for us factor = 0.7 assert dists[0] / factor >= dists[1], 'dists: %s' % dists assert corrs[0] * factor <= corrs[1], 'corrs: %s' % corrs assert gc_dists[0] / factor >= gc_dists[1] * 0.8, \ 'gc-dists (ori): %s' % gc_dists assert amp_errs[0] / factor >= amp_errs[1],\ 'amplitude errors: %s' % amp_errs # This one is weird because our cov/sim/picking is weird assert gofs[0] * factor <= gofs[1] * 2, 'gof: %s' % gofs
csd_ers = mne.time_frequency.csd_morlet(epochs, freqs, tmin=0.5, tmax=1.5, decim=5, n_jobs=4) csd = csd.mean() csd_baseline = csd_baseline.mean() csd_ers = csd_ers.mean() ############################################################################### # read dipole created by 06_dipole.py ############################################################################### dip = mne.read_dipole(fname.ecd) # get the position of the dipole in MRI coordinates mri_pos = mne.head_to_mri(dip.pos, mri_head_t=trans, subject=subject_id, subjects_dir=fname.subjects_dir) # get true_vert_idx rr = fwd['src'][0]['rr'] inuse = fwd['src'][0]['inuse'] indices = np.where(fwd['src'][0]['inuse'])[0] rr_inuse = rr[indices] true_vert_idx = np.where( np.linalg.norm(rr_inuse - dip.pos, axis=1) == np.linalg.norm( rr_inuse - dip.pos, axis=1).min())[0][0]
from config import dics_settings, fname, args from megset.config import fname as megset_fname from megset.config import freq_range subject = args.subject print(f'Running analsis for subject {subject}') mne.set_log_level(False) # Shhh ############################################################################### # Load the data ############################################################################### epochs = mne.read_epochs(megset_fname.epochs_long(subject=subject)) fwd = mne.read_forward_solution(megset_fname.fwd(subject=subject)) dip = mne.read_dipole(megset_fname.ecd(subject=subject)) ############################################################################### # Sensor-level analysis for beamformer ############################################################################### epochs_grad = epochs.copy().pick_types(meg='grad') epochs_mag = epochs.copy().pick_types(meg='mag') epochs_joint = epochs.copy().pick_types(meg=True) # Make csd matrices freqs = np.arange(*freq_range[subject]) csd = mne.time_frequency.csd_morlet(epochs, freqs, tmin=-0.8, tmax=1.0,
brain = mne.viz.Brain('sample', subjects_dir=subjects_dir, **brain_kwargs) evoked = mne.read_evokeds(op.join(sample_dir, 'sample_audvis-ave.fif'))[0] trans = mne.read_trans(op.join(sample_dir, 'sample_audvis_raw-trans.fif')) brain.add_sensors(evoked.info, trans) brain.show_view(distance=500) # move back to show sensors # %% # Add current dipoles # ------------------- # # Dipole modeling as in :ref:`tut-dipole-orientations` can be plotted on the # brain as well. brain = mne.viz.Brain('sample', subjects_dir=subjects_dir, **brain_kwargs) dip = mne.read_dipole(op.join(sample_dir, 'sample_audvis_set1.dip')) cmap = plt.get_cmap('YlOrRd') colors = [cmap(gof / dip.gof.max()) for gof in dip.gof] brain.add_dipole(dip, trans, colors=colors, scales=list(dip.amplitude * 1e8)) brain.show_view(azimuth=-20, elevation=60, distance=300) img = brain.screenshot() # for next section # %% # Create a screenshot for exporting the brain image # ------------------------------------------------- # Also, we can a static image of the brain using ``screenshot`` (above), # which will allow us to add a colorbar. This is useful for figures in # publications. fig, ax = plt.subplots() ax.imshow(img)
def test_dipole_fitting(): """Test dipole fitting""" amp = 10e-9 tempdir = _TempDir() rng = np.random.RandomState(0) fname_dtemp = op.join(tempdir, "test.dip") fname_sim = op.join(tempdir, "test-ave.fif") fwd = convert_forward_solution(read_forward_solution(fname_fwd), surf_ori=False, force_fixed=True) evoked = read_evokeds(fname_evo)[0] cov = read_cov(fname_cov) n_per_hemi = 5 vertices = [np.sort(rng.permutation(s["vertno"])[:n_per_hemi]) for s in fwd["src"]] nv = sum(len(v) for v in vertices) stc = SourceEstimate(amp * np.eye(nv), vertices, 0, 0.001) evoked = simulate_evoked(fwd, stc, evoked.info, cov, snr=20, random_state=rng) # For speed, let's use a subset of channels (strange but works) picks = np.sort( np.concatenate( [pick_types(evoked.info, meg=True, eeg=False)[::2], pick_types(evoked.info, meg=False, eeg=True)[::2]] ) ) evoked.pick_channels([evoked.ch_names[p] for p in picks]) evoked.add_proj(make_eeg_average_ref_proj(evoked.info)) write_evokeds(fname_sim, evoked) # Run MNE-C version run_subprocess( [ "mne_dipole_fit", "--meas", fname_sim, "--meg", "--eeg", "--noise", fname_cov, "--dip", fname_dtemp, "--mri", fname_fwd, "--reg", "0", "--tmin", "0", ] ) dip_c = read_dipole(fname_dtemp) # Run mne-python version sphere = make_sphere_model(head_radius=0.1) dip, residuals = fit_dipole(evoked, fname_cov, sphere, fname_fwd) # Sanity check: do our residuals have less power than orig data? data_rms = np.sqrt(np.sum(evoked.data ** 2, axis=0)) resi_rms = np.sqrt(np.sum(residuals ** 2, axis=0)) factor = 1.0 # XXX weird, inexplicable differenc for 3.5 build we'll assume is due to # Anaconda bug for now... if os.getenv("TRAVIS", "false") == "true" and sys.version[:3] in ("3.5", "2.7"): factor = 0.8 assert_true((data_rms > factor * resi_rms).all(), msg="%s (factor: %s)" % ((data_rms / resi_rms).min(), factor)) # Compare to original points transform_surface_to(fwd["src"][0], "head", fwd["mri_head_t"]) transform_surface_to(fwd["src"][1], "head", fwd["mri_head_t"]) src_rr = np.concatenate([s["rr"][v] for s, v in zip(fwd["src"], vertices)], axis=0) src_nn = np.concatenate([s["nn"][v] for s, v in zip(fwd["src"], vertices)], axis=0) # MNE-C skips the last "time" point :( dip.crop(dip_c.times[0], dip_c.times[-1]) src_rr, src_nn = src_rr[:-1], src_nn[:-1] # check that we did at least as well corrs, dists, gc_dists, amp_errs, gofs = [], [], [], [], [] for d in (dip_c, dip): new = d.pos diffs = new - src_rr corrs += [np.corrcoef(src_rr.ravel(), new.ravel())[0, 1]] dists += [np.sqrt(np.mean(np.sum(diffs * diffs, axis=1)))] gc_dists += [180 / np.pi * np.mean(np.arccos(np.sum(src_nn * d.ori, axis=1)))] amp_errs += [np.sqrt(np.mean((amp - d.amplitude) ** 2))] gofs += [np.mean(d.gof)] assert_true(dists[0] >= dists[1] * factor, "dists: %s" % dists) assert_true(corrs[0] <= corrs[1] / factor, "corrs: %s" % corrs) assert_true(gc_dists[0] >= gc_dists[1] * factor, "gc-dists (ori): %s" % gc_dists) assert_true(amp_errs[0] >= amp_errs[1] * factor, "amplitude errors: %s" % amp_errs) assert_true(gofs[0] <= gofs[1] / factor, "gof: %s" % gofs)
def test_dipole_fitting(): """Test dipole fitting""" amp = 10e-9 tempdir = _TempDir() rng = np.random.RandomState(0) fname_dtemp = op.join(tempdir, 'test.dip') fname_sim = op.join(tempdir, 'test-ave.fif') fwd = convert_forward_solution(read_forward_solution(fname_fwd), surf_ori=False, force_fixed=True) evoked = read_evokeds(fname_evo)[0] cov = read_cov(fname_cov) n_per_hemi = 5 vertices = [np.sort(rng.permutation(s['vertno'])[:n_per_hemi]) for s in fwd['src']] nv = sum(len(v) for v in vertices) stc = SourceEstimate(amp * np.eye(nv), vertices, 0, 0.001) with warnings.catch_warnings(record=True): # semi-def cov evoked = generate_evoked(fwd, stc, evoked, cov, snr=20, random_state=rng) # For speed, let's use a subset of channels (strange but works) picks = np.sort(np.concatenate([ pick_types(evoked.info, meg=True, eeg=False)[::2], pick_types(evoked.info, meg=False, eeg=True)[::2]])) evoked.pick_channels([evoked.ch_names[p] for p in picks]) evoked.add_proj(make_eeg_average_ref_proj(evoked.info)) write_evokeds(fname_sim, evoked) # Run MNE-C version run_subprocess([ 'mne_dipole_fit', '--meas', fname_sim, '--meg', '--eeg', '--noise', fname_cov, '--dip', fname_dtemp, '--mri', fname_fwd, '--reg', '0', '--tmin', '0', ]) dip_c = read_dipole(fname_dtemp) # Run mne-python version sphere = make_sphere_model(head_radius=0.1) dip, residuals = fit_dipole(evoked, fname_cov, sphere, fname_fwd) # Sanity check: do our residuals have less power than orig data? data_rms = np.sqrt(np.sum(evoked.data ** 2, axis=0)) resi_rms = np.sqrt(np.sum(residuals ** 2, axis=0)) assert_true((data_rms > resi_rms).all()) # Compare to original points transform_surface_to(fwd['src'][0], 'head', fwd['mri_head_t']) transform_surface_to(fwd['src'][1], 'head', fwd['mri_head_t']) src_rr = np.concatenate([s['rr'][v] for s, v in zip(fwd['src'], vertices)], axis=0) src_nn = np.concatenate([s['nn'][v] for s, v in zip(fwd['src'], vertices)], axis=0) # MNE-C skips the last "time" point :( dip.crop(dip_c.times[0], dip_c.times[-1]) src_rr, src_nn = src_rr[:-1], src_nn[:-1] # check that we did at least as well corrs, dists, gc_dists, amp_errs, gofs = [], [], [], [], [] for d in (dip_c, dip): new = d.pos diffs = new - src_rr corrs += [np.corrcoef(src_rr.ravel(), new.ravel())[0, 1]] dists += [np.sqrt(np.mean(np.sum(diffs * diffs, axis=1)))] gc_dists += [180 / np.pi * np.mean(np.arccos(np.sum(src_nn * d.ori, axis=1)))] amp_errs += [np.sqrt(np.mean((amp - d.amplitude) ** 2))] gofs += [np.mean(d.gof)] assert_true(dists[0] >= dists[1], 'dists: %s' % dists) assert_true(corrs[0] <= corrs[1], 'corrs: %s' % corrs) assert_true(gc_dists[0] >= gc_dists[1], 'gc-dists (ori): %s' % gc_dists) assert_true(amp_errs[0] >= amp_errs[1], 'amplitude errors: %s' % amp_errs)
def test_make_forward_dipole(): """Test forward-projecting dipoles.""" rng = np.random.RandomState(0) evoked = read_evokeds(fname_evo)[0] cov = read_cov(fname_cov) dip_c = read_dipole(fname_dip) # Only use magnetometers for speed! picks = pick_types(evoked.info, meg='mag', eeg=False) evoked.pick_channels([evoked.ch_names[p] for p in picks]) info = evoked.info # Make new Dipole object with n_test_dipoles picked from the dipoles # in the test dataset. n_test_dipoles = 3 # minimum 3 needed to get uneven sampling in time dipsel = np.sort(rng.permutation(np.arange(len(dip_c)))[:n_test_dipoles]) dip_test = Dipole(times=dip_c.times[dipsel], pos=dip_c.pos[dipsel], amplitude=dip_c.amplitude[dipsel], ori=dip_c.ori[dipsel], gof=dip_c.gof[dipsel]) sphere = make_sphere_model(head_radius=0.1) # Warning emitted due to uneven sampling in time with warnings.catch_warnings(record=True) as w: fwd, stc = make_forward_dipole(dip_test, sphere, info, trans=fname_trans) assert_true(issubclass(w[-1].category, RuntimeWarning)) # stc is list of VolSourceEstimate's assert_true(isinstance(stc, list)) for nd in range(n_test_dipoles): assert_true(isinstance(stc[nd], VolSourceEstimate)) # Now simulate evoked responses for each of the test dipoles, # and fit dipoles to them (sphere model, MEG and EEG) times, pos, amplitude, ori, gof = [], [], [], [], [] snr = 20. # add a tiny amount of noise to the simulated evokeds for s in stc: evo_test = simulate_evoked(fwd, s, info, cov, snr=snr, random_state=rng) # evo_test.add_proj(make_eeg_average_ref_proj(evo_test.info)) dfit, resid = fit_dipole(evo_test, cov, sphere, None) times += dfit.times.tolist() pos += dfit.pos.tolist() amplitude += dfit.amplitude.tolist() ori += dfit.ori.tolist() gof += dfit.gof.tolist() # Create a new Dipole object with the dipole fits dip_fit = Dipole(times, pos, amplitude, ori, gof) # check that true (test) dipoles and fits are "close" # cf. mne/tests/test_dipole.py diff = dip_test.pos - dip_fit.pos corr = np.corrcoef(dip_test.pos.ravel(), dip_fit.pos.ravel())[0, 1] dist = np.sqrt(np.mean(np.sum(diff * diff, axis=1))) gc_dist = 180 / np.pi * \ np.mean(np.arccos(np.sum(dip_test.ori * dip_fit.ori, axis=1))) amp_err = np.sqrt(np.mean((dip_test.amplitude - dip_fit.amplitude)**2)) # Make sure each coordinate is close to reference # NB tolerance should be set relative to snr of simulated evoked! assert_allclose(dip_fit.pos, dip_test.pos, rtol=0, atol=1e-2, err_msg='position mismatch') assert_true(dist < 1e-2, 'dist: %s' % dist) # within 1 cm assert_true(corr > 1 - 1e-2, 'corr: %s' % corr) assert_true(gc_dist < 20, 'gc_dist: %s' % gc_dist) # less than 20 degrees assert_true(amp_err < 10e-9, 'amp_err: %s' % amp_err) # within 10 nAm # Make sure rejection works with BEM: one dipole at z=1m # NB _make_forward.py:_prepare_for_forward will raise a RuntimeError # if no points are left after min_dist exclusions, hence 2 dips here! dip_outside = Dipole(times=[0., 0.001], pos=[[0., 0., 1.0], [0., 0., 0.040]], amplitude=[100e-9, 100e-9], ori=[[1., 0., 0.], [1., 0., 0.]], gof=1) assert_raises(ValueError, make_forward_dipole, dip_outside, fname_bem, info, fname_trans) # if we get this far, can safely assume the code works with BEMs too # -> use sphere again below for speed # Now make an evenly sampled set of dipoles, some simultaneous, # should return a VolSourceEstimate regardless times = [0., 0., 0., 0.001, 0.001, 0.002] pos = np.random.rand(6, 3) * 0.020 + \ np.array([0., 0., 0.040])[np.newaxis, :] amplitude = np.random.rand(6) * 100e-9 ori = np.eye(6, 3) + np.eye(6, 3, -3) gof = np.arange(len(times)) / len(times) # arbitrary dip_even_samp = Dipole(times, pos, amplitude, ori, gof) fwd, stc = make_forward_dipole(dip_even_samp, sphere, info, trans=fname_trans) assert_true(isinstance, VolSourceEstimate) assert_allclose(stc.times, np.arange(0., 0.003, 0.001))
tmax=0.4, method='empirical', rank='info') # Compute evokeds tmin = 0.03 tmax = 0.05 evoked_grad = epochs_grad.average().crop(tmin, tmax) evoked_mag = epochs_mag.average().crop(tmin, tmax) evoked_joint = epochs_joint.average().crop(tmin, tmax) ############################################################################### # read dipole created by 06_dipole.py ############################################################################### dip = mne.read_dipole(somato_fname.ecd) # get the position of the dipole in MRI coordinates mri_pos = mne.head_to_mri(dip.pos, mri_head_t=trans, subject=subject_id, subjects_dir=somato_fname.subjects_dir) # get true_vert_idx rr = fwd['src'][0]['rr'] inuse = fwd['src'][0]['inuse'] indices = np.where(fwd['src'][0]['inuse'])[0] rr_inuse = rr[indices] true_vert_idx = np.where( np.linalg.norm(rr_inuse - dip.pos, axis=1) == np.linalg.norm( rr_inuse - dip.pos, axis=1).min())[0][0]