Beispiel #1
0
def main():
    print(
        "WARNING! The partial g(r)'s in this function might be a bit off (compared to RINGS calculations). Also, the total is a bit off too. However, if you add up all the partials you DO get the correct total (assuming RINGS is right)."
    )
    modelfile = sys.argv[1]
    m = Model(modelfile)

    # This block of code prints the cutoffs
    cutoffs = generate_cutoffs(m)
    print(cutoffs)

    # This block of code saves all the gr's to gr.txt
    outcontent = []
    types = list(m.atomtypes)
    for L in range(1, len(types) + 1):
        for subset in itertools.combinations(types, L):
            print(subset)
            s = list(subset)
            x, g = gr(m, types=s)
            g = list(g)
            s = [znum2sym.z2sym(y) for y in s]
            g.insert(0, "gr_{0}".format("_".join(s)))
            outcontent.append(g)
    print("Writing output to gr.txt.")
    x = list(x)
    x.insert(0, "dr")
    outcontent.insert(0, x)
    outcontent = [[str(y) for y in x] for x in zip(*outcontent)]
    of = open("gr.txt", "w")
    for i in xrange(0, len(outcontent)):
        of.write(" ".join(outcontent[i]) + "\n")
def index_stats(m):
    """ Prints the number of atoms in each VP index"""
    cats = {}
    for atom in m.atoms:
        #if atom.sym == 'Zr' or atom.sym == 'Al': continue
        #if atom.sym == 'Zr' or atom.sym == 'Cu': continue
        if atom.vp.index not in cats:
            cats[atom.vp.index] = OrderedDict()
            for typ in sorted([z2sym(x) for x in m.atomtypes], reverse=True):
                cats[atom.vp.index][typ] = 0
        cats[atom.vp.index][atom.sym] = cats[atom.vp.index].get(atom.sym,0) + 1
        cats[atom.vp.index]["Total"]  = cats[atom.vp.index].get("Total",0) + 1
    # Print
    for val,key in sorted( ((v,k) for k,v in cats.iteritems()), key=lambda t: t[0]['Total']): 
        #for atom in m.atoms:
        #    if(atom.vp.index == key):
        #        typ = atom.vp.type
        #        break
        #print("{0}: \t{1}\t{2}".format(key,val,typ))
        #if list(key)[0:4] != [0,2,8,0]:
        #    continue
        if val['Total'] < m.natoms*0.005: continue
        val = [(k,value) for k,value in val.items()]
        val = [str(x) for row in val for x in row]
        val = '\t'.join(val)
        print("{0}: \t{1}".format(key,val))
        #print("{0}: \t{1}\t{2}".format(key,val,round(val['Total']/float(m.natoms)*100,3)))
    return cats
 def index_stats(self):
     cats = {}
     for atom in self.m.atoms:
         if atom.vp.index not in cats:
             cats[atom.vp.index] = OrderedDict()
             for typ in sorted([z2sym(x) for x in self.m.atomtypes], reverse=True):
                 cats[atom.vp.index][typ] = 0
         cats[atom.vp.index][atom.sym] = cats[atom.vp.index].get(atom.sym, 0) + 1
         cats[atom.vp.index]["Total"] = cats[atom.vp.index].get("Total", 0) + 1
     return cats
Beispiel #4
0
 def __init__(self, id, znum, x, y, z):
     self.id = id
     if(isinstance(znum,int)):
         self.z = znum
     elif(isinstance(znum,str)):
         self.z = znum2sym.sym2z(znum)
     self.coord = (x,y,z)
     self.vp = VoronoiPoly()
     self.neighs = None # Neighbors. List when set
     self.cn = None # Coordination number. int when set
     self.sym = znum2sym.z2sym(self.z) #atomic symbol
