def read_outcar(FileName, InitialStep): #read poscar file print('Reading outcar file ', FileName, ' from initial step ', InitialStep) switch = False flagrprimd = -1 iatom = -1 istep = 0 MyCrystal = cr.Lattice() TimeStep = 1.0 newfile = FileName + '.umd.dat' nf = open(newfile, 'w') nf.close() atomictype = 0 CurrentTime = 0.0 TimeStep = 0.0 with open(FileName, 'r') as ff: while True: line = ff.readline() if not line: break line = line.strip() entry = line.split() if (len(entry) > 0): if (entry[0] == 'ions'): #determine how many atoms jatom = 0 MyCrystal.natom = 0 MyCrystal.ntypat = len(entry) - 4 MyCrystal.types = [0 for _ in range(MyCrystal.ntypat)] for ii in range(len(entry) - 4): MyCrystal.natom = MyCrystal.natom + int(entry[4 + ii]) MyCrystal.types[ii] = int(entry[4 + ii]) MyCrystal.typat = [0 for _ in range(MyCrystal.natom)] for ii in range(len(entry) - 4): atomictype += 1 for jj in range(int(entry[4 + ii])): MyCrystal.typat[jatom] = atomictype - 1 jatom = jatom + 1 MyCrystal.atoms = [ cr.Atom() for _ in range(MyCrystal.natom) ] oldpos = [cr.Atom() for _ in range(MyCrystal.natom)] MyCrystal.elements = ['X' for _ in range(MyCrystal.ntypat)] MyCrystal.masses = [0.0 for _ in range(MyCrystal.ntypat)] MyCrystal.zelec = [0.0 for _ in range(MyCrystal.ntypat)] MyCrystal.stress = [0.0 for _ in range(6)] phase = [[0.0, 0.0, 0.0] for _ in range(MyCrystal.natom)] diffcoords = [[0.0, 0.0, 0.0] for _ in range(MyCrystal.natom)] MyCrystal.magnetization = 0.0 print('Total number of atoms = ', len(diffcoords)) break ff.close() flagmass = 0 flagtitle = 0 atn = '' ats = '' atno = '' with open(FileName, 'r') as ff: while True: line = ff.readline() if not line: break line = line.strip() entry = line.split() if (len(entry) > 0): if (len(entry) > 1): if entry[1] == 'Iteration': break # if (entry[0]=='VRHFIN'): # flagtitle += 1 # atomicsymbol = entry[1] # MyCrystal.elements[flagtitle-1] = atomicsymbol[1:-1] # print ('element ',flagtitle,' is ',MyCrystal.elements[flagtitle-1]) # (atn,ats,atno,MyCrystal.masses[flagtitle-1])=cr.Elements2rest(MyCrystal.elements[flagtitle-1]) # print ('just chekcing: ',atn,ats,atno) if (entry[0] == 'POTCAR:'): if (flagtitle < MyCrystal.ntypat): MyCrystal.elements[flagtitle] = entry[2].split('_')[0] # print ('element ',flagtitle,' is ',MyCrystal.elements[flagtitle]) (atn, ats, atno, MyCrystal.masses[flagtitle]) = cr.Elements2rest( MyCrystal.elements[flagtitle]) # print ('just chekcing: ',atn,ats,atno) print('element ', flagtitle, ' is ', MyCrystal.elements[flagtitle], ' with atomic number ', atno, ' and mass ', MyCrystal.masses[flagtitle]) flagtitle += 1 if (entry[0] == 'POMASS'): if flagmass < MyCrystal.ntypat: # print('flagmass is',flagmass,' with the line ',entry) # for ii in range(MyCrystal.ntypat): MyCrystal.masses[flagmass] = float(entry[2][:-1]) MyCrystal.zelec[flagmass] = float(entry[5]) flagmass += 1 # if (entry[0]=='ZVAL'): # for ii in range(MyCrystal.ntypat): # MyCrystal.zelec[ii]=float(entry[ii+2]) # if (entry[0]=='Mass'): # flagmass=1 if (entry[0] == 'NELECT'): MyCrystal.noelectrons = float(entry[2]) ff.close() umd.print_header(FileName, MyCrystal) with open(FileName, 'r') as ff: while True: line = ff.readline() if not line: break line = line.strip() entry = line.split() if (len(entry) == 6): # print ('a line of 6 elements: ',entry) if (entry[4] == 'magnetization'): # print ('the line of 6 elements: ',entry) MyCrystal.magnetization = float(entry[5]) if (switch == False): if (len(entry) > 0 and entry[0] == 'POTIM'): TimeStep = float(entry[2]) if (len(entry) >= 2 and entry[1] == 'aborting'): switch = True else: continue if (switch == True and len(entry) > 0): # print 'entry[0] is ',entry[0] jatom = 0 if ( entry[0] == 'Total+kin.' ): #reading stress tensor, corrected for the internal kinetic pressure (the term contains it itself0 for ii in range(6): MyCrystal.stress[ii] = float( entry[ii + 1]) / 10.0 #transforms from kbars into GPa MyCrystal.pressure = ( float(entry[1]) + float(entry[2]) + float(entry[3]) ) / 30.0 #transforms also from kbars into GPa if entry[0] == 'energy': if entry[ 2] == 'entropy=': #reading Kohn-Sham energy, contains all the electronic energy without the electronic entropy MyCrystal.internalenergy = float( entry[3] ) #this leads only part of the internal energy, one should add the kinetic energy of ions #the variance of {this energy + kinetic energy of ions} yields Cv if (entry[0] == '%'): if ( entry[1] == 'ion-electron' ): #the term T*Sel in the formula F = E - T*Sel, with F = Kohn-Sham energy and E = Kohn-Sham energy without the electronic entropy MyCrystal.electronicentropy = MyCrystal.internalenergy - float( entry[4]) if (entry[0] == 'magnetization' ): #reading magnetization of individual atoms #print('reading magnetization') line = ff.readline() line = ff.readline() line = ff.readline() for ii in range(MyCrystal.natom): line = ff.readline() line = line.strip() entry = line.split() MyCrystal.atoms[ii].magnet = float(entry[len(entry) - 1]) #print ('for atom ',iatom,' magnetization is ',MyCrystal.atoms[ii].magnet) # if (len(entry) == 6): # print ('a line of 6 elements: ',entry) # if (entry[0] == 'number'): # print ('the line of 6 elements: ',entry) # MyCrystal.magnetization = float(entry[5]) if line == 'total charge': #reading the atomi charges #print('reading magnetization') line = ff.readline() line = ff.readline() line = ff.readline() for ii in range(MyCrystal.natom): line = ff.readline() line = line.strip() entry = line.split() MyCrystal.atoms[ii].charge = float(entry[len(entry) - 1]) if (entry[0] == 'kinetic'): #reading kinetic energy of ions if (len(entry) > 2): if (entry[2] == 'EKIN'): MyCrystal.kineticenergy = float(entry[4]) if (entry[0] == 'total'): #reading energy #KS energy + thermostat + ion-kinetic terms #used to check the drift in energy over a simulation if (len(entry) > 2): if (entry[2] == 'ETOTAL'): MyCrystal.energywithdrift = float(entry[4]) #ETOTAL is the last value we want to take in the umd, so we can put the switch off and increase the counter of steps #Once istep >= InitialStep, we can compute the velocities, diffcoord etc. and print the umd switch = False istep = istep + 1 if istep >= InitialStep: #print (' treating step no. ', istep) for jatom in range(MyCrystal.natom): for ii in range(3): jump = MyCrystal.atoms[jatom].xcart[ ii] - oldpos[jatom].xcart[ii] if jump > MyCrystal.acell[ii] / 2: #print ('positive jump',jump,jatom,MyCrystal.atoms[jatom].xcart[ii],oldpos[jatom].xcart[ii]) phase[jatom][ ii] = phase[jatom][ii] - ( MyCrystal.rprimd[ii][0] + MyCrystal.rprimd[ii][1] + MyCrystal.rprimd[ii][2]) diffcoords[jatom][ ii] = MyCrystal.atoms[ jatom].xcart[ii] + phase[ jatom][ii] jump = jump - ( MyCrystal.rprimd[ii][0] + MyCrystal.rprimd[ii][1] + MyCrystal.rprimd[ii][2]) elif jump < -MyCrystal.acell[ii] / 2: #print ('negatie jump',jump,jatom,MyCrystal.atoms[jatom].xcart[ii],oldpos[jatom].xcart[ii]) phase[jatom][ ii] = phase[jatom][ii] + ( MyCrystal.rprimd[ii][0] + MyCrystal.rprimd[ii][1] + MyCrystal.rprimd[ii][2]) jump = jump + ( MyCrystal.rprimd[ii][0] + MyCrystal.rprimd[ii][1] + MyCrystal.rprimd[ii][2]) diffcoords[jatom][ ii] = MyCrystal.atoms[ jatom].xcart[ii] + phase[ jatom][ii] else: diffcoords[jatom][ ii] = MyCrystal.atoms[ jatom].xcart[ii] + phase[ jatom][ii] MyCrystal.atoms[jatom].vels[ ii] = jump / TimeStep for jj in range(3): MyCrystal.atoms[jatom].xred[ ii] = MyCrystal.atoms[jatom].xred[ ii] + MyCrystal.gprimd[ii][ jj] * MyCrystal.atoms[ jatom].xcart[ii] while MyCrystal.atoms[jatom].xred[ ii] >= 1.0: MyCrystal.atoms[jatom].xred[ ii] = MyCrystal.atoms[ jatom].xred[ii] - 1.0 (CurrentTime, TimeStep) = umd.print_snapshots( FileName, MyCrystal, TimeStep, (istep - InitialStep) * TimeStep, diffcoords) if (entry[0] == 'kin.'): #reading the temperature if len(entry) == 7: MyCrystal.temperature = float(entry[5]) elif len(entry) == 6: mixedtemp = entry[4] MyCrystal.temperature = float(mixedtemp[-8:]) else: print('defect on the temperature line', entry) if (flagrprimd > -1): #reaeding the unit cell # print 'entries are ',entry MyCrystal.rprimd[flagrprimd][0] = float( entry[0].split(',')[0]) MyCrystal.rprimd[flagrprimd][1] = float( entry[1].split(',')[0]) MyCrystal.rprimd[flagrprimd][2] = float( entry[2].split(')')[0]) MyCrystal.acell[flagrprimd] = math.sqrt( MyCrystal.rprimd[flagrprimd][0] * MyCrystal.rprimd[flagrprimd][0] + MyCrystal.rprimd[flagrprimd][1] * MyCrystal.rprimd[flagrprimd][1] + MyCrystal.rprimd[flagrprimd][2] * MyCrystal.rprimd[flagrprimd][2]) flagrprimd = flagrprimd + 1 if (flagrprimd == 3): MyCrystal.gprimd = MyCrystal.makegprimd() #MyCrystal.cellvolume = MyCrystal.makevolume() MyCrystal.density = MyCrystal.getdensity() #print('gprimd ',MyCrystal.gprimd) #print(MyCrystal.cellvolume) flagrprimd = -1 if (entry[0] == 'direct'): flagrprimd = flagrprimd + 1 if (iatom > -1): #reading the atomic positions #print ('current iatom is ',iatom) MyCrystal.atoms[iatom].xred = [0.0, 0.0, 0.0] MyCrystal.atoms[iatom].vels = [0.0, 0.0, 0.0] oldpos[iatom].xcart = MyCrystal.atoms[iatom].xcart MyCrystal.atoms[iatom].xcart = [ float(entry[0]), float(entry[1]), float(entry[2]) ] MyCrystal.atoms[iatom].forces = [ float(entry[3]), float(entry[4]), float(entry[5]) ] iatom = iatom + 1 if (iatom == MyCrystal.natom): iatom = -1 if (entry[0] == 'POSITION'): line = ff.readline() iatom = 0 return (CurrentTime, TimeStep)
def main(argv): """ ********* Main program ********* """ #other dictionnaries and parameters for the figure markers = ['o','^','*','P','X','<','>','v','8','s','p','h','+','D'] #************************************Be sure you have enough markers for all the pairs you want to plot colors_T = {'T2':'#800080','T3':'#297fff','T4':'#00ff00','T4.5':'#bae200','T5':'#ffcd01','T5.5':'#ff6e00','T6':'#ff0101','T6.5':'#ff00a2','T7':'#ff01de','T7.5':'#ffa6f4','T10':'#ffe86e','T15':'#ffbf90','T20':'#ff7788'} plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (4,4),"size_markers" : 8,"size_lines" : 1,"shift_labelpad" : 20} label = {'xmax':r"1st $g(r)$ peak location ($\AA$)",'xmin':r"Coordination sphere radius ($\AA$)",'bond':r"Bond length ($\AA$)"} #initialization of variables bondanalysis = 0 elements = '' number = '' atoms = [] legend_labels = {} data = {} #big dictionnary with inside dist dictionnary and rho, all coresponding to different T distance_columns = {'xmax':1,'xmin':3,'bond':5} #other parameters Na=6.022*10**23 try: options,arg = getopt.getopt(argv,"hg:a:d:b:",["gofrsfilename","atom","distance",'bondanalysis']) except getopt.GetoptError: print("plot_distances+analysis_xmin.py -g <_gofrs.txt> -a <pairs of atoms>(ex: 'Ca-O,Ca-Ca,O2') -d <distance type to print ('xmax' or 'xmin' or 'bond')> -b <=1 if analysis and update of bondfiles, default =0>") sys.exit() for opt,arg in options: if opt == '-h': print('') print('plot_distances+analysis_xmin.py program to plot xmin,xmax or bond length as a function of density or acell for each T and all the selected pairs of atoms') print("plot_distances+analysis_xmin.py -g <_gofrs.txt> -a <pairs of atoms>(ex: 'Ca-O,Ca-Ca,O2') -d <distance type to print ('xmax' or 'xmin' or 'bond')> -b <=1 if analysis and update of bondfiles, default =0>") print("plot_distances+analysis_xmin.py requires _gofrs.txt file (use analyze_gofrs_semi_automatic.py)") print('') print('WARNING: this script use the filenames inside the _gofrs.txt file to extract the temperature and cell size for the plot. If you do have both information in your filenames at the same place, then update the function split_name to extract them correctly.') sys.exit() if opt in ('-g','--gofrsfilename'): filename = str(arg) elif opt in ('-a','--atoms'): atoms = arg.split(',') #list of atom pairs we want to analyze here elif opt in ('-d','--distance'): distance_type = str(arg) elif opt in ('-b','--bondanalysis'): bondanalysis = int(arg) #******* 1st step: read the header and extract all relevant informations #creation of elements and number lists and initialization of T skip_head = 0 with open(filename,'r') as f: while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t') skip_head +=1 if entry[0] == 'elements': elements = list(filter(None, entry[1:])) print(elements) if entry[0] == 'number': number = list(filter(None, entry[1:])) print(number) if entry[0] == 'pair': allpairs_ordered = entry[1:] if entry[0] == 'file': line = f.readline() entry=line.split() temperature0, acell0 = split_name(entry[0]) break if elements != '' and number != '': #calculation of M*N nedded for the calculation of densities MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] else: MN =0 #creation of the list containing all the pairs only once and in the same order unique_pairs = [allpairs_ordered[0]] for i in range(1,len(allpairs_ordered)): if allpairs_ordered[i] != allpairs_ordered[i-1]: unique_pairs.append(allpairs_ordered[i]) print('All the pairs availables in the file are:',unique_pairs) print('The pairs selected for the plot are:', atoms) print('The index for each pair is:') #initialization of the dictionnaries containing the data #we create sub dictionnaries of the data dictionnary data[temperature0] = {'file':[],'rho':[],'dist':{}} selected_pairs = [] #pairs to analyze along with their column number for i in range(0,len(unique_pairs)): for atom_pair in atoms: if (unique_pairs[i] == atom_pair): data[temperature0]['dist'][atom_pair] = [] selected_pairs.append((atom_pair,i*5+distance_columns[distance_type])) print(atom_pair, i*5+distance_columns[distance_type]) #******* 2nd step: extraction of data from the fullgofrs.txt file with open(filename,'r') as f: [f.readline() for i in range(skip_head)] while True: line = f.readline() if not line: break else: entry=line.split('\t') temperature, acell = split_name(entry[0]) if temperature != temperature0: #if we change T: #we create sub dictionnaries of the data dictionnary and we re-initialize the arrays temperature0 = temperature data[temperature0] = {'file':[],'rho':[],'dist':{}} for i in range(len(selected_pairs)): data[temperature0]['dist'][selected_pairs[i][0]] = [] if MN ==0: data[temperature0]['rho'].append(float(acell)) #rho is replaced by acell else: data[temperature0]['rho'].append(MN/(Na*float(acell)**3*10**(-24))) #calculation density data[temperature0]['file'].append(entry[0].split('/')[-1].split('.gofr.dat')[0]) #extract filename #we replace the 0 (no data) by NaN for i in range(len(selected_pairs)): if float(entry[selected_pairs[i][1]]) == 0.0: data[temperature0]['dist'][selected_pairs[i][0]].append(float('nan')) else: data[temperature0]['dist'][selected_pairs[i][0]].append(float(entry[selected_pairs[i][1]])) #******* 3rd step: bond analysis #Smooth xmin data using fitting and get minrho, maxrho even if we don't want to update/create .bonds.inp new_xmin, minrho, maxrho, params, chi2_reduced = smoothing_xmin(data,selected_pairs) if bondanalysis == 1: #**** Extract all gofrfiles available allgofrfiles = [] for dirpath, dirnames, filenames in os.walk(os.curdir): allgofrfiles.extend(sorted(glob.glob(dirpath+'/*.gofr.dat'))) print("**** gofrfiles in the current directory are:", allgofrfiles) gofrfileslocation = {} for gofrfile in allgofrfiles: gofrfileslocation[gofrfile.split('/')[-1].split('.gofr.dat')[0]] = gofrfile #**** For each line (gofrfile) in the .gofrs.txt file for temp in sorted(data): for file in data[temp]['file']: #Check if the bondfile already exist: if yes we update it, if not we create it bondfile = gofrfileslocation[file].split('.gofr.dat')[0]+'.bonds.inp' if (os.path.isfile(bondfile)): update_bonds(bondfile,selected_pairs,atoms,new_xmin,unique_pairs,file) else: create_bonds(bondfile,selected_pairs,atoms,new_xmin,unique_pairs,file) else: print("Bond analysis not done. If you want it, use option -b 1") #******* 4th step: plot of the data and write the deviation from mean in file plt.close(1) h = 2 * len(atoms) #height of the figure depends on the number of pairs we display fig = plt.figure(1,figsize = (4,h)) plt.subplots_adjust(top = 0.97, bottom = 0.07, right = 0.89, left = 0.07, hspace = 0, wspace = 0) #Creation of ticks if MN != 0: major_ticks = np.arange(0.5, 7, 0.5) minor_ticks = np.arange(0.5, 7, 0.1) else: major_ticks = AutoLocator() minor_ticks = AutoMinorLocator() #plot & write percentage variation of distance ylim_allT = {} string = '' for atom_pair in atoms: string = string+'_'+atom_pair newfilename = 'distance_variation_'+distance_type+'_'+filename[:-4]+string+'.txt' f=open(newfilename,'w') for i in range(len(selected_pairs)): atom_pair = selected_pairs[i][0] ylim_allT[atom_pair] = [9999,0] #print('***************** for atom pair:',atom_pair) f.write(atom_pair+'\t'+"\t".join(temp for temp in sorted(data) )+ "\n") all_means='mean' all_range='range' all_percent='%var_from_mean' all_percent_rho='%var_from_mean_per_rho' all_params_a='fitted_parameter_a' all_params_b='fitted_parameter_b' all_params_c='fitted_parameter_c' all_params_d='fitted_parameter_d' all_chi2='chi2_reduced' plt.subplot(len(atoms), 1, atoms.index(atom_pair)+1) ax = plt.gca() #plot and prepare the strings to write in the new log file for temp in sorted(data): #loop over temperatures = key in data dictionnary #classic analysis (mean, range, %variation) #print('******* for temperature:',temp) mean_dist=np.nanmean(data[temp]['dist'][atom_pair]) all_means = all_means+'\t'+str(np.round(mean_dist,2)) #print('mean dist for',atom_pair,'=',np.round(mean_dist,2)) range_var=(np.nanmax(data[temp]['dist'][atom_pair])- np.nanmin(data[temp]['dist'][atom_pair]) ) all_range = all_range+'\t'+str(np.round(range_var,2)) #print('dist range for', atom_pair, '=', np.round(range_var,2)) percent_var_mean = (range_var / mean_dist) * 100 all_percent=all_percent+'\t'+str(np.round(percent_var_mean,1)) #print('percent var mean for', atom_pair, '=', np.round(percent_var_mean,1)) percent_var_mean_per_rho = percent_var_mean / ( np.nanmax(data[temperature0]['rho']) - np.nanmin(data[temperature0]['rho']) ) all_percent_rho=all_percent_rho+'\t'+str(np.round(percent_var_mean_per_rho,1)) #print('percent var mean per rho for', atom_pair, '=', np.round(percent_var_mean_per_rho,1)) #results from fit if bondanalysis == 1: newrhoX = np.arange(minrho, maxrho+0.1, 0.1) try: all_params_a= all_params_a+'\t'+str(params[temp][atom_pair][0]) all_params_b= all_params_b+'\t'+str(params[temp][atom_pair][1]) if len(params[temp][atom_pair])==4: all_params_c= all_params_c+'\t'+str(params[temp][atom_pair][2]) all_params_d= all_params_d+'\t'+str(params[temp][atom_pair][3]) function = poly3 else: all_params_c= all_params_c+'\t-' all_params_d= all_params_d+'\t-' function = linear all_chi2 = all_chi2+'\t'+str(chi2_reduced[temp][atom_pair]) #print('chi2 for', atom_pair, '=', chi2_reduced[temp][atom_pair]) ax.plot(newrhoX,function(newrhoX,*params[temp][atom_pair]), '-',color=colors_T[temp], linewidth = plot_parameters["size_lines"] ) except KeyError: all_chi2 = all_chi2+'\t-' all_params_a= all_params_a+'\t-' all_params_b= all_params_b+'\t-' all_params_c= all_params_c+'\t-' all_params_d= all_params_d+'\t-' #plot ax.plot(data[temp]['rho'],data[temp]['dist'][atom_pair], '--', color=colors_T[temp], linewidth = plot_parameters["size_lines"], marker = markers[atoms.index(atom_pair)], markersize = plot_parameters["size_markers"]) # ax.text(1.025,0.5, atom_pair ,transform=ax.transAxes, fontsize=plot_parameters["size_fonts"], fontweight='bold') ax.text(0.85,0.9, atom_pair, transform=ax.transAxes, fontsize=plot_parameters["size_fonts"], fontweight='bold') #define bounds for axis if ylim_allT[atom_pair][1] < np.nanmax(data[temp]['dist'][atom_pair]): ylim_allT[atom_pair][1] = np.nanmax(data[temp]['dist'][atom_pair]) if ylim_allT[atom_pair][0] > np.nanmin(data[temp]['dist'][atom_pair]): ylim_allT[atom_pair][0] = np.nanmin(data[temp]['dist'][atom_pair]) f.write(all_means+'\n') f.write(all_range+'\n') f.write(all_percent+'\n') f.write(all_percent_rho+'\n') f.write(all_chi2+'\n') f.write(all_params_a+'\n') f.write(all_params_b+'\n') f.write(all_params_c+'\n') f.write(all_params_d+'\n') f.write('\n') #Adjustment of ticks and make the graph prettier if MN != 0: ax.set_xticks(major_ticks) ax.set_xticks(minor_ticks, minor=True) else: ax.xaxis.set_major_locator(major_ticks) ax.xaxis.set_minor_locator(minor_ticks) ax.xaxis.set_ticks_position('both') ax.yaxis.set_ticks_position('both') majorLocator = AutoLocator() minorLocator = AutoMinorLocator() ax.yaxis.set_major_locator(majorLocator) ax.yaxis.set_minor_locator(minorLocator) ax.set_xlim(minrho,maxrho) ax.set_ylim(ylim_allT[atom_pair][0],ylim_allT[atom_pair][1]) if atoms.index(atom_pair) != len(atoms)-1: plt.setp(ax.get_xticklabels(), visible=False) ax.tick_params(which = 'both', labelsize = plot_parameters["size_font_ticks"], width = plot_parameters["size_lines"]/2) f.close() # Fine-tune figure ax0 = fig.add_subplot(111, frameon=False) plt.tick_params(labeltop=False, top=False, labelbottom=False, bottom=False, labelleft=False, left=False, labelright=False, right=False) if MN != 0: ax0.set_xlabel(r'Density (g.cm$^{-3}$)', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]) else: ax0.set_xlabel(r'Cell size ($\AA$)', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]) ax0.set_ylabel(label[distance_type],fontsize=plot_parameters["size_fonts"],fontweight='bold', labelpad = plot_parameters["shift_labelpad"]+plot_parameters["shift_labelpad"]/1.3) #Legend for temp in data: legend_labels[str(int(float(temp.strip('T'))*1000))] = mpatches.Patch(color=colors_T[temp]) s = [(k, legend_labels[k]) for k in sorted(legend_labels.keys(),reverse = False)] #legend = ax0.legend([v for k,v in s],[k for k,v in s], title = ' $\\bf{Temperature}$ \n (K)',loc='upper left',bbox_to_anchor=(1.2, 1), fontsize = plot_parameters["size_fonts"], borderaxespad=0.,ncol=1) #plt.setp(legend.get_title(),fontsize= plot_parameters["size_fonts"]) #plt.title(filename.split('.txt')[0], fontsize = plot_parameters["size_fonts"], fontweight='bold') #save the figure string = '' for atom_pair in atoms: string = string+'_'+atom_pair figurename = 'distance_'+distance_type+'_'+filename[:-4]+string+'.png' fig.savefig(figurename, bbox_inches = 'tight', dpi = 150) print(figurename, ' created')
def main(argv): """ ********* Main program ********* """ #param for the plot colors_elem = { 'Al': 'pink', 'C': '0.25', 'Ca': 'c', 'H': 'w', 'K': 'm', 'Na': 'b', 'O': 'r', 'Si': 'y' } #other dictionnaries and parameters for the figure for article version letter = '' statfile2 = '' plot_parameters = { "size_fonts": 12, "size_font_ticks": 10, "size_figure": (8, 4), "size_markers": 4, "size_lines": 1, "shift_labelpad": 20 } #plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (8,4),"size_markers" : 10,"size_lines" : 2,"shift_labelpad" : 20} #other parameters Na = 6.022 * 10**23 try: options, arg = getopt.getopt(argv, "hf:g:v:m:d:l:", [ "file1", "gfile2", "variable", "mineralfile", "density_max", "letter" ]) except getopt.GetoptError: print( "plot_speciation-r1-elements.py -v <variable (rho,T)> -m <mineralfile with elements> -f <stat-concentrate_r1_abso_filename1> -g <stat-concentrate_r1_abso_filename2> -d <maximum density to plot in g/cm3> -l <letter for article subplot, default = ''>" ) sys.exit() for opt, arg in options: if opt == '-h': print('') print( 'plot_speciation-r1-elements.py program to Plot abundance of elements as a function of rho or T' ) print( "plot_speciation-r1-elements.py -v <variable (rho,T)> -m <mineralfile with elements> -f <stat-concentrate_r1_abso_filename1> -g <stat-concentrate_r1_abso_filename2> -d <maximum density to plot in g/cm3> -l <letter for article subplot, default = ''>" ) print( 'requires the file containing elements and number (in order to compute the densities)' ) print('') sys.exit() elif opt in ("-f", "--file1"): statfile1 = str(arg) elif opt in ("-g", "--gfile2"): statfile2 = str(arg) elif opt in ("-v", "--variable"): variable = str(arg) elif opt in ("-m", "--mineralfile"): mineralfile = str(arg) elif opt in ("-d", "--density_max"): max_den = float(arg) elif opt in ("-l", "--letter"): letter = str(arg) #***** Calculation of the molecular mass with open(mineralfile, 'r') as mf: entry = mf.readline() elements = entry.split()[1:] entry = mf.readline() number = list(map(int, entry.split()[1:])) MN = 0 for i in range(len(elements)): MN = MN + number[i] * cr.Elements2rest(elements[i])[3] #**** Calculation of congruent proportions congruent = {} for ii in range(len(elements)): congruent[elements[ii]] = number[ii] / sum(number) #***** Creation of the plot if statfile2 != '': allstatfiles = [statfile1, statfile2] with open(statfile1, 'r') as f: line = f.readline() file1 = line.split()[1] with open(statfile2, 'r') as f2: line = f2.readline() file2 = line.split()[1] fig, ax1, ax2 = creation_plot2(variable, file1, file2, MN, plot_parameters, max_den, letter) figurename = statfile1.split('/')[-1].split( '.dat')[0] + '+' + statfile2.split('/')[-1].split( '.dat')[0] + '_' + variable + '-elements' else: allstatfiles = [statfile1] fig, ax1 = creation_plot(variable, plot_parameters, max_den, letter) figurename = statfile1.split('.dat')[0] + '_' + variable + '-elements' for ii in range(len(allstatfiles)): statfile = allstatfiles[ii] #selection of the plot if ii == 1: ax = ax2 else: ax = ax1 #initialisation atomsnumbers = { } #create dictionnary which will contain the number of atom for each element in each species filescolumns = { } #create dictionnary containing the column number for the different files xdata = {'T': [], 'rho': []} #dictionnary containing the x data lifetime = { } #dictionnary containing lifetime data for each element and file perc = {} #idem for percentages selected_files = [ ] #list containing the files we use for the plot (depends on the density limit) #***** Extraction of all files and cluster and count of their atoms with open(statfile, 'r') as f: line = f.readline() entry = line.split('\n')[0].split('\t')[1:-1] for file in entry: filescolumns[file] = entry.index(file) while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t') if len(entry) > 1: atomsnumbers[entry[0]] = { } #create dictionnary which will contain the number of atom for each element in each species for elem in elements: #print("for elem",elem) for species in atomsnumbers: #print("for species",species) m = re.search(elem, species) if m: #if there is the current element in the species ii = m.end( ) #then we use the index of the end of the matching pattern m try: #to try to see if there is several iteration of this element using '_' if species[ii] == '_': num = '' try: while re.match('[0-9]', species[ii + 1]): num = num + species[ii + 1] ii += 1 except IndexError: #index error when we arrive at the end of the cluster name pass #print('end of the cluster') #print("num after '_':", num) atomsnumbers[species][elem] = int(num) else: #if there is no '_' after the matching pattern it means there is only one atom of this element atomsnumbers[species][elem] = 1 except IndexError: #if the matching pattern is actually at the end of the string we raise an indexerror --> there is only one instance of this element atomsnumbers[species][elem] = 1 else: atomsnumbers[species][elem] = 0 #print(atomsnumbers) #**** Extraction of selected files for file in filescolumns: temperature, acell = split_name(file) density = MN / (Na * float(acell)**3 * 10**(-24)) if density <= max_den: xdata['rho'].append(density) #calculation density xdata['T'].append(int(temperature)) selected_files.append(file) print("selected files are", selected_files) #**** Initialization of perc and lifetime dictionnary for each element and file for elem in elements: perc[elem] = {} lifetime[elem] = {} for file in selected_files: perc[elem][file] = [] lifetime[elem][file] = [] #***************************** #******************* #******* #**** Extract the lifetimes with open(statfile, 'r') as f: f.readline() while True: line = f.readline( ) #for each line of the file we extract the data if not line: break else: entry = line.split('\n')[0].split('\t')[:-1] #print("entry is",entry) for elem in atomsnumbers[entry[ 0]]: #we skip the analysis for element that are not present in the species if atomsnumbers[entry[0]][elem] == 0: continue else: #and we store the lifetime for each element and file for file in selected_files: try: lifetime[elem][file].append( float(entry[filescolumns[file] + 1]) * atomsnumbers[entry[0]][elem]) except ValueError: #if there is '' instead of a numerical value lifetime[elem][file].append(0) #**** Compute percentages #1st: sum lifetime per element for elem in elements: perc[elem] = [] for file in selected_files: perc[elem].append(sum(lifetime[elem][file])) #2nd: sum all tot lifetime totlifetime = [] for ii in range(len(selected_files)): sumlifetime = 0 for elem in perc: sumlifetime = sumlifetime + perc[elem][ii] totlifetime.append(sumlifetime) #3rd: compute percentages for elem in perc: for ii in range(len(selected_files)): perc[elem][ii] = perc[elem][ii] / totlifetime[ii] #***************************** #******************* #******* #**** Plot the percentages and write file with percentages newfilename = statfile.split( '.dat')[0] + '_' + variable + '-elements' + '.txt' nf = open(newfilename, 'w') if variable == 'rho': nf.write('Density(g/cm3)\t' + '\t'.join( str(round(density, 2)) for density in xdata[variable]) + '\n') else: nf.write('Temperature(K)\t' + '\t'.join(str(temp) for temp in xdata[variable]) + '\n') ydata = [] ycolors = [] labels = [] for elem in perc: #sort the data by the x value x, y = zip(*sorted(zip(xdata[variable], perc[elem]))) #plot lines line, = ax.plot(x, y, '.--', color=colors_elem[elem], markersize=plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"], label=elem) label_line(ax, line, elem, halign='center') #write data in file nf.write(elem + '\t' + '\t'.join(str(round(data, 4)) for data in perc[elem]) + '\n') #for stackplot only ydata.append(y) ycolors.append(colors_elem[elem]) labels.append(elem) #plot stacked area #plt.stackplot(x,ydata[0],ydata[1],ydata[2],ydata[3], colors = ycolors, labels = labels ) #plot lines of congruent gas for elem in congruent: ax.axhline(y=congruent[elem], color=colors_elem[elem], linewidth=plot_parameters["size_lines"] / 1.5, linestyle=':') #legend = plt.legend(bbox_to_anchor=(1.01, 1), loc='upper left', fontsize = plot_parameters["size_fonts"], title = '$\\bf{Elements}$', borderaxespad=0., ncol = 1) #plt.setp(legend.get_title(),fontsize= plot_parameters["size_fonts"]) print(newfilename, 'is created') figurename = figurename + '.pdf' plt.savefig(figurename, bbox_inches='tight', dpi=300) print(figurename, 'is created')
def main(argv): """ ********* Main program ********* """ files = [] all_lifetimes = {} #dictionnary containing lifetimes for each cluster all_length = {}#dictionnary containing length of cluster for each cluster all_clusters_sizes = [] #list with all the cluster sizes accross all files all_species = [] #list with all the species accross all files nsubfig = np.zeros(13,dtype=int) #list of number of subfig per natoms cluster order_species={} #dictionnary to order all the species in each column for ii in range(1,14): order_species[ii]=[] #parameters for the figures depending on the output format (presentation or article) plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (8,4),"size_markers" : 4,"size_lines" : 1,"shift_labelpad" : 20} colors_T = {'2000':'#800080','3000':'#297fff','4000':'#00ff00','4500':'#bae200','5000':'#ffcd01','6000':'#ff0101','6500':'#ff00a2','7000':'#ff01de'} letters = ['a','b','c','d','e','f','g','h','i'] #other parameters Na=6.022*10**23 try: options,arg = getopt.getopt(argv,"hm:f:",["mineralfile","filename"]) except getopt.GetoptError: print("plot_speciation-lifetime-r1.py -m <mineralfile with elements> -f <one filename of the same format name than all we want to plot> ") sys.exit() for opt,arg in options: if opt == '-h': print('') print('plot_speciation-lifetime-r1.py program to Plot lifetime barchart for all clusters smaller then 13 atoms, one subfigure per cluster, one figure per speciation_r1.popul.dat file created by the script speciation_lifetime.py') print("plot_speciation-lifetime-r1.py -m <mineralfile with elements> -f <one filename of the same format name than all we want to plot> ") print("") print('requires the file containing elements and number (in order to compute the densities)') print('') sys.exit() elif opt in ("-m","--mineralfile"): mineralfile = str(arg) elif opt in ("-f","--filename"): firstfilename = str(arg) #***** Calculation of the molecular mass with open(mineralfile,'r') as mf: entry = mf.readline() elements = entry.split()[1:] entry = mf.readline() number = entry.split()[1:] MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #***** 1st step : List of all the files concerned by the T and acell cell = firstfilename.split('.outcar.umd.dat')[0].split('_')[3].strip('a') speciation = firstfilename.split('.outcar.umd.dat.r')[-1].split('.popul.dat')[0] length = firstfilename.split('.popul.dat_L')[-1].split('.txt')[0] filename = '*_a'+cell+'*outcar.umd.dat.r'+speciation+'.popul.dat_L'+length+'*.txt' print('I search for files of type', filename) allfiles = sorted(glob.glob(filename)) #I list every population file created by plot_speciation-lifetime.py in alphabetic order #print('all files are:',allfiles) #we remove the empty files (the ones created by hand) from the file list for file in allfiles: if os.stat(file).st_size != 0: files.append(file) #print('selected files are:',files) #***** 2nd step : Extraction of all cluster type from all files in order to have max number of rows per columns for file in files: print('************* for file',file) with open(file,'r') as f: #**** Extract species and lengths line = f.readline() #we read the first line with cluster sizes clusters_sizes = line.split('\n')[0].split('\t') line = f.readline() #we read the second line with cluster names clusters=line.split('\n')[0].split('\t') #print('clusters in file:',clusters) for ii in range(len(clusters)): all_length[clusters[ii]] = int(clusters_sizes[ii]) #***** Count the number of subfigure per natoms cluster and Create dictionnary to order all the species in each column #update of the list containing each cluster size for species in clusters: if species not in all_species: all_clusters_sizes.append(clusters_sizes[clusters.index(species)]) #update of the newcount based on all the cluster that have been seen up to now for ii in range(1,14): newcount = all_clusters_sizes.count(str(ii)) if nsubfig[ii-1] < newcount: nsubfig[ii-1] = newcount for species in clusters: if species in order_species[all_length[species]]: continue else: order_species[all_length[species]].append(species) all_species.append(species) #creation of the list containing each species ONCE all_species = [] for ii in range(1,14): for species in order_species[ii]: all_species.append(species) #print('total number of subfig:',nsubfig) print('order of species',order_species) #print('all the species are',all_species) #**** 3rd step : Core of the script = extraction of data and plot for file in files: print('************* for file',file) letter = letters[allfiles.index(file)] #**** 3.1) Extraction of T and acell temperature, acell = split_name(file) #**** 3.2) Extract all data with open(file,'r') as f: #**** Extract species and lengths line = f.readline() #we read the first line with cluster sizes clusters_sizes = line.split('\n')[0].split('\t') line = f.readline() #we read the second line with cluster names clusters=line.split('\n')[0].split('\t') for ii in range(len(clusters)): all_length[clusters[ii]] = int(clusters_sizes[ii]) all_lifetimes[clusters[ii]] = [] #**** Extract lifetimes while True: line = f.readline() #we read all the other lines with lifetime for each apparition if not line: break else: entry=line.split('\n')[0].split('\t') for ii in range(0,len(clusters)): #we store the correct lifetime in the dictionnary for the corresponding key if entry[ii] != '': all_lifetimes[clusters[ii]].append(float(entry[ii])) else: continue #**** 3.3) plot #fig 1 has the clusters up to 7 atoms print("creation of plot 1 with",max(nsubfig[0:7]),'subplots in rows') fig1 = plt.figure(figsize=(7*2,max(nsubfig[0:7])*1.9), constrained_layout=False) gs1 = fig1.add_gridspec(nrows=max(nsubfig[0:7]), ncols=7, width_ratios =np.ones(7), height_ratios =np.ones(max(nsubfig[0:7])), wspace = 0.5, hspace = 0.5, figure=fig1) #fig 2 has the clusters from 8 to 13 atoms print("creation of plot 2 with",max(nsubfig[7:]),'subplots in rows') fig2 = plt.figure(figsize=(7*2,max(nsubfig[7:])*1.9), constrained_layout=False) gs2 = fig2.add_gridspec(nrows=max(nsubfig[7:]), ncols=7, width_ratios =np.ones(7), height_ratios =np.ones(max(nsubfig[7:])), wspace = 0.5, hspace = 0.5, figure=fig2) for species in all_species: if all_length[species] < 8: #print(species, order_species[all_length[species]].index(species), all_length[species]-1 ) #plot only if there is something to draw if species in clusters: #creation subplot ax = fig1.add_subplot(gs1[order_species[all_length[species]].index(species), all_length[species]-1]) #text ax.text(0.85,0.85, format_1label(species) , transform=ax.transAxes, horizontalalignment = 'right', fontsize = plot_parameters["size_fonts"]) if order_species[all_length[species]].index(species) == 0: ax.text(0.5,1.1, str(all_length[species]) , transform=ax.transAxes, horizontalalignment = 'center', fontsize = plot_parameters["size_fonts"], fontweight = 'bold') #plot ax.bar(np.arange(len(all_lifetimes[species])),all_lifetimes[species], width = 1, align = 'edge', color = colors_T[temperature]) #axis limits (pretty, rounded up) maxnumberx = max_axis(len(all_lifetimes[species])) ax.set_xticks([0, maxnumberx]) ax.set_xlim([0, maxnumberx]) maxnumbery = max_axis(max(all_lifetimes[species])) ax.set_yticks([0,maxnumbery]) ax.set_ylim([0,maxnumbery]) ax.tick_params(which = 'both', labelsize = plot_parameters["size_font_ticks"], width = plot_parameters["size_lines"]/2) #empty subplot otherwise else: ax = fig1.add_subplot(gs1[order_species[all_length[species]].index(species), all_length[species]-1], frameon=False) ax.tick_params(labeltop=False, top=False, labelbottom=False, bottom=False, labelleft=False, left=False, labelright = False, right=False) else: #plot only if there is something to draw if species in clusters: #creation subplot ax = fig2.add_subplot(gs2[order_species[all_length[species]].index(species), all_length[species]-8]) #text ax.text(0.85,0.85, format_1label(species) , transform=ax.transAxes, horizontalalignment = 'right', fontsize = plot_parameters["size_fonts"]) if order_species[all_length[species]].index(species) == 0: ax.text(0.5,1.1, str(all_length[species]) , transform=ax.transAxes, horizontalalignment = 'center', fontsize = plot_parameters["size_fonts"], fontweight = 'bold') #plot ax.bar(np.arange(len(all_lifetimes[species])),all_lifetimes[species], width = 1, align = 'edge', color = colors_T[temperature]) #axis limits (pretty, rounded up) maxnumberx = max_axis(len(all_lifetimes[species])) ax.set_xticks([0, maxnumberx]) ax.set_xlim([0, maxnumberx]) maxnumbery = max_axis(max(all_lifetimes[species])) ax.set_yticks([0,maxnumbery]) ax.set_ylim([0,maxnumbery]) ax.tick_params(which = 'both', labelsize = plot_parameters["size_font_ticks"], width = plot_parameters["size_lines"]/2) else: ax = fig2.add_subplot(gs2[order_species[all_length[species]].index(species), all_length[species]-8], frameon=False) ax.tick_params(labeltop=False, top=False, labelbottom=False, bottom=False, labelleft=False, left=False, labelright = False, right=False) #**** 4th step : Add a big invisible subplot in order to center x and y labels (since the ticklabels are turned off we have to move the x and y labels with labelpad) ax0 = fig1.add_subplot(gs1[:,:], frameon=False) ax0bis = fig2.add_subplot(gs2[:,:], frameon=False) for ax in [ax0,ax0bis]: ax.tick_params(labeltop=False, top=False, labelbottom=False, bottom=False, labelleft=False, left=False, labelright = False, right=False) ax.set_xlabel(r'Number of species occurence', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]*1.2) ax.set_ylabel(r'Lifetime (fs)', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]*2.5) ax.text(-0.1,1, letter , transform=ax.transAxes, horizontalalignment = 'left', fontweight = 'bold', fontsize = 12, bbox=dict(facecolor='none', edgecolor='k', pad=3.0)) #**** 5th step: Save plot figurename1 = file.split('/')[-1].split('.txt')[0]+'_matrix1.pdf' fig1.savefig(figurename1, dpi=300, bbox_inches='tight') #remove 'tight' to take into account options of subplots_adjust figurename2 = file.split('/')[-1].split('.txt')[0]+'_matrix2.pdf' fig2.savefig(figurename2, dpi=300, bbox_inches='tight') #remove 'tight' to take into account options of subplots_adjust print(figurename1, 'is created') print(figurename2, 'is created') #plt.show() #**** 6th step: For files that does not exist and for which we created a corresponding empty file, we create an empty figure and remove them of the list of files for file in allfiles: if os.stat(file).st_size == 0: temperature, acell = split_name(file) letter = letters[allfiles.index(file)] #fig 1 has the clusters up to 7 atoms fig1 = plt.figure(figsize=(7*2,max(nsubfig[0:7])*1.9), constrained_layout=False) gs1 = fig1.add_gridspec(nrows=max(nsubfig[0:7]), ncols=7, width_ratios =np.ones(7), height_ratios =np.ones(max(nsubfig[0:7])), wspace = 0.5, hspace = 0.5, figure=fig1) #fig 2 has the clusters from 8 to 13 atoms fig2 = plt.figure(figsize=(7*2,max(nsubfig[7:])*1.9), constrained_layout=False) gs2 = fig2.add_gridspec(nrows=max(nsubfig[7:]), ncols=7, width_ratios =np.ones(7), height_ratios =np.ones(max(nsubfig[7:])), wspace = 0.5, hspace = 0.5, figure=fig2) #**** 3rd step : Add a big invisible subplot in order to center x and y labels (since the ticklabels are turned off we have to move the x and y labels with labelpad) ax0 = fig1.add_subplot(gs1[:,:], frameon=False) ax0bis = fig2.add_subplot(gs2[:,:], frameon=False) for ax in [ax0,ax0bis]: ax.tick_params(labeltop=False, top=False, labelbottom=False, bottom=False, labelleft=False, left=False, labelright = False, right=False) ax.set_xlabel(r'Number of species occurence', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]*1.2) ax.set_ylabel(r'Lifetime (fs)', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]*2.5) ax.text(-0.1,1, letter , transform=ax.transAxes, horizontalalignment = 'left', fontweight = 'bold', fontsize = 12, bbox=dict(facecolor='none', edgecolor='k', pad=3.0))
def main(argv): """ ********* Main program ********* """ #other dictionnaries and parameters for the figure colors_densities = {} lines = { } #dictionnary for the lines for legend (the keys are acell or densities, and values are the color of lines) limits = {} #dictionnary for y limits AllTrho = [] #list for storing the temperature in order to sort them files = [] #other parameters Na = 6.022 * 10**23 #avogadro constant try: options, arg = getopt.getopt(argv, "hm:", ["mineralfile"]) except getopt.GetoptError: print("plot_msd_allrhoT.py -m <mineralfile with elements>") sys.exit() for opt, arg in options: if opt == '-h': print( "plot_msd_allrhoT.py script to plot all the msd at every acell and T (matrix with atom in columns and T in lines)" ) print("plot_msd_allrhoT.py -m <mineralfile with elements> ") print( 'requires the file containing elements and number (in order to compute the densities)' ) sys.exit() elif opt in ("-m", "--mineralfile"): mineralfile = str(arg) size_fonts = 12 size_fonts_ticks = 10 size_figure = (14, 14) size_lines = 2 shift_label = 20 #***** Calculation of the molecular mass with open(mineralfile, 'r') as mf: entry = mf.readline() elements = entry.split()[1:] entry = mf.readline() number = entry.split()[1:] MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #***** List the files in alphabetical order regarding to temperature (need to extract T and compute it because of the T4.5 listed before T4) initfiles = sorted(glob.glob( '*outcar.msd.dat')) #I list every msd files in alphabetic order for file in initfiles: temperature, acell = split_name(file) temperature = int(float(temperature.strip('T')) * 1000) AllTrho.append((temperature, acell)) AllTrho = sorted(AllTrho) #first I sort everything in alphabetical order AllTrho = sorted(AllTrho, key=lambda tup: tup[0], reverse=True) #then I reverse the order of the T only for Trho in AllTrho: T = Trho[0] / 1000 rem = Trho[0] % 1000 if rem == 0: T = int(T) pattern = '_T' + str(T) + '_nvt_a' + Trho[1] for file in initfiles: if re.search(pattern, file): files.append(file) #print(files) #***** Calculation of the number of figures (T * ntypat) firstfile = files[0] #I take the first file temperature0, acell0 = split_name(firstfile) with open(firstfile, 'r') as f: atoms = f.readline() atoms = atoms.strip('time_(fs)').split() #I extract the atoms T_numsubplot = [temperature0 ] #list for the correspondance T / subplot number for file in files: temperature, acell = split_name(file) if temperature != temperature0: T_numsubplot.append(temperature) temperature0 = temperature temperature0, acell0 = split_name(firstfile) #***** Count of the number of densities (needed for the automatic color change) #first store every density into the dictionary for file in files: #calculation of densities in g/cm3 temperature, acell = split_name(file) Volume = float(acell)**3 Density = MN / (Na * Volume * 10**(-24)) #we store the densities into the dictionnary colors_densities[round(Density, 1)] = [] #now the dictionary has every possible densities of our mineral, we attribute the colors to each density name = 'devon' cm_data = np.loadtxt( "/Users/akobsch/Dropbox/Recherche/PhD-MD-silicates/simulations/scripts/Analysis/ScientificColourMaps6/" + name + "/" + name + ".txt") #cm_data = cm_data[::-1] #for reverse colors (hawaii,lajolla) new_map = LinearSegmentedColormap.from_list( 'new', cm_data[:-20]) #cm_data[:-20] for devon, davos, oslo color = iter(new_map(np.linspace( 0, 1, len(colors_densities)))) #Creation of the color list allrho = [] for key in natsort.natsorted(colors_densities): c = next(color) colors_densities[key] = c allrho.append(key) #***************************** #******************* #******* #Read & plot plt.close(1) fig = plt.figure(1, figsize=size_figure) plt.subplots_adjust(top=0.97, bottom=0.07, right=0.89, left=0.07, hspace=0, wspace=0) plt.subplot(len(T_numsubplot), len(atoms), 1) ax = plt.gca() for atom in atoms: for file in files: #calculation of densities in g/cm3 temperature, acell = split_name(file) Volume = float(acell)**3 Density = MN / (Na * Volume * 10**(-24)) #change of subplot if temperature != temperature0: plt.subplot( len(T_numsubplot), len(atoms), T_numsubplot.index(temperature) * 4 + 1 + atoms.index(atom)) ax = plt.gca() temperature0 = temperature #importation of data Temps, DataAtom = np.loadtxt(file, skiprows=1, usecols=(0, atoms.index(atom) + 1), unpack=True) #plot lines[str(round(Density, 1))], = ax.plot(Temps, DataAtom, '-', color=colors_densities[round( Density, 1)], linewidth=size_lines) #we add x and y labels outside the plot on the right columns and lines if T_numsubplot.index(temperature) == 0: ax.set_xlabel(atoms[atoms.index(atom)], fontweight='bold', fontsize=size_fonts) ax.xaxis.set_label_position('top') if atoms.index(atom) == len(atoms) - 1: ax.set_ylabel(str(int(float(temperature.strip('T')) * 1000)) + ' K', fontweight='bold', fontsize=size_fonts) ax.yaxis.set_label_position('right') #limitation of data along x and ticks (linear only) Xlimit = 9999 #major_ticks = np.arange(0, Xlimit, 2000) #minor_ticks = np.arange(0, Xlimit, 500) #ax.set_xticks(major_ticks) #ax.set_xticks(minor_ticks, minor=True) ax.set_xscale('log') ax.set_xlim(10, Xlimit) #limitation of data along y ax.set_yscale('log') if atoms.index(atom) == 0: ax.autoscale(axis='y', tight=True) limits[temperature] = (0.100001, ax.get_ylim()[1]) ax.set_ylim(limits[temperature]) #we make the graph prettier if atoms.index(atom) != 0: plt.setp(ax.get_yticklabels(), visible=False) if T_numsubplot.index(temperature) != len(T_numsubplot) - 1: plt.setp(ax.get_xticklabels(), visible=False) ax.xaxis.set_ticks_position('both') ax.yaxis.set_ticks_position('both') ax.yaxis.set_tick_params(which='both', direction='inout') ax.xaxis.set_tick_params(which='both', direction='inout') ax.grid(axis='y', which='major', linestyle='--', linewidth=size_lines / 2, alpha=0.5) ax.set_facecolor((1, 1, 1, 0)) #ax.get_xaxis().set_tick_params(direction='inout') #ax.get_yaxis().set_tick_params(direction='inout') #plt.setp(ax.get_xticklabels()[-2], visible=False) #plt.setp(ax.get_yticklabels()[-1], visible=False) ax.tick_params(which='both', labelsize=size_fonts_ticks, width=size_lines / 2) #************ Fine tune figure ax0 = fig.add_subplot(111, frameon=False) plt.tick_params(labeltop=False, top=False, labelbottom=False, bottom=False, labelleft=False, left=False, labelright=False, right=False) ax0.set_xlabel(r'Time (fs)', fontweight='bold', fontsize=size_fonts, labelpad=shift_label) ax0.set_ylabel(r"Mean square displacement ($\mathregular{\AA^2}$)", fontsize=size_fonts, fontweight='bold', labelpad=shift_label + shift_label / 2) #************ legend ncols = 12 custom_lines = [ Line2D([0], [0], color=colors_densities[key], ls='-', marker='', linewidth=size_lines) for key in allrho[:ncols] ] legend = ax0.legend([col for col in custom_lines], [label for label in allrho[:ncols]], title='$\\bf{Density}$ (g.cm$^{-3}$)', bbox_to_anchor=(0.5, 1.05), loc="lower center", fontsize=size_fonts, borderaxespad=0., ncol=ncols) custom_lines = [ Line2D([0], [0], color=colors_densities[key], ls='-', marker='', linewidth=size_lines) for key in allrho[ncols:] ] legend2 = ax0.legend([col for col in custom_lines], [label for label in allrho[ncols:]], bbox_to_anchor=(0.5, 1.05), loc="upper center", fontsize=size_fonts, borderaxespad=0., ncol=ncols) ax0.add_artist(legend) plt.setp(legend.get_title(), fontsize=size_fonts) figurename = 'msd_' + file.split('_')[0] + '.pdf' plt.savefig(figurename, bbox_inches='tight', dpi=300) print(figurename, 'is created')
def main(argv): """ ********* Main program ********* """ #other dictionnaries and parameters for the figure markers = [ 'o', '^', '*', 'P', 'X', '<', '>', 'v', '8', 's', 'p', 'h', '+', 'D' ] #************************************Be sure you have enough markers for all the pairs you want to plot colors_T = { 'T2': '#800080', 'T3': '#297fff', 'T4': '#00ff00', 'T4.5': '#bae200', 'T5': '#ffcd01', 'T5.5': '#ff6e00', 'T6': '#ff0101', 'T6.5': '#ff00a2', 'T7': '#ff01de', 'T7.5': '#ffa6f4', 'T10': '#ffe86e', 'T15': '#ffbf90', 'T20': '#ff7788' } plot_parameters = { "size_fonts": 12, "size_font_ticks": 10, "size_figure": (4, 4), "size_markers": 8, "size_lines": 1, "shift_labelpad": 20 } label = { 'xmax': r"1st $g(r)$ peak location ($\AA$)", 'xmin': r"Coordination sphere radius ($\AA$)", 'bond': r"Bond length ($\AA$)" } #initialization of variables elements = '' number = '' atoms = [] legend_labels = {} data = { } #big dictionnary with inside dist dictionnary and rho, all coresponding to different T distance_columns = {'xmax': 1, 'xmin': 3, 'bond': 5} xvariable = 'rho' TP = {} #dictionnary with P and T in each simufile #dictionnary for fullaverages file in full version column_number = { 'rho': 2, 'P': 5, 'stdev_P': 6, 'err_P': 7, 'T': 8, 'stdev_T': 9, 'err_T': 10, 'E': 14, 'stdev_E': 15, 'err_E': 16, 'Cvm_Nkb': 23, 'stdev_Cvm_Nkb': 24, 'Cvm': 25, 'stdev_Cvm': 26, 'testCv': 31, 'stdev_testCv': 32 } #other parameters Na = 6.022 * 10**23 try: options, arg = getopt.getopt(argv, "hf:g:j:a:d:x:", [ "fgofrsfilename1", "gofrsfilename2", "jgofrsfilename3", "atom", "distance", 'xvariable' ]) except getopt.GetoptError: print( "plot_distances_5x3.py -f <_gofrs.txt 1> -g <_gofrs.txt 2> -j <_gofrs.txt 3> -a <pairs of atoms>(ex: 'Ca-O,Ca-Ca,O2') -d <distance type to print ('xmax' or 'xmin' or 'bond')> -x <xvariable (P or rho)>" ) sys.exit() for opt, arg in options: if opt == '-h': print('') print( 'plot_distances_5x3.py program to plot xmin,xmax or bond length as a function of density or acell for each T and 5 selected pairs of atoms' ) print( "plot_distances_5x3.py -f <_gofrs.txt 1> -g <_gofrs.txt 2> -j <_gofrs.txt 3> -a <pairs of atoms>(ex: 'Ca-O,Ca-Ca,O2') -d <distance type to print ('xmax' or 'xmin' or 'bond')> -x <xvariable (P or rho)> " ) print( "plot_distances_5x3.py requires _gofrs.txt file (use analyze_gofrs_semi_automatic.py)" ) print('') print( 'For plots as function of P, make sure the files from fullaverages.py are in the current folder' ) print( 'WARNING: this script use the filenames inside the _gofrs.txt file to extract the temperature and cell size for the plot. If you do have both information in your filenames at the same place, then update the function split_name to extract them correctly.' ) sys.exit() if opt in ('-f', '--gofrsfilename'): filename1 = str(arg) elif opt in ('-g', '--gofrsfilename'): filename2 = str(arg) elif opt in ('-j', '--gofrsfilename'): filename3 = str(arg) elif opt in ('-a', '--atoms'): atoms = arg.split(',') #list of atom pairs we want to analyze here elif opt in ('-d', '--distance'): distance_type = str(arg) elif opt in ('-x', '--xvariable'): xvariable = str(arg) files = [filename1, filename2, filename3] #******* write data analysis and find ymax, ymin for every atoms ylim_allT = { 'Ca-O': [9999, 0], 'K-O': [9999, 0], 'Na-O': [9999, 0], 'Al-O': [9999, 0], 'Si-O': [9999, 0], 'O-O': [9999, 0], 'O2': [9999, 0], 'Ca-Ca': [9999, 0], 'K-K': [9999, 0], 'Na-Na': [9999, 0], 'Ca-Al': [9999, 0], 'K-Al': [9999, 0], 'Na-Al': [9999, 0], 'Al-Al': [9999, 0], 'Al-Si': [9999, 0], 'Si-Si': [9999, 0] } for filename in files: print('********Analysis', filename) #******* 1st step: read the header and extract all relevant informations #creation of elements and number lists and initialization of T skip_head = 0 with open(filename, 'r') as f: while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t') skip_head += 1 if entry[0] == 'elements': elements = list(filter(None, entry[1:])) print(elements) if entry[0] == 'number': number = list(filter(None, entry[1:])) print(number) if entry[0] == 'pair': allpairs_ordered = entry[1:] if entry[0] == 'file': line = f.readline() entry = line.split() temperature0, acell0 = split_name(entry[0]) break if elements != '' and number != '': #calculation of M*N nedded for the calculation of densities MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] else: MN = 0 #creation of the list containing all the pairs only once and in the same order unique_pairs = [allpairs_ordered[0]] for i in range(1, len(allpairs_ordered)): if allpairs_ordered[i] != allpairs_ordered[i - 1]: unique_pairs.append(allpairs_ordered[i]) print('The index for each pair is:') #initialization of the dictionnaries containing the data #we create sub dictionnaries of the data dictionnary data = {} data[temperature0] = {'file': [], 'rho': [], 'dist': {}} selected_pairs = [] #pairs to analyze along with their column number for atom_pair in atoms: for i in range(0, len(unique_pairs)): if (unique_pairs[i] == atom_pair): data[temperature0]['dist'][atom_pair] = [] selected_pairs.append( (atom_pair, i * 5 + distance_columns[distance_type])) print(atom_pair, i * 5 + distance_columns[distance_type]) print('All the pairs availables in the file are:', unique_pairs) print('The pairs selected for the plot are:', selected_pairs) #******* 2nd step: extraction of data from the fullgofrs.txt file with open(filename, 'r') as f: [f.readline() for i in range(skip_head)] while True: line = f.readline() if not line: break else: entry = line.split('\t') temperature, acell = split_name(entry[0]) if temperature != temperature0: #if we change T: #we create sub dictionnaries of the data dictionnary and we re-initialize the arrays temperature0 = temperature data[temperature0] = { 'file': [], 'rho': [], 'dist': {} } for i in range(len(selected_pairs)): data[temperature0]['dist'][selected_pairs[i] [0]] = [] if MN == 0: data[temperature0]['rho'].append( float(acell)) #rho is replaced by acell else: data[temperature0]['rho'].append( MN / (Na * float(acell)**3 * 10**(-24))) #calculation density data[temperature0]['file'].append(entry[0].split( '/')[-1].split('.gofr.dat')[0]) #extract filename #we replace the 0 (no data) by NaN for i in range(len(selected_pairs)): print(selected_pairs[i]) if float(entry[selected_pairs[i][1]]) == 0.0: data[temperature0]['dist'][ selected_pairs[i][0]].append(float('nan')) else: data[temperature0]['dist'][ selected_pairs[i][0]].append( float(entry[selected_pairs[i][1]])) #******* 3rd step: analysis #Smooth xmin data using fitting and get minrho, maxrho even if we don't want to update/create .bonds.inp new_xmin, minrho, maxrho, params, chi2_reduced = smoothing_xmin( data, selected_pairs) #******* 4th step: write the deviation from mean in file and update the ymax and ymin # write percentage variation of distance string = '' for sp_tuple in selected_pairs: atom_pair = sp_tuple[0] string = string + '_' + atom_pair newfilename = 'distance_variation_' + distance_type + '_' + filename[: -4] + string + '.txt' nf = open(newfilename, 'w') for i in range(len(selected_pairs)): atom_pair = selected_pairs[i][0] #print('***************** for atom pair:',atom_pair) nf.write(atom_pair + '\t' + "\t".join(temp for temp in sorted(data)) + "\n") all_means = 'mean' all_range = 'range' all_percent = '%var_from_mean' all_percent_rho = '%var_from_mean_per_rho' all_params_a = 'fitted_parameter_a' all_params_b = 'fitted_parameter_b' all_params_c = 'fitted_parameter_c' all_params_d = 'fitted_parameter_d' all_chi2 = 'chi2_reduced' #plot and prepare the strings to write in the new log file for temp in sorted( data): #loop over temperatures = key in data dictionnary #classic analysis (mean, range, %variation) #print('******* for temperature:',temp) mean_dist = np.nanmean(data[temp]['dist'][atom_pair]) all_means = all_means + '\t' + str(np.round(mean_dist, 2)) #print('mean dist for',atom_pair,'=',np.round(mean_dist,2)) range_var = (np.nanmax(data[temp]['dist'][atom_pair]) - np.nanmin(data[temp]['dist'][atom_pair])) all_range = all_range + '\t' + str(np.round(range_var, 2)) #print('dist range for', atom_pair, '=', np.round(range_var,2)) percent_var_mean = (range_var / mean_dist) * 100 all_percent = all_percent + '\t' + str( np.round(percent_var_mean, 1)) #print('percent var mean for', atom_pair, '=', np.round(percent_var_mean,1)) percent_var_mean_per_rho = percent_var_mean / ( np.nanmax(data[temperature0]['rho']) - np.nanmin(data[temperature0]['rho'])) all_percent_rho = all_percent_rho + '\t' + str( np.round(percent_var_mean_per_rho, 1)) #print('percent var mean per rho for', atom_pair, '=', np.round(percent_var_mean_per_rho,1)) #define bounds for axis if ylim_allT[atom_pair][1] < np.nanmax( data[temp]['dist'][atom_pair]): ylim_allT[atom_pair][1] = np.nanmax( data[temp]['dist'][atom_pair]) if ylim_allT[atom_pair][0] > np.nanmin( data[temp]['dist'][atom_pair]): ylim_allT[atom_pair][0] = np.nanmin( data[temp]['dist'][atom_pair]) nf.write(all_means + '\n') nf.write(all_range + '\n') nf.write(all_percent + '\n') nf.write(all_percent_rho + '\n') nf.write(all_chi2 + '\n') nf.write(all_params_a + '\n') nf.write(all_params_b + '\n') nf.write(all_params_c + '\n') nf.write(all_params_d + '\n') nf.write('\n') nf.close() #update the ylim_allT to have the same vertical scale ylim_allT = update_ylim(ylim_allT, ['Ca-O', 'Na-O', 'K-O']) ylim_allT = update_ylim(ylim_allT, ['Ca-Ca', 'Na-Na', 'K-K']) ylim_allT = update_ylim(ylim_allT, ['Ca-Al', 'Na-Al', 'K-Al']) #************ Plot data print('*******************************') print('******************') print('********') print('Plot') plt.close(1) fig, axes = plt.subplots(nrows=5, ncols=3, figsize=(10, 14)) plt.subplots_adjust(top=0.97, bottom=0.07, right=0.89, left=0.07, hspace=0, wspace=0) for filename in files: #******* 0th step: extract P and T for each thermo file if xvariable == 'P': TP = {} mineralname = filename.split('_')[1] thermofiles = sorted(glob.glob('thermo_' + mineralname + '*.txt')) for file in thermofiles: TP = extract_TP(file, column_number, TP, '') #print(TP) #******* 1st step: read the header and extract all relevant informations #creation of elements and number lists and initialization of T skip_head = 0 with open(filename, 'r') as f: while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t') skip_head += 1 if entry[0] == 'elements': elements = list(filter(None, entry[1:])) print(elements) if entry[0] == 'number': number = list(filter(None, entry[1:])) print(number) if entry[0] == 'pair': allpairs_ordered = entry[1:] if entry[0] == 'file': line = f.readline() entry = line.split() temperature0, acell0 = split_name(entry[0]) break if elements != '' and number != '': #calculation of M*N nedded for the calculation of densities MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] else: MN = 0 #creation of the list containing all the pairs only once and in the same order unique_pairs = [allpairs_ordered[0]] for i in range(1, len(allpairs_ordered)): if allpairs_ordered[i] != allpairs_ordered[i - 1]: unique_pairs.append(allpairs_ordered[i]) #initialization of the dictionnaries containing the data #we create sub dictionnaries of the data dictionnary data = {} data[temperature0] = {'file': [], 'rho': [], 'dist': {}, 'P': []} selected_pairs = [] #pairs to analyze along with their column number for atom_pair in atoms: for i in range(0, len(unique_pairs)): if (unique_pairs[i] == atom_pair): data[temperature0]['dist'][atom_pair] = [] selected_pairs.append( (atom_pair, i * 5 + distance_columns[distance_type])) unique_pairs = [] for sp_tuple in selected_pairs: unique_pairs.append(sp_tuple[0]) print('The pairs selected for the plot are:', unique_pairs) #******* 2nd step: extraction of data from the fullgofrs.txt file with open(filename, 'r') as f: [f.readline() for i in range(skip_head)] while True: line = f.readline() if not line: break else: entry = line.split('\t') temperature, acell = split_name(entry[0]) if temperature != temperature0: #if we change T: #we create sub dictionnaries of the data dictionnary and we re-initialize the arrays temperature0 = temperature data[temperature0] = { 'file': [], 'rho': [], 'dist': {}, 'P': [] } for i in range(len(selected_pairs)): data[temperature0]['dist'][selected_pairs[i] [0]] = [] if MN == 0: data[temperature0]['rho'].append( float(acell)) #rho is replaced by acell else: data[temperature0]['rho'].append( MN / (Na * float(acell)**3 * 10**(-24))) #calculation density data[temperature0]['file'].append(entry[0].split( '/')[-1].split('.gofr.dat')[0]) #extract filename if xvariable == 'P': data[temperature0]['P'].append(TP[entry[0].split( 'outcar.gofr.dat')[0].split('/')[-1]][1]) #we replace the 0 (no data) by NaN for i in range(len(selected_pairs)): if float(entry[selected_pairs[i][1]]) == 0.0: data[temperature0]['dist'][ selected_pairs[i][0]].append(float('nan')) else: data[temperature0]['dist'][ selected_pairs[i][0]].append( float(entry[selected_pairs[i][1]])) #******* 3rd step: analysis #Smooth xmin data using fitting and get minrho, maxrho even if we don't want to update/create .bonds.inp new_xmin, minrho, maxrho, params, chi2_reduced = smoothing_xmin( data, selected_pairs) #******* 4th step: plot of the data #Creation of ticks if MN != 0: major_ticks = np.arange(0.5, 7, 1) minor_ticks = np.arange(0.5, 7, 0.5) else: major_ticks = AutoLocator() minor_ticks = AutoMinorLocator() #plot for i in range(len(selected_pairs)): atom_pair = selected_pairs[i][0] ax = axes[unique_pairs.index(atom_pair), files.index(filename)] #line,col = atom,feldspar #plot and prepare the strings to write in the new log file for temp in sorted( data): #loop over temperatures = key in data dictionnary #print('******* for temperature:',temp) #plot ax.plot(data[temp][xvariable], data[temp]['dist'][atom_pair], '--', color=colors_T[temp], linewidth=plot_parameters["size_lines"], marker=markers[unique_pairs.index(atom_pair)], markersize=plot_parameters["size_markers"]) # ax.text(1.025,0.5, atom_pair ,transform=ax.transAxes, fontsize=plot_parameters["size_fonts"], fontweight='bold') ax.text(0.97, 0.9, atom_pair, transform=ax.transAxes, horizontalalignment='right', fontsize=plot_parameters["size_fonts"], fontweight='bold') #Adjustment of ticks and make the graph prettier if xvariable == 'P': ax.set_xlim(1, 275) ax.set_xscale('log') elif MN != 0: ax.set_xticks(major_ticks) ax.set_xticks(minor_ticks, minor=True) ax.set_xlim(minrho, maxrho) else: ax.xaxis.set_major_locator(major_ticks) ax.xaxis.set_minor_locator(minor_ticks) ax.set_xlim(minrho, maxrho) ax.set_facecolor((1, 1, 1, 0)) ax.xaxis.set_ticks_position('both') ax.yaxis.set_ticks_position('both') majorLocator = AutoLocator() minorLocator = AutoMinorLocator() ax.yaxis.set_major_locator(majorLocator) ax.yaxis.set_minor_locator(minorLocator) ax.set_ylim(ylim_allT[atom_pair][0], ylim_allT[atom_pair][1]) if unique_pairs.index(atom_pair) != len(unique_pairs) - 1: plt.setp(ax.get_xticklabels(), visible=False) if files.index(filename) != 0: plt.setp(ax.get_yticklabels(), visible=False) ax.tick_params(which='both', labelsize=plot_parameters["size_font_ticks"], width=plot_parameters["size_lines"] / 2) # Fine-tune figure ax0 = fig.add_subplot(111, frameon=False) plt.tick_params(labeltop=False, top=False, labelbottom=False, bottom=False, labelleft=False, left=False, labelright=False, right=False) if xvariable == 'P': ax0.set_xlabel(r'Pressure (GPa)', fontweight='bold', fontsize=plot_parameters["size_fonts"], labelpad=plot_parameters["shift_labelpad"]) elif MN != 0: ax0.set_xlabel(r'Density (g.cm$^{-3}$)', fontweight='bold', fontsize=plot_parameters["size_fonts"], labelpad=plot_parameters["shift_labelpad"]) else: xvariable = 'acell' ax0.set_xlabel(r'Cell size ($\AA$)', fontweight='bold', fontsize=plot_parameters["size_fonts"], labelpad=plot_parameters["shift_labelpad"]) ax0.set_ylabel(label[distance_type], fontsize=plot_parameters["size_fonts"], fontweight='bold', labelpad=plot_parameters["shift_labelpad"] + plot_parameters["shift_labelpad"] / 1.3) #Legend for temp in data: legend_labels[str(int(float(temp.strip('T')) * 1000))] = mpatches.Patch(color=colors_T[temp]) s = [(k, legend_labels[k]) for k in sorted(legend_labels.keys(), reverse=False)] #legend = ax0.legend([v for k,v in s],[k for k,v in s], title = ' $\\bf{Temperature}$ \n (K)',loc='upper left',bbox_to_anchor=(1.2, 1), fontsize = plot_parameters["size_fonts"], borderaxespad=0.,ncol=1) #plt.setp(legend.get_title(),fontsize= plot_parameters["size_fonts"]) #plt.title(filename.split('.txt')[0], fontsize = plot_parameters["size_fonts"], fontweight='bold') #save the figure string = '' for atom_pair in atoms: string = string + '_' + atom_pair figurename = 'distance_' + distance_type + '_all' + string + '_' + xvariable + '.pdf' fig.savefig(figurename, bbox_inches='tight', dpi=150) print(figurename, ' created')
def main(argv): """ ********* Main program ********* """ nmeltatoms = 100 #limit of natoms to consider a species being part of the melt #other dictionnaries and parameters for the figure for article version letter = '' statfile2 = '' plot_parameters = { "size_fonts": 12, "size_font_ticks": 10, "size_figure": (8, 4), "size_markers": 4, "size_lines": 1, "shift_labelpad": 20 } #plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (8,4),"size_markers" : 10,"size_lines" : 2,"shift_labelpad" : 20} #other parameters Na = 6.022 * 10**23 try: options, arg = getopt.getopt(argv, "hf:g:v:m:d:l:", [ "file1", "gfile2", "variable", "mineralfile", "density_max", "letter" ]) except getopt.GetoptError: print( "plot_speciation-r1-species.py -v <variable (rho,T)> -m <mineralfile with elements> -f <stat-concentrate_r1_abso_filename> -g <stat-concentrate_r1_abso_filename2> -d <maximum density to plot in g/cm3> -l <letter for article subplot, default = ''>" ) sys.exit() for opt, arg in options: if opt == '-h': print('') print( 'plot_speciation-r1-species.py program to Plot abundance of chemical species for selected cation as a function of rho or T' ) print( "plot_speciation-r1-species.py -v <variable (rho,T)> -m <mineralfile with elements> -f <stat-concentrate_r1_abso_filename> -g <stat-concentrate_r1_abso_filename2> -d <maximum density to plot in g/cm3> -l <letter for article subplot, default = ''>" ) print( 'requires the file containing elements and number (in order to compute the densities)' ) print('') sys.exit() elif opt in ("-f", "--file1"): statfile1 = str(arg) elif opt in ("-g", "--gfile2"): statfile2 = str(arg) elif opt in ("-v", "--variable"): variable = str(arg) elif opt in ("-m", "--mineralfile"): mineralfile = str(arg) elif opt in ("-d", "--density_max"): max_den = float(arg) elif opt in ("-l", "--letter"): letter = str(arg) #***** Calculation of the molecular mass with open(mineralfile, 'r') as mf: entry = mf.readline() elements = entry.split()[1:] entry = mf.readline() number = entry.split()[1:] MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #***** Creation of the plot if statfile2 != '': allstatfiles = [statfile1, statfile2] with open(statfile1, 'r') as f: line = f.readline() file1 = line.split()[1] with open(statfile2, 'r') as f2: line = f2.readline() file2 = line.split()[1] fig, ax1, ax2 = creation_plot2(variable, file1, file2, MN, plot_parameters, max_den, letter) figurename = statfile1.split('/')[-1].split( '.dat')[0] + '+' + statfile2.split('/')[-1].split( '.dat')[0] + '_' + variable + '-species' else: allstatfiles = [statfile1] fig, ax1 = creation_plot(variable, plot_parameters, max_den, letter) figurename = statfile1.split('.dat')[0] + '_' + variable + '-species' for ii in range(len(allstatfiles)): statfile = allstatfiles[ii] #selection of the plot if ii == 1: ax = ax2 else: ax = ax1 #initialisation xdata = {'T': [], 'rho': []} #dictionnary containing the x data data = [] #list containing y data melt = [] #list containing y data for species with 100 atoms or more selected_files = [ ] #list containing the files we use for the plot (depends on the density limit) species1 = [] list_colored_species = [] list_colored_red = [] list_colored_blue = [] list_colored_purple = [] list_colored_green = [] list_grey_species = [] list_black_species = ["melt-like"] colors_species = {} #***** Count of the number of clusters for the selected atom type (needed for the automatic color change) #first store every cluster type into the dictionary if re.search("L208", statfile): #print("we group all the species of more than nmeltatoms atoms under the denomination 'melt-like'") with open(statfile, 'r') as f: line = f.readline() while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t') if len(entry) > 1: natoms = count_natom(entry[0]) if natoms < nmeltatoms: species1.append(entry[0]) colors_species[entry[0]] = [] species1.append("melt-like") colors_species["melt-like"] = [] else: #print("we use the standard script") with open(statfile, 'r') as f: line = f.readline() while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t') if len(entry) > 1: species1.append(entry[0]) colors_species[entry[0]] = [] #***************************** #******************* #******* #Read and compute percentages #in case of speciation r1 L208, we group all the species of more than 100 atoms under the denomination "melt-like" with open(statfile, 'r') as f: line = f.readline() entry = line.split() files = entry[1:] #creation of the x data list for file in files: temperature, acell = split_name(file) density = MN / (Na * float(acell)**3 * 10**(-24)) if density <= max_den: xdata['rho'].append(density) #calculation density xdata['T'].append(int(temperature)) selected_files.append(file) if re.search("L208", statfile): print("we group all the species of more than", nmeltatoms, "atoms under the denomination 'melt-like'") #creation of the y data matrix while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t')[:-1] linedata = [] #we initialize the list of data per line if len(entry) > 1: for i in range(1, len(entry)): if files[ i - 1] in selected_files: #if the column which corresponding file is in the selected files, then we use the data if entry[i] == '': entry[i] = 0 else: entry[i] = float(entry[i]) linedata.append( entry[i] ) #we create a list of the data for this line (cluster) natoms = count_natom(entry[0]) if natoms < nmeltatoms: data.append( linedata[:] ) #we add this list to the big list of data in order to have nested lists else: melt.append(linedata[:]) print('for files', selected_files) print('all species are', species1, len(species1)) print('and density', xdata['rho']) #calculation of the percentages per density totalsmelt = np.ndarray.tolist(np.sum( melt, 0)) #we sum all the melt species together data.append( totalsmelt[:]) #and we add this total to the data matrix print('initial data of len', np.size(data, 0), np.size(data, 1)) totals = np.sum(data, 0) #print('totals', totals) for i in range(np.size(data, 0)): for j in range(np.size(data, 1)): if totals[j] == 0: data[i][j] = 0 else: data[i][j] = data[i][j] / totals[j] #print('calculated percentages',data) newtotals = np.sum(data, 0) print('total should be 1', newtotals) else: print("we use the standard script") #creation of the y data matrix while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t')[:-1] linedata = [] #we initialize the list of data per line if len(entry) > 1: for i in range(1, len(entry)): if files[ i - 1] in selected_files: #if the column which corresponding file is in the selected files, then we use the data if entry[i] == '': entry[i] = 0 else: entry[i] = float(entry[i]) linedata.append( entry[i] ) #we create a list of the data for this line (cluster) data.append( linedata[:] ) #we add this list to the big list of data in order to have nested lists print('for files', selected_files) print('all species are', species1) #print('initial data',data) #print('and density', xdata['rho']) #calculation of the percentages per density totals = np.sum(data, 0) #print('totals', totals) for i in range(np.size(data, 0)): for j in range(np.size(data, 1)): if totals[j] == 0: data[i][j] = 0 else: data[i][j] = data[i][j] / totals[j] #print('calculated percentages',data) newtotals = np.sum(data, 0) print('total should be 1', newtotals) #***************************** #******************* #******* # #now the dictionary has every possible cluster, we attribute the colors to each cluster # list_species = [] # color = iter(plt.cm.jet(np.linspace(0,1,len(colors_species)))) #Creation of the color list # for key in natsort.natsorted(colors_species): # c = next(color) # colors_species[key] = c # list_species.append(key) # print(list_species, len(list_species)) #*** check the abundance to put in grey the species less abundant than 1% and put a label only for species more abundante than 5% at least one time for i in range(np.size(data, axis=0)): #loop on each cluster if max(data[i]) < 0.01: colors_species[species1[i]] = '0.5' list_grey_species.append(species1[i]) else: #this is for basic automatic color change list_colored_species.append(species1[i]) #this is for custom color change relative to the feldspars if (species1[i][0] == 'N' or species1[i][0] == 'K' or species1[i][0] == 'C') and re.search( 'Si_1O', species1[i]): list_colored_blue.append(species1[i]) elif re.match('Si_1O', species1[i]): list_colored_red.append(species1[i]) elif (species1[i][0] == 'N' or species1[i][0] == 'K' or species1[i][0] == 'C') and re.search('O', species1[i]): list_colored_purple.append(species1[i]) elif species1[i][0:5] == 'Al_1O': list_colored_green.append(species1[i]) #We add the label if max(data[i]) > 0.05: x_max = xdata[variable][data[i].index(max(data[i]))] y_max = max(data[i]) label = species1[i] #formatage of label label = format1label(label) ax.text(x_max, y_max, label, color='0.35') print('list red', list_colored_red) print('list blue', list_colored_blue) print('list purple', list_colored_purple) print('list green', list_colored_green) #**** we attribute the colors to each cluster with abundance > 0.01 #this is for basic automatic color change #color = iter(plt.cm.jet(np.linspace(0,1,len(list_colored_species)))) #Creation of the color list #for key in natsort.natsorted(list_colored_species): # c = next(color) # colors_species[key] = c #and this is for custom color change relative to the feldspars dict_r = { 'red': ( ( 0.0, 1.0, 1.0 ), # <- at 0.0 (first value), the red component is 1 (second value) (the third value may be alpha) (1.0, 0.3, 1.0)), # <- at 1.0, the red component is 0.3 'green': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0)), 'blue': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0)) } cmreds = LinearSegmentedColormap('reds', dict_r) color_r = iter(cmreds(np.linspace( 0, 1, len(list_colored_red)))) #Creation of the color list for reds dict_b = { 'red': ((0.0, 0.0, 0.0), (1.0, 0.4, 1.0)), 'green': ((0.0, 0.0, 0.0), (1.0, 1.0, 1.0)), 'blue': ( ( 0.0, 1.0, 1.0 ), # <- at 0.0 (first value), the blue component is 1 (second value) (the third value may be alpha) (1.0, 1.0, 1.0)) # <- at 1.0, the blue component is 0.3 } cmblues = LinearSegmentedColormap('blues', dict_b) color_b = iter(cmblues(np.linspace( 0, 1, len(list_colored_blue)))) #Creation of the color list for blues dict_p = { 'red': ( ( 0.0, 0.6, 1.0 ), # <- at 0.0 (first value), the red component is 0.6 (second value) (the third value may be alpha) (1.0, 0.3, 1.0)), # <- at 1.0, the red component is 0.3 'green': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0)), 'blue': ( ( 0.0, 0.6, 1.0 ), # <- at 0.0 (first value), the blue component is 0.6 (second value) (the third value may be alpha) (1.0, 0.3, 1.0)) # <- at 1.0, the blue component is 0.3 } cmpurples = LinearSegmentedColormap('purples', dict_p) color_p = iter(cmpurples(np.linspace(0, 1, len( list_colored_purple)))) #Creation of the color list for purples dict_g = { 'red': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0)), 'green': ( ( 0.0, 1.0, 1.0 ), # <- at 0.0 (first value), the green component is 0.7 (second value) (the third value may be alpha) (1.0, 0.3, 1.0)), # <- at 1.0, the green component is 0.3 'blue': ((0.0, 0.0, 0.0), (1.0, 0.0, 0.0)) } cmgreens = LinearSegmentedColormap('greens', dict_g) color_g = iter(cmgreens(np.linspace( 0, 1, len(list_colored_green)))) #Creation of the color list for greens for key in natsort.natsorted(list_colored_species): if key == 'O_1': colors_species[key] = 'gold' elif key == 'O_2': colors_species[key] = 'darkorange' elif key == 'O_3': colors_species[key] = 'tomato' elif key == 'Na_1' or key == 'K_1' or key == 'Ca_1': colors_species[key] = (0.5, 0, 1.0) elif key == "melt-like": colors_species[key] = '0' else: colors_species[key] = '0.5' colors_species = color_change(color_r, list_colored_red, colors_species) colors_species = color_change(color_b, list_colored_blue, colors_species) colors_species = color_change(color_p, list_colored_purple, colors_species) colors_species = color_change(color_g, list_colored_green, colors_species) #***************************** #******************* #******* #***plot for each cluster and write file with percentages newfilename = statfile.split( '.dat')[0] + '_' + variable + '-species' + '.txt' nf = open(newfilename, 'w') if variable == 'rho': nf.write('Density(g/cm3)\t' + '\t'.join( str(round(density, 2)) for density in xdata[variable]) + '\n') else: nf.write('Temperature(K)\t' + '\t'.join(str(temp) for temp in xdata[variable]) + '\n') #plot stacked area # plt.stackplot(xdata[variable],data) #plot lines if re.search("L208", statfile): #print("we group all the species of more than nmeltatoms atoms under the denomination 'melt-like'") i = -1 with open(statfile, 'r') as f: line = f.readline() while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t')[:-1] if len(entry) > 1: natoms = count_natom(entry[0]) if natoms < nmeltatoms: i += 1 x, y = zip( *sorted(zip(xdata[variable], data[i]))) if entry[ 0] in list_colored_species: #we plot only the colored lines. delete this line to plot also the grey species line, = ax.plot( x, y, '.--', color=colors_species[entry[0]], markersize=plot_parameters[ "size_markers"], linewidth=plot_parameters["size_lines"] ) nf.write( format1label(entry[0]) + '\t' + '\t'.join( str(round(perc, 4)) for perc in data[i]) + '\n') #we plot the last line, for the melt-like i += 1 x, y = zip(*sorted(zip(xdata[variable], data[i]))) line, = ax.plot(x, y, '.--', color=colors_species['melt-like'], markersize=plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"]) nf.write( format1label('melt-like') + '\t' + '\t'.join(str(round(perc, 4)) for perc in data[i]) + '\n') else: i = -1 with open(statfile, 'r') as f: line = f.readline() while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t')[:-1] if len(entry) > 1: i += 1 x, y = zip(*sorted(zip(xdata[variable], data[i]))) if entry[ 0] in list_colored_species: #we plot only the colored lines. delete this line to plot also the grey species line, = ax.plot( x, y, '.--', color=colors_species[entry[0]], markersize=plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"]) nf.write( format1label(entry[0]) + '\t' + '\t'.join( str(round(perc, 4)) for perc in data[i]) + '\n') # if variable == 'T': # label_line(ax, line, entry[0], halign='right') # elif list_species.index(entry[0]) < int(len(list_species)/2): # label_line(ax, line, entry[0], halign='left') # else: # label_line(ax, line, entry[0], halign='right') # ax.hlines(y=0.05, xmin = 1, xmax=2.1, color = 'r') # ax.hlines(y=0.01, xmin = 1, xmax=2.1, color = 'm') #***************************** #******************* #******* #legend #custom_lines_grey = [Line2D([0],[0],color = colors_species[key], ls = '--', marker = '.', markersize = plot_parameters["size_markers"], linewidth = plot_parameters["size_lines"]) for key in natsort.natsorted(list_grey_species)] list_grey_species = format_label(natsort.natsorted(list_grey_species)) #legend_grey = plt.legend([line for line in custom_lines_grey],[label for label in list_grey_species],title = '$\\bf{Clusters <1\%}$', bbox_to_anchor=(1.25, 1), loc='upper left', fontsize = plot_parameters["size_fonts"], borderaxespad=0.) #plt.gca().add_artist(legend_grey) #plt.setp(legend_grey.get_title(),fontsize= plot_parameters["size_fonts"]) custom_lines = [ Line2D([0], [0], color=colors_species[key], ls='--', marker='.', markersize=plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"]) for key in natsort.natsorted(list_colored_species) ] list_colored_species = format_label( natsort.natsorted(list_colored_species)) if statfile2 != '': legend = ax.legend([line for line in custom_lines], [label for label in list_colored_species], bbox_to_anchor=(0.5, 0.99), loc='upper center', fontsize=plot_parameters["size_font_ticks"], borderaxespad=0., ncol=3) #if len(list_colored_species) > 16: # legend = plt.legend([line for line in custom_lines],[label for label in list_colored_species],title = '$\\bf{Species}$', bbox_to_anchor=(1.01, 1), loc='upper left', fontsize = plot_parameters["size_fonts"], borderaxespad=0., ncol = 2) # legend = plt.legend([line for line in custom_lines],[label for label in list_colored_species],title = '$\\bf{Species}$', bbox_to_anchor=(0.5, 0.99), loc='upper center', fontsize = plot_parameters["size_fonts"], borderaxespad=0.,ncol = 8) else: # legend = plt.legend([line for line in custom_lines],[label for label in list_colored_species],title = '$\\bf{Species}$', bbox_to_anchor=(1.01, 1), loc='upper left', fontsize = plot_parameters["size_fonts"], borderaxespad=0.) legend = ax.legend([line for line in custom_lines], [label for label in list_colored_species], title='$\\bf{Species}$', bbox_to_anchor=(0.5, 0.99), loc='upper center', fontsize=plot_parameters["size_fonts"], borderaxespad=0., ncol=8) plt.setp(legend.get_title(), fontsize=plot_parameters["size_fonts"]) nf.write('\n') nf.write('Species<1%\t' + '\t'.join(str(species) for species in list_grey_species) + '\n') print(newfilename, 'is created') figurename = figurename + '.pdf' plt.savefig(figurename, bbox_inches='tight', dpi=300) print(figurename, 'is created')
def main(argv): """ ********* Main program ********* """ #parameters for the figures depending on the output format (presentation or article) plot_parameters = { "size_fonts": 12, "size_font_ticks": 10, "size_figure": (8, 4), "size_markers": 4, "size_lines": 1, "shift_labelpad": 20 } #other dictionnaries and parameters for the figure colors_T = { 'T2': '#800080', 'T3': '#297fff', 'T4': '#00ff00', 'T4.5': '#bae200', 'T5': '#ffcd01', 'T5.5': '#ff6e00', 'T6': '#ff0101', 'T6.5': '#ff00a2', 'T7': '#ff01de', 'T10': '#ffa6f4', 'T15': '#ffe86e', 'T20': '#ffbf90' } #colors_T = create_colors() allT = {} #initialization of parameters filename2 = '' xvariable = 'rho' #dictionnary for fullaverages file in full version column_number = { 'rho': 2, 'P': 5, 'stdev_P': 6, 'err_P': 7, 'T': 8, 'stdev_T': 9, 'err_T': 10, 'E': 14, 'stdev_E': 15, 'err_E': 16, 'Cvm_Nkb': 23, 'stdev_Cvm_Nkb': 24, 'Cvm': 25, 'stdev_Cvm': 26, 'testCv': 31, 'stdev_testCv': 32 } #other parameters Na = 6.022 * 10**23 try: options, arg = getopt.getopt( argv, "hf:g:a:x:", ["filename1", "gfilename2", "atoms", 'xvariable']) except getopt.GetoptError: print( "plot_coordinence_separated.py -f <gofr_compound.txt> -g <gofr_compound.txt 2> -a <atomic pair list:'Ca-O,K-O,Al-O,Si-O'> -x <xvariable (P or rho)>" ) sys.exit() for opt, arg in options: if opt == '-h': print('') print( 'plot_coordinence_separated.py program to plot coordinence as a function of density for each T and all cations with O' ) print( "plot_coordinence_separated.py -f <gofr_compound.txt> -g <gofr_compound.txt 2> -a <atomic pair list:'Ca-O,K-O,Al-O,Si-O'> -x <xvariable (P or rho)>" ) print( "plot_coordinence_separated.py requires gofr txt file containing every bond distance and coordination of one compound for every acell and T with the number of elements in header (use analyze_gofrs script etc.)" ) print('') print( 'For plots as function of P, make sure the files from fullaverages.py are in the current folder' ) sys.exit() if opt in ('-f', '--filename'): filename = str(arg) elif opt in ('-g', '--gfilename'): filename2 = str(arg) elif opt in ('-a', '--atoms'): atoms = arg.split(',') elif opt in ('-x', '--xvariable'): xvariable = str(arg) #************ creation of the figure to plot (with correct number of lines) if filename2 != '': files = [filename, filename2] figurename = 'coordinence_' + filename.split('.txt')[0].split( '_')[1] + '-' + filename2.split('.txt')[0].split( '_')[1] + '_' + xvariable typeline = {filename: '--', filename2: '-'} typemarker = {filename: 'x', filename2: ''} compo = { filename2: format1label(filename2.split('_')[1]), filename: format1label(filename.split('_')[1]) } else: files = [filename] figurename = 'coordinence_' + filename.split( '.txt')[0] + '_' + xvariable typeline = {filename: '-'} typemarker = {filename: '*'} compo = {filename: format1label(filename.split('_')[1])} if xvariable == 'P': fig, ax1, ax2, ax3, ax11, ax22, ax33, ax0 = creation_plot_P( plot_parameters) axis1 = [ax1, ax11] axis2 = [ax2, ax22] axis3 = [ax3, ax33] else: fig, ax1, ax2, ax3, ax0 = creation_plot(plot_parameters) axis1 = [ax1] axis2 = [ax2] axis3 = [ax3] offset = 0 #offset for printing text on Na-O K-O subplot #************** for each file we extract and plot data for each atom on the correct subplot for file in files: #***** Initialization of data dictionnaries pair_columns = {} data = { } #big dictionnary with inside coord all coresponding to different T and atom pairs X = {} #idem for rho or P #******* Extract P and T for each thermo file if xvariable == 'P': TP = {} mineralname = file.split('_')[1] thermofiles = sorted(glob.glob('thermo_' + mineralname + '*.txt')) for thermofile in thermofiles: TP = extract_TP(thermofile, column_number, TP, '') #***** Calculation of the molecular mass with open(file, 'r') as f: line = f.readline() entry = line.split() elements = entry[1:] line = f.readline() entry = line.split() number = entry[1:] line = f.readline() entry = line.split() pair = entry[1:] MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #******** extraction of data pair_columns[pair[0]] = 4 for i in range(1, len(pair)): if pair[i] != pair[i - 1]: pair_columns[pair[i]] = i + 4 print('All the pair availables in the file with their index are:', pair_columns) for atom_pair in pair_columns: for atom in atoms: if atom_pair == atom: data[atom] = {} X[atom] = {} with open(file, 'r') as f: [f.readline() for i in range(4)] while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t') temperature, acell = split_name(entry[0]) for atom_pair in pair_columns: for atom in atoms: if atom_pair == atom: try: data[atom][temperature].append( float(entry[pair_columns[atom]])) if xvariable == 'P': X[atom][temperature].append(TP[ entry[0].split('outcar.gofr.dat') [0].split('/')[-1]][1]) else: X[atom][temperature].append( MN / (Na * float(acell)**3 * 10**(-24))) #calculation density except KeyError: data[atom][temperature] = [ float(entry[pair_columns[atom]]) ] if xvariable == 'P': X[atom][temperature] = [ TP[entry[0].split( 'outcar.gofr.dat')[0].split( '/')[-1]][1] ] else: X[atom][temperature] = [ MN / (Na * float(acell)**3 * 10**(-24)) ] #calculation density #***** Plot each atom pair on the correct subplot --> ax1 for Na/K-O, ax2 for Al-O, ax3 for Si-O for temperature in data['Si-O']: allT[temperature] = '' for atom in data: if atom == 'Na-O' or atom == 'K-O' or atom == 'Ca-O': for ax in axis1: ax.plot(X[atom][temperature], data[atom][temperature], marker=typemarker[file], linestyle=typeline[file], color=colors_T[temperature], markersize=plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"]) ax1.text(0.02, 0.91 - offset, atom, transform=ax1.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold') # plt.setp(ax.get_xticklabels(), visible=False) elif atom == 'Si-O': for ax in axis3: ax.plot(X[atom][temperature], data[atom][temperature], marker=typemarker[file], linestyle=typeline[file], color=colors_T[temperature], markersize=plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"]) ax3.text(0.02, 0.91, atom, transform=ax3.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold') elif atom == 'Al-O': for ax in axis2: ax.plot(X[atom][temperature], data[atom][temperature], marker=typemarker[file], linestyle=typeline[file], color=colors_T[temperature], markersize=plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"]) ax2.text(0.02, 0.91, atom, transform=ax2.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold') offset = offset + 0.10 #we update the offset for printing text on Na-O K-O subplot after finishing the first file #************ legend Tlist = [label for label in natsort.natsorted(allT)] custom_patch = [mpatches.Patch(color=colors_T[key]) for key in Tlist] legend = ax0.legend( [col for col in custom_patch], [str(int(float(label.strip('T')) * 1000)) for label in Tlist], title='$\\bf{Temperature~(K)}$', bbox_to_anchor=(0.5, 1.07), loc="lower center", fontsize=plot_parameters["size_font_ticks"], borderaxespad=0., ncol=len(Tlist)) plt.setp(legend.get_title(), fontsize=plot_parameters["size_font_ticks"]) legend_labels = {} for file in files: legend_labels[compo[file]] = plt.Line2D( (0, 1), (0, 0), color='k', linestyle=typeline[file], markersize=plot_parameters["size_markers"] + 2, marker=typemarker[file]) s = [(k, legend_labels[k]) for k in sorted(legend_labels.keys(), reverse=False)] legend1 = ax0.legend([v for k, v in s], [k for k, v in s], loc='lower center', bbox_to_anchor=(0.5, 1.02), ncol=len(files), fontsize=plot_parameters["size_font_ticks"], borderaxespad=0.) ax0.add_artist(legend) #save the figure figurename = figurename + '.pdf' fig.savefig(figurename, bbox_inches='tight', dpi=300) print(figurename, ' created')
def main(argv): """ ********* Main program ********* """ atoms = 'all' max_den = 6 size = {} lifetime = {} datadic = {} xdata = {'T':[],'rho':[]} #dictionnary containing the x data selected_clusters = [] selected_files = [] #list containing the files we use for the plot (depends on the density limit) #other dictionnaries and parameters for the figure for article version list_colored_species = [] list_colored_red = [] list_colored_green = [] list_colored_blue = [] list_colored_purple = [] list_minor_species = [] colors_species = {"melt-like":'0'} letter = '' plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (6,4),"size_markers" : 4,"size_lines" : 1,"shift_labelpad" : 20} #other parameters Na=6.022*10**23 sizelimit = 13 try: options,arg = getopt.getopt(argv,"hf:v:m:l:a:t:d:",["filenameoutput","variable","mineralfile","letter","atoms",'type',"density_max"]) except getopt.GetoptError: print("plot_speciation-analyzed-lifetime-r0.py -f <output filename> -v <variable (rho,T)> -m <mineralfile with elements> -l <letter for article subplot, default = ''> -t <type (max or median)> -d <maximum density to plot in g/cm3> -a <list of first atoms determining the type of cluster to plot (e.g. 'Si_1O,Al_1O,melt,O')>") sys.exit() for opt,arg in options: if opt == '-h': print('') print('plot_speciation-analyzed-lifetime-r0.py program to Plot the average and median lifetime of selected species as a function of T or rho') print("plot_speciation-analyzed-lifetime-r0.py -f <output filename> -v <variable (rho,T)> -m <mineralfile with elements> -l <letter for article subplot, default = ''> -t <type (max or median)> -d <maximum density to plot in g/cm3> -a <list of first atoms determining the type of cluster to plot (e.g. 'Si_1O,Al_1O,melt,O')>") print('') print("all the species with more than 13 atoms are grouped together under the name 'melt-like'. To display the corresponding lifetime, indicate melt in the list of atoms") print('') print('requires to be launched from subfolder T or acell containing the requires the files popul.dat ') print('requires also the file containing elements and number (in order to compute the densities)') print('') sys.exit() elif opt in ('-f','--filename'): outputfilename = str(arg) elif opt in ("-v", "--variable"): xvariable = str(arg) elif opt in ("-m","--mineralfile"): mineralfile = str(arg) elif opt in ("-l","--letter"): letter = str(arg) elif opt in ("-a","--atoms"): atoms = arg.split(',') elif opt in ("-t","--type"): yvariable = str(arg) elif opt in ("-d","--density_max"): max_den = float(arg) #***************************** #******************* #******* #***** Calculation of the molecular mass with open(mineralfile,'r') as mf: entry = mf.readline() elements = entry.split()[1:] entry = mf.readline() number = entry.split()[1:] MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #***************************** #******************* #******* #***** Extraction of the lifetimes and creation of the xdata lists files = sorted(glob.glob('*r0.popul.dat')) #I list every popul.dat files in alphabetic order for file in files: #creation of the x data list temperature, acell = split_name(file) density = MN/(Na*float(acell)**3*10**(-24)) if density <= max_den: xdata['rho'].append(density ) #calculation density xdata['T'].append(int(temperature)) selected_files.append(file) lifetime[file] = {} #dictionnary with the lifetime of all the cluster in each file with open(file,'r') as f: f.readline() f.readline() while True: line = f.readline() if not line: break else: entry=line.split('\t') natoms = len(entry[4].split(',')) if natoms > sizelimit: #print('for ',entry[0], 'natoms = ',natoms, '>', sizelimit) try: lifetime[file]['melt-like'].append(float(entry[3])) except KeyError : lifetime[file]['melt-like'] = [float(entry[3])] size['melt-like'] = '>'+str(sizelimit) else: try: lifetime[file][entry[0]].append(float(entry[3])) except KeyError : lifetime[file][entry[0]] = [float(entry[3])] size[entry[0]] = natoms #print('lifetimes melt-like',lifetime[file]['melt-like']) print('for files', selected_files, len(selected_files)) #print('we have xdata',xdata['rho'], len(xdata['rho'])) #print('we have xdata',xdata['T'], len(xdata['T'])) #**** Creation of the dictionnaries and lists of max or median lifetime for each cluster #initialisation of the dictionnary containing a list for each cluster selected if atoms == ['all']: print("we use all clusters") for file in selected_files: for cluster in lifetime[file]: datadic[cluster] = [] else: print("we use the selected clusters") for file in selected_files: for cluster in lifetime[file]: for atom in atoms: if cluster[:len(atom)] == atom: datadic[cluster] = [] #choice of the function to use if yvariable == 'median': function = np.median else: function = np.max for cluster in datadic: selected_clusters.append(cluster) for file in selected_files: try: datadic[cluster].append(function(lifetime[file][cluster])) except KeyError: datadic[cluster].append(0) #print('medianlife is',medianlife) #print('averagelife is',averagelife) print("The selected clusters are",selected_clusters) #***************************** #******************* #******* #***** Color attribution #**** Now the dictionary has every possible cluster, we attribute the colors to each cluster #check the lifetime not display the species with an average lifetime smaller than 50 fs and we add name of the species for cluster in datadic : #loop on each cluster if max(datadic[cluster]) < 0: list_minor_species.append(cluster) elif cluster == 'melt-like': continue else: #this is for basic automatic color change list_colored_species.append(cluster) #**** we attribute the colors to each cluster #this is for basic automatic color change color = iter(plt.cm.jet(np.linspace(0,1,11))) #Creation of the color list for 11 coordination # for i in range(1,12,1): c = next(color) colors_species[i] = c #***************************** #******************* #******* #*** Creation of the plots #one subplot per type without interstitial --> 2 subplots fig, ax1, ax2, ax0 = creation_plot(max_den,xvariable,yvariable,plot_parameters,letter) #plot for each cluster and write file with median and average lifetime figurename = outputfilename+'_'+xvariable+'_r0_'+yvariable newfilename = figurename + '.txt' nf = open(newfilename,'w') if xvariable == 'rho': nf.write('Density(g/cm3)\t' + '\t'.join(str(round(density,2)) for density in xdata[xvariable]) + '\n') else: nf.write('Temperature(K)\t' + '\t'.join(str(temp) for temp in xdata[xvariable]) + '\n') #plot lines for cluster in list_colored_species: print("for cluster",cluster) if cluster[:5] == 'Al_1O' : #print('plot on ax1 for cluster', cluster) plot_and_write(xdata, xvariable, datadic, cluster, colors_species, plot_parameters, nf, ax1) elif cluster[:5] == 'Si_1O' : #print('plot on ax2 for cluster', cluster) plot_and_write(xdata, xvariable, datadic, cluster, colors_species, plot_parameters, nf, ax2) #***************************** #******************* #******* #legend list_minor_species = format_label(natsort.natsorted(list_minor_species)) custom_lines = [Line2D([0],[0],color = colors_species[CN], ls = '--', marker = '.', markersize = plot_parameters["size_markers"], linewidth = plot_parameters["size_lines"]) for CN in range(1,12,1)] list_colored_species = [str(CN) for CN in range(1,12,1)] print(list_colored_species) legend = ax0.legend([line for line in custom_lines],[label for label in list_colored_species],title = '$\\bf{x}$', bbox_to_anchor=(0.5, 1.04), loc='lower center', fontsize = plot_parameters["size_fonts"], borderaxespad=0., ncol = 11) plt.setp(legend.get_title(),fontsize= plot_parameters["size_fonts"]) ax1.text(0.99,0.99, r'AlO$_{x}$' , transform=ax1.transAxes, horizontalalignment = 'right', verticalalignment = 'top', fontweight = 'bold', fontsize = plot_parameters["size_fonts"]) ax2.text(0.99,0.99, r'SiO$_{x}$' , transform=ax2.transAxes, horizontalalignment = 'right', verticalalignment = 'top', fontweight = 'bold', fontsize = plot_parameters["size_fonts"]) #***************************** #******************* #******* #save plots extension = '.svg' figurename = figurename+ extension fig.savefig(figurename, bbox_inches='tight', dpi=300) print(figurename, 'is created') nf.write('\n') nf.write('Species_with_medianlife<50fs\t'+ '\t'.join(str(species) for species in list_minor_species) + '\n') nf.close() print(newfilename, 'is created')
def main(argv): """ ********* Main program ********* """ #parameters for the figure for article plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (4,4),"size_markers" : 4,"size_lines" : 1,"shift_labelpad" : 10} thermofile = 'all' thermofile2 = '' filetype = 'all' init_letter = '' letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'] #figure dictionnary colors_T = {'T2':'#800080','T3':'#297fff','T4':'#00ff00','T4.5':'#bae200','T5':'#ffcd01','T5.5':'#ff6e00','T6':'#ff0101','T6.5':'#ff00a2','T7':'#ff01de','T10':'#ffa6f4','T15':'#ffe86e','T20':'#ffbf90'} #other parameters Na=6.022*10**23 eVtoJ = 1.6e-19 #1eV = 1.6e-19 J kb = 1.38064852e-23 #boltzmann constant try: options,arg = getopt.getopt(argv,"hf:g:t:l:",["filename","gfilename","type",'letter']) except getopt.GetoptError: print("plot_thermo-rho.py -f <thermo_filename (default = 'all')> -g <thermo_filename 2 (if we want to plot 2 files)> -t <type of the file: 'short' or 'all'> -l <letter of first plot, default = ''> ") sys.exit() for opt,arg in options: if opt == '-h': print('') print('plot_thermo-rho.py program to fit and plot BM3 as a function of density') print("plot_thermo-rho.py -f <thermo_filename (default = 'all' -> 3plot)> -g <thermo_filename 2 (if we want to plot 2 files)> -t <type of the file: 'short' or 'all'> -l <letter of first plot, default = ''>") print('') sys.exit() elif opt in ('-f','--filename'): thermofile = str(arg) elif opt in ('-g','--gfilename'): thermofile2 = str(arg) elif opt in ('-t','--type'): filetype = str(arg) elif opt in ('-l','--letter'): init_letter = str(arg) #selection of the column depending on the type of the thermo file if filetype == 'all': column_number = {'rho':2,'P':5,'stdev_P':6,'err_P':7,'T':8,'stdev_T':9,'err_T':10,'E':14,'stdev_E':15,'err_E':16,'Cvm_Nkb':23,'stdev_Cvm_Nkb':24,'Cvm':25,'stdev_Cvm':26} else: column_number = {'rho':2,'P':5,'stdev_P':6,'err_P':7,'T':8,'stdev_T':9,'err_T':10,'E':11,'stdev_E':12,'err_E':13,'Cvm_Nkb':14,'stdev_Cvm_Nkb':15} #************ initialization of the plot if thermofile == 'all': fig,ax1,ax2,ax3, ax0 = creation_plot_3(plot_parameters) print("axis are ax1",ax1,"ax2",ax2,"ax3",ax3,"ax0",ax0) files = sorted(glob.glob('thermo_*O8_'+filetype+'.txt'),reverse=True) #I list every thermo files figurename = 'Fit_BM3_thermo_all' elif thermofile2 != '': fig,ax1,ax2, ax0 = creation_plot_2(plot_parameters) print("axis are ax1",ax1,"ax2",ax2,"ax0",ax0) files = [thermofile, thermofile2] #we will plot 2 files figurename = 'Fit_BM3_'+thermofile.split('.txt')[0]+'_'+thermofile2.split('.txt')[0].split('_')[1] else: fig, ax = creation_plot(plot_parameters) files = [thermofile] #I take only the file we want figurename = 'Fit_BM3_'+thermofile.split('.txt')[0] #************ creation of arrays and plot at the same time for file in files: print("****** For file",file) #********initialisations #**change of subplot if thermofile == 'all' or thermofile2 !='': if files.index(file) == 0: ax=ax1 letter = init_letter if files.index(file) == 1: ax=ax2 try: letter = letters[letters.index(init_letter)+1] except ValueError: print("You haven't indicated any letter") letter = '' if files.index(file) == 2: ax=ax3 try: letter = letters[letters.index(init_letter)+2] except ValueError: print("You haven't indicated any letter") #print("I plot on axis",ax) #**initialisation of data dictionnaries rho = {} V = {} P = {} stdev_P = {} data = {} #********* creation of the BM3 txt file bm = fileBM3(file) #********* fill the dictionnaries with data with open(file,'r') as f: line = f.readline() entry=line.split() elements = entry[1:] line = f.readline() entry=line.split() number = entry[1:] f.readline() #calculation of M*N nedded for the calculation of volumes MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #extract data while True: line = f.readline() if not line: break else: entry=line.split('\n')[0].split('\t') temperature, acell = split_name(entry[0]) try: data[temperature].append([ float(entry[column_number['rho']]) , float(entry[column_number['P']]) , float(entry[column_number['stdev_P']]) ]) except KeyError: data[temperature] = [] data[temperature].append([ float(entry[column_number['rho']]) , float(entry[column_number['P']]) , float(entry[column_number['stdev_P']]) ]) #********* remove the data we do not want to use for temperature in data: #first we sort the data by density from biggest to smallest data[temperature] = sorted(data[temperature], key=lambda x: x[0], reverse=True) #sort by the first column: rho #second we create rho,P,stdev_P dictionnaries with only the data with positive P starting below 100 GPa for ii in range(len(data[temperature])): if data[temperature][ii][1] < 100: if data[temperature][ii][1] < 1 or data[temperature][ii][0] < 1.6 : #if the pressure is below 1GPa or below the limit density, then we take this value and STOP the loop to not take the others try: rho[temperature].append(data[temperature][ii][0] ) V[temperature].append( MN / (Na * data[temperature][ii][0]*1E-24)) P[temperature].append(data[temperature][ii][1] ) stdev_P[temperature].append(data[temperature][ii][2] ) except KeyError: rho[temperature] = [] rho[temperature].append(data[temperature][ii][0] ) V[temperature] = [ MN / (Na * data[temperature][ii][0]*1E-24)] P[temperature] = [data[temperature][ii][1] ] stdev_P[temperature] = [data[temperature][ii][2] ] break else: try: rho[temperature].append(data[temperature][ii][0] ) V[temperature].append( MN / (Na * data[temperature][ii][0]*1E-24)) P[temperature].append(data[temperature][ii][1] ) stdev_P[temperature].append(data[temperature][ii][2] ) except KeyError: rho[temperature] = [] rho[temperature].append(data[temperature][ii][0] ) V[temperature] = [] V[temperature].append(MN / (Na * data[temperature][ii][0]*1E-24)) P[temperature] = [] P[temperature].append(data[temperature][ii][1] ) stdev_P[temperature] = [] stdev_P[temperature].append(data[temperature][ii][2] ) #******** Fit data and plot #This is the theoretical model (initial guesses), based on common values m0 = {'T2':[2.6,15,4],'T3':[2.6,15,4],'T4':[2.6,15,4],'T5':[2.6,15,4],'T6':[2.6,15,4],'T10':[2.6,15,4],'T15':[2.6,15,4],'T20':[2.6,15,4]} #rho0 in g/cm3, K0 in GPa, Kp0 #m0 = {'T3':[3000,19,4],'T4':[3000,19,4],'T5':[3000,15,4],'T6':[3000,15,6]} #V0 in angstrom3, K0 in GPa, Kp0 drho = 0.1 for temperature in sorted(rho): if len(rho[temperature]) > 4: #***************** fit using P=f(rho) # try: #Least square fit # m, pcov = curve_fit(fonction_BM3, rho[temperature], P[temperature], p0=m0[temperature], sigma=stdev_P[temperature], absolute_sigma=False ) # chi2 = chi2red(m,rho[temperature],P[temperature],stdev_P[temperature]) # DensityX=np.arange(rho[temperature][-1]-drho,rho[temperature][0]+drho,drho) # ax.plot(DensityX,fonction_BM3(DensityX,m[0],m[1],m[2]),'-', color=colors_T[temperature], label= temperature + ' BM3 fit') # print(temperature, "Least-square fit of BM3") # perr = np.sqrt(np.diag(pcov)) #stdev on the parameters # bm.write(str(temperature) + '\t' + str('{:1.2e}'.format(chi2)) + '\t' + str('{:1.2e}'.format(m[0])) + '\t' + str('{:1.2e}'.format(m[1])) + '\t' + str('{:1.2e}'.format(m[2])) + '\t' + str('{:1.2e}'.format(perr[0])) + '\t' + str('{:1.2e}'.format(perr[1])) + '\t' + str('{:1.2e}'.format(perr[2])) +'\n') #try: #fmin fit # m=simplex(fonction, m0[temperature], args=(rho[temperature], P[temperature], stdev_P[temperature]), maxiter = 1000000, full_output=0) # chi2=chi2red(m,rho[temperature],P[temperature],stdev_P[temperature]) # DensityX=np.arange(rho[temperature][-1]-drho,rho[temperature][0]+drho,drho) # ax.plot(DensityX,fonction_BM3(DensityX,m[0],m[1],m[2]),'-', color=colors_T[temperature], label= temperature + ' BM3 fit') # print(temperature, "Least-square fit of BM3") # bm.write(str(temperature) + '\t' + str('{:1.2e}'.format(chi2)) + '\t' + str('{:1.2e}'.format(m[0])) + '\t' + str('{:1.2e}'.format(m[1])) + '\t' + str('{:1.2e}'.format(m[2])) + '\n') try: #odr fit eos_model_BM3 = odr.Model(BM3_P_rho) # model for fitting stdev_rho = [i/1000 for i in rho[temperature]] #creation of stdev for rho data_for_ODR = odr.RealData(rho[temperature], P[temperature], stdev_rho, stdev_P[temperature]) # RealData object using our data odr_process = odr.ODR(data_for_ODR, eos_model_BM3, beta0=m0[temperature], maxit = 10000) # Set up orth-dist-reg with the model and data odr_results = odr_process.run() # run the regression print('***************',temperature, "Fit of BM3") odr_results.pprint() # use the pprint method to display results DensityX=np.arange(rho[temperature][-1]-drho,rho[temperature][0]+drho,drho) ax.plot(DensityX,BM3_P_rho(odr_results.beta,DensityX),'-', color=colors_T[temperature], label= temperature + ' BM3 fit') bm.write(str(temperature) + '\t' + str('{:1.2e}'.format(odr_results.res_var)) + '\t' + str('{:1.2e}'.format(odr_results.beta[0])) + '\t' + str('{:1.2e}'.format(odr_results.beta[1])) + '\t' + str('{:1.2e}'.format(odr_results.beta[2])) + '\t' + str('{:1.2e}'.format(odr_results.sd_beta[0])) + '\t' + str('{:1.2e}'.format(odr_results.sd_beta[1])) + '\t' + str('{:1.2e}'.format(odr_results.sd_beta[2])) + '\n') #print('chi2red', chi2red(odr_results.beta,rho[temperature],P[temperature],stdev_P[temperature])) #print('residual variance',odr_results.res_var) #***************** fit using P=f(V) #try: #odr fit # eos_model_BM3 = odr.Model(BM3_P_V) # model for fitting # stdev_V = [i/1000 for i in V[temperature]] #creation of stdev for rho # data_for_ODR = odr.RealData(V[temperature], P[temperature], stdev_V, stdev_P[temperature]) # RealData object using our data # odr_process = odr.ODR(data_for_ODR, eos_model_BM3, beta0=m0[temperature], maxit = 10000) # Set up orth-dist-reg with the model and data # odr_results = odr_process.run() # run the regression # print('***************',temperature, "Fit of BM3") # odr_results.pprint() # use the pprint method to display results # DensityX=np.arange(rho[temperature][-1]-drho,rho[temperature][0]+drho,drho) # VolumeX = [MN/(Na*DensityX[ii]*1E-24) for ii in range(len(DensityX))] # ax.plot(DensityX,BM3_P_V(odr_results.beta,VolumeX),'-', color=colors_T[temperature], label= temperature + ' BM3 fit') # bm.write(str(temperature) + '\t' + str('{:1.2e}'.format(odr_results.sum_square)) + '\t' + str('{:1.2e}'.format(MN/(Na*odr_results.beta[0]*1E-24))) + '\t' + str('{:1.2e}'.format(odr_results.beta[1])) + '\t' + str('{:1.2e}'.format(odr_results.beta[2])) + '\n') except RuntimeError: print(temperature, "FAIL of fit of BM3") bm.write(str(temperature) + '\t-\t-\t-\t-\n') ax.plot(rho[temperature],P[temperature],'o', color=colors_T[temperature], markersize = plot_parameters['size_markers'], label= temperature + ' data') #Create legend from custom artist/label lists # legend_labels['not started'] = plt.Line2D((0,1),(0,0), markersize = plot_parameters["size_markers"], marker='o', facecolor = 'r', edgecolor='r', linestyle='') # s = [(k, legend_labels[k]) for k in sorted(legend_labels.keys(),reverse = False)] # if filename == 'all': # ax=ax0 # plt.legend([v for k,v in s],[k for k,v in s],loc='upper center', bbox_to_anchor=(0.46, 1.14),fancybox=True, fontsize = plot_parameters["size_fonts"], ncol=len(style_lines)) figurename = figurename+'.png' print("figure saved with name ",figurename) fig.savefig(figurename, bbox_inches = 'tight', dpi = 300)
def main(argv): """ ********* Main program ********* """ #parameters for the figures depending on the output format (presentation or article) plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (8,4), "size_markers" : 8,"size_lines" : 1,"shift_labelpad" : 20} colors_T = {'2000':'#800080','3000':'#297fff','4000':'#00ff00','4500':'#bae200', '5000':'#ffcd01','5500':'#ff6e00','6000':'#ff0101','6500':'#ff00a2','7000':'#ff01de'} #initialization of parameters yvariable = 4 #for coord # #yvariable = 5 #for bond length #yvariable = 1 #for xmax filename4 = '' filename3 = '' xvariable = 'rho' #dictionnary for fullaverages file in full version column_number = {'rho':2,'P':5,'stdev_P':6,'err_P':7,'T':8,'stdev_T':9,'err_T':10, 'E':14,'stdev_E':15,'err_E':16,'Cvm_Nkb':23,'stdev_Cvm_Nkb':24, 'Cvm':25,'stdev_Cvm':26,'testCv':31,'stdev_testCv':32} #other parameters Na=6.022*10**23 try: options,arg = getopt.getopt(argv,"hf:g:j:i:x:",["filename2","gfilename","jfilename","ifilename",'xvariable']) except getopt.GetoptError: print("plot_coordinence+comparison.py -f <gofr_compound.txt> -g <gofr_comparison1.txt> -j <gofr_comparison2.txt> -i <gofr_comparison3.txt> -x <xvariable (P or rho)>") sys.exit() for opt,arg in options: if opt == '-h': print('') print('plot_coordinence+comparison.py same program as plot_coordinence_separated but to compare one of our data file with other (literrature) data files') print("plot_coordinence+comparison.py-f <gofr_compound.txt> -g <gofr_comparison1.txt> -j <gofr_comparison2.txt> -i <gofr_comparison3.txt> -x <xvariable (P or rho)>") print("plot_coordinence+comparison.py requires gofr txt file containing every bond distance and coordination of one compound for every acell and T with the number of elements in header (use analyze_gofrs script etc.)") print('') print('For plots as function of P, make sure the files from fullaverages.py are in the current folder') sys.exit() if opt in ('-f','--filename'): filename = str(arg) elif opt in ('-g','--gfilename'): filename2 = str(arg) elif opt in ('-j','--jfilename'): filename3 = str(arg) elif opt in ('-i','--ifilename'): filename4 = str(arg) elif opt in ('-x','--xvariable'): xvariable = str(arg) #************ creation of the figure to plot (with correct number of lines) string = filename.split('_')[1] files = [filename] for file in [filename2,filename3,filename4]: if file != '': files.append(file) string += '-'+file.split('.txt')[0].split('_')[-1] string +='_'+xvariable typeline = {filename : '-', filename2: '*', filename3: '+',filename4: 'd'} atoms = ['Na-O','Ca-O','Al-O','Si-O'] if xvariable == 'P': fig, ax1,ax2,ax3,ax11,ax22,ax33, ax0 = creation_plot_P(plot_parameters) axis1 = [ax1,ax11] axis2 = [ax2,ax22] axis3 = [ax3,ax33] else: fig, ax1,ax2,ax3,ax0 = creation_plot(plot_parameters) axis1 = [ax1] axis2 = [ax2] axis3 = [ax3] offset = 0 #offset for printing text on Na-O K-O subplot if yvariable == 4: ax0.set_ylabel(r'Coordination number', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]) figurename = 'coordinence_'+ string elif yvariable == 5: ax0.set_ylabel(r'Bond length ($\AA$)', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]*2) figurename = 'bondlength_'+ string else: ax0.set_ylabel(r'????', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]) figurename = 'unknown_'+ string #************** Extract our data and plot #*** Initialization of data dictionnaries pair_columns = {} data = {} #big dictionnary with inside coord all coresponding to different T and atom pairs X = {} #idem for rho or P #******* Extract P and T for each thermo file if xvariable == 'P': TP = {} mineralname = filename.split('_')[1] thermofiles = sorted(glob.glob('thermo_'+mineralname+'*.txt')) for thermofile in thermofiles: TP = extract_TP(thermofile, column_number, TP,'') #*** Calculation of the molecular mass with open(filename, 'r') as f: line = f.readline() entry=line.split() elements = entry[1:] line = f.readline() entry=line.split() number = entry[1:] line = f.readline() entry=line.split() pair = entry[1:] MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #******** extraction of data pair_columns[pair[0]] =yvariable for i in range(1,len(pair)): if pair[i] != pair[i-1]: pair_columns[pair[i]] = i+yvariable print('All the pairs available in the file with their index are:', pair_columns) for atom_pair in pair_columns: for atom in atoms: if atom_pair == atom: data[atom] = {} X[atom] = {} with open(filename,'r') as f: [f.readline() for i in range(4)] while True: line = f.readline() if not line: break else: entry=line.split('\n')[0].split('\t') temperature, acell = split_name(entry[0]) for atom_pair in pair_columns: for atom in atoms: if atom_pair == atom: try: data[atom][temperature].append( float(entry[pair_columns[atom]]) ) if xvariable == 'P': X[atom][temperature].append(TP[entry[0].split('outcar.gofr.dat')[0].split('/')[-1]][1]) else: X[atom][temperature].append( MN/(Na*float(acell)**3*10**(-24)) ) #calculation density except KeyError: data[atom][temperature] = [ float(entry[pair_columns[atom]]) ] if xvariable == 'P': X[atom][temperature] = [TP[entry[0].split('outcar.gofr.dat')[0].split('/')[-1]][1]] else: X[atom][temperature] = [ MN/(Na*float(acell)**3*10**(-24)) ] #calculation density #***** Plot each atom pair on the correct subplot --> ax1 for Na/Ca-O, ax2 for Al-O, ax3 for Si-O for temperature in data['Si-O']: for atom in data: if atom == 'Ca-O' or atom == 'Na-O': for ax in axis1: ax.plot(X[atom][temperature],data[atom][temperature], linestyle = typeline[filename][:], color=colors_T[temperature], markersize = plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"] ) elif atom == 'Si-O': for ax in axis2: ax.plot(X[atom][temperature],data[atom][temperature], linestyle = typeline[filename][:], color=colors_T[temperature], markersize = plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"] ) ax2.text( 0.02,0.91, atom ,transform=ax2.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for coord #ax2.text( 0.87,0.91, atom ,transform=ax2.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for bond elif atom == 'Al-O': for ax in axis3: ax.plot(X[atom][temperature],data[atom][temperature],linestyle = typeline[filename][:], color=colors_T[temperature], markersize = plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"] ) ax3.text(0.02,0.91, atom ,transform=ax3.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for coord #ax3.text(0.87,0.91, atom ,transform=ax3.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for bond #************** Extract the collected data and plot pair_sources = {'gofrs-coordinence_Neilson2016.txt':'Na-O','gofrs-coordinence_Spera2009.txt':'Ca-O','gofrs-coordinence_deKoker2010.txt':'Ca-O'} sources = {'gofrs-coordinence_Neilson2016.txt':'Neilson $et~al.$ (2016)','gofrs-coordinence_Spera2009.txt':'Spera $et~al.$ (2009)','gofrs-coordinence_deKoker2010.txt':'de Koker (2010)','gofrs-bond_deKoker2010.txt':'de Koker (2010)'} for file in files[1:]: print('For file ',file) #***** Initialization of data dictionnaries pair_columns={'Na-O':2,'Ca-O':2,'Al-O':3,'Si-O':4} data = {} #big dictionnary with inside coord all coresponding to different T and atom pairs X = {} #idem for rho or P with open(file, 'r') as f: line = f.readline() entry=line.split() pairs = entry[2:9] print('All the pairs available in the file are:', pairs) #******** extraction of data for atom_pair in pairs: for atom in atoms: if atom_pair == atom: data[atom] = {} X[atom] = {} with open(file,'r') as f: f.readline() while True: line = f.readline() if not line: break else: entry=line.split('\n')[0].split('\t') temperature = str(int(float( entry[9]))) for atom_pair in pairs: for atom in atoms: if atom_pair == atom: try: data[atom][temperature].append( float(entry[pair_columns[atom]]) ) if xvariable == 'P': X[atom][temperature].append( float(entry[1])) else: X[atom][temperature].append( float(entry[0])/1000) except KeyError: data[atom][temperature] = [ float(entry[pair_columns[atom]]) ] if xvariable == 'P': X[atom][temperature] = [ float(entry[1])] else: X[atom][temperature] = [ float(entry[0])/1000] #***** Plot each atom pair on the correct subplot --> ax1 for Na/Ca-O, ax2 for Al-O, ax3 for Si-O for temperature in data['Si-O']: #**** select the color of symbols typefill = {filename : None, filename2: colors_T[temperature], filename3: 'w',filename4: 'w'} for atom in data: if atom == 'Ca-O' or atom == 'Na-O': #print('plot M-O for ', temperature) for ax in axis1: ax.plot(X[atom][temperature],data[atom][temperature], marker = typeline[file][0], markeredgewidth = 0.5, linestyle = 'None', markerfacecolor=typefill[file], markeredgecolor=colors_T[temperature], markersize = plot_parameters["size_markers"] ) elif atom == 'Si-O': #print('plot Si-O for ', temperature) for ax in axis2: ax.plot(X[atom][temperature],data[atom][temperature], marker = typeline[file][0], markeredgewidth = 0.5, linestyle = 'None', markerfacecolor=typefill[file], markeredgecolor=colors_T[temperature], markersize = plot_parameters["size_markers"] ) elif atom == 'Al-O': #print('plot Al-O for ', temperature) for ax in axis3: ax.plot(X[atom][temperature],data[atom][temperature], marker = typeline[file][0], markeredgewidth = 0.5, linestyle = 'None', markerfacecolor=typefill[file], markeredgecolor=colors_T[temperature], markersize = plot_parameters["size_markers"] ) for atom in ['Ca-O','Na-O']: ax1.text( 0.02,0.91-offset, atom,transform=ax1.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for coord #ax1.text( 0.87,0.91-offset, atom,transform=ax1.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for bond offset = offset + 0.10 #we update the offset for printing text on Na-O K-O subplot after finishing the first file #Legend typefill = {filename : None, filename2: 'k', filename3: 'w',filename4: 'w'} legend_labels = {} for file in files[1:]: legend_labels[sources[file]] = plt.Line2D((0,1),(0,0), markeredgecolor='k', markerfacecolor = typefill[file], linestyle = 'None', markersize = plot_parameters["size_markers"], marker=typeline[file][0]) legend_labels['this study'] = plt.Line2D((0,1),(0,0), color='k', linestyle=typeline[filename][:], linewidth = plot_parameters["size_lines"]) s = [(k, legend_labels[k]) for k in sorted(legend_labels.keys(),reverse = False)] ax1.legend([v for k,v in s],[k for k,v in s], loc='lower right', bbox_to_anchor=(0.99, 0.01), ncol=1, fontsize = plot_parameters["size_font_ticks"], borderaxespad=0.) #for coord #ax1.legend([v for k,v in s],[k for k,v in s], loc='lower left', bbox_to_anchor=(0.01, 0.01), ncol=1, fontsize = plot_parameters["size_font_ticks"], borderaxespad=0.) #for bond #save the figure figurename = figurename + '.pdf' fig.savefig(figurename, bbox_inches = 'tight', dpi = 300) print(figurename, ' created')
def main(argv): """ ********* Main program ********* """ #parameters for the figure for article plot_parameters = { "size_fonts": 12, "size_font_ticks": 10, "size_figure": (10, 4), "size_markers": 4, "size_lines": 1, "shift_labelpad": 5 } #other dictionnaries and parameters for the figure lines = {} #dictionnary for the lines for legend Na = 6.022 * 10**23 #avogadro constant #other dictionnaries and parameters for the figure colors_densities = {} colors_T = { 'T2': '#800080', 'T3': '#297fff', 'T4': '#00ff00', 'T4.5': '#bae200', 'T5': '#ffcd01', 'T6': '#ff0101', 'T6.5': '#ff00a2', 'T7': '#ff01de' } #colors_T = create_colors() allT = {} #dictionnary for the legend letters = ['a', 'b'] try: options, arg = getopt.getopt(argv, "hm:a:v:f:g:l:", [ "mineralfile", "atoms", "variable", "folder1", "gfolder2", "letters" ]) except getopt.GetoptError: print( "plot_allgofrs_2subplots.py -m <mineralfile> -a <1 couple of atoms>(ex: 'O-O') -v <variable for colors (rho,T)> -f <folder 1> -g <folder 2> -l <two letters>" ) sys.exit() for opt, arg in options: if opt == '-h': print( "plot_allgofrs_2subplots.py script to plot all the gofrs of the selected couple of atoms at every acell for 2 T or at every T for 2 acell" ) print( "plot_allgofrs_2subplots.py for O-O, an insert is added to zoom in the 0-2$\AA$ region" ) print("WARNING!!!!!") print( "plot_allgofrs_2subplots.py requires to have separated folders of T and acell in order to plot all the files from the 2 T folders or from the 2 acell folders" ) print("") print( "plot_allgofrs_2subplots.py -m <mineralfile> -a <1 couple of atoms>(ex: 'O-O') -v <variable for colors (rho,T)> -f <folder 1> -g <folder 2> -l <two letters>" ) print("") sys.exit() elif opt in ("-a", "--atoms"): atom_couple = str( arg) #list of atom couples we want to analyze here elif opt in ("-m", "--mineralfile"): mineralfile = str(arg) elif opt in ("-v", "--variable"): variable = str(arg) elif opt in ("-f", "--folder1"): folder1 = str(arg).split('/')[0] elif opt in ("-g", "--gfolder2"): folder2 = str(arg).split('/')[0] elif opt in ("-l", "--letters"): letters = arg.split(',') #***** Calculation of the molecular mass with open(mineralfile, 'r') as mf: entry = mf.readline() elements = entry.split()[1:] entry = mf.readline() number = entry.split()[1:] MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest( elements[i])[3] #I compute the molecular mass #***** Count of the number of densities or temperatures (needed for the automatic color change) #loop throught all files of the selected folder files1 = sorted( glob.glob(folder1 + '/*outcar.gofr.dat' )) #I list every gofr files from folder1 in alphabetic order files2 = sorted( glob.glob(folder2 + '/*outcar.gofr.dat' )) #I list every gofr files from folder1 in alphabetic order files = files1[:] files.extend(files2) print(files) files.reverse() if variable == 'rho': #we store every density into the dictionary colors_densities for file in files: #calculation of densities in g/cm3 temperature, acell = split_name(file) Volume = float(acell)**3 Density = MN / (Na * Volume * 10**(-24)) #we store the densities into the dictionnary colors_densities[round(Density, 1)] = [] #now the dictionary has every possible densities or temperatures of our mineral, we attribute the colors to each density/temperature list_densities = [] if variable == 'rho': color = iter(plt.cm.rainbow(np.linspace( 0, 1, len(colors_densities)))) #Creation of the color list for key in natsort.natsorted(colors_densities): c = next(color) colors_densities[key] = c list_densities.append( key ) #list usefull if we want to plot the value of densities near to the lines, see plot_speciation_r0 print( list_densities, "densities list for color bar. If you don't want densities but temperatures, please change the variable option to T" ) else: print([ key for key in colors_T ], "temperature list for color bar. If you don't want temperatures but densities, please change the variable option to rho" ) #***************************** #******************* #******* #Read & plot firstfile = files[0] #I take the first file temperature0, acell0 = split_name(firstfile) with open(firstfile, 'r') as f: couples = f.readline() couples = couples.strip('dist') couples = re.sub('(Int\([A-Za-z-]*\))', ' ', couples).split( ) #I substitute all Int(...) by a blankspace and split using spaces col = 0 for couple in couples: if (couple == atom_couple): if atom_couple == 'O-O': fig, ax1, ax2, ax11, ax22 = creation_plot_insert( plot_parameters, atom_couple) indexcol = couples.index(couple) + col + 1 if variable == 'rho': for file in files1: #extraction of data distance, gofr = extraction(file, indexcol) #extraction of key for color legend temperature, acell = split_name(file) Volume = float(acell)**3 Density = MN / (Na * Volume * 10**(-24) ) #calculation of densities in g/cm3 #plot lines[str(round(Density, 1))], = ax1.plot( distance, gofr, color=colors_densities[round(Density, 1)], linewidth=plot_parameters['size_lines']) ax11.plot(distance, gofr, color=colors_densities[round(Density, 1)], linewidth=plot_parameters['size_lines']) for file in files2: #extraction of data distance, gofr = extraction(file, indexcol) #extraction of key for color legend temperature, acell = split_name(file) Volume = float(acell)**3 Density = MN / (Na * Volume * 10**(-24) ) #calculation of densities in g/cm3 #plot lines[str(round(Density, 1))], = ax2.plot( distance, gofr, color=colors_densities[round(Density, 1)], linewidth=plot_parameters['size_lines']) ax22.plot(distance, gofr, color=colors_densities[round(Density, 1)], linewidth=plot_parameters['size_lines']) else: #variable == T for file in files1: #extraction of data distance, gofr = extraction(file, indexcol) #extraction of key for color legend temperature, acell = split_name(file) #plot lines[format_T(temperature)], = ax1.plot( distance, gofr, color=colors_T[temperature], linewidth=plot_parameters['size_lines']) ax11.plot(distance, gofr, color=colors_T[temperature], linewidth=plot_parameters['size_lines']) for file in files2: #extraction of data distance, gofr = extraction(file, indexcol) #extraction of key for color legend temperature, acell = split_name(file) #plot lines[format_T(temperature)], = ax2.plot( distance, gofr, color=colors_T[temperature], linewidth=plot_parameters['size_lines']) ax22.plot(distance, gofr, color=colors_T[temperature], linewidth=plot_parameters['size_lines']) else: #atom_couple != O-O fig, ax1, ax2 = creation_plot(plot_parameters, atom_couple) indexcol = couples.index(couple) + col + 1 if variable == 'rho': for file in files1: #extraction of data distance, gofr = extraction(file, indexcol) #extraction of key for color legend temperature, acell = split_name(file) Volume = float(acell)**3 Density = MN / (Na * Volume * 10**(-24) ) #calculation of densities in g/cm3 #plot lines[str(round(Density, 1))], = ax1.plot( distance, gofr, color=colors_densities[round(Density, 1)], linewidth=plot_parameters['size_lines']) for file in files2: #extraction of data distance, gofr = extraction(file, indexcol) #extraction of key for color legend temperature, acell = split_name(file) Volume = float(acell)**3 Density = MN / (Na * Volume * 10**(-24) ) #calculation of densities in g/cm3 #plot lines[str(round(Density, 1))], = ax2.plot( distance, gofr, color=colors_densities[round(Density, 1)], linewidth=plot_parameters['size_lines']) else: #variable == T for file in files1: #extraction of data distance, gofr = extraction(file, indexcol) #extraction of key for color legend temperature, acell = split_name(file) #plot lines[format_T(temperature)], = ax1.plot( distance, gofr, color=colors_T[temperature], linewidth=plot_parameters['size_lines']) for file in files2: #extraction of data distance, gofr = extraction(file, indexcol) #extraction of key for color legend temperature, acell = split_name(file) #plot lines[format_T(temperature)], = ax2.plot( distance, gofr, color=colors_T[temperature], linewidth=plot_parameters['size_lines']) col += 1 #article letter ax1.text(0.012, 0.985, letters[0], transform=ax1.transAxes, verticalalignment='top', horizontalalignment='left', fontweight='bold', fontsize=plot_parameters["size_fonts"], bbox=dict(facecolor='none', edgecolor='k', pad=3.0)) ax2.text(0.012, 0.985, letters[1], transform=ax2.transAxes, verticalalignment='top', horizontalalignment='left', fontweight='bold', fontsize=plot_parameters["size_fonts"], bbox=dict(facecolor='none', edgecolor='k', pad=3.0)) # Legend ax0 = fig.add_subplot(111, frameon=False) plt.tick_params(labeltop=False, top=False, labelbottom=False, bottom=False, labelleft=False, left=False, labelright=False, right=False) s = [(k, lines[k]) for k in sorted(lines.keys())] #sort the dictionnary if variable == 'rho': title_legend = ' $\\bf{Density}$ \n (g.cm$^{-3}$)' else: title_legend = ' $\\bf{Temperature}$ (K)' #title_legend=' $\\bf{Temperature}$ \n (K)' ncol = 8 legend = ax0.legend([v for k, v in s[:ncol]], [k for k, v in s[:ncol]], title=title_legend, bbox_to_anchor=(0.5, 1.05), loc="lower center", borderaxespad=0., fontsize=plot_parameters['size_font_ticks'], ncol=ncol) #legendbis = ax0.legend([v for k,v in s[ncol:]],[k for k,v in s[ncol:]], bbox_to_anchor=(0.5, 1.05), loc="upper center", borderaxespad=0., fontsize = plot_parameters['size_font_ticks'], ncol = ncol) #legend = ax0.legend([v for k,v in s],[k for k,v in s], title = title_legend, bbox_to_anchor=(1.05, 1), loc='upper left", borderaxespad=0., fontsize = plot_parameters['size_font_ticks']) plt.setp(legend.get_title(), fontsize=plot_parameters['size_fonts']) ax0.add_artist(legend) #Save fig filename = 'gofrs_' + files[0].split('/')[-1].split( '_')[0] + '_' + folder1 + '_' + folder2 + '_' + atom_couple + '.pdf' plt.savefig(filename, bbox_inches="tight", dpi=300) print(filename, ' is created')
def main(argv): """ ********* Main program ********* """ SkipSteps = 0 units = 0 #parameters Na = 6.022e23 #Avogadro constant eVtoJ = 1.6e-19 #1eV = 1.6e-19 J KtoeV = 0.000086173324 #1K = 8.62E-5 eV kb = 1.38064852e-23 #boltzmann constant umd.headerumd() try: options, arg = getopt.getopt(argv, "hs:u:", ["sSkipSteps", "units"]) except getopt.GetoptError: print( 'fullaverages.py -s <SkipSteps> -u <units version: 0 = minimal (default), 1 = full units>' ) sys.exit() for opt, arg in options: if opt == '-h': print( 'fullaverages.py -s <SkipSteps> -u <units version: 0 = minimal (default), 1 = full units>' ) print( 'Program to extract and average thermodynamic data from all the umd files in the current folder' ) print( 'As ouptut it produces a fullthermo.dat file. On each line there are specified in order: ' ) print(' - the umd filename, the number of snapshots') print(' - 3 columns per variable (rho,P,T,E)') print(' - average') print(' - stdev of data to the mean') print(' - statistical error on the mean') print( ' - 2 columns for the Cv(Nkb) with the calculated value and statistical error' ) print( 'WARNING: please note that the Cv formulation is valdid *only* for NVT simulations' ) print(' ') sys.exit() elif opt in ("-s", "--sSkipSteps"): SkipSteps = int(arg) elif opt in ("-u", "--units"): units = int(arg) #Initialization files = sorted( glob.glob('*.umd.dat')) #list every umd files in alphabetic order f, natom = headerfile(files[0], units) #I create the first newfile for averages #Calculation for each file and writing of the newfile for file in files: results = [ ] #initialization of the final result array, used to print each line of result in the new file is_E = 0 #initialization of the indicator of energy (in order to compute the Cv) is_KE = 0 print('Averaging in file', file) results.append(file) #********** Extraction of the Data for the Density, Pressure, Temperature and Energy # In each case we try to: # 1) extract the data from the umd, create the array and compute the average and stendard deviation # 2) compute the sequence of values obtained from (c0/(n-1))**(1/2) (see blocking method in Flyvbjerg1989) # 3) select the values to write in the file # #**** Density try: nsteps_rho, Density, Average_rho, Variance_rho, stdev_rho = grep_pattern( file, "Density", SkipSteps) list_sigma_rho, list_err_rho = blocking_method( Density, Variance_rho) final_sigma_rho, final_err_rho = selection_value( list_sigma_rho, list_err_rho) except subprocess.CalledProcessError: print(' WARNING !!! Density is not defined in the UMD file') nsteps_rho, Density, Average_rho, Variance_rho, stdev_rho = (0.0, 0.0, 0.0, 0.0, 0.0) list_sigma_rho, list_err_rho = (np.zeros(3), np.zeros(3)) final_sigma_rho, final_err_rho = ('0.0', '0.0') #**** Pressure try: nsteps_P, Pressure, Average_P, Variance_P, stdev_P = grep_pattern( file, "Pressure", SkipSteps) list_sigma_P, list_err_P = blocking_method(Pressure, Variance_P) final_sigma_P, final_err_P = selection_value( list_sigma_P, list_err_P) except subprocess.CalledProcessError: print(' WARNING !!! Pressure is not defined in the UMD file') nsteps_P, Pressure, Average_P, Variance_P, stdev_P = (0.0, 0.0, 0.0, 0.0, 0.0) list_sigma_P, list_err_P = (np.zeros(3), np.zeros(3)) final_sigma_P, final_err_P = ('0.0', '0.0') #**** Temperature try: nsteps_T, Temperature, Average_T, Variance_T, stdev_T = grep_pattern( file, "Temperature", SkipSteps) list_sigma_T, list_err_T = blocking_method(Temperature, Variance_T) final_sigma_T, final_err_T = selection_value( list_sigma_T, list_err_T) except subprocess.CalledProcessError: print(' WARNING !!! Temperature is not defined in the UMD file') nsteps_T, Temperature, Average_T, Variance_T, stdev_T = (0.0, 0.0, 0.0, 0.0, 0.0) list_sigma_T, list_err_T = (np.zeros(3), np.zeros(3)) final_sigma_T, final_err_T = ('0.0', '0.0') #**** Energies try: #this energy does not include the kinetic energy of ions, it is the energy without entropy of VASP nsteps_EWE, EnergyWithoutEntropy, Average_EWE, Variance_EWE, stdev_EWE = grep_pattern( file, "InternalEnergy", SkipSteps) list_sigma_EWE, list_err_EWE = blocking_method( EnergyWithoutEntropy, Variance_EWE) final_sigma_EWE, final_err_EWE = selection_value( list_sigma_EWE, list_err_EWE) is_E = 1 except subprocess.CalledProcessError: print( ' WARNING !!! InternalEnergy is not defined in the UMD file' ) nsteps_EWE, EnergyWithoutEntropy, Average_EWE, Variance_EWE, stdev_EWE = ( 0.0, 0.0, 0.0, 0.0, 0.0) list_sigma_EWE, list_err_EWE = (np.zeros(3), np.zeros(3)) final_sigma_EWE, final_err_EWE = ('0.0', '0.0') try: nsteps_K, KineticEnergy, Average_K, Variance_K, stdev_K = grep_pattern( file, "KineticEnergyIons", SkipSteps) is_KE = 1 except subprocess.CalledProcessError: print( ' WARNING !!! KineticEnergy is not defined in the UMD file') nsteps_K, KineticEnergy, Average_K, Variance_K, stdev_K = (0.0, 0.0, 0.0, 0.0, 0.0) #the internal energy as used in the Hugoniot calculation is the internal energy which includes the kinetic energy of ions if is_E == 1 and is_KE == 1: Energy = [ KineticEnergy[ii] + EnergyWithoutEntropy[ii] for ii in range(len(KineticEnergy)) ] nsteps_E = len(Energy) Average_E = sum(Energy) / nsteps_E Variance_E = 0 for ii in range(nsteps_E): Variance_E = Variance_E + (Energy[ii] - Average_E)**2 Variance_E = Variance_E / nsteps_E stdev_E = np.sqrt(Variance_E) list_sigma_E, list_err_E = blocking_method(Energy, Variance_E) final_sigma_E, final_err_E = selection_value( list_sigma_E, list_err_E) else: print( ' WARNING !!! InternalEnergy does not include the kinetic energy of ions!!' ) nsteps_E, Energy, Average_E, Variance_E, stdev_E = nsteps_EWE, EnergyWithoutEntropy, Average_EWE, Variance_EWE, stdev_EWE list_sigma_E, list_err_E = list_sigma_EWE, list_err_EWE final_sigma_E, final_err_E = final_sigma_EWE, final_err_EWE #**** For the calculation of Cv and conversions we need the mass of the cell and natoms #--> we read the header of the umd file using umd_process store the elements information in the class MyCrystal (MyCrystal, TimeStep) = umd.read_bigheader_umd(file) natom = MyCrystal.natom #***** Calculation of Cv and statistical error using the bootstrap method #*** The calculation of Cv depends on the data we have (E, KE) # If we have E but not KE, then we take the ideal gas kinetic part to compute the Cv if is_E == 1 and is_KE == 0: print( ' For information: Cv is computed using the ideal gas kinetic part' ) Cv_bootstrap = [] for n in range(1000): #print('*****Bootstrap N°',n) Energy_rand = np.random.choice(Energy, nsteps_E, replace=True) variance_Erand = 0 variance_Erand = np.mean(Energy_rand** 2) - np.mean(Energy_rand)**2 Cv = variance_Erand * (eVtoJ)**2 / ( kb * Average_T**2) + 3 / 2 * natom * kb #in J/unitcell/K Cv_bootstrap.append(Cv) Cv_bootstrap = np.asarray(Cv_bootstrap) Cv = np.mean( Cv_bootstrap) #an estimator of the mean of Cv, in J/unitcell/K Cv_stdev = np.sqrt( np.mean(Cv_bootstrap**2) - np.mean(Cv_bootstrap)** 2) #the error on the previous mean, in J/unitcell/K # If we have E and KE, then we take both variances to compute the Cv elif is_E == 1 and is_KE == 1: print( ' For information: Cv is computed using both internal and kinetic energy variances' ) Cv_bootstrap = [] for n in range(1000): #print('*****Bootstrap N°',n) Energy_rand = np.random.choice(Energy, nsteps_E, replace=True) variance_Erand = 0 variance_Erand = np.mean(Energy_rand** 2) - np.mean(Energy_rand)**2 Cv = variance_Erand * (eVtoJ)**2 / (kb * Average_T**2 ) #in J/unitcell/K Cv_bootstrap.append(Cv) Cv_bootstrap = np.asarray(Cv_bootstrap) Cv = np.mean( Cv_bootstrap) #an estimator of the mean of Cv, in J/unitcell/K Cv_stdev = np.sqrt( np.mean(Cv_bootstrap**2) - np.mean(Cv_bootstrap)** 2) #the error on the previous mean, in J/unitcell/K #if we do not have the energy, then we do not compute the Cv else: print(' WARNING !!! Cv is not computed') Cv, Cv_stdev = (0, 0) Cvm = Cv * Na / natom #in J/K/mol Cvm_stdev = Cv_stdev * Na / natom #in J/K/mol Cvm_Nkb = Cv / (kb * natom) #in Nakb Cvm_Nkb_stdev = Cv_stdev / (kb * natom) #in Nakb #****** Write result line #**** For the conversions we need the mass of the cell #--> we read the header of the umd file using umd_process store the elements information in the class MyCrystal (MyCrystal, TimeStep) = umd.read_bigheader_umd(file) mass = 0 for itypat in range(MyCrystal.ntypat): (atomicname, atomicsymbol, atomicnumber, MyCrystal.masses[itypat]) = cr.Elements2rest( MyCrystal.elements[itypat]) mass = mass + MyCrystal.masses[itypat] * MyCrystal.types[itypat] mass = mass / Na #convert eV/unitcell to eV/atom or to J/g if final_sigma_E[0] == '>': final_sigma_E_conv = '>' + '{:1.1e}'.format( float(final_sigma_E[1:]) / natom) final_sigma_E_mass = '>' + '{:1.1e}'.format( float(final_sigma_E[1:]) * eVtoJ / mass) else: final_sigma_E_conv = '{:1.1e}'.format( float(final_sigma_E[:]) / natom) final_sigma_E_mass = '{:1.1e}'.format( float(final_sigma_E[:]) * eVtoJ / mass) if units == 0: results.extend([ str(nsteps_P), '{:1.2f}'.format(Average_rho), '{:1.1e}'.format(stdev_rho), str(final_sigma_rho), '{:1.2e}'.format(Average_P), '{:1.1e}'.format(stdev_P), str(final_sigma_P), '{:1.0f}'.format(Average_T), '{:1.0f}'.format(stdev_T), str(final_sigma_T), '{:1.2e}'.format(Average_E / natom), '{:1.1e}'.format(stdev_E / natom), str(final_sigma_E_conv), '{:1.2f}'.format(Cvm_Nkb), '{:1.1e}'.format(Cvm_Nkb_stdev) ]) else: #additional conversion of units #conversion of eV/unitcell to J/g Average_E_mass = Average_E * eVtoJ / mass stdev_E_mass = stdev_E * eVtoJ / mass #conversion of J/K to J/K/g Cvm_mass = Cv / mass Cvm_mass_stdev = Cv_stdev / mass #conversion K to eV if final_sigma_T[0] == '>': final_sigma_T_conv = '>' + '{:1.1e}'.format( float(final_sigma_T[1:]) * KtoeV) else: final_sigma_T_conv = '{:1.1e}'.format( float(final_sigma_T[:]) * KtoeV) results.extend([ str(nsteps_P), '{:1.2f}'.format(Average_rho), '{:1.1e}'.format(stdev_rho), str(final_sigma_rho), '{:1.2e}'.format(Average_P), '{:1.1e}'.format(stdev_P), str(final_sigma_P), '{:1.0f}'.format(Average_T), '{:1.0f}'.format(stdev_T), str(final_sigma_T), '{:1.2e}'.format(Average_T * KtoeV), '{:1.1e}'.format(stdev_T * KtoeV), str(final_sigma_T_conv), '{:1.2e}'.format(Average_E / natom), '{:1.1e}'.format(stdev_E / natom), str(final_sigma_E_conv), '{:1.3e}'.format(Average_E), '{:1.1e}'.format(stdev_E), str(final_sigma_E), '{:1.3e}'.format(Average_E_mass), '{:1.1e}'.format(stdev_E_mass), str(final_sigma_E_mass), '{:1.2f}'.format(Cvm_Nkb), '{:1.1e}'.format(Cvm_Nkb_stdev), '{:1.2e}'.format(Cvm), '{:1.1e}'.format(Cvm_stdev), '{:1.2e}'.format(Cvm_mass), '{:1.1e}'.format(Cvm_mass_stdev), '{:1.2e}'.format(Cv), '{:1.1e}'.format(Cv_stdev) ]) f.write("\t".join(x for x in results) + "\n") f.close()
def main(argv): """ ********* Main program ********* """ #parameters for the figures depending on the output format (presentation or article) plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (8,4),"size_markers" : 8,"size_lines" : 1,"shift_labelpad" : 20} colors_T = {'0':'k','2000':'#800080','3000':'#297fff','4000':'#00ff00','4500':'#bae200','5000':'#ffcd01','5500':'#ff6e00','6000':'#ff0101','6500':'#ff00a2','7000':'#ff01de'} plot_area = 1 #0 to only plot lines of each colors for our data, 1 to plot instead area (enveloppe) of our data #initialization of parameters filename4 = '' filename3 = '' #other parameters Na=6.022*10**23 try: options,arg = getopt.getopt(argv,"hf:g:j:i:",["filename2","gfilename","jfilename","ifilename"]) except getopt.GetoptError: print("plot_coordinence_separated.py -f <bonds_compound.txt> -g <gofr_comparison1.txt> -j <gofr_comparison2.txt> -i <gofr_comparison3.txt> ") sys.exit() for opt,arg in options: if opt == '-h': print('') print('plot_coordinence_separated.py program to plot coordinence as a function of density for each T and all cations with O') print("plot_coordinence_separated.py-f <bonds_compound.txt> -g <gofr_comparison1.txt> -j <gofr_comparison2.txt> -i <gofr_comparison3.txt> ") print("plot_coordinence_separated.py requires bonds.txt file containing every bond distance of one compound for every acell (use bond_analysis.py script)") print('') sys.exit() if opt in ('-f','--filename'): filename = str(arg) #plot bond length --> column 5 and xmax --> column 1 elif opt in ('-g','--gfilename'): filename2 = str(arg) # plot from deKoker 2010 elif opt in ('-j','--jfilename'): filename3 = str(arg) elif opt in ('-i','--ifilename'): filename4 = str(arg) #************ creation of the figure to plot (with correct number of lines) if filename3 == '': if filename4 == '': files = [filename,filename2] string = filename.split('_')[1]+'-'+filename2.split('.txt')[0].split('_')[-1] else: files = [filename,filename2, filename3] string = filename.split('_')[1]+'-'+filename2.split('.txt')[0].split('_')[-1]+'-'+filename3.split('.txt')[0].split('_')[-1] else: if filename4 == '': files = [filename,filename2, filename3] string = filename.split('_')[1]+'-'+filename2.split('.txt')[0].split('_')[-1]+'-'+filename3.split('.txt')[0].split('_')[-1] else: files = [filename,filename2,filename3,filename4] string = filename.split('_')[1]+'-'+filename2.split('.txt')[0].split('_')[-1]+'-'+filename3.split('.txt')[0].split('_')[-1]+'-'+filename4.split('.txt')[0].split('_')[-1] typeline = {filename : '-', filename2: '+', filename3: '*',filename4: 'x'} atoms = ['Na-O','Ca-O','Al-O','Si-O'] nlines = 3 size_figure = (6,2.3*nlines) #height of the figure depends on the number of pair we display offset = 0 #offset for printing text on Na-O K-O subplot plt.close(1) fig, (ax1,ax2,ax3) = plt.subplots(nrows = nlines, ncols = 1, sharex = True, sharey = False, figsize=size_figure) major_xticks = np.arange(0, 8, 0.5) minor_xticks = np.arange(0, 8, 0.1) for ax in [ax1,ax2,ax3]: ax.set_xticks(major_xticks) ax.set_xticks(minor_xticks, minor=True) ax.xaxis.set_ticks_position('both') majorLocator = AutoLocator() minorLocator = AutoMinorLocator() ax.yaxis.set_ticks_position('both') ax.yaxis.set_major_locator(majorLocator) ax.yaxis.set_minor_locator(minorLocator) ax.set_xlim(0.9,4.4) plt.autoscale(axis='y') ax.tick_params(which = 'both', labelsize = plot_parameters["size_font_ticks"], width = plot_parameters["size_lines"]/2) # Fine-tune figure : 1) make subplots close to each other (+ less whitespace around), 2) hide x ticks for all but bottom plot, 3) add a big invisible subplot in order to center x and y labels (since the ticklabels are turned off we have to move the x and y labels with labelpad) fig.subplots_adjust(top = 0.95, bottom = 0.1, right = 0.95, left = 0.1, hspace = 0.03, wspace = 0.02) ax0 = fig.add_subplot(111, frameon=False) plt.tick_params(labeltop=False, top=False, labelbottom=False, bottom=False, labelleft=False, left=False, labelright = False, right=False) ax0.set_xlabel(r'Density (g.cm$^{-3}$)', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]) ax0.set_ylabel(r'Bond length ($\AA$)', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]*1.5) figurename = 'bondlength_'+ string #************** Extract our data and plot #*** Initialization of data dictionnaries pair_columns = {} data = {} #big dictionnary with inside coord all coresponding to different T and atom pairs rho = {} #idem for rho enveloppe = {} rhoenveloppe = {} yvariable = 1 #first file --> xmax linestyle = '-' colorline = '#368400ff' colorfill = '#3684007f' for iteration in range(3): #*** Calculation of the molecular mass with open(filename, 'r') as f: line = f.readline() entry=line.split() elements = entry[1:] line = f.readline() entry=line.split() number = entry[1:] line = f.readline() entry=line.split() pair = entry[1:] MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #******** extraction of data pair_columns[pair[0]] =yvariable for i in range(1,len(pair)): if pair[i] != pair[i-1]: pair_columns[pair[i]] = i+yvariable print('All the pairs available in the file with their index are:', pair_columns) for atom_pair in pair_columns: for atom in atoms: if atom_pair == atom: data[atom] = {} rho[atom] = {} enveloppe[atom] = {} rhoenveloppe[atom]= {} with open(filename,'r') as f: [f.readline() for i in range(4)] while True: line = f.readline() if not line: break else: entry=line.split('\n')[0].split('\t') temperature, acell = split_name(entry[0]) for atom_pair in pair_columns: for atom in atoms: if atom_pair == atom: try: data[atom][temperature].append( float(entry[pair_columns[atom]]) ) rho[atom][temperature].append( MN/(Na*float(acell)**3*10**(-24)) ) #calculation density except KeyError: data[atom][temperature] = [ float(entry[pair_columns[atom]]) ] rho[atom][temperature] = [ MN/(Na*float(acell)**3*10**(-24)) ] #calculation density #***** Compute the enveloppe of our data if plot_area == 1: for atom in data: #take all the data together alldata = [] allrho = [] for temp in data[atom]: alldata.extend(data[atom][temp]) allrho.extend(rho[atom][temp]) allrho, alldata = zip(*sorted(zip(allrho, alldata))) #extract enveloppe enveloppe[atom]['up'] = [alldata[0]] enveloppe[atom]['down'] = [alldata[0]] rhoenveloppe[atom] = [allrho[0]] j = 0 for i in range(1,len(allrho)): if allrho[i] == allrho[i-1]: if alldata[i] > enveloppe[atom]['up'][j]: enveloppe[atom]['up'][j] = alldata[i] if alldata[i] < enveloppe[atom]['down'][j]: enveloppe[atom]['down'][j] = alldata[i] else: j+=1 rhoenveloppe[atom].append(allrho[i]) enveloppe[atom]['up'].append(alldata[i]) enveloppe[atom]['down'].append(alldata[i]) #print('len enveloppe',len(enveloppe[atom]['up']),len(enveloppe[atom]['down']), len(rhoenveloppe[atom])) #***** Plot each atom pair on the correct subplot --> ax1 for Na/Ca-O, ax2 for Al-O, ax3 for Si-O for temperature in data['Si-O']: for atom in data: if atom == 'Ca-O' or atom == 'Na-O': if plot_area == 1: ax1.fill_between(rhoenveloppe[atom],enveloppe[atom]['up'],enveloppe[atom]['down'], facecolor = colorfill, linewidth=plot_parameters['size_lines'], alpha = 0.1) ax1.plot(rhoenveloppe[atom],enveloppe[atom]['down'], linestyle = linestyle, color=colorline, linewidth=plot_parameters["size_lines"] ) ax1.plot(rhoenveloppe[atom],enveloppe[atom]['up'], linestyle = linestyle, color=colorline, linewidth=plot_parameters["size_lines"] ) else: ax1.plot(rho[atom][temperature],data[atom][temperature], linestyle = linestyle, color=colors_T[temperature], markersize = plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"] ) elif atom == 'Si-O': if plot_area == 1: ax3.fill_between(rhoenveloppe[atom],enveloppe[atom]['up'],enveloppe[atom]['down'], facecolor = colorfill, linewidth=plot_parameters['size_lines'], alpha = 0.1) ax3.plot(rhoenveloppe[atom],enveloppe[atom]['down'], linestyle = linestyle, color=colorline, linewidth=plot_parameters["size_lines"] ) ax3.plot(rhoenveloppe[atom],enveloppe[atom]['up'], linestyle = linestyle, color=colorline, linewidth=plot_parameters["size_lines"] ) else: ax3.plot(rho[atom][temperature],data[atom][temperature], linestyle = linestyle, color=colors_T[temperature], markersize = plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"] ) #ax3.text( 0.02,0.91, atom ,transform=ax3.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for coord ax3.text( 0.89,0.91, atom ,transform=ax3.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for bond elif atom == 'Al-O': if plot_area == 1: ax2.fill_between(rhoenveloppe[atom],enveloppe[atom]['up'],enveloppe[atom]['down'], facecolor = colorfill, linewidth=plot_parameters['size_lines'], alpha = 0.1) ax2.plot(rhoenveloppe[atom],enveloppe[atom]['down'], linestyle = linestyle, color=colorline, linewidth=plot_parameters["size_lines"] ) ax2.plot(rhoenveloppe[atom],enveloppe[atom]['up'], linestyle = linestyle, color=colorline, linewidth=plot_parameters["size_lines"] ) else: ax2.plot(rho[atom][temperature],data[atom][temperature],linestyle = linestyle, color=colors_T[temperature], markersize = plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"] ) #ax2.text(0.02,0.91, atom ,transform=ax2.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for coord ax2.text(0.89,0.91, atom ,transform=ax2.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for bond if iteration == 0: linestyle = '--' colorline = '#368400ff' colorfill = '#3684007f' yvariable = 2 #second run --> average elif iteration == 1: linestyle = '-.' colorline = '#6fc933ff' colorfill = '#6fc9337f' yvariable = 3 #third run --> median elif iteration == 2: linestyle = ':' colorline = 'k' colorfill = 'gray' yvariable = 4 #fourth run --> bondr3 #************** Extract the collected data and plot sources = {'gofrs-bond_deKoker2010.txt':'de Koker (2010)','gofrs-bond_Angel1990.txt':'Angel $et~al.$ (1990)','gofrs-bond_Taylor1979.txt':'Taylor and Brown (1979)'} print('files from other sources',files[1:]) for file in files[1:]: print('For file ',file) #***** Initialization of data dictionnaries pair_columns={'Na-O':2,'Ca-O':2,'Al-O':3,'Si-O':4} data = {} #big dictionnary with inside coord all coresponding to different T and atom pairs rho = {} #idem for rho with open(file, 'r') as f: line = f.readline() entry=line.split() pairs = entry[2:9] print('All the pairs available in the file are:', pairs) #******** extraction of data for atom_pair in pairs: for atom in atoms: if atom_pair == atom: data[atom] = {} rho[atom] = {} with open(file,'r') as f: f.readline() while True: line = f.readline() if not line: break else: entry=line.split('\n')[0].split('\t') temperature = str(int(float( entry[9]))) for atom_pair in pairs: for atom in atoms: if atom_pair == atom: datapoint = float(entry[pair_columns[atom]]) #replace 0 by nan if datapoint == 0.0: datapoint = float(np.nan) #add datapoint to data dic try: data[atom][temperature].append( datapoint ) rho[atom][temperature].append( float(entry[0])/1000) except KeyError: data[atom][temperature] = [ datapoint ] rho[atom][temperature] = [ float(entry[0])/1000] #***** Plot each atom pair on the correct subplot --> ax1 for Na/Ca-O, ax2 for Al-O, ax3 for Si-O for temperature in data['Si-O']: for atom in data: if atom == 'Ca-O' or atom == 'Na-O': #print('plot M-O for ', temperature) ax1.plot(rho[atom][temperature],data[atom][temperature], marker = typeline[file][0], linestyle = 'None', color=colors_T[temperature], markersize = plot_parameters["size_markers"] ) elif atom == 'Si-O': #print('plot Si-O for ', temperature) ax3.plot(rho[atom][temperature],data[atom][temperature], marker = typeline[file][0], linestyle = 'None', color=colors_T[temperature], markersize = plot_parameters["size_markers"]) elif atom == 'Al-O': #print('plot Al-O for ', temperature) ax2.plot(rho[atom][temperature],data[atom][temperature], marker = typeline[file][0], linestyle = 'None', color=colors_T[temperature], markersize = plot_parameters["size_markers"]) for atom in ['Ca-O']:#,'Na-O']: #ax1.text( 0.02,0.91-offset, atom,transform=ax1.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for coord ax1.text( 0.89,0.91-offset, atom,transform=ax1.transAxes, fontsize=plot_parameters['size_fonts'], fontweight='bold' ) #for bond offset = offset + 0.10 #we update the offset for printing text on Na-O K-O subplot after finishing the first file #Legend legend_labels = {} legend_labels2 = {} for file in files[1:]: legend_labels[sources[file]] = plt.Line2D((0,1),(0,0), color='k', linestyle = 'None', markersize = plot_parameters["size_markers"]-2, marker=typeline[file][0]) if plot_area == 1: legend_labels2['xmax'] = mpatches.Patch(facecolor='#3684007f', linestyle = '-',edgecolor='#368400ff') legend_labels2['average'] = mpatches.Patch(facecolor='#3684007f', linestyle = '--',edgecolor='#368400ff') legend_labels2['median'] = mpatches.Patch(facecolor='#6fc9337f', linestyle = '-.',edgecolor='#6fc933ff') else: legend_labels2['xmax'] = plt.Line2D((0,1),(0,0), color='k', linestyle='-', linewidth = plot_parameters["size_lines"]) legend_labels2['average'] = plt.Line2D((0,1),(0,0), color='k', linestyle='--', linewidth = plot_parameters["size_lines"]) legend_labels2['median'] = plt.Line2D((0,1),(0,0), color='k', linestyle='-.', linewidth = plot_parameters["size_lines"]) s = [(k, legend_labels[k]) for k in sorted(legend_labels.keys(),reverse = False)] s2 = [(k, legend_labels2[k]) for k in sorted(legend_labels2.keys(),reverse = False)] #legend1 = ax1.legend([v for k,v in s],[k for k,v in s], loc='lower left', bbox_to_anchor=(0.3, 1.02), ncol=1, fontsize = plot_parameters["size_font_ticks"], borderaxespad=0.) #legend2 = ax1.legend([v for k,v in s2],[k for k,v in s2], loc='lower left', bbox_to_anchor=(0.01, 1.02), ncol=1, fontsize = plot_parameters["size_font_ticks"], borderaxespad=0., title='This study') #plt.setp(legend2.get_title(),fontsize= plot_parameters["size_font_ticks"], fontweight = 'bold') legend1 = ax1.legend([v for k,v in s],[k for k,v in s], loc='lower left', bbox_to_anchor=(0.3, 0.02), ncol=1, fontsize = plot_parameters["size_font_ticks"]-2, borderaxespad=0.) legend2 = ax1.legend([v for k,v in s2],[k for k,v in s2], loc='lower left', bbox_to_anchor=(0.01, 0.02), ncol=1, fontsize = plot_parameters["size_font_ticks"]-2, borderaxespad=0.) ax1.add_artist(legend1) #save the figure figurename = figurename + '.pdf' fig.savefig(figurename, bbox_inches = 'tight', dpi = 300) print(figurename, ' created')
def main(argv): """ ********* Main program ********* """ #parameters for the figures depending on the output format (presentation or article) plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (8,8), "size_markers" : 5,"size_lines" : 1,"shift_labelpad" : 10} #other dictionnaries and parameters for the figure style_markers = {'CaAl2Si2O8':'d','KAlSi3O8':'s','NaAlSi3O8':'o'} style_lines = {'CaAl2Si2O8':':','KAlSi3O8':'--','NaAlSi3O8':'-'} colors_T = {'T2':'#800080','T3':'#297fff','T4':'#00ff00','T4.5':'#bae200', 'T5':'#ffcd01','T6':'#ff0101','T6.5':'#ff00a2','T7':'#ff01de'} #colors_T = create_colors() #variables nedded fot the plot filename = 'all' filename2 = '' ions = [] compounds = [] Temperatures = [] data = {} #dictionnary containing the data for each element, initialized for each T stdev = {} #same for stdev #other parameters Na=6.022*10**23 #dictionnary for fullaverages file in full version column_number = {'rho':2,'P':5,'stdev_P':6,'err_P':7,'T':8,'stdev_T':9,'err_T':10, 'E':14,'stdev_E':15,'err_E':16,'Cvm_Nkb':23,'stdev_Cvm_Nkb':24, 'Cvm':25,'stdev_Cvm':26,'testCv':31,'stdev_testCv':32} try: options,arg = getopt.getopt(argv,"hf:g:p:v:",["filename","gfilename2",'property','variable']) except getopt.GetoptError: print("plot_diffusion_2x2.py -f <filename>(default = all) -g <filename2(option)> -p <property to plot (D or t)> -v <variable x axis (rho or P)> ") sys.exit() for opt,arg in options: if opt == '-h': print('') print('plot_diffusion_2x2.py program to plot diffusion coefficient (or time of ballistic to diffusive regime change) as a function of density or pressure for each T and the selected minerals containing 4 elements') print("plot_diffusion_2x2.py -f <filename>(default = all files of every compound) -g <filename2(option)> -p <property to plot (D or t)> -v <variable x axis (rho or P)>") print("plot_diffusion_2x2.py requires to be lauched from the folder containing every diffusivities file created by the script analyze_msd") print('') print('For plots as function of P, make sure the files from fullaverages.py are in the current folder') sys.exit() if opt in ('-f','--filename'): filename = str(arg) elif opt in ('-g','--gfilename2'): filename2 = str(arg) elif opt in ('-p','--property'): prop = str(arg) elif opt in ('-v','--variable'): xvariable = str(arg) #** Figure creation fig,ax1,ax2,ax3,ax4, ax0 = creation_plot_2x2(plot_parameters, prop, xvariable) if prop == 'D': name = 'diffusivities' index = 1 else: name = 'regimechange' index = 6 if filename == 'all': files = sorted(glob.glob('diffusivities_*.txt'),reverse=True) #I list every diffusivities files figurename = name + '_2x2_all_'+xvariable elif filename2 != '': files = [filename,filename2] #I list every diffusivities files figurename = name + '_2x2_'+filename.split('.txt')[0].split('_')[1]+'_'+filename2.split('.txt')[0].split('_')[1]+'_'+xvariable else: files = [filename] #I take only the file we want figurename = name + '_2x2_'+filename.split('.txt')[0].split('_')[1]+'_'+xvariable #** Plot expe data handles, legendlabels = [] ,[] if prop == 'D': handles, legendlabels = plot_deKoker2010(ax1,ax2,ax3,ax4, handles, legendlabels, xvariable) handles, legendlabels = plot_Neilson2016(ax1,ax2,ax3,ax4, handles, legendlabels, xvariable) #handles, legendlabels = plot_Spera2009(ax1,ax2,ax3,ax4, handles, legendlabels, xvariable) #** Plot our data for file in files: #print("************************ for diffusivity file named",file) #**extraction compound compounds.append(file.split('_')[1].split('.txt')[0]) #we need the compound for the legend #******* Extract P and T for each thermo file if xvariable == 'P': TP = {} mineralname = file.split('_')[1].split('.txt')[0] thermofiles = sorted(glob.glob('thermo_'+mineralname+'*.txt')) for thermofile in thermofiles: TP = extract_TP(thermofile, column_number, TP,'') if TP == {}: print('ERROR!!!! TP dictionnary empty') #**creation of elements and number lists and initialization of T with open(file,'r') as f: skiplines = 0 while True: line = f.readline() skiplines += 1 entry=line.split() if entry[0] == 'elements': elements = entry[1:] ions.append(elements[0]) elif entry[0] == 'number': number = entry[1:] elif entry[0] == 'file': line = f.readline() entry=line.split() mineral, temperature0, acell0 = split_name(entry[0]) break #**calculation of M*N nedded for the calculation of densities MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #**initialisation of data data = {} #big dictionnary with inside self diffusion coefficient or time of regime change, all coresponding to different T and atom pairs stdev = {} #idem for stdev X = {} #idem for rho or P for elem in elements: stdev[elem] = {} data[elem] = {} X[elem] = {} #****** Extraction of data with open(file,'r') as f: [f.readline() for i in range(skiplines)] while True: line = f.readline() if not line: break else: entry=line.split('\n')[0].split('\t') mineral, temperature, acell = split_name(entry[0]) #print(entry[0]) for i in range(len(elements)): elem = elements[i] try: data[elem][temperature].append(float(entry[i*6+index])) stdev[elem][temperature].append(float(entry[i*6+2])) if xvariable == 'P': X[elem][temperature].append(TP[entry[0].split('outcar.msd.dat')[0].split('/')[-1]][1]) else: X[elem][temperature].append( MN/(Na*float(acell)**3*10**(-24)) ) #calculation density except KeyError: data[elem][temperature] = [ float(entry[i*6+index])] stdev[elem][temperature] = [ float(entry[i*6+2]) ] if xvariable == 'P': X[elem][temperature] = [TP[entry[0].split('outcar.msd.dat')[0].split('/')[-1]][1]] else: X[elem][temperature] = [ MN/(Na*float(acell)**3*10**(-24)) ] #calculation density #***** Plot each element on the correct subplot for elem in elements: #choice of axis if elem == 'O': ax = ax4 elif elem == 'Si': ax = ax3 elif elem == 'Al': ax = ax2 else: ax = ax1 for temperature in data[elem]: #print("******** ", temperature) #print(data[elem][temperature]) Temperatures.append(temperature) #attribution of fill color if mineral == 'NaAlSi3O8': fillcolor = colors_T[temperature]+'ff'#with custom dict #np.array([colors_T[temperature][0],colors_T[temperature][1],colors_T[temperature][2],1]) #with dic from create_colors() function elif mineral == 'CaAl2Si2O8': fillcolor = 'w' elif mineral == 'KAlSi3O8': fillcolor = colors_T[temperature]+'7f'#with custom dict #np.array([colors_T[temperature][0],colors_T[temperature][1],colors_T[temperature][2],0.5]) #with dic from create_colors() function #remove data with nan ThisData = np.array(data[elem][temperature]) ThisX= np.array(X[elem][temperature]) data_mask = np.isfinite(ThisData) ax.plot(ThisX[data_mask],ThisData[data_mask], style_markers[mineral]+style_lines[mineral], markersize = plot_parameters["size_markers"], markeredgewidth = 0.5, color = colors_T[temperature], markerfacecolor = fillcolor, markeredgecolor = colors_T[temperature], linewidth = plot_parameters["size_lines"]) #if prop == 'D': #ax.errorbar(X[elem][temperature],data[elem][temperature], yerr=stdev[elem][temperature], fmt=style_markers[mineral], markersize = plot_parameters[size_markers], markeredgewidth = 0.5, edgecolor colors_T[temperature], facecolor = fillcolor, linestyle = style_lines[mineral], linewidth = plot_parameters["size_lines"] ) #********* Legend #Create legend from custom artist/label lists Temperatures = list(set(Temperatures)) #get elements only once in the list custom_patch = [mpatches.Patch(color=colors_T[key]) for key in natsort.natsorted(Temperatures)] legend = ax0.legend([col for col in custom_patch],[str(int(float(label.strip('T'))*1000)) for label in natsort.natsorted(Temperatures)],title = '$\\bf{Temperature~(K)}$', bbox_to_anchor=(0.5, 1.07), loc="lower center", fontsize = plot_parameters["size_font_ticks"], borderaxespad=0., ncol=len(Temperatures)) plt.setp(legend.get_title(),fontsize= plot_parameters["size_font_ticks"]) #definition of line and marker style fillcolor = {} for mineral in style_markers: if mineral == 'CaAl2Si2O8': fillcolor[mineral] = 'w' elif mineral == 'KAlSi3O8': fillcolor[mineral] = '#0000007f' else: fillcolor[mineral] = '#000000ff' custom_lines = [plt.Line2D([0],[0], marker = style_markers[key], linestyle = style_lines[key], markeredgecolor = 'k', markerfacecolor = fillcolor[key], color = 'k', markersize = plot_parameters["size_markers"], markeredgewidth = 0.5, linewidth = plot_parameters["size_lines"]) for key in sorted(compounds)] ax0.legend([line for line in custom_lines],[format1label(label) for label in sorted(compounds)], bbox_to_anchor=(0.5, 1.02), loc='lower center', fontsize = plot_parameters["size_fonts"], borderaxespad=0., ncol =3) ax0.add_artist(legend) #Add elements on subplots if filename == 'all' or filename2 != '': string = ions[0] for i in range(1,len(ions)): string = string + ' ' + ions[i] ax1.text(0.95,0.9, string, transform=ax1.transAxes, horizontalalignment = 'right', fontweight = 'bold', fontsize = plot_parameters['size_fonts']) else: ax1.text(0.95,0.9, elements[0], transform=ax1.transAxes, horizontalalignment = 'right', fontweight = 'bold', fontsize = plot_parameters['size_fonts']) ax2.text(0.95,0.9, elements[1], transform=ax2.transAxes, horizontalalignment = 'right', fontweight = 'bold', fontsize = plot_parameters['size_fonts']) ax3.text(0.95,0.9, elements[2], transform=ax3.transAxes, horizontalalignment = 'right', fontweight = 'bold', fontsize = plot_parameters['size_fonts']) ax4.text(0.95,0.9, elements[3], transform=ax4.transAxes, horizontalalignment = 'right', fontweight = 'bold', fontsize = plot_parameters['size_fonts']) figurename = figurename + '.pdf' fig.savefig(figurename, bbox_inches = 'tight', dpi = 150) print(figurename,' created')
def main(argv): """ ********* Main program ********* """ #parameters for the figure for article plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (10,10), "size_markers" : 4,"size_lines" : 1,"shift_labelpad" : 10} #other dictionnaries and parameters for the figure colors_T = {'T2':'#800080','T3':'#297fff','T4':'#00ff00','T4.5':'#bae200', 'T5':'#ffcd01','T5.5':'#ff6e00','T6':'#ff0101','T6.5':'#ff00a2','T7':'#ff01de'} xvariable = 'rho' #variables nedded fot the plot #other dictionnaries and parameters for the figure Temperatures = [] #other parameters Na=6.022*10**23 #dictionnary for fullaverages file in full version column_number = {'rho':2,'P':5,'stdev_P':6,'err_P':7,'T':8,'stdev_T':9,'err_T':10, 'E':14,'stdev_E':15,'err_E':16,'Cvm_Nkb':23,'stdev_Cvm_Nkb':24, 'Cvm':25,'stdev_Cvm':26,'testCv':31,'stdev_testCv':32} try: options,arg = getopt.getopt(argv,"hv:",['variable']) except getopt.GetoptError: print("plot_diffusion_all_compvibr.py -v <variable x axis (rho or P)> ") sys.exit() for opt,arg in options: if opt == '-h': print('') print('plot_diffusion_all_compvibr.py program to plot diffusion coefficient as a function of density for each T and the selected minerals containing 4 elements') print("plot_diffusion_all_compvibr.py -v <variable x axis (rho or P)> ") print("plot_diffusion_all_compvibr.py requires to be lauched from the folder containing every diffusivities file created by the script analyze_msd and vibr2diffusion") print('') print('For plots as function of P, make sure the files from fullaverages.py are in the current folder') sys.exit() if opt in ('-v','--variable'): xvariable = str(arg) figurename = 'diffusivities_all_compvibr_'+xvariable if xvariable == 'rho': major_xticks = np.arange(0, 4.5, 0.5) minor_xticks = np.arange(0, 4.1, 0.1) label = r'Density (g.cm$^{-3}$)' else: label = r'Pressure (GPa)' minerals = ['NaAlSi3O8','KAlSi3O8','CaAl2Si2O8'] plt.close(1) fig = plt.figure(1,figsize=plot_parameters['size_figure']) plt.subplots_adjust(top = 0.97, bottom = 0.07, right = 0.89, left = 0.07, hspace = 0, wspace = 0) plt.subplot(4,3,1) #4 inles 3 columns ax = plt.gca() for mineral in minerals: #************ Extract Data diffusion_msd_file = 'diffusivities_'+mineral+'.txt' diffusion_vibr_file = 'diffusivities-vibr_'+mineral+'.txt' #** creation of elements and number lists with open(diffusion_vibr_file,'r') as f: skiplines = 0 while True: line = f.readline() skiplines += 1 entry=line.split() if entry[0] == 'elements': elements = entry[1:] elif entry[0] == 'number': number = entry[1:] elif entry[0] == 'file': break #** calculation of M*N nedded for the calculation of densities MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #** Extraction of data in diffusivities-vibr_mineral.txt file datavibr = {} Xvibr = {} #initialisation of data datavibr = {} #big dictionnary with inside self diffusion coefficient or time of regime change, all coresponding to different T and atom pairs Xvibr = {} #idem for rho or P for i in range(len(elements)): elem = elements[i] datavibr[elem] = {} Xvibr[elem] = {} #fill dictionnaries with open(diffusion_vibr_file,'r') as f: [f.readline() for i in range(skiplines)] while True: line = f.readline() if not line: break else: entry=line.split('\n')[0].split('\t') temp, acell = split_name(entry[0]) for i in range(len(elements)): elem = elements[i] try: datavibr[elem][temp].append(float(entry[i+2])) if xvariable == 'P': Xvibr[elem][temp].append(float(entry[1])) else: Xvibr[elem][temp].append( MN/(Na*float(acell)**3*10**(-24)) ) #calculation density except KeyError: datavibr[elem][temp] = [ float(entry[i+2])] if xvariable == 'P': Xvibr[elem][temp] = [float(entry[1])] else: Xvibr[elem][temp] = [ MN/(Na*float(acell)**3*10**(-24)) ] #calculation density #** Extract P and T from thermofile if xvariable == 'P': TP = {} thermofile = 'thermo_'+mineral+'_all.txt' TP = extract_TP(thermofile, column_number, TP,'') if TP == {}: print('ERROR!!!! TP dictionnary empty') #** Extraction of data in diffusivities_mineral.txt file dataMSD = {} XMSD = {} #count number lines in header with open(diffusion_msd_file,'r') as f: skiplines = 0 while True: line = f.readline() skiplines += 1 entry=line.split() if entry[0] == 'file': break #initialisation of data dataMSD = {} #big dictionnary with inside self diffusion coefficient or time of regime change, all coresponding to different T and atom pairs XMSD = {} #idem for rho or P for i in range(len(elements)): elem = elements[i] dataMSD[elem] = {} XMSD[elem] = {} #fill dictionnaries with open(diffusion_msd_file,'r') as f: [f.readline() for i in range(skiplines)] while True: line = f.readline() if not line: break else: entry=line.split('\n')[0].split('\t') temp, acell = split_name(entry[0]) for i in range(len(elements)): elem = elements[i] try: dataMSD[elem][temp].append(float(entry[i*6+1])) if xvariable == 'P': XMSD[elem][temp].append(TP[entry[0].split('outcar.msd.dat')[0].split('/')[-1]][1]) else: XMSD[elem][temp].append( MN/(Na*float(acell)**3*10**(-24)) ) #calculation density except KeyError: dataMSD[elem][temp] = [ float(entry[i*6+1])] if xvariable == 'P': XMSD[elem][temp] = [TP[entry[0].split('outcar.msd.dat')[0].split('/')[-1]][1]] else: XMSD[elem][temp] = [ MN/(Na*float(acell)**3*10**(-24)) ] #calculation density #************ Plot Data for elem in elements: #print("******** ", elem) #change of subplot plt.subplot(4,3,elements.index(elem)*3+1+minerals.index(mineral)) ax = plt.gca() #plot for temp in datavibr[elem]: #print("******** ", temp) #put only the T you want in colors_T (no T10, 15) try: ax.plot(Xvibr[elem][temp],datavibr[elem][temp], ls = ':', marker = 'x', markersize = plot_parameters["size_markers"], color = colors_T[temp], linewidth = plot_parameters["size_lines"]) ax.plot(XMSD[elem][temp],dataMSD[elem][temp], ls = '-', marker = '*', markersize = plot_parameters["size_markers"], color = colors_T[temp], linewidth = plot_parameters["size_lines"]) Temperatures.append(temp) except KeyError: pass #we add x and y labels outside the plot on the right columns and lines if elements.index(elem) == 0: ax.set_xlabel(format1label(mineral), fontweight = 'bold', fontsize = plot_parameters["size_fonts"]) ax.xaxis.set_label_position('top') if minerals.index(mineral) == len(minerals)-1: if elements.index(elem) == 0: ax.set_ylabel('Na, K, Ca', fontweight = 'bold', fontsize = plot_parameters["size_fonts"]) else: ax.set_ylabel(elem, fontweight = 'bold', fontsize = plot_parameters["size_fonts"]) ax.yaxis.set_label_position('right') #limitation of data along x if xvariable == 'rho': ax.set_xticks(major_xticks) ax.set_xticks(minor_xticks, minor=True) ax.set_xlim(1.0,4.1) if minerals.index(mineral) != len(minerals)-1: plt.setp(ax.get_xticklabels()[-1], visible=False) else: ax.set_xscale('log') ax.set_xlim(1,275) #limitation of data along y ax.set_yscale('log') ax.set_ylim(4e-10,3e-7) #we remove unwanted axis tick labels if minerals.index(mineral) != 0: plt.setp(ax.get_yticklabels(), visible=False) if elements.index(elem) != len(elements)-1: plt.setp(ax.get_xticklabels(), visible=False) #we make the graph prettier ax.xaxis.set_ticks_position('both') ax.yaxis.set_ticks_position('both') ax.yaxis.set_tick_params(which = 'both', direction='inout') ax.xaxis.set_tick_params(which = 'both', direction='inout') ax.grid(axis = 'y', which = 'major', linestyle = '--', linewidth = plot_parameters["size_lines"]/2, alpha = 0.5) ax.tick_params(which = 'both', labelsize = plot_parameters["size_font_ticks"], width = plot_parameters["size_lines"]/2) ax.set_facecolor((1,1,1,0)) #plt.setp(ax.get_yticklabels()[-1], visible=False) #************ Fine tune figure ax0 = fig.add_subplot(111, frameon=False) plt.tick_params(labeltop=False, top=False, labelbottom=False, bottom=False, labelleft=False, left=False, labelright = False, right=False) ax0.set_xlabel(label, fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]*2) ax0.set_ylabel(r'Diffusion coefficient (m$^2$.s$^{-1}$)', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], labelpad = plot_parameters["shift_labelpad"]*3+plot_parameters["shift_labelpad"]/2) #************ Create legend from custom artist/label lists Temperatures = list(set(Temperatures)) #get elements only once in the list custom_patch = [mpatches.Patch(color=colors_T[key]) for key in natsort.natsorted(Temperatures)] legend_labels = {'D from MSD': plt.Line2D((0,1),(0,0), color='k', markersize = plot_parameters["size_markers"], marker='*', linestyle='-', linewidth = plot_parameters["size_lines"]), 'D from vibrational spectrum': plt.Line2D((0,1),(0,0), color='k', markersize = plot_parameters["size_markers"], marker='x', linestyle='--', linewidth = plot_parameters["size_lines"])} s = [(k, legend_labels[k]) for k in sorted(legend_labels.keys(),reverse = False)] legend = ax0.legend([col for col in custom_patch],[str(int(float(label.strip('T'))*1000)) for label in natsort.natsorted(Temperatures)],title = '$\\bf{Temperature~(K)}$', bbox_to_anchor=(0.5, 1.08), loc="lower center", fontsize = plot_parameters["size_font_ticks"], borderaxespad=0., ncol=len(Temperatures)) plt.setp(legend.get_title(),fontsize= plot_parameters["size_font_ticks"]) plt.legend([v for k,v in s],[k for k,v in s], bbox_to_anchor=(0.5, 1.03), loc='lower center',fancybox=True, fontsize = plot_parameters["size_fonts"], ncol=len(legend_labels)) ax0.add_artist(legend) figurename = figurename + '.pdf' print("figure saved with name ",figurename) fig.savefig(figurename, bbox_inches = 'tight', dpi = 300)
def main(argv): """ ********* Main program ********* """ data1 = {} #dictionnary containing lifetimes for each cluster (file 1) data2 = {} #dictionnary containing lifetimes for each cluster (file 2) data3 = {} #dictionnary containing lifetimes for each cluster (file 3) cluster_lengths = { } #dictionnary containing length of cluster for each cluster of all files filename3 = '' atoms = 'all' letter = '' #other dictionnaries and parameters for the figure colors_T = { '2000': '#800080', '3000': '#297fff', '4000': '#00ff00', '5000': '#ffcd01', '6000': '#ff0101', '7000': '#ff01de' } plot_parameters = { "size_fonts": 12, "size_font_ticks": 10, "size_figure": (8, 4), "size_markers": 4, "size_lines": 1, "shift_labelpad": 20 } #other parameters Na = 6.022 * 10**23 try: options, arg = getopt.getopt(argv, "hf:g:j:a:v:m:l:", [ "file1", "gfile2", "jfile3", "atom", "variable", "mineralfile", 'letter' ]) except getopt.GetoptError: print( "plot_speciation-lifetime-comp.py -m <mineralfile with elements> -a <list of first atoms determining the type of cluster to plot (default = 'all')> -v <variable (rho,T)> -l <letter, default = ''> -f <small_popul.txt filename> -g <small_popul.txt filename n°2> -j <small_popul.txt filename n°3 (option)>" ) sys.exit() for opt, arg in options: if opt == '-h': print('') print( 'plot_speciation-lifetime-comp.py program to Plot lifetime barchart for 3 files (.txt files obtained from plot_speciation-lifetime.py) for selected clusters' ) print( "plot_speciation-lifetime-comp.py -m <mineralfile with elements> -a <list of first atoms determining the type of cluster to plot (default = 'all')> -v <variable (rho,T)> -l <letter, default = ''> -f <small_popul.txt filename> -g <small_popul.txt filename n°2> -j <small_popul.txt filename n°3 (option)> " ) print('') print( 'requires the file containing elements and number (in order to compute the densities)' ) print( 'requires the files .txt created with the plot_speciation_lifetime.py script' ) print('') sys.exit() elif opt in ("-f", "--file1"): filename1 = str(arg) elif opt in ("-g", "--gfile2"): filename2 = str(arg) elif opt in ("-j", "--jfile3"): filename3 = str(arg) elif opt in ("-a", "--atom"): atoms = arg.split(',') elif opt in ("-v", "--variable"): variable = str(arg) elif opt in ("-m", "--mineralfile"): mineralfile = str(arg) elif opt in ('-l', 'letter'): letter = str(arg) #***** Calculation of the molecular mass with open(mineralfile, 'r') as mf: entry = mf.readline() elements = entry.split()[1:] entry = mf.readline() number = entry.split()[1:] MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #***** Extraction of all cluster type from all files along with max size of data per cluster print("*********************** 1st step: extraction of data separately") with open(filename1, 'r') as f: print('********** for file', filename1) line = f.readline() #we read the first line with cluster sizes all_length = line.split('\n')[0].split('\t') line = f.readline() #we read the second line with cluster names clusters = line.split('\n')[0].split('\t') #print('clusters in file:',clusters) #we take all the clusters if atoms == 'all': print("I use all atomic clusters") for i in range(len(clusters)): data1[clusters[i]] = [] #initialization of data cluster_lengths[clusters[i]] = int(all_length[i]) else: #or we select only the cluster names we want print('I use only clusters starting by ', atoms) for atom in atoms: for i in range(len(clusters)): if clusters[i][:len(atom)] == atom: data1[clusters[i]] = [] #initialization of data cluster_lengths[clusters[i]] = int(all_length[i]) #print(data1) while True: line = f.readline( ) #we read all the other lines with lifetime for each apparition if not line: break else: entry = line.split('\n')[0].split('\t') for i in range( 0, len(clusters) ): #we store the correct lifetime in the dictionnary for the corresponding key if entry[i] != '': try: data1[clusters[i]].append(float(entry[i])) except KeyError: continue else: continue with open(filename2, 'r') as f: print('********** for file', filename2) line = f.readline() #we read the first line with cluster sizes all_length = line.split('\n')[0].split('\t') line = f.readline() #we read the second line with cluster names clusters = line.split('\n')[0].split('\t') #print('clusters in file:',clusters) #we take all the clusters if atoms == 'all': print("I use all atomic clusters") for i in range(len(clusters)): data2[clusters[i]] = [] #initialization of data cluster_lengths[clusters[i]] = int(all_length[i]) else: #or we select only the cluster names we want print('I use only clusters starting by ', atoms) for atom in atoms: for i in range(len(clusters)): if clusters[i][:len(atom)] == atom: data2[clusters[i]] = [] #initialization of data cluster_lengths[clusters[i]] = int(all_length[i]) #print(data1) while True: line = f.readline( ) #we read all the other lines with lifetime for each apparition if not line: break else: entry = line.split('\n')[0].split('\t') for i in range( 0, len(clusters) ): #we store the correct lifetime in the dictionnary for the corresponding key if entry[i] != '': try: data2[clusters[i]].append(float(entry[i])) except KeyError: continue else: continue if filename3 != '': with open(filename3, 'r') as f: print('********** for file', filename3) line = f.readline() #we read the first line with cluster sizes all_length = line.split('\n')[0].split('\t') line = f.readline() #we read the second line with cluster names clusters = line.split('\n')[0].split('\t') #print('clusters in file:',clusters) #we take all the clusters if atoms == 'all': print("I use all atomic clusters") for i in range(len(clusters)): data3[clusters[i]] = [] #initialization of data cluster_lengths[clusters[i]] = int(all_length[i]) else: #or we select only the cluster names we want print('I use only clusters starting by ', atoms) for atom in atoms: for i in range(len(clusters)): if clusters[i][:len(atom)] == atom: data3[clusters[i]] = [] #initialization of data cluster_lengths[clusters[i]] = int(all_length[i]) #print(data1) while True: line = f.readline( ) #we read all the other lines with lifetime for each apparition if not line: break else: entry = line.split('\n')[0].split('\t') for i in range( 0, len(clusters) ): #we store the correct lifetime in the dictionnary for the corresponding key if entry[i] != '': try: data3[clusters[i]].append(float(entry[i])) except KeyError: continue else: continue #creation of the list containing all the cluster once and only once clusters = [] [clusters.append(key) for key in data1] for key in data2: if key not in clusters: clusters.append(key) if filename3 != '': for key in data3: if key not in clusters: clusters.append(key) clusters.sort() print(clusters) print( "*********************** 2nd step: Addition of '0' data in order to have the same x axis " ) #*********creation of the dictionnaries containing: #-sizes of the data #-lists of labels (with the cluster name and then voids) #-data completed by voids labels = {} sizes = {} size3 = 0 for cluster in clusters: #***test to obtain the size of data list for current cluster try: size1 = len(data1[cluster]) #print("#1:",cluster,size1) except KeyError: size1 = 0 #print("#1:",cluster,size1) try: size2 = len(data2[cluster]) #print("#2:",cluster,size2) except KeyError: size2 = 0 #print("#2:",cluster,size2) if filename3 != '': try: size3 = len(data3[cluster]) #print("#2:",cluster,size2) except KeyError: size3 = 0 #the number we keep is the max of the three previous values sizes[cluster] = max(size1, size2, size3) #***now we can create the labels #either with simple method of 'label'+ voids labels[cluster] = [cluster] for i in range(sizes[cluster] - 1): labels[cluster].append('') #or by putting the label in the middle of the arrays #labels[cluster]=[] #if sizes[cluster] > 1: # if sizes[cluster] > 2: # for i in range(round(sizes[cluster]/2)-1): # labels[cluster].append('') # labels[cluster].append(cluster) # for i in range(round(sizes[cluster]/2)-1): # labels[cluster].append('') # else: # labels[cluster].extend([cluster,'']) #else: # labels[cluster]=[cluster] #***Now we add 'nan' to data array in order to have the same x axis try: if size1 < sizes[cluster]: for i in range(sizes[cluster] - size1 - 1): data1[cluster].append(float('nan')) data1[cluster].append(0) except KeyError: data1[cluster] = [] for i in range(sizes[cluster] - 1): data1[cluster].append(float('nan')) data1[cluster].append(0) try: if size2 < sizes[cluster]: for i in range(sizes[cluster] - size2 - 1): data2[cluster].append(float('nan')) data2[cluster].append(0) except KeyError: data2[cluster] = [] for i in range(sizes[cluster] - 1): data2[cluster].append(float('nan')) data2[cluster].append(0) if filename3 != '': try: if size3 < sizes[cluster]: for i in range(sizes[cluster] - size3 - 1): data3[cluster].append(float('nan')) data3[cluster].append(0) except KeyError: data3[cluster] = [] for i in range(sizes[cluster] - 1): data3[cluster].append(float('nan')) data3[cluster].append(0) #print(labels) #print("sizes of lists",sizes) print( "*********************** 3rd step: Creation of labels and arrays to plot" ) #creation of the big list of data (concatenation) and labels totdata1 = [] totdata2 = [] totdata3 = [] totlabels = [] #if we want to sort clusters by size and name sorted_cluster_lengths = [ (v[0], v[1]) for v in natsort.natsorted(cluster_lengths.items(), key=lambda kv: (kv[1], kv[0])) ] #[v[0] for v in sorted(d.items(), key=lambda kv: (-kv[1], kv[0]))] # natsort.natsorted(cluster_lengths.items(), key=lambda kv: kv[1]) print(sorted_cluster_lengths) for i in range(len(sorted_cluster_lengths)): cluster = sorted_cluster_lengths[i][0] totdata1.extend(data1[cluster]) totdata2.extend(data2[cluster]) if filename3 != '': totdata3.extend(data3[cluster]) totlabels.extend(labels[cluster]) #print(cluster, sizes[cluster]) #formatage of labels for j in range(len(totlabels)): if totlabels[j] != '': totlabels[j] = format1label(totlabels[j]) #print(totlabels) if (len(totdata1) == 0) and (len(totdata2) == 0) and (len(totdata3) == 0): print("There is nothing to plot for clusters of type ", atoms) sys.exit() #creation of x vector totsize = 0 for key in sizes: totsize = totsize + sizes[key] x = np.arange(totsize) #creation of custom labels temp1, acell1 = split_name(filename1) temp2, acell2 = split_name(filename2) if filename3 != '': temp3, acell3 = split_name(filename3) if variable == 'rho': var1 = 'a' + acell1 label1 = str(round(MN / (Na * float(acell1)**3 * 10**(-24)), 2)) + ' g.cm$^{-3}$' print(label1) var2 = 'a' + acell2 label2 = str(round(MN / (Na * float(acell2)**3 * 10**(-24)), 2)) + ' g.cm$^{-3}$' print(label2) if filename3 != '': var3 = 'a' + acell3 label3 = str(round(MN / (Na * float(acell3)**3 * 10**(-24)), 2)) + ' g.cm$^{-3}$' print(label3) fixedvar = temp1 title = filename1.split('_')[0] #formatage of the mineral name i = 0 while True: if i <= len(title) - 1: if re.match('[0-9]', title[i]): title = title[:i] + '$_{' + title[i] + '}$' + title[i + 1:] i = i + 5 i = i + 1 else: break title = title + ' at ' + fixedvar + ' K' else: var1 = temp1 + 'K' label1 = str(temp1) + ' K' var2 = temp2 + 'K' label2 = str(temp2) + ' K' if filename3 != '': var3 = temp3 + 'K' label3 = str(temp3) + ' K' fixedvar = str(round(MN / (Na * float(acell2)**3 * 10**(-24)), 2)) title = filename1.split('_')[0] #formatage of the mineral name i = 0 while True: if i <= len(title) - 1: if re.match('[0-9]', title[i]): num = 0 try: while re.match('[0-9]', title[i + num]): num += 1 except IndexError: #index error when we arrive at the end of the cluster name pass #print('end of the cluster') title = title[:i] + '$_{' + title[i:i + num] + '}$' + title[i + num:] i = i + 5 i = i + 1 else: break title = title + ' at ' + fixedvar + ' g.cm$^{-3}$' print( "*********************** 4th step: Plot everything on the same figure") #*********** Plot #Creation of the plot speciation_type = filename1.split('umd.dat.')[1].split('.popul.dat')[0] if speciation_type == 'r1': xlabel = 'Chemical species' else: xlabel = 'Coordinating polyhedra' fig, ax = creation_plot(xlabel) #if speciation_type == 'r0': #because of resolution problems (too many bars so they are too thin to appear) we should use a line plot filled for r0 # print("speciation 0") # plt.fill_between(x,totdata1, y2 =0, color=colors_T[temp1], alpha = 1, label=label1) # plt.fill_between(x,totdata2, y2 =0, color=colors_T[temp2], alpha = 0.5, label=label2) # if filename3 != '': # plt.fill_between(x,totdata3, y2=0, color=colors_T[temp3], alpha = 0.35, label=label3) #else: #but for r1 we keep the standard bar plot (less bars to plot) # print("speciation 1") # plt.bar(x,totdata1, width = 1, color=colors_T[temp1], alpha = 1, label=label1) # plt.bar(x,totdata2, width = 1, color=colors_T[temp2], alpha = 0.5, label=label2) # if filename3 != '': # plt.bar(x,totdata3, width = 1, color=colors_T[temp3], alpha = 0.35, label=label3) plt.plot(x, totdata1, '-', color=colors_T[temp1], label=label1) plt.plot(x, totdata2, '-', color=colors_T[temp2], label=label2) if filename3 != '': plt.plot(x, totdata3, '-', color=colors_T[temp3], label=label3) plt.xticks(x, totlabels, rotation=45, fontsize=10) ax.yaxis.set_ticks_position('both') if letter != '': ax.text(0.007, 0.94, letter, transform=ax.transAxes, horizontalalignment='left', fontweight='bold', fontsize=plot_parameters["size_fonts"], bbox=dict(facecolor='none', edgecolor='k', pad=3.0)) #plt.title(title, fontsize = 12, fontweight = 'bold') #plt.legend(loc='upper right', fontsize = 12) #save plot if filename3 != '': figurename = 'comparison_lifetime_' + filename1.split('/')[-1].split( '_' )[0] + '_' + speciation_type + '_' + fixedvar + '_' + var1 + '-' + var2 + '-' + var3 else: figurename = 'comparison_lifetime_' + filename1.split('/')[-1].split( '_' )[0] + '_' + speciation_type + '_' + fixedvar + '_' + var1 + '-' + var2 figurename = figurename + '.svg' plt.savefig(figurename, bbox_inches='tight', dpi=300) print(figurename, 'is created')
def main(argv): """ ********* Main program ********* """ files = [] data = {} #dictionnary containing lifetimes for each cluster cluster_lengths = {}#dictionnary containing length of cluster for each cluster sizes = {} labels = {} note = {} #dictionnary to add a note on the figure in case of max lifetime = simulation time #other dictionnaries and parameters for the figure colors_T = {'2000':'#800080','3000':'#297fff','4000':'#00ff00','4500':'#bae200','5000':'#ffcd01','6000':'#ff0101','6500':'#ff00a2','7000':'#ff01de'} atoms = 'all' atomslist = 'all' letters = ['a','b','c','d','e','f','g','h','i'] #other parameters Na=6.022*10**23 try: options,arg = getopt.getopt(argv,"hm:a:f:l:",["mineralfile","atom","filename","lifetime"]) # options,arg = getopt.getopt(argv,"hc:m:a:r:l:",["cell","mineralfile",'atoms','rspeciation',"length"]) except getopt.GetoptError: print("plot_speciation-lifetime-comp-allT.py -m <mineralfile with elements> -a <list of first atom determining the type of cluster to plot (default = 'all')> -f <one filename of the same format name than all we want to plot> -l <list of max lifetime of all the simu> ") # print("plot_speciation-lifetime-comp-allT.py -m <mineralfile with elements> -a <list of first atom determining the type of cluster to plot (default = 'all')> -c <cell we want to plot> -r <speciation type (0 or 1)> -l <max length of clusters> ") sys.exit() for opt,arg in options: if opt == '-h': print('') print('plot_speciation-lifetime-comp-allT.py program to Plot lifetime barchart for all temperatures at a selected acell for some cluster, one figure per file') print("plot_speciation-lifetime-comp-allT.py -m <mineralfile with elements> -a <list of first atom determining the type of cluster to plot (default = 'all')> -f <one filename of the same format name than all we want to plot> -l <list of max lifetime of all the simu> ") # print("plot_speciation-lifetime-comp-allT.py -m <mineralfile with elements> -a <list of first atom determining the type of cluster to plot (default = 'all')> -c <cell we want to plot> -r <speciation type (0 or 1)> -l <max length of clusters> ") print("") print('requires the file containing elements and number (in order to compute the densities)') print('requires to launch the script from the directory containing all the files .txt created with the plot_speciation_lifetime.py script') print('') sys.exit() # elif opt in ("-c", "--cell"): # cell = str(arg) elif opt in ("-m","--mineralfile"): mineralfile = str(arg) elif opt in ("-a","--atoms"): atomslist = str(arg) atoms = arg.split(',') #list of atom couples we want to analyze here elif opt in ("-f","--filename"): firstfilename = str(arg) elif opt in ("-l","--lifetime"): max_lifetimes = list(map(int,arg.split(','))) # elif opt in ("-r","--rspeciation"): # speciation = str(arg) # elif opt in ("-l","--length"): # length = str(arg) #***** Calculation of the molecular mass with open(mineralfile,'r') as mf: entry = mf.readline() elements = entry.split()[1:] entry = mf.readline() number = entry.split()[1:] MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #***** List of all the files concerned by the T and acell cell = firstfilename.split('.outcar.umd.dat')[0].split('_')[3].strip('a') speciation = firstfilename.split('.outcar.umd.dat.r')[-1].split('.popul.dat')[0] length = firstfilename.split('.popul.dat_L')[-1].split('.txt')[0] filename = '*_a'+cell+'*outcar.umd.dat.r'+speciation+'.popul.dat_L'+length+'*.txt' print('I search for files of type', filename) allfiles = sorted(glob.glob(filename)) #I list every population file created by plot_speciation-lifetime.py in alphabetic order #print(files) print('I use the corresponding limit lifetimes', max_lifetimes) #we remove the empty files (the ones created by hand) from the file list for file in allfiles: if os.stat(file).st_size != 0: files.append(file) #***** Extraction of all cluster type from all files along with max size of data per cluster print("*********************** 1st step: calculation of total number of bars in order to have the same x axis") for file in files: print('********** for file',file) with open(file,'r') as f: line = f.readline() #we read the first line with cluster sizes all_length = line.split('\n')[0].split('\t') print(all_length) line = f.readline() #we read the second line with cluster names clusters=line.split('\n')[0].split('\t') print('clusters in file:',clusters) #we take all the clusters if atoms == 'all': print("I use all atomic clusters") for i in range(len(clusters)): data[clusters[i]] = [] #initialization of data cluster_lengths[clusters[i]] = all_length[i] else: #or we select only the cluster names we want print('I use only clusters starting by ', atoms) for atom in atoms: for i in range(len(clusters)): if clusters[i][:len(atom)] == atom: print(clusters[i]) data[clusters[i]] = [] #initialization of data cluster_lengths[clusters[i]] = all_length[i] #extraction of data, all in the same data dictionnary in order to know the total (cumulative) number of bars in the bar plot while True: line = f.readline() #we read all the other lines with lifetime for each apparition if not line: break else: entry=line.split('\n')[0].split('\t') for i in range(0,len(clusters)): #we store the correct lifetime in the dictionnary for the corresponding key if entry[i] != '': try: data[clusters[i]].append(float(entry[i])) except KeyError: continue else: continue #print('data',data) #test to find the maximum value for data sizes (for each cluster) if atoms == 'all': for cluster in clusters: try: if len(data[cluster]) > sizes[cluster]: sizes[cluster] = len(data[cluster]) except KeyError: sizes[cluster] = len(data[cluster]) else: for atom in atoms: for cluster in clusters: if cluster[:len(atom)] == atom: try: if len(data[cluster]) > sizes[cluster]: sizes[cluster] = len(data[cluster]) except KeyError: sizes[cluster] = len(data[cluster]) #print("sizes",sizes) #************ Extraction of the data and determination of the max of all figures (to keep the y axis identical) print("*********************** 2nd step: Extraction of data per file and deterination of ymax for all fig") ymax = 0 for file in files: print('********** for file',file) letter = letters[allfiles.index(file)] print('letter is', letter) data = {} #initialization of data with open(file,'r') as f: line = f.readline() #we read the first line with cluster sizes line = f.readline() #we read the second line with cluster names clusters=line.split('\n')[0].split('\t') #print('clusters in file:',clusters) #we take all the clusters if atoms == 'all': for i in range(len(clusters)): data[clusters[i]] = [] #initialization of data else: #or we select only the cluster names we want for atom in atoms: for i in range(len(clusters)): if clusters[i][:len(atom)] == atom: data[clusters[i]] = [] #initialization of data #extraction of data while True: line = f.readline() #we read all the other lines with lifetime for each apparition if not line: break else: entry=line.split('\n')[0].split('\t') for i in range(0,len(clusters)): #we store the correct lifetime in the dictionnary for the corresponding key if entry[i] != '': try: data[clusters[i]].append(float(entry[i])) except KeyError: continue else: continue #we complete the data lists with nan in order to have the same x axis for cluster in sizes: try: if len(data[cluster]) < sizes[cluster]: for i in range(sizes[cluster]-len(data[cluster])): data[cluster].append(float('nan')) except KeyError: data[cluster] = [] for i in range(sizes[cluster]): data[cluster].append(float('nan')) #********* Creation of the dictionnary containing the lists of labels (with the cluster name and then voids) for cluster in sizes: print('cluster',cluster) print(data[cluster]) if str(data[cluster][0]) != 'nan': #we replace labels by voids when the specie is not there labels[cluster]=[cluster] for i in range(sizes[cluster]-1): labels[cluster].append('') else: labels[cluster]=[''] for i in range(sizes[cluster]-1): labels[cluster].append('') #********* Creation of the big list of data (concatenation) and labels sorted by length of clusters totdata = [] totlabels = [] sorted_cluster_lengths = natsort.natsorted(cluster_lengths.items(), key=lambda kv: kv[1]) print(sorted_cluster_lengths) for i in range(len(sorted_cluster_lengths)): cluster = sorted_cluster_lengths[i][0] totdata.extend(data[cluster]) totlabels.extend(labels[cluster]) print('maximum of data',np.nanmax(totdata)) if np.nanmax(totdata) < max_lifetimes[files.index(file)] : if np.nanmax(totdata) > ymax: ymax = np.nanmax(totdata) note[file] = '' else: note[file] = 'maximum lifetime \n = simulation time' print("*********************************** ymax =",ymax) #************ Same as before with plot, each on a different figure (one fig per T) print("*********************** 3rd step: Extraction of data per file and plot each graph on a different figure") for file in files: print('********** for file',file) letter = letters[allfiles.index(file)] print('letter is', letter) data = {} #initialization of data with open(file,'r') as f: line = f.readline() #we read the first line with cluster sizes line = f.readline() #we read the second line with cluster names clusters=line.split('\n')[0].split('\t') #print('clusters in file:',clusters) #we take all the clusters if atoms == 'all': for i in range(len(clusters)): data[clusters[i]] = [] #initialization of data else: #or we select only the cluster names we want for atom in atoms: for i in range(len(clusters)): if clusters[i][:len(atom)] == atom: data[clusters[i]] = [] #initialization of data #extraction of data while True: line = f.readline() #we read all the other lines with lifetime for each apparition if not line: break else: entry=line.split('\n')[0].split('\t') for i in range(0,len(clusters)): #we store the correct lifetime in the dictionnary for the corresponding key if entry[i] != '': try: data[clusters[i]].append(float(entry[i])) except KeyError: continue else: continue #we complete the data lists with nan in order to have the same x axis for cluster in sizes: try: if len(data[cluster]) < sizes[cluster]: for i in range(sizes[cluster]-len(data[cluster])): data[cluster].append(float('nan')) except KeyError: data[cluster] = [] for i in range(sizes[cluster]): data[cluster].append(float('nan')) #********* Creation of the dictionnary containing the lists of labels (with the cluster name and then voids) for cluster in sizes: if str(data[cluster][0]) != 'nan': #we replace labels by voids when the specie is not there labels[cluster]=[cluster] for i in range(sizes[cluster]-1): labels[cluster].append('') else: labels[cluster]=[''] for i in range(sizes[cluster]-1): labels[cluster].append('') #********* Creation of the big list of data (concatenation) and labels sorted by length of clusters totdata = [] totlabels = [] sorted_cluster_lengths = natsort.natsorted(cluster_lengths.items(), key=lambda kv: kv[1]) print(sorted_cluster_lengths) for i in range(len(sorted_cluster_lengths)): cluster = sorted_cluster_lengths[i][0] totdata.extend(data[cluster]) totlabels.extend(labels[cluster]) #formatage of labels for j in range(len(totlabels)): if totlabels[j] != '': i=0 while True: #print('i=',i, 'len totlabels -1 = ',len(totlabels[j])-1 ) if i <= len(totlabels[j])-1: #print('totlabels j i = ', totlabels[j][i]) if re.match('_',totlabels[j][i]): num=0 try: while re.match('[0-9]',totlabels[j][i+1+num]): num +=1 except IndexError: #index error when we arrive at the end of the cluster name pass #print('end of the cluster') totlabels[j] = totlabels[j][:i]+'$_{'+totlabels[j][i+1:i+1+num]+'}$' + totlabels[j][i+1+num:] #print('new totlabels j =',totlabels[j]) i = i+5 i = i+1 else:break #print(totlabels) #*********** Plot #Creation of the plot fig, ax = creation_plot(speciation) if (len(totdata) == 0) : print("There is nothing to plot for clusters of type ",atoms, 'in file ', file ) #save empty plot empty_plot(fig, ax, file, ymax, letter, colors_T, speciation, length, atomslist) continue #creation of x vector totsize = 0 for key in sizes: totsize = totsize + sizes[key] x = np.arange(totsize) print('len of x= ', len(x)) #creation of custom labels temp, acell = split_name(file) label= str(temp)+' K' fixedvar = str(round(MN/(Na*float(acell)**3*10**(-24)),2)) title = file.split('_')[0] #formatage of the mineral name i=0 while True: if i <= len(title)-1: if re.match('[0-9]',title[i]): num=0 try: while re.match('[0-9]',title[i+num]): num +=1 except IndexError: #index error when we arrive at the end of the cluster name pass #print('end of the cluster') title = title[:i]+'$_{'+title[i:i+num]+'}$' + title[i+num:] i = i+5 i = i+1 else:break title = title+' at '+fixedvar+' g.cm$^{-3}$' if speciation == '0' or len(x)>1000: #because of resolution problems (too many bars so they are too thin to appear) we should use a line plot filled for r0 plt.fill_between(x,totdata, y2 =0, color=colors_T[temp], alpha = 1, label=label) else: #but for r1 we keep the standard bar plot (less bars to plot) plt.bar(x,totdata, width = 1, color=colors_T[temp], alpha = 1, label=label) plt.xticks(x, totlabels, rotation = 45, fontsize = 10) width=20 ax.set_xlim(-width,len(x)+width) ax.set_ylim(0,ymax) ax.yaxis.set_ticks_position('both') #plt.title(title, fontsize = 12, fontweight = 'bold') plt.text(0.01,0.95, letter , transform=ax.transAxes, horizontalalignment = 'left', fontweight = 'bold', fontsize = 12, bbox=dict(facecolor='none', edgecolor='k', pad=3.0)) plt.legend(loc='upper right', fontsize = 12) plt.subplots_adjust(top = 0.97, bottom = 0.26, right = 0.94, left = 0.12, hspace = 0, wspace = 0) #addition of the note if it exists if note[file] != '': plt.text(0.7,0.7, note[file] , transform=ax.transAxes, horizontalalignment = 'left', fontsize = 12) #save plot figurename = 'lifetime_allT_'+file.split('.outcar.umd.dat')[0]+'_r'+speciation+'_L'+length+'_'+atomslist+'.png' plt.savefig(figurename, dpi=150)#, bbox_inches='tight') #remove 'tight' to take into account options of subplots_adjust print(figurename, 'is created') #plt.show() #For files that does not exist and for which we created a corresponding empty file, we create an empty figure and remove them of the list of files for file in allfiles: if os.stat(file).st_size == 0: letter = letters[allfiles.index(file)] fig, ax = creation_plot(speciation) empty_plot(fig, ax, file, ymax, letter, colors_T, speciation, length, atomslist)
def main(argv): """ ********* Main program ********* """ xdata = {'T': [], 'rho': [], 'P': []} #dictionnary containing the x data data = [] #list containing y data xdata2 = {'T': [], 'rho': [], 'P': []} #dictionnary containing the x data data2 = [] #list containing y data TP = {} #dictionnary with P and T in each simufile colors_species = {} #other dictionnaries and parameters for the figure for article version #plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (8,4),"size_markers" : 4,"size_lines" : 1,"shift_labelpad" : 20} plot_parameters = { "size_fonts": 16, "size_font_ticks": 14, "size_figure": (12, 7), "size_markers": 10, "size_lines": 2, "shift_labelpad": 10 } #dictionnary for fullaverages file in full version column_number = { 'rho': 2, 'P': 5, 'stdev_P': 6, 'err_P': 7, 'T': 8, 'stdev_T': 9, 'err_T': 10, 'E': 14, 'stdev_E': 15, 'err_E': 16, 'Cvm_Nkb': 23, 'stdev_Cvm_Nkb': 24, 'Cvm': 25, 'stdev_Cvm': 26, 'testCv': 31, 'stdev_testCv': 32 } #other parameters Na = 6.022 * 10**23 statfile2 = '' try: options, arg = getopt.getopt( argv, "hf:g:a:v:m:", ["file1", "gfile2", "atom", "variable", "mineralfile"]) except getopt.GetoptError: print( "plot_speciation-r0.py -a <first atom determining the type of cluster to plot> -v <variable (rho,P,T)> -m <mineralfile with elements> -f <stat-concentrate_r0_perc_filename> -g <stat-concentrate_perc_filename n°2 (option)> " ) sys.exit() for opt, arg in options: if opt == '-h': print('') print( 'plot_speciation-r0.py program to Plot abundance of coordinations for selected cation as a function of rho,P or T' ) print( "plot_speciation-r0.py -a <first atom determining the type of cluster to plot> -v <variable (rho,P,T)> -m <mineralfile with elements> -f <stat-concentrate_r0_perc_filename> -g <stat-concentrate_perc_filename n°2 (option)> " ) print( 'requires the file containing elements and number (in order to compute the densities)' ) print('') print( 'For plots as function of P, make sure the files from fullaverages.py are in the current folder' ) sys.exit() elif opt in ("-f", "--file1"): statfile = str(arg) elif opt in ("-g", "--gfile2"): statfile2 = str(arg) elif opt in ("-a", "--atom"): atom = str(arg) elif opt in ("-v", "--variable"): variable = str(arg) elif opt in ("-m", "--mineralfile"): mineralfile = str(arg) #***** Calculation of the molecular mass with open(mineralfile, 'r') as mf: entry = mf.readline() elements = entry.split()[1:] entry = mf.readline() number = entry.split()[1:] MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #***** Creation of the plot if statfile2 != '': with open(statfile, 'r') as f: line = f.readline() file1 = line.split()[1] with open(statfile2, 'r') as f2: line = f2.readline() file2 = line.split()[1] fig, ax, ax2 = creation_plot2(variable, file1, file2, MN, plot_parameters) axrange = ax.get_xlim() ax2range = ax2.get_xlim() else: fig, ax = creation_plot(variable, plot_parameters) axrange = ax.get_xlim() #***** Count of the number of clusters for the selected atom type (needed for the automatic color change) #first store every cluster type into the dictionary with open(statfile, 'r') as f: while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t') if len(entry) > 1: if entry[0][:len(atom)] == atom: colors_species[entry[0]] = [] mineralname = statfile.split('/')[-1].split('_')[0] #then, in case of a second file, we check if there is additional cluster and add them to the dictionary if applicable if statfile2 != '': with open(statfile2, 'r') as f2: while True: line = f2.readline() if not line: break else: entry = line.split('\n')[0].split('\t') if len(entry) > 1: if entry[0][:len(atom)] == atom: if not entry[0] in colors_species: colors_species[entry[0]] = [] name = 'batlow' #'lajolla' #'imola' if 'Al_1O' in atom or 'Si_1O' in atom: #Creation of the color list for 11 coordination list_species = [] cm_data = np.loadtxt( "/Users/akobsch/Dropbox/Recherche/PhD-MD-silicates/simulations/scripts/Analysis/ScientificColourMaps6/" + name + "/" + name + ".txt") #cm_data = cm_data[::-1] #for reverse colors (lajolla) new_map = LinearSegmentedColormap.from_list( 'new', cm_data) #[:-20]) #no cut for imola color = iter(new_map(np.linspace(0, 1, 11))) #Creation of the color list #color = iter(plt.cm.jet(np.linspace(0,1,11))) for i in range(1, 12, 1): c = next(color) curr_species = atom + '_' + str(i) if curr_species in colors_species: colors_species[curr_species] = c list_species.append(curr_species) print(list_species, len(list_species)) else: #Creation of the color list for 19 coordination list_species = [] cm_data = np.loadtxt( "/Users/akobsch/Dropbox/Recherche/PhD-MD-silicates/simulations/scripts/Analysis/ScientificColourMaps6/" + name + "/" + name + ".txt") #cm_data = cm_data[::-1] #for reverse colors new_map = LinearSegmentedColormap.from_list('new', cm_data) color = iter(new_map(np.linspace(0, 1, 19))) #Creation of the color list #color = iter(plt.cm.jet(np.linspace(0,1,19))) for i in range(1, 20, 1): c = next(color) curr_species = atom + '_' + str(i) if curr_species in colors_species: colors_species[curr_species] = c list_species.append(curr_species) print(list_species, len(list_species)) #***************************** #******************* #******* # Extraction of P and T for each simufile of each thermo file thermofiles = sorted(glob.glob('thermo_' + mineralname + '*.txt')) for file in thermofiles: TP = extract_TP(file, column_number, TP, '') #***************************** #******************* #******* #Read & plot for the first file #read the file1 with open(statfile, 'r') as f: line = f.readline() entry = line.split() files = entry[1:] #creation of the x data list for file in files: temperature, acell = split_name(file) xdata['rho'].append( MN / (Na * float(acell)**3 * 10**(-24))) #calculation density xdata['T'].append(int(temperature)) xdata['P'].append(TP[file.split('/')[-1]][1]) #print(file.split('/')[-1],MN/(Na*float(acell)**3*10**(-24)),int(temperature),TP[file.split('/')[-1]][1]) with open(statfile, 'r') as f: #creation of the y data list and plot for each cluster while True: line = f.readline() if not line: break else: entry = line.split('\n')[0].split('\t') if len(entry) > 1: if entry[0][:len(atom)] == atom: for i in range( 1, len(entry)): #we loop over all the files if entry[i] == '': entry[i] = 0 data.append(float(entry[i])) #now the data array is filled, we plot the line for this species x, y = zip(*sorted(zip(xdata[variable], data))) line, = ax.plot( x, y, '.--', color=colors_species[entry[0]], markersize=plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"]) #if variable == 'T': # label_line(ax, line, entry[0], halign='right') #elif list_species.index(entry[0]) < int(len(list_species)/2): # label_line(ax, line, entry[0], halign='left') #else: # label_line(ax, line, entry[0], halign='right') #and we plot the name of the species near the max of the curve if max(data) > 0.05: x_max = xdata[variable][data.index(max(data))] if x_max > axrange[0] and x_max < axrange[1]: y_max = max(data) label = entry[0] #**** formatage of label with removing _1 label = format1label(label) ax.text(x_max, y_max, label, color='0.35', fontsize=plot_parameters['size_fonts']) data = [ ] #reinitialization of data array for the next species figurename = statfile.split( '.dat')[0] + '_' + atom + '-clusters_' + variable #***************************** #******************* #******* #Same as before but for the second file if it exists if statfile2 != '': with open(statfile2, 'r') as f2: line = f2.readline() entry = line.split() files = entry[1:] #creation of the x data list for file in files: temperature, acell = split_name(file) xdata2['rho'].append( MN / (Na * float(acell)**3 * 10**(-24))) #calculation density xdata2['T'].append(int(temperature)) xdata2['P'].append(TP[file.split('/')[-1]][1]) with open(statfile2, 'r') as f2: #creation of the y data list and plot for each cluster while True: line = f2.readline() if not line: break else: entry = line.split('\n')[0].split('\t') if len(entry) > 1: if entry[0][:len(atom)] == atom: for i in range( 1, len(entry)): #we loop over all the files if entry[i] == '': entry[i] = 0 data2.append(float(entry[i])) #now the data array is filled, we plot the line for this species x2, y2 = zip(*sorted(zip(xdata2[variable], data2))) line, = ax2.plot( x2, y2, '.--', color=colors_species[entry[0]], markersize=plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"]) #if variable == 'T': # label_line(ax2, line, entry[0], halign='right') #elif list_species.index(entry[0]) < int(len(list_species)/2): # label_line(ax2, line, entry[0], halign='left') #else: # label_line(ax2, line, entry[0], halign='right') #and we plot the name of the species near the max of the curve if max(data2) > 0.05: x2_max = xdata2[variable][data2.index( max(data2))] if x2_max > ax2range[0] and x2_max < ax2range[ 1]: y2_max = max(data2) label2 = entry[0] #**** formatage of label with removing _1 label2 = format1label(label2) ax2.text( x2_max, y2_max, label2, color='0.35', fontsize=plot_parameters['size_fonts']) data2 = [ ] #reinitialization of data array for the next species figurename = statfile.split('/')[-1].split( '.dat')[0] + '+' + statfile2.split('/')[-1].split( '.dat')[0] + '_' + atom + '-clusters_' + variable #********* Legend #* formatage of label with removing _1 for j in range(len(list_species)): if list_species[j] != '': list_species[j] = format1label(list_species[j]) custom_lines = [ Line2D([0], [0], color=colors_species[key], ls='--', marker='.', markersize=plot_parameters["size_markers"], linewidth=plot_parameters["size_lines"]) for key in natsort.natsorted(colors_species) ] legend = plt.legend([line for line in custom_lines], [label for label in natsort.natsorted(list_species)], title='$\\bf{Polyhedra}$', bbox_to_anchor=(1.05, 1), loc=2, fontsize=plot_parameters["size_fonts"], borderaxespad=0.) plt.setp(legend.get_title(), fontsize=plot_parameters["size_fonts"]) figurename = figurename + '.pdf' print(figurename, 'is created') plt.savefig(figurename, bbox_inches='tight', dpi=150)
def main(argv): """ ********* Main program ********* """ thermofile = '' #file for thermo values ground_state_file = '' #file for ground_state #extracted and created data dictionnaries rho = {} E = {} P = {} stdev_P = {} ground_state = {} hugoniot = {} #impact values impactor_velocities = [12.9, 15.2, 18.1, 8.3, 11.5, 15.2] #in km/s, see bibliography excel file impactor_density = 3000 #kg/m3 #figure dictionnary colors_T = { 'T2': '#800080', 'T3': '#297fff', 'T4': '#00ff00', 'T4.5': '#bae200', 'T5': '#ffcd01', 'T5.5': '#ff6e00', 'T6': '#ff0101', 'T6.5': '#ff00a2', 'T7': '#ff01de', 'T7.5': '#ffa6f4', 'T10': '#ffe86e', 'T15': '#ffbf90', 'T20': '#ff7788' } #other parameters Na = 6.022 * 10**23 eVtoJ = 1.6e-19 #1eV = 1.6e-19 J kb = 1.38064852e-23 #boltzmann constant try: options, arg = getopt.getopt(argv, "hf:g:t:", ["filename", "groundstate"]) except getopt.GetoptError: print( "analyze_Hugoniot.py -f <thermo_filename (from analyze fullaverage)> -t <type of the file: 'short' or 'all'> -g <ground-state_filename>" ) sys.exit() for opt, arg in options: if opt == '-h': print('') print( 'analyze_Hugoniot.py program to find the Hugoniot point from a thermo file and the ground state file associated' ) print( "analyze_Hugoniot.py -f <thermo_filename (from analyze fullaverage)> -t <type of the file: 'short' or 'all'> -g <ground-state_filename>" ) print('') print( 'requires the .txt file with ground states condition: two lines of header, a first column containing the density in kg/m3, a second column with the specific energy in J/kg, a third column with the pressure in Pa and a last column with the temperature in K' ) print('') sys.exit() elif opt in ("-g", "--groundstate"): ground_state_file = str(arg) elif opt in ('-f', '--filename'): thermofile = str(arg) elif opt in ('-t', '--type'): filetype = str(arg) #selection of the column depending on the type of the thermo file if filetype == 'all': column_number = {'rho': 2, 'P': 5, 'T': 8, 'E': 14} else: column_number = {'rho': 2, 'P': 5, 'T': 8, 'E': 11} #************ Extraction of elements info and ground state data #**creation of elements and number lists and initialization of T with open(thermofile, 'r') as f: line = f.readline() print(line) entry = line.split() elements = entry[1:] line = f.readline() entry = line.split() number = entry[1:] f.readline() line = f.readline() entry = line.split() temperature0, acell0 = split_name(entry[0]) #**calculation of M*N (in kg.part/mol) nedded for the calculation of densities and mass MN = 0 ntot = 0 for i in range(len(elements)): ntot = ntot + float(number[i]) MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] * 1E-3 #extraction of ground-state data into a dictionnary with open(ground_state_file, 'r') as g: line = g.readline() line = g.readline() while True: line = g.readline() if not line: break else: entry = line.split() ground_state[int(entry[0])] = ( float(entry[1]), float(entry[2]), round(float(entry[3])) ) #key = density value in kg/m3, value = (energy/mass of the cell,pressure, temperature) hugoniot[int(entry[0])] = { } #nested dictionnary of hugoniot equation for each T and each value of rho for ground state #************ Extraction of P-rho-E data with open(thermofile, 'r') as f: [f.readline() for i in range(3)] while True: line = f.readline() if not line: break else: entry = line.split() temperature, acell = split_name(entry[0]) if acell <= '15.0': try: rho[temperature].append( float(entry[column_number['rho']]) * 1000) #calculation density in kg/m3 E[temperature].append(float( entry[column_number['E']])) #in eV/atom P[temperature].append(float( entry[column_number['P']])) #in GPa stdev_P[temperature].append( convert_to_float(entry[column_number['P'] + 2])) #in GPa except KeyError: rho[temperature] = [ float(entry[column_number['rho']]) * 1000 ] #calculation density in kg/m3 E[temperature] = [float(entry[column_number['E']]) ] #in eV/atom P[temperature] = [float(entry[column_number['P']]) ] #in GPa stdev_P[temperature] = [ convert_to_float(entry[column_number['P'] + 2]) ] #in GPa print("******") print("*********") print("************") print("****************") #*********** For each ground state we create the file with Hugoniot point and we fill it with data for density_gs in sorted(ground_state): print("******************************* For reference density", density_gs, 'kg/m3 and reference temperature', ground_state[density_gs][2], ' K') #creation of the file with hugoniot values and BM3 fit parameters nf = Hugoniot(thermofile, ground_state, density_gs, impactor_velocities, impactor_density) #creation of the figure to see the BM3 fit fig, ax = creation_plot(thermofile) #for each T, calculation of Hugoniot values for temperature in natsort.natsorted(rho): print("************** For ", temperature) if temperature == 'T1.932' or temperature == 'T4.5' or temperature == 'T5.5' or temperature == 'T6.5' or temperature == 'T2' or temperature == 'T7': print("we skip this T") continue else: #calculation of Hugoniot density string = str(int(float(temperature.strip('T')) * 1000)) hugoniot[temperature] = [] previous_len = len(string) #we fill this array with data of the hugoniot equation for i in range(len(rho[temperature])): Hg = E[temperature][ i] * eVtoJ * Na * ntot / MN - ground_state[density_gs][ 0] + 0.5 * (P[temperature][i] * 1E9 + ground_state[density_gs][1]) * ( 1 / rho[temperature][i] - 1 / density_gs) hugoniot[temperature].append(Hg) print(i, int(round(rho[temperature][i], 0)), Hg, i - 1, int(round(rho[temperature][i - 1], 0)), hugoniot[temperature][i - 1]) #and we compute the value of the rho for which Hg = 0 if np.sign(Hg) != np.sign(hugoniot[temperature][i - 1]): #print('change of sign --> we use the straight line between these 2 points to find the rho for which Hg = 0') #print('the equation of such a line is Hg = (Hg[i]-Hg[i-1])/(rho[i]-rho[i-1]) * rho + Hg[i] - (Hg[i]-Hg[i-1])/(rho[i]-rho[i-1]) * rho[i]') #print('Hg = 0 for rho = rho[i] - Hg[i]/( (Hg[i]-Hg[i-1])/(rho[i]-rho[i-1]) ) ') rho0 = rho[temperature][i] - hugoniot[temperature][i] / ( (hugoniot[temperature][i] - hugoniot[temperature][i - 1]) / (rho[temperature][i] - rho[temperature][i - 1])) print('change of sign --> rho0 =', rho0) #******We fit a BM3 to this isotherm in order to find the correct pressure corresponding to the Hugoniot density if len(rho[temperature]) >= 4: #Fit of the equation and calculation of the corresponding chi2 m0 = { 'T3': [2600, 15, 4], 'T4': [2600, 15, 4], 'T5': [2600, 15, 4], 'T6': [2600, 15, 4], 'T10': [2600, 15, 4], 'T15': [2600, 15, 4], 'T20': [2600, 15, 4] } #rho0 in kg/m3, K0 in GPa, Kp0 drho = 0.1 try: #odr fit eos_model_BM3 = odr.Model( BM3_P_rho) # model for fitting stdev_rho = [ i / 1000 for i in rho[temperature] ] #creation of stdev for rho data_for_ODR = odr.RealData( rho[temperature], P[temperature], stdev_rho, stdev_P[temperature] ) # RealData object using our data odr_process = odr.ODR( data_for_ODR, eos_model_BM3, beta0=m0[temperature], maxit=10000 ) # Set up orth-dist-reg with the model and data odr_results = odr_process.run( ) # run the regression print('***************', temperature, "Fit of BM3") odr_results.pprint( ) # use the pprint method to display results DensityX = np.arange( rho[temperature][-1] - drho, rho[temperature][0] + drho, drho) ax.plot(DensityX, BM3_P_rho(odr_results.beta, DensityX), '-', color=colors_T[temperature], label=temperature + ' BM3 fit') ax.plot(rho[temperature], P[temperature], 'o', color=colors_T[temperature], label=temperature + ' data') #print(str(temperature) + '\t' + str('{:1.2e}'.format(odr_results.res_var)) + '\t' + str('{:1.2e}'.format(odr_results.beta[0])) + '\t' + str('{:1.2e}'.format(odr_results.beta[1])) + '\t' + str('{:1.2e}'.format(odr_results.beta[2])) + '\t' + str('{:1.2e}'.format(odr_results.sd_beta[0])) + '\t' + str('{:1.2e}'.format(odr_results.sd_beta[1])) + '\t' + str('{:1.2e}'.format(odr_results.sd_beta[2])) + '\n') chi2 = chi2red(odr_results.beta, rho[temperature], P[temperature], stdev_P[temperature]) #print('residual variance',odr_results.res_var) P0 = fonction_BM3(rho0, odr_results.beta[0], odr_results.beta[1], odr_results.beta[2]) string = string + '\t' + str( round(rho0) ) + '\t' + str(round(P0, 2)) + '\t' + str( round(odr_results.beta[0])) + '\t' + str( round(odr_results.beta[1], 2) ) + '\t' + str( round(odr_results.beta[2], 2)) + '\t' + str(round(chi2, 2)) #This is the theoretical model (initial guesses), based on common values # m0=np.array([2600, 19, 6]) #rho0 in kg/m3, K0 in GPa, Kp0 # try: # m, pcov = curve_fit(fonction_BM3, rho[temperature], P[temperature], p0=m0, sigma=stdev_P[temperature], absolute_sigma=False ) # chi2 = chi2red(m,rho[temperature],P[temperature],stdev_P[temperature]) # DensityX=np.arange(3200,6300,10) # ax.plot(DensityX,fonction_BM3(DensityX,m[0],m[1],m[2]),'-', color=colors_T[temperature], label= temperature + ' BM3 fit') # ax.plot(rho[temperature],P[temperature],'o', color=colors_T[temperature], label= temperature + ' data') # print("Least-square fit of BM3") #print('T, Chi2red, rho0(kg/m3), K0(GPa), Kp0(no-units)') #print(temperature,chi2,m[0],m[1],m[2]) # P0 = fonction_BM3(rho0,m[0],m[1],m[2]) # string = string + '\t' + str(round(rho0)) + '\t' + str(round(P0,2)) + '\t' + str(round(m[0])) + '\t' + str(round(m[1],2)) + '\t' + str(round(m[2],2)) + '\t' + str(round(chi2,2)) #if least-square minimization fails except RuntimeError: try: popt, pcov = curve_fit( poly3, rho[temperature], P[temperature], p0=None, sigma=stdev_P[temperature], absolute_sigma=False) chi2 = chi2red_3(rho[temperature], P[temperature], stdev_P[temperature], popt) DensityX = np.arange(3200, 6300, 10) ax.plot(DensityX, poly3(DensityX, *popt), '--', color=colors_T[temperature], label=temperature + ' poly3 fit') ax.plot(rho[temperature], P[temperature], 'o', color=colors_T[temperature], label=temperature + ' data') print("Least-square fit of poly3") P0 = poly3(rho0, *popt) string = string + '\t' + str( round(rho0)) + '\t' + str(round( P0, 2)) + '\t-\t-\t-\t' + str( round(chi2, 2)) except RuntimeError: print("Fail of both BM3 a,nd poly3 fit") P0 = P[temperature][ i] - hugoniot[temperature][i] / ( (hugoniot[temperature][i] - hugoniot[temperature][i - 1]) / (P[temperature][i] - P[temperature][i - 1])) string = string + '\t' + str( round(rho0)) + '\t' + str(round( P0, 2)) + '\t-\t-\t-\t-' ax.plot(rho[temperature], P[temperature], 'o', color=colors_T[temperature], label=temperature + ' data') #if we don't have enough data, we find P using same method as for finding rho else: print("Not enough data for BM3 fit") ax.plot(rho[temperature], P[temperature], 'o', color=colors_T[temperature], label=temperature + ' data') P0 = P[temperature][i] - hugoniot[temperature][i] / ( (hugoniot[temperature][i] - hugoniot[temperature][i - 1]) / (P[temperature][i] - P[temperature][i - 1])) string = string + '\t' + str( round(rho0)) + '\t' + str(round( P0, 2)) + '\t-\t-\t-\t-' #Calculation of E0 in J/kg (E hugoniot) using Hugoniot equation and rho,P Hugoniot E0 = ground_state[density_gs][0] - 0.5 * ( P0 * 1E9 + ground_state[density_gs][1]) * ( 1 / rho0 - 1 / density_gs) string = string + '\t' + str(round(E0, 2)) #****** Calculation of particle velocities Up = np.sqrt( (P0 * 1E9 - ground_state[density_gs][1]) * (rho0 - density_gs) / (rho0 * density_gs)) * 1E-3 string = string + '\t' + str(round(Up, 2)) for Uimp in impactor_velocities: Up = -np.sqrt( (rho0 - impactor_density) * P0 * 1E9 / (rho0 * impactor_density)) * 1E-3 + Uimp string = string + '\t' + str(round(Up, 2)) break if len(string) == previous_len: print('Hg = 0 not found') string = string + '\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-\t-' nf.write(string + '\n') print('the file ', nf.name, ' is created') plt.legend(loc='best') figurename = 'BM3_fit_' + thermofile.split('/')[-1].split( '_')[1].split('.txt')[0] + '_rho' + str(density_gs) + 'T' + str( ground_state[density_gs][2]) + '.png' fig.savefig(figurename, bbox_inches='tight', dpi=150) print(figurename, ' is created')
def main(argv): """ ********* Main program ********* """ #parameters for the figure for article plot_parameters = {"size_fonts" : 12,"size_font_ticks":10,"size_figure" : (4,4), "size_markers" : 4,"size_lines" : 1,"shift_labelpad" : 10} #other dictionnaries and parameters for the figure style_markers = {'Ca':'','K':'','Na':'','Al':'x','Si':'*','O':''} style_lines = {'Ca':'--','K':'--','Na':'--','Al':'--','Si':'-','O':'-'} legend_labels = {} colors_T = {'T2':'#800080','T3':'#297fff','T4':'#00ff00','T4.5':'#bae200', 'T5':'#ffcd01','T6':'#ff0101','T6.5':'#ff00a2','T7':'#ff01de'} filename = 'all' filename2 = '' atoms = 'all' xvariable = 'rho' #variables nedded fot the plot data = {} #dictionnary containing the data for each element, initialized for each T stdev = {} #same for stdev #other dictionnaries and parameters for the figure ions = [] compounds = [] Temperatures = [] #other parameters Na=6.022*10**23 #dictionnary for fullaverages file in full version column_number = {'rho':2,'P':5,'stdev_P':6,'err_P':7,'T':8,'stdev_T':9,'err_T':10, 'E':14,'stdev_E':15,'err_E':16,'Cvm_Nkb':23,'stdev_Cvm_Nkb':24, 'Cvm':25,'stdev_Cvm':26,'testCv':31,'stdev_testCv':32} try: options,arg = getopt.getopt(argv,"hf:g:a:v:",["filename","gfilename",'atoms','variable']) except getopt.GetoptError: print("plot_diffusion_allin1.py -f <filename>(default = all) -g <filename 2 (if we want to plot 2 files)> -a <atoms list, default = 'all'> -v <variable x axis (rho or P)> ") sys.exit() for opt,arg in options: if opt == '-h': print('') print('plot_diffusion_allin1.py program to plot diffusion coefficient as a function of density for each T and the selected minerals containing 4 elements') print("plot_diffusion_allin1.py -f <filename>(default = all files of every compound) -g <filename 2 (if we want to plot 2 files)> -a <atoms list, default = 'all'> -v <variable x axis (rho or P)> ") print("plot_diffusion_allin1.py requires to be lauched from the folder containing every diffusivities file created by the script analyze_msd") print('') print('For plots as function of P, make sure the files from fullaverages.py are in the current folder') sys.exit() if opt in ('-f','--filename'): filename = str(arg) elif opt in ('-g','--gfilename'): filename2 = str(arg) elif opt in ('-a','--atoms'): atoms = str(arg) elif opt in ('-v','--variable'): xvariable = str(arg) if filename == 'all': fig,ax1,ax2,ax3, ax0 = creation_plot_3(plot_parameters,xvariable) print("axis are ax1",ax1,"ax2",ax2,"ax3",ax3,"ax0",ax0) files = sorted(glob.glob('diffusivities_*.txt'),reverse=True) #I list every diffusivities files figurename = 'diffusivities_all_'+atoms elif filename2 != '': fig,ax1,ax2, ax0 = creation_plot_2(plot_parameters,xvariable) print("axis are ax1",ax1,"ax2",ax2,"ax0",ax0) files = [filename, filename2] #we will plot 2 files figurename = filename.split('.txt')[0] +'_'+ filename2.split('.txt')[0].split('_')[1]+'_'+atoms else: fig, ax = creation_plot(plot_parameters,xvariable) files = [filename] #I take only the file we want figurename = filename.split('.txt')[0]+'_'+atoms #************ creation of arrays and plot at the same time for file in files: #********initialisations #**change of subplot if filename == 'all' or filename2 !='': if files.index(file) == 0: ax=ax1 letter = 'a' if files.index(file) == 1: ax=ax2 letter = 'b' if files.index(file) == 2: ax=ax3 letter = 'c' print("I plot on axis",ax) #**extraction compound compound = file.split('_')[1].split('.txt')[0] compounds.append(format1label(compound)) #******* Extract P and T for each thermo file if xvariable == 'P': TP = {} mineralname = file.split('_')[1].split('.txt')[0] thermofiles = sorted(glob.glob('thermo_'+mineralname+'*.txt')) for thermofile in thermofiles: TP = extract_TP(thermofile, column_number, TP,'') if TP == {}: print('ERROR!!!! TP dictionnary empty') #**creation of elements and number lists and initialization of T with open(file,'r') as f: skiplines = 0 while True: line = f.readline() skiplines += 1 entry=line.split() if entry[0] == 'elements': elements = entry[1:] ions.append(elements[0]) elif entry[0] == 'number': number = entry[1:] elif entry[0] == 'file': line = f.readline() entry=line.split() temperature0, acell0 = split_name(entry[0]) break #**calculation of M*N nedded for the calculation of densities MN = 0 for i in range(len(elements)): MN = MN + float(number[i]) * cr.Elements2rest(elements[i])[3] #**initialisation of data data = {} #big dictionnary with inside self diffusion coefficient or time of regime change, all coresponding to different T and atom pairs stdev = {} #idem for stdev X = {} #idem for rho or P for i in range(len(elements)): elem = elements[i] stdev[elem] = {} data[elem] = {} X[elem] = {} #we store all the ions only once in ions list indicator = 0 for j in range(len(ions)): if elements[i] == ions[j]: indicator = 1 if indicator == 0: ions.append(elements[i]) #****** Extraction of data with open(file,'r') as f: [f.readline() for i in range(skiplines)] while True: line = f.readline() if not line: break else: entry=line.split('\n')[0].split('\t') temp, acell = split_name(entry[0]) for i in range(len(elements)): elem = elements[i] try: data[elem][temp].append(float(entry[i*6+1])) stdev[elem][temp].append(float(entry[i*6+2])) if xvariable == 'P': X[elem][temp].append(TP[entry[0].split('outcar.msd.dat')[0].split('/')[-1]][1]) else: X[elem][temp].append( MN/(Na*float(acell)**3*10**(-24)) ) #calculation density except KeyError: data[elem][temp] = [ float(entry[i*6+1])] stdev[elem][temp] = [ float(entry[i*6+2]) ] if xvariable == 'P': X[elem][temp] = [TP[entry[0].split('outcar.msd.dat')[0].split('/')[-1]][1]] else: X[elem][temp] = [ MN/(Na*float(acell)**3*10**(-24)) ] #calculation density #****** Selection of elements we plot if atoms != 'all': elements = atoms.split(',') print('now elements list is',elements) #****** Plot for elem in elements: for temperature in data[elem]: print("******** ", temperature) print(data[elem][temperature]) Temperatures.append(temperature) ax.plot(X[elem][temperature],data[elem][temperature], style_markers[elem]+style_lines[elem], markersize = plot_parameters["size_markers"], color = colors_T[temperature], linewidth = plot_parameters["size_lines"]) #ax.text(0.95,0.85, compound , transform=ax.transAxes, horizontalalignment = 'right', fontweight = 'bold', fontsize = plot_parameters["size_fonts"]) if filename == 'all': ax.text(0.985,0.95, letter , transform=ax.transAxes, horizontalalignment = 'right', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], bbox=dict(facecolor='none', edgecolor='k', pad=3.0)) elif filename2 != '': ax.text(0.985,0.95, letter , transform=ax.transAxes, horizontalalignment = 'right', fontweight = 'bold', fontsize = plot_parameters["size_fonts"], bbox=dict(facecolor='none', edgecolor='k', pad=3.0)) #****** Create legend from custom artist/label lists #********* Legend #Create legend from custom artist/label lists Temperatures = list(set(Temperatures)) #get elements only once in the list custom_patch = [mpatches.Patch(color=colors_T[key]) for key in natsort.natsorted(Temperatures)] if atoms != 'all': ions = elements print(ions) for ion in ions: legend_labels[ion] = plt.Line2D((0,1),(0,0), color='k', markersize = plot_parameters["size_markers"], marker=style_markers[ion], linestyle=style_lines[ion], linewidth = plot_parameters["size_lines"]) s = [(k, legend_labels[k]) for k in sorted(legend_labels.keys(),reverse = False)] if filename == 'all': ax=ax0 legend = ax0.legend([col for col in custom_patch],[str(int(float(label.strip('T'))*1000)) for label in natsort.natsorted(Temperatures)],title = '$\\bf{Temperature~(K)}$', bbox_to_anchor=(0.5, 1.12), loc="lower center", fontsize = plot_parameters["size_font_ticks"], borderaxespad=0., ncol=len(Temperatures)) plt.setp(legend.get_title(),fontsize= plot_parameters["size_font_ticks"]) plt.legend([v for k,v in s],[k for k,v in s], bbox_to_anchor=(0.5, 1), loc='lower center',fancybox=True, fontsize = plot_parameters["size_fonts"], ncol=len(style_lines)) ax0.add_artist(legend) elif filename2 != '': ax=ax0 legend = ax0.legend([col for col in custom_patch],[str(int(float(label.strip('T'))*1000)) for label in natsort.natsorted(Temperatures)],title = '$\\bf{Temperature~(K)}$', bbox_to_anchor=(0.5, 1.12), loc="lower center", fontsize = plot_parameters["size_font_ticks"], borderaxespad=0., ncol=len(Temperatures)) plt.setp(legend.get_title(),fontsize= plot_parameters["size_font_ticks"]) plt.legend([v for k,v in s],[k for k,v in s], bbox_to_anchor=(0.5, 1), loc='lower center',fancybox=True, fontsize = plot_parameters["size_fonts"], ncol=len(style_lines)) ax0.add_artist(legend) figurename = figurename + '.pdf' print("figure saved with name ",figurename) fig.savefig(figurename, bbox_inches = 'tight', dpi = 300)