Ejemplo n.º 1
0
def create_wrapper_mol_from_atoms_and_bonds(species,
                                            coords,
                                            bonds,
                                            charge=0,
                                            free_energy=None,
                                            identifier=None):
    """
    Create a :class:`MoleculeWrapper` from atoms and bonds.

    Args:
        species (list of str): atom species str
        coords (2D array): positions of atoms
        bonds (list of tuple): each tuple is a bond (atom indices)
        charge (int): chare of the molecule
        free_energy (float): free energy of the molecule
        identifier (str): (unique) identifier of the molecule

    Returns:
        MoleculeWrapper instance
    """

    pymatgen_mol = pymatgen.Molecule(species, coords, charge)
    bonds = {tuple(sorted(b)): None for b in bonds}
    mol_graph = MoleculeGraph.with_edges(pymatgen_mol, bonds)

    return MoleculeWrapper(mol_graph, free_energy, identifier)
Ejemplo n.º 2
0
def readStructures(sfile, central, ligand, radius=3.):
    """
    Read structure from file sfile and look for environments of all central
    atoms in the structure. Only neighbors of type ligand are taken into
    account.

    Returns a list of mg.Molecule in which the first atom is the central atom
    and the following atoms are the neighbors of type ligand of this central
    atom.
    """

    struct = mg.Structure.from_file(sfile)
    central_sites = [
        site for site in struct if site.specie == mg.Element(central)
    ]

    envs = list()

    print("Identified sites:")
    for site in central_sites:

        mol = mg.Molecule([site.specie], [site.coords])

        neighbors = struct.get_neighbors(site, radius)

        for neighbor, d in neighbors:
            if neighbor.specie == mg.Element(ligand):
                mol.append(neighbor.specie, neighbor.coords)

        envs.append(mol)
        print("%2s[%2d] : #ligand = %d (%s)" %
              (site.specie, struct.index(site), len(mol[1:]), " ".join(
                  [at.specie.symbol for at in mol[1:]])))

    return envs
Ejemplo n.º 3
0
def write_gau_input(species, coords, iframe, jobname="run_gau", **kwargs):
    """ write a gaussian input file """

    path = kwargs["path"]
    functional = kwargs["functional"]
    basis_set = kwargs["basis_set"]
    nprocs = kwargs["nprocs"]

    # get first letter of atom name => element
    species = [specie[0] for specie in species]

    # convert nm to angstrom
    coords = np.array(coords) * 10

    # build Molecule and Gaussian object
    mol = mg.Molecule(species, coords, validate_proximity=True)
    ginp = GaussianInput(
        mol,
        charge=0,
        title="Written by gro2qm - snapshot %d" % iframe,
        functional=functional, basis_set=basis_set,
        route_parameters={"pop": "(MK, MBS)"},
        link0_parameters={"%nprocs": nprocs},
        dieze_tag="#"
    )

    basename = "gau_%05d" % iframe
    ginp.write_file(os.path.join(path, basename + ".com"), cart_coords=True)
    mol.to(fmt="xyz", filename=os.path.join(path, basename + ".xyz"))

    return "sbatch -J snap_%05d %s %s.com" % (iframe, jobname, basename)
