Esempio n. 1
0
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
Esempio n. 2
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]]) / 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)
Esempio n. 3
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)
Esempio n. 4
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)')
Esempio n. 5
0
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)
Esempio n. 6
0
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)
Esempio n. 8
0
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
Esempio n. 9
0
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