def find_meanmods(confobj, meanmods_foundation): """ Finds best meanmods for input maps. Parameters ---------- confobj : object of type MstConfiguration Contains the parameters used for microstate computation and visualization. meanmods_foundation : array Contains the input maps for the modelmap computation. Returns ---------- bestresmm : array best meanmods for the input maps attributes_dict : dict includes ['Mean Correlation'] = best_mean_correlation """ #get number of original_nr_of_maps*nch modelmaps in meanmods_foundation list number_of_basic_maps = len(meanmods_foundation) #get configuration info from confobj original_nr_of_maps = confobj.original_nr_of_maps seed_number=confobj.seed_number max_number_of_iterations=confobj.max_number_of_iterations if number_of_basic_maps < original_nr_of_maps: print('Attention, you have only', number_of_basic_maps ,'groups/participants/conditions/runs to select your', original_nr_of_maps ,'random maps from') #get number of channel from first modelmap in meanmods_foundation list nch = meanmods_foundation[0].shape[1] #initialize variables for modelmap computation iii=0 best_results = {} bestcorr = {} best_mean_correlation = 0 found_best = False ##get fixed seed from confobj if not None fixed_seed = confobj.fixed_seed if fixed_seed != None: numpy.random.seed(fixed_seed) ##get user-requested normalization for meanmods_foundation for elenr, ele in enumerate(meanmods_foundation): meanmods_foundation[elenr]=normalize_maps(ele, confobj.modelmaps_normalization_type) #if there is only one map in the meanmods_foundation list, skip procedure and return output directly if len(meanmods_foundation) == 1: bestresmm = meanmods_foundation[0] attributes_dict = {} attributes_dict['Mean Correlation'] = 1 else: while iii < seed_number: #print('------------') #print('SEED', iii, ':') delta_correlation = 0.1 mean_correlation=0.1 ii = 0 delta_attribution_matrix=1 # create an empty list for iteration iii and add the best found maps best_results[iii] = {} # intitialize model_maps_mean array model_maps_mean=numpy.zeros( (original_nr_of_maps, nch) ) # intitialize attribution_matrix_old attribution_matrix_old=numpy.zeros( (number_of_basic_maps,original_nr_of_maps) ) ######### ### create original_nr_of_maps x nch array with 4 random maps ######### randmap=numpy.zeros((original_nr_of_maps, nch)) #selects from array: meanmods_foundation, the EEG of original_nr_of_maps random keys and random maps if iii <= 10: #Take all maps of one participant as seed random_vp= random.choice(list(range(len(meanmods_foundation)))) for i in range(original_nr_of_maps): randmap[i,:]=meanmods_foundation[random_vp][i,:] #print('seed', iii, 'random_vp', random_vp, 'random_map', i) else: #Completely random for i in range(original_nr_of_maps): random_vp= random.choice(list(range(len(meanmods_foundation)))) random_map= randrange(original_nr_of_maps) randmap[i,:]=meanmods_foundation[random_vp][random_map,:] #print('seed', iii, 'random_vp', random_vp, 'random_map', random_map) ######### ### Loop Across Iterations ######### while (ii < max_number_of_iterations) and abs(delta_correlation) > 0.0002: #print('iteration:', ii) best_results[iii][ii] = [] #intitialize attribution_matrix #attribution_matrix=numpy.zeros( (number_of_basic_maps ,original_nr_of_maps) ) attribution_matrix= dict.fromkeys(list(range(len(meanmods_foundation)))) #Find best map attribution for VP, save its indices and the corresponding correlation #for ivpi, vpi in enumerate(VP): (SO WARS VORHER) for numberi, number in enumerate((list(range(len(meanmods_foundation))))): #get maps from VP with key number maps=meanmods_foundation[number] #initialize dict for all permuations to later save mean correlation of that permutation mean_correlations = dict.fromkeys( list(range(math.factorial(original_nr_of_maps))) ) #for ithperm, perm in enumerate(itertools.permutations([0,1,2,3])): for ithperm, perm in enumerate(itertools.permutations((list(range(original_nr_of_maps))))): pearsons=[] pearsons2=[] for i in range(original_nr_of_maps): pr, pp=scipy.stats.pearsonr( maps[i,:], randmap[perm[i],:]) pearsons.append(pr) if confobj.ERP: pearsons2.append(float(pearsons[i])) else: pearsons2.append([abs(float(pearsons[i]))]) mean_correlationo =numpy.mean(pearsons2) mean_correlations[ithperm] = mean_correlationo bestpermi=max(mean_correlations.iteritems(), key=operator.itemgetter(1))[0] attribution_matrix[number] = list(itertools.permutations((list(range(original_nr_of_maps)))))[bestpermi] #save bestcorrelation which corresponds to the one of the best attribution for VP bestcorr[number]=mean_correlations[bestpermi] #generate a dictionary, where keys 0, 1, 2, 3 and arrays nVP x nch (best map that corresponds for each vp) best_fit = dict.fromkeys( list(range( 0, original_nr_of_maps)) ) for i in best_fit: b=numpy.zeros(( number_of_basic_maps , nch)) for vpnr, vpi in enumerate(attribution_matrix.keys()): vpindex=list(attribution_matrix[vpi]).index(i) b[vpnr,:]=meanmods_foundation[vpi][vpindex,:] best_fit[i]=b # for each key you have an array where you have to compute the first PC across participants # extract the first principal component of the array across participants for k in best_fit: P=best_fit[k] if confobj.ERP: coeff = P.mean(axis=0) #ERP: mean computed instead of PC1 assert coeff.real.all() == abs(coeff).all() coeff = coeff.real else: coeff = princomp_B(P,1) assert coeff.real.all() == abs(coeff).all() coeff = coeff.real randmap[k,:] = coeff.ravel() ##get user-requested normalization for meanmods randmap=normalize_maps(randmap, confobj.modelmaps_normalization_type) #compute delta_correlation compared to last iteration list_bestcorr_values= list(bestcorr.values()) bc_v_arr = numpy.asarray(list_bestcorr_values) bc_v_arr_mean=bc_v_arr[~numpy.isnan(bc_v_arr)].mean() delta_correlation=bc_v_arr_mean-mean_correlation #Update attribution matrix attribution_matrix_old=attribution_matrix #save attribution_matrix, mean_correlation and randmap IF delta_correlation >0 if (delta_correlation >0): #print 'delta correlation bigger than zero, append to best result' #update mean_correlation of current iteration mean_correlation=numpy.mean(bestcorr.values()) best_results[iii][ii]=[mean_correlation, randmap, attribution_matrix] ii += 1 iii += 1 #extract the best randmap and attribution_matrix for each seed best_mean_correlation = 0.1 for seednr in best_results.keys(): for iterationnr in best_results[seednr].keys(): if len(best_results[seednr][iterationnr]) == 0: if confobj.debug: print('value is zero: seed', seednr, ' iterationnr', iterationnr) else: corr, resmm, attrmatrix = best_results[seednr][iterationnr] #print 'current best', best_mean_correlation, ' current corr', corr if corr > best_mean_correlation : found_best = True best_mean_correlation = corr bestresmm = resmm bestattr_matrix = attrmatrix if found_best: if confobj.debug: #print 'best of all resmm and attr matrix', bestresmm.shape, bestattr_matrix #print 'best of all correlations', best_mean_correlation #print 'for condition', ci pass else: if confobj.debug: print('for SEED', iii, 'not found best') #save attributes in dictionary attributes_dict = {} attributes_dict['Mean Correlation'] = best_mean_correlation return bestresmm, attributes_dict
def find_modmaps(confobj, nch, eeg, gfp_peak_indices, gfp_curve): """ Finds N-M number of modelmaps from dataset based on all tfs or only gfp_peaks Parameters ---------- confobj : object of type MstConfiguration object that defines the parameters for the microstate modelmap computation nch : int number of channels from eeg_info_study_obj eeg : ndarray Array containing values for all time frames and channels. gfp_peak_indices : ndarray Array containing indices for all GFP peaks in eeg / all tfs if all tfs are used gfp_curve : array ntf length of GFP across all nch Returns ------- b_model : array original_nr_of_maps x nch array containing the retrieved microstate modelmap b_ind : double b_loading : double best_fit : double highest mean correlation between the N modelmaps and the M GFP peak maps exp_var : double explained variance of all GFP peaks exp_var_tot : explained variance of the whole EEG """ ################# # 0.) ###Configuration for modelmaps.py ################# #only necessary if we do not want to use the whole EEG but for example only a random selection of its gfp peaks to compute the modelmaps org_data = eeg if confobj.debug: print(org_data.shape) best_fit = 0 #max_n refers to the maximal number of GFP peaks used for computation, here the default is all gfp peaks max_n = len(gfp_peak_indices) #loop across runs for run in range(confobj.seed_number): if confobj.debug: print("-----------------") print("Seed_number", run) print("-----------------") #Pick 4 random map indices based on all gfp peaks random_map_indices = numpy.array(random.sample(set(gfp_peak_indices),confobj.original_nr_of_maps)) #Make sure that the four seeds are unique if len(random_map_indices)!=len(set(random_map_indices)): #add correct error type raise IndexError("No unique" + confobj.original_nr_of_maps + " maps could be randomly drawn from the set of GFP Peaks.") #the first model is based on the above random selection model = eeg[random_map_indices] if confobj.debug: print('random_map_indices', random_map_indices) #Computation of norm vector (set all to vector length 1) b=numpy.sum(numpy.abs(model)**2,axis=-1)**(1./2) #Divide all elements by the norm vector for col in range(nch): model[:,col]=model[:,col]/b #Some initialization for the attribution matrix (shape: number of global field power peaks x 1) #max_n: maximal number of gfp peaks used, by default all gfp_peaks o_ind= numpy.zeros((max_n)) ind=numpy.ones((max_n)) #Loop until the attribution matrix does not change anymore while numpy.allclose(o_ind, ind, rtol=1.0000000000000001e-05, atol=1e-08)==False: #Update attribution matrix from last loop o_ind = ind if confobj.ERP: #Get signed covariance matrix for ERP covm= numpy.dot(eeg[gfp_peak_indices],model.T) else: #Get unsigned covariance matrix for EEG covm= abs(numpy.dot(eeg[gfp_peak_indices],model.T)) #Look for the best fit (gives maximum value of axis = 1 of covm) ind = covm.argmax(axis=1) #Compute PC1 #uses function "princomp_B" from keypy.ressources for mm_index in range(confobj.original_nr_of_maps): P=numpy.array(eeg[gfp_peak_indices[ind==mm_index],:]) coeff = princomp_B(P,1) assert coeff.real.all() == abs(coeff).all() coeff = coeff.real model[mm_index,:] = coeff.ravel() #avg ref and norm b=numpy.sum(numpy.abs(model)**2,axis=-1)**(1./2) for col in range(nch): model[:,col]=model[:,col]/b #Get unsigned covariance matrix covm= numpy.dot(eeg[gfp_peak_indices],model.T) if confobj.ERP: #Look for the best fit ind = (covm).argmax(axis=1) else: #Look for the best fit ind = abs(covm).argmax(axis=1) #Get the unsigned covariance covm=numpy.dot(org_data[gfp_peak_indices],model.T) covm_all=numpy.dot(org_data,model.T) if confobj.ERP: # Look for the best fit ind = covm.argmax(axis=1) loading=covm.max(axis=1) #Indices for all timeframes #ind_all = covm_all.argmax(axis=1) loading_all=covm_all.max(axis=1) else: # Look for the best fit ind = abs(covm).argmax(axis=1) loading=abs(covm).max(axis=1) #Indices for all timeframes #ind_all = abs(covm_all).argmax(axis=1) loading_all=abs(covm_all).max(axis=1) tot_fit = sum(loading) if tot_fit > best_fit: b_model=model b_ind=ind b_loading=loading/sqrt(nch) b_loading_all=loading_all/sqrt(nch) best_fit=tot_fit #exp var based on gfp peaks only exp_var=sum(b_loading)/sum(eeg[gfp_peak_indices].std(axis=1)) #exp var based on all eeg timeframes exp_var_tot=sum(b_loading_all)/sum(eeg.std(axis=1)) return b_model, b_ind, b_loading, best_fit, exp_var, exp_var_tot ####--------------------------------------------------------------####
def find_modmaps(confobj, nch, eeg, gfp_peak_indices, gfp_curve): """ Finds N-M number of modelmaps from dataset based on all tfs or only gfp_peaks Parameters ---------- confobj : object of type MstConfiguration object that defines the parameters for the microstate modelmap computation nch : int number of channels from eeg_info_study_obj eeg : ndarray Array containing values for all time frames and channels. gfp_peak_indices : ndarray Array containing indices for all GFP peaks in eeg / all tfs if all tfs are used gfp_curve : array ntf length of GFP across all nch Returns ------- b_model : array original_nr_of_maps x nch array containing the retrieved microstate modelmap b_ind : double b_loading : double best_fit : double highest mean correlation between the N modelmaps and the M GFP peak maps exp_var : double explained variance of all GFP peaks exp_var_tot : explained variance of the whole EEG """ ################# # 0.) ###Configuration for modelmaps.py ################# #only necessary if we do not want to use the whole EEG but for example only a random selection of its gfp peaks to compute the modelmaps org_data = eeg if confobj.debug: print(org_data.shape) best_fit = 0 #max_n refers to the maximal number of GFP peaks used for computation, here the default is all gfp peaks max_n = len(gfp_peak_indices) #loop across runs for run in range(confobj.seed_number): if confobj.debug: print("-----------------") print("Seed_number", run) print("-----------------") #Pick 4 random map indices based on all gfp peaks random_map_indices = numpy.array( random.sample(set(gfp_peak_indices), confobj.original_nr_of_maps)) #Make sure that the four seeds are unique if len(random_map_indices) != len(set(random_map_indices)): #add correct error type raise IndexError( "No unique" + confobj.original_nr_of_maps + " maps could be randomly drawn from the set of GFP Peaks.") #the first model is based on the above random selection model = eeg[random_map_indices] if confobj.debug: print('random_map_indices', random_map_indices) #Computation of norm vector (set all to vector length 1) b = numpy.sum(numpy.abs(model)**2, axis=-1)**(1. / 2) #Divide all elements by the norm vector for col in range(nch): model[:, col] = model[:, col] / b #Some initialization for the attribution matrix (shape: number of global field power peaks x 1) #max_n: maximal number of gfp peaks used, by default all gfp_peaks o_ind = numpy.zeros((max_n)) ind = numpy.ones((max_n)) #Loop until the attribution matrix does not change anymore while numpy.allclose(o_ind, ind, rtol=1.0000000000000001e-05, atol=1e-08) == False: #Update attribution matrix from last loop o_ind = ind if confobj.ERP: #Get signed covariance matrix for ERP covm = numpy.dot(eeg[gfp_peak_indices], model.T) else: #Get unsigned covariance matrix for EEG covm = abs(numpy.dot(eeg[gfp_peak_indices], model.T)) #Look for the best fit (gives maximum value of axis = 1 of covm) ind = covm.argmax(axis=1) #Compute PC1 #uses function "princomp_B" from keypy.ressources for mm_index in range(confobj.original_nr_of_maps): P = numpy.array(eeg[gfp_peak_indices[ind == mm_index], :]) coeff = princomp_B(P, 1) assert coeff.real.all() == abs(coeff).all() coeff = coeff.real model[mm_index, :] = coeff.ravel() #avg ref and norm b = numpy.sum(numpy.abs(model)**2, axis=-1)**(1. / 2) for col in range(nch): model[:, col] = model[:, col] / b #Get unsigned covariance matrix covm = numpy.dot(eeg[gfp_peak_indices], model.T) if confobj.ERP: #Look for the best fit ind = (covm).argmax(axis=1) else: #Look for the best fit ind = abs(covm).argmax(axis=1) #Get the unsigned covariance covm = numpy.dot(org_data[gfp_peak_indices], model.T) covm_all = numpy.dot(org_data, model.T) if confobj.ERP: # Look for the best fit ind = covm.argmax(axis=1) loading = covm.max(axis=1) #Indices for all timeframes #ind_all = covm_all.argmax(axis=1) loading_all = covm_all.max(axis=1) else: # Look for the best fit ind = abs(covm).argmax(axis=1) loading = abs(covm).max(axis=1) #Indices for all timeframes #ind_all = abs(covm_all).argmax(axis=1) loading_all = abs(covm_all).max(axis=1) tot_fit = sum(loading) if tot_fit > best_fit: b_model = model b_ind = ind b_loading = loading / sqrt(nch) b_loading_all = loading_all / sqrt(nch) best_fit = tot_fit #exp var based on gfp peaks only exp_var = sum(b_loading) / sum(eeg[gfp_peak_indices].std(axis=1)) #exp var based on all eeg timeframes exp_var_tot = sum(b_loading_all) / sum(eeg.std(axis=1)) return b_model, b_ind, b_loading, best_fit, exp_var, exp_var_tot ####--------------------------------------------------------------####