Example #1
0
def readXYZ(xyz, bonds=None):
    # extract molecule information from xyz
    mol = next(pb.readfile('xyz', xyz))
    # Manually give bond information
    # (Because in metal system the bond information detect by openbabel usually have some problem)
    m = Molecule(pb.ob.OBMol())
    obmol = m.OBMol
    obmol.BeginModify()
    for atom in mol:
        coords = [coord for coord in atom.coords]
        atomno = atom.atomicnum
        obatom = ob.OBAtom()
        obatom.thisown = 0
        obatom.SetAtomicNum(atomno)
        obatom.SetVector(*coords)
        obmol.AddAtom(obatom)
        del obatom

    bonds = [(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(),
              bond.GetBondOrder()) for bond in pb.ob.OBMolBondIter(mol.OBMol)]
    bonds.extend([(12, 14, 1), (12, 15, 1), (12, 16, 1), (12, 17, 1),
                  (12, 13, 1), (17, 23, 1), (16, 23, 1)])

    for bond in bonds:
        obmol.AddBond(bond[0], bond[1], bond[2])

    # obmol.PerceiveBondOrders()
    # obmol.SetTotalCharge(int(mol.charge))
    # obmol.Center()
    obmol.EndModify()
    mol_obj = gen3D.Molecule(obmol)
    return mol_obj
def xyz_to_pyMol(xyz, cluster_bond_path=None):
    mol = next(pybel.readfile('xyz', xyz))
    if cluster_bond_path:
        m = pybel.ob.OBMol()
        m.BeginModify()
        for atom in mol:
            coords = [coord for coord in atom.coords]
            atomno = atom.atomicnum
            obatom = ob.OBAtom()
            obatom.thisown = 0
            obatom.SetAtomicNum(atomno)
            obatom.SetVector(*coords)
            m.AddAtom(obatom)
            del obatom

        with open(cluster_bond_path, 'r') as f:
            lines = f.read()
        cluster_bond = eval(lines)
        bonds = [(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(),
                  bond.GetBondOrder())
                 for bond in pybel.ob.OBMolBondIter(mol.OBMol)]
        bonds.extend(cluster_bond)
        for bond in bonds:
            m.AddBond(bond[0], bond[1], bond[2])
        pybelmol = pybel.Molecule(m)
        return pybelmol
    else:
        return mol
def readXYZ(xyz, bonds=None, cluster_bond=None, fixed_atoms=None):
    # extract molecule information from xyz
    mol = next(pb.readfile('xyz', xyz))
    reactant_atom = [a.OBAtom.GetAtomicNum() for a in mol]
    # Manually give bond information
    # (Because in metal system the bond information detect by openbabel usually have some problem)
    if bonds or cluster_bond:
        m = Molecule(pb.ob.OBMol())
        obmol = m.OBMol

        obmol.BeginModify()
        for atom in mol:
            coords = [coord for coord in atom.coords]
            atomno = atom.atomicnum
            obatom = ob.OBAtom()
            obatom.thisown = 0
            obatom.SetAtomicNum(atomno)
            obatom.SetVector(*coords)
            obmol.AddAtom(obatom)
            del obatom

        if cluster_bond:
            bonds = [(bond.GetBeginAtomIdx(), bond.GetEndAtomIdx(),
                      bond.GetBondOrder())
                     for bond in pb.ob.OBMolBondIter(mol.OBMol)]
            #bonds = imaginary_bond(bonds, reactant_atom, fixed_atoms)
            bonds.extend(cluster_bond)

        for bond in bonds:
            obmol.AddBond(bond[0], bond[1], bond[2])

        # obmol.ConnectTheDots()
        obmol.PerceiveBondOrders()
        # obmol.SetTotalSpinMultiplicity(1)
        obmol.SetTotalCharge(int(mol.charge))
        obmol.Center()
        obmol.EndModify()

        mol_obj = gen3D.Molecule(obmol)

        reactant_graph = Species(xyz_file_to_atoms(xyz))
        reactant_bonds = [(i[0] - 1, i[1] - 1) for i in bonds]
        make_graph(reactant_graph, bond_list=reactant_bonds)
    else:
        mol_obj = gen3D.Molecule(mol.OBMol)
        reactant_graph = Species(xyz_file_to_atoms(xyz))
        reactant_bonds = tuple(
            sorted([(bond.GetBeginAtomIdx() - 1, bond.GetEndAtomIdx() - 1)
                    for bond in pb.ob.OBMolBondIter(mol.OBMol)]))
        make_graph(reactant_graph, bond_list=reactant_bonds)
    return mol_obj, reactant_graph
