Beispiel #1
0
    def read_new_type(self):
        """
        Routine for reading a file type not contained in open babel.
        """
        infile = open(self.file_path, 'r')
        line = infile.readline()

        if self.file_type == 'txyz2':  # Tinker format preserving all information
            self.tinker_symbs = []
            self.tinker_extra = []
            num_at_chk = int(line.split()[0])
            line = infile.readline()
            while (line != ''):
                words = line.split()
                if len(words) == 0:
                    break
                obatom = openbabel.OBAtom()
                self.tinker_symbs.append(words[1])
                lett1 = words[1][0]
                if words[1] in symbol_Z_dict:
                    at_num = symbol_Z_dict[words[1]]
                elif words[1][0] in symbol_Z_dict:
                    at_num = symbol_Z_dict[words[1][0]]
                else:
                    at_num = 99
                obatom.SetAtomicNum(at_num)

                coords = [float(word) for word in words[2:5]]
                obatom.SetVector(*coords)
                self.tinker_extra.append(words[5:])
                # maybe one could use SetSymbol here

                self.mol.AddAtom(obatom)
                line = infile.readline()

            #print self.mol.NumAtoms()
            assert (num_at_chk == self.mol.NumAtoms())
        elif self.file_type == 'col' or self.file_type == 'nx':
            while (line != ''):
                words = line.split()
                obatom = openbabel.OBAtom()
                obatom.SetAtomicNum(int(float(words[1])))
                coords = [
                    float(word) * units.length['A'] for word in words[2:5]
                ]
                obatom.SetVector(*coords)

                self.mol.AddAtom(obatom)
                line = infile.readline()
        else:
            print('type %s not supported for input' % self.file_type)
            exit(1)

        infile.close()
Beispiel #2
0
def exchangeAtom(C, H, molTS, molFG, outfile, bondLength):
    # read write xyz file
    convTS, convFG = [ob.OBConversion() for i in range(2)]
    convTS.SetInAndOutFormats("xyz", "xyz")
    convFG.SetInAndOutFormats("xyz", "xyz")

    # builder
    builder = ob.OBBuilder()

    # define molecules, atoms and bond classes
    TS, FG = [ob.OBMol() for i in range(2)]
    atomH = ob.OBAtom()
    atomC = ob.OBAtom()
    bond = ob.OBBond()

    # read in xyz files
    convTS.ReadFile(TS, molTS)
    convFG.ReadFile(FG, molFG)

    # number of atoms in TS molecule
    numAtoms = TS.NumAtoms()

    # get hydrogen atom and its vector
    atomH = TS.GetAtom(H)
    atomC = TS.GetAtom(C)
    vec = ob.vector3(float(atomH.GetX()), float(atomH.GetY()),
                     float(atomH.GetZ()))

    # delete hydrogen atom
    TS.DeleteAtom(atomH)

    # put both molecules together (same coord system)
    TS += FG

    # making the bond
    builder.Connect(TS, C, numAtoms, vec, 1)

    bond = TS.GetBond(C, numAtoms)
    bond.SetLength(atomC, bondLength)

    # call opimizer
    #opt_mmff_FG(TS, numAtoms, outfile)

    convTS.WriteFile(TS, "single/" + outfile)

    # clear TS and FG molecule classes
    TS.Clear()
    FG.Clear()
Beispiel #3
0
def get_zmatrix_template(parser):
    """Make a zmatrix from the original geometry.

    Parameters
    ----------
    parser : object
        Parser object from vetee.

    Returns
    -------
    zmatrix : str
        The zmatrix (gzmat format) for the parser
        molecule. Will be used to combine with
        dihedral angles.

    """
    # from vetee
    obmol = openbabel.OBMol()
    # add coordinates for each atom
    for atom in parser.coords:
        obatom = openbabel.OBAtom()
        atomicnum = vetee.gaussian_options.periodic_table(atom[0])
        obatom.SetAtomicNum(atomicnum)
        obatom.SetVector(atom[1], atom[2], atom[3])
        obmol.AddAtom(obatom)
    # set charge, multiplicity, and comments (title)
    obmol.SetTotalCharge(parser.charge)
    obmol.SetTotalSpinMultiplicity(parser.multip)
    if parser.comments is not None:
        obmol.SetTitle(parser.comments)
    # convert the obmol to a pybel Molecule
    pybelmol = pybel.Molecule(obmol)
    # generate a zmatrix string using the obmol input
    zmatrix = pybelmol.write("gzmat")
    return zmatrix
Beispiel #4
0
    def __init__(self, mol):
        """
        Initializes with pymatgen Molecule or OpenBabel"s OBMol.

        Args:
            mol:
                pymatgen"s Molecule or OpenBabel OBMol
        """
        if isinstance(mol, Molecule):
            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 = ob.OBMol()
            for site in mol:
                coords = [c for c in site.coords]
                atomno = site.specie.Z
                obatom = ob.OBAtom()
                obatom.SetAtomicNum(atomno)
                obatom.SetVector(*coords)
                obmol.AddAtom(obatom)
            obmol.ConnectTheDots()
            obmol.PerceiveBondOrders()
            obmol.SetTotalSpinMultiplicity(mol.spin_multiplicity)
            obmol.SetTotalCharge(mol.charge)
            self._obmol = obmol
        elif isinstance(mol, ob.OBMol):

            self._obmol = mol
