def main():
    # sys.argv == [categorize_parameters.txt, modelfile]
    if(len(sys.argv) <= 2): sys.exit("\nERROR! Fix your inputs!\n\nArg 1:  input param file detailing each voronoi 'structure'.\nShould be of the form:\nCrystal:\n    0,2,8,*\n\nArg2: a model file.\n\nOutput is printed to screen.")

    paramfile = sys.argv[1]
    modelfiles = sys.argv[2:]

    from cutoff import cutoff

    vp_dict = load_param_file(paramfile)

    m0 = Model(modelfiles[0])
    m0.generate_neighbors(cutoff)
    voronoi_3d(m0, cutoff)
    set_atom_vp_types(m0, vp_dict)
    stats0 = VPStatistics(m0)
    print(modelfiles[0])
    #stats0.print_indexes()
    stats0.print_categories()
    return

    if len(modelfiles) > 1:
        for modelfile in modelfiles[1:]:
            print(modelfile)
            m = Model(modelfile)
            voronoi_3d(m, cutoff)
            set_atom_vp_types(m, vp_dict)
            stats = VPStatistics(m)
            stats.print_categories()
Esempio n. 2
0
def main():
    # NOTE: Cutoff can either be a single integer or it
    # can be a dictionary where the keys are two-tuples
    # of atomic numbers (e.g. (40,13)=3.5 for Zr,Al).
    modelfile = sys.argv[1]
    submodelfile = sys.argv[2]
    rotatedsubmodelfile = sys.argv[3]
    m = Model(modelfile)
    try:
        cut = 3.5  # float(sys.argv[2])
        cutoff = {}
        for z1 in m.atomtypes:
            for z2 in m.atomtypes:
                cutoff[(z1, z2)] = cut
                cutoff[(z2, z1)] = cut
    except:
        print("You didn't input a cutoff so you much define it in the code.")
    voronoi_3d(m, cutoff)

    subm = Model(submodelfile)
    rotsubm = Model(rotatedsubmodelfile)
    for atom in subm.atoms:
        if atom in m.atoms:
            rotsubm.atoms[atom.id].vp = m.atoms[m.atoms.index(atom)].vp
        else:
            print("Couldn't find atom {0} in full model!".format(atom))
    icofrac(rotsubm)
    # rotsubm.write_real_xyz()
    rotsubm.write_real_xyz(rotatedsubmodelfile[:-4] + ".icofrac.real.xyz")
def main():
    wholemodelfile = sys.argv[1]
    submodelfile = sys.argv[2]
    vpparamfile = sys.argv[3]

    wm = Model(wholemodelfile)
    voronoi_3d(wm,3.5)
    #try:
    sm = Model(submodelfile)
    #highlight(wholemodelfile,submodelfile)
    vp_analyze(wm, sm, vpparamfile)
Esempio n. 4
0
def main():
    # sys.argv == [categorize_parameters.txt, modelfile]
    if len(sys.argv) <= 2:
        sys.exit(
            "\nERROR! Fix your inputs!\n\nArg 1:  input param file detailing each voronoi 'structure'.\nShould be of the form:\nCrystal:\n    0,2,8,*\n\nArg2: a model file.\n\nOutput is printed to screen."
        )

    paramfile = sys.argv[1]
    modelfiles = sys.argv[2:]

    from cutoff import cutoff

    vp_dict = load_param_file(paramfile)

    m0 = Model(modelfiles[0])
    m0.generate_neighbors(cutoff)
    # voronoi_3d(m0, cutoff)
    # set_atom_vp_types(m0, vp_dict)
    # stats0 = VPStatistics(m0)
    # stats0.print_indexes()
    # stats0.print_categories()

    from atom import Atom

    m = Model(
        "atoms with less than 12 neighbors in Zr50Cu45Al15 MD model (originally with 91200 atoms)",
        m0.lx,
        m0.ly,
        m0.lz,
        [],
    )
    count = 0
    for j, atom in enumerate(m0.atoms):
        if len(atom.neighs) >= 12:
            continue
        new = Atom(count, "Si", *atom.coord)
        count += 1
        print("Added new atom {0}".format(new))
        m.add(new)
    m.write("less_than_12_neighbors.xyz")

    if len(modelfiles) > 1:
        for modelfile in modelfiles[1:]:
            m = Model(modelfile)
            voronoi_3d(m, cutoff)
            set_atom_vp_types(m, vp_dict)

            stats0 = stats0 + m
            stats0.print_categories()
            stats0.print_indexes()