Ejemplo n.º 4
0
def cif_to_charged_cluster_within_radius(file, bondmap, radius, centeratom=False, supercell=None, oxid='guess', clobber=False):
    '''Heads up, supercell needs to be large enough to cover the radius requested'''
    assert file[-4:] == '.cif', 'Only works with cif files'
    if oxid == 'guess':
        mol = make_molecular_cluster_from_cif(file, supercell=supercell, guessoxid=True)
    else:
        mol = make_molecular_cluster_from_cif(file, supercell=supercell, guessoxid=False)
        mol.add_oxidation_state_by_element(oxid)
    
    center_cluster_on_atom(mol, centeratom)
    sites = mol.get_sites_in_sphere([0, 0, 0], radius)
    mol = mg.Molecule([s[0].species_string for s in sites], [s[0].coords for s in sites])
    assign_nearest_neighbors(mol)
    
    missing = calculate_missing_bonds(mol, bondmap)
    charge, bondcharges = calculate_charge_for_cluster(missing, bondmap)
    
        
    
    outfilename = file[:-4]+'.xyz'
    
    if not clobber:
        assert not os.path.exists(outfilename), 'Output file with name {} already exists!'.format(outfilename)

    mol.add_oxidation_state_by_element(dict.fromkeys(mol.symbol_set))
    mol.to('xyz', outfilename)

    with open(outfilename, 'r+') as file:
        lines = file.readlines()
        lines[1] = '{}; charge for DFT cluster calculation: {}; based on bondchargemap: {};\n'.format(lines[1][:-1], charge, bondcharges)
        file.seek(0)
        file.writelines(lines)

    dumb_rename_center_atom(outfilename, mol)
Ejemplo n.º 5
0
def make_molecular_cluster_from_cif(file, supercell=None, guessoxid=False):
    structure = mg.Structure.from_file(file)
    if guessoxid:
        structure.add_oxidation_state_by_guess()
    if supercell is not None:
        structure.make_supercell(supercell)
        
    molecule = mg.Molecule(structure.species, structure.cart_coords)
    return molecule
Ejemplo n.º 6
0
def get_pointgroup(atoms: ase.Atoms) -> str:
    """
    uses pymatgen.symmetry.analyzer
	"""
    atoms.center()
    symbs = atoms.get_chemical_symbols()
    pos = atoms.get_positions()
    mol = pmg.Molecule(symbs, pos)
    return pysym.PointGroupAnalyzer(mol).sch_symbol
Ejemplo n.º 7
0
def getPointgroup(kind, storagepath):
    if kind != 'molecule': return None
    import pymatgen
    import pymatgen.io.ase as pmgase
    import pymatgen.symmetry.analyzer as psa
    atoms = getAtoms(storagepath)
    cm = atoms.get_center_of_mass()
    m = pymatgen.Molecule(atoms.get_chemical_symbols(),
                          atoms.get_positions() - cm)
    return psa.PointGroupAnalyzer(m).sch_symbol
Ejemplo n.º 8
0
    def symmetry_information(self):
        """
        Returns symmetry information of the molecule as for example its point group

        :return info: a dictionary with symmetry informations
        """
        mol = mg.Molecule(self.atoms[:, 3], self.atoms[:, :3])
        analyzer = PointGroupAnalyzer(mol)
        info = {'point group': analyzer.get_pointgroup()}
        return info
Ejemplo n.º 9
0
def getPointgroup(kind,inittraj): 
	if kind == 'molecule':
		atoms 	= pickle.loads(inittraj)
		cm 		= atoms.get_center_of_mass()
		m 		= pymatgen.Molecule(atoms.get_chemical_symbols(),atoms.get_positions()-cm)
		try:
			return psa.PointGroupAnalyzer(m).sch_symbol
		except ValueError:
			viz.view(atoms)
			sys.exit()
	else: return None
Ejemplo n.º 10
0
def make_constrain_ordered_xyz(file, neighbor0='P', neighbor1='H'):
    mol = mg.Molecule.from_file(file)
    assign_nearest_neighbors(mol)

    edge = mg.Molecule(['Zr'], [[0,0,0]]) #dummy Zr to let me instantiate the molecule
    edge.pop(0) #discard dummy

    poplist = []
    for i, site in enumerate(mol):
        if site.specie.name == neighbor0:
            for n in site.nearests:
                if n.specie.name == neighbor1:
                    poplist.append(i)
                    edge.append(site.specie, site.coords)
                    continue
    mol.remove_sites(poplist)

    poplist = []
    for i, site in enumerate(mol):
        if site.specie.name == neighbor1:
            for n in site.nearests:
                if n.specie.name == neighbor0:
                    poplist.append(i)
                    edge.append(site.specie, site.coords)
                    continue
    mol.remove_sites(poplist)

    filename = file.split('.xyz')[0].split('/')[-1] #oops only works on linux...