Beispiel #5
0
def makeopenbabel(atomcoords, atomnos, charge=0, mult=1):
    """Create an Open Babel molecule.

    >>> import numpy, openbabel
    >>> atomnos = numpy.array([1, 8, 1], "i")
    >>> coords = numpy.array([[-1., 1., 0.], [0., 0., 0.], [1., 1., 0.]])
    >>> obmol = makeopenbabel(coords, atomnos)
    >>> obconversion = openbabel.OBConversion()
    >>> formatok = obconversion.SetOutFormat("inchi")
    >>> print obconversion.WriteString(obmol).strip()
    InChI=1/H2O/h1H2
    """
    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(charge)
    return obmol
Beispiel #6
0
def get_pdb_ccd_open_babel_mol(pdb_mol):
    """ Generate an Open Babel representation of a PDB CCD entry

    Args:
        pdb_mol (:obj:`dict`): structure of a entry

    Returns:
        :obj:`openbabel.OBMol`: structure of a entry
    """
    if not pdb_mol['complete']:
        return None

    mol = openbabel.OBMol()

    for pdb_atom in pdb_mol['atoms']:
        atom = openbabel.OBAtom()
        atom.SetAtomicNum(pdb_atom['atomic_num'])
        atom.SetFormalCharge(pdb_atom['charge'])
        mol.AddAtom(atom)

    for pdb_bond in pdb_mol['bonds']:
        bond = openbabel.OBBond()
        bond.SetBegin(mol.GetAtom(pdb_bond['begin']))
        bond.SetEnd(mol.GetAtom(pdb_bond['end']))
        bond.SetBondOrder(pdb_bond['order'])
        assert mol.AddBond(bond)

    return mol
Beispiel #7
0
def EFP2atom(s):
    at=openbabel.OBAtom()
    st=s.split()
    at.SetAtomicNum(int(float(st[-1])))
    at.SetVector(float(st[1])*Bohr, float(st[2])*Bohr, float(st[3])*Bohr)
    at.SetTitle(st[0][3:len(st[0])])
    return at
Beispiel #8
0
def hash2smiles(hash):
    import openbabel

    result_list = []
    obconvert = openbabel.OBConversion()
    obconvert.SetOutFormat('smiles')

    for (atoms, bonds) in parse_hash(hash):
        mol = openbabel.OBMol()
        for n in xrange(len(atoms)):
            (node, valence, hydrogens, charge,
             chirality) = parse_atom(atoms[n])
            if node == 'PO3':
                node = 'P'
            atom = openbabel.OBAtom()
            atom.SetAtomicNum(atomicnum_table[node])
            mol.AddAtom(atom)
        for n in range(len(atoms)):
            for m in range(n):
                order = bonds.pop(0)
                if order:
                    mol.AddBond(n + 1, m + 1, order)

        smiles = obconvert.WriteString(mol).strip()
        result_list.append(smiles)

    return result_list
Beispiel #9
0
 def __init__(self, OBAtom=None, index=None):
     if not OBAtom:
         OBAtom = ob.OBAtom()
     self.OBAtom = OBAtom
     # For the moment, I will remember the index of the atom in the molecule...
     # I'm not sure if this is useful, though.
     self.index = index
Beispiel #10
0
def GetConf(mol, args, catoms=[]):
    # Create a mol3D copy with a dummy metal metal
    Conf3D = mol3D()
    Conf3D.copymol3D(mol)
    Conf3D.addAtom(atom3D('Fe', [0, 0, 0]))  #Add dummy metal to the mol3D
    dummy_metal = openbabel.OBAtom()  #And add the dummy metal to the OBmol
    dummy_metal.SetAtomicNum(26)
    Conf3D.OBMol.AddAtom(dummy_metal)
    for i in catoms:
        Conf3D.OBMol.AddBond(i + 1, Conf3D.OBMol.NumAtoms(), 1)
    natoms = Conf3D.natoms
    Conf3D.createMolecularGraph()

    shape = findshape(args, mol)
    LB, UB = GetBoundsMatrices(Conf3D, natoms, catoms, shape)
    status = False
    while not status:
        D = Metrize(LB, UB, natoms)
        D0, status = GetCMDists(D, natoms)
    G = GetMetricMatrix(D, D0, natoms)
    L, V = Get3Eigs(G, natoms)
    X = np.dot(V, L)  # get projection
    x = np.reshape(X, 3 * natoms)
    res1 = optimize.fmin_cg(DistErr,
                            x,
                            fprime=DistErrGrad,
                            gtol=0.1,
                            args=(LB, UB, natoms),
                            disp=0)
    X = np.reshape(res1, (natoms, 3))
    Conf3D = SaveConf(X, Conf3D, True, catoms)

    return Conf3D
Beispiel #11
0
    def _removeMetalAtoms(self):
        _metalAtoms = []

        removing = True
        while removing:
            added = 0
            if self.mol.NumAtoms() == 0:
                break
            for i in range(1, self.mol.NumAtoms() + 1):
                atom = self.mol.GetAtom(i)
                if atom.GetAtomicNum() in [1, 6, 7, 8, 12, 15, 16]:
                    if atom not in self._atoms: self._atoms.append(atom)
                    added += 1
                else:
                    print(
                        "Info: FragIt [FRAGMENTATION] Temporarily removing atom with Z={}"
                        .format(atom.GetAtomicNum()))
                    # the atoms are most-likely counter ions, so we give them an
                    # appropriate formal charge (of +/- 1)
                    atomic_charge = 0  # default
                    if atom.GetAtomicNum() in [11, 19]:  # Na+ and K+:
                        atomic_charge = 1
                    elif atom.GetAtomicNum() in [9, 17]:  # F- and Cl-
                        atomic_charge = -1

                    new_atom = openbabel.OBAtom()
                    new_atom.Duplicate(atom)
                    new_atom.SetFormalCharge(atomic_charge)

                    _metalAtoms.append(new_atom)
                    self.mol.DeleteAtom(atom)
                    break

                if added == self.mol.NumAtoms():
                    removing = False
                    break

        if len(self.getExplicitlyBreakAtomPairs()) > 0:
            print(
                "\n WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING"
            )
            print(
                "    You have requested to manually fragment atom indices. However,"
            )
            print(
                "    because you _also_ have metal atoms in your input file, atom"
            )
            print(
                "    indices might have shifted around and you will likely see an"
            )
            print(
                "    error below about atoms not being connected with a bond.\n"
            )
            print(
                "    A possible fix is to move metal atoms to the end of your file.\n"
            )
            #print(" WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING")

        return _metalAtoms