Example #4
0
 def generate_inter_lp(init_str: pybel.Molecule, end_str: pybel.Molecule, inter: int):
     int_list = [pybel.Molecule(ob.OBMol()) for i in range(inter)]
     for i, j in zip(init_str.atoms, end_str.atoms):
         # define the vector for propagation
         i_coord = np.array(i.coords)
         j_coord = np.array(j.coords)
         coord_vector = (j_coord - i_coord) / (inter + 1)
         for k in range(inter):
             # define the atomic position for k-th intermediate and write to OBmol object
             atom_position = i_coord + coord_vector * (k + 1)
             newatom = ob.OBAtom()
             newatom.SetAtomicNum(i.OBAtom.GetAtomicNum())
             newatom.SetVector(atom_position[0], atom_position[1], atom_position[2])
             int_list[k].OBMol.AddAtom(newatom)
     return int_list
Example #5
0
        def add_atom(self, _atom):
            """ Adds an atom to the molecule

                This method creates OBAtoms based on the atoms so it can use
                the internal functions that openbabel provides through OBMol.

                Note: This will surely break at some point for .pdb files etc.
            """
            if not isinstance(_atom, Atom):
                raise TypeError
            _obatom = openbabel.OBAtom()
            _obatom.SetAtomicNum(_atom.get_nuclear_charge())
            x, y, z = _atom.get_coordinate()
            _obatom.SetVector(x, y, z)
            _obatom.SetId(_atom.get_idx())
            _obatom.SetFormalCharge(_atom.get_formal_charge())
            self._obmol.AddAtom(_obatom)
Example #6
0
def makeopenbabel(atomcoords, atomnos, charge=0, mult=1):
    """Create an Open Babel molecule."""
    _check_openbabel(_found_openbabel)
    obmol = ob.OBMol()
    for i in range(len(atomnos)):
        # Note that list(atomcoords[i]) is not equivalent!!!
        # For now, only take the last geometry.
        # TODO: option to export last geometry or all geometries?
        coords = atomcoords[-1][i].tolist()
        atomno = int(atomnos[i])
        obatom = ob.OBAtom()
        obatom.SetAtomicNum(atomno)
        obatom.SetVector(*coords)
        obmol.AddAtom(obatom)
    obmol.ConnectTheDots()
    obmol.PerceiveBondOrders()
    obmol.SetTotalSpinMultiplicity(mult)
    obmol.SetTotalCharge(int(charge))
    return obmol
Example #7
0
    def find_N_cap(self):
        a1 = ob.OBAtom()
        for atom in ob.OBAtomAtomIter(self.NTerminus):
            if atom.GetAtomicNum() == 6:
                for n_atom in ob.OBAtomAtomIter(atom):
                    if n_atom.GetAtomicNum() == 8 and atom.GetBond(
                            n_atom).GetBondOrder() == 2:
                        self.NTermCap.AddAtom(atom)
                        self.NTermCap.AddAtom(n_atom)
                        a1 = atom

        for atom in ob.OBAtomAtomIter(self.NTerminus):
            if OBAminoAcid.Equals(atom, a1):
                for atom1 in ob.OBAtomAtomIter(atom):
                    if atom1.GetAtomicNum() == 6:
                        self.NTermCap.AddAtom(atom1)
                        for n_atom1 in ob.OBAtomAtomIter(atom1):
                            if not OBAminoAcid.Equals(n_atom1, atom):
                                self.NTermCap.AddAtom(n_atom1)
Example #8
0
    def SulfurHydrogenator(sulfur, mainAtom, mol):

        sulfur_coords = np.array(
            [sulfur.GetX(), sulfur.GetY(),
             sulfur.GetZ()], dtype=float)
        main_atom_coords = np.array(
            [mainAtom.GetX(),
             mainAtom.GetY(),
             mainAtom.GetZ()], dtype=float)

        S = sulfur_coords
        C = main_atom_coords

        V = C - S

        print(S, C, V)

        V = V / np.linalg.norm(V)

        R = np.array([V[1] * V[2], -2 * V[0] * V[2], V[0] * V[1]], dtype=float)

        R = R / np.linalg.norm(R)

        H = R * math.cos(math.radians(2.1)) - V * math.sin(math.radians(2.1))

        print(V, R, H)

        H = S + (1.34 * H)

        print(S, H)

        hydrogen = ob.OBAtom()
        hydrogen.SetAtomicNum(1)

        print(H[0], H[1], H[2])

        hydrogen.SetVector(H[0], H[1], H[2])

        if mol.AddAtom(hydrogen):
            print("Hydrogen Added Successfully to Sulfur")

        return mol
Example #9
0
    def to_obmol(self, explicit_hydrogen: Optional[bool] = True) -> ob.OBMol:
        obmol = ob.OBMol()

        for a in self.atoms:
            obatom = ob.OBAtom()
            obatom.SetAtomicNum(a.Z)
            obatom.SetVector(*a.position.squeeze())
            obmol.AddAtom(obatom)

        obmol.ConnectTheDots()
        obmol.PerceiveBondOrders()

        if not explicit_hydrogen:
            obmol.DeleteHydrogens()
            # NOTE: empirically, this appears to renumber the atoms correctly
            # (i.e. it maintains the original order as specified by self.atoms while
            # removing hydrogens & renumbering sequentially)
            # this is consistent with how to_graph works

        return obmol
