def load_source_morph(self): if self._source_morph is None: try: self._source_morph = mne.read_source_morph( self.source_morph_path) except OSError: self._source_morph = mne.read_source_morph( self.old_source_morph_path) return self._source_morph
def read_morph(mri_subject, morph_to, source_space_spacing, subjects_dir): morph_name = mri_subject + '--to--' + morph_to + '-' + \ source_space_spacing + '-morph.h5' morph_path = join(subjects_dir, mri_subject, morph_name) morph = mne.read_source_morph(morph_path) return morph
def test_surface_vector_source_morph(): """Test surface and vector source estimate morph.""" tempdir = _TempDir() inverse_operator_surf = read_inverse_operator(fname_inv_surf) stc_surf = read_source_estimate(fname_smorph, subject='sample') stc_surf.crop(0.09, 0.1) # for faster computation stc_vec = _real_vec_stc() source_morph_surf = compute_source_morph(inverse_operator_surf['src'], subjects_dir=subjects_dir, smooth=1, warn=False) # smooth 1 for speed assert source_morph_surf.subject_from == 'sample' assert source_morph_surf.subject_to == 'fsaverage' assert source_morph_surf.kind == 'surface' assert isinstance(source_morph_surf.src_data, dict) assert isinstance(source_morph_surf.src_data['vertices_from'], list) assert isinstance(source_morph_surf, SourceMorph) stc_surf_morphed = source_morph_surf.apply(stc_surf) assert isinstance(stc_surf_morphed, SourceEstimate) stc_vec_morphed = source_morph_surf.apply(stc_vec) with pytest.raises(ValueError, match='Only volume source estimates'): source_morph_surf.apply(stc_surf, output='nifti1') # check if correct class after morphing assert isinstance(stc_surf_morphed, SourceEstimate) assert isinstance(stc_vec_morphed, VectorSourceEstimate) # check __repr__ assert 'surface' in repr(source_morph_surf) # check loading and saving for surf source_morph_surf.save(op.join(tempdir, '42.h5')) source_morph_surf_r = read_source_morph(op.join(tempdir, '42.h5')) assert (all([ read == saved for read, saved in zip(sorted(source_morph_surf_r.__dict__), sorted(source_morph_surf.__dict__)) ])) # check wrong subject correction stc_surf.subject = None assert isinstance(source_morph_surf.apply(stc_surf), SourceEstimate) # degenerate stc_vol = read_source_estimate(fname_vol, 'sample') with pytest.raises(ValueError, match='stc_from was type'): source_morph_surf.apply(stc_vol)
def test_surface_vector_source_morph(): """Test surface and vector source estimate morph.""" tempdir = _TempDir() inverse_operator_surf = read_inverse_operator(fname_inv_surf) stc_surf = read_source_estimate(fname_smorph, subject='sample') stc_surf.crop(0.09, 0.1) # for faster computation stc_vec = _real_vec_stc() source_morph_surf = compute_source_morph( inverse_operator_surf['src'], subjects_dir=subjects_dir, smooth=1, warn=False) # smooth 1 for speed assert source_morph_surf.subject_from == 'sample' assert source_morph_surf.subject_to == 'fsaverage' assert source_morph_surf.kind == 'surface' assert isinstance(source_morph_surf.src_data, dict) assert isinstance(source_morph_surf.src_data['vertices_from'], list) assert isinstance(source_morph_surf, SourceMorph) stc_surf_morphed = source_morph_surf.apply(stc_surf) assert isinstance(stc_surf_morphed, SourceEstimate) stc_vec_morphed = source_morph_surf.apply(stc_vec) with pytest.raises(ValueError, match='Only volume source estimates'): source_morph_surf.apply(stc_surf, output='nifti1') # check if correct class after morphing assert isinstance(stc_surf_morphed, SourceEstimate) assert isinstance(stc_vec_morphed, VectorSourceEstimate) # check __repr__ assert 'surface' in repr(source_morph_surf) # check loading and saving for surf source_morph_surf.save(op.join(tempdir, '42.h5')) source_morph_surf_r = read_source_morph(op.join(tempdir, '42.h5')) assert (all([read == saved for read, saved in zip(sorted(source_morph_surf_r.__dict__), sorted(source_morph_surf.__dict__))])) # check wrong subject correction stc_surf.subject = None assert isinstance(source_morph_surf.apply(stc_surf), SourceEstimate) # degenerate stc_vol = read_source_estimate(fname_vol, 'sample') with pytest.raises(ValueError, match='stc_from was type'): source_morph_surf.apply(stc_vol)
def test_surface_vector_source_morph(): """Test surface and vector source estimate morph.""" inverse_operator_surf = read_inverse_operator(fname_inv_surf) stc_surf = read_source_estimate(fname_smorph, subject='sample') stc_surf.crop(0.09, 0.1) # for faster computation stc_vec = _real_vec_stc() source_morph_surf = SourceMorph(subjects_dir=subjects_dir, spacing=[np.arange(10242)] * 2, src=inverse_operator_surf['src']) assert isinstance(source_morph_surf, SourceMorph) assert isinstance( SourceMorph(subjects_dir=subjects_dir)(stc_surf), SourceEstimate) stc_surf_morphed = source_morph_surf(stc_surf) stc_vec_morphed = source_morph_surf(stc_vec) with pytest.raises(ValueError, match='Only volume source estimates'): source_morph_surf.as_volume(stc_surf_morphed) # check if correct class after morphing assert isinstance(stc_surf_morphed, SourceEstimate) assert isinstance(stc_vec_morphed, VectorSourceEstimate) # check __repr__ assert isinstance(source_morph_surf.__repr__(), string_types) # check loading and saving for surf source_morph_surf.save(os.path.join(tempdir, '42.h5')) source_morph_surf_r = read_source_morph(os.path.join(tempdir, '42.h5')) assert (all([ read == saved for read, saved in zip(sorted(source_morph_surf_r.__dict__), sorted(source_morph_surf.__dict__)) ])) # check wrong subject correction stc_surf.subject = None assert isinstance(source_morph_surf(stc_surf), SourceEstimate)
def test_volume_source_morph(tmpdir): """Test volume source estimate morph, special cases and exceptions.""" import nibabel as nib inverse_operator_vol = read_inverse_operator(fname_inv_vol) stc_vol = read_source_estimate(fname_vol_w, 'sample') # check for invalid input type with pytest.raises(TypeError, match='src must be'): compute_source_morph(src=42) # check for raising an error if neither # inverse_operator_vol['src'][0]['subject_his_id'] nor subject_from is set, # but attempting to perform a volume morph src = inverse_operator_vol['src'] assert src._subject is None # already None on disk (old!) with pytest.raises(ValueError, match='subject_from could not be inferred'): with pytest.warns(RuntimeWarning, match='recommend regenerating'): compute_source_morph(src=src, subjects_dir=subjects_dir) # check infer subject_from from src[0]['subject_his_id'] src[0]['subject_his_id'] = 'sample' with pytest.raises(ValueError, match='Inter-hemispheric morphing'): compute_source_morph(src=src, subjects_dir=subjects_dir, xhemi=True) with pytest.raises(ValueError, match='Only surface.*sparse morph'): compute_source_morph(src=src, sparse=True, subjects_dir=subjects_dir) # terrible quality but fast zooms = 20 kwargs = dict(zooms=zooms, niter_sdr=(1,), niter_affine=(1,)) source_morph_vol = compute_source_morph( subjects_dir=subjects_dir, src=fname_inv_vol, subject_from='sample', **kwargs) shape = (13,) * 3 # for the given zooms assert source_morph_vol.subject_from == 'sample' # the brain used in sample data has shape (255, 255, 255) assert tuple(source_morph_vol.sdr_morph.domain_shape) == shape assert tuple(source_morph_vol.pre_affine.domain_shape) == shape # proofs the above assert_array_equal(source_morph_vol.zooms, (zooms,) * 3) # assure proper src shape mri_size = (src[0]['mri_height'], src[0]['mri_depth'], src[0]['mri_width']) assert source_morph_vol.src_data['src_shape_full'] == mri_size fwd = read_forward_solution(fname_fwd_vol) fwd['src'][0]['subject_his_id'] = 'sample' # avoid further warnings source_morph_vol = compute_source_morph( fwd['src'], 'sample', 'sample', subjects_dir=subjects_dir, **kwargs) # check wrong subject_to with pytest.raises(IOError, match='cannot read file'): compute_source_morph(fwd['src'], 'sample', '42', subjects_dir=subjects_dir) # two different ways of saving source_morph_vol.save(tmpdir.join('vol')) # check loading source_morph_vol_r = read_source_morph(tmpdir.join('vol-morph.h5')) # check for invalid file name handling () with pytest.raises(IOError, match='not found'): read_source_morph(tmpdir.join('42')) # check morph stc_vol_morphed = source_morph_vol.apply(stc_vol) # old way, verts do not match assert not np.array_equal(stc_vol_morphed.vertices[0], stc_vol.vertices[0]) # vector stc_vol_vec = VolVectorSourceEstimate( np.tile(stc_vol.data[:, np.newaxis], (1, 3, 1)), stc_vol.vertices, 0, 1) stc_vol_vec_morphed = source_morph_vol.apply(stc_vol_vec) assert isinstance(stc_vol_vec_morphed, VolVectorSourceEstimate) for ii in range(3): assert_allclose(stc_vol_vec_morphed.data[:, ii], stc_vol_morphed.data) # check output as NIfTI assert isinstance(source_morph_vol.apply(stc_vol_vec, output='nifti2'), nib.Nifti2Image) # check for subject_from mismatch source_morph_vol_r.subject_from = '42' with pytest.raises(ValueError, match='subject_from must match'): source_morph_vol_r.apply(stc_vol_morphed) # check if nifti is in grid morph space with voxel_size == spacing img_morph_res = source_morph_vol.apply(stc_vol, output='nifti1') # assure morph spacing assert isinstance(img_morph_res, nib.Nifti1Image) assert img_morph_res.header.get_zooms()[:3] == (zooms,) * 3 # assure src shape img_mri_res = source_morph_vol.apply(stc_vol, output='nifti1', mri_resolution=True) assert isinstance(img_mri_res, nib.Nifti1Image) assert (img_mri_res.shape == (src[0]['mri_height'], src[0]['mri_depth'], src[0]['mri_width']) + (img_mri_res.shape[3],)) # check if nifti is defined resolution with voxel_size == (5., 5., 5.) img_any_res = source_morph_vol.apply(stc_vol, output='nifti1', mri_resolution=(5., 5., 5.)) assert isinstance(img_any_res, nib.Nifti1Image) assert img_any_res.header.get_zooms()[:3] == (5., 5., 5.) # check if morph outputs correct data assert isinstance(stc_vol_morphed, VolSourceEstimate) # check if loaded and saved objects contain the same assert (all([read == saved for read, saved in zip(sorted(source_morph_vol_r.__dict__), sorted(source_morph_vol.__dict__))])) # check __repr__ assert 'volume' in repr(source_morph_vol) # check Nifti2Image assert isinstance( source_morph_vol.apply(stc_vol, mri_resolution=True, mri_space=True, output='nifti2'), nib.Nifti2Image) # Degenerate conditions with pytest.raises(TypeError, match='output must be'): source_morph_vol.apply(stc_vol, output=1) with pytest.raises(ValueError, match='subject_from does not match'): compute_source_morph(src=src, subject_from='42') with pytest.raises(ValueError, match='output'): source_morph_vol.apply(stc_vol, output='42') with pytest.raises(ValueError, match='subject_to cannot be None'): compute_source_morph(src, 'sample', None, subjects_dir=subjects_dir) # Check if not morphed, but voxel size not boolean, raise ValueError. # Note that this check requires dipy to not raise the dipy ImportError # before checking if the actual voxel size error will raise. with pytest.raises(ValueError, match='Cannot infer original voxel size'): stc_vol.as_volume(inverse_operator_vol['src'], mri_resolution=4) stc_surf = read_source_estimate(fname_stc, 'sample') with pytest.raises(TypeError, match='stc_from must be an instance'): source_morph_vol.apply(stc_surf) # src_to source_morph_vol = compute_source_morph( fwd['src'], subject_from='sample', src_to=fwd['src'], subject_to='sample', subjects_dir=subjects_dir, **kwargs) stc_vol_2 = source_morph_vol.apply(stc_vol) # new way, verts match assert_array_equal(stc_vol.vertices[0], stc_vol_2.vertices[0]) stc_vol_bad = VolSourceEstimate( stc_vol.data[:-1], [stc_vol.vertices[0][:-1]], stc_vol.tmin, stc_vol.tstep) match = ( 'vertices do not match between morph \\(4157\\) and stc \\(4156\\).*' '\n.*\n.*\n.*Vertices were likely excluded during forward computatio.*' ) with pytest.raises(ValueError, match=match): source_morph_vol.apply(stc_vol_bad)
def test_volume_source_morph(): """Test volume source estimate morph, special cases and exceptions.""" import nibabel as nib tempdir = _TempDir() inverse_operator_vol = read_inverse_operator(fname_inv_vol) stc_vol = read_source_estimate(fname_vol, 'sample') # check for invalid input type with pytest.raises(TypeError, match='src must be an instance of'): compute_source_morph(src=42) # check for raising an error if neither # inverse_operator_vol['src'][0]['subject_his_id'] nor subject_from is set, # but attempting to perform a volume morph src = inverse_operator_vol['src'] src[0]['subject_his_id'] = None with pytest.raises(ValueError, match='subject_from could not be inferred'): compute_source_morph(src=src, subjects_dir=subjects_dir) # check infer subject_from from src[0]['subject_his_id'] src[0]['subject_his_id'] = 'sample' with pytest.raises(ValueError, match='Inter-hemispheric morphing'): compute_source_morph(src=src, subjects_dir=subjects_dir, xhemi=True) with pytest.raises(ValueError, match='Only surface.*sparse morph'): compute_source_morph(src=src, sparse=True, subjects_dir=subjects_dir) # terrible quality buts fast zooms = 20 kwargs = dict(zooms=zooms, niter_sdr=(1,), niter_affine=(1,)) source_morph_vol = compute_source_morph( subjects_dir=subjects_dir, src=inverse_operator_vol['src'], **kwargs) shape = (13,) * 3 # for the given zooms assert source_morph_vol.subject_from == 'sample' # the brain used in sample data has shape (255, 255, 255) assert tuple(source_morph_vol.sdr_morph.domain_shape) == shape assert tuple(source_morph_vol.pre_affine.domain_shape) == shape # proofs the above assert_array_equal(source_morph_vol.zooms, (zooms,) * 3) # assure proper src shape mri_size = (src[0]['mri_height'], src[0]['mri_depth'], src[0]['mri_width']) assert source_morph_vol.src_data['src_shape_full'] == mri_size fwd = read_forward_solution(fname_fwd_vol) source_morph_vol = compute_source_morph( fwd['src'], 'sample', 'sample', subjects_dir=subjects_dir, **kwargs) # check wrong subject_to with pytest.raises(IOError, match='cannot read file'): compute_source_morph(fwd['src'], 'sample', '42', subjects_dir=subjects_dir) # two different ways of saving source_morph_vol.save(op.join(tempdir, 'vol')) # check loading source_morph_vol_r = read_source_morph( op.join(tempdir, 'vol-morph.h5')) # check for invalid file name handling () with pytest.raises(IOError, match='not found'): read_source_morph(op.join(tempdir, '42')) # check morph stc_vol_morphed = source_morph_vol.apply(stc_vol) # check output as NIfTI assert isinstance(source_morph_vol.apply(stc_vol, output='nifti2'), nib.Nifti2Image) # check for subject_from mismatch source_morph_vol_r.subject_from = '42' with pytest.raises(ValueError, match='subject_from must match'): source_morph_vol_r.apply(stc_vol_morphed) # check if nifti is in grid morph space with voxel_size == spacing img_morph_res = source_morph_vol.apply(stc_vol, output='nifti1') # assure morph spacing assert isinstance(img_morph_res, nib.Nifti1Image) assert img_morph_res.header.get_zooms()[:3] == (zooms,) * 3 # assure src shape img_mri_res = source_morph_vol.apply(stc_vol, output='nifti1', mri_resolution=True) assert isinstance(img_mri_res, nib.Nifti1Image) assert (img_mri_res.shape == (src[0]['mri_height'], src[0]['mri_depth'], src[0]['mri_width']) + (img_mri_res.shape[3],)) # check if nifti is defined resolution with voxel_size == (5., 5., 5.) img_any_res = source_morph_vol.apply(stc_vol, output='nifti1', mri_resolution=(5., 5., 5.)) assert isinstance(img_any_res, nib.Nifti1Image) assert img_any_res.header.get_zooms()[:3] == (5., 5., 5.) # check if morph outputs correct data assert isinstance(stc_vol_morphed, VolSourceEstimate) # check if loaded and saved objects contain the same assert (all([read == saved for read, saved in zip(sorted(source_morph_vol_r.__dict__), sorted(source_morph_vol.__dict__))])) # check __repr__ assert 'volume' in repr(source_morph_vol) # check Nifti2Image assert isinstance( source_morph_vol.apply(stc_vol, mri_resolution=True, mri_space=True, output='nifti2'), nib.Nifti2Image) # Degenerate conditions with pytest.raises(TypeError, match='output must be'): source_morph_vol.apply(stc_vol, output=1) with pytest.raises(ValueError, match='subject_from does not match'): compute_source_morph(src=src, subject_from='42') with pytest.raises(ValueError, match='output must be one of'): source_morph_vol.apply(stc_vol, output='42') with pytest.raises(TypeError, match='subject_to must'): compute_source_morph(src, 'sample', None, subjects_dir=subjects_dir) # Check if not morphed, but voxel size not boolean, raise ValueError. # Note that this check requires dipy to not raise the dipy ImportError # before checking if the actual voxel size error will raise. with pytest.raises(ValueError, match='Cannot infer original voxel size'): stc_vol.as_volume(inverse_operator_vol['src'], mri_resolution=4)
subjects_dir = PATHfrom + 'freesurfersubjects' #for the NT group X_sum = [] for subject in SUBJ_NT: subjpath = PATHfrom + 'SUBJECTS/' + subject + '/ICA_nonotch_crop/epochs/' savepath = myPATH + 'Results_Alpha_and_Gamma/' #load stcs sum_csp = mne.read_source_estimate(savepath + '1_results/CSP_sum/' + subject + 'sum_CSP_97_102_diff_V3-V1_new') #Setting up SourceMorph for SourceEstimate morph = mne.read_source_morph(savepath + '1_results/morph_CSP/' + subject + 'CSP-morph.h5') #Apply morph to SourceEstimate sum_csp_fsaverage = morph.apply(sum_csp) # if sum_csp_fsaverage.shape[1]>5: # X_sum.append(sum_csp_fsaverage.data[:,1:6]) # else: X_sum.append(sum_csp_fsaverage.data) #average across freqs and subjects X = np.asarray(X_sum) X_avg_freq = np.mean(X, axis=2) X_avg_group = np.mean(X_avg_freq, axis=0) X_avg = X_avg_group[:, np.newaxis]
PATHfrom = '/net/server/data/Archive/aut_gamma/orekhova/KI/' myPATH = '/net/server/data/Archive/aut_gamma/orekhova/KI/Scripts_bkp/Shishkina/KI/' subjects_dir = PATHfrom + 'freesurfersubjects' for subject in SUBJ_ASD: subjpath = PATHfrom + 'SUBJECTS/' + subject + '/ICA_nonotch_crop/epochs/' savepath = myPATH + 'Results_Alpha_and_Gamma/' #load stcs stc_slow = mne.read_source_estimate(savepath + subject + '/' + subject + 'meg_slow_isi_2_40Hz') stc_fast = mne.read_source_estimate(savepath + subject + '/' + subject + 'meg_fast_isi_2_40Hz') #Setting up SourceMorph for SourceEstimate morph = mne.read_source_morph(savepath + subject + '/' + subject + 'morph_2_40-morph.h5') #Apply morph to SourceEstimate stc_fsaverage_slow = morph.apply(stc_slow) stc_fsaverage_fast = morph.apply(stc_fast) stc_fsaverage_diff = stc_fsaverage_slow stc_fsaverage_diff.data = stc_fsaverage_fast.data - stc_fsaverage_slow.data n_vertices_fsave, n_times = stc_fsaverage_slow.data.shape n_subjects = len(SUBJ_ASD) # Let's make sure our results replicate, so set the seed. np.random.seed(0) X1 = np.random.randn(n_vertices_fsave, n_times, n_subjects) X1[:, :, :] += stc_fsaverage_diff.data[:, :, np.newaxis] for subject in SUBJ_NT:
ExpID = 'SF' useFsaveModel = 'oct6' # load epoch data to get information os.chdir(filedir+'/'+SubjID+'/'+ExpID+'/Datafiles/EpochData') Epochs = mne.read_epochs('ProperEpochData-epo.fif', preload=True) epochs = Epochs.copy().pick_types(meg=True) del Epochs conditions = list(epochs.event_id.keys()) conditions2 = [i for i in conditions if i != 'target'] del epochs # load SourceMorph instance morph = mne.read_source_morph(filedir+'/'+SubjID+'/SrcMorph_%stoFsaverage%s-morph.h5' % (SubjID, useFsaveModel.capitalize())) #- directory manipulation -# savedir = filedir+'/'+SubjID+'/'+ExpID+'/Datafiles/SourceEstimate/SurfSrcEst_dSPM_forEvoked' os.chdir(savedir) if not os.path.exists('./Fsaverage_%s' % useFsaveModel): os.mkdir('./Fsaverage_%s' % useFsaveModel) # do morphing print('\n<< Morph individual stc data to decimated fsaverage >>') nRep = 0 for cond in conditions2: print('< Processing %s condition data >' % (cond.replace('_','-')))
inv_sol.sort() morph_path = op.join(subject_meg, "{}-morph.h5".format(subject)) file_list.append( tuple(list(list(zip(inv_sol, all_epochs))[0]) + [morph_path])) file_list.append( tuple(list(list(zip(inv_sol, all_epochs))[1]) + [morph_path])) inv_path, epo_path, morph_path = file_list[index] print(inv_path) print(epo_path) print(morph_path) # read files inv = mne.minimum_norm.read_inverse_operator(inv_path) morph = mne.read_source_morph(morph_path) epochs = mne.read_epochs(epo_path, preload=True) atlas_labels = pd.read_csv(atlas_csv) # label selection labels = mne.read_labels_from_annot(subjects_dir=subjects_dir, parc="hcp-mmp-b", hemi="both", subject="fsaverage") # processing trial_order = epochs.events[:, 2] names = [i.name[:-7] for i in labels] epochs = epochs.apply_baseline((-0.1, 0.0))
for stc in stcs_cont: stc.data[:, :] = np.abs(stc.data) with warnings.catch_warnings(): warnings.simplefilter('ignore') stc.data = np.array(stc.data, 'float64') for stc in stcs_break: stc.data[:, :] = np.abs(stc.data) with warnings.catch_warnings(): warnings.simplefilter('ignore') stc.data = np.array(stc.data, 'float64') # average across epochs per condition mean_cont = np.mean([stc.data for stc in stcs_cont], axis=0) mean_break = np.mean([stc.data for stc in stcs_break], axis=0) mean_diff = mean_cont - mean_break # now make stcs and morph to fsaverage for GA collection morph = mne.read_source_morph("{}{}_fs_vol-morph.h5".format(meg_dir,meg)) stc_c = stcs_cont[0].copy() stc_c.data = mean_cont stc_fs_c = morph.apply(stc_c) stc_fs_c.save("{}{}alpha_source_env_cont".format(meg_dir,meg)) GA_cont.append(stc_fs_c) stc_b = stcs_cont[0].copy() stc_b.data = mean_break stc_fs_b = morph.apply(stc_b) stc_fs_b.save("{}{}alpha_source_env_break".format(meg_dir,meg)) GA_break.append(stc_fs_b) stc_d = stcs_cont[0].copy() stc_d.data = mean_diff stc_fs_d = morph.apply(stc_d) stc_fs_d.save("{}{}alpha_source_env_diff".format(meg_dir,meg)) GA_diff.append(stc_fs_d)
def test_volume_source_morph(): """Test volume source estimate morph, special cases and exceptions.""" import nibabel as nib data_path = sample.data_path( download=False) # because testing data has no brain.mgz subjects_dir = os.path.join(data_path, 'subjects') sample_dir = os.path.join(data_path, 'MEG', 'sample') fname_inv_vol = os.path.join(sample_dir, 'sample_audvis-meg-vol-7-meg-inv.fif') inverse_operator_vol = read_inverse_operator(fname_inv_vol) stc_vol = read_source_estimate(fname_vol, 'sample') # check for invalid input type with pytest.raises(ValueError, match='src must be an instance of'): SourceMorph(src=42) # check for raising an error if neither # inverse_operator_vol['src'][0]['subject_his_id'] nor subject_from is set, # but attempting to perform a volume morph src = inverse_operator_vol['src'] src[0]['subject_his_id'] = None with pytest.raises(ValueError, match='subject_from is None.'): SourceMorph(src=src, subjects_dir=subjects_dir) # check infer subject_from from src[0]['subject_his_id'] src[0]['subject_his_id'] = 'sample' with pytest.raises(ValueError, match='Inter-hemispheric morphing'): SourceMorph(src=src, subjects_dir=subjects_dir, xhemi=True) with pytest.raises(ValueError, match='Only surface'): SourceMorph(src=src, sparse=True) source_morph_vol = SourceMorph(subjects_dir=subjects_dir, src=inverse_operator_vol['src'], niter_affine=(1, ), niter_sdr=(1, ), spacing=7) assert source_morph_vol.subject_from == 'sample' # the brain used in sample data has shape (255, 255, 255) assert (tuple( source_morph_vol.params['DiffeomorphicMap']['domain_shape']) == (37, 37, 37)) assert (tuple( source_morph_vol.params['AffineMap']['domain_shape']) == (37, 37, 37)) # proofs the above assert source_morph_vol.spacing == 7 # assure proper src shape assert source_morph_vol.params['src_shape_full'] == (src[0]['mri_height'], src[0]['mri_depth'], src[0]['mri_width']) fwd = read_forward_solution( os.path.join(sample_dir, 'sample_audvis-meg-vol-7-fwd.fif')) # check input via path to src and path to subject_to source_morph_vol = SourceMorph(subject_from='sample', subject_to=os.path.join( data_path, 'subjects', 'fsaverage', 'mri', 'brain.mgz'), subjects_dir=subjects_dir, niter_affine=(1, ), src=fwd['src'], niter_sdr=(1, ), spacing=7) # check wrong subject_to with pytest.raises(IOError, match='cannot read file'): SourceMorph(subject_from='sample', subject_to='42', subjects_dir=subjects_dir, src=fwd['src']) # two different ways of saving source_morph_vol.save(os.path.join(tempdir, 'vol')) # check loading source_morph_vol_r = read_source_morph( os.path.join(tempdir, 'vol-morph.h5')) # check for invalid file name handling () with pytest.raises(IOError, match='not found'): read_source_morph(os.path.join(tempdir, '42')) # check morph stc_vol_morphed = source_morph_vol(stc_vol) # check as_volume=True assert isinstance(source_morph_vol(stc_vol, as_volume=True), nib.Nifti1Image) # check for subject_from mismatch source_morph_vol_r.subject_from = '42' with pytest.raises(ValueError, match='subject_from must match'): source_morph_vol_r(stc_vol_morphed) # check if nifti is in grid morph space with voxel_size == spacing img_morph_res = source_morph_vol.as_volume(stc_vol_morphed, mri_resolution=False) # assure morph spacing assert isinstance(img_morph_res, nib.Nifti1Image) assert img_morph_res.header.get_zooms()[:3] == (7., 7., 7.) # assure src shape img_mri_res = source_morph_vol.as_volume(stc_vol_morphed, mri_resolution=True) assert isinstance(img_mri_res, nib.Nifti1Image) assert (img_mri_res.shape == (src[0]['mri_height'], src[0]['mri_depth'], src[0]['mri_width']) + (img_mri_res.shape[3], )) # check if nifti is defined resolution with voxel_size == (5., 5., 5.) img_any_res = source_morph_vol.as_volume(stc_vol_morphed, mri_resolution=(5., 5., 5.), fname=os.path.join(tempdir, '42')) assert isinstance(img_any_res, nib.Nifti1Image) assert img_any_res.header.get_zooms()[:3] == (5., 5., 5.) # check if morph outputs correct data assert isinstance(stc_vol_morphed, VolSourceEstimate) # check if loaded and saved objects contain the same assert (all([ read == saved for read, saved in zip(sorted(source_morph_vol_r.__dict__), sorted(source_morph_vol.__dict__)) ])) # check __repr__ assert isinstance(source_morph_vol.__repr__(), string_types) # check Nifti2Image assert isinstance( source_morph_vol.as_volume(stc_vol_morphed, mri_resolution=True, mri_space=True, format='nifti2'), nib.Nifti2Image) with pytest.raises(ValueError, match='subject_from does not match'): SourceMorph(src=src, subject_from='42') # check wrong format with pytest.raises(ValueError, match='invalid format specifier'): source_morph_vol.as_volume(stc_vol_morphed, format='42') with pytest.raises(ValueError, match='invalid format specifier'): stc_vol_morphed.as_volume(inverse_operator_vol['src'], format='42')
def test_volume_source_morph_round_trip( tmpdir, subject_from, subject_to, lower, upper, dtype, morph_mat, monkeypatch): """Test volume source estimate morph round-trips well.""" import nibabel as nib from nibabel.processing import resample_from_to src = dict() if morph_mat: # ~1.5 minutes with pos=7. (4157 morphs!) for sample, so only test # morph_mat computation mode with a few labels label_names = sorted(get_volume_labels_from_aseg(fname_aseg))[1:2] if 'sample' in (subject_from, subject_to): src['sample'] = setup_volume_source_space( 'sample', subjects_dir=subjects_dir, volume_label=label_names, mri=fname_aseg) assert sum(s['nuse'] for s in src['sample']) == 12 if 'fsaverage' in (subject_from, subject_to): src['fsaverage'] = setup_volume_source_space( 'fsaverage', subjects_dir=subjects_dir, volume_label=label_names[:3], mri=fname_aseg_fs) assert sum(s['nuse'] for s in src['fsaverage']) == 16 else: assert not morph_mat if 'sample' in (subject_from, subject_to): src['sample'] = mne.read_source_spaces(fname_vol) src['sample'][0]['subject_his_id'] = 'sample' assert src['sample'][0]['nuse'] == 4157 if 'fsaverage' in (subject_from, subject_to): # Created to save space with: # # bem = op.join(op.dirname(mne.__file__), 'data', 'fsaverage', # 'fsaverage-inner_skull-bem.fif') # src_fsaverage = mne.setup_volume_source_space( # 'fsaverage', pos=7., bem=bem, mindist=0, # subjects_dir=subjects_dir, add_interpolator=False) # mne.write_source_spaces(fname_fs_vol, src_fsaverage, # overwrite=True) # # For speed we do it without the interpolator because it's huge. src['fsaverage'] = mne.read_source_spaces(fname_fs_vol) src['fsaverage'][0].update( vol_dims=np.array([23, 29, 25]), seg_name='brain') _add_interpolator(src['fsaverage']) assert src['fsaverage'][0]['nuse'] == 6379 src_to, src_from = src[subject_to], src[subject_from] del src # No SDR just for speed once everything works kwargs = dict(niter_sdr=(), niter_affine=(1,), subjects_dir=subjects_dir, verbose=True) morph_from_to = compute_source_morph( src=src_from, src_to=src_to, subject_to=subject_to, **kwargs) morph_to_from = compute_source_morph( src=src_to, src_to=src_from, subject_to=subject_from, **kwargs) nuse = sum(s['nuse'] for s in src_from) assert nuse > 10 use = np.linspace(0, nuse - 1, 10).round().astype(int) data = np.eye(nuse)[:, use] if dtype is complex: data = data * 1j vertices = [s['vertno'] for s in src_from] stc_from = VolSourceEstimate(data, vertices, 0, 1) with catch_logging() as log: stc_from_rt = morph_to_from.apply( morph_from_to.apply(stc_from, verbose='debug')) log = log.getvalue() assert 'individual volume morph' in log maxs = np.argmax(stc_from_rt.data, axis=0) src_rr = np.concatenate([s['rr'][s['vertno']] for s in src_from]) dists = 1000 * np.linalg.norm(src_rr[use] - src_rr[maxs], axis=1) mu = np.mean(dists) # fsaverage=5.99; 7.97 without additional src_ras_t fix # fsaverage=7.97; 25.4 without src_ras_t fix assert lower <= mu < upper, f'round-trip distance {mu}' # check that pre_affine is close to identity when subject_to==subject_from if subject_to == subject_from: for morph in (morph_to_from, morph_from_to): assert_allclose( morph.pre_affine.affine, np.eye(4), atol=1e-2) # check that power is more or less preserved (labelizing messes with this) if morph_mat: if subject_to == 'fsaverage': limits = (18, 18.5) else: limits = (7, 7.5) else: limits = (1, 1.2) stc_from_unit = stc_from.copy().crop(0, 0) stc_from_unit._data.fill(1.) stc_from_unit_rt = morph_to_from.apply(morph_from_to.apply(stc_from_unit)) assert_power_preserved(stc_from_unit, stc_from_unit_rt, limits=limits) if morph_mat: fname = tmpdir.join('temp-morph.h5') morph_to_from.save(fname) morph_to_from = read_source_morph(fname) assert morph_to_from.vol_morph_mat is None morph_to_from.compute_vol_morph_mat(verbose=True) morph_to_from.save(fname, overwrite=True) morph_to_from = read_source_morph(fname) assert isinstance(morph_to_from.vol_morph_mat, csr_matrix), 'csr' # equivalence (plus automatic calling) assert morph_from_to.vol_morph_mat is None monkeypatch.setattr(mne.morph, '_VOL_MAT_CHECK_RATIO', 0.) with catch_logging() as log: with pytest.warns(RuntimeWarning, match=r'calling morph\.compute'): stc_from_rt_lin = morph_to_from.apply( morph_from_to.apply(stc_from, verbose='debug')) assert isinstance(morph_from_to.vol_morph_mat, csr_matrix), 'csr' log = log.getvalue() assert 'sparse volume morph matrix' in log assert_allclose(stc_from_rt.data, stc_from_rt_lin.data) del stc_from_rt_lin stc_from_unit_rt_lin = morph_to_from.apply( morph_from_to.apply(stc_from_unit)) assert_allclose(stc_from_unit_rt.data, stc_from_unit_rt_lin.data) del stc_from_unit_rt_lin del stc_from, stc_from_rt # before and after morph, check the proportion of vertices # that are inside and outside the brainmask.mgz brain = nib.load(op.join(subjects_dir, subject_from, 'mri', 'brain.mgz')) mask = _get_img_fdata(brain) > 0 if subject_from == subject_to == 'sample': for stc in [stc_from_unit, stc_from_unit_rt]: img = stc.as_volume(src_from, mri_resolution=True) img = nib.Nifti1Image( # abs to convert complex np.abs(_get_img_fdata(img)[:, :, :, 0]), img.affine) img = _get_img_fdata(resample_from_to(img, brain, order=1)) assert img.shape == mask.shape in_ = img[mask].astype(bool).mean() out = img[~mask].astype(bool).mean() if morph_mat: out_max = 0.001 in_min, in_max = 0.005, 0.007 else: out_max = 0.02 in_min, in_max = 0.97, 0.98 assert out < out_max, f'proportion out of volume {out}' assert in_min < in_ < in_max, f'proportion inside volume {in_}'
epo = mne.read_epochs("{}{}-epo.fif".format(proc_dir, meg)) fwd = mne.read_forward_solution("{}{}-fwd.fif".format(proc_dir, meg)) # load filters for DICS beamformer filters = mne.beamformer.read_beamformer('{}{}-gamma-dics.h5'.format( proc_dir, meg)) # load CSDs for conditions to compare, apply filters csd_a = mne.time_frequency.read_csd("{}{}_{}-gamma-csd.h5".format( proc_dir, meg, cond_a)) csd_b = mne.time_frequency.read_csd("{}{}_{}-gamma-csd.h5".format( proc_dir, meg, cond_b)) stc_a, freqs_a = mne.beamformer.apply_dics_csd(csd_a.mean(65, 95), filters) stc_b, freqs_b = mne.beamformer.apply_dics_csd(csd_b.mean(65, 95), filters) # calculate the difference between conditions stc_diff = (stc_a - stc_b) / stc_b # morph diff to fsaverage morph = mne.read_source_morph("{}{}_fs_mix-morph.h5".format(proc_dir, meg)) stc_fs_diff = morph.apply(stc_diff) all_diff.append(stc_fs_diff) X_diff_s.append(stc_fs_diff.surface().data.T) X_diff_v.append(stc_fs_diff.volume().data.T) # create STC grand average for plotting stc_sum = all_diff.pop() for stc in all_diff: stc_sum = stc_sum + stc GA_stc_diff = stc_sum / len(sub_dict) # plot difference on fsaverage mixed source space # brain = GA_stc_diff.plot(subjects_dir=mri_dir,subject='fsaverage',surface='white',hemi='both',src=fs_src) # brain.add_annotation('aparc', borders=1, alpha=0.9) # now do cluster permutation analysis on all frequencies
# load leadfield matrix fwdfile = [i for i in os.listdir(os.getcwd()) if 'forSrcEst-fwd.fif' in i and 'SurfaceSourceSpace' in i][0] fwd = mne.read_forward_solution(fwdfile) fwd = mne.convert_forward_solution(fwd, surf_ori=True, force_fixed=False) #--- get MRI data ---# # get MRI subject name MRIsubject = '' # set directory name of MRI data subjects_dir = '' # load SourceMorph instance (fsaverage ico5) morph = mne.read_source_morph(filedir+'/'+SubjID+'/SrcMorph_%stoFsaverage-morph.h5' % SubjID) #%% #--- Source estimation by dSPM ---# os.chdir(savedir) for name in ['IndivBrain', 'Fsaverage']: if not os.path.exists('./'+name): os.mkdir('./'+name) del name preTmin = -0.1 preTmax = 0 conditions2 = [i for i in conditions if i != 'target'] epochs_basecorred = epochs[conditions2].copy().apply_baseline(baseline=(preTmin, preTmax))