#     unconstrainf = '{}_Unconstrain.xyz'.format(filename)
#     mol.to('xyz', unconstrainf)
#     constrainf = '{}_Constrain.xyz'.format(filename)
#     edge.to('xyz', constrainf)

#     unca, uncc = read_xyz(unconstrainf)
#     ca, cc = read_xyz(constrainf)

    unca, uncc = mol.species, mol.cart_coords
    ca, cc = edge.species, edge.cart_coords

    print('Saving new file as: {}'.format('{}_Reordered'.format(filename)))
    write_xyz_from_atoms_coords('{}_Reordered'.format(filename), 
                                atoms=unca + ca, 
                                coords=np.concatenate([uncc, cc]), 
                                comment='Unconstrained {}; Constrained {}; Fix atoms {}:{}'.format(
                                    len(unca),
                                    len(ca),
                                    len(unca) + 1,
                                    len(unca) + len(ca)
                                ))
Ejemplo n.º 11
0
def mol_Oh(central, ligand, scale):
    """ 
    Return a perfect octahedra as a mg.Molecule object.

    Args:
        central: (string) Name of the central atom
        ligand: (string) Name of ligand atoms
        scale: (float) length of central-ligand distance

    Returns
        mg.Molecule object
    """
    species = [mg.Element(central)] + 6 * [mg.Element(ligand)]
    template = [[0., 0., 0.], [1., 0., 0.], [-1., 0., 0.], [0., 1., 0.],
                [0., -1., 0.], [0., 0., 1.], [0., 0., -1.]]
    coords = [[scale * xi for xi in coord] for coord in template]
    return mg.Molecule(species, coords)
Ejemplo n.º 12
0
    def boxed_molecule(cls, pseudos, cart_coords, acell=3 * (10, )):
        """
        Creates a molecule in a periodic box of lengths acell [Bohr]

        Args:
            pseudos: List of pseudopotentials
            cart_coords: Cartesian coordinates
            acell: Lengths of the box in *Bohr*
        """
        cart_coords = np.atleast_2d(cart_coords)

        molecule = pymatgen.Molecule([p.symbol for p in pseudos], cart_coords)

        l = ArrayWithUnit(acell, "bohr").to("ang")

        structure = molecule.get_boxed_structure(l[0], l[1], l[2])

        return cls(structure)
Ejemplo n.º 13
0
def rdkit_mol_to_wrapper_mol(m,
                             charge=None,
                             free_energy=None,
                             identifier=None):
    """
    Convert an rdkit molecule to a :class:`MoleculeWrapper` molecule.

    This constructs a molecule graph from the rdkit mol and assigns the rdkit mol
    to the molecule wrapper.

    Args:
        m (Chem.Mol): rdkit molecule
        charge (int): charge of the molecule. If None, inferred from the rdkit mol;
            otherwise, the provided charge will override the inferred.
        free_energy (float): free energy of the molecule
        identifier (str): (unique) identifier of the molecule

    Returns:
        MoleculeWrapper instance
    """

    species = [a.GetSymbol() for a in m.GetAtoms()]

    # coords = m.GetConformer().GetPositions()
    # NOTE, the above way to get coords results in segfault on linux, so we use the
    # below workaround
    conformer = m.GetConformer()
    coords = [[x for x in conformer.GetAtomPosition(i)]
              for i in range(m.GetNumAtoms())]

    bonds = [[b.GetBeginAtomIdx(), b.GetEndAtomIdx()] for b in m.GetBonds()]
    bonds = {tuple(sorted(b)): None for b in bonds}

    charge = Chem.GetFormalCharge(m) if charge is None else charge

    pymatgen_mol = pymatgen.Molecule(species, coords, charge)
    mol_graph = MoleculeGraph.with_edges(pymatgen_mol, bonds)

    if identifier is None:
        identifier = m.GetProp("_Name")
    mw = MoleculeWrapper(mol_graph, free_energy, identifier)
    mw.rdkit_mol = m

    return mw