Beispiel #12
0
 def oasa_to_ob_atom(self, oatom):
     num = PT[oatom.symbol]['ord']
     obatom = openbabel.OBAtom()
     obatom.SetAtomicNum(num)
     obatom.SetVector(oatom.x, oatom.y, oatom.z)
     obatom.SetFormalCharge(oatom.charge)
     #patom = pybel.Atom()
     #patom.atomicnum = num
     return obatom
Beispiel #13
0
    def _to_normal_coordinates(self, atom, index):
        """Returns:
            The `atom`'s normal coordinates for normal mode at `index`.
        """
        def ar(vec):
            """Returns a numpy array with the coordinates of the vector."""
            return np.array((vec.GetX(), vec.GetY(), vec.GetZ()))

        atomnc = ob.OBAtom()
        nc = ar(atom) + self.lx[index][atom.GetIdx() - 1]
        atomnc.SetVector(*nc)
        return atomnc
Beispiel #14
0
def to_openbabel_Mol(mol, CalcBondmap = False):
    obmol = ob.OBMol()
    if not mol.coords == None:
        for atom, coord in zip(mol.atoms, mol.coords):
            obatom = ob.OBAtom()
            obatom.SetAtomicNum(ob.OBElementTable().GetAtomicNum(atom))
            coord_vec = ob.vector3(coord[0], coord[1], coord[2])
            obatom.SetVector(coord_vec)
            obmol.InsertAtom(obatom)
    else:
        for atom in mol.atoms:
            obatom = ob.OBAtom()
            obatom.SetAtomicNum(ob.OBElementTable().GetAtomicNum(atom))
            obmol.InsertAtom(obatom)
    if CalcBondmap == True:
        obmol.ConnectTheDots()
        obmol.PerceiveBondOrders()
    else:
        for bond in mol.bondmap:
            obmol.AddBond(bond[0] + 1, bond[1] + 1, bond[2])
    return obmol
	def __init__(self, Id, Type, Val, Cor, Q, Bonds, Mol):
		self.id = Id
		self.type = Type
		self.val = Val
		self.cor = Cor
		self.q = Q
		self.bonds = Bonds
		self.mol = Mol

		self.atom = openbabel.OBAtom()
		self.atom.SetId(Id)
		self.atom.SetAtomicNum(Type)
Beispiel #16
0
    def read_cclib(self, data, ind=-1, lvprt=1):
        if lvprt >= 1:
            print(("Reading cclib structure with %i atoms." % data.natom))

        self.mol = openbabel.OBMol()

        for iat in range(data.natom):
            obatom = openbabel.OBAtom()
            obatom.SetAtomicNum(int(data.atomnos[iat]))
            coords = data.atomcoords[ind][iat]
            obatom.SetVector(*coords)

            self.mol.AddAtom(obatom)
Beispiel #17
0
def GetConf(mol, args, catoms=[]):
    """Uses distance geometry to get a random conformer.
        
    Parameters
    ----------
        mol : mol3D
            mol3D class instance for molecule of interest.
        args : Namespace
            Namespace argument from inparse.
        catoms : list, optional
            List of connection atoms used to generate additional constraints if specified (see GetBoundsMatrices()). Default is empty.
        
    Returns
    -------
        Conf3D : mol3D
            mol3D class instance of new conformer.

    """
    # Create a mol3D copy with a dummy metal metal
    Conf3D = mol3D()
    Conf3D.copymol3D(mol)
    Conf3D.addAtom(atom3D('Fe', [0, 0, 0]))  #Add dummy metal to the mol3D
    dummy_metal = openbabel.OBAtom()  #And add the dummy metal to the OBmol
    dummy_metal.SetAtomicNum(26)
    Conf3D.OBMol.AddAtom(dummy_metal)
    for i in catoms:
        Conf3D.OBMol.AddBond(i + 1, Conf3D.OBMol.NumAtoms(), 1)
    natoms = Conf3D.natoms
    Conf3D.createMolecularGraph()

    shape = findshape(args, mol)
    LB, UB = GetBoundsMatrices(Conf3D, natoms, catoms, shape)
    status = False
    while not status:
        D = Metrize(LB, UB, natoms)
        D0, status = GetCMDists(D, natoms)
    G = GetMetricMatrix(D, D0, natoms)
    L, V = Get3Eigs(G, natoms)
    X = np.dot(V, L)  # get projection
    x = np.reshape(X, 3 * natoms)
    res1 = optimize.fmin_cg(DistErr,
                            x,
                            fprime=DistErrGrad,
                            gtol=0.1,
                            args=(LB, UB, natoms),
                            disp=0)
    X = np.reshape(res1, (natoms, 3))
    Conf3D = SaveConf(X, Conf3D, True, catoms)

    return Conf3D