Example #10
0
    def __init__(self, mol):
        """
        Initializes with pymatgen Molecule or OpenBabel"s OBMol.

        Args:
            mol: pymatgen's Molecule/IMolecule or OpenBabel OBMol
        """
        if isinstance(mol, IMolecule):
            if not mol.is_ordered:
                raise ValueError(
                    "OpenBabel Molecule only supports ordered molecules.")

            # For some reason, manually adding atoms does not seem to create
            # the correct OBMol representation to do things like force field
            # optimization. So we go through the indirect route of creating
            # an XYZ file and reading in that file.
            obmol = ob.OBMol()
            obmol.BeginModify()
            for site in mol:
                coords = list(site.coords)
                atomno = site.specie.Z
                obatom = ob.OBAtom()
                obatom.thisown = 0
                obatom.SetAtomicNum(atomno)
                obatom.SetVector(*coords)
                obmol.AddAtom(obatom)
                del obatom
            obmol.ConnectTheDots()
            obmol.PerceiveBondOrders()
            obmol.SetTotalSpinMultiplicity(mol.spin_multiplicity)
            obmol.SetTotalCharge(int(mol.charge))
            obmol.Center()
            obmol.EndModify()
            self._obmol = obmol
        elif isinstance(mol, ob.OBMol):
            self._obmol = mol
        elif isinstance(mol, pb.Molecule):
            self._obmol = mol.OBMol
Example #11
0
    def test_building_a_molecule(self):
        mol = ob.OBMol()
        C = add_atom(mol, 6)
        N = add_atom(mol, 7)
        # XXX Why can't I do mol.AddBond(C, N, 3)?
        mol.AddBond(C.GetIdx(), N.GetIdx(), 3)
        self.assertEqual(C.ImplicitHydrogenCount(), 1)
        C.IncrementImplicitValence(
        )  # Is this how to increment the implicit hcount?
        self.assertEqual(C.ImplicitHydrogenCount(), 2)
        conv = ob.OBConversion()
        conv.SetOutFormat("can")
        s = conv.WriteString(mol).strip()
        # XXX How does this work when the ImplicitHydrogenCount is 2?? XXX
        self.assertEqual(s, "C#N")

        # I can even add an atom this way. (Why are there 2 ways?)
        O = ob.OBAtom()
        O.SetAtomicNum(8)
        mol.AddAtom(O)
        O.SetImplicitValence(2)

        s = conv.WriteString(mol).strip()
        self.assertEqual(s, "C#N.O")
Example #12
0
def Hydrogenate(carbon, mainAtom, mol):
    """
    Adds 3 hydrogens to a molecule that will be bonded to a carbon

    carbon: The carbon atom where the 3 hydrogens will be added to
    mainAtom: The other atom the carbon is attached to
    mol: The molecule that will be hydrogenated

    returns: THe hydrogenated molecule
    """

    chbl = 1.09

    bond_length = carbon.GetDistance(mainAtom)

    Ux = mainAtom.GetX() - carbon.GetX()
    Uy = mainAtom.GetY() - carbon.GetY()
    Uz = mainAtom.GetZ() - carbon.GetZ()

    U = np.array([Ux, Uy, Uz])

    V = np.array([Uy * Uz, -2 * Ux * Uz, Ux * Uy])

    U = U / (np.linalg.norm(U))

    V = V / (np.linalg.norm(V))

    ang1 = math.radians(70.5)

    H1 = -U * math.cos(ang1) + V * math.sin(ang1)

    h1 = ob.OBAtom()
    h1.SetAtomicNum(1)
    h1.SetVector(carbon.GetX() + H1[0] * chbl,
                 carbon.GetY() + H1[1] * chbl,
                 carbon.GetZ() + H1[2] * chbl)

    mol.AddAtom(h1)

    Z = -U - H1
    Z = Z / (np.linalg.norm(Z))

    Y = np.cross(U, H1)
    Y = Y / (np.linalg.norm(Y))

    X = np.cross(Y, Z)
    X = X / (np.linalg.norm(X))

    ang2 = math.radians(54.7)

    H2 = Z * math.cos(ang2) + Y * math.sin(ang2)

    h2 = ob.OBAtom()
    h2.SetAtomicNum(1)

    h2.SetVector(carbon.GetX() + H2[0] * chbl,
                 carbon.GetY() + H2[1] * chbl,
                 carbon.GetZ() + H2[2] * chbl)

    if mol.AddAtom(h2):
        print("Success adding H2")

    H3 = -(H1 + H2 + U)
    H3 = H3 / (np.linalg.norm(H3))

    h3 = ob.OBAtom()
    h3.SetAtomicNum(1)

    h3.SetVector(carbon.GetX() + H3[0] * chbl,
                 carbon.GetY() + H3[1] * chbl,
                 carbon.GetZ() + H3[2] * chbl)

    if mol.AddAtom(h3):
        print("Success adding H3")

    return mol