Exemple #1
0
def test_morphing():
    mne.set_log_level('warning')
    data_dir = mne.datasets.sample.data_path()
    subjects_dir = os.path.join(data_dir, 'subjects')

    sss = datasets._mne_source_space('fsaverage', 'ico-4', subjects_dir)
    vertices_to = [sss[0]['vertno'], sss[1]['vertno']]
    ds = datasets.get_mne_sample(-0.1,
                                 0.1,
                                 src='ico',
                                 sub='index==0',
                                 stc=True)
    stc = ds['stc', 0]
    morph_mat = mne.compute_morph_matrix('sample', 'fsaverage', stc.vertices,
                                         vertices_to, None, subjects_dir)
    ndvar = ds['src']

    morphed_ndvar = morph_source_space(ndvar, 'fsaverage')
    morphed_stc = mne.morph_data_precomputed('sample', 'fsaverage', stc,
                                             vertices_to, morph_mat)
    assert_array_equal(morphed_ndvar.x[0], morphed_stc.data)
    morphed_stc_ndvar = load.fiff.stc_ndvar([morphed_stc],
                                            'fsaverage',
                                            'ico-4',
                                            subjects_dir,
                                            'dSPM',
                                            False,
                                            'src',
                                            parc=None)
    assert_dataobj_equal(morphed_ndvar, morphed_stc_ndvar)
Exemple #2
0
def morph_stc(subject_id):
    subject = "sub%03d" % subject_id
    print("processing subject: %s" % subject)
    data_path = op.join(meg_dir, subject)

    # Morph STCs
    morph_mat = None
    for condition in ('contrast', 'faces_eq', 'scrambled_eq'):
        stc = mne.read_source_estimate(
            op.join(data_path,
                    'mne_dSPM_inverse_highpass-%sHz-%s' % (l_freq, condition)),
            subject)
        if morph_mat is None:
            morph_mat = mne.compute_morph_matrix(subject,
                                                 'fsaverage',
                                                 stc.vertices,
                                                 fsaverage_vertices,
                                                 smooth,
                                                 subjects_dir=subjects_dir,
                                                 warn=False)
        morphed = stc.morph_precomputed('fsaverage', fsaverage_vertices,
                                        morph_mat)
        morphed.save(
            op.join(
                data_path, 'mne_dSPM_inverse_morph_highpass-%sHz-%s' %
                (l_freq, condition)))
        if condition == 'contrast':
            out = morphed
    return out
def morph_data(data_array, parameters_cache, vector, subjects_dir):
    """Morphs the subject brains to fs_average brain.

    :param data_array: Statistical data obtained from obtain_statistical_data function
    :param parameters_cache: Statistical parameters cache obtained from obtain_statistical_data function
    :param vector: Method to perform modelling ('sLORETA' etc.)
    :param subjects_dir: Directory to the brain model
    :return:  (morphed brain data array)
    """
    # Unpack parameter cache dictionary
    n_vertices = parameters_cache['n_vertices']
    n_times = parameters_cache['n_times']
    n_subjects = parameters_cache['n_subjects']
    subject_vertices = parameters_cache['subject_vertices']

    if vector is True:
        n_vec = parameters_cache['n_vec']

    # Create the fs average vertices
    fs_ave_vertices = [np.arange(10242), np.arange(10242)]

    # Add in fs_ave_vertices to parameter_cache
    parameters_cache['fs_ave_vertices'] = fs_ave_vertices

    # Compute the morph matrix
    smooth_int = 20
    morph_mat = compute_morph_matrix('subjects', 'fsaverage', subject_vertices,
                                     fs_ave_vertices, smooth_int, subjects_dir)
    n_vertices_fs_ave = morph_mat.shape[0]
    # morph_mat shape is (20484, 20484)

    # Reshape in order for dot() to work properly
    if vector is False:
        X = data_array.reshape(n_vertices, n_times * n_subjects *
                               2)  # Shape is (20484, 257*12*2)
    else:
        X = data_array.reshape(
            n_vertices * n_vec, n_times * n_subjects *
            2)  # Shape is (20484*3, 257*12*2) ##### TO DOUBLE CHECK #####

    print('Morphing data...')

    X = morph_mat.dot(X)  # morph_mat is a sparse matrix

    # Reshape into (vertices, times, subjects and conditions)
    if vector is False:
        X = X.reshape(n_vertices_fs_ave, n_times, n_subjects,
                      2)  # Shape is (20484, 257, 12, 2)
    # Reshape into (vertices, vecs, times, subjects and conditions)
    else:
        X = X.reshape(n_vertices, n_vec, n_times, n_subjects,
                      2)  # Shape is (20484, 3, 257, 12, 2)
    return X, parameters_cache
Exemple #4
0
def test_morphing():
    mne.set_log_level('warning')
    sss = datasets._mne_source_space('fsaverage', 'ico-4', subjects_dir)
    vertices_to = [sss[0]['vertno'], sss[1]['vertno']]
    ds = datasets.get_mne_sample(-0.1, 0.1, src='ico', sub='index==0', stc=True)
    stc = ds['stc', 0]
    morph_mat = mne.compute_morph_matrix('sample', 'fsaverage', stc.vertno,
                                         vertices_to, None, subjects_dir)
    ndvar = ds['src']

    morphed_ndvar = morph_source_space(ndvar, 'fsaverage')
    morphed_stc = mne.morph_data_precomputed('sample', 'fsaverage', stc,
                                             vertices_to, morph_mat)
    assert_array_equal(morphed_ndvar.x[0], morphed_stc.data)
    morphed_stc_ndvar = load.fiff.stc_ndvar([morphed_stc], 'fsaverage', 'ico-4',
                                            subjects_dir, 'src', parc=None)
    assert_dataobj_equal(morphed_ndvar, morphed_stc_ndvar)
Exemple #5
0
    def make_stcs(self, snr = 3.0, method='dSPM', save_to_disk = False, morph=True):
        """docstring for make_stcs"""

        morph_status = 'no_morph'

        lambda2 = 1.0 / snr ** 2.0
        pick_ori = None

        stcs = []

        for evoked_object, cond in self.evoked_list:

            print "Making source estimates for %s." %cond
            stc = mne.minimum_norm.apply_inverse(evoked_object, self.inverse_solution, method = method, lambda2 = lambda2, pick_ori = pick_ori)

            if morph == True:

                morph_status = 'morphed'
                # create morph map
                # get vertices to morph to (we'll take the fsaverage vertices)
                subject_to = 'fsaverage'
                fs = mne.read_source_spaces(self.subjects_dir + '%s/bem/%s-ico-4-src.fif' % (subject_to, subject_to))
                vertices_to = [fs[0]['vertno'], fs[1]['vertno']]

                # info of the stc we're going to morph is just the present stc
                subject_from = self.subject
                stc_from = stc

                # use the morph function
                morph_mat = mne.compute_morph_matrix(subject_from, subject_to, vertices_from=stc_from.vertices, vertices_to=vertices_to, subjects_dir=self.subjects_dir)
                stc = mne.morph_data_precomputed(subject_from, subject_to, stc_from, vertices_to, morph_mat)


                # stc_to.save('%s_audvis-meg' % subject_from)
                # mne.compute_morph_matrix('2-COMB','3-COMB',stcs[0].vertices, stcs[5].vertices, subjects_dir=self.subjects_dir)

            if save_to_disk:
                fact_morph_cond_path = op.join(self.stc_fact, morph_status, cond)
                if not os.path.isdir(fact_morph_cond_path):
                    os.makedirs(fact_morph_cond_path)

                stc.save(op.join(fact_morph_cond_path, '%s_%s_%s' %(self.subject, cond, morph_status)))

                self.add_preprocessing_notes("Saved source estimates (%s) for %s." %(morph_status, cond))
    def make_stcs(self, snr = 3.0, method='dSPM', save_to_disk = False, morph=True):
        """docstring for make_stcs"""

        morph_status = 'no_morph'

        lambda2 = 1.0 / snr ** 2.0
        pick_ori = None

        stcs = []

        for evoked_object, cond in self.evoked_list:

            print "Making source estimates for %s." %cond
            stc = mne.minimum_norm.apply_inverse(evoked_object, self.inverse_solution, method = method, lambda2 = lambda2, pick_ori = pick_ori)

            if morph == True:

                morph_status = 'morphed'
                # create morph map
                # get vertices to morph to (we'll take the fsaverage vertices)
                subject_to = 'fsaverage'
                fs = mne.read_source_spaces(self.subjects_dir + '%s/bem/%s-ico-4-src.fif' % (subject_to, subject_to))
                vertices_to = [fs[0]['vertno'], fs[1]['vertno']]

                # info of the stc we're going to morph is just the present stc
                subject_from = self.subject
                stc_from = stc

                # use the morph function
                morph_mat = mne.compute_morph_matrix(subject_from, subject_to, vertices_from=stc_from.vertices, vertices_to=vertices_to, subjects_dir=self.subjects_dir)
                stc = mne.morph_data_precomputed(subject_from, subject_to, stc_from, vertices_to, morph_mat)


                # stc_to.save('%s_audvis-meg' % subject_from)
                # mne.compute_morph_matrix('2-COMB','3-COMB',stcs[0].vertices, stcs[5].vertices, subjects_dir=self.subjects_dir)

            if save_to_disk:
                fact_morph_cond_path = op.join(self.stc_fact, morph_status, cond)
                if not os.path.isdir(fact_morph_cond_path):
                    os.makedirs(fact_morph_cond_path)

                stc.save(op.join(fact_morph_cond_path, '%s_%s_%s' %(self.subject, cond, morph_status)))

                self.add_preprocessing_notes("Saved source estimates (%s) for %s." %(morph_status, cond))
    def make_epoch_stcs(self, epochs, snr = 2.0, method='dSPM', morph=True, save_to_disk = False):
        """Apply inverse operator to epochs to get source estimates of each item"""


        lambda2 = 1.0 / snr ** 2.0

        inverse = mne.minimum_norm.read_inverse_operator( self.processed_files + self.subject + '_inv.fif' )

        eps = mne.minimum_norm.apply_inverse_epochs(epochs=epochs,inverse_operator=inverse,lambda2=lambda2,method = method)

        if morph == True:
            eps_morphed = []
            counter = 1
            morph_status = 'morphed'
            # create morph map
            # get vertices to morph to (we'll take the fsaverage vertices)
            subject_to = 'fsaverage'
            fs = mne.read_source_spaces(self.subjects_dir + '%s/bem/%s-ico-4-src.fif' % (subject_to, subject_to))
            vertices_to = [fs[0]['vertno'], fs[1]['vertno']]
            subject_from = self.subject

            for stc_from in eps:
                print "Morphing source estimate for epoch %d" %counter
            # use the morph function
                morph_mat = mne.compute_morph_matrix(subject_from, subject_to, vertices_from=stc_from.vertices, vertices_to=vertices_to, subjects_dir=self.subjects_dir)
                stc = mne.morph_data_precomputed(subject_from, subject_to, stc_from, vertices_to, morph_mat)
                # stc = mne.morph_data(subject_from, subject_to, stc_from, n_jobs=1,
                #                     grade=vertices_to, subjects_dir=self.subjects_dir)

                eps_morphed.append(stc)
                counter += 1

            eps = eps_morphed

        if save_to_disk:
            with open(op.join(self.stc_cont, '%s_stc_epochs.pickled' %self.subject), 'w') as fileout:
                pickle.dump(eps, fileout)
            #save.pickle(obj=eps,dest=self.stc_cont + self.subject + '_stc_epochs')

        return eps
Exemple #8
0
    def make_epoch_stcs(self, epochs, snr = 2.0, method='dSPM', morph=True, save_to_disk = False):
        """Apply inverse operator to epochs to get source estimates of each item"""


        lambda2 = 1.0 / snr ** 2.0

        inverse = mne.minimum_norm.read_inverse_operator( self.processed_files + self.subject + '_inv.fif' )

        eps = mne.minimum_norm.apply_inverse_epochs(epochs=epochs,inverse_operator=inverse,lambda2=lambda2,method = method)

        if morph == True:
            eps_morphed = []
            counter = 1
            morph_status = 'morphed'
            # create morph map
            # get vertices to morph to (we'll take the fsaverage vertices)
            subject_to = 'fsaverage'
            fs = mne.read_source_spaces(self.subjects_dir + '%s/bem/%s-ico-4-src.fif' % (subject_to, subject_to))
            vertices_to = [fs[0]['vertno'], fs[1]['vertno']]
            subject_from = self.subject

            for stc_from in eps:
                print "Morphing source estimate for epoch %d" %counter
            # use the morph function
                morph_mat = mne.compute_morph_matrix(subject_from, subject_to, vertices_from=stc_from.vertices, vertices_to=vertices_to, subjects_dir=self.subjects_dir)
                stc = mne.morph_data_precomputed(subject_from, subject_to, stc_from, vertices_to, morph_mat)
                # stc = mne.morph_data(subject_from, subject_to, stc_from, n_jobs=1,
                #                     grade=vertices_to, subjects_dir=self.subjects_dir)

                eps_morphed.append(stc)
                counter += 1

            eps = eps_morphed

        if save_to_disk:
            with open(op.join(self.stc_cont, '%s_stc_epochs.pickled' %self.subject), 'w') as fileout:
                pickle.dump(eps, fileout)
            #save.pickle(obj=eps,dest=self.stc_cont + self.subject + '_stc_epochs')

        return eps