Esempio n. 5
0
    def __init__(self,modelfile,cutoff):
        """ Constructor
        @param cutoff is the cutoff we will use to determine neighbors """

        super(AtomGraph,self).__init__()
        
        self.model = Model(modelfile)
        #self.model.generate_neighbors(cutoff)

        #self.model.generate_coord_numbers()
        #print('Coordination numbers:')
        #pprint(self.model.coord_numbers)
        #self.model.print_bond_stats()

        # Generate CNs for different cutoffs. I can plot this and find
        # where it changes the least (ie deriv=0); this is a good spot
        # to set the cutoff distances because then the neighbors are
        # the least dependent on the cutoff distance.
        # I should make this into a function in model.py TODO
        #for cut in np.arange(2.0,4.6,0.1):
        #    self.model.generate_neighbors(cut)
        #    self.model.generate_coord_numbers()
        #    print("Cutoff: {0}".format(cut))
        #    for key in self.model.coord_numbers:
        #        if(len(key) < 4):
        #            print('  {0}: {1}'.format(key,self.model.coord_numbers[key]))

        #vor_instance = Vor()
        #vor_instance.runall(modelfile,cutoff)
        #index = vor_instance.get_indexes()
        #vor_instance.set_atom_vp_indexes(self.model)
        voronoi_3d(self.model,cutoff)
        
        #vorcats = VorCats('/home/jjmaldonis/OdieCode/vor/scripts/categorize_parameters.txt')
        self.vp_dict = categorize_vor.load_param_file('/home/jjmaldonis/model_analysis/scripts/categorize_parameters_iso.txt')
        #Eself.vp_dict = categorize_vor.load_param_file('/home/maldonis/model_analysis/scripts/categorize_parameters_iso.txt')
        #self.atom_dict = categorize_vor.generate_atom_dict(index,self.vp_dict)
        #vorcats.save(index)
        categorize_vor.set_atom_vp_types(self.model,self.vp_dict)
def main():
    modelfile = sys.argv[1]

    m = Model(modelfile)
    keys = [(41, 41), (28, 28), (41, 28)]
    cutoff = {}
    cutoff[(41, 41)] = 3.5
    cutoff[(28, 28)] = 3.5
    cutoff[(41, 28)] = 3.5

    # for dc in [-0.3, -0.2, 0.0, -0.1, 0.1, 0.2, 0.3]:
    for c in [3.3, 3.4, 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 4.1, 4.2, 4.3, 4.4, 4.5]:
        cutoff2 = copy.deepcopy(cutoff)
        m = Model(modelfile)
        for key in keys:
            cutoff2[key] = c
        try:
            voronoi_3d(m, cutoff2)
            print("Cutoff = {0}".format(c))
            cn_histo(m)
        except:
            pass
Esempio n. 7
0
def main():
    ##### sys.argv == [categorize_parameters.txt, *_index.out]
    # sys.argv == [categorize_parameters.txt, modelfile]
    #if(len(sys.argv) <= 2): sys.exit("\nERROR! Fix your inputs!\n\nArg 1:  input param file detailing each voronoi 'structure'.\nShould be of the form:\nCrystal:\n    0,2,8,*\n\nArg2: an _index.out file.\n\nOutput is printed to screen.")
    if(len(sys.argv) <= 2): sys.exit("\nERROR! Fix your inputs!\n\nArg 1:  input param file detailing each voronoi 'structure'.\nShould be of the form:\nCrystal:\n    0,2,8,*\n\nArg2: a model file.\n\nOutput is printed to screen.")

    modelfile = sys.argv[2]
    paramfile = sys.argv[1]

    m = Model(modelfile)

    voronoi_3d(m,3.5)

    #vorrun = vor.Vor()
    #vorrun.runall(modelfile,3.5)

    vp_dict = load_param_file(paramfile)
    #atom_dict = generate_atom_dict(vorrun.index,vp_dict)
    #vor_cats.load_index_file(sys.argv[2])
    #printVorCats(atom_dict,vp_dict)

    set_atom_vp_types(m,vp_dict)
    vor_stats(m)