Beispiel #18
0
    def read_at_dicts(self, at_dicts):
        """
        Create a mol from information specified in a list of dictionaries.
        [{'Z':, 'x':, 'y':, 'z':}, ...]
        """
        self.mol = openbabel.OBMol()

        for iat in range(len(at_dicts)):
            obatom = openbabel.OBAtom()
            obatom.SetAtomicNum(at_dicts[iat]['Z'])
            coords = (at_dicts[iat]['x'], at_dicts[iat]['y'],
                      at_dicts[iat]['z'])
            obatom.SetVector(*coords)

            self.mol.AddAtom(obatom)
Beispiel #19
0
def makeopenbabel(atomcoords, atomnos, charge=0, mult=1):
    """Create an Open Babel molecule."""
    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
Beispiel #20
0
    def _single_protonation_orca_strings(self, pymol):
        orca_strings = []

        self.stored_data['protonated_children'] = []
        for atom in pymol.atoms:
            if atom.atomicnum in [7, 8, 15, 16]:
                print 'Atom #{} is {} atom with\n coords {}'.format(
                    atom.idx, element(atom.atomicnum), atom.coords)
                child = {}
                child['atom_index'] = atom.idx
                child['element'] = element(atom.atomicnum).symbol

                if atom.hyb > 2:
                    child['likely_to_break'] = True
                else:
                    child['likely_to_break'] = False
                obmol = pymol.OBMol

                h = openbabel.OBAtom()
                h.SetAtomicNum(1)
                h.SetVector(*atom.coords)
                h.SetVector(h.GetVector().GetX() + 0.4,
                            h.GetVector().GetY() + 0.4,
                            h.GetVector().GetZ() + 0.4)
                print 'New Proton is #{} with info {} and\n coords ({}, {}. {})'.format(
                    h.GetIdx(), element(h.GetAtomicNum()),
                    h.GetVector().GetX(),
                    h.GetVector().GetY(),
                    h.GetVector().GetZ())
                obmol.InsertAtom(h)
                obmol.AddBond(atom.idx, h.GetIdx(), 1)
                obmol.SetTotalCharge(pymol.charge + 1)
                tmp_pymol = pybel.Molecule(obmol)
                tmp_pymol.localopt()

                orca_string, _ = create_orca_input_string(tmp_pymol)
                child['orca_string'] = orca_string
                orca_strings.append(orca_string)
                self.stored_data['protonated_children'].append(child)

        return orca_strings
Beispiel #21
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")
Beispiel #22
0
    def construct(self, db, mol):
        cores = []
        support = []
        nfrags = 0
        for e in db.entries:
            fr = pybel.Smarts(e.smarts)
            found = fr.findall(mol)
            if len(found)>0:
                cores.append([e.name, found])
                for f in found:
                    support.append([e.name, f])
                    nfrags += 1

        print "\nTotal number of database matches: ", nfrags, "\n"

        # constructing overlap matrix of the fragments
        print "Constructing overlap matrix"
        overlap = []
        for i in xrange(len(support)):
            overlap.append([])
            for j in xrange(len(support)):
                overlap[-1].append(ListOverlap(support[i][1], support[j][1]))

        # subdivide molecule into non-overlapping fragments without any atoms left
        print "Creating a set of unique fragments"
        numat = mol.OBMol.NumHvyAtoms()
        complete = False
        result = None
        nums = []
        for i in xrange(len(support)):
            nums.append([i])
        n0 = 0
        n = len(nums)
        ntry = 0
        for i in xrange(len(support)-1):
            for nn in nums[n0:n]:
                for j in xrange(len(support)):
                    if j not in nn:
                        good = 1
                        for k in nn:
                            if overlap[j][k]:
                                good = 0
                                break
                        if good:
                            newl = nn[:]
                            newl.append(j)
                            sstop = 0 
                            for nn2 in nums[n:]:
                                if IsIncluded(nn2,newl):
                                    sstop = 1
                                    break
                            if (sstop == 0):
                                ntry += 1
                                nat = 0
                                for k in newl:
                                    nat += len(support[k][1])
                                if (nat == numat):
                                    complete = True
                                    result = newl
                                    break
                                nums.append(newl)
#                                print i, j, newl
                if (complete):
                    break
            if (complete):
                break
            n0 = n
            n = len(nums)

        if (result == None):
            for nn in nums:
                nat = 0
                for k in nn:
                    nat += len(support[k][1])
                if (nat == numat):
                    result = nn
                    break
#            result = [0]

        # convert data to the appropriate format
        coredict = {}
        nfrag = 0
        for ss in result:
            if support[ss][0] not in coredict:
                coredict[support[ss][0]] = [support[ss][1]]
                nfrag += 1
            else:
                coredict[support[ss][0]].append(support[ss][1])
                nfrag += 1
        cores = []
        print "The molecule was subdivided into ", nfrag, " non-overlapping fragments after ", ntry+1, " attempts\n" 
        for c in coredict:
            cores.append([c, coredict[c]])

        for c in cores:
#            print c
            for cc in c[1]:
                self.frags.append(frag())
                self.frags[-1].ename = c[0]
                self.frags[-1].refndx = list(cc[:])
                WithBonds0 = list(cc[:])
                for i in cc:
                    for at in openbabel.OBAtomAtomIter(mol.OBMol.GetAtom(i)):
                        if (at.GetIndex()+1 not in cc):
                            if (at.GetAtomicNum() > 1):
                                WithBonds0.append(at.GetIndex()+1) 
                            else:
                                self.frags[-1].refndx.append(at.GetIndex()+1)
                # Creating submolecule from the fragment
