def source_space_vertices(kind, grade, subject, subjects_dir): """Vertices in ico-``grade`` source space""" if kind == 'ico' and subject in ICO_SLICE_SUBJECTS: n = ICO_N_VERTICES[grade] return np.arange(n), np.arange(n) path = Path(subjects_dir) / subject / 'bem' / f'{subject}-{kind}-{grade}-src.fif' if path.exists(): src_to = mne.read_source_spaces(str(path)) return [ss['vertno'] for ss in src_to] elif kind == 'ico': return mne.grade_to_vertices(subject, grade, subjects_dir) else: raise NotImplementedError(f"Can't infer vertices for {kind}-{grade} source space")
def source_space_vertices(kind, grade, subject, subjects_dir): """Vertices in ico-``grade`` source space""" if kind == 'ico' and subject in ICO_SLICE_SUBJECTS: n = ICO_N_VERTICES[grade] return np.arange(n), np.arange(n) path = Path( subjects_dir) / subject / 'bem' / f'{subject}-{kind}-{grade}-src.fif' if path.exists(): src_to = mne.read_source_spaces(str(path)) return [ss['vertno'] for ss in src_to] elif kind == 'ico': return mne.grade_to_vertices(subject, grade, subjects_dir) else: raise NotImplementedError( f"Can't infer vertices for {kind}-{grade} source space")
def smooth_ttest_results(tmin, tstep, subjects_dir, inverse_method='dSPM', n_jobs=1): for cond_id, cond_name in enumerate(events_id.keys()): for patient in get_patients(): results_file_name = op.join(LOCAL_ROOT_DIR, 'permutation_ttest_results', '{}_{}_{}_clusters.npy'.format(patient, cond_name, inverse_method)) if op.isfile(results_file_name): data = np.load(results_file_name) print('smoothing {} {}'.format(patient, cond_name)) fsave_vertices = [np.arange(10242), np.arange(10242)] stc = _make_stc(data, fsave_vertices, tmin=tmin, tstep=tstep, subject='fsaverage') vertices_to = mne.grade_to_vertices('fsaverage', grade=None, subjects_dir=subjects_dir) print(stc.data.shape, vertices_to[0].shape) stc_smooth = mne.morph_data('fsaverage', 'fsaverage', stc, n_jobs=n_jobs, grade=vertices_to, subjects_dir=subjects_dir) stc_smooth.save(op.join(LOCAL_ROOT_DIR, 'results_for_blender', '{}_{}_{}'.format(patient, cond_name, inverse_method)), ftype='h5') else: print('no results for {} {}'.format(patient, cond_name))
def source_space_vertices(kind, grade, subject, subjects_dir): """Vertices in ico-``grade`` source space""" if kind == 'ico' and subject in ICO_SLICE_SUBJECTS: n = ICO_N_VERTICES[grade] return np.arange(n), np.arange(n) path = SourceSpace._SRC_PATH.format(subjects_dir=subjects_dir, subject=subject, src='ico-%i' % grade) if os.path.exists(path): src_to = mne.read_source_spaces(path) return src_to[0]['vertno'], src_to[1]['vertno'] elif kind != 'ico': raise NotImplementedError( "Can't infer vertices for non-ico source space") else: return mne.grade_to_vertices(subject, grade, subjects_dir)
def test_morph_stc_dense(): """Test morphing stc.""" subject_from = 'sample' subject_to = 'fsaverage' stc_from = read_source_estimate(fname_smorph, subject='sample') stc_to = read_source_estimate(fname_fmorph) # make sure we can specify grade stc_from.crop(0.09, 0.1) # for faster computation stc_to.crop(0.09, 0.1) # for faster computation assert_array_equal(stc_to.time_as_index([0.09, 0.1], use_rounding=True), [0, len(stc_to.times) - 1]) # After dep change this to: morph = compute_source_morph( subject_to=subject_to, spacing=3, smooth=12, src=stc_from, subjects_dir=subjects_dir, precompute=True) assert morph.vol_morph_mat is None # a no-op for surface stc_to1 = morph.apply(stc_from) assert_allclose(stc_to.data, stc_to1.data, atol=1e-5) mean_from = stc_from.data.mean(axis=0) mean_to = stc_to1.data.mean(axis=0) assert np.corrcoef(mean_to, mean_from).min() > 0.999 vertices_to = grade_to_vertices(subject_to, grade=3, subjects_dir=subjects_dir) # make sure we can fill by morphing with pytest.warns(RuntimeWarning, match='consider increasing'): morph = compute_source_morph( stc_from, subject_from, subject_to, spacing=None, smooth=1, subjects_dir=subjects_dir) stc_to5 = morph.apply(stc_from) assert stc_to5.data.shape[0] == 163842 + 163842 # Morph vector data stc_vec = _real_vec_stc() stc_vec_to1 = compute_source_morph( stc_vec, subject_from, subject_to, subjects_dir=subjects_dir, spacing=vertices_to, smooth=1, warn=False).apply(stc_vec) assert stc_vec_to1.subject == subject_to assert stc_vec_to1.tmin == stc_vec.tmin assert stc_vec_to1.tstep == stc_vec.tstep assert len(stc_vec_to1.lh_vertno) == 642 assert len(stc_vec_to1.rh_vertno) == 642 # Degenerate conditions # Morphing to a density that is too high should raise an informative error # (here we need to push to grade=6, but for some subjects even grade=5 # will break) with pytest.raises(ValueError, match='Cannot use icosahedral grade 6 '): compute_source_morph( stc_to1, subject_from=subject_to, subject_to=subject_from, spacing=6, subjects_dir=subjects_dir) del stc_to1 with pytest.raises(ValueError, match='smooth.* has to be at least 1'): compute_source_morph( stc_from, subject_from, subject_to, spacing=5, smooth=-1, subjects_dir=subjects_dir) # subject from mismatch with pytest.raises(ValueError, match="subject_from does not match"): compute_source_morph(stc_from, subject_from='foo', subjects_dir=subjects_dir) # only one set of vertices with pytest.raises(ValueError, match="grade.*list must have two elements"): compute_source_morph( stc_from, subject_from=subject_from, spacing=[vertices_to[0]], subjects_dir=subjects_dir)
def test_morph_stc_dense(): """Test morphing stc.""" subject_from = 'sample' subject_to = 'fsaverage' stc_from = read_source_estimate(fname_smorph, subject='sample') stc_to = read_source_estimate(fname_fmorph) # make sure we can specify grade stc_from.crop(0.09, 0.1) # for faster computation stc_to.crop(0.09, 0.1) # for faster computation assert_array_equal(stc_to.time_as_index([0.09, 0.1], use_rounding=True), [0, len(stc_to.times) - 1]) # After dep change this to: stc_to1 = compute_source_morph( subject_to=subject_to, spacing=3, smooth=12, src=stc_from, subjects_dir=subjects_dir).apply(stc_from) assert_allclose(stc_to.data, stc_to1.data, atol=1e-5) mean_from = stc_from.data.mean(axis=0) mean_to = stc_to1.data.mean(axis=0) assert np.corrcoef(mean_to, mean_from).min() > 0.999 vertices_to = grade_to_vertices(subject_to, grade=3, subjects_dir=subjects_dir) # make sure we can fill by morphing with pytest.warns(RuntimeWarning, match='consider increasing'): morph = compute_source_morph( stc_from, subject_from, subject_to, spacing=None, smooth=1, subjects_dir=subjects_dir) stc_to5 = morph.apply(stc_from) assert stc_to5.data.shape[0] == 163842 + 163842 # Morph vector data stc_vec = _real_vec_stc() stc_vec_to1 = compute_source_morph( stc_vec, subject_from, subject_to, subjects_dir=subjects_dir, spacing=vertices_to, smooth=1, warn=False).apply(stc_vec) assert stc_vec_to1.subject == subject_to assert stc_vec_to1.tmin == stc_vec.tmin assert stc_vec_to1.tstep == stc_vec.tstep assert len(stc_vec_to1.lh_vertno) == 642 assert len(stc_vec_to1.rh_vertno) == 642 # Degenerate conditions # Morphing to a density that is too high should raise an informative error # (here we need to push to grade=6, but for some subjects even grade=5 # will break) with pytest.raises(ValueError, match='Cannot use icosahedral grade 6 '): compute_source_morph( stc_to1, subject_from=subject_to, subject_to=subject_from, spacing=6, subjects_dir=subjects_dir) del stc_to1 with pytest.raises(ValueError, match='smooth.* has to be at least 1'): compute_source_morph( stc_from, subject_from, subject_to, spacing=5, smooth=-1, subjects_dir=subjects_dir) # subject from mismatch with pytest.raises(ValueError, match="does not match source space subj"): compute_source_morph(stc_from, subject_from='foo', subjects_dir=subjects_dir) # only one set of vertices with pytest.raises(ValueError, match="grade.*list must have two elements"): compute_source_morph( stc_from, subject_from=subject_from, spacing=[vertices_to[0]], subjects_dir=subjects_dir)
def test_morph_data(): """Test morphing of data.""" tempdir = _TempDir() subject_from = 'sample' subject_to = 'fsaverage' stc_from = read_source_estimate(fname_smorph, subject='sample') stc_to = read_source_estimate(fname_fmorph) # make sure we can specify grade stc_from.crop(0.09, 0.1) # for faster computation stc_to.crop(0.09, 0.1) # for faster computation assert_array_equal(stc_to.time_as_index([0.09, 0.1], use_rounding=True), [0, len(stc_to.times) - 1]) morph = SourceMorph(subject_from=subject_from, subject_to=subject_to, spacing=5, smooth=-1, subjects_dir=subjects_dir) # negative smooth pytest.raises(ValueError, morph, stc_from) stc_to1 = SourceMorph(subject_to=subject_to, spacing=3, smooth=12, subjects_dir=subjects_dir)(stc_from) stc_to1.save(op.join(tempdir, '%s_audvis-meg' % subject_to)) # Morphing to a density that is too high should raise an informative error # (here we need to push to grade=6, but for some subjects even grade=5 # will break) morph = SourceMorph(subject_from=subject_to, subject_to=subject_from, spacing=6, subjects_dir=subjects_dir) pytest.raises(ValueError, morph, stc_to1) # make sure we can specify vertices vertices_to = grade_to_vertices(subject_to, grade=3, subjects_dir=subjects_dir) # make sure we get a warning about # of smoothing steps with pytest.warns(RuntimeWarning, match='consider increasing'): SourceMorph(subject_from, subject_to, spacing=vertices_to, smooth=1, subjects_dir=subjects_dir)(stc_from) assert_array_almost_equal(stc_to.data, stc_to1.data, 5) # subject from mismatch morph = SourceMorph(subject_from='foo') pytest.raises(ValueError, morph, stc_from) # only one set of vertices morph = SourceMorph(subject_from=subject_from, spacing=[vertices_to[0]], subjects_dir=subjects_dir) pytest.raises(ValueError, morph, stc_from) # steps warning with pytest.warns(RuntimeWarning, match='steps'): SourceMorph(subject_from=subject_from, subject_to=subject_to, subjects_dir=subjects_dir, smooth=1, spacing=vertices_to)(stc_from) mean_from = stc_from.data.mean(axis=0) mean_to = stc_to1.data.mean(axis=0) assert (np.corrcoef(mean_to, mean_from).min() > 0.999) # make sure we can fill by morphing (deprecation warning) stc_to5 = SourceMorph(subject_from=subject_from, subject_to=subject_to, spacing=None, smooth=12, subjects_dir=subjects_dir)(stc_from) assert (stc_to5.data.shape[0] == 163842 + 163842) # Morph sparse data # Make a sparse stc stc_from.vertices[0] = stc_from.vertices[0][[100, 500]] stc_from.vertices[1] = stc_from.vertices[1][[200]] stc_from._data = stc_from._data[:3] morph = SourceMorph(subject_from=subject_from, subject_to=subject_to, spacing=5, sparse=True, subjects_dir=subjects_dir) # spacing not None # steps warning with pytest.warns(RuntimeWarning, match='steps'): pytest.raises(RuntimeError, morph, stc_from) stc_to_sparse = SourceMorph(subject_from=subject_from, subject_to=subject_to, spacing=None, sparse=True, subjects_dir=subjects_dir)(stc_from) assert_array_almost_equal(np.sort(stc_from.data.sum(axis=1)), np.sort(stc_to_sparse.data.sum(axis=1))) assert len(stc_from.rh_vertno) == len(stc_to_sparse.rh_vertno) assert len(stc_from.lh_vertno) == len(stc_to_sparse.lh_vertno) assert stc_to_sparse.subject == subject_to assert stc_from.tmin == stc_from.tmin assert stc_from.tstep == stc_from.tstep stc_from.vertices[0] = np.array([], dtype=np.int64) stc_from._data = stc_from._data[:1] with pytest.warns(RuntimeWarning, match='steps'): stc_to_sparse = SourceMorph(subject_from=subject_from, subject_to=subject_to, spacing=None, sparse=True, subjects_dir=subjects_dir)(stc_from) assert_array_almost_equal(np.sort(stc_from.data.sum(axis=1)), np.sort(stc_to_sparse.data.sum(axis=1))) assert len(stc_from.rh_vertno) == len(stc_to_sparse.rh_vertno) assert len(stc_from.lh_vertno) == len(stc_to_sparse.lh_vertno) assert stc_to_sparse.subject == subject_to assert stc_from.tmin == stc_from.tmin assert stc_from.tstep == stc_from.tstep # Morph vector data stc_vec = _real_vec_stc() stc_vec_to1 = SourceMorph(subject_from=subject_from, subject_to=subject_to, subjects_dir=subjects_dir, spacing=5, smooth=12)(stc_vec) assert stc_vec_to1.subject == subject_to assert stc_vec_to1.tmin == stc_vec.tmin assert stc_vec_to1.tstep == stc_vec.tstep assert len(stc_vec_to1.lh_vertno) == 10242 assert len(stc_vec_to1.rh_vertno) == 10242
fname_stc = C.fname_STC(C, 'SensitivityMaps', subject, 'SensMap_' + modality + '_' + metric) 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)
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
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