def main():
    cutoff = {}
    cutoff[(40,40)] = 3.6
    cutoff[(13,29)] = 3.6
    cutoff[(29,13)] = 3.6
    cutoff[(40,13)] = 3.6
    cutoff[(13,40)] = 3.6
    cutoff[(29,40)] = 3.6
    cutoff[(40,29)] = 3.6
    cutoff[(13,13)] = 3.6
    cutoff[(29,29)] = 3.6

    cutoff[(41,41)] = 3.7
    cutoff[(28,28)] = 3.7
    cutoff[(41,28)] = 3.7
    cutoff[(28,41)] = 3.7

    cutoff[(46,46)] = 3.45
    cutoff[(14,14)] = 3.45
    cutoff[(46,14)] = 3.45
    cutoff[(14,46)] = 3.45

    paramfile = sys.argv[1]
    vp_dict = load_param_file(paramfile)

    modelfiles = sys.argv[2:]
    count = defaultdict(int) # Stores how many VPs have been found of each index type
    count = 0
    direc = 'ZrCuAl/md_80k/'
    for modelfile in modelfiles:
        print(modelfile)
        m = Model(modelfile)
        m.generate_neighbors(cutoff)
        #voronoi_3d(m,cutoff)
        #set_atom_vp_types(m,vp_dict)
        #vor_stats(m)
        #cats = index_stats(m)
        #for atom in m.atoms:
        #    #new = Model('0,0,12,0; number of atoms is {0};'.format(count), m.lx, m.ly, m.lz, atom.neighs + [atom])
        #    new = Model('{0}; number of atoms is {1};'.format(atom.vp.index, count[atom.vp.index]), m.lx, m.ly, m.lz, atom.neighs + [atom])
        #    fix_cluster_pbcs(new)
        #    val = normalize_bond_distances(new)
        #    new.comment = '{0}; number of atoms is {1}; bond length scaling factor is {2}'.format(atom.vp.index, count,val)
        #    center = find_center_atom(new)
        #    new.remove(center)
        #    new.add(center)
        #    vp_str = ''.join([str(x) for x in atom.vp.index])
        #    if not os.path.exists(direc+vp_str):
        #        os.makedirs(direc+vp_str)
        #    new.write(direc+'{0}/{0}.{1}.xyz'.format(vp_str, count[atom.vp.index]))
        #    count[atom.vp.index] += 1
        #print(count)
        cn = 0.0
        for atom in m.atoms:
            cn += atom.cn
        cn = float(cn)/m.natoms
        print(cn)

        for atom in m.atoms:
            new_cut = copy.copy(cutoff)
            old_cn = atom.cn
            inc = 0.0
            while atom.cn < 12:
                for key,val in new_cut.items(): new_cut[key] = val + 0.1
                inc += 0.1
                atom.neighs = m.get_atoms_in_cutoff(atom, new_cut)
                if(atom in atom.neighs): atom.neighs.remove(atom)
                atom.cn = len(atom.neighs)
            new = Model('CN changed from {0} to {1};'.format(old_cn, atom.cn), m.lx, m.ly, m.lz, atom.neighs + [atom])
            new.write('temp/{0}.xyz'.format(count))
            if inc > 0.0: print("Increased shell by {0} Ang. for atom {1}".format(inc, count))
            count += 1
        cn = 0.0
        for atom in m.atoms:
            cn += atom.cn
        cn = float(cn)/m.natoms
        print(cn)

    return 0

    modelfile = sys.argv[2]
    m = Model(modelfile)
    xtal_atoms = sys.argv[3]
    xtal_atoms = Model(xtal_atoms).atoms

    #x,y,z = (round(x,6) for x in self.coord)
    #a,b,c = (round(x,6) for x in other.coord)
    #print("HERE")
    #print([round(x,7) for x in xtal_atoms[13].coord])
    #print([round(x,7) for x in m.atoms[153].coord])
    #print(type(xtal_atoms[13]))
    #print(type(m.atoms[153]))
    #print(xtal_atoms[13] == m.atoms[153])
    #return 0

    glassy_atoms = []
    for atom in m.atoms:
        if atom not in xtal_atoms:
            glassy_atoms.append(atom)
    print(len(glassy_atoms))
    print(len(xtal_atoms))
    assert len(glassy_atoms) + len(xtal_atoms) == m.natoms
    voronoi_3d(m, cutoff)
    set_atom_vp_types(m, vp_dict)
    m.generate_neighbors(3.45)
    head, tail = os.path.split(modelfile)
    head = head + '/'
    if not os.path.exists(head+'glassy/'):
        os.makedirs(head+'glassy/')
    if not os.path.exists(head+'xtal/'):
        os.makedirs(head+'xtal/')
    for count, atom in enumerate(xtal_atoms):
        i = m.atoms.index(atom)
        atom = m.atoms[i]
        new = Model('{0}'.format(atom.vp.index), m.lx, m.ly, m.lz, atom.neighs + [atom])
        fix_cluster_pbcs(new)
        val = normalize_bond_distances(new)
        new.comment = '{0}; bond length scaling factor is {1}'.format(atom.vp.index, val)
        center = find_center_atom(new)
        new.remove(center)
        new.add(center)
        vp_str = ''.join([str(x) for x in atom.vp.index])
        new.write(head+'xtal/{0}.xyz'.format(count))
    for count, atom in enumerate(glassy_atoms):
        i = m.atoms.index(atom)
        atom = m.atoms[i]
        new = Model('{0}'.format(atom.vp.index), m.lx, m.ly, m.lz, atom.neighs + [atom])
        fix_cluster_pbcs(new)
        val = normalize_bond_distances(new)
        new.comment = '{0}; bond length scaling factor is {1}'.format(atom.vp.index, val)
        center = find_center_atom(new)
        new.remove(center)
        new.add(center)
        vp_str = ''.join([str(x) for x in atom.vp.index])
        new.write(head+'glassy/{0}.xyz'.format(count))
    return 0
        




    for atom in volume_atoms.atoms:
        for i,atom2 in enumerate(m.atoms):
            if(atom.z == atom2.z and [round(x, 5) for x in atom.coord] == [round(x, 5) for x in atom2.coord]): good[i] = True
    count = defaultdict(int) # Stores how many VPs have been found of each index type
    for modelfile in modelfiles:
        print(modelfile)
        m = Model(modelfile)
        voronoi_3d(m,cutoff)
        set_atom_vp_types(m,vp_dict)
        #vor_stats(m)
        #cats = index_stats(m)
        for i,atom in enumerate(m.atoms):
            if not good[i]: continue
            #new = Model('0,0,12,0; number of atoms is {0};'.format(count), m.lx, m.ly, m.lz, atom.neighs + [atom])
            new = Model('{0}; number of atoms is {1};'.format(atom.vp.index, count), m.lx, m.ly, m.lz, atom.neighs + [atom])
            fix_cluster_pbcs(new)
            val = normalize_bond_distances(new)
            new.comment = '{0}; number of atoms is {1}; bond length scaling factor is {2}'.format(atom.vp.index, count,val)
            center = find_center_atom(new)
            new.remove(center)
            new.add(center)
            vp_str = ''.join([str(x) for x in atom.vp.index])
            if not os.path.exists(vp_str):
                os.makedirs(vp_str)
            new.write('{0}/{0}.{1}.xyz'.format(vp_str, count[atom.vp.index]))
            count[atom.vp.index] += 1
        print(count)
        for c,v in count.items():
            print("{0}: {1}".format(c,v))
        print(sum(count.values()))
        cn = 0.0
        for atom in m.atoms:
            cn += atom.cn
        cn = float(cn)/m.natoms
        print(cn)