#                subMol = openbabel.OBMol()
                for at in openbabel.OBMolAtomIter(mol.OBMol):
                    if (at.GetIndex()+1) in WithBonds0:
                        at1 = openbabel.OBAtom()
                        at1.Duplicate(at)
                        self.frags[-1].subMol.AddAtom(at1)
                self.frags[-1].subMol.ConnectTheDots()
                self.frags[-1].subMol.PerceiveBondOrders()
                self.frags[-1].subMol.AddHydrogens()    
                # creating new lists for submolecule
                frB = pybel.Smarts(pybel.Molecule(self.frags[-1].subMol).write("smi"))
#                print "========================  fragment", self.frags[-1].ename, " ==========================="
#                print self.frags[-1].ename, pybel.Molecule(self.frags[-1].subMol).write("smi")
                fr = pybel.Smarts(db.Smarts(c[0]))
                self.frags[-1].moltotal = frB.findall(pybel.Molecule(self.frags[-1].subMol))[0]
                newcore = fr.findall(pybel.Molecule(self.frags[-1].subMol))[0]  # indices in the submolecule
                self.frags[-1].molcore = []
                for f in self.frags[-1].moltotal:
                    if f in newcore:
                        self.frags[-1].molcore.append(f)
                # creating new lists for EFP fragment
                nbd = len(self.frags[-1].moltotal) - len(self.frags[-1].molcore)  # number of connections
                bpat = db.Bondpatterns(c[0], nbd)
                found = 0
                for fn in bpat:
                    efpmol = pyEFP.EFP2mol("./"+db.dirname+"/"+str(c[0])+"/"+fn+".efp")
#                    print self.frags[-1].fname, pybel.Molecule(efpmol).write("smi")
                    newlB = frB.findall(pybel.Molecule(efpmol))
#                    print c[0], fn, efpmol.NumAtoms(), len(self.frags[-1].moltotal) - len(self.frags[-1].molcore), newlB
#                    print pybel.Molecule(efpmol).write("smi")
#                    print "frB = ", pybel.Molecule(self.frags[-1].subMol).write("smi")
#                    print frB.findall(mol)
                    if len(newlB) > 0:
                        self.frags[-1].efptotal = newlB[0]
                        found = 1
                        break
                if (found==0):
                    print "Cannot find bond pattern for fragment ", self.frags[-1].ename, " corresponding to the structure ", pybel.Molecule(self.frags[-1].subMol).write("smi").strip(), "( ", nbd, " connections )"
                    return 1
                self.frags[-1].fname = fn
                newl = fr.findall(pybel.Molecule(efpmol))[0]
                self.frags[-1].efpcore = []
                for f in self.frags[-1].efptotal:
                    if f in newl:
                        self.frags[-1].efpcore.append(f)
        # calculating links
        # first loop to identify index in local reference
        for f in self.frags:
            for i in xrange(len(f.efptotal)):
                if (f.efptotal[i] not in f.efpcore):
                    f.links.append([f.efptotal[i], f.moltotal[i]])
        # second loop to identify linked residue and index in the corresponding reference
        ifr0 = 0
        for f in self.frags:
            for xx in xrange(len(f.links)):
                i = f.links[xx][1]
                x0 = f.subMol.GetAtom(i).x()
                y0 = f.subMol.GetAtom(i).y()
                z0 = f.subMol.GetAtom(i).z()
                found = 0
                ifr = 0
                for f2 in self.frags:
#                    if (f2.molcore[0] != f.molcore[0]):
                    if (ifr0 != ifr):
                        for j in f2.molcore:
                            x1 = f2.subMol.GetAtom(j).x()
                            y1 = f2.subMol.GetAtom(j).y()
                            z1 = f2.subMol.GetAtom(j).z()
                            dx = x1-x0
                            dy = y1-y0
                            dz = z1-z0
                            dr2 = dx*dx + dy*dy + dz*dz
                            if dr2 < 0.0001:
                                found = 1
                                f.links[xx].append(ifr)
