Esempio n. 1
0
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
Esempio n. 2
0
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
 ####--------------------------------------------------------------####
Esempio n. 3
0
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

####--------------------------------------------------------------####