def main():
    """ Columns that I should have:
        % atoms that are xtal-like (i.e. what % of all the xtal-like atoms are in this sub-model?)
        % atoms that are ico-like
        % atoms that are mixed
        % atoms that are undefined
        Can you see planes?
        Is the spot visible in the sub-model's FT?
        What is the ratio of the max intensity of the spot in the original FT / that in the sub-model's FT? (Do this on a per-atom basis to account for the different number of atoms.)"""

    # paramfile, jobid, original ft, main ft direc, VP categories paramfile
    # It is necessary to have a "spot_ft" directory and a "submodels" directory
    # in the main ft directory for this to work.
    paramfile = sys.argv[1] # Paramfile
    with open(paramfile) as f:
        params = f.readlines()
    params = [line.strip() for line in params]
    modelfile = params[0]
    num_spots = int(params[1])
    jobid = sys.argv[2] # jobid
    orig_ft = sys.argv[3] # original ft
    main_direc = sys.argv[4] # spot ft direc
    spot_ft_direc = main_direc+'/spot_fts/'
    spot_fts = sorted(os.listdir(spot_ft_direc))
    spot_fts = [spot_ft_direc+line for line in spot_fts]
    submodel_direc = main_direc+'/submodels/'
    vp_paramfile = sys.argv[5] # VP paramfile for categorizing

    # Do the VP analysis first, it's faster.
    m = Model(modelfile)
    vp_dict = load_param_file(vp_paramfile)
    vp_dict['Undef'] = []
    cutoff = {}
    cutoff[(40,40)] = 3.6
    cutoff[(13,29)] = 3.6
    cutoff[(29,13)] = 3.6
    cutoff[(40,13)] = 3.6
    cutoff[(13,40)] = 3.6
    cutoff[(29,40)] = 3.6
    cutoff[(40,29)] = 3.6
    cutoff[(13,13)] = 3.6
    cutoff[(29,29)] = 3.6
    voronoi_3d(m,cutoff)
    set_atom_vp_types(m,vp_dict)
    vp_models = []
    for i,vptype in enumerate(vp_dict):
        vp_models.append( Model('{0} atoms'.format(vptype),m.lx,m.ly,m.lz, [atom for atom in m.atoms if atom.vp.type == vptype]) )
        vp_models[i].write_real_xyz('{0}.real.xyz'.format(vptype))
    vpcoloredmodel = Model('vp colored atoms',m.lx,m.ly,m.lz, m.atoms)
    for atom in vpcoloredmodel.atoms:
        if(atom.vp.type == 'Full-icosahedra'):
            atom.z = 1
        elif(atom.vp.type == 'Icosahedra-like'):
            atom.z = 2
        elif(atom.vp.type == 'Mixed'):
            atom.z = 3
        elif(atom.vp.type == 'Crystal-like'):
            atom.z = 4
        elif(atom.vp.type == 'Undef'):
            atom.z = 5
    vpcoloredmodel.write_our_xyz('vpcolored.xyz')

    #sm = Model(sys.argv[6])
    #rm = Model(sys.argv[7])
    #submodel_vp_colored(m,sm,rm)
    #vor_stats(sm)
    #vor_stats(rm)
    
    atom_dict_m = generate_atom_dict(m)
    smtable = {}
    submodelfiles = os.listdir(submodel_direc)
    submodelfiles = [smf for smf in submodelfiles if('real' not in smf)]
    submodelfiles = [smf for smf in submodelfiles if('cif' not in smf)]
    submodelfiles = [submodel_direc+smf for smf in submodelfiles]
    submodelfiles.sort()
    for i,submodelfile in enumerate(submodelfiles):
        sm = Model(submodelfile)
        for atom in sm.atoms:
            if( atom in m.atoms ):
                atom.vp = m.atoms[m.atoms.index(atom)].vp.copy()
        smtable[submodelfile] = {}
        for vptype in vp_dict:
            atom_dict_sm = generate_atom_dict(sm)
            #smtable[submodelfile][vptype] = len(atom_dict_sm[vptype]) / float(len(atom_dict_m[vptype]))
            smtable[submodelfile][vptype] = len(atom_dict_sm[vptype]) / float(sm.natoms)
    #for smf in submodelfiles:
    #    typedict = smtable[smf]
    #    print(smf)
    #    for vptype,ratio in typedict.iteritems():
    #        print("  {1}% {0}".format(vptype,round(100*ratio)))
    #    print("  Ratio of ico-like / xtal-like: {0}".format(typedict['Icosahedra-like']/typedict['Crystal-like']))
    #    print('')
    print_table(smtable)
    #return

    # Calculate the ratio of spot intensitites
    spot_ints = []
    orig_intensities = read_intensity_file(orig_ft)
    for i in range(0,num_spots):
        for intensityfile in spot_fts:
            id = get_spot_id(intensityfile)
            if(i == id):
                print("Intensity file: {0} => i={1}".format(intensityfile,id))
                # Find and generate corresponding sub-model
                # Need this to rescale by number of atoms
                # smf will stay at the correct string for appending to table
                for smf in submodelfiles:
                    if(get_spot_id(smf) == id):
                        sm = Model(smf)
                        break
                j = id*7 +2
                x0,y0,z0    = tuple([float(x) for x in params[j+1].split()])
                sx,sy,sz    = tuple([float(x) for x in params[j+2].split()])
                cxy,cxz,cyz = tuple([float(x) for x in params[j+3].split()])
                xi,xf,xc    = tuple([float(x)*2 for x in params[j+4].split()][:3])
                yi,yf,yc    = tuple([float(x)*2 for x in params[j+5].split()][:3])
                zi,zf,zc    = tuple([float(x)*2 for x in params[j+6].split()][:3])
                ft_intensities = read_intensity_file(intensityfile)
                maxoi = 0.0
                maxi = 0.0
                for x in range(xi-1,xf):
                    for y in range(yi-1,yf):
                        for z in range(zi-1,zf):
                            #print(x,y,z,orig_intensities[x][y][z])
                            if( ft_intensities[x][y][z] > maxi ):
                                maxi = ft_intensities[x][y][z]
                                print(orig_intensities[x][y][z],x,y,z)
                            if( orig_intensities[x][y][z] > maxoi ):
                                maxoi = orig_intensities[x][y][z]
                print("  Unscaled intensity ratio: {0}/{1}={2}".format(maxi,maxoi,maxi/maxoi))
                smtable[smf]['UIR'] = maxi/maxoi
                smtable[smf]['MUIR'] = sm.natoms/float(m.natoms)
                maxoi /= m.natoms  # rescale by number of atoms (ft is lineary scaling)
                maxi /= sm.natoms  # rescale by number of atoms (ft is lineary scaling)
                smtable[smf]['IR'] = maxi/maxoi
                print("  Intensity ratio: {0}/{1}={2}".format(maxi,maxoi,smtable[smf]['IR']))
                spot_ints.append((id,maxi,maxoi,maxi/maxoi))
                print(spot_ints)
                print_table(smtable)

    print_table(smtable)

    return
    # sys.argv[1] should be the modelfile in the xyz format
    # sys.argv[2] should be the cutoff desired
    modelfile = sys.argv[1]
    cutoff = float(sys.argv[2])
    ag = AtomGraph(modelfile,cutoff)
    model = Model(modelfile)
    model.generate_neighbors(cutoff)
    submodelfile = sys.argv[3]

    mixedmodel = Model('Mixed atoms',model.lx,model.ly,model.lz, [atom for atom in ag.model.atoms if atom.vp.type == 'Mixed'])
    icolikemodel = Model('Ico-like atoms',model.lx,model.ly,model.lz, [atom for atom in ag.model.atoms if(atom.vp.type == 'Icosahedra-like' or atom.vp.type == 'Full-icosahedra')])
    fullicomodel = Model('Full-icosahedra atoms',model.lx,model.ly,model.lz, [atom for atom in ag.model.atoms if atom.vp.type == 'Full-icosahedra'])
    xtalmodel = Model('Xtal-like atoms',model.lx,model.ly,model.lz, [atom for atom in ag.model.atoms if atom.vp.type == 'Crystal-like'])
    undefmodel = Model('Undef atoms',model.lx,model.ly,model.lz, [atom for atom in ag.model.atoms if atom.vp.type == 'Undef'])
    #mixedmodel.write_cif('mixed.cif')
    #mixedmodel.write_our_xyz('mixed.xyz')
    #icolikemodel.write_cif('icolike.cif')
    #icolikemodel.write_our_xyz('icolike.xyz')
    #fullicomodel.write_cif('fullico.cif')
    #fullicomodel.write_our_xyz('fullico.xyz')
    #xtalmodel.write_cif('xtal.cif')
    #xtalmodel.write_our_xyz('xtal.xyz')
    #undefmodel.write_cif('undef.cif')
    #undefmodel.write_our_xyz('undef.xyz')
    icomixedmodel = Model('ico+mix atoms',model.lx,model.ly,model.lz, mixedmodel.atoms + icolikemodel.atoms)
    #mixedmodel.write_cif('icomixed.cif')
    #mixedmodel.write_our_xyz('icomixed.xyz')
    vpcoloredmodel = Model('vp colored atoms',model.lx,model.ly,model.lz, ag.model.atoms)
    for atom in vpcoloredmodel.atoms:
        if(atom.vp.type == 'Full-icosahedra'):
            atom.z = 1
        elif(atom.vp.type == 'Icosahedra-like'):
            atom.z = 2
        elif(atom.vp.type == 'Mixed'):
            atom.z = 3
        elif(atom.vp.type == 'Crystal-like'):
            atom.z = 4
        elif(atom.vp.type == 'Undef'):
            atom.z = 5
    #vpcoloredmodel.write_cif('vpcolored.cif')
    #vpcoloredmodel.write_our_xyz('vpcolored.xyz')
    subvpcoloredmodel = Model(submodelfile)
    for atom in subvpcoloredmodel.atoms:
        atom.z = vpcoloredmodel.atoms[ag.model.atoms.index(atom)].z
    subvpcoloredmodel.write_cif('subvpcolored.cif')
    subvpcoloredmodel.write_our_xyz('subvpcolored.xyz')
    return

    golden = False

    #cluster_prefix = 'ico.t3.'
    #cluster_types = 'Icosahedra-like', 'Full-icosahedra' # Need this for final/further analysis

    #cluster_prefix = 'fi.t3.'
    #cluster_types = ['Full-icosahedra'] # Need this for final/further analysis

    cluster_prefix = 'xtal.t3.'
    cluster_types = 'Crystal-like' # Need this for final/further analysis

    #cluster_prefix = 'mix.t3'
    #cluster_types = ['Mixed'] # Need this for final/further analysis

    #cluster_prefix = 'undef.t3'
    #cluster_types = ['Undef'] # Need this for final/further analysis

    # Decide what time of clustering you want to do
    #clusters = ag.get_clusters_with_n_numneighs(cutoff,5,cluster_types) #Vertex
    #clusters = ag.get_vertex_sharing_clusters(cutoff,cluster_types) #Vertex
    #clusters = ag.get_edge_sharing_clusters(cutoff,cluster_types) #Edge
    #clusters = ag.get_face_sharing_clusters(cutoff,cluster_types) #Face
    clusters = ag.get_interpenetrating_atoms(cutoff,cluster_types) #Interpenetrating
    #clusters = ag.get_interpenetrating_clusters_with_neighs(cutoff,cluster_types) #Interpenetrating+neighs
    #clusters = ag.get_connected_clusters_with_neighs(cutoff, cluster_types) #Connected (vertex) + neighs
    #v,e,f,i = ag.vefi_sharing(cluster_types)
    #print("V: {0}  E: {1}  F: {2}  I: {3}".format(int(v),int(e),int(f),int(i)))

    orig_clusters = clusters[:]
    # Print orig clusters
    j = 0
    for i,cluster in enumerate(clusters):
        print("Orig cluster {0} contains {1} atoms.".format(i,len(cluster)))
        if(golden):
            for atom in cluster:
                if(atom.vp.type in cluster_types):
                    atom.z = 0
        # Save cluster files
        cluster_model = Model("Orig cluster {0} contains {1} atoms.".format(i,len(cluster)),model.lx, model.ly, model.lz, cluster)
        cluster_model.write_cif('{1}cluster{0}.cif'.format(i,cluster_prefix))
        cluster_model.write_our_xyz('{1}cluster{0}.xyz'.format(i,cluster_prefix))

    allclusters = []
    for cluster in clusters:
        for atom in cluster:
            if(atom not in allclusters):
                allclusters.append(atom)
                #if(atom.vp.type in cluster_types): print('  {0}\t{1}'.format(atom,atom.vp.type))
    allclusters = Model("All clusters.",model.lx, model.ly, model.lz, allclusters)
    allclusters.write_cif('{0}allclusters.cif'.format(cluster_prefix))
    allclusters.write_our_xyz('{0}allclusters.xyz'.format(cluster_prefix))
    print("{0}allclusters.cif and {0}allclusters.xyz contain {1} atoms.".format(cluster_prefix, allclusters.natoms))

    if(not golden):
        x_cluster = []
        for i,atom in enumerate(model.atoms):
            if atom not in allclusters.atoms:
                x_cluster.append(atom)
        x_cluster = Model("Opposite cluster of {0}".format(cluster_prefix),model.lx, model.ly, model.lz, x_cluster)
        x_cluster.write_cif('{0}opposite.cif'.format(cluster_prefix))
        x_cluster.write_our_xyz('{0}opposite.xyz'.format(cluster_prefix))
        print('{0}opposite.cif and {0}opposite.xyz contain {1} atoms.'.format(cluster_prefix, x_cluster.natoms))
    
    if(False): # Further analysis
        cn = 0.0
        for atom in model.atoms:
            cn += atom.cn
        cn /= model.natoms

        vpcn = 0.0
        count = 0
        for atom in ag.model.atoms:
            if( atom.vp.type in cluster_types ):
                vpcn += atom.cn
                count += 1
        vpcn /= count

        natomsinVPclusters = allclusters.natoms # Number of atoms in VP clusters
        nVPatoms = count # Number of VP atoms
        numsepVPatoms = nVPatoms * vpcn # Number of atoms in VP clusters if all clusters were separated
        maxnumatoms = model.natoms # Max number of atoms in VP clusters if all clusters were separated but still within the model size

        print('Average CN is {0}'.format(cn))
        print('Average CN of VP atoms is {0}'.format(vpcn))
        print('# atoms in all clusters: {0}. # VP atoms * vpcn: {1}. # VP atoms: {2}'.format(natomsinVPclusters,numsepVPatoms,nVPatoms))
        print('~ Number of VP that can fit in the model: {0}'.format(maxnumatoms/vpcn))
        print('Ratio of: (# atoms involved in VP clusters)/(# atoms involved in VP clusters if all clusters were completely separated):                          {0}%  <--- Therefore {1}% sharing.'.format(round(float(natomsinVPclusters)/(numsepVPatoms)*100.0,3),100.0-round(float(natomsinVPclusters)/(numsepVPatoms)*100.0,3)))
        print('Ratio of: (# atoms involved in VP clusters)/(# atoms involved in VP clusters if all clusters were separated as much as possible within the model): {0}%  <--- Therefore {1}% sharing.'.format(round(float(natomsinVPclusters)/min(numsepVPatoms,maxnumatoms)*100.0,3),100.0-round(float(natomsinVPclusters)/min(numsepVPatoms,maxnumatoms)*100.0,3) if numsepVPatoms < maxnumatoms else round(float(natomsinVPclusters)/min(numsepVPatoms,maxnumatoms)*100.0,3)))

        vor_instance = Vor()
        vor_instance.runall(modelfile,cutoff)
        index = vor_instance.get_indexes()
        vor_instance.set_atom_vp_indexes(model)
        vp_dict = categorize_vor.load_param_file('/home/jjmaldonis/model_analysis/scripts/categorize_parameters_iso.txt')
        atom_dict = categorize_vor.generate_atom_dict(index,vp_dict)
        categorize_vor.set_atom_vp_types(model,vp_dict)
        # Count the number of common neighbors in each of the VP
        vp_atoms = []
        for atom in model.atoms:
            if(atom.vp.type in cluster_types):
                vp_atoms.append(atom)
        common_neighs = 0.0
        atom_pairs = []
        for atomi in vp_atoms:
            for atomj in vp_atoms:
                if(atomi != atomj):
                    if(atomi in atomj.neighs and [atomi,atomj] not in atom_pairs and [atomj,atomi] not in atom_pairs):
                        common_neighs += 1
                        atom_pairs.append([atomi,atomj])
                    #if(atomj in atomi.neighs): common_neighs += 0.5
                    for n in atomi.neighs:
                        if(n in atomj.neighs and [n,atomj] not in atom_pairs and [atomj,n] not in atom_pairs):
                            common_neighs += 1
                            atom_pairs.append([n,atomj])
                    #for n in atomj.neighs:
                    #    if(n in atomi.neighs): common_neighs += 0.5
        # Now common_neighs is the number of shared atoms
        #print(common_neighs)
        print('Percent shared based on common neighsbors: {0}'.format(100.0*common_neighs/natomsinVPclusters))