Ejemplo n.º 14
0
def mol_D4h(central, ligand, d1, d2):
    """ 
    Return a D4h molecule as a mg.Molecule object.

    Args:
        central: (string) Name of the central atom
        ligand: (string) Name of ligand atoms
        d1: (float) length of central-ligand axial distance
        d2: (float) length of central-ligand equatorial distance

    Returns
        mg.Molecule object
    """
    species = [mg.Element(central)] + 6 * [mg.Element(ligand)]
    template = [[0., 0., 0.], [1., 0., 0.], [-1., 0., 0.], [0., 1., 0.],
                [0., -1., 0.], [0., 0., 1.], [0., 0., -1.]]
    coords = [template[0]] \
           + [[d1 * xi for xi in coord] for coord in template[1:5]] \
           + [[d2 * xi for xi in coord] for coord in template[5:]]
    return mg.Molecule(species, coords)
Ejemplo n.º 15
0
def getSymmetry(ids, xyz):
    mol = PointGroupAnalyzer(mg.Molecule(ids, xyz))
    return mol.sch_symbol
Ejemplo n.º 16
0
def make_hydrogen_capped_cluster_from_cif_3(outfilename, ciffile, numnearest, cappingdistances, bqchargemap, centeratom, sphereradius=6, supercell=6, bondlengthcutoff=2.5):
    '''Make hydrogen-capped cluster.

    Note: 3 means that this version is trying to accommodate inequivalent sites
    
    Supercell needs to be big enough that all atoms in sphere and neighbors thereof
    have full neighbors.'''
    print('Importing structure')
    struct = mg.Structure.from_file(ciffile)
    struct.make_supercell(supercell)
    # mol = mg.Molecule(struct.species, struct.cart_coords)
    mol = tag_sites_by_equivalency(struct)
    center_cluster_on_atom(mol, centeratom) # fixed 3.23.19 to add centeratom arg
    remove_oxidation_state_from_species(mol)

    print('Finding site inside/outside sphere.')
    innersites = mol.get_sites_in_sphere([0, 0, 0], sphereradius)
    inner = mg.Molecule.from_sites([s[0] for s in innersites])

    neighboringmol = mg.Molecule([], [])
    for isite in inner:
        print('Checking neighbors of site {}'.format(mol.index(isite)), end='\r')
        neighbors = mol.get_neighbors(isite, bondlengthcutoff)
        for s, _ in neighbors:
            if s not in inner:  

                if s not in neighboringmol:
                    neighboringmol.append(s.specie, s.coords)

                try:
                    neighboringmol[neighboringmol.index(s)].innerneighbors.append(isite)
                except AttributeError:
                    neighboringmol[neighboringmol.index(s)].innerneighbors = [isite]

    hydrcoords = []
    hydrneighbors = []
    hydrreplace = []
    for ns in neighboringmol:
        for n in ns.innerneighbors:
            hydrcoords.append(np.mean([ns.coords, n.coords], axis=0)) # create hydrogen halfway along bond
            hydrneighbors.append(n) # keep track of neighbor identity
            hydrreplace.append(ns) # keep track of identitiy of atom being replaced

    hydrsites = [mg.Site('H', c) for c in hydrcoords]
    hydr = mg.Molecule.from_sites(hydrsites)

    # add hydrogen neighbors and adjust bond lengths accordingly
    for hs, hn, hr in zip(hydrsites, hydrneighbors, hydrreplace):
        hydr[hydr.index(hs)].innerneighbor = hn
        hydr[hydr.index(hs)].replacing = hr
    for s in hydr:
        adjust_bond_length(s, s.innerneighbor, cappingdistances[str(s.innerneighbor.specie)])

    capped = mg.Molecule.from_sites(hydr.sites + inner.sites)
    print('Writing capped cluster file: ', '{}.xyz'.format(outfilename))
    capped.to('xyz', '{}.xyz'.format(outfilename))

    print('Writing bq charge file: ', '{}.bq'.format(outfilename))
    totalbqcharge = 0
    with open('{}.bq'.format(outfilename), 'w') as file:
        for s in hydr:
            file.write('Bq {:>15.8f}{:>15.8f}{:>15.8f}{:>10.4f}\n'.format(
                *s.coords, bqchargemap[str(s.replacing.specie)][str(s.innerneighbor.specie)]))
            totalbqcharge += bqchargemap[str(s.replacing.specie)][str(s.innerneighbor.specie)]

    with open('{}.xyz'.format(outfilename), 'r') as file:
        oldlines = file.readlines()

    oldlines[1] = oldlines[1].strip() + '; Total bqcharge for capped cluster: {}\n'.format(totalbqcharge)
    with open('{}.xyz'.format(outfilename), 'w') as file:
        for line in oldlines:
            file.write(line)

    slightly_less_dumb_rename_center_atom('{}.xyz'.format(outfilename))