Exemple #9
0
def test_source_estimate():
    "Test SourceSpace dimension"
    ds = datasets.get_mne_sample(src='ico')
    dsa = ds.aggregate('side')

    # test auto-conversion
    asndvar('epochs', ds=ds)
    asndvar('epochs', ds=dsa)
    asndvar(dsa['epochs'][0])

    # source space clustering
    res = testnd.ttest_ind('src', 'side', ds=ds, samples=0, pmin=0.05,
                           tstart=0.05, mintime=0.02, minsource=10)
    assert_equal(res.clusters.n_cases, 52)

    # test morphing
    dsa = ds.aggregate('side')
    ndvar = dsa['src']
    stc = mne.SourceEstimate(ndvar.x[0], ndvar.source.vertno,
                             ndvar.time.tmin, ndvar.time.tstep,
                             ndvar.source.subject)
    subjects_dir = ndvar.source.subjects_dir
    path = ndvar.source._src_pattern.format(subject='fsaverage',
                                            src=ndvar.source.src,
                                            subjects_dir=subjects_dir)
    if os.path.exists(path):
        src_to = mne.read_source_spaces(path)
    else:
        src_to = mne.setup_source_space('fsaverage', path, 'ico4',
                                        subjects_dir=subjects_dir)
    vertices_to = [src_to[0]['vertno'], src_to[1]['vertno']]
    mm = mne.compute_morph_matrix('sample', 'fsaverage', ndvar.source.vertno,
                                  vertices_to, None, subjects_dir)
    stc_to = mne.morph_data_precomputed('sample', 'fsaverage', stc,
                                        vertices_to, mm)

    ndvar_m = morph_source_space(ndvar, 'fsaverage')
    assert_array_equal(ndvar_m.x[0], stc_to.data)
epochs_ds.resample(20)
evoked_ds = [epochs_ds[name].average() for name in ['STI-correct', 'STI-incorrect']]

# contruct two types of inverse solution: one based on baseline data (before the red square appears), and one based on blank data
cov_blank = mne.compute_covariance(epochs_ds['STB'], tmin=0, tmax=None, method='auto')
inv_blank = make_inverse_operator(epochs_ds.info, forward, cov_blank,
                                  loose=0.2, depth=0.8)
blank_idx = np.nonzero(epochs_ds.events[:, 2] == 15)[0]
epochs_ds.drop_epochs(blank_idx)
cov_base = mne.compute_covariance(epochs_ds, tmin=None, tmax=0, method='auto')
inv_base = make_inverse_operator(epochs_ds.info, forward, cov_base,
                                 loose=0.2, depth=0.8)

