def GetNumRings(mol): count = 0 for ring in openbabel.OBMolRingIter(mol): count += 1 return count
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)
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