def convert_aseg_head_to_mni(labels_aseg, mri_head_t, sbj, subjects_dir): """Convert the coordinates of substructures vol from head coordinate system to MNI ones to MNI.""" ROI_aseg_MNI_coords = list() ROI_aseg_name = list() ROI_aseg_color = list() # get the MRI (surface RAS) -> head matrix # head_mri_t = invert_transform(mri_head_t) # head->MRI (surface RAS) for label in labels_aseg: print(('sub structure {} \n'.format(label.name))) # Convert coo from head coordinate system to MNI ones. aseg_coo = label.pos coo_MNI = mne.head_to_mni(aseg_coo, sbj, mri_head_t, subjects_dir) ROI_aseg_MNI_coords.append(coo_MNI) ROI_aseg_name.append(label.name) ROI_aseg_color.append(label.color) nvert_roi = [len(vn) for vn in ROI_aseg_MNI_coords] nvert_src = [l.pos.shape[0] for l in labels_aseg] if np.sum(nvert_roi) != np.sum(nvert_src): raise RuntimeError('number of vol src space vertices must be equal to \ the total number of ROI vertices') roi_mni = dict(ROI_aseg_name=ROI_aseg_name, ROI_aseg_MNI_coords=ROI_aseg_MNI_coords, ROI_aseg_color=ROI_aseg_color) return roi_mni
def test_head_to_mni(): """Test conversion of aseg vertices to MNI coordinates.""" # obtained using freeview coords = np.array([[22.52, 11.24, 17.72], [22.52, 5.46, 21.58], [16.10, 5.46, 22.23], [21.24, 8.36, 22.23]]) / 1000. xfm = read_talxfm('sample', subjects_dir) coords_MNI = apply_trans(xfm['trans'], coords) * 1000. mri_head_t, _ = _get_trans(trans_fname, 'mri', 'head', allow_none=False) # obtained from sample_audvis-meg-oct-6-mixed-fwd.fif coo_right_amygdala = np.array([[0.01745682, 0.02665809, 0.03281873], [0.01014125, 0.02496262, 0.04233755], [0.01713642, 0.02505193, 0.04258181], [0.01720631, 0.03073877, 0.03850075]]) coords_MNI_2 = head_to_mni(coo_right_amygdala, 'sample', mri_head_t, subjects_dir) # less than 1mm error assert_allclose(coords_MNI, coords_MNI_2, atol=10.0)
def test_head_to_mni(): """Test conversion of aseg vertices to MNI coordinates.""" # obtained using freeview coords = np.array([[22.52, 11.24, 17.72], [22.52, 5.46, 21.58], [16.10, 5.46, 22.23], [21.24, 8.36, 22.23]]) xfm = _read_talxfm('sample', subjects_dir) coords_MNI = apply_trans(xfm['trans'], coords) trans = read_trans(trans_fname) # head->MRI (surface RAS) mri_head_t = invert_transform(trans) # MRI (surface RAS)->head matrix # obtained from sample_audvis-meg-oct-6-mixed-fwd.fif coo_right_amygdala = np.array([[0.01745682, 0.02665809, 0.03281873], [0.01014125, 0.02496262, 0.04233755], [0.01713642, 0.02505193, 0.04258181], [0.01720631, 0.03073877, 0.03850075]]) coords_MNI_2 = head_to_mni(coo_right_amygdala, 'sample', mri_head_t, subjects_dir) # less than 1mm error assert_allclose(coords_MNI, coords_MNI_2, atol=10.0)
evoked_full = evoked.copy() evoked.crop(0.07, 0.08) # Fit a dipole dip = mne.fit_dipole(evoked, fname_cov, fname_bem, fname_trans)[0] # Plot the result in 3D brain with the MRI image. dip.plot_locations(fname_trans, 'sample', subjects_dir, mode='orthoview') # Plot the result in 3D brain with the MRI image using Nilearn # In MRI coordinates and in MNI coordinates (template brain) trans = mne.read_trans(fname_trans) subject = 'sample' mni_pos = mne.head_to_mni(dip.pos, mri_head_t=trans, subject=subject, subjects_dir=subjects_dir) mri_pos = mne.head_to_mri(dip.pos, mri_head_t=trans, subject=subject, subjects_dir=subjects_dir) t1_fname = op.join(subjects_dir, subject, 'mri', 'T1.mgz') fig = plot_anat(t1_fname, cut_coords=mri_pos[0], title='Dipole loc.') template = load_mni152_template() fig = plot_anat(template, cut_coords=mni_pos[0], title='Dipole loc. (MNI Space)')
def test_scale_mri_xfm(tmp_path, few_surfaces, subjects_dir_tmp_few): """Test scale_mri transforms and MRI scaling.""" # scale fsaverage tempdir = str(subjects_dir_tmp_few) sample_dir = subjects_dir_tmp_few / 'sample' subject_to = 'flachkopf' spacing = 'oct2' for subject_from in ('fsaverage', 'sample'): if subject_from == 'fsaverage': scale = 1. # single dim else: scale = [0.9, 2, .8] # separate src_from_fname = op.join(tempdir, subject_from, 'bem', '%s-%s-src.fif' % (subject_from, spacing)) src_from = mne.setup_source_space(subject_from, spacing, subjects_dir=tempdir, add_dist=False) write_source_spaces(src_from_fname, src_from) vertices_from = np.concatenate([s['vertno'] for s in src_from]) assert len(vertices_from) == 36 hemis = ([0] * len(src_from[0]['vertno']) + [1] * len(src_from[0]['vertno'])) mni_from = mne.vertex_to_mni(vertices_from, hemis, subject_from, subjects_dir=tempdir) if subject_from == 'fsaverage': # identity transform source_rr = np.concatenate( [s['rr'][s['vertno']] for s in src_from]) * 1e3 assert_allclose(mni_from, source_rr) if subject_from == 'fsaverage': overwrite = skip_fiducials = False else: with pytest.raises(IOError, match='No fiducials file'): scale_mri(subject_from, subject_to, scale, subjects_dir=tempdir) skip_fiducials = True with pytest.raises(IOError, match='already exists'): scale_mri(subject_from, subject_to, scale, subjects_dir=tempdir, skip_fiducials=skip_fiducials) overwrite = True if subject_from == 'sample': # support for not needing all surf files os.remove(op.join(sample_dir, 'surf', 'lh.curv')) scale_mri(subject_from, subject_to, scale, subjects_dir=tempdir, verbose='debug', overwrite=overwrite, skip_fiducials=skip_fiducials) if subject_from == 'fsaverage': assert _is_mri_subject(subject_to, tempdir), "Scaling failed" src_to_fname = op.join(tempdir, subject_to, 'bem', '%s-%s-src.fif' % (subject_to, spacing)) assert op.exists(src_to_fname), "Source space was not scaled" # Check MRI scaling fname_mri = op.join(tempdir, subject_to, 'mri', 'T1.mgz') assert op.exists(fname_mri), "MRI was not scaled" # Check MNI transform src = mne.read_source_spaces(src_to_fname) vertices = np.concatenate([s['vertno'] for s in src]) assert_array_equal(vertices, vertices_from) mni = mne.vertex_to_mni(vertices, hemis, subject_to, subjects_dir=tempdir) assert_allclose(mni, mni_from, atol=1e-3) # 0.001 mm # Check head_to_mni (the `trans` here does not really matter) trans = rotation(0.001, 0.002, 0.003) @ translation(0.01, 0.02, 0.03) trans = Transform('head', 'mri', trans) pos_head_from = np.random.RandomState(0).randn(4, 3) pos_mni_from = mne.head_to_mni(pos_head_from, subject_from, trans, tempdir) pos_mri_from = apply_trans(trans, pos_head_from) pos_mri = pos_mri_from * scale pos_head = apply_trans(invert_transform(trans), pos_mri) pos_mni = mne.head_to_mni(pos_head, subject_to, trans, tempdir) assert_allclose(pos_mni, pos_mni_from, atol=1e-3)
def create_mxne_summary( subjects, p, morph_subject=None, n_display=None, pattern_in='', pattern_out='_mxne', path_out='./', title='%s Dipoles', ): '''Create a report and spreadsheet about mixed-norm dipoles.''' src_file = os.path.join(p.subjects_dir, 'fsaverage', 'bem', 'fsaverage-ico-5-src.fif') src_fsavg = mne.read_source_spaces(src_file) src_file = os.path.join(p.subjects_dir, '14mo_surr', 'bem', '14mo_surr-oct-6-src.fif') src_14mo = mne.read_source_spaces(src_file) mni_labels = mne.read_labels_from_annot('fsaverage', 'HCPMMP1', subjects_dir=p.subjects_dir) labels = mne.read_labels_from_annot('14mo_surr', use_parc, subjects_dir=p.subjects_dir) for subject in subjects: # Load STCs and other saved data # cond = p.stc_params['condition'] stc_path = os.path.join(p.work_dir, subject, p.stc_dir) stc_stem = subject + '_' + cond + pattern_in stc_file = os.path.join(stc_path, stc_stem) if not os.path.isfile(stc_file + '-lh.stc'): print(f'** STC file matching {stc_stem} not found ********.\n') continue stc_mxne = mne.read_source_estimate(stc_file) n_dipoles, n_times = stc_mxne.data.shape meta_data = np.load(stc_file + '.npy', allow_pickle=True) gof_mxne = meta_data[0] residual_mxne = meta_data[1] evk_path = os.path.join(p.work_dir, subject, p.inverse_dir) evk_file = f'Locations_40-sss_eq_{subject}-ave.fif' evk_file = os.path.join(evk_path, evk_file) evoked = mne.read_evokeds(evk_file, condition=cond, kind='average') evoked.pick_types(meg=True) cov_path = os.path.join(p.work_dir, subject, p.cov_dir) cov_file = f'{subject}-40-sss-cov.fif' cov_file = os.path.join(cov_path, cov_file) cov = mne.read_cov(cov_file) trans_path = os.path.join(p.work_dir, subject, p.trans_dir) trans_file = f'{subject}-trans.fif' trans_file = os.path.join(trans_path, trans_file) trans = mne.read_trans(trans_file, verbose=False) fwd_path = os.path.join(p.work_dir, subject, p.forward_dir) fwd_file = f'{subject}-sss-fwd.fif' fwd_file = os.path.join(fwd_path, fwd_file) fwd = mne.read_forward_solution(fwd_file, verbose=False) assert fwd['src'][0]['nuse'] == src_14mo[0]['nuse'] assert fwd['src'][1]['nuse'] == src_14mo[1]['nuse'] # Run analysis on the dipoles, then sort then by goodness-of-fit # results = analyze_dipoles(stc_mxne, gof_mxne, evoked, cov, p.stc_params['gof_t_range']) results, sort_idx = sort_dipoles(results) # stc still unsorted gof_results, amp_results = results assert len(gof_results) == n_dipoles # Collect info for the top dipoles, in order # n_show = n_dipoles if n_display: n_show = min(n_display, n_show) n_left = len(stc_mxne.vertices[0]) # .data stacked lh then rh postop, mnitop, wavtop = [], [], [] for i in range(n_dipoles): di = sort_idx[i] hemid = int(di >= n_left) vidx = di - hemid * n_left vert = stc_mxne.vertices[hemid][vidx] pos = fwd['src'][hemid]['rr'][vert] postop.append(pos) mni = mne.vertex_to_mni(vert, hemid, subject, subjects_dir=p.subjects_dir) mnitop.append(mni) wav = stc_mxne.data[di, :] wavtop.append(wav) assert wav[amp_results[i].pidx] == amp_results[i].peak # check last # Make various figures # figure_list, figure_info, figure_comment = [], [], [] # 1) Top dipoles in one set of surface maps. if morph_subject: src_subject = morph_subject caption = 'Surface Plots | ' + morph_subject else: src_subject = subject caption = 'Surface Plots | Coreg.' fig_surface = make_surfaceplots(stc_mxne, src_subject, p.subjects_dir, sort_idx, parc=use_parc) figure_list.append(fig_surface) figure_info.append([caption, 'Surface Plots']) figure_comment.append(color_comment) # 2) Top dipoles in 3D slices (non-morphed and MNI). mri_file = os.path.join(p.subjects_dir, subject, 'mri', 'T1.mgz') postop_mri = mne.head_to_mri(postop, mri_head_t=trans, subject=subject, subjects_dir=p.subjects_dir) postop_mni = mne.head_to_mni(postop, mri_head_t=trans, subject=subject, subjects_dir=p.subjects_dir) assert_allclose(mnitop[0], postop_mni[0], atol=0.01) assert_allclose(mnitop[-1], postop_mni[-1], atol=0.01) fig_orthog1 = make_orthogplots(mri_file, postop_mri[:n_show]) fig_orthog2 = make_orthogplots(mni_template, postop_mni[:n_show]) figure_list.append(fig_orthog1) figure_info.append(['Orthogonal Plots | Coreg.', 'Orthogonal Plots']) figure_comment.append(None) figure_list.append(fig_orthog2) figure_info.append(['Orthogonal Plots | MNI)', 'Orthogonal Plots']) figure_comment.append(f'Top {n_show} of {n_dipoles} dipoles ' 'displayed.') # 3) Top dipoles' time waveforms. fig_wav = make_sourcewavs(wavtop, stc_mxne.times, p.stc_params['gof_t_range']) figure_list.append(fig_wav) figure_info.append(['STC Time Course', 'Temporal Waveforms']) figure_comment.append(None) # 4) Evoked and residual waveforms (averages across sensors) fig_sensor = make_sensorwavs(evoked, residual_mxne) figure_list.append(fig_sensor) figure_info.append(['Sensor Time Course', 'Temporal Waveforms']) figure_comment.append(None) # Determine 14-mo surrogate "aparc" label for each dipole # labels_stc = [] # note these are not gof-ordered for hh, hemi in enumerate(('lh', 'rh')): for vert in stc_mxne.vertices[hh]: label = which_label(vert, hemi, labels) if label: labels_stc.append(label.name) else: labels_stc.append('no_label') # Expand the sparse STC so it can be morphed (X='expanded') # # v_lh = fwd['src'][0]['vertno'] # the full source space # v_rh = fwd['src'][1]['vertno'] # n_vtotal = vertices = len(v_lh) + len(v_rh) # data_mxneX = np.zeros((n_vtotal, n_times)) # idx_vrts = np.isin(v_lh, stc_mxne.vertices[0]) # idx_vrts = np.where(idx_vrts)[0] # data_mxneX[idx_vrts, :] = stc_mxne.data[:n_left, :] # idx_vrts = np.isin(v_rh, stc_mxne.vertices[1]) # idx_vrts = np.where(idx_vrts)[0] # data_mxneX[idx_vrts, :] = stc_mxne.data[n_left:, :] # stc_mxneX = mne.SourceEstimate(data_mxneX, [v_lh, v_rh], # tmin=stc_mxne.tmin, tstep=stc_mxne.tstep, # subject=stc_mxne.subject) # Determine fsaverage "HCPMMP1" labels for each dipole # # Note: 'sparse' doesn't give a 1-to-1 mapping. morph_fcn = mne.compute_source_morph(stc_mxne, src_to=src_fsavg, smooth='nearest', spacing=None, warn=False, subjects_dir=p.subjects_dir, niter_sdr=(), sparse=True, subject_from=subject, subject_to='fsaverage') mlabels_stc = [] # like above, but now for fsaverage:HCPMMP1 verts_mni = [] for di in range(n_dipoles): stc_temp = stc_mxne.copy() # zero all but dipole of interest stc_temp.data = np.zeros((n_dipoles, n_times)) stc_temp.data[di, :] = stc_mxne.data[di, :] mstc_temp = morph_fcn.apply(stc_temp) vidx = np.where(mstc_temp.data[:, 0] > 0)[0] vidx_lh = [i for i in vidx if i < n_left] # don't assume hemi vidx_rh = [i - n_left for i in vidx if i >= n_left] verts_byhemi = [None, None] verts_byhemi[0] = mstc_temp.vertices[0][vidx_lh] verts_byhemi[1] = mstc_temp.vertices[1][vidx_rh] verts_mni.append(verts_byhemi) cnt = 0 for verts, hemi, prefix in zip(verts_byhemi, ['lh', 'rh'], ['L_', 'R_']): if not verts: continue vert = verts[0] # should only be one with sparse arg. lbl = which_label(vert, hemi, mni_labels) if lbl: lbl = lbl.name else: lbl = 'no_label' lbl = re.sub(rf"^{prefix}", "", lbl) lbl = re.sub(r"_ROI", "", lbl) cnt += 1 assert cnt == 1 # only one hemisphere should be valid mlabels_stc.append(lbl) # Create formatted tables for a report section # # SMB: Saving as string objects in case they can be added to report. strobj1 = StringIO() # TABLE 1: sorted gof and amplitude info sprint = lambda *x: print(*x, file=strobj1, end='') ff = '<8.2f' # format: center on 8-char field, 2 decimal places sprint(f'{"Dip #":^6} {"Peak/Mean Amp":<16} ' f'{"Peak/Mean GOF":<16} {"GOF Time":<8}\n') for i in range(n_dipoles): amp_m = 1e9 * amp_results[i].mean amp_p = 1e9 * amp_results[i].peak gof_m = gof_results[i].mean gof_p = gof_results[i].peak time_p = evoked.times[gof_results[i].pidx] sprint(f'{i:^6} {amp_p:{ff}}{amp_m:{ff}} ' f'{gof_p:{ff}}{gof_m:{ff}} ' f'{time_p:{"<8.3f"}}\n') sprint('\n') strobj2 = StringIO() # TABLE 2: coordinate and label info sprint = lambda *x: print(*x, file=strobj2, end='') ff = '<20' sprint(f'{"Dip #":^6} {"14mo Coord":{ff}} {"MNI Coord":{ff}} ' f'{"14mo Aparc | Fsavg HCPMMP1":{ff}}\n') for i in range(n_dipoles): di = sort_idx[i] hemid = int(di >= n_left) # hemi = 'rh' if hemid else 'lh' vidx = di - hemid * n_left vert = stc_mxne.vertices[hemid][vidx] coord = src_14mo[hemid]['rr'][vert] * 1000 coord_str = ' '.join([f'{x:.1f}' for x in coord]) vert = verts_mni[di][hemid][0] # just the first one coord = src_fsavg[hemid]['rr'][vert] * 1000 mcoord_str = ' '.join([f'{x:.1f}' for x in coord]) sprint(f'{i:^6} {coord_str:{ff}} {mcoord_str:{ff}} ' f'{labels_stc[di]:{ff}}\n {"":<47} ' f'{mlabels_stc[di]:{ff}}\n') # Print out the tables # print(f'\nGOF-sorted dipole info for {subject}:') strobj1.seek(0) print(strobj1.read()) strobj1.close() print(f'\nGOF-sorted position info for {subject}:') strobj2.seek(0) print(strobj2.read()) strobj2.close() # Compile all figures into a report # print(f'Compiling report for {subject}.') if not os.path.exists(path_out): os.mkdir(path_out) if '%s ' in title: title_use = title.replace('%s ', 'Group') else: title_use = title report = mne.Report(title=title_use, image_format='png') for fig, info, cstr in zip(figure_list, figure_info, figure_comment): report.add_figs_to_section(fig, captions=info[0], scale=1.0, section=info[1], comments=cstr) report_file = os.path.join(path_out, subject + pattern_out + '.html') report.save(report_file, open_browser=False, overwrite=True)
# --------------------------------- ## ECD from nilearn.plotting import plot_anat from mne.evoked import combine_evoked from mne.simulation import simulate_evoked from mne.forward import make_forward_dipole # evoked=evoked_full evoked_full = evoked.copy() evoked.crop(0.14, 0.16) # Fit a dipole dip = mne.fit_dipole(evoked, cov, bem, trans)[0] # Plot the result in 3D brain with the MRI image. dip.plot_locations(trans, mri_partic, subjects_dir=mri_dir, mode='orthoview') #plot on scan mni_pos = mne.head_to_mni(dip.pos, mri_head_t=trans,subject=mri_partic, subjects_dir=mri_dir) mri_pos = mne.head_to_mri(dip.pos, mri_head_t=trans,subject=mri_partic, subjects_dir=mri_dir) t1_fname = mri_dir+'\\'+ mri_partic+ '\\mri\\T1.mgz' fig_T1 = plot_anat(t1_fname, cut_coords=mri_pos[0], title='Dipole loc.') # #plot on standard # from nilearn.datasets import load_mni152_template # template = load_mni152_template() # fig_template = plot_anat(template, cut_coords=mni_pos[0],title='Dipole loc. (MNI Space)') #plot fied predicted by dipole with max goodness of fit, compare to data and take diff fwd_dip, stc_dip = make_forward_dipole(dip, bem, evoked.info, trans) pred_evoked = simulate_evoked(fwd_dip, stc_dip, evoked.info, cov=None, nave=np.inf) # find time point with highest goodness of fit (gof) best_idx = np.argmax(dip.gof)
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
evoked.pick_types(meg=True, eeg=False) evoked_full = evoked.copy() evoked.crop(0.07, 0.08) # Fit a dipole dip = mne.fit_dipole(evoked, fname_cov, fname_bem, fname_trans)[0] # Plot the result in 3D brain with the MRI image. dip.plot_locations(fname_trans, 'sample', subjects_dir, mode='orthoview') # Plot the result in 3D brain with the MRI image using Nilearn # In MRI coordinates and in MNI coordinates (template brain) trans = mne.read_trans(fname_trans) subject = 'sample' mni_pos = mne.head_to_mni(dip.pos, mri_head_t=trans, subject=subject, subjects_dir=subjects_dir) mri_pos = mne.head_to_mri(dip.pos, mri_head_t=trans, subject=subject, subjects_dir=subjects_dir) t1_fname = op.join(subjects_dir, subject, 'mri', 'T1.mgz') fig_T1 = plot_anat(t1_fname, cut_coords=mri_pos[0], title='Dipole loc.') template = load_mni152_template() fig_template = plot_anat(template, cut_coords=mni_pos[0], title='Dipole loc. (MNI Space)') ############################################################################### # Calculate and visualise magnetic field predicted by dipole with maximum GOF # and compare to the measured data, highlighting the ipsilateral (right) source fwd, stc = make_forward_dipole(dip, fname_bem, evoked.info, fname_trans)
import mne import pickle as pkl import os import numpy as np pth_res = 'assets/' # Load MNE position file in head coordinates: https://mne.tools/dev/auto_tutorials/source-modeling/plot_source_alignment.html with open(pth_res + '/pos.pkl', 'rb') as file: pos = pkl.load(file)[0] # Transform from head space to MNI space subject = 'fsaverage' fs_dir = mne.datasets.fetch_fsaverage(verbose=True) trans = os.path.join(fs_dir, 'bem', 'fsaverage-trans.fif') trans = mne.read_trans(trans) pos_mne_mni = mne.head_to_mni( pos, subject=subject, mri_head_t=trans, verbose=0) / 1000 # Load Brainstorm Vertice Positions in MNI space: pth_bst_pos = 'C:/Users/Lukas/Documents/projects/eeg_inverse_solutions/matlab/results/model/mni_positions.mat' pos_bst_mni = loadmat(pth_bst_pos)['mni_positions'] def k_neighbor_connectivity(pos_bst_mni, pos_mne_mni, k=3): ''' Parameters: ----------- pos_bst_mni : str, path of the brainstorm vertex position file. Positions are required to be in MNI space pos_mne_mni : str, path of the MNE headmodel vertex position file. Positions need to be in MNI space. k : int, number of neighbors to include into the neighbor matrix