#                                print xx, len(f.links), f2.moltotal.index(j), len(f2.efptotal), f2.fname, f2.ename
#                                sys.stdout.flush()
                                f.links[xx].append(f2.efptotal[f2.moltotal.index(j)])
                                f.links[xx].append(j)
                                break
                        if (found == 1):
                            break
                    ifr += 1
            ifr0 += 1
        return 0
	def harvestGaussian(self, Filename):
		molinfo = {
			# . crucial info
			'smi': '',	# SMILES representation of the molecule
			'M': 0.0,	# molecular mass
			'cSPE': 0.0,	# zero-point corrected single-point energy
			'Tr': [0,0,0],	# rotational temperatures
			'v0': [],	# harmonic frequencies
			'eff': 0.0,	# ReaxFF reference energy
			'Ip': [],	# ReaxFF reference inertia
			'Htherm': 0.0,	# thermal enthalpy at 298.15K
			'spin': 0.0,	# spin multiplicity
			# . Hindered Rotor info
			'rotor': {},	# internal rotation data
			# . additional info
			'sym': 1,	# rotational symmetry number
			'geo': {},	# charge-centered coordinates {id:[type,[x,y,z]]}
			'cmd': [],	# g09 command line parameters used for all calculations
			'confirmed': True,	# IRC TS confirmation
			'normalTerm': False,	# normal termination flag
			'errorLink': 0	# g09 part with error
		}
		rotor = {}
		geo = {}
		ivib = []	#   subdata: harmonic frequency
		iper = []	#   subdata: periodicity
		isym = []	#   subdata: symmetry number
		imom = []	#   subdata: reduced moment of inertia
		bond = []	#   subdata: connection between frequency and rotor
		bond2 = {}	#   subdata: connection between frequency and rotor
		ax = []		#   subdata: rotor axes
		irot = 0	#   subdata: number of internal rot deg of freedom
		irc = [[], []]

		# . parse Gaussian log file
		print('file:', Filename)
		done = False
		reaxFFdone = False
		reader = open(Filename, 'r')
		line = reader.readline()
		try:
			while not done:
				if 'Gaussian 09:' in line:
					line = reader.readline(); line = reader.readline()

					# . harvest g09 command line
					while not line.startswith(' # ') and line != '':
						line = reader.readline()
					tmp = line[3:-1]
					line = reader.readline()
					while '----------' not in line and line != '':
						tmp += line[1:-1]
						line = reader.readline()
					cmd = tmp.split()
					cmd = ' '.join([c for c in tmp.split() if '=' not in c and 'opt' not in c and 'freq' not in c and 'int' not in c and 'scf' not in c and 'maxdisk' not in c.lower() and 'symmetry' not in c])
					molinfo['cmd'].append(cmd)

				# . harvest ReaxFF information
				#   stands at start of every job
				#   if no 'normal termination' follows, the job was aborted
				elif line.startswith(' REAXFF:'):
					if not reaxFFdone:
						words = line.strip().split()
						molinfo['smi'] = words[1]
						molinfo['eff'] = float(words[2])
						molinfo['Ip'] = [float(w) for w in words[3:]]
						reaxFFdone = True
					molinfo['normalTerm'] = False

				# . harvest spin multiplicity
				elif 'Symbolic Z-matrix:' in line:
					line = reader.readline()
					words = line.strip().split()
					molinfo['spin'] = float(words[5])

				# . harvest internal rotation data	(anharmonicity)
				elif 'Hindered Internal Rotation Analysis' in line and not ivib:
					while '- Thermochemistry For Hindered Internal Rotation -' not in line and 'No hindered rotor corrections are necessary' not in line and 'This molecule contains only rings' not in line and line != '':
						line = reader.readline()
						words = line.strip().split()
						if line.startswith(' Number of internal rotation degrees of freedom'):
							irot = int(words[-1])
						#elif line.startswith(' Normal Mode Analysis for Internal Rotation'): # or line.startswith(' Redo normal mode analysis with added constraints')
						#	ivib = []
						elif 'Frequencies ---' in line and len(ivib) < irot:
							for v in [float(w) for w in words[2:]]:
								ivib.append(v)
						elif len(words) == 6 and words[0][-1] == ')':
							iper.append(int(words[3])) # periodicity
							isym.append(int(words[4])) # symmetry number
						elif 'Reduced Moments ---' in line:
							for m in [float(w) for w in words[3:]]:
								if m not in imom: imom.append(m)
						elif line.strip() == 'Bond':
							line = reader.readline()
							words = line.strip().split()
							bidx = 0
							while len(words) > 3 and words[1] == '-':
								ax.append(sorted([int(words[0]), int(words[2])])) # bond partners of axis
								if bidx+1 > len(bond): bond.append([])
								bond[bidx] += [float(w) for w in words[3:]] # axis share
								bidx += 1
								line = reader.readline()
								words = line.strip().split()

				# . harvest harmonic frequencies	(vibration)
				elif 'Harmonic frequencies (cm**-1)' in line:
					if molinfo['v0']: molinfo['v0'] = []
					while '- Thermochemistry -' not in line and line != '':
						line = reader.readline()
						if 'Frequencies --' in line:
							words = line.strip().split()
							molinfo['v0'] += [float(w) for w in words[2:]]

				# . harvest molecular mass		(translation)
				elif 'Molecular mass:' in line:
					words = line.strip().split()
					molinfo['M'] = float(words[2])

				# . harvest rotational temperatures	(rotation)
				elif 'Rotational symmetry number' in line:
					words = line.strip().split()
					molinfo['sym'] = int(words[3][:-1])
				elif 'Rotational temperatures (Kelvin)' in line or 'Rotational temperature (Kelvin)' in line:
					words = line.strip().split()
					molinfo['Tr'] = [float(w) for w in words[3:] if '***' not in w]

				# . harvest energetics
				elif 'Sum of electronic and zero-point Energies=' in line:
					words = line.strip().split()
					molinfo['cSPE'] = float(words[6])
				elif 'Sum of electronic and thermal Enthalpies=' in line:
					words = line.strip().split()
					molinfo['Htherm'] = float(words[6])
				elif 'CBS-QB3 (0 K)=' in line:
					words = line.strip().split()
					molinfo['cSPE'] = float(words[3])
				elif 'CBS-QB3 Enthalpy=' in line:
					words = line.strip().split()
					molinfo['Htherm'] = float(words[2])
				elif 'G3MP2(0 K)=' in line:
					words = line.strip().split()
					molinfo['cSPE'] = float(words[2])
				elif 'G3MP2 Enthalpy=' in line:
					words = line.strip().split()
					molinfo['Htherm'] = float(words[2])

				# . harvest geometry
				elif 'Standard orientation' in line:
					for i in range(5): line = reader.readline()
					while '-----------------------------------' not in line and line != '':
						words = line.strip().split()
						geo[int(words[0])] = [int(words[1]),[float(words[3]),float(words[4]),float(words[5])]]
						line = reader.readline()
					molinfo['geo'] = geo

				# . harvest IRC information
				elif 'Input orientation:' in line:
					tmp = []
					line = reader.readline()
					line = reader.readline()
					line = reader.readline()
					line = reader.readline()
					line = reader.readline()
					while '---' not in line:
						words = line.split()
						tmp.append([int(words[1]), [float(words[3]), float(words[4]), float(words[5])]])
						line = reader.readline()
				elif 'Calculation of FORWARD path complete.' in line: irc[0] = tmp
				elif 'Calculation of REVERSE path complete.' in line: irc[1] = tmp

				# . normal termination?
				elif 'Normal termination of Gaussian' in line:
					molinfo['normalTerm'] = True
				elif 'Error termination ' in line:
					molinfo['normalTerm'] = False
					words = line.strip().split()
					if len(words) > 7: molinfo['errorLink'] = words[5].split('/')[-1]

				line = reader.readline()
				if line == '': done = True
			reader.close()
		except:
			# . return here if exception
			self.log.printIssue(Text='Exception while executing\n'+traceback.format_exc(), Fatal=False)
			molinfo['normalTerm'] = False
			molinfo['M'] = 0.0
			return molinfo

		# . return here if crucial data misses
		#   eff=0 and Tr=[0,0,0] allowed ([H])
		if molinfo['cSPE'] == 0.0 or molinfo['M'] == 0.0 or molinfo['smi'] == '' or molinfo['Ip'] == [] or molinfo['Htherm'] == 0.0:
			molinfo['M'] = 0.0
			molinfo['normalTerm'] = False
			return molinfo
		
		# . delete frequencies too close to each other
		keep = [not any(abs(ivib[i]-ivib[j])<1 for i in range(j+1,irot)) for j in range(irot)]
		if not all(keep):
			ivib = [ivib[i] for i in range(irot) if keep[i]]
			iper = [iper[i] for i in range(irot) if keep[i]]		
			isym = [isym[i] for i in range(irot) if keep[i]]
			imom = [imom[i] for i in range(irot) if keep[i]]
			bond = [bond[i] for i in range(irot) if keep[i]]
			ax   = [ax[i]   for i in range(irot) if keep[i]]
		nfreqs = len(ivib)

		# . merge internal rotation data (4.649783E-48 (kg/amu)*(m/bohr)**2
		#   don't use a frequency twice
		unused = [True]*nfreqs
		for i in range(nfreqs):
			idx = bond[i].index(max([bond[i][k] for k in range(nfreqs) if unused[k]]))
			unused[idx] = False
			if imom[idx] != 0.0:
				rotor[ivib[idx]] = isym[i]**2 *self.h**2 /(8 *numpy.math.pi**2 *self.kB *imom[idx] *4.649783E-48 *iper[i]**2)

		# . remove internal rotation axes which are part of ring
		#   atom.thisown=False should solve instabilities
		mol = openbabel.OBMol()
		for a in geo:
			atom = openbabel.OBAtom()
			atom.thisown = False
			atom.SetAtomicNum(geo[a][0])
			atom.SetVector(geo[a][1][0], geo[a][1][1], geo[a][1][2])
			mol.AddAtom(atom)
		mol.ConnectTheDots()
		mol.PerceiveBondOrders()
		tmp_rotor = self.findInternalRotors(Mol=mol)

		# . delete false rotors, which are part of a ring
		#  ax: axes found by g09
		#  tmp_rotor: axes found by local method, no rings
		#  rotor: mapping of rot. freq. <-> rot. temp. (g09 data)
		for idx in range(nfreqs):
			if ax[idx] not in tmp_rotor and ivib[idx] in rotor: del rotor[ivib[idx]]
		molinfo['rotor'] = rotor

		# . check number of molecules (==1)
		#   if species, but nmol > 1, dont use qm-data
		#   return information for species
		if molinfo['smi'] == '[H]' or molinfo['smi'] == '[H][H]': nmol = 1
		else: nmol = len(self.conv.WriteString(mol).strip().split('.'))
		if ':' not in molinfo['smi']:
			molinfo['confirmed'] = (nmol == 1)
			return molinfo

		# . IRC check, only for TS
		#   build reactants
		mol = openbabel.OBMol()
		for a in irc[0]:
			atom = openbabel.OBAtom()
			atom.thisown = False
			if a[0] == 1: atom.SetAtomicNum(9); atom.SetType('H')
			else: atom.SetAtomicNum(a[0])
			atom.SetVector(a[1][0], a[1][1], a[1][2])
			mol.AddAtom(atom)
		mol.ConnectTheDots()
		for atom in openbabel.OBMolAtomIter(mol):
			if atom.GetType() == 'H': atom.SetAtomicNum(1)
		mol.AssignSpinMultiplicity(True)
		reactants = []
		for frag in mol.Separate():
			if frag.NumHvyAtoms() == 0:
				if frag.NumAtoms() == 1: reactants.append('[H]')
				elif frag.NumAtoms() == 2: reactants.append('[H][H]')
				continue
			self.conv.SetInAndOutFormats('mdl','inchi')
			inchi = self.conv.WriteString(frag)
			self.conv.SetInAndOutFormats('inchi','mdl')
			self.conv.ReadString(frag, inchi)
			self.conv.SetInAndOutFormats('mdl','can')
			reactants.append(self.conv.WriteString(frag).strip())

		# . build products
		mol = openbabel.OBMol()
		for a in irc[1]:
			atom = openbabel.OBAtom()
			atom.thisown = False
			if a[0] == 1: atom.SetAtomicNum(9); atom.SetType('H')
			else: atom.SetAtomicNum(a[0])
			atom.SetVector(a[1][0], a[1][1], a[1][2])
			mol.AddAtom(atom)
		mol.ConnectTheDots()
		for atom in openbabel.OBMolAtomIter(mol):
			if atom.GetType() == 'H': atom.SetAtomicNum(1)
		mol.AssignSpinMultiplicity(True)
		products = []
		for frag in mol.Separate():
			if frag.NumHvyAtoms() == 0:
				if frag.NumAtoms() == 1: products.append('[H]')
				elif frag.NumAtoms() == 2: products.append('[H][H]')
				continue
			self.conv.SetInAndOutFormats('mdl','inchi')
			inchi = self.conv.WriteString(frag)
			self.conv.SetInAndOutFormats('inchi','mdl')
			self.conv.ReadString(frag, inchi)
			self.conv.SetInAndOutFormats('mdl','can')
			products.append(self.conv.WriteString(frag).strip())

		# . check
		reacIRC = sorted( [sorted(reactants), sorted(products)] )
		reacFF  = sorted( [sorted(molinfo['smi'].split(':')[0].split(',')), sorted(molinfo['smi'].split(':')[1].split(','))] )
		molinfo['confirmed'] = (reacIRC == reacFF)

		# . return information (for TS)
		return molinfo