vertices_to = [np.arange(10242), np.arange(10242)]
vertices_from = [forward['src'][0]['vertno'], forward['src'][1]['vertno']]
morph_mat = mne.compute_morph_matrix(subj, 'fsaverage', vertices_from, vertices_to)
for c in range(len(conds)):
    # start with the simplest method, MNE + dSPM
    stc = apply_inverse(evoked_ds[c], inv_base, lambda2, method)
    stc = mne.morph_data_precomputed(subj, 'fsaverage', stc,
                                     vertices_to, morph_mat)
    fname = out_dir + '%s_%s_dSPM_base_clean' % (subj, conds[c])
    stc.save(fname)
    stc = apply_inverse(evoked_ds[c], inv_blank, lambda2, method)
    stc = mne.morph_data_precomputed(subj, 'fsaverage', stc,
                                     vertices_to, morph_mat)
    fname = out_dir + '%s_%s_dSPM_blank_clean' % (subj, conds[c])
    stc.save(fname)

    # the next estimate is LCMV beamformer in time
    data_cov = mne.compute_covariance(epochs_ds[conds[c]], tmin=0, tmax=None,
print("Simulating data for %d subjects." % n_subjects)

#    Let's make sure our results replicate, so set the seed.
np.random.seed(0)
X = randn(n_vertices_sample, n_times, n_subjects, 4) * 10
for ii, condition in enumerate(conditions):
    X[:, :, :, ii] += condition.lh_data[:, :, np.newaxis]

#    It's a good idea to spatially smooth the data, and for visualization
#    purposes, let's morph these to fsaverage, which is a grade 5 source space
#    with vertices 0:10242 for each hemisphere. Usually you'd have to morph
#    each subject's data separately (and you might want to use morph_data
#    instead), but here since all estimates are on 'sample' we can use one
#    morph matrix for all the heavy lifting.
fsave_vertices = [np.arange(10242), np.array([])]  # right hemisphere is empty
morph_mat = compute_morph_matrix("sample", "fsaverage", sample_vertices, fsave_vertices, 20, subjects_dir)
n_vertices_fsave = morph_mat.shape[0]

#    We have to change the shape for the dot() to work properly
X = X.reshape(n_vertices_sample, n_times * n_subjects * 4)
print("Morphing data.")
X = morph_mat.dot(X)  # morph_mat is a sparse matrix
X = X.reshape(n_vertices_fsave, n_times, n_subjects, 4)

#    Now we need to prepare the group matrix for the ANOVA statistic.
#    To make the clustering function work correctly with the
#    ANOVA function X needs to be a list of multi-dimensional arrays
#    (one per condition) of shape: samples (subjects) x time x space

X = np.transpose(X, [2, 1, 0, 3])  # First we permute dimensions
# finally we split the array into a list a list of conditions
Exemple #12
0
import mne

from library.config import (subjects_dir, meg_dir, exclude_subjects, smooth,
                            fsaverage_vertices, l_freq)

stcs = list()
for subject_id in range(1, 20):
    if subject_id in exclude_subjects:
        continue
    subject = "sub%03d" % subject_id
    print("processing subject: %s" % subject)
    data_path = op.join(meg_dir, subject)

    stc = mne.read_source_estimate(
        op.join(data_path, 'mne_LCMV_inverse_highpass-%sHz-contrast' % l_freq),
        subject)
    morph_mat = mne.compute_morph_matrix(subject,
                                         'fsaverage',
                                         stc.vertices,
                                         fsaverage_vertices,
                                         smooth,
                                         subjects_dir=subjects_dir,
                                         warn=False)
    morphed = stc.morph_precomputed('fsaverage', fsaverage_vertices, morph_mat)
    stcs.append(morphed)

data = np.average([s.data for s in stcs], axis=0)
stc = mne.SourceEstimate(data, stcs[0].vertices, stcs[0].tmin, stcs[0].tstep)
stc.save(op.join(meg_dir, 'contrast-average-lcmv_highpass-%sHz' % l_freq))
Exemple #13
0
def morph_source_space(ndvar, subject_to, vertices_to=None, morph_mat=None,
                       copy=False):
    """Morph source estimate to a different MRI subject

    Parameters
    ----------
    ndvar : NDVar
        NDVar with SourceSpace dimension.
    subject_to : string
        Name of the subject on which to morph.
    vertices_to : None | list of array of int
        The vertices on the destination subject's brain. If ndvar contains a
        whole source space, vertices_to can be automatically loaded, although
        providing them as argument can speed up processing by a second or two.
    morph_mat : None | sparse matrix
        The morphing matrix. If ndvar contains a whole source space, the morph
        matrix can be automatically loaded, although providing a cached matrix
        can speed up processing by a second or two.
    copy : bool
        Make sure that the data of ``morphed_ndvar`` is separate from
        ``ndvar`` (default False).

    Returns
    -------
    morphed_ndvar : NDVar
        NDVar morphed to the destination subject.

    Notes
    -----
    This function is used to make sure a number of different NDVars are defined
    on the same MRI subject and handles scaled MRIs efficiently. If the MRI
    subject on which ``ndvar`` is defined is a scaled copy of ``subject_to``,
    by default a shallow copy of ``ndvar`` is returned. That means that it is
    not safe to assume that ``morphed_ndvar`` can be modified in place without
    altering ``ndvar``. To make sure the date of the output is independent from
    the data of the input, set the argument ``copy=True``.
    """
    subjects_dir = ndvar.source.subjects_dir
    subject_from = ndvar.source.subject
    src = ndvar.source.src
    if vertices_to is None:
        path = SourceSpace._src_pattern.format(subjects_dir=subjects_dir,
                                               subject=subject_to, src=src)
        src_to = mne.read_source_spaces(path)
        vertices_to = [src_to[0]['vertno'], src_to[1]['vertno']]
    elif not isinstance(vertices_to, list) or not len(vertices_to) == 2:
        raise ValueError('vertices_to must be a list of length 2')

    if subject_from == subject_to and _vertices_equal(ndvar.source.vertno,
                                                      vertices_to):
        if copy:
            return ndvar.copy()
        else:
            return ndvar

    axis = ndvar.get_axis('source')
    x = ndvar.x

    # check whether it is a scaled brain
    do_morph = True
    cfg_path = os.path.join(subjects_dir, subject_from,
                            'MRI scaling parameters.cfg')
    if os.path.exists(cfg_path):
        cfg = mne.coreg.read_mri_cfg(subject_from, subjects_dir)
        subject_from = cfg['subject_from']
        if subject_to == subject_from and _vertices_equal(ndvar.source.vertno,
                                                          vertices_to):
            if copy:
                x_ = x.copy()
            else:
                x_ = x
            vertices_to = ndvar.source.vertno
            do_morph = False

    if do_morph:
        vertices_from = ndvar.source.vertno
        if morph_mat is None:
            morph_mat = mne.compute_morph_matrix(subject_from, subject_to,
                                                 vertices_from, vertices_to,
                                                 None, subjects_dir)
        elif not sp.sparse.issparse(morph_mat):
            raise ValueError('morph_mat must be a sparse matrix')
        elif not sum(len(v) for v in vertices_to) == morph_mat.shape[0]:
            raise ValueError('morph_mat.shape[0] must match number of '
                             'vertices in vertices_to')

        # flatten data
        if axis != 0:
            x = x.swapaxes(0, axis)
        n_sources = len(x)
        if not n_sources == morph_mat.shape[1]:
            raise ValueError('ndvar source dimension length must be the same '
                             'as morph_mat.shape[0]')
        if ndvar.ndim > 2:
            shape = x.shape
            x = x.reshape((n_sources, -1))

        # apply morph matrix
        x_ = morph_mat * x

        # restore data shape
        if ndvar.ndim > 2:
            shape_ = (len(x_),) + shape[1:]
            x_ = x_.reshape(shape_)
        if axis != 0:
            x_ = x_.swapaxes(axis, 0)

    # package output NDVar
    if ndvar.source.parc is None:
        parc = None
    else:
        parc = ndvar.source.parc.name
    source = SourceSpace(vertices_to, subject_to, src, subjects_dir, parc)
    dims = ndvar.dims[:axis] + (source,) + ndvar.dims[axis + 1:]
    info = ndvar.info.copy()
    out = NDVar(x_, dims, info, ndvar.name)
    return out
#     vertices_to = mne.grade_to_vertices(subject_to, grade=5)
# But fsaverage's source space was set up so we can just do this:
vertices_to = [np.arange(10242), np.arange(10242)]
stc_to = mne.morph_data(subject_from,
                        subject_to,
                        stc_from,
                        n_jobs=1,
                        grade=vertices_to,
                        subjects_dir=subjects_dir)
stc_to.save('%s_audvis-meg' % subject_to)

# Morph using another method -- useful if you're going to do a lot of the
# same inter-subject morphing operations; you could save and load morph_mat
morph_mat = mne.compute_morph_matrix(subject_from,
                                     subject_to,
                                     stc_from.vertices,
                                     vertices_to,
                                     subjects_dir=subjects_dir)
stc_to_2 = mne.morph_data_precomputed(subject_from, subject_to, stc_from,
                                      vertices_to, morph_mat)
stc_to_2.save('%s_audvis-meg_2' % subject_to)

# View source activations
plt.plot(stc_from.times, stc_from.data.mean(axis=0), 'r', label='from')
plt.plot(stc_to.times, stc_to.data.mean(axis=0), 'b', label='to')
plt.plot(stc_to_2.times, stc_to.data.mean(axis=0), 'g', label='to_2')
plt.xlabel('time (ms)')
plt.ylabel('Mean Source amplitude')
plt.legend()
plt.show()
Exemple #15
0
def stft_source_localization(data, fn_inv, method="dSPM",
                             morph2fsaverage=False,
                             nave=1, snr=3.,
                             pick_ori="normal", verbose=True):

    """
    Apply inverse operator to data. In general, the
    L2-norm inverse solution is computed.

        Parameters
        ----------
        data: array of MEG data
            (only the data, no MNE-data object!)
        kernel: kernel of the inverse operator.
            (could be estimated using
            mne.minimum_norm._assemble_kernel())
        noise_norm: noise normalization array.
            (could be estimated using
            mne.minimum_norm._assemble_kernel())

        Returns
        -------
        src_loc: SourceEstimate | VolSourceEstimate
            The source estimates
        estimation_time: time needed to perform source
            localization (for one time slice)
    """

    # -------------------------------------------
    # import necessary modules
    # -------------------------------------------
    import numpy as np
    import types

    # check if data should be morphed
    if morph2fsaverage:
        from mne import compute_morph_matrix, grade_to_vertices, morph_data_precomputed
        from mne.source_estimate import SourceEstimate
        from os.path import basename, dirname


    # -------------------------------------------
    # estimate inverse kernel
    # -------------------------------------------
    kernel, noise_norm, vertno = calc_inv_kernel(fn_inv, method=method,
                                                 nave=nave, snr=snr,
                                                 pick_ori=pick_ori)


    # -------------------------------------------
    # get some information from the
    # input data
    # -------------------------------------------
    nfreq, nepochs, nchan = data.shape
    nvoxel = noise_norm.shape[0]

    if isinstance(data[0, 0, 0], types.ComplexType):
        src_loc_data = np.zeros((nfreq, nepochs, nvoxel), dtype=np.complex)
    else:
        src_loc_data = np.zeros((nfreq, nepochs, nvoxel))


    # -------------------------------------------
    # read in morphing matrix
    # -------------------------------------------
    if morph2fsaverage:
        subject_id = basename(fn_inv)[:6]
        subjects_dir = dirname(dirname(fn_inv))
        vertices_to = grade_to_vertices('fsaverage', grade=4,
                                        subjects_dir=subjects_dir)

        morph_mat = compute_morph_matrix(subject_id, 'fsaverage',
                                         vertno, vertices_to,
                                         subjects_dir=subjects_dir)
        nvoxel_morph = 2 * len(vertices_to[0])

        if isinstance(data[0, 0, 0], types.ComplexType):
            morphed_src_loc_data = np.zeros((nfreq, nepochs, nvoxel_morph), dtype=np.complex)
        else:
            morphed_src_loc_data = np.zeros((nfreq, nepochs, nvoxel_morph), dtype=np.complex)


    # -------------------------------------------
    # apply inverse operator for each time slice
    # -------------------------------------------
    for iepoch in range(nepochs):

        if verbose:
            from sys import stdout
            info = "\r" if iepoch > 0 else ""
            info += "... --> Epoch %d of %d done" % (iepoch+1, nepochs)
            stdout.write(info)
            stdout.flush()

        for ifreq in range(0, nfreq):
            # multiply measured data with inverse kernel
            loc_tmp = np.dot(kernel, data[ifreq, iepoch, :])

            if pick_ori != "normal":

                # estimate L2-norm and apply noise normalization
                src_loc_data[ifreq, iepoch, :] = loc_tmp[0::3].real ** 2 + 1j * loc_tmp[0::3].imag ** 2
                src_loc_data[ifreq, iepoch, :] += loc_tmp[1::3].real ** 2 + 1j * loc_tmp[1::3].imag ** 2
                src_loc_data[ifreq, iepoch, :] += loc_tmp[2::3].real ** 2 + 1j * loc_tmp[2::3].imag ** 2
                src_loc_data[ifreq, iepoch, :] = (np.sqrt(src_loc_data[ifreq, iepoch, :].real) +
                                                  1j * np.sqrt(src_loc_data[ifreq, iepoch, :].imag))
            else:
                src_loc_data[ifreq, iepoch, :] = loc_tmp

            src_loc_data[ifreq, iepoch, :] *= noise_norm[:, 0]


        if morph2fsaverage:
            SrcEst = SourceEstimate(src_loc_data[:, iepoch, :].T,
                                    vertno, 0, 1, verbose=verbose)
            SrcEst_morphed = morph_data_precomputed(subject_id, 'fsaverage',
                                                    SrcEst, vertices_to, morph_mat)

            morphed_src_loc_data[:, iepoch, :] = SrcEst_morphed.data.T

    if verbose:
         print ""

    if morph2fsaverage:
        src_loc_data = morphed_src_loc_data
        vertno = vertices_to

    return src_loc_data, vertno
Exemple #16
0
def morph_source_space(ndvar, subject_to=None, vertices_to=None, morph_mat=None,
                       copy=False, parc=True, xhemi=False, mask=None):
    """Morph source estimate to a different MRI subject

    Parameters
    ----------
    ndvar : NDVar
        NDVar with SourceSpace dimension.
    subject_to : str
        Name of the subject on which to morph (by default this is the same as
        the current subject for ``xhemi`` morphing).
    vertices_to : None | list of array of int | 'lh' | 'rh'
        The vertices on the destination subject's brain. If ndvar contains a
        whole source space, vertices_to can be automatically loaded, although
        providing them as argument can speed up processing by a second or two.
        Use 'lh' or 'rh' to target vertices from only one hemisphere.
    morph_mat : None | sparse matrix
        The morphing matrix. If ndvar contains a whole source space, the morph
        matrix can be automatically loaded, although providing a cached matrix
        can speed up processing by a second or two.
    copy : bool
        Make sure that the data of ``morphed_ndvar`` is separate from
        ``ndvar`` (default False).
    parc : bool | str
        Parcellation for target source space. The default is to keep the
        parcellation from ``ndvar``. Set to ``False`` to load no parcellation.
        If the annotation files are missing for the target subject an IOError
        is raised.
    xhemi : bool
        Mirror hemispheres (i.e., project data from the left hemisphere to the
        right hemisphere and vice versa).
    mask : bool
        Restrict output to known sources. If the parcellation of ``ndvar`` is
        retained keep only sources with labels contained in ``ndvar``, otherwise
        remove only sourves with ``”unknown-*”`` label (default is True unless
        ``vertices_to`` is specified).

    Returns
    -------
    morphed_ndvar : NDVar
        NDVar morphed to the destination subject.

    Notes
    -----
    This function is used to make sure a number of different NDVars are defined
    on the same MRI subject and handles scaled MRIs efficiently. If the MRI
    subject on which ``ndvar`` is defined is a scaled copy of ``subject_to``,
    by default a shallow copy of ``ndvar`` is returned. That means that it is
    not safe to assume that ``morphed_ndvar`` can be modified in place without
    altering ``ndvar``. To make sure the date of the output is independent from
    the data of the input, set the argument ``copy=True``.
    """
    axis = ndvar.get_axis('source')
    source = ndvar.get_dim('source')
    subjects_dir = source.subjects_dir
    subject_from = source.subject
    if subject_to is None:
        subject_to = subject_from
    else:
        assert_subject_exists(subject_to, subjects_dir)
    # catch cases that don't require morphing
    if not xhemi:
        subject_is_same = subject_from == subject_to
        subject_is_scaled = find_source_subject(subject_to, subjects_dir) == subject_from or find_source_subject(subject_from, subjects_dir) == subject_to
        if subject_is_same or subject_is_scaled:
            if vertices_to is None:
                pass
            elif vertices_to in ('lh', 'rh'):
                ndvar = ndvar.sub(source=vertices_to)
            elif isinstance(vertices_to, str):
                raise ValueError(f"vertices_to={vertices_to!r}")
            else:
                raise TypeError(f"vertices_to={vertices_to!r}")

            x = ndvar.x.copy() if copy else ndvar.x
            parc_arg = None if parc is True else parc
            if subject_is_scaled or parc_arg is not None:
                source_to = source._copy(subject_to, parc=parc_arg)
            else:
                source_to = source

            dims = (*ndvar.dims[:axis], source_to, *ndvar.dims[axis + 1:])
            return NDVar(x, dims, ndvar.info, ndvar.name)

    has_lh_out = bool(source.rh_n if xhemi else source.lh_n)
    has_rh_out = bool(source.lh_n if xhemi else source.rh_n)
    if vertices_to in (None, 'lh', 'rh'):
        default_vertices = source_space_vertices(source.kind, source.grade, subject_to, subjects_dir)
        lh_out = vertices_to == 'lh' or (vertices_to is None and has_lh_out)
        rh_out = vertices_to == 'rh' or (vertices_to is None and has_rh_out)
        vertices_to = [default_vertices[0] if lh_out else np.empty(0, int),
                       default_vertices[1] if rh_out else np.empty(0, int)]
        if mask is None:
            if source.parc is None:
                mask = False
            else:
                mask = not np.any(source.parc.startswith('unknown-'))
    elif not isinstance(vertices_to, list) or not len(vertices_to) == 2:
        raise ValueError(f"vertices_to={vertices_to!r}: must be a list of length 2")

    # check that requested data is available
    n_to_lh = len(vertices_to[0])
    n_to_rh = len(vertices_to[1])
    if n_to_lh and not has_lh_out:
        raise ValueError("Data on the left hemisphere was requested in vertices_to but is not available in ndvar")
    elif n_to_rh and not has_rh_out:
        raise ValueError("Data on the right hemisphere was requested in vertices_to but is not available in ndvar")
    elif n_to_lh == 0 and n_to_rh == 0:
        raise ValueError("No target vertices")

    # parc for new source space
    if parc is True:
        parc_to = None if source.parc is None else source.parc.name
    else:
        parc_to = parc
    if mask and parc_to is None:
        raise ValueError("Can't mask source space without parcellation...")
    # check that annot files are available
    if parc_to:
        fname = SourceSpace._ANNOT_PATH.format(
            subjects_dir=subjects_dir, subject=subject_to, hemi='%s',
            parc=parc_to)
        fnames = tuple(fname % hemi for hemi in ('lh', 'rh'))
        missing = tuple(fname for fname in fnames if not os.path.exists(fname))
        if missing:
            missing = '\n'.join(missing)
            raise IOError(f"Annotation files are missing for parc={parc_to!r}, subject={subject_to!r}. Use the parc parameter when morphing to set a different parcellation. The following files are missing:\n{missing}")
    # find target source space
    source_to = SourceSpace(vertices_to, subject_to, source.src, subjects_dir, parc_to)
    if mask is True:
        if parc is True:
            keep_labels = source.parc.cells
            if xhemi:
                keep_labels = [switch_hemi_tag(label) for label in keep_labels]
            index = source_to.parc.isin(keep_labels)
        else:
            index = source_to.parc.isnotin(('unknown-lh', 'unknown-rh'))
        source_to = source_to[index]
    elif mask not in (None, False):
        raise TypeError(f"mask={mask!r}")

    if morph_mat is None:
        with warnings.catch_warnings():
            warnings.filterwarnings('ignore', r'\d+/\d+ vertices not included in smoothing', module='mne')
            morph_mat = mne.compute_morph_matrix(subject_from, subject_to, source.vertices, source_to.vertices, None, subjects_dir, xhemi=xhemi)
    elif not sp.sparse.issparse(morph_mat):
        raise ValueError('morph_mat must be a sparse matrix')
    elif not sum(len(v) for v in source_to.vertices) == morph_mat.shape[0]:
        raise ValueError('morph_mat.shape[0] must match number of vertices in vertices_to')

    # flatten data
    x = ndvar.x
    if axis != 0:
        x = x.swapaxes(0, axis)
    n_sources = len(x)
    if not n_sources == morph_mat.shape[1]:
        raise ValueError('ndvar source dimension length must be the same as morph_mat.shape[0]')
    if ndvar.ndim > 2:
        shape = x.shape
        x = x.reshape((n_sources, -1))

    # apply morph matrix
    x_m = morph_mat * x

    # restore data shape
    if ndvar.ndim > 2:
        shape_ = (len(x_m),) + shape[1:]
        x_m = x_m.reshape(shape_)
    if axis != 0:
        x_m = x_m.swapaxes(axis, 0)

    # package output NDVar
    dims = (*ndvar.dims[:axis], source_to, *ndvar.dims[axis + 1:])
    return NDVar(x_m, dims, ndvar.info, ndvar.name)
Exemple #17
0
            cov = mne.compute_covariance(epochs_rej,tmin=None,tmax=0, method=['shrunk', 'diagonal_fixed', 'empirical'])
            cov.save(cov_fname)
            print 'Done. File saved.'


        #---------------------Inverse operator-------------------------#
        print 'Getting inverse operator'
        if fixed == True:
            fwd = mne.convert_forward_solution(fwd, surf_ori=True)

        inv = mne.minimum_norm.make_inverse_operator(info, fwd, cov, depth=None, loose=None, fixed=fixed) #fixed=False: Ignoring dipole direction.
        lambda2 = 1.0 / SNR ** 2.0

        #--------------------------STCs--------------------------------#

        print '%s: Creating STCs...'%subj
        os.makedirs('STC/%s' %subj)
        for ev in evoked:
            stc = mne.minimum_norm.apply_inverse(ev, inv, lambda2=lambda2, method='dSPM')
            # mophing stcs to the fsaverage using precomputed matrix method:
            vertices_to = mne.grade_to_vertices('fsaverage', grade=4, subjects_dir=subjects_dir) #fsaverage's source space
            morph_mat = mne.compute_morph_matrix(subject_from=subj, subject_to='fsaverage', vertices_from=stc.vertices, vertices_to=vertices_to, subjects_dir=subjects_dir)
            stc_morph = mne.morph_data_precomputed(subject_from=subj, subject_to='fsaverage', stc_from=stc, vertices_to=vertices_to, morph_mat=morph_mat)
            stc_morph.save('STC/%s/%s_%s_dSPM' %(subj,subj,ev.comment))
            del stc, stc_morph
        print '>> DONE CREATING STCS FOR SUBJ=%s'%subj
        print '-----------------------------------------\n'

        #deleting variables
        del epochs_rej, evoked, info, trans, src, fwd, cov, inv
            continue
        raw_fname = paths('sss', subject=meg_subject, block=1)
        inv_fname = paths('inv', subject=meg_subject)
        cov = load('cov', subject=meg_subject)
        fwd = load('fwd', subject=meg_subject)
        info = read_info(raw_fname)
        inv = make_inverse_operator(info, fwd, cov, loose=0.2, depth=0.8)
        save(inv, 'inv', subject=meg_subject, overwrite=True)

# Morph anatomy into common model ---------------------------------------------
from mne import EvokedArray
from mne import compute_morph_matrix
from mne.minimum_norm import apply_inverse
if True:
    for meg_subject, subject in zip(range(1, 21), subjects_id):
        if subject in bad_mri:
            continue
        raw_fname = paths('sss', subject=meg_subject, block=1)
        info = read_info(raw_fname)

        # precompute morphing matrix for faster processing
        inv = load('inv', subject=meg_subject)
        evoked = EvokedArray(np.zeros((len(info['chs']), 2)), info, 0)
        evoked.pick_types(eeg=False, meg=True)
        stc = apply_inverse(evoked, inv, lambda2=1.0 / (2 ** 3.0),
                            method='dSPM', pick_ori=None)
        morph = compute_morph_matrix(subject, 'fsaverage', stc.vertices,
                                     vertices_to=[np.arange(10242)] * 2,
                                     subjects_dir=subjects_dir)
        save(morph, 'morph', subject=meg_subject)
                 time_unit='s')
