def GetNumRings(mol):
    count = 0

    for ring in openbabel.OBMolRingIter(mol):
        count += 1

    return count
Exemplo n.º 2
0
    def test_ring_center_and_normal(self):
        mol = parse_smiles("c1ccccc1")
        R = 1.5
        for i in range(6):
            atom = mol.GetAtom(i + 1)
            atom.SetVector(R * math.cos(2 * math.pi * i / 6),
                           R * math.sin(2 * math.pi * i / 6), 0.0)
        for ring in ob.OBMolRingIter(mol):
            break

        center = ob.vector3()
        norm1 = ob.vector3()
        norm2 = ob.vector3()
        ring.findCenterAndNormal(center, norm1, norm2)
        self.assertZero(center.GetX())
        self.assertZero(center.GetY())
        self.assertZero(center.GetZ())

        self.assertZero(norm1.GetX())
        self.assertZero(norm1.GetY())
        self.assertClose(norm1.GetZ(), 1.0)

        self.assertZero(norm2.GetX())
        self.assertZero(norm2.GetY())
        self.assertClose(norm2.GetZ(), -1.0)
Exemplo n.º 3
0
def make_obmol(struct, verbose=False):
    '''Create an OBMol from AtomStruct that attempts to maintain
    correct atom typing'''
    mol = ob.OBMol()
    mol.BeginModify()
    visited_mols = []

    atoms = []
    for xyz, t in zip(struct.xyz, struct.c):
        x, y, z = map(float, xyz)
        ch = struct.channels[t]
        atom = mol.NewAtom()
        atom.SetAtomicNum(ch.atomic_num)
        atom.SetVector(x, y, z)
        atoms.append(atom)

    fixup(atoms, mol, struct)
    visited_mols.append(ob.OBMol(mol))

    connect_the_dots(mol, atoms, struct)
    fixup(atoms, mol, struct)
    visited_mols.append(ob.OBMol(mol))

    mol.EndModify()

    mol.AddPolarHydrogens()  #make implicits explicit
    visited_mols.append(ob.OBMol(mol))

    mol.PerceiveBondOrders()
    fixup(atoms, mol, struct)
    visited_mols.append(ob.OBMol(mol))

    for (i, a) in enumerate(atoms):
        ob.OBAtomAssignTypicalImplicitHydrogens(a)

    fixup(atoms, mol, struct)
    visited_mols.append(ob.OBMol(mol))

    mol.AddHydrogens()
    fixup(atoms, mol, struct)
    visited_mols.append(ob.OBMol(mol))

    #make rings all aromatic if majority of carbons are aromatic
    for ring in ob.OBMolRingIter(mol):
        if 5 <= ring.Size() <= 6:
            carbon_cnt = 0
            aromatic_ccnt = 0
            for ai in ring._path:
                a = mol.GetAtom(ai)
                if a.GetAtomicNum() == 6:
                    carbon_cnt += 1
                    if a.IsAromatic():
                        aromatic_ccnt += 1
            if aromatic_ccnt / carbon_cnt >= .5 and aromatic_ccnt != ring.Size(
            ):
                #set all ring atoms to be aromatic
                for ai in ring._path:
                    a = mol.GetAtom(ai)
                    a.SetAromatic(True)

    #bonds must be marked aromatic for smiles to match
    for bond in ob.OBMolBondIter(mol):
        a1 = bond.GetBeginAtom()
        a2 = bond.GetEndAtom()
        if a1.IsAromatic() and a2.IsAromatic():
            bond.SetAromatic(True)

    visited_mols.append(ob.OBMol(mol))

    mismatches = 0
    for (a, t) in zip(atoms, struct.c):
        ch = struct.channels[t]
        if 'Donor' in ch.name and not a.IsHbondDonor():
            mismatches += 1
            if verbose:
                print("Not Donor", ch.name, a.GetX(), a.GetY(), a.GetZ())
        if ch.name != 'NitrogenXSDonorAcceptor' and 'Acceptor' in ch.name and a.GetExplicitDegree(
        ) != a.GetTotalDegree():
            #there are issues with nitrogens and openbabel protonation..
            mismatches += 1
            if verbose:
                print("Not Acceptor", ch.name, a.GetX(), a.GetY(), a.GetZ())

        if 'Aromatic' in ch.name and not a.IsAromatic():
            mismatches += 1
            if verbose:
                print("Not Aromatic", ch.name, a.GetX(), a.GetY(), a.GetZ())

    return pybel.Molecule(mol), mismatches, visited_mols