Beispiel #24
0
def amol2mol(amol):
    mol = openbabel.OBMol()
    atoms = list()
    bonds = list()
    atoms, bonds = pickle.loads(amol)
    natoms = len(atoms)
    mol.ReserveAtoms(natoms)
    atomidx = 0
    chiatoms = dict()
    a = openbabel.OBAtom()
    for atom in atoms:
        hybridization, atnum, fcharge, isotope, stereo, mult, aromatic = atom
        a.Clear()
        atomidx += 1
        a.SetIdx(atomidx)
        a.SetHyb(hybridization)
        a.SetAtomicNum(atnum)
        a.SetIsotope(isotope)
        a.SetFormalCharge(fcharge)
        if stereo == 1:
            a.SetClockwiseStereo()
        elif stereo == 2:
            a.SetAntiClockwiseStereo()
        elif stereo == 3:
            a.SetChiral()
        a.SetSpinMultiplicity(mult)
        if aromatic: a.SetAromatic()

        if not mol.AddAtom(a):
            return None

        if stereo:
            cd = openbabel.OBChiralData()
            catom = mol.GetAtom(atomidx)
            catom.CloneData(cd)
            chiatoms[catom] = cd
            pass

    for bond in bonds:
        flags = 0
        #b = openbabel.OBBond()
        start, end, order, stereo, aromatic, updown = bond
        if start == 0 or end == 0 or order == 0 or start > natoms or end > natoms:
            return None
        if order == 4: order = 5
        if stereo == 1:
            flags |= openbabel.OB_WEDGE_BOND
        elif stereo == 6:
            flags |= openbabel.OB_HASH_BOND
        if aromatic:
            flags |= openbabel.OB_AROMATIC_BOND
        if updown == 1:
            flags |= openbabel.OB_TORUP_BOND
            print flags
        elif updown == 2:
            flags |= openbabel.OB_TORDOWN_BOND
            print flags
        if not mol.AddBond(start, end, order, flags):
            return None

        chidata = chiatoms.get(mol.GetAtom(start))
        if chidata:
            chidata.AddAtomRef(end, openbabel.input)
        chidata = chiatoms.get(mol.GetAtom(end))
        if chidata:
            chidata.AddAtomRef(start, openbabel.input)

    mol.SetAromaticPerceived()
    mol.SetKekulePerceived()
    return mol
 def test_FragmentationGetOBAtom(self):
     test_atom = self.fragmentation.getOBAtom(1)
     self.assertEqual(type(test_atom), type(openbabel.OBAtom()))
    def pic(self, filename, picformat='svg'):
        """
        Generates a graphical file with 2D-representation of the resonance structure
        """
        try:
            import openbabel as ob
        except:
            print "Cannot import openbabel"
            return

        #ValEl = {'H':1, 'B':3,'C':4,'N':5,'O':6,'F':7,'S':6}
        #ValEl = {'1':1, '5':3,'6':4,'7':5,'8':6,'9':7,'16':6}
        # Import Element Numbers
        ati = []
        Sym2Num = ob.OBElementTable()
        for a in self.symbols:
            ElNum = Sym2Num.GetAtomicNum(a)
            ati.append(ElNum)

        # Import connections
        conn = self.data

        mol = ob.OBMol()

        # Create atoms
        for a in ati:
            at = ob.OBAtom()
            at.SetAtomicNum(a)
            mol.AddAtom(at)

        # Create connections
        val = []
        total_LP = 0
        for i in range(len(conn)):
            total_LP += conn[i][i]

        for i in range(len(conn)):
            val.append(conn[i][i] * 2)
            for j in range(i):
                if conn[i][j] == 0:
                    continue
                val[i] += conn[i][j]
                val[j] += conn[i][j]
                atA = mol.GetAtomById(i)
                atB = mol.GetAtomById(j)

                b = ob.OBBond()
                b.SetBegin(atA)
                b.SetEnd(atB)
                b.SetBO(int(conn[i][j]))
                mol.AddBond(b)
        for i in range(len(conn)):
            atA = mol.GetAtomById(i)
            atAN = atA.GetAtomicNum()
            FormValEl = CountValenceEl(atAN)
            #if total_LP == 0:
            #    if atAN == 1:
            #        FullShell = 2
            #    else:
            #        FullShell = 8
            #    FormCharge = FormValEl + int(val[i]) - FullShell
            #else:
            FormCharge = int(FormValEl - val[i])
            #print "atAN, FormValEl, val[i], FullShell"
            #print atAN, FormValEl, val[i], FullShell
            #FormCharge = FormCharge % 2
            atA.SetFormalCharge(FormCharge)

        # Export file
        mol.DeleteNonPolarHydrogens()
        conv = ob.OBConversion()
        conv.SetOutFormat(picformat)
        conv.AddOption('C')
        conv.WriteFile(mol, filename)