brain.add_foci(vertno_max,
               coords_as_verts=True,
               hemi='rh',
               color='blue',
               scale_factor=0.6)
brain.show_view('lateral')

###############################################################################
# Morph data to average brain
# ---------------------------

fs_vertices = [np.arange(10242)] * 2
morph_mat = mne.compute_morph_matrix('sample',
                                     'fsaverage',
                                     stc.vertices,
                                     fs_vertices,
                                     smooth=None,
                                     subjects_dir=subjects_dir)
stc_fsaverage = stc.morph_precomputed('fsaverage', fs_vertices, morph_mat)
brain_fsaverage = stc_fsaverage.plot(surface='inflated',
                                     hemi='rh',
                                     subjects_dir=subjects_dir,
                                     clim=dict(kind='value', lims=[8, 12, 15]),
                                     initial_time=time_max,
                                     time_unit='s')
brain_fsaverage.show_view('lateral')

###############################################################################
# Exercise
# --------
#    - By changing the method parameter to 'sloreta' recompute the source
src_fname = data_path + '/MEG/sample/sample_audvis-meg-oct-6-fwd.fif'

# Read input stc file
stc_from = mne.read_source_estimate(fname)
# Morph using one method (supplying the vertices in fsaverage's source
# space makes it faster). Note that for any generic subject, you could do:
#     vertices_to = mne.grade_to_vertices(subject_to, grade=5)
# But fsaverage's source space was set up so we can just do this:
vertices_to = [np.arange(10242), np.arange(10242)]
stc_to = mne.morph_data(subject_from, subject_to, stc_from, n_jobs=1,
                        grade=vertices_to, subjects_dir=subjects_dir)
stc_to.save('%s_audvis-meg' % subject_to)

# Morph using another method -- useful if you're going to do a lot of the
# same inter-subject morphing operations; you could save and load morph_mat
morph_mat = mne.compute_morph_matrix(subject_from, subject_to,
                                     stc_from.vertices, vertices_to,
                                     subjects_dir=subjects_dir)
stc_to_2 = mne.morph_data_precomputed(subject_from, subject_to,
                                      stc_from, vertices_to, morph_mat)
stc_to_2.save('%s_audvis-meg_2' % subject_to)

# View source activations
plt.plot(stc_from.times, stc_from.data.mean(axis=0), 'r', label='from')
plt.plot(stc_to.times, stc_to.data.mean(axis=0), 'b', label='to')
plt.plot(stc_to_2.times, stc_to.data.mean(axis=0), 'g', label='to_2')
plt.xlabel('time (ms)')
plt.ylabel('Mean Source amplitude')
plt.legend()
plt.show()
        info = read_info(raw_fname)
        inv = make_inverse_operator(info, fwd, cov, loose=0.2, depth=0.8)
        save(inv, 'inv', subject=meg_subject, overwrite=True)

# Morph anatomy into common model ---------------------------------------------
from mne import EvokedArray
from mne import compute_morph_matrix
from mne.minimum_norm import apply_inverse
if True:
    for meg_subject, subject in zip(range(1, 21), subjects_id):
        if subject in bad_mri:
            continue
        raw_fname = paths('sss', subject=meg_subject, block=1)
        info = read_info(raw_fname)

        # precompute morphing matrix for faster processing
        inv = load('inv', subject=meg_subject)
        evoked = EvokedArray(np.zeros((len(info['chs']), 2)), info, 0)
        evoked.pick_types(eeg=False, meg=True)
        stc = apply_inverse(evoked,
                            inv,
                            lambda2=1.0 / (2**3.0),
                            method='dSPM',
                            pick_ori=None)
        morph = compute_morph_matrix(subject,
                                     'fsaverage',
                                     stc.vertices,
                                     vertices_to=[np.arange(10242)] * 2,
                                     subjects_dir=subjects_dir)
        save(morph, 'morph', subject=meg_subject)
Exemple #22
0
data_dir = mne.datasets.sample.data_path()
subjects_dir = data_dir + '/subjects'
stc_path = data_dir + '/MEG/sample/sample_audvis-meg-eeg'

stc = mne.read_source_estimate(stc_path, 'sample')

# First, morph the data to fsaverage_sym, for which we have left_right
# registrations:
stc = stc.morph('fsaverage_sym', subjects_dir=subjects_dir, smooth=5)

# Compute a morph-matrix mapping the right to the left hemisphere. Use the
# vertices parameters to determine source and target hemisphere:
mm = mne.compute_morph_matrix(
    'fsaverage_sym',
    'fsaverage_sym',
    xhemi=True,  # cross-hemisphere morphing
    vertices_from=[[], stc.vertices[1]],  # from the right hemisphere
    vertices_to=[stc.vertices[0], []],  # to the left hemisphere
    subjects_dir=subjects_dir)

# SourceEstimate on the left hemisphere:
stc_lh = mne.SourceEstimate(stc.lh_data, [stc.vertices[0], []], stc.tmin,
                            stc.tstep, stc.subject)
# SourceEstimate of the right hemisphere, morphed to the left:
stc_rh_on_lh = mne.SourceEstimate(mm * stc.rh_data, [stc.vertices[0], []],
                                  stc.tmin, stc.tstep, stc.subject)
# Since both STCs are now on the same hemisphere we can subtract them:
diff = stc_lh - stc_rh_on_lh