Ejemplo n.º 17
0
def make_hydrogen_capped_cluster_from_cif_old_logic(outfilename, ciffile, numnearest, cappingdistances, bqchargemap, centeratom, sphereradius=6, supercell=6):
    '''Make hydrogen-capped cluster.
    
    Supercell needs to be big enough that all atoms in sphere and neighbors thereof
    have full neighbors.'''
    print('Importing structure')
    struct = mg.Structure.from_file(ciffile)
    struct.make_supercell(6)
    mol = mg.Molecule(struct.species, struct.cart_coords)
    center_cluster_on_atom(mol, centeratom) # fixed 3.23.19 to add centeratom arg

    print('Finding site inside/outside sphere.')
    innersites = mol.get_sites_in_sphere([0, 0, 0], sphereradius)
    inner = mg.Molecule.from_sites([s[0] for s in innersites])
    SHELLDIST = 4
    outersites = mol.get_neighbors_in_shell([0, 0, 0], sphereradius + SHELLDIST / 2, SHELLDIST / 2)

    outersiteindices = []
    for site, _ in outersites:
        outersiteindices.append(mol.index(site))
    neighboringsites = []
    for osi in outersiteindices:
        print('Checking neighbors of site {}'.format(osi), end='\r')
        neighbors = get_nearest_sites_by_num_neighbors(mol, mol[osi], numnearest)
        for s, _ in neighbors:
            if s in inner:            
                try:
                    mol[osi].innerneighbors.append(s)
                except AttributeError:
                    mol[osi].innerneighbors = [s]

                if osi not in neighboringsites:
                    neighboringsites.append(osi)

    hydrcoords = []
    hydrneighbors = []
    hydrreplace = []
    for ns in neighboringsites:
        ocoords = mol[ns].coords
        for n in mol[ns].innerneighbors:
            hydrcoords.append(np.mean([ocoords, n.coords], axis=0))
            hydrneighbors.append(n)
            hydrreplace.append(mol[ns])

    hydrsites = [mg.Site('H', c) for c in hydrcoords]
    hydr = mg.Molecule.from_sites(hydrsites)

    # add hydrogen neighbors and adjust bond lengths accordingly
    for hs, hn, hr in zip(hydrsites, hydrneighbors, hydrreplace):
        hydr[hydr.index(hs)].innerneighbor = hn
        hydr[hydr.index(hs)].replacing = hr
    for s in hydr:
        adjust_bond_length(s, s.innerneighbor, cappingdistances[str(s.innerneighbor.specie)])

    capped = mg.Molecule.from_sites(hydr.sites + inner.sites)
    print('Writing capped cluster file: ', '{}.xyz'.format(outfilename))
    capped.to('xyz', '{}.xyz'.format(outfilename))
    print('Writing bq charge file: ', '{}.bq'.format(outfilename))
    with open('{}.bq'.format(outfilename), 'w') as file:
        for s in hydr:
            file.write('Bq {:>15.8f}{:>15.8f}{:>15.8f}{:>10.4f}\n'.format(
                *s.coords, bqchargemap[str(s.replacing.specie)]))