def get_spinp(x, y, corrval, nspin, lhannot, rhannot, corrtype): surf_path = ('/home/gshafiei/data2/Projects/HCP_MEG/' + 'parcellationData/common/') surfaces = [ surf_path + 'L.sphere.32k_fs_LR.surf.gii', surf_path + 'R.sphere.32k_fs_LR.surf.gii' ] lhannot = lhannot rhannot = rhannot centroids, hemiid = spin_conte69.get_gifti_centroids( surfaces, lhannot, rhannot) spins, cost = netneurostats.gen_spinsamples(centroids, hemiid, n_rotate=nspin, seed=272) permuted_r = np.zeros((nspin, 1)) for spin in range(nspin): if corrtype == 'spearman': permuted_r[spin] = scipy.stats.spearmanr(x[spins[:, spin]], y)[0] elif corrtype == 'pearson': permuted_r[spin] = scipy.stats.pearsonr(x[spins[:, spin]], y)[0] permmean = np.mean(permuted_r) pvalspin = (len( np.where(abs(permuted_r - permmean) >= abs(corrval - permmean))[0]) + 1) / (nspin + 1) return pvalspin
def hungarian(y, parcellation, scale, fn=None): y = np.asarray(y) if USE_CACHED and fn is not None: spins = simnulls.load_spins(fn, n_perm=N_PERM) else: annot = _get_annot(parcellation, scale) coords, hemi = nnsurf.find_parcel_centroids(lhannot=annot.lh, rhannot=annot.rh, version='fsaverage5', surf='sphere', method='surface') spins = nnstats.gen_spinsamples(coords, hemi, method='hungarian', n_rotate=N_PERM, seed=SEED) return y[spins]
def get_spinidx(nspin, lhannot, rhannot): surf_path = ('/home/gshafiei/data2/Projects/HCP_MEG/' + 'parcellationData/common/') surfaces = [ surf_path + 'L.sphere.32k_fs_LR.surf.gii', surf_path + 'R.sphere.32k_fs_LR.surf.gii' ] lhannot = lhannot rhannot = rhannot centroids, hemiid = spin_conte69.get_gifti_centroids( surfaces, lhannot, rhannot) spins, cost = netneurostats.gen_spinsamples(centroids, hemiid, n_rotate=nspin, seed=272) return spins
def vazquez_rodriguez(y, parcellation, scale, fn=None): y = np.asarray(y) if USE_CACHED and fn is not None: spins = simnulls.load_spins(fn, n_perm=N_PERM) else: if parcellation != 'vertex': annot = _get_annot(parcellation, scale) coords, hemi = nnsurf.find_parcel_centroids(lhannot=annot.lh, rhannot=annot.rh, version='fsaverage5', surf='sphere', method='surface') else: coords, hemi = nnsurf._get_fsaverage_coords(scale, 'sphere') spins = nnstats.gen_spinsamples(coords, hemi, method='original', n_rotate=N_PERM, seed=SEED) return y[spins]
def generate_spins(parcel, lhannot, rhannot, order, info_path, hemi='', k=10000): ''' Function to generate spun permutation of a parcellation's parcels. ''' # Generate the spins coords, hemi_centroids = find_parcel_centroids(lhannot=lhannot, rhannot=rhannot) spins_LR = gen_spinsamples(coords, hemi_centroids, n_rotate=k) # Get some info about hemispheres and subcortex hemi_info = load_data._load_hemi_info(parcel, info_path) sub_info = load_data._load_subcortex_info(parcel, info_path) # Remove subcortex info from hemi_info (spins are only on the surface) hemi_info = np.delete(hemi_info, sub_info) R_id = np.where(hemi_info == 0)[0] L_id = np.where(hemi_info == 1)[0] n_R = len(R_id) n_L = len(L_id) # If order is RL, we must invert the order of the spun annotations if order == 'RL': spins = np.zeros((spins_LR.shape)) spins[R_id, :] = (spins_LR[np.where(hemi_centroids == 1)[0], :] - n_L) spins[L_id, :] = (spins_LR[np.where(hemi_centroids == 0)[0], :] + n_R) elif order == 'LR': spins = spins_LR # Only keep the information about the hemisphere we want if hemi == "L": if order == 'RL': spins = spins[np.where(hemi_info == 1)[0], :] - n_R elif order == 'LR': spins = spins[np.where(hemi_info == 1)[0], :] elif hemi == 'R': if order == 'RL': spins = spins[np.where(hemi_info == 0)[0], :] elif order == 'LR': spins = spins[np.where(hemi_info == 1)[0], :] - n_L spins = spins.astype(int) return spins
def generate_dist(annot): """ Parameters ---------- annot : (2,) namedtuple With entries ('lh', 'rh') corresponding to annotation files for specified hemisphere for `fsaverage5` resolution Returns ------- dist : (90, 90) np.ndarray Distance matrix for resamplings from different null frameworks and parcel centroid definition methods """ # generate spins for all the parcel-based rotation methods using # three different methods for generating parcel centroid estimates orig_spins, vasa_spins, hung_spins = [], [], [] for sptype, spins in zip(['original', 'vasa', 'hungarian'], [orig_spins, vasa_spins, hung_spins]): for method in ['average', 'surface', 'geodesic']: # get parcel centroids using specified centroid method coords, hemi = nnsurf.find_parcel_centroids(lhannot=annot.lh, rhannot=annot.rh, version='fsaverage5', method=method) # generate 10 spin resamples for specified spin method out = nnstats.gen_spinsamples(coords, hemi, n_rotate=10, method=sptype, seed=1234) spins.append(out) # stack and transpose for easy distance calculation all_spins = np.row_stack( (np.column_stack(orig_spins).T, np.column_stack(vasa_spins).T, np.column_stack(hung_spins).T)) all_dist = cdist(all_spins, all_spins, metric='hamming') return all_dist
def test_gen_spinsamples(): # grab a few points from a spherical surface and duplicate it for the # "other hemisphere" coords = [_get_sphere_coords(s, t, r=1) for s, t in itertools.product(range(0, 360, 45), range(0, 360, 45))] coords = np.row_stack([coords, coords]) hemi = np.hstack([np.zeros(len(coords) // 2), np.ones(len(coords) // 2)]) # generate "normal" test spins spins, cost = stats.gen_spinsamples(coords, hemi, n_rotate=10, seed=1234, return_cost=True) assert spins.shape == (len(coords), 10) assert cost.shape == (len(coords), 10) # confirm that `exact` parameter functions as desired for method in ['vasa', 'hungarian']: spin_exact, cost_exact = stats.gen_spinsamples(coords, hemi, n_rotate=10, seed=1234, method=method, return_cost=True) assert spin_exact.shape == (len(coords), 10) assert cost.shape == (len(coords), 10) for s in spin_exact.T: assert len(np.unique(s)) == len(s) # confirm that check_duplicates will raise warnings # since spins aren't exact permutations we need to use 4C4 with repeats # and then perform one more rotation than that number (i.e., 35 + 1) with pytest.warns(UserWarning): i = [0, 1, -2, -1] # only grab a few coordinates stats.gen_spinsamples(coords[i], hemi[i], n_rotate=36, seed=1234) # non-3D coords with pytest.raises(ValueError): stats.gen_spinsamples(coords[:, :2], hemi) # non-1D hemi with pytest.raises(ValueError): stats.gen_spinsamples(coords, np.column_stack([hemi, hemi])) # different length coords and hemi with pytest.raises(ValueError): stats.gen_spinsamples(coords, hemi[:-1]) # only one hemisphere # TODO: should this be allowed? with pytest.raises(ValueError): stats.gen_spinsamples(coords[hemi == 0], hemi[hemi == 0])
# well as a vector identifying to which hemisphere each parcel belongs # (`hemi`): from netneurotools import freesurfer coords, hemi = freesurfer.find_fsaverage_centroids(lhannot, rhannot) print(coords.shape, hemi.shape) ############################################################################### # We'll use these coordinates to generate a resampling array based on this idea # of a "rotation"-based null model. As an example we'll only generate 1000 # rotations (i.e., permutations), but you can easily generate more by changing # the `n_rotate` parameter. Since these rotations are random we can set a # `seed` to ensure reproducibility: from netneurotools import stats spin, cost = stats.gen_spinsamples(coords, hemi, n_rotate=1000, seed=1234) print(spin.shape) ############################################################################### # The function returns both a resampling array (`spins`) as well as a cost # vector (`cost`) detailing the average distance between each rotated parcel # and the one to which it was matched. # # We'll use `spins` to resample one of our data vectors and regenerate the # correlations: import numpy as np r_spinperm = np.zeros((spin.shape[-1], )) for perm in range(spin.shape[-1]): r_spinperm[perm] = pearsonr(x[spin[:, perm]], y)[0]
# mass univariate comparison #################################### # Pearson r X = node_score[:, :2] Y = stats.zscore(featMat) rho = np.zeros((X.shape[1], Y.shape[1])) for i in range(X.shape[1]): for j in range(Y.shape[1]): tmpcorr = scipy.stats.pearsonr(X[:, i], Y[:, j]) rho[i, j] = tmpcorr[0] # spin tests centroids, hemiid = spin_conte69.get_gifti_centroids(surfaces, lhlabels, rhlabels) spins, cost = netneurostats.gen_spinsamples(centroids, hemiid, n_rotate=10000, seed=272) n_spins = spins.shape[1] rhoPerm = np.zeros((X.shape[1], Y.shape[1], n_spins)) for spin in range(n_spins): for i in range(X.shape[1]): for j in range(Y.shape[1]): rhoPerm[i, j, spin] = scipy.stats.pearsonr( X[spins[:, spin], i], Y[:, j])[0] pvalPerm = np.zeros((X.shape[1], Y.shape[1])) corrected_pval = np.zeros((X.shape[1], Y.shape[1])) sigidx = [] nonsigidx = [] for comp in range(X.shape[1]):
# data itself, but we _can_ use the above vertex-level spins for that for name, annotations in parcellations.items(): print(f'PARCELLATION: {name}') for scale, annot in annotations.items(): coords, hemi = nnsurf.find_parcel_centroids(lhannot=annot.lh, rhannot=annot.rh, version='fsaverage5', surf='sphere', method='surface') spin_fn = f'{scale}_spins.csv' fname = SPINDIR / name / 'vazquez-rodriguez' / spin_fn if not fname.exists(): print(f'Generating V-R spins for {scale}') spins = nnstats.gen_spinsamples(coords, hemi, exact=False, n_rotate=10000, verbose=True, check_duplicates=False, seed=1234) putils.save_dir(fname, spins) fname = SPINDIR / name / 'vasa' / spin_fn if not fname.exists(): print(f'Generating Vasa spins for {scale}') spins = nnstats.gen_spinsamples(coords, hemi, exact='vasa', n_rotate=10000, verbose=True, check_duplicates=False, seed=1234) putils.save_dir(fname, spins) fname = SPINDIR / name / 'hungarian' / spin_fn if not fname.exists(): print(f'Generating Hungarian spins for {scale}')
from netneurotools import datasets, freesurfer, stats projdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) if __name__ == '__main__': # this will fetch Freesurfer annotation files for the Cammoun parcellation # they will be saved to ~/nnt-data/atl-cammoun2012 surf_files = datasets.fetch_cammoun2012('surface') spinmat = [] for scale, (lh, rh) in surf_files.items(): print('Running {}'.format(scale)) # find spherical coordinates of the parcels + hemisphere assignments coords, hemi = freesurfer.find_fsaverage_centroids(lh, rh) # generate the rotations / resampling indices spins, cost = stats.gen_spinsamples(coords, hemi, exact=False, seed=1234, n_rotate=10000) spinmat.append(spins.astype('int16')) # convert list to an object array to ensure it will be loaded as a cell # array by Matlab mat = dict(spinmat=np.array(spinmat, dtype=object)) fpath = os.path.join(projdir, 'data', 'spinmat.mat') sio.savemat(fpath, mat)