Beispiel #5
0
 def _write_cif(self, outfile=None):
     if outfile is None: of = sys.stdout
     else:               of = open(outfile,'w')
     of.write('_pd_phase_name\t'+self.comment+'\n')
     of.write('_cell_length_a '+str(self.xsize)+'\n')
     of.write('_cell_length_b '+str(self.ysize)+'\n')
     of.write('_cell_length_c '+str(self.zsize)+'\n')
     of.write('_cell_angle_alpha 90\n_cell_angle_beta 90\n_cell_angle_gamma 90\n')
     of.write('_symmetry_space_group_name_H-M         \'P 1\'\n_symmetry_Int_Tables_number            1\n\n')
     of.write('loop_\n_symmetry_equiv_pos_as_xyz\n   \'x, y, z\'\n\n')
     of.write('loop_\n   _atom_site_label\n   _atom_site_occupancy\n   _atom_site_fract_x\n   _atom_site_fract_y\n   _atom_site_fract_z\n   _atom_site_adp_type\n   _atom_site_B_iso_or_equiv\n   _atom_site_type_symbol\n')
     atomtypes = {}
     for atom in self.atoms:
         atomtypes[atom.z] = atomtypes.get(atom.z, 0) + 1
         of.write('   '+znum2sym.z2sym(atom.z)+str(atomtypes[atom.z])+'\t1.0\t'+str(atom.coord[0]/self.xsize+0.5)+'\t'+str(atom.coord[1]/self.ysize+0.5)+'\t'+str(atom.coord[2]/self.zsize+0.5)+'\tBiso\t1.000000\t'+znum2sym.z2sym(atom.z)+'\n')
     of.write('\n')
     of.close()
Beispiel #6
0
def generate_cutoffs(m):
    outcontent = []

    cutoff_types = []
    types = list(m.atomtypes)
    types.sort()
    for L in range(1, len(types)):
        # for L in range(1,len(types)+1):
        for subset in itertools.combinations(types, L):
            # print(subset)
            s = list(subset)
            xx, g = gr(m, types=s)
            g = list(g)
            s = [znum2sym.z2sym(y) for y in s]
            # g.insert(0,'gr_{0}'.format('_'.join(s)))
            outcontent.append(g)
            cutoff_types.append(s)
    cutoff_types = [[x[0], x[0]] if len(x) == 1 else x for x in cutoff_types]
    cutoff_types = [[znum2sym.sym2z(y) for y in x] for x in cutoff_types]
    cutoff_types = [[types.index(y) for y in x] for x in cutoff_types]
    # print(cutoff_types)

    cutoffs = np.zeros((len(m.atomtypes), len(m.atomtypes)))

    xx = list(xx)
    # xx.insert(0,'dr')
    outcontent.insert(0, xx)
    for i, arr in enumerate(outcontent[1:]):
        peak1 = arr.index(max(arr))
        # print('peak1',peak1,xx[peak1],arr[peak1])
        # print(arr[peak1:int(round(peak1*3.5))])
        min1 = peak1 + arr[peak1 : int(round(peak1 * 3.5))].index(min(arr[peak1 : int(round(peak1 * 3.5))]))
        # print('min1',min1,xx[min1],arr[min1])
        peak2 = min1 + arr[min1:].index(max(arr[min1:]))
        # print('peak2',peak2,xx[peak2],arr[peak2])
        # print('')
        cutoffs[cutoff_types[i][0]][cutoff_types[i][1]] = xx[min1]
        cutoffs[cutoff_types[i][1]][cutoff_types[i][0]] = xx[min1]
    # print(cutoffs)
    return cutoffs
    def __add__(self, other):
        if isinstance(other, Model):
            self.natoms += other.natoms
            cats = self.indices
            for atom in other.atoms:
                if atom.vp.index not in cats:
                    cats[atom.vp.index] = OrderedDict()
                    for typ in sorted([z2sym(x) for x in other.atomtypes], reverse=True):
                        cats[atom.vp.index][typ] = 0
                cats[atom.vp.index][atom.sym] = cats[atom.vp.index].get(atom.sym, 0) + 1
                cats[atom.vp.index]["Total"] = cats[atom.vp.index].get("Total", 0) + 1

            cats = self.categories
            for atom in other.atoms:
                if atom.vp.type not in cats:
                    cats[atom.vp.type] = {}
                cats[atom.vp.type][atom.sym] = cats[atom.vp.type].get(atom.sym, 0) + 1
                cats[atom.vp.type]["Total"] = cats[atom.vp.type].get("Total", 0) + 1
        # elif isinstance(other, VPStatistics):
        else:
            raise Exception("Cannot add type {0} to VPStatistics!".format(type(other)))
        return self
Beispiel #8
0
 def generate_coord_numbers(self):
     """ atom.neighs must be defined first for all atoms """
     self.coord_numbers = {}
     # Form will be:
     #   {'Cu-Al': 4.5}, etc.
     for typea in self.atomtypes:
         self.coord_numbers[znum2sym.z2sym(typea)] = 0
         for typeb in self.atomtypes:
             self.coord_numbers[znum2sym.z2sym(typea)+'-'+znum2sym.z2sym(typeb)] = 0
     for atom in self.atoms:
         for n in atom.neighs:
             self.coord_numbers[znum2sym.z2sym(atom.z)] += 1
             self.coord_numbers[znum2sym.z2sym(atom.z)+'-'+znum2sym.z2sym(n.z)] += 1
     self.bonds = self.coord_numbers.copy()
     for key in self.coord_numbers:
         elem = znum2sym.sym2z(key.split('-')[0])
         self.coord_numbers[key] /= float(self.atomtypes[elem])
Beispiel #9
0
 def radial_composition(self, outfile):
     """ Creates 1D waves stored in outfile for each element in the model. Each 
     wave is a histogram of the number of atoms between two radial positions
     starting at the center of model and radiating outward. """
     # TODO Rewrite if I ever need this again
     npix = 16
     keys = self.atomtypes.keys()
     #histo = [[0.0 for x in range(npix)] for key in keys]
     histo = [{} for x in range(npix)]
     dx = (self.xsize/2.0)/npix # Cube assumed
     for i,r in enumerate(drange(dx, npix*dx-dx, dx)):
         atoms = self.get_atoms_in_cutoff( (0.0,0.0,0.0), r)
         print(r, len(atoms))
         comp = {}
         for atom in atoms:
             comp[str(atom.z)] = comp.get(str(atom.z),0) + 1.0
         for type in self.atomtypes:
             if( str(type) not in comp.keys()):
                 comp[str(type)] = 0.0
         comp['Total'] = len(atoms)
         histo[i] = comp
     of = open(outfile,'w')
     of.write('IGOR\n')
     for atomtype in keys:
         of.write('\nWAVES/N=({0})\t {1}\nBEGIN\n'.format(npix,'partial_radial_comp_'+znum2sym.z2sym(atomtype)))
         for i in range(npix-2):
             if(i != 0):
                 of.write("{0} ".format((histo[i][str(atomtype)] - histo[i-1][str(atomtype)])/( 4.0/3.0*np.pi*( (i*dx)**3 - ((i-1)*dx)**3 ))))
                 #print("{1}  {0} ".format(histo[i][str(atomtype)],i*dx))
                 #print("  {1}  {0} ".format(histo[i][str(atomtype)] - histo[i-1][str(atomtype)],i*dx))
             else:
                 of.write("{0} ".format(histo[i][str(atomtype)]))
                 #print("{1}  {0} ".format(histo[i][str(atomtype)],i*dx))
         of.write("\n")
         of.write('END\n')
         of.write('X SetScale x 0,{1}, {0};\n'.format('partial_comp_'+znum2sym.z2sym(atomtype),npix*dx-dx))
     of.close()
Beispiel #10
0
 def generate_average_coord_numbers(self):
     """ atom.neighs must be defined first for all atoms
         Form will be:
             {'Cu-Al': 4.5, ... }
     """
     coord_numbers = {}
     for typea in self.atomtypes:
         coord_numbers[znum2sym.z2sym(typea)] = 0
         for typeb in self.atomtypes:
             coord_numbers[znum2sym.z2sym(typea)+'-'+znum2sym.z2sym(typeb)] = 0
     for atom in self.atoms:
         for n in atom.neighs:
             coord_numbers[znum2sym.z2sym(atom.z)] += 1
             coord_numbers[znum2sym.z2sym(atom.z)+'-'+znum2sym.z2sym(n.z)] += 1
     for key in coord_numbers:
         elem = znum2sym.sym2z(key.split('-')[0])
         coord_numbers[key] /= float(self.atomtypes[elem])
     return coord_numbers
Beispiel #11
0
 def local_composition(self, outfile):
     """ Variable radius sliding average Goes pixel by pixel and calculates the
     composition around that pixel (within some radius) and assigns the center
     pixel that composition. Use a 256 x 256 x 256 matrix. """
     # TODO Rewrite if I ever need this again
     radius = 3.6 * 2
     npix = 64
     #mat = np.zeros((npix,npix,npix),dtype=np.float)
     #mat = np.zeros((npix,npix,npix),dtype={'names':['col1', 'col2', 'col3'], 'formats':['f4','f4','f4']})
     #mat = np.zeros((npix,npix,npix),dtype={'names':['40', '13', '29'], 'formats':['f4','f4','f4']})
     #mat = np.zeros((npix,npix,npix),dtype={'names':['id','data'], 'formats':['f4','f4']})
     #names = ['id','data']
     #formats = ['i4',('f4','f4','f4')]
     #mat = np.zeros((npix,npix,npix),dtype=dict(names = names, formats=formats))
     #mat = np.zeros((npix,npix,npix),dtype={'40':('i4',0), '29':('f4',0), '13':('f4',0)})
     print("Creating matrix...")
     mat = [[[{} for i in range(npix)] for j in range(npix)] for k in range(npix)]
     print("Finished creating matrix.")
     #print(repr(mat))
     dx = self.xsize/npix
     dy = self.ysize/npix
     dz = self.zsize/npix
     for ii,i in enumerate(drange(-npix/2*dx,npix/2*dx-dx,dx)):
         print("On ii = {0}".format(ii))
         for jj,j in enumerate(drange(-npix/2*dy,npix/2*dy-dy,dy)):
             for kk,k in enumerate(drange(-npix/2*dz,npix/2*dz-dz,dz)):
                 atoms = self.get_atoms_in_cutoff( (i,j,k), radius )
                 comp = {}
                 for atom in atoms:
                     comp[str(atom.z)] = comp.get(str(atom.z),0) + 1.0
                 for key in comp:
                     comp[key] /= len(atoms)
                 #print(comp)
                 #mat[ii][jj][kk] = copy.copy(comp)
                 mat[ii][jj][kk] = comp
     of = open(outfile,'w')
     of.write('IGOR\n')
     for atomtype in self.atomtypes:
         of.write('\nWAVES/N=({0},{1},{2})\t {3}\nBEGIN\n'.format(npix,npix,npix,'partial_comp_'+znum2sym.z2sym(atomtype)))
         for layer in mat:
             for column in layer:
                 for value in column:
                     try:
                         of.write("{0} ".format(value[str(atomtype)]))
                     except KeyError:
                         of.write("{0} ".format(0.0))
             of.write("\n")
         of.write('END\n')
         of.write('X SetScale/P x 0,1,"", {0}; SetScale/P y 0,1,"", {0}; SetScale/P z 0,1,"", {0}; SetScale d 0,0,"", {0}\n'.format('partial_comp_'+znum2sym.z2sym(atomtype)))
     of.close()
     return mat
Beispiel #12
0
 def composition(self):
     d = {}
     for key in self.atomtypes:
         d[znum2sym.z2sym(key)] = self.atomtypes[key]/float(self.natoms)
     return d
Beispiel #13
0
 def convert_to_sym(self):
     self.z = znum2sym.z2sym(self.z)
     return self
Beispiel #14
0
 def realxyz(self):
     return str(znum2sym.z2sym(self.z))+'\t'+str(self.coord[0])+'\t'+str(self.coord[1])+'\t'+str(self.coord[2])
Beispiel #15
0
 def vesta(self):
     """ returns a string with the atoms information in the format for the vesta input file """
     if(type(self.z) != type('hi')):
         return znum2sym.z2sym(self.z) + '\t' + str(self.coord[0]) + '\t' + str(self.coord[1]) + '\t' + str(self.coord[2])
     elif(type(self.z) == type('hi')):
         return self.z + '\t' + str(self.coord[0]) + '\t' + str(self.coord[1]) + '\t' + str(self.coord[2])