def main():
    modelfile = sys.argv[1]
    keys = [(40,40),(29,29),(13,13),(40,29),(40,13),(29,13)]
    cuttol = 0.2
    cutdelta = 0.1
    cutoff = {}
    cutoff[(40,40)] = 3.8
    cutoff[(13,29)] = 3.5
    cutoff[(29,13)] = 3.5
    cutoff[(40,13)] = 3.7
    cutoff[(13,40)] = 3.7
    cutoff[(29,40)] = 3.5
    cutoff[(40,29)] = 3.5
    cutoff[(13,13)] = 3.5
    cutoff[(29,29)] = 3.5

    models = []
    num = 1
    #print("Number of runs: {0}".format((cuttol/cutdelta*2) * len(keys)+1))
    #models.append(fortran_voronoi_3d(modelfile,cutoff))
    print("Running {0} of {1}".format(num,(cuttol/cutdelta*2) * len(keys)+1))
    m = Model(modelfile)
    voronoi_3d(m,cutoff)
    models.append(m)
    for key in keys:
        for deltacut in drange(-cuttol,cuttol+cutdelta,cutdelta):
        #for deltacut in drange(0,cuttol+cutdelta,cutdelta):
            if(deltacut == 0):
                continue
            num += 1
            print("Running {0} of {1}".format(num,(cuttol/cutdelta*2) * len(keys)+1))
            #if(num > 2): break
            #print(key,deltacut)
            cutoff2 = copy.deepcopy(cutoff)
            cutoff2[key] += deltacut
            if(key != key[::-1]):
                cutoff2[key[::-1]] += deltacut
            #print(cutoff2)
            #models.append(fortran_voronoi_3d(modelfile,cutoff2))
            m = Model(modelfile)
            voronoi_3d(m,cutoff2)
            models.append(m)

    print("Got {0} models.".format(len(models)))
    index_in_models = [count_number_of_indexes_in_model(m) for m in models]
    #for item,key in index_in_models[1].items():
    #    print("{0}: {1}".format(item,key))
    models_containing_index = {}
    for d in index_in_models: # Go thru each model
        for index in d: # if the index was in the model, increment
            models_containing_index[index] = models_containing_index.get(index,0) + 1
    #index_in_models = sum_dicts(index_in_models)
    dict = {}
    dict2 = {}
    for i,modeli in enumerate(models):
        #for j,modelj in enumerate(models[i+1:]):
        #for j,modelj in enumerate(models[1:]):
        for j,modelj in enumerate(models):
            #realj = i+1+j
            if(i != j):
                td = compare_models_vp_indexes(modeli,modelj)
                for key in td:
                    #print(key, td[key], index_in_models[i][key[0]])
                    #if(key[0] == (1, 2, 6, 5, 1, 0, 0, 0)):
                        #print("The transition {0} to {1} took place {2} times. There were {3} {0} indexes in the model and {4} {1} indexes.".format(key[0],key[1],td[key],index_in_models[i][key[0]], index_in_models[i].get(key[1],0)))
                        #print("Added {1} to index {0}".format(key, td[key]/index_in_models[i][key[0]]))
                        #print(dict.get(key,0.0),td[key]/index_in_models[i][key[0]])
                    try:
                        #dict[key] = dict.get(key,0.0) + td[key]/(index_in_models[i][key[0]]-td.get((key[0],key[0]),0))
                        dict[key] = dict.get(key,0.0) + td[key]/index_in_models[i][key[0]]
                    except ZeroDivisionError:
                        dict[key] = dict.get(key,0.0) + 0
                    dict2[key] = dict2.get(key,0.0) + td[key]
    
    #for key in index_in_models:
    #    print("{0}: {1}".format(index_in_models[key],key))
    #for key in dict:
        #print(key)
        #print(key[0])
        #dict[key] /= float(index_in_models[key[0]])

    for key in dict:
        dict[key] /= (models_containing_index[key[0]]*(len(models)-1))

    transitions_of_type = {}
    for key in dict2:
        transitions_of_type[key[0]] = transitions_of_type.get(key[0],0) + dict2[key]

    #double = True
    #while(double == True):
    #    for key in dict:
    #        if(key[::-1] in dict and key != key[::-1]):
    #            dict[key] += dict[key[::-1]]
    #            del dict[key[::-1]]
    #            break
    #    else:
    #        double = False

    dict3 = {}
    for key in dict:
        #print("There were {0} {1} -> {2} transitions which composes {3}% of the non-identity {1} transitions.".format(dict2[key]-dict2.get((key[0],key[0]),0),key[0],key[1],round(100.0*dict2[key]/indexes_in_dict[key[0]],1)))
        if(key[0] != key[1]):
            dict3[key] = dict2[key]/( transitions_of_type[key[0]]-dict2.get((key[0],key[0]),0))
            #if( 100.0*dict2[key]/( transitions_of_type[key[0]]-dict2.get((key[0],key[0]),0)) > 10 and dict2[key] > 50):
                #print("There were {0} {1} -> {2} transitions which composes {3}% of the non-identity {1} transitions.".format(dict2[key],key[0],key[1], 100.0*dict2[key]/( transitions_of_type[key[0]]-dict2.get((key[0],key[0]),0) )))

                #print("{3}%: {1} -> {2} totaled {0}".format(dict2[key],key[0],key[1], round(100.0*dict2[key]/( transitions_of_type[key[0]]-dict2.get((key[0],key[0]),0)),2) ))

        else:
            #dict3[key] = dict[key]
            dict3[key] = 0
            #print("There were {0} {1} -> {2} transitions which composes {3}% of the {1} transitions.".format(dict2[key],key[0],key[1],round(dict[key]*100.0)))

    lookup,mat = create_matrix_from_dict(dict3)
    G = create_graph_from_dict(dict3)

    keys = dict3.keys()
    indexes = []
    for key in keys:
        if(key[0] not in indexes):
            indexes.append(key[0])
        if(key[1] not in indexes):
            indexes.append(key[1])
    nelems = len(indexes)
    for ind in indexes:
        try:
            path = nx.dijkstra_path(G,ind,(0, 0, 12, 0, 0, 0, 0, 0))
            print("Shortest path from {0} to FI:".format(ind))
            print(path)
            print("Length = {0}".format(path_length(path,dict3)))
        except:
            pass
        try:
            path = nx.dijkstra_path(G,(0, 0, 12, 0, 0, 0, 0, 0),ind)
            print("Shortest path from FI to {0}:".format(ind))
            print(path)
            print("Length = {0}".format(path_length(path,dict3)))
        except:
            pass
        try:
            path = nx.dijkstra_path(G,ind,(0, 6, 0, 8, 0, 0, 0, 0))
            print("Shortest path from {0} to BCC:".format(ind))
            print(path)
            print("Length = {0}".format(path_length(path,dict3)))
        except:
            pass
        try:
            path = nx.dijkstra_path(G,(0, 6, 0, 8, 0, 0, 0, 0),ind)
            print("Shortest path from BCC to {0}:".format(ind))
            print(path)
            print("Length = {0}".format(path_length(path,dict3)))
        except:
            pass
        print('')

    print("Shortest path from BCC to FI:")
    path = nx.dijkstra_path(G,(0, 6, 0, 8, 0, 0, 0, 0), (0, 0, 12, 0, 0, 0, 0, 0))
    print(path)
    print("Length = {0}".format(path_length(path,dict3)))

    print("Shortest path from HCP to FI:")
    print(path)
    path = nx.dijkstra_path(G,(0, 6, 0, 2, 0, 0, 0, 0), (0, 0, 12, 0, 0, 0, 0, 0))
    print("Length = {0}".format(path_length(path,dict3)))