diff.plot(hemi='lh',
          subjects_dir=subjects_dir,
Exemple #23
0
def morph_source_space(ndvar,
                       subject_to,
                       vertices_to=None,
                       morph_mat=None,
                       copy=False,
                       parc=True,
                       xhemi=False,
                       mask=None):
    """Morph source estimate to a different MRI subject

    Parameters
    ----------
    ndvar : NDVar
        NDVar with SourceSpace dimension.
    subject_to : string
        Name of the subject on which to morph.
    vertices_to : None | list of array of int | 'lh' | 'rh'
        The vertices on the destination subject's brain. If ndvar contains a
        whole source space, vertices_to can be automatically loaded, although
        providing them as argument can speed up processing by a second or two.
        Use 'lh' or 'rh' to target vertices from only one hemisphere.
    morph_mat : None | sparse matrix
        The morphing matrix. If ndvar contains a whole source space, the morph
        matrix can be automatically loaded, although providing a cached matrix
        can speed up processing by a second or two.
    copy : bool
        Make sure that the data of ``morphed_ndvar`` is separate from
        ``ndvar`` (default False).
    parc : bool | str
        Parcellation for target source space. The default is to keep the
        parcellation from ``ndvar``. Set to ``False`` to load no parcellation.
        If the annotation files are missing for the target subject an IOError
        is raised.
    xhemi : bool
        Mirror hemispheres (i.e., project data from the left hemisphere to the
        right hemisphere and vice versa).
    mask : bool
        Remove sources in "unknown-" labels (default is True unless ``ndvar``
        contains sources with "unknown-" label or ``vertices_to`` is specified).

    Returns
    -------
    morphed_ndvar : NDVar
        NDVar morphed to the destination subject.

    Notes
    -----
    This function is used to make sure a number of different NDVars are defined
    on the same MRI subject and handles scaled MRIs efficiently. If the MRI
    subject on which ``ndvar`` is defined is a scaled copy of ``subject_to``,
    by default a shallow copy of ``ndvar`` is returned. That means that it is
    not safe to assume that ``morphed_ndvar`` can be modified in place without
    altering ``ndvar``. To make sure the date of the output is independent from
    the data of the input, set the argument ``copy=True``.
    """
    source = ndvar.get_dim('source')
    subjects_dir = source.subjects_dir
    subject_from = source.subject
    src = source.src
    has_lh_out = bool(source.rh_n if xhemi else source.lh_n)
    has_rh_out = bool(source.lh_n if xhemi else source.rh_n)
    assert_subject_exists(subject_to, subjects_dir)
    if vertices_to in (None, 'lh', 'rh'):
        default_vertices = source_space_vertices(source.kind, source.grade,
                                                 subject_to, subjects_dir)
        lh_out = vertices_to == 'lh' or (vertices_to is None and has_lh_out)
        rh_out = vertices_to == 'rh' or (vertices_to is None and has_rh_out)
        vertices_to = [
            default_vertices[0] if lh_out else np.empty(0, int),
            default_vertices[1] if rh_out else np.empty(0, int)
        ]
        if mask is None:
            if source.parc is None:
                mask = False
            else:
                mask = not np.any(source.parc.startswith('unknown-'))
    elif not isinstance(vertices_to, list) or not len(vertices_to) == 2:
        raise ValueError('vertices_to must be a list of length 2, got %r' %
                         (vertices_to, ))

    # check that requested data is available
    n_to_lh = len(vertices_to[0])
    n_to_rh = len(vertices_to[1])
    if n_to_lh and not has_lh_out:
        raise ValueError("Data on the left hemisphere was requested in "
                         "vertices_to but is not available in ndvar")
    elif n_to_rh and not has_rh_out:
        raise ValueError("Data on the right hemisphere was requested in "
                         "vertices_to but is not available in ndvar")
    elif n_to_lh == 0 and n_to_rh == 0:
        raise ValueError("No target vertices")

    # parc for new source space
    if parc is True:
        parc_to = None if source.parc is None else source.parc.name
    else:
        parc_to = parc
    if mask and parc_to is None:
        raise ValueError("Can't mask source space without parcellation...")
    # check that annot files are available
    if parc_to:
        fname = SourceSpace._ANNOT_PATH.format(subjects_dir=subjects_dir,
                                               subject=subject_to,
                                               hemi='%s',
                                               parc=parc_to)
        fnames = tuple(fname % hemi for hemi in ('lh', 'rh'))
        missing = tuple(fname for fname in fnames if not os.path.exists(fname))
        if missing:
            raise IOError(
                "Annotation files are missing for parc=%r for target subject "
                "%s. Use the parc parameter to change the parcellation. The "
                "following files are missing:\n%s" %
                (parc_to, subject_to, '\n'.join(missing)))
    # catch in == out
    if subject_from == subject_to and _vertices_equal(source.vertices,
                                                      vertices_to):
        if copy:
            ndvar = ndvar.copy()
        if parc is not True:
            set_parc(ndvar, parc)
        return ndvar
    # find target source space
    source_to = SourceSpace(vertices_to, subject_to, src, subjects_dir,
                            parc_to)
    if mask is True:
        index = np.invert(source_to.parc.startswith('unknown-'))
        source_to = source_to[index]
    elif mask not in (None, False):
        raise TypeError("mask=%r" % (mask, ))

    axis = ndvar.get_axis('source')
    x = ndvar.x

    # check whether it is a scaled brain
    do_morph = True
    if not xhemi:
        cfg_path = os.path.join(subjects_dir, subject_from,
                                'MRI scaling parameters.cfg')
        if os.path.exists(cfg_path):
            cfg = mne.coreg.read_mri_cfg(subject_from, subjects_dir)
            subject_from = cfg['subject_from']
            if (subject_to == subject_from
                    and _vertices_equal(source_to.vertices, source.vertices)):
                if copy:
                    x_ = x.copy()
                else:
                    x_ = x
                do_morph = False

    if do_morph:
        if morph_mat is None:
            with warnings.catch_warnings():
                warnings.filterwarnings(
                    'ignore',
                    '\d+/\d+ vertices not included in smoothing',
                    module='mne')
                morph_mat = mne.compute_morph_matrix(subject_from,
                                                     subject_to,
                                                     source.vertices,
                                                     source_to.vertices,
                                                     None,
                                                     subjects_dir,
                                                     xhemi=xhemi)
        elif not sp.sparse.issparse(morph_mat):
            raise ValueError('morph_mat must be a sparse matrix')
        elif not sum(len(v) for v in source_to.vertices) == morph_mat.shape[0]:
            raise ValueError('morph_mat.shape[0] must match number of '
                             'vertices in vertices_to')

        # flatten data
        if axis != 0:
            x = x.swapaxes(0, axis)
        n_sources = len(x)
        if not n_sources == morph_mat.shape[1]:
            raise ValueError('ndvar source dimension length must be the same '
                             'as morph_mat.shape[0]')
        if ndvar.ndim > 2:
            shape = x.shape
            x = x.reshape((n_sources, -1))

        # apply morph matrix
        x_ = morph_mat * x

        # restore data shape
        if ndvar.ndim > 2:
            shape_ = (len(x_), ) + shape[1:]
            x_ = x_.reshape(shape_)
        if axis != 0:
            x_ = x_.swapaxes(axis, 0)

    # package output NDVar
    dims = ndvar.dims[:axis] + (source_to, ) + ndvar.dims[axis + 1:]
    info = ndvar.info.copy()
    return NDVar(x_, dims, info, ndvar.name)
Exemple #24
0
def xhemi(ndvar, mask=None, hemi='lh', parc=True):
    """Project data from both hemispheres to ``hemi`` of fsaverage_sym

    Project data from both hemispheres to the same hemisphere for
    interhemisphere comparisons. The fsaverage_sym brain is a symmetric
    version of fsaverage to facilitate interhemisphere comparisons. It is
    included with FreeSurfer > 5.1 and can be obtained as described `here
    <http://surfer.nmr.mgh.harvard.edu/fswiki/Xhemi>`_. For statistical
    comparisons between hemispheres, use of the symmetric ``fsaverage_sym``
    model is recommended to minimize bias [1]_.

    Parameters
    ----------
    ndvar : NDVar
        NDVar with SourceSpace dimension.
    mask : bool
        Remove sources in "unknown-" labels (default is True unless ``ndvar``
        contains sources with "unknown-" label).
    hemi : 'lh' | 'rh'
        Hemisphere onto which to morph the data.
    parc : bool | str
        Parcellation for target source space; True to use same as in ``ndvar``
        (default).

    Returns
    -------
    lh : NDVAr
        Data from the left hemisphere on ``hemi`` of ``fsaverage_sym``.
    rh : NDVar
        Data from the right hemisphere on ``hemi`` of ``fsaverage_sym``.

    References
    ----------
    .. [1] Greve D. N., Van der Haegen L., Cai Q., Stufflebeam S., Sabuncu M.
           R., Fischl B., Brysbaert M.
           A Surface-based Analysis of Language Lateralization and Cortical
           Asymmetry. Journal of Cognitive Neuroscience 25(9), 1477-1492, 2013.
    """
    other_hemi = 'rh' if hemi == 'lh' else 'lh'

    if ndvar.source.subject == 'fsaverage_sym':
        ndvar_sym = ndvar
    else:
        ndvar_sym = morph_source_space(ndvar,
                                       'fsaverage_sym',
                                       parc=parc,
                                       mask=mask)

    vert_lh, vert_rh = ndvar_sym.source.vertices
    vert_from = [[], vert_rh] if hemi == 'lh' else [vert_lh, []]
    vert_to = [vert_lh, []] if hemi == 'lh' else [[], vert_rh]
    with warnings.catch_warnings():
        warnings.filterwarnings('ignore',
                                '\d+/\d+ vertices not included in smoothing',
                                module='mne')
        morph_mat = mne.compute_morph_matrix(
            'fsaverage_sym',
            'fsaverage_sym',
            vert_from,
            vert_to,
            subjects_dir=ndvar.source.subjects_dir,
            xhemi=True)

    out_same = ndvar_sym.sub(source=hemi)
    out_other = morph_source_space(ndvar_sym.sub(source=other_hemi),
                                   'fsaverage_sym',
                                   out_same.source.vertices,
                                   morph_mat,
                                   parc=parc,
                                   xhemi=True,
                                   mask=mask)

    if hemi == 'lh':
        return out_same, out_other
    else:
        return out_other, out_same
Exemple #25
0
    evokeds = [
        mne.read_evokeds(op.join(data_path, '%s' % s, 'inverse',
                                 'Conditions_80-sss_eq_%s-ave.fif' % s),
                         condition=c) for c in conditions
    ]
    stcs = [
        apply_inverse(e, inv, lambda2, method=method, pick_ori=None)
        for e in evokeds
    ]
    if not op.isdir(op.join(data_path, '%s' % s, 'stc')):
        os.mkdir(op.join(data_path, '%s' % s, 'stc'))
    for j, stc in enumerate(stcs):
        stc.save(
            op.join(data_path, '%s' % s, 'stc',
                    '%s_' % s + evokeds[j].comment))
    m = mne.compute_morph_matrix(s, 'BBC_249', stcs[0].vertices, source_verts)
    morphed_stcs = [
        stcz.morph_precomputed('BBC_249-5-src.fif', source_verts, m)
        for stcz in stcs
    ]
    for j, stc in enumerate(morphed_stcs):
        stc.save(
            op.join(data_path, '%s' % s, 'stc',
                    '%s_BBC_249_morph_' % s + evokeds[j].comment))
    if si == 0:
        data = np.empty(
            (len(morphed_stcs), len(subj), morphed_stcs[0].shape[0],
             morphed_stcs[0].shape[1]))  # conditions X subjs X space X time
    for k, stc in enumerate(morphed_stcs):
        data[k, si] = stc.data
#    test = mne.SourceEstimate(data[0].squeeze(), vertices=source_verts,
vertno_max, time_max = stc.get_peak(hemi='rh')

subjects_dir = data_path + '/subjects'
brain = stc.plot(surface='inflated', hemi='rh', subjects_dir=subjects_dir,
                 clim=dict(kind='value', lims=[8, 12, 15]),
                 initial_time=time_max, time_unit='s')
brain.add_foci(vertno_max, coords_as_verts=True, hemi='rh', color='blue',
               scale_factor=0.6)
brain.show_view('lateral')

###############################################################################
# Morph data to average brain
# ---------------------------

fs_vertices = [np.arange(10242)] * 2
morph_mat = mne.compute_morph_matrix('sample', 'fsaverage', stc.vertices,
                                     fs_vertices, smooth=None,
                                     subjects_dir=subjects_dir)
stc_fsaverage = stc.morph_precomputed('fsaverage', fs_vertices, morph_mat)
brain_fsaverage = stc_fsaverage.plot(surface='inflated', hemi='rh',
                                     subjects_dir=subjects_dir,
                                     clim=dict(kind='value', lims=[8, 12, 15]),
                                     initial_time=time_max, time_unit='s')
brain_fsaverage.show_view('lateral')

###############################################################################
# Exercise
# --------
#    - By changing the method parameter to 'sloreta' recompute the source
#      estimates using the sLORETA method.
src_fname = data_path + '/MEG/sample/sample_audvis-meg-oct-6-fwd.fif'

# Read input stc file
stc_from = mne.read_source_estimate(fname)
# Morph using one method (supplying the vertices in fsaverage's source
# space makes it faster). Note that for any generic subject, you could do:
#     vertices_to = mne.grade_to_vertices(subject_to, grade=5)
# But fsaverage's source space was set up so we can just do this:
vertices_to = [np.arange(10242), np.arange(10242)]
stc_to = mne.morph_data(subject_from, subject_to, stc_from, n_jobs=1,
                        grade=vertices_to)
stc_to.save('%s_audvis-meg' % subject_to)

# Morph using another method -- useful if you're going to do a lot of the
# same inter-subject morphing operations; you could save and load morph_mat
morph_mat = mne.compute_morph_matrix(subject_from, subject_to, stc_from.vertno,
                                     vertices_to)
stc_to_2 = mne.morph_data_precomputed(subject_from, subject_to,
                                      stc_from, vertices_to, morph_mat)
stc_to_2.save('%s_audvis-meg_2' % subject_to)

# View source activations
import pylab as pl
pl.plot(stc_from.times, stc_from.data.mean(axis=0), 'r', label='from')
pl.plot(stc_to.times, stc_to.data.mean(axis=0), 'b', label='to')
pl.plot(stc_to_2.times, stc_to.data.mean(axis=0), 'g', label='to_2')
pl.xlabel('time (ms)')
pl.ylabel('Mean Source amplitude')
pl.legend()
pl.show()
        fname_morph = C.fname_STC(
            C, 'SensitivityMaps', subject,
            'SensMap_' + modality + '_' + metric + '_mph')

        # read existing source estimate
        print('Reading: %s.' % fname_stc)
        stc = mne.read_source_estimate(fname_stc, subject)

        # compute morph_mat only once per subject
        if morph_mat == []:

            vertices_to = mne.grade_to_vertices(subject=C.stc_morph,
                                                grade=5,
                                                subjects_dir=C.subjects_dir)

            morph_mat = mne.compute_morph_matrix(subject_from=subject,
                                                 subject_to=C.stc_morph,
                                                 vertices_from=stc.vertices,
                                                 vertices_to=vertices_to,
                                                 subjects_dir=C.subjects_dir)

        # Morphing to standard brain
        morphed = mne.morph_data_precomputed(subject_from=subject,
                                             subject_to=C.stc_morph,
                                             stc_from=stc,
                                             vertices_to=vertices_to,
                                             morph_mat=morph_mat)

        print('Writing morphed to: %s.' % fname_morph)
        morphed.save(fname_morph)
# Done
Exemple #29
0
def xhemi(ndvar, mask=None, hemi='lh', parc=True):
    """Project data from both hemispheres to ``hemi`` of fsaverage_sym

    Project data from both hemispheres to the same hemisphere for
    interhemisphere comparisons. The fsaverage_sym brain is a symmetric
    version of fsaverage to facilitate interhemisphere comparisons. It is
    included with FreeSurfer > 5.1 and can be obtained as described `here
    <http://surfer.nmr.mgh.harvard.edu/fswiki/Xhemi>`_. For statistical
    comparisons between hemispheres, use of the symmetric ``fsaverage_sym``
    model is recommended to minimize bias [1]_.

    Parameters
    ----------
    ndvar : NDVar
        NDVar with SourceSpace dimension.
    mask : bool
        Remove sources in "unknown-" labels (default is True unless ``ndvar``
        contains sources with "unknown-" label).
    hemi : 'lh' | 'rh'
        Hemisphere onto which to morph the data.
    parc : bool | str
        Parcellation for target source space; True to use same as in ``ndvar``
        (default).

    Returns
    -------
    lh : NDVAr
        Data from the left hemisphere on ``hemi`` of ``fsaverage_sym``.
    rh : NDVar
        Data from the right hemisphere on ``hemi`` of ``fsaverage_sym``.

    See Also
    --------
    morph_source_space: lower level function for morphing

    Notes
    -----
    Only symmetric volume source spaces are currently supported.

    References
    ----------
    .. [1] Greve D. N., Van der Haegen L., Cai Q., Stufflebeam S., Sabuncu M.
           R., Fischl B., Brysbaert M.
           A Surface-based Analysis of Language Lateralization and Cortical
           Asymmetry. Journal of Cognitive Neuroscience 25(9), 1477-1492, 2013.
    """
    source = ndvar.get_dim('source')
    other_hemi = 'rh' if hemi == 'lh' else 'lh'

    if isinstance(source, VolumeSourceSpace):
        ax = ndvar.get_axis('source')
        # extract hemi
        is_in_hemi = source.hemi == hemi
        source_out = source[is_in_hemi]
        # map other_hemi into hemi
        is_in_other = source.hemi == other_hemi
        coord_map = {
            tuple(source.coordinates[i]): i
            for i in np.flatnonzero(is_in_other)
        }
        try:
            other_source = [
                coord_map[-x, y, z] for x, y, z in source_out.coordinates
            ]
        except KeyError:
            raise NotImplementedError(
                "Only implemented for symmetric volume source spaces")
        # extract hemi-data
        x_hemi = ndvar.x[index(is_in_hemi, at=ax)]
        x_other = ndvar.x[index(other_source, at=ax)]
        # for vector data, the L/R component has to be mirrored
        for space_ax, dim in enumerate(ndvar.dims):
            if isinstance(dim, Space):
                for direction in 'LR':
                    if direction in dim:
                        i = dim._array_index(direction)
                        x_other[index(i, at=space_ax)] *= -1
        # combine data
        dims = list(ndvar.dims)
        dims[ax] = source_out
        out_same = NDVar(x_hemi, dims, ndvar.name, ndvar.info)
        out_other = NDVar(x_other, dims, ndvar.name, ndvar.info)
    else:
        if source.subject == 'fsaverage_sym':
            ndvar_sym = ndvar
        else:
            ndvar_sym = morph_source_space(ndvar,
                                           'fsaverage_sym',
                                           parc=parc,
                                           mask=mask)

        vert_lh, vert_rh = ndvar_sym.source.vertices
        vert_from = [[], vert_rh] if hemi == 'lh' else [vert_lh, []]
        vert_to = [vert_lh, []] if hemi == 'lh' else [[], vert_rh]
        with warnings.catch_warnings():
            warnings.filterwarnings(
                'ignore',
                r'\d+/\d+ vertices not included in smoothing',
                module='mne')
            morph_mat = mne.compute_morph_matrix(
                'fsaverage_sym',
                'fsaverage_sym',
                vert_from,
                vert_to,
                subjects_dir=ndvar.source.subjects_dir,
                xhemi=True)

        out_same = ndvar_sym.sub(source=hemi)
        out_other = morph_source_space(ndvar_sym.sub(source=other_hemi),
                                       'fsaverage_sym',
                                       out_same.source.vertices,
                                       morph_mat,
                                       parc=parc,
                                       xhemi=True,
                                       mask=mask)

    if hemi == 'lh':
        return out_same, out_other
    else:
        return out_other, out_same
Exemple #30
0
def morph_source_space(ndvar, subject_to, morph_mat=None, vertices_to=None):
    """Morph source estimate between subjects using a precomputed matrix

    Parameters
    ----------
    ndvar : NDVar
        NDVar with SourceSpace dimension.
    subject_to : string
        Name of the subject on which to morph.
    morph_mat : None | sparse matrix
        The morphing matrix. If ndvar contains a whole source space, the morph
        matrix can be automatically loaded, although providing a cached matrix
        can speed up processing by a second or two.
    vertices_to : None | list of array of int
        The vertices on the destination subject's brain. If ndvar contains a
        whole source space, vertices_to can be automatically loaded, although
        providing them as argument can speed up processing by a second or two.

    Returns
    -------
    morphed_ndvar : NDVar
        NDVar morphed to the destination subject.
    """
    src = ndvar.source.src
    subject_from = ndvar.source.subject
    subjects_dir = ndvar.source.subjects_dir
    vertices_from = ndvar.source.vertno
    if vertices_to is None:
        path = SourceSpace._src_pattern.format(subjects_dir=subjects_dir,
                                               subject=subject_to, src=src)
        src_to = mne.read_source_spaces(path)
        vertices_to = [src_to[0]['vertno'], src_to[1]['vertno']]
    elif not isinstance(vertices_to, list) or not len(vertices_to) == 2:
        raise ValueError('vertices_to must be a list of length 2')

    if morph_mat is None:
        morph_mat = mne.compute_morph_matrix(subject_from, subject_to,
                                             vertices_from, vertices_to, None,
                                             subjects_dir)
    elif not sp.sparse.issparse(morph_mat):
        raise ValueError('morph_mat must be a sparse matrix')
    elif not sum(len(v) for v in vertices_to) == morph_mat.shape[0]:
        raise ValueError('morph_mat.shape[0] must match number of vertices in '
                         'vertices_to')

    # flatten data
    axis = ndvar.get_axis('source')
    x = ndvar.x
    if axis != 0:
        x = x.swapaxes(0, axis)
    n_sources = len(x)
    if not n_sources == morph_mat.shape[1]:
        raise ValueError('ndvar source dimension length must be the same as '
                         'morph_mat.shape[0]')
    if ndvar.ndim > 2:
        shape = x.shape
        x = x.reshape((n_sources, -1))

    # apply morph matrix
    x_ = morph_mat * x

    # restore data shape
    if ndvar.ndim > 2:
        shape_ = (len(x_),) + shape[1:]
        x_ = x_.reshape(shape_)
    if axis != 0:
        x_ = x_.swapaxes(axis, 0)

    # package output NDVar
    parc = ndvar.source.parc
    source = SourceSpace(vertices_to, subject_to, src, subjects_dir, parc)
    dims = ndvar.dims[:axis] + (source,) + ndvar.dims[axis + 1:]
    info = ndvar.info.copy()
    out = NDVar(x_, dims, info, ndvar.name)
    return out
Exemple #31
0
def xhemi(ndvar, mask=None, hemi='lh', parc=True):
    """Project data from both hemispheres to ``hemi`` of fsaverage_sym

    Project data from both hemispheres to the same hemisphere for
    interhemisphere comparisons. The fsaverage_sym brain is a symmetric
    version of fsaverage to facilitate interhemisphere comparisons. It is
    included with FreeSurfer > 5.1 and can be obtained as described `here
    <http://surfer.nmr.mgh.harvard.edu/fswiki/Xhemi>`_. For statistical
    comparisons between hemispheres, use of the symmetric ``fsaverage_sym``
    model is recommended to minimize bias [1]_.

    Parameters
    ----------
    ndvar : NDVar
        NDVar with SourceSpace dimension.
    mask : bool
        Remove sources in "unknown-" labels (default is True unless ``ndvar``
        contains sources with "unknown-" label).
    hemi : 'lh' | 'rh'
        Hemisphere onto which to morph the data.
    parc : bool | str
        Parcellation for target source space; True to use same as in ``ndvar``
        (default).

    Returns
    -------
    lh : NDVAr
        Data from the left hemisphere on ``hemi`` of ``fsaverage_sym``.
    rh : NDVar
        Data from the right hemisphere on ``hemi`` of ``fsaverage_sym``.

    Notes
    -----
    Only symmetric volume source spaces are currently supported.

    References
    ----------
    .. [1] Greve D. N., Van der Haegen L., Cai Q., Stufflebeam S., Sabuncu M.
           R., Fischl B., Brysbaert M.
           A Surface-based Analysis of Language Lateralization and Cortical
           Asymmetry. Journal of Cognitive Neuroscience 25(9), 1477-1492, 2013.
    """
    source = ndvar.get_dim('source')
    other_hemi = 'rh' if hemi == 'lh' else 'lh'

    if isinstance(source, VolumeSourceSpace):
        ax = ndvar.get_axis('source')
        # extract hemi
        is_in_hemi = source.hemi == hemi
        source_out = source[is_in_hemi]
        # map other_hemi into hemi
        is_in_other = source.hemi == other_hemi
        coord_map = {tuple(source.coordinates[i]): i for i in np.flatnonzero(is_in_other)}
        other_source = [coord_map[-x, y, z] for x, y, z in source_out.coordinates]
        # combine data
        x_hemi = ndvar.x[index(is_in_hemi, at=ax)]
        x_other = ndvar.x[index(other_source, at=ax)]
        dims = list(ndvar.dims)
        dims[ax] = source_out
        out_same = NDVar(x_hemi, dims, ndvar.info, ndvar.name)
        out_other = NDVar(x_other, dims, ndvar.info, ndvar.name)
    else:
        if source.subject == 'fsaverage_sym':
            ndvar_sym = ndvar
        else:
            ndvar_sym = morph_source_space(ndvar, 'fsaverage_sym', parc=parc, mask=mask)

        vert_lh, vert_rh = ndvar_sym.source.vertices
        vert_from = [[], vert_rh] if hemi == 'lh' else [vert_lh, []]
        vert_to = [vert_lh, []] if hemi == 'lh' else [[], vert_rh]
        with warnings.catch_warnings():
            warnings.filterwarnings('ignore', r'\d+/\d+ vertices not included in smoothing', module='mne')
            morph_mat = mne.compute_morph_matrix(
                'fsaverage_sym', 'fsaverage_sym', vert_from, vert_to,
                subjects_dir=ndvar.source.subjects_dir, xhemi=True)

        out_same = ndvar_sym.sub(source=hemi)
        out_other = morph_source_space(
            ndvar_sym.sub(source=other_hemi), 'fsaverage_sym',
            out_same.source.vertices, morph_mat, parc=parc, xhemi=True, mask=mask)

    if hemi == 'lh':
        return out_same, out_other
    else:
        return out_other, out_same
Exemple #32
0
def morph_source_space(ndvar,
                       subject_to,
                       vertices_to=None,
                       morph_mat=None,
                       copy=False,
                       parc=True):
    """Morph source estimate to a different MRI subject

    Parameters
    ----------
    ndvar : NDVar
        NDVar with SourceSpace dimension.
    subject_to : string
        Name of the subject on which to morph.
    vertices_to : None | list of array of int
        The vertices on the destination subject's brain. If ndvar contains a
        whole source space, vertices_to can be automatically loaded, although
        providing them as argument can speed up processing by a second or two.
    morph_mat : None | sparse matrix
        The morphing matrix. If ndvar contains a whole source space, the morph
        matrix can be automatically loaded, although providing a cached matrix
        can speed up processing by a second or two.
    copy : bool
        Make sure that the data of ``morphed_ndvar`` is separate from
        ``ndvar`` (default False).
    parc : bool | str
        Parcellation for target source space. The default is to keep the
        parcellation from ``ndvar``. Set to ``False`` to load no parcellation.
        If the annotation files are missing for the target subject an IOError
        is raised.

    Returns
    -------
    morphed_ndvar : NDVar
        NDVar morphed to the destination subject.

    Notes
    -----
    This function is used to make sure a number of different NDVars are defined
    on the same MRI subject and handles scaled MRIs efficiently. If the MRI
    subject on which ``ndvar`` is defined is a scaled copy of ``subject_to``,
    by default a shallow copy of ``ndvar`` is returned. That means that it is
    not safe to assume that ``morphed_ndvar`` can be modified in place without
    altering ``ndvar``. To make sure the date of the output is independent from
    the data of the input, set the argument ``copy=True``.
    """
    subjects_dir = ndvar.source.subjects_dir
    subject_from = ndvar.source.subject
    src = ndvar.source.src
    if vertices_to is None:
        path = SourceSpace._SRC_PATH.format(subjects_dir=subjects_dir,
                                            subject=subject_to,
                                            src=src)
        src_to = mne.read_source_spaces(path)
        vertices_to = [
            src_to[0]['vertno'] if ndvar.source.lh_n else np.empty(0, int),
            src_to[1]['vertno'] if ndvar.source.rh_n else np.empty(0, int)
        ]
    elif not isinstance(vertices_to, list) or not len(vertices_to) == 2:
        raise ValueError('vertices_to must be a list of length 2')

    # parc for new source space
    if parc is True:
        parc_to = ndvar.source.parc.name if ndvar.source.parc else None
    else:
        parc_to = parc
    # check that annot files are available
    if parc_to:
        fname = SourceSpace._ANNOT_PATH.format(subjects_dir=subjects_dir,
                                               subject=subject_to,
                                               hemi='%s',
                                               parc=parc_to)
        fnames = tuple(fname % hemi for hemi in ('lh', 'rh'))
        missing = tuple(fname for fname in fnames if not os.path.exists(fname))
        if missing:
            raise IOError(
                "Annotation files are missing for parc=%r for target subject "
                "%s. Use the parc parameter to change the parcellation. The "
                "following files are missing:\n%s" %
                (parc_to, subject_to, '\n'.join(missing)))

    if subject_from == subject_to and _vertices_equal(ndvar.source.vertno,
                                                      vertices_to):
        if copy:
            ndvar = ndvar.copy()
        if parc is not True:
            ndvar.source.set_parc(parc)
        return ndvar

    axis = ndvar.get_axis('source')
    x = ndvar.x

    # check whether it is a scaled brain
    do_morph = True
    cfg_path = os.path.join(subjects_dir, subject_from,
                            'MRI scaling parameters.cfg')
    if os.path.exists(cfg_path):
        cfg = mne.coreg.read_mri_cfg(subject_from, subjects_dir)
        subject_from = cfg['subject_from']
        if subject_to == subject_from and _vertices_equal(
                ndvar.source.vertno, vertices_to):
            if copy:
                x_ = x.copy()
            else:
                x_ = x
            vertices_to = ndvar.source.vertno
            do_morph = False

    if do_morph:
        vertices_from = ndvar.source.vertno
        if morph_mat is None:
            morph_mat = mne.compute_morph_matrix(subject_from, subject_to,
                                                 vertices_from, vertices_to,
                                                 None, subjects_dir)
        elif not sp.sparse.issparse(morph_mat):
            raise ValueError('morph_mat must be a sparse matrix')
        elif not sum(len(v) for v in vertices_to) == morph_mat.shape[0]:
            raise ValueError('morph_mat.shape[0] must match number of '
                             'vertices in vertices_to')

        # flatten data
        if axis != 0:
            x = x.swapaxes(0, axis)
        n_sources = len(x)
        if not n_sources == morph_mat.shape[1]:
            raise ValueError('ndvar source dimension length must be the same '
                             'as morph_mat.shape[0]')
        if ndvar.ndim > 2:
            shape = x.shape
            x = x.reshape((n_sources, -1))

        # apply morph matrix
        x_ = morph_mat * x

        # restore data shape
        if ndvar.ndim > 2:
            shape_ = (len(x_), ) + shape[1:]
            x_ = x_.reshape(shape_)
        if axis != 0:
            x_ = x_.swapaxes(axis, 0)

    # package output NDVar
    source = SourceSpace(vertices_to, subject_to, src, subjects_dir, parc_to)
    dims = ndvar.dims[:axis] + (source, ) + ndvar.dims[axis + 1:]
    info = ndvar.info.copy()
    out = NDVar(x_, dims, info, ndvar.name)
    return out
Exemple #33
0
        inv = op.join(inv_dir, '%s-%d-sss-%s-inv.fif' % (subj, p.lp_cut, inv_type))
        inv = read_inverse_operator(inv)
        fname = op.join(inv_dir, '%s_%d-sss_eq_%s-ave.fif'
                        % (p.analyses[0], p.lp_cut, subj))
        aves = [mne.Evoked(fname, cond, baseline=(None, 0), proj=True,
                                kind='average') for cond in conditions]
        nave = np.unique([a.nave for a in aves])
        assert len(nave) == 1
        for ave, cond in zip(aves, conditions):
                assert ave.comment == cond
        naves[si] = nave[0]

        # apply inverse, bin, morph
        stcs = [apply_inverse(ave, inv, lambda2, 'dSPM') for ave in aves]
        stcs = [stc.bin(0.005) for stc in stcs]
        m = mne.compute_morph_matrix(struc, 'fsaverage', stcs[0].vertices,
                                     fs_verts, n_smooth)
        stcs = [stc.morph_precomputed('fsaverage', fs_verts, m)
                for stc in stcs]

        # put in big matrix
        if subj == p.subjects[0]:
            data = np.empty((len(stcs), len(p.subjects), stcs[0].shape[0],
                             stcs[0].shape[1]))
        for di, stc in enumerate(stcs):
            data[di, si, :, :] = stc.data
            times = stc.times
        print('Writing data...')
        np.savez_compressed(fname_data, data=data, times=times, naves=naves)
else:
    print('Loading saved data...')
    data = np.load(fname_data)
Exemple #34
0
def morph_source_space(ndvar,
                       subject_to=None,
                       vertices_to=None,
                       morph_mat=None,
                       copy=False,
                       parc=True,
                       xhemi=False,
                       mask=None):
    """Morph source estimate to a different MRI subject

    Parameters
    ----------
    ndvar : NDVar
        NDVar with SourceSpace dimension.
    subject_to : str
        Name of the subject on which to morph (by default this is the same as
        the current subject for ``xhemi`` morphing).
    vertices_to : None | list of array of int | 'lh' | 'rh'
        The vertices on the destination subject's brain. If ndvar contains a
        whole source space, vertices_to can be automatically loaded, although
        providing them as argument can speed up processing by a second or two.
        Use 'lh' or 'rh' to target vertices from only one hemisphere.
    morph_mat : None | sparse matrix
        The morphing matrix. If ndvar contains a whole source space, the morph
        matrix can be automatically loaded, although providing a cached matrix
        can speed up processing by a second or two.
    copy : bool
        Make sure that the data of ``morphed_ndvar`` is separate from
        ``ndvar`` (default False).
    parc : bool | str
        Parcellation for target source space. The default is to keep the
        parcellation from ``ndvar``. Set to ``False`` to load no parcellation.
        If the annotation files are missing for the target subject an IOError
        is raised.
    xhemi : bool
        Mirror hemispheres (i.e., project data from the left hemisphere to the
        right hemisphere and vice versa).
    mask : bool
        Restrict output to known sources. If the parcellation of ``ndvar`` is
        retained keep only sources with labels contained in ``ndvar``, otherwise
        remove only sourves with ``”unknown-*”`` label (default is True unless
        ``vertices_to`` is specified).

    Returns
    -------
    morphed_ndvar : NDVar
        NDVar morphed to the destination subject.

    See Also
    --------
    xhemi: morph data from both hemisphere to one for comparing hemispheres

    Notes
    -----
    This function is used to make sure a number of different NDVars are defined
    on the same MRI subject and handles scaled MRIs efficiently. If the MRI
    subject on which ``ndvar`` is defined is a scaled copy of ``subject_to``,
    by default a shallow copy of ``ndvar`` is returned. That means that it is
    not safe to assume that ``morphed_ndvar`` can be modified in place without
    altering ``ndvar``. To make sure the date of the output is independent from
    the data of the input, set the argument ``copy=True``.

    Examples
    --------
    Generate a symmetric ROI based on a test result (``res``)::

        # Generate a mask based on significance
        mask = res.p.min('time') <= 0.05
        # store the vertices for which we want the end result
        fsa_vertices = mask.source.vertices
        # morphing is easier with a complete source space
        mask = complete_source_space(mask)
        # Use a parcellation that is available for the ``fsaverage_sym`` brain
        mask = set_parc(mask, 'aparc')
        # morph both hemispheres to the left hemisphere
        mask_from_lh, mask_from_rh = xhemi(mask)
        # take the union; morphing interpolates, so re-cast values to booleans
        mask_lh = (mask_from_lh > 0) | (mask_from_rh > 0)
        # morph the new ROI to the right hemisphere
        mask_rh = morph_source_space(mask_lh, vertices_to=[[], mask_lh.source.vertices[0]], xhemi=True)
        # cast back to boolean
        mask_rh = mask_rh > 0
        # combine the two hemispheres
        mask_sym = concatenate([mask_lh, mask_rh], 'source')
        # morph the result back to the source brain (fsaverage)
        mask = morph_source_space(mask_sym, 'fsaverage', fsa_vertices)
    """
    axis = ndvar.get_axis('source')
    source = ndvar.get_dim('source')
    subjects_dir = source.subjects_dir
    subject_from = source.subject
    if subject_to is None:
        subject_to = subject_from
    else:
        assert_subject_exists(subject_to, subjects_dir)
    # catch cases that don't require morphing
    if not xhemi:
        subject_is_same = subject_from == subject_to
        subject_is_scaled = find_source_subject(
            subject_to, subjects_dir) == subject_from or find_source_subject(
                subject_from, subjects_dir) == subject_to
        if subject_is_same or subject_is_scaled:
            if vertices_to is None:
                pass
            elif vertices_to in ('lh', 'rh'):
                ndvar = ndvar.sub(source=vertices_to)
            elif isinstance(vertices_to, str):
                raise ValueError(f"vertices_to={vertices_to!r}")
            else:
                raise TypeError(f"vertices_to={vertices_to!r}")

            x = ndvar.x.copy() if copy else ndvar.x
            parc_arg = None if parc is True else parc
            if subject_is_scaled or parc_arg is not None:
                source_to = source._copy(subject_to, parc=parc_arg)
            else:
                source_to = source

            dims = (*ndvar.dims[:axis], source_to, *ndvar.dims[axis + 1:])
            return NDVar(x, dims, ndvar.name, ndvar.info)

    has_lh_out = bool(source.rh_n if xhemi else source.lh_n)
    has_rh_out = bool(source.lh_n if xhemi else source.rh_n)
    if vertices_to in (None, 'lh', 'rh'):
        default_vertices = source_space_vertices(source.kind, source.grade,
                                                 subject_to, subjects_dir)
        lh_out = vertices_to == 'lh' or (vertices_to is None and has_lh_out)
        rh_out = vertices_to == 'rh' or (vertices_to is None and has_rh_out)
        vertices_to = [
            default_vertices[0] if lh_out else np.empty(0, int),
            default_vertices[1] if rh_out else np.empty(0, int)
        ]
        if mask is None:
            if source.parc is None:
                mask = False
            else:
                mask = not np.any(source.parc.startswith('unknown-'))
    elif not isinstance(vertices_to, list) or not len(vertices_to) == 2:
        raise ValueError(
            f"vertices_to={vertices_to!r}: must be a list of length 2")

    # check that requested data is available
    n_to_lh = len(vertices_to[0])
    n_to_rh = len(vertices_to[1])
    if n_to_lh and not has_lh_out:
        raise ValueError(
            "Data on the left hemisphere was requested in vertices_to but is not available in ndvar"
        )
    elif n_to_rh and not has_rh_out:
        raise ValueError(
            "Data on the right hemisphere was requested in vertices_to but is not available in ndvar"
        )
    elif n_to_lh == 0 and n_to_rh == 0:
        raise ValueError("No target vertices")

    # parc for new source space
    if parc is True:
        parc_to = None if source.parc is None else source.parc.name
    else:
        parc_to = parc
    if mask and parc_to is None:
        raise ValueError("Can't mask source space without parcellation...")
    # check that annot files are available
    if parc_to:
        fname = SourceSpace._ANNOT_PATH.format(subjects_dir=subjects_dir,
                                               subject=subject_to,
                                               hemi='%s',
                                               parc=parc_to)
        fnames = tuple(fname % hemi for hemi in ('lh', 'rh'))
        missing = tuple(fname for fname in fnames if not os.path.exists(fname))
        if missing:
            missing = '\n'.join(missing)
            raise IOError(
                f"Annotation files are missing for parc={parc_to!r}, subject={subject_to!r}. Use the parc parameter when morphing to set a different parcellation. The following files are missing:\n{missing}"
            )
    # find target source space
    source_to = SourceSpace(vertices_to, subject_to, source.src, subjects_dir,
                            parc_to)
    if mask is True:
        if parc is True:
            keep_labels = source.parc.cells
            if xhemi:
                keep_labels = [switch_hemi_tag(label) for label in keep_labels]
            index = source_to.parc.isin(keep_labels)
        else:
            index = source_to.parc.isnotin(('unknown-lh', 'unknown-rh'))
        source_to = source_to[index]
    elif mask not in (None, False):
        raise TypeError(f"mask={mask!r}")

    if morph_mat is None:
        with warnings.catch_warnings():
            warnings.filterwarnings(
                'ignore',
                r'\d+/\d+ vertices not included in smoothing',
                module='mne')
            morph_mat = mne.compute_morph_matrix(subject_from,
                                                 subject_to,
                                                 source.vertices,
                                                 source_to.vertices,
                                                 None,
                                                 subjects_dir,
                                                 xhemi=xhemi)
    elif not sp.sparse.issparse(morph_mat):
        raise ValueError('morph_mat must be a sparse matrix')
    elif not sum(len(v) for v in source_to.vertices) == morph_mat.shape[0]:
        raise ValueError(
            'morph_mat.shape[0] must match number of vertices in vertices_to')

    # flatten data
    x = ndvar.x
    if axis != 0:
        x = x.swapaxes(0, axis)
    n_sources = len(x)
    if not n_sources == morph_mat.shape[1]:
        raise ValueError(
            'ndvar source dimension length must be the same as morph_mat.shape[0]'
        )
    if ndvar.ndim > 2:
        shape = x.shape
        x = x.reshape((n_sources, -1))

    # apply morph matrix
    x_m = morph_mat * x

    # restore data shape
    if ndvar.ndim > 2:
        shape_ = (len(x_m), ) + shape[1:]
        x_m = x_m.reshape(shape_)
    if axis != 0:
        x_m = x_m.swapaxes(axis, 0)

    # package output NDVar
    dims = (*ndvar.dims[:axis], source_to, *ndvar.dims[axis + 1:])
    return NDVar(x_m, dims, ndvar.name, ndvar.info)
Exemple #35
0
data_dir = mne.datasets.sample.data_path()
subjects_dir = data_dir + '/subjects'
stc_path = data_dir + '/MEG/sample/sample_audvis-meg-eeg'

stc = mne.read_source_estimate(stc_path, 'sample')

# First, morph the data to fsaverage_sym, for which we have left_right
# registrations:
stc = stc.morph('fsaverage_sym', subjects_dir=subjects_dir, smooth=5)

# Compute a morph-matrix mapping the right to the left hemisphere. Use the
# vertices parameters to determine source and target hemisphere:
mm = mne.compute_morph_matrix(
    'fsaverage_sym', 'fsaverage_sym', xhemi=True,  # cross-hemisphere morphing
    vertices_from=[[], stc.vertices[1]],  # from the right hemisphere
    vertices_to=[stc.vertices[0], []],  # to the left hemisphere
    subjects_dir=subjects_dir)

# SourceEstimate on the left hemisphere:
stc_lh = mne.SourceEstimate(stc.lh_data, [stc.vertices[0], []], stc.tmin,
                            stc.tstep, stc.subject)
# SourceEstimate of the right hemisphere, morphed to the left:
stc_rh_on_lh = mne.SourceEstimate(mm * stc.rh_data, [stc.vertices[0], []],
                                  stc.tmin, stc.tstep, stc.subject)
# Since both STCs are now on the same hemisphere we can subtract them:
diff = stc_lh - stc_rh_on_lh

diff.plot(hemi='lh', subjects_dir=subjects_dir, initial_time=0.07,
          size=(800, 600))
Exemple #36
0
print('Simulating data for %d subjects.' % n_subjects)

#    Let's make sure our results replicate, so set the seed.
np.random.seed(0)
X = randn(n_vertices_sample, n_times, n_subjects, 4) * 10
for ii, condition in enumerate(conditions):
    X[:, :, :, ii] += condition.lh_data[:, :, np.newaxis]

#    It's a good idea to spatially smooth the data, and for visualization
#    purposes, let's morph these to fsaverage, which is a grade 5 source space
#    with vertices 0:10242 for each hemisphere. Usually you'd have to morph
#    each subject's data separately (and you might want to use morph_data
#    instead), but here since all estimates are on 'sample' we can use one
#    morph matrix for all the heavy lifting.
fsave_vertices = [np.arange(10242), np.array([])]  # right hemisphere is empty
morph_mat = compute_morph_matrix('sample', 'fsaverage', sample_vertices,
                                 fsave_vertices, 20, subjects_dir)
n_vertices_fsave = morph_mat.shape[0]

#    We have to change the shape for the dot() to work properly
X = X.reshape(n_vertices_sample, n_times * n_subjects * 4)
print('Morphing data.')
X = morph_mat.dot(X)  # morph_mat is a sparse matrix
X = X.reshape(n_vertices_fsave, n_times, n_subjects, 4)

#    Now we need to prepare the group matrix for the ANOVA statistic.
#    To make the clustering function work correctly with the
#    ANOVA function X needs to be a list of multi-dimensional arrays
#    (one per condition) of shape: samples (subjects) x time x space

X = np.transpose(X, [2, 1, 0, 3])  # First we permute dimensions
# finally we split the array into a list a list of conditions
Exemple #37
0
    def sublevel_spatial_stats(X, subject, index, stc, clust_p, modality,
                               method, condition):

        con = mne.spatial_tris_connectivity(grade_to_tris(5))

        # morphing data
        subjects_dir = '/neurospin/meg/meg_tmp/MTT_MEG_Baptiste/mri/'

        fsave_vertices = [np.arange(10242), np.arange(10242)]
        subject_vertices = [stc.lh_vertno, stc.rh_vertno]
        morph_mat = compute_morph_matrix(subject, 'fsaverage',
                                         subject_vertices, fsave_vertices, 20,
                                         subjects_dir)
        n_vertices_fsave = morph_mat.shape[0]

        nobs = index[0]
        ncond = len(index)
        ntimes = X.shape[2]
        nvertices = stc.lh_vertno.shape[0] + stc.rh_vertno.shape[0]

        #    We have to change the shape for the dot() to work properly
        X = np.transpose(X, [1, 2, 0])  # vertices * times * obs
        X = X.reshape(nvertices, ntimes * nobs * ncond)
        print('Morphing data.')
        X = morph_mat.dot(X)  # morph_mat is a sparse matrix
        X = X.reshape(n_vertices_fsave, ntimes, nobs, ncond)

        # list of array of shapes ncond*(obs, time, vertices)
        X = np.transpose(X, [2, 1, 0, 3])
        X = [np.squeeze(x) for x in np.split(X, 3, axis=-1)]

        # average over time to clusterize only on spatial dimension
        X = [np.mean(x, 1) for x in X]

        p_threshold = clust_p
        f_threshold = stats.distributions.f.ppf(1 - p_threshold, ncond - 1,
                                                ncond * (nobs - 1))

        # use default function one-way anova (not repeated measures!)
        F_obs, clu, clu_p_val, H0 = mne.stats.permutation_cluster_test(
            X,
            threshold=f_threshold,
            connectivity=con,
            n_jobs=4,
            verbose=True,
            seed=666)

        wdir = "/neurospin/meg/meg_tmp/MTT_MEG_Baptiste/MEG/"
        save_path = (wdir + subject + '/mne_python/STATS')

        if not os.path.exists(save_path):
            os.makedirs(save_path)

        # save cluster stats
        spatial_clust_F = np.array((F_obs, clu, clu_p_val, H0))
        np.save((save_path + '/' + modality + '_' + 'cluster_stats_' +
                 "_vs_".join(condition)), spatial_clust_F)

        # save F-Map
        tmp = F_obs
        tmp = tmp[:, np.newaxis]
        fsave_vertices = [np.arange(10242), np.arange(10242)]
        stc_Ftest = mne.SourceEstimate(tmp, fsave_vertices, 0, stc.tstep)
        stc_Ftest.save(
            (save_path + '/' + modality + '_' + "_vs_".join(condition)))

        # to create probability maps: threshold the map at p < 0.05 and binarize
        ind = np.where(F_obs >= f_threshold)[0]
        VertKept = np.empty((len(F_obs)))
        for v, vertices in enumerate(VertKept):
            if v in ind:
                VertKept[v] = 1
            else:
                VertKept[v] = 0

        VertKept = VertKept[:, np.newaxis]
        fsave_vertices = [np.arange(10242), np.arange(10242)]
        stc_Ftest = mne.SourceEstimate(VertKept, fsave_vertices, 0, stc.tstep)
        stc_Ftest.save((save_path + '/' + modality + '_' + 'BinForProb_' +
                        "_vs_".join(condition)))

        return F_obs, clu, clu_p_val, H0
Exemple #38
0
        #        plt.xlabel('time (ms)')
        #        plt.ylabel('%s value' % method)
        #        plt.show()

        stc.crop(-0.1, 0.9)

        tstep = stc.tstep
        times = stc.times
        # Average brain
        """
        One should check if morph map is current and correct. Otherwise, it will spit out and error.
        Check SUBJECTS_DIR/morph-maps
        """
        morph_mat = mne.compute_morph_matrix(subs[n],
                                             'fsaverage',
                                             stc.vertices,
                                             fs_vertices,
                                             smooth=20,
                                             subjects_dir=fs_dir)
        stc_fsaverage = stc.morph_precomputed('fsaverage', fs_vertices,
                                              morph_mat, subs[n])

        #        tmin, tmax = 0.080, 0.120
        #        stc_mean = stc_fsaverage.copy().crop(tmin, tmax).mean()
        #
        #        labels = mne.read_labels_from_annot('fsaverage', parc='HCPMMP1', surf_name='white', subjects_dir=fs_dir)
        #        V1_label_lh = [label for label in labels if label.name == 'L_V1_ROI-lh'][0]
        #        V1_label_rh = [label for label in labels if label.name == 'R_V1_ROI-rh'][0]
        #
        #        stc_mean_label = stc_mean.in_label(V1_label_lh)
        #        data = np.abs(stc_mean_label.data)
        #        stc_mean_label.data[data < 0.6 * np.max(data)] = 0.
#early
exclude = [1,2,3,4,5,6,7,8,9,10,11,12,14,15,16,18,20,22,24,25,26,27,29,31,33,37,38,40,41,42,43,44,45,46,47,48,49,50] 
for run in range(1, 51):
    if run in exclude:
        continue
    subject = "s%02d" % run
    stc_fname = op.join('/raid5/rcho/MEG_NM_NR_testing/FINALMNE/DATA/stc/', '%s_40hz' % (subject))
    fssub = "S%02d" % run
    subjects_dir=op.join('/raid5/rcho/PSYCH_CFC/fMRI/', '%s/RAW/fs_test/' % (fssub))
    print("processing subject: %s" % subject)
    stc=mne.read_source_estimate(stc_fname, subject=subject)
#    morphed = stc.morph(subject_from=fssub, subject_to='fsaverage',
#                        subjects_dir=subjects_dir, grade=4)
    fs_vertices = [np.arange(10242)] * 2  # fsaverage is special this way
    morph_mat = mne.compute_morph_matrix(fssub, 'fsaverage', stc.vertices,
                                     fs_vertices, smooth=None,
                                     subjects_dir=subjects_dir)
    stc_fsaverage = stc.morph_precomputed('fsaverage', fs_vertices, morph_mat)
    #morphed.save(op.join(datapath, '%s-morphed' % (subject)))
    stcs.append(stc_fsaverage)

data = np.average([s.data for s in stcs], axis=0)
stc_e = mne.SourceEstimate(data, stcs[0].vertices, stcs[0].tmin, stcs[0].tstep)
stc_e.save(op.join('/raid5/rcho/MEG_NM_NR_testing/FINALMNE/DATA/group/patient/', 'STCearly_average'))
###########################################
#plotting
stc_e_fname=op.join('/raid5/rcho/MEG_NM_NR_testing/FINALMNE/DATA/group/patient/', 'STCearly_average')  
stc_e=mne.read_source_estimate(stc_e_fname)
tmin=0.150
tmax=0.900
stc_e_mean = stc_e.copy().crop(tmin, tmax).mean()
Exemple #40
0
stc_from = mne.read_source_estimate(fname)
# Morph using one method (supplying the vertices in fsaverage's source
# space makes it faster). Note that for any generic subject, you could do:
#     vertices_to = mne.grade_to_vertices(subject_to, grade=5)
# But fsaverage's source space was set up so we can just do this:
vertices_to = [np.arange(10242), np.arange(10242)]
stc_to = mne.morph_data(subject_from,
                        subject_to,
                        stc_from,
                        n_jobs=1,
                        grade=vertices_to)
stc_to.save('%s_audvis-meg' % subject_to)

# Morph using another method -- useful if you're going to do a lot of the
# same inter-subject morphing operations; you could save and load morph_mat
morph_mat = mne.compute_morph_matrix(subject_from, subject_to, stc_from.vertno,
                                     vertices_to)
stc_to_2 = mne.morph_data_precomputed(subject_from, subject_to, stc_from,
                                      vertices_to, morph_mat)
stc_to_2.save('%s_audvis-meg_2' % subject_to)

# View source activations
import matplotlib.pyplot as plt
plt.plot(stc_from.times, stc_from.data.mean(axis=0), 'r', label='from')
plt.plot(stc_to.times, stc_to.data.mean(axis=0), 'b', label='to')
plt.plot(stc_to_2.times, stc_to.data.mean(axis=0), 'g', label='to_2')
plt.xlabel('time (ms)')
plt.ylabel('Mean Source amplitude')
plt.legend()
plt.show()
                                  forward,
                                  cov_blank,
                                  loose=0.2,
                                  depth=0.8)
blank_idx = np.nonzero(epochs_ds.events[:, 2] == 15)[0]
epochs_ds.drop_epochs(blank_idx)
cov_base = mne.compute_covariance(epochs_ds, tmin=None, tmax=0, method='auto')
inv_base = make_inverse_operator(epochs_ds.info,
                                 forward,
                                 cov_base,
                                 loose=0.2,
                                 depth=0.8)

vertices_to = [np.arange(10242), np.arange(10242)]
vertices_from = [forward['src'][0]['vertno'], forward['src'][1]['vertno']]
morph_mat = mne.compute_morph_matrix(subj, 'fsaverage', vertices_from,
                                     vertices_to)
for c in range(len(conds)):
    # start with the simplest method, MNE + dSPM
    stc = apply_inverse(evoked_ds[c], inv_base, lambda2, method)
    stc = mne.morph_data_precomputed(subj, 'fsaverage', stc, vertices_to,
                                     morph_mat)
    fname = out_dir + '%s_%s_dSPM_base_clean' % (subj, conds[c])
    stc.save(fname)
    stc = apply_inverse(evoked_ds[c], inv_blank, lambda2, method)
    stc = mne.morph_data_precomputed(subj, 'fsaverage', stc, vertices_to,
                                     morph_mat)
    fname = out_dir + '%s_%s_dSPM_blank_clean' % (subj, conds[c])
    stc.save(fname)

    # the next estimate is LCMV beamformer in time
    data_cov = mne.compute_covariance(epochs_ds[conds[c]],
print('Simulating data for %d subjects.' % n_subjects)

#    Let's make sure our results replicate, so set the seed.
np.random.seed(0)
X = randn(n_vertices_sample, n_times, n_subjects, 4) * 10
for ii, condition in enumerate(conditions):
    X[:, :, :, ii] += condition.lh_data[:, :, np.newaxis]

#    It's a good idea to spatially smooth the data, and for visualization
#    purposes, let's morph these to fsaverage, which is a grade 5 source space
#    with vertices 0:10242 for each hemisphere. Usually you'd have to morph
#    each subject's data separately (and you might want to use morph_data
#    instead), but here since all estimates are on 'sample' we can use one
#    morph matrix for all the heavy lifting.
fsave_vertices = [np.arange(10242), np.array([], int)]  # right hemi is empty
morph_mat = compute_morph_matrix('sample', 'fsaverage', sample_vertices,
                                 fsave_vertices, 20, subjects_dir)
n_vertices_fsave = morph_mat.shape[0]

#    We have to change the shape for the dot() to work properly
X = X.reshape(n_vertices_sample, n_times * n_subjects * 4)
print('Morphing data.')
X = morph_mat.dot(X)  # morph_mat is a sparse matrix
X = X.reshape(n_vertices_fsave, n_times, n_subjects, 4)

#    Now we need to prepare the group matrix for the ANOVA statistic.
#    To make the clustering function work correctly with the
#    ANOVA function X needs to be a list of multi-dimensional arrays
#    (one per condition) of shape: samples (subjects) x time x space

X = np.transpose(X, [2, 1, 0, 3])  # First we permute dimensions
# finally we split the array into a list a list of conditions
            
            n_epochs2[n][iCond] = evoked.nave
            
            stc = mne.minimum_norm.apply_inverse(evoked,inv,lambda2, method=method, pick_ori="normal")
            
            stc.crop(-0.1, 0.9)
            tmin = stc.tmin
            tstep = stc.tstep
            times = stc.times
            # Average brain
            """
            One should check if morph map is current and correct. Otherwise, it will spit out and error.
            Check SUBJECTS_DIR/morph-maps
            """
            morph_mat = mne.compute_morph_matrix(subs2[n], 'fsaverage', stc.vertices,
                                                 fs_vertices, smooth=None,
                                                 subjects_dir=fs_dir)
            stc_fsaverage = stc.morph_precomputed('fsaverage', fs_vertices, morph_mat)
        #    morph_dat = mne.morph_data(subs[n], 'fsaverage', stc, n_jobs=16,
        #                        grade=fs_vertices, subjects_dir=fs_dir)
            X2[:,:,n,iCond] = stc_fsaverage.data

    os.chdir(raw_dir)
    np.save(fname_data, X2)
    np.save('session2_times.npy',times)
    np.save('session2_tstep.npy',tstep)
    np.save('session2_n_averages.npy',n_epochs2)
else:
    os.chdir(raw_dir)
    X2 = np.load(fname_data)
    times = np.load('session2_times.npy')