def test_make_eeg_average_ref_proj(): """Test EEG average reference projection.""" raw = read_raw_fif(raw_fname, preload=True) eeg = pick_types(raw.info, meg=False, eeg=True) # No average EEG reference assert not np.all(raw._data[eeg].mean(axis=0) < 1e-19) # Apply average EEG reference car = make_eeg_average_ref_proj(raw.info) reref = raw.copy() reref.add_proj(car) reref.apply_proj() assert_array_almost_equal(reref._data[eeg].mean(axis=0), 0, decimal=19) # Error when custom reference has already been applied with raw.info._unlock(): raw.info['custom_ref_applied'] = True pytest.raises(RuntimeError, make_eeg_average_ref_proj, raw.info) # test that an average EEG ref is not added when doing proj raw.set_eeg_reference(projection=True) assert _has_eeg_average_ref_proj(raw.info['projs']) raw.del_proj(idx=-1) assert not _has_eeg_average_ref_proj(raw.info['projs']) raw.apply_proj() assert not _has_eeg_average_ref_proj(raw.info['projs'])
def test_make_eeg_average_ref_proj(): """Test EEG average reference projection.""" raw = read_raw_fif(raw_fname, preload=True) eeg = mne.pick_types(raw.info, meg=False, eeg=True) # No average EEG reference assert not np.all(raw._data[eeg].mean(axis=0) < 1e-19) # Apply average EEG reference car = make_eeg_average_ref_proj(raw.info) reref = raw.copy() reref.add_proj(car) reref.apply_proj() assert_array_almost_equal(reref._data[eeg].mean(axis=0), 0, decimal=19) # Error when custom reference has already been applied raw.info['custom_ref_applied'] = True pytest.raises(RuntimeError, make_eeg_average_ref_proj, raw.info) # test that an average EEG ref is not added when doing proj raw.set_eeg_reference(projection=True) assert _has_eeg_average_ref_proj(raw.info['projs']) raw.del_proj(idx=-1) assert not _has_eeg_average_ref_proj(raw.info['projs']) raw.apply_proj() assert not _has_eeg_average_ref_proj(raw.info['projs'])
def test_sensitivity_maps(): """Test sensitivity map computation.""" fwd = read_forward_solution(fwd_fname) fwd = convert_forward_solution(fwd, surf_ori=True) projs = read_proj(eog_fname) projs.extend(read_proj(ecg_fname)) decim = 6 for ch_type in ['eeg', 'grad', 'mag']: w = read_source_estimate(sensmap_fname % (ch_type, 'lh')).data stc = sensitivity_map(fwd, projs=None, ch_type=ch_type, mode='free', exclude='bads') assert_array_almost_equal(stc.data, w, decim) assert stc.subject == 'sample' # let's just make sure the others run if ch_type == 'grad': # fixed (2) w = read_source_estimate(sensmap_fname % (ch_type, '2-lh')).data stc = sensitivity_map(fwd, projs=None, mode='fixed', ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) if ch_type == 'mag': # ratio (3) w = read_source_estimate(sensmap_fname % (ch_type, '3-lh')).data stc = sensitivity_map(fwd, projs=None, mode='ratio', ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) if ch_type == 'eeg': # radiality (4), angle (5), remaining (6), and dampening (7) modes = ['radiality', 'angle', 'remaining', 'dampening'] ends = ['4-lh', '5-lh', '6-lh', '7-lh'] for mode, end in zip(modes, ends): w = read_source_estimate(sensmap_fname % (ch_type, end)).data stc = sensitivity_map(fwd, projs=projs, mode=mode, ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) # test corner case for EEG stc = sensitivity_map(fwd, projs=[make_eeg_average_ref_proj(fwd['info'])], ch_type='eeg', exclude='bads') # test corner case for projs being passed but no valid ones (#3135) pytest.raises(ValueError, sensitivity_map, fwd, projs=None, mode='angle') pytest.raises(RuntimeError, sensitivity_map, fwd, projs=[], mode='angle') # test volume source space fname = op.join(sample_path, 'sample_audvis_trunc-meg-vol-7-fwd.fif') fwd = read_forward_solution(fname) sensitivity_map(fwd)
def test_sensitivity_maps(): """Test sensitivity map computation""" fwd = mne.read_forward_solution(fwd_fname, surf_ori=True) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') proj_eog = read_proj(eog_fname) decim = 6 for ch_type in ['eeg', 'grad', 'mag']: w = read_source_estimate(sensmap_fname % (ch_type, 'lh')).data stc = sensitivity_map(fwd, projs=None, ch_type=ch_type, mode='free', exclude='bads') assert_array_almost_equal(stc.data, w, decim) assert_true(stc.subject == 'sample') # let's just make sure the others run if ch_type == 'grad': # fixed (2) w = read_source_estimate(sensmap_fname % (ch_type, '2-lh')).data stc = sensitivity_map(fwd, projs=None, mode='fixed', ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) if ch_type == 'mag': # ratio (3) w = read_source_estimate(sensmap_fname % (ch_type, '3-lh')).data stc = sensitivity_map(fwd, projs=None, mode='ratio', ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) if ch_type == 'eeg': # radiality (4), angle (5), remaining (6), and dampening (7) modes = ['radiality', 'angle', 'remaining', 'dampening'] ends = ['4-lh', '5-lh', '6-lh', '7-lh'] for mode, end in zip(modes, ends): w = read_source_estimate(sensmap_fname % (ch_type, end)).data stc = sensitivity_map(fwd, projs=proj_eog, mode=mode, ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) # test corner case for EEG stc = sensitivity_map(fwd, projs=[make_eeg_average_ref_proj(fwd['info'])], ch_type='eeg', exclude='bads') # test volume source space fname = op.join(sample_path, 'sample_audvis_trunc-meg-vol-7-fwd.fif') fwd = mne.read_forward_solution(fname) sensitivity_map(fwd)
def test_sensitivity_maps(): """Test sensitivity map computation.""" fwd = mne.read_forward_solution(fwd_fname) fwd = mne.convert_forward_solution(fwd, surf_ori=True) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') projs = read_proj(eog_fname) projs.extend(read_proj(ecg_fname)) decim = 6 for ch_type in ['eeg', 'grad', 'mag']: w = read_source_estimate(sensmap_fname % (ch_type, 'lh')).data stc = sensitivity_map(fwd, projs=None, ch_type=ch_type, mode='free', exclude='bads') assert_array_almost_equal(stc.data, w, decim) assert_true(stc.subject == 'sample') # let's just make sure the others run if ch_type == 'grad': # fixed (2) w = read_source_estimate(sensmap_fname % (ch_type, '2-lh')).data stc = sensitivity_map(fwd, projs=None, mode='fixed', ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) if ch_type == 'mag': # ratio (3) w = read_source_estimate(sensmap_fname % (ch_type, '3-lh')).data stc = sensitivity_map(fwd, projs=None, mode='ratio', ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) if ch_type == 'eeg': # radiality (4), angle (5), remaining (6), and dampening (7) modes = ['radiality', 'angle', 'remaining', 'dampening'] ends = ['4-lh', '5-lh', '6-lh', '7-lh'] for mode, end in zip(modes, ends): w = read_source_estimate(sensmap_fname % (ch_type, end)).data stc = sensitivity_map(fwd, projs=projs, mode=mode, ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) # test corner case for EEG stc = sensitivity_map(fwd, projs=[make_eeg_average_ref_proj(fwd['info'])], ch_type='eeg', exclude='bads') # test corner case for projs being passed but no valid ones (#3135) assert_raises(ValueError, sensitivity_map, fwd, projs=None, mode='angle') assert_raises(RuntimeError, sensitivity_map, fwd, projs=[], mode='angle') # test volume source space fname = op.join(sample_path, 'sample_audvis_trunc-meg-vol-7-fwd.fif') fwd = mne.read_forward_solution(fname) sensitivity_map(fwd)
def test_make_eeg_average_ref_proj(): """Test EEG average reference projection""" raw = Raw(raw_fname, add_eeg_ref=False, preload=True) eeg = mne.pick_types(raw.info, meg=False, eeg=True) # No average EEG reference assert_true(not np.all(raw._data[eeg].mean(axis=0) < 1e-19)) # Apply average EEG reference car = make_eeg_average_ref_proj(raw.info) reref = raw.copy() reref.add_proj(car) reref.apply_proj() assert_array_almost_equal(reref._data[eeg].mean(axis=0), 0, decimal=19) # Error when custom reference has already been applied raw.info['custom_ref_applied'] = True assert_raises(RuntimeError, make_eeg_average_ref_proj, raw.info)
def test_sensitivity_maps(): """Test sensitivity map computation.""" fwd = mne.read_forward_solution(fwd_fname, surf_ori=True) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") projs = read_proj(eog_fname) projs.extend(read_proj(ecg_fname)) decim = 6 for ch_type in ["eeg", "grad", "mag"]: w = read_source_estimate(sensmap_fname % (ch_type, "lh")).data stc = sensitivity_map(fwd, projs=None, ch_type=ch_type, mode="free", exclude="bads") assert_array_almost_equal(stc.data, w, decim) assert_true(stc.subject == "sample") # let's just make sure the others run if ch_type == "grad": # fixed (2) w = read_source_estimate(sensmap_fname % (ch_type, "2-lh")).data stc = sensitivity_map(fwd, projs=None, mode="fixed", ch_type=ch_type, exclude="bads") assert_array_almost_equal(stc.data, w, decim) if ch_type == "mag": # ratio (3) w = read_source_estimate(sensmap_fname % (ch_type, "3-lh")).data stc = sensitivity_map(fwd, projs=None, mode="ratio", ch_type=ch_type, exclude="bads") assert_array_almost_equal(stc.data, w, decim) if ch_type == "eeg": # radiality (4), angle (5), remaining (6), and dampening (7) modes = ["radiality", "angle", "remaining", "dampening"] ends = ["4-lh", "5-lh", "6-lh", "7-lh"] for mode, end in zip(modes, ends): w = read_source_estimate(sensmap_fname % (ch_type, end)).data stc = sensitivity_map(fwd, projs=projs, mode=mode, ch_type=ch_type, exclude="bads") assert_array_almost_equal(stc.data, w, decim) # test corner case for EEG stc = sensitivity_map(fwd, projs=[make_eeg_average_ref_proj(fwd["info"])], ch_type="eeg", exclude="bads") # test corner case for projs being passed but no valid ones (#3135) assert_raises(ValueError, sensitivity_map, fwd, projs=None, mode="angle") assert_raises(RuntimeError, sensitivity_map, fwd, projs=[], mode="angle") # test volume source space fname = op.join(sample_path, "sample_audvis_trunc-meg-vol-7-fwd.fif") fwd = mne.read_forward_solution(fname) sensitivity_map(fwd)
def test_sensitivity_maps(): """Test sensitivity map computation""" fwd = mne.read_forward_solution(fwd_fname, surf_ori=True) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') proj_eog = read_proj(eog_fname) decim = 6 for ch_type in ['eeg', 'grad', 'mag']: w = read_source_estimate(sensmap_fname % (ch_type, 'lh')).data stc = sensitivity_map(fwd, projs=None, ch_type=ch_type, mode='free', exclude='bads') assert_array_almost_equal(stc.data, w, decim) assert_true(stc.subject == 'sample') # let's just make sure the others run if ch_type == 'grad': # fixed (2) w = read_source_estimate(sensmap_fname % (ch_type, '2-lh')).data stc = sensitivity_map(fwd, projs=None, mode='fixed', ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) if ch_type == 'mag': # ratio (3) w = read_source_estimate(sensmap_fname % (ch_type, '3-lh')).data stc = sensitivity_map(fwd, projs=None, mode='ratio', ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) if ch_type == 'eeg': # radiality (4), angle (5), remaining (6), and dampening (7) modes = ['radiality', 'angle', 'remaining', 'dampening'] ends = ['4-lh', '5-lh', '6-lh', '7-lh'] for mode, end in zip(modes, ends): w = read_source_estimate(sensmap_fname % (ch_type, end)).data stc = sensitivity_map(fwd, projs=proj_eog, mode=mode, ch_type=ch_type, exclude='bads') assert_array_almost_equal(stc.data, w, decim) # test corner case for EEG stc = sensitivity_map(fwd, projs=[make_eeg_average_ref_proj(fwd['info'])], ch_type='eeg', exclude='bads')
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_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_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 = 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(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
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 DeFleCT_make_estimator(forward, noise_cov, labels, lambda2_cov=3/10., lambda2_S=1/9., pick_meg=True, pick_eeg=False, mode='svd', n_svd_comp=1, verbose=None): """ Create the DeFleCT estimator for a set of labels Parameters: ----------- forward: forward solution (assumes surf_ori=True) noise_cov: noise covariance matrix lambda2_cov: regularisation paramter for noise covariance matrix (whitening) pick_meg: Which MEG channels to pick (True/False/'grad'/'mag') pick_eeg: Which EEG channels to pick (True/False) labels: list of labels, first one is the target for DeFleCT mode : 'mean' | 'sum' | 'svd' | PSFs can be computed for different summary measures with labels: 'sum' or 'mean': sum or means of sub-leadfields for labels This corresponds to situations where labels can be assumed to be homogeneously activated. 'svd': SVD components of sub-leadfields for labels This is better suited for situations where activation patterns are assumed to be more variable. "sub-leadfields" are the parts of the forward solutions that belong to vertices within invidual labels. n_svd_comp : integer Number of SVD components for which PSFs will be computed and output (irrelevant for 'sum' and 'mean'). Explained variances within sub-leadfields are shown in screen output. verbose : bool, str, int, or None If not None, override default verbose level (see mne.verbose). Returns: -------- w: np-array (1xn_chan), spatial filter for first column of P F: np-array, whitened leadfield matrix (n_chan x n_vert) P: np-array, whitened projection matrix (n_chan x n_comp) noise_cov_mat: noise covariance matrix as used in DeFleCT whitener: whitening matrix as used in DeFleCT """ # get wanted channels picks = pick_types(forward['info'], meg=pick_meg, eeg=pick_eeg, eog=False, stim=False, exclude='bads') fwd_ch_names_all = [c['ch_name'] for c in forward['info']['chs']] fwd_ch_names = [fwd_ch_names_all[pp] for pp in picks] ch_names = [c for c in fwd_ch_names if ((c not in noise_cov['bads']) and (c not in forward['info']['bads'])) and (c in noise_cov.ch_names)] if not len(forward['info']['bads']) == len(noise_cov['bads']) or \ not all([b in noise_cov['bads'] for b in forward['info']['bads']]): logger.info('\nforward["info"]["bads"] and noise_cov["bads"] do not ' 'match excluding bad channels from both') # reduce forward to desired channels forward = pick_channels_forward(forward, ch_names) noise_cov = pick_channels_cov(noise_cov, ch_names) logger.info("\nNoise covariance matrix has %d channels." % noise_cov.data.shape[0] ) info_fwd = deepcopy(forward['info']) info_fwd['sfreq'] = 1000. if pick_eeg: avgproj = make_eeg_average_ref_proj(info_fwd, activate=True) info_fwd['projs'] = [] info_fwd['projs'].append(avgproj) else: info_fwd['projs'] = noise_cov['projs'] if lambda2_cov: # regularize covariance matrix "old style" lbd = lambda2_cov noise_cov_reg = cov_regularize(noise_cov, info_fwd, mag=lbd['mag'], grad=lbd['gra'], eeg=lbd['eeg'], proj=True) else: # use cov_mat as is noise_cov_reg = noise_cov fwd_info, leadfield, noise_cov_fwd, whitener, n_nzero = _prepare_forward( forward, info_fwd, noise_cov_reg, pca=False, rank=None, verbose=None) leadfield = leadfield[:,2::3] # assumes surf_ori=True, (normal component) n_chan, n_vert = leadfield.shape logger.info("\nLeadfield has dimensions %d by %d\n" % (n_chan, n_vert)) # if EEG present: remove mean of columns for EEG (average-reference) if pick_eeg: print "\nReferening EEG \n" EEG_idx = [cc for cc in range(len(ch_names)) if ch_names[cc][:3]=='EEG'] nr_eeg = len(EEG_idx) lfdmean = leadfield[EEG_idx,:].mean(axis=0) leadfield[EEG_idx,:] = leadfield[EEG_idx,:] - lfdmean[np.newaxis,:] #### CREATE SUBLEADFIELDs FOR LABELS # extract SUBLEADFIELDS for labels label_lfd_summary = DeFleCT_make_subleadfields(labels, forward, leadfield, mode='svd', n_svd_comp=n_svd_comp, verbose=None) #### COMPUTE DEFLECT ESTIMATOR # rename variables to match paper F = np.dot( whitener, leadfield ) P = np.dot( whitener, label_lfd_summary ) nr_comp = P.shape[1] i = np.eye( nr_comp )[0,:].T # desired sensitivity to columns in P t = np.zeros(n_vert).T[np.newaxis,:] # desired CTF associated with w # Compute DeFleCT ESTIMATOR w = DeFleCT_matrix(F, P, i, t, lambda2_S) # add whitener on the right (i.e. input should be unwhitened) w = w.dot(whitener) return w, ch_names, leadfield, label_lfd_summary, noise_cov_fwd, whitener