unsigned int Schuffenhauer::CalculateAcyclicBonds(OpenBabel::OBMol& mol) { unsigned int nbonds(0); OpenBabel::OBAtom* nbratom[2]; OpenBabel::OBBond* bond; std::vector<OpenBabel::OBBond*>::iterator bvi; for (bond = mol.BeginBond(bvi); bond; bond = mol.NextBond(bvi)) { nbratom[0] = bond->GetBeginAtom(); nbratom[1] = bond->GetEndAtom(); if (nbratom[0] && nbratom[1]) { if (!bond->IsInRing() && (nbratom[0]->GetValence() > 1) && (nbratom[1]->GetValence() > 1)) { ++nbonds; } } } return nbonds; }
bool Schuffenhauer::HasLinkerToHeteroAtom(OpenBabel::OBMol& mol, OpenBabel::OBRing* ring) { std::vector<OpenBabel::OBBond*>::iterator bvi; OpenBabel::OBBond* bond; OpenBabel::OBAtom* nbrAtom[2]; for (bond = mol.BeginBond(bvi); bond; bond = mol.NextBond(bvi)) { nbrAtom[0] = bond->GetBeginAtom(); nbrAtom[1] = bond->GetEndAtom(); if ( // Neighbours are real nbrAtom[0] && nbrAtom[1] && // Bond should be acyclic !bond->IsInRing() && // Both atoms have to be ring atoms nbrAtom[0]->IsInRing() && nbrAtom[1]->IsInRing() && // At least one of the atoms should be hetero (nbrAtom[0]->IsHeteroatom() || nbrAtom[1]->IsHeteroatom()) && // One of the atoms, but not both, should be part of this ring ((ring->IsMember(nbrAtom[0]) && !ring->IsMember(nbrAtom[1])) || (ring->IsMember(nbrAtom[1]) && !ring->IsMember(nbrAtom[0]))) ) { return true; } } return false; }
OpenBabel::OBMol Schuffenhauer::Rule_7(OpenBabel::OBMol& oldMol) { std::vector<OpenBabel::OBRing*> allrings(oldMol.GetSSSR()); if (allrings.size() <= _ringsToBeRetained) { return oldMol; } // Are all atoms and bonds aromatic? std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBAtom* atom; for (atom = oldMol.BeginAtom(avi); atom; atom = oldMol.NextAtom(avi)) { if (!atom->IsAromatic()) { return oldMol; } } std::vector<OpenBabel::OBBond*>::iterator bvi; OpenBabel::OBBond* bond; for (bond = oldMol.BeginBond(bvi); bond; bond = oldMol.NextBond(bvi)) { if (!bond->IsAromatic()) { return oldMol; } } std::vector<OpenBabel::OBMol> mols; for (unsigned int i(0); i < allrings.size(); ++i) { mols.push_back(oldMol); } std::vector<OpenBabel::OBMol> validMols; for (unsigned int i(0); i < mols.size(); ++i) { mols[i] = RemoveRing(mols[i], allrings, i); if (!mols[i].Empty()) { // Has aromaticity been broken? bool broken(false); for (atom = mols[i].BeginAtom(avi); atom; atom = mols[i].NextAtom(avi)) { if (atom->IsInRing() && !atom->IsAromatic()) { broken = true; break; } } if (!broken) { validMols.push_back(mols[i]); } } } if (validMols.size() == 1) { return validMols[0]; } return oldMol; }
void FilterRingsystems::Calculate(OpenBabel::OBMol* mol) { // Are there rings? bool rings(false); OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) { if (atom->IsInRing()) { rings = true; break; } } if (rings) { // Make workcopy of original mol OpenBabel::OBMol m = *mol; m.DeleteHydrogens(); // Remove all atoms that are not part of ring std::vector<OpenBabel::OBAtom*> nonRingAtoms; nonRingAtoms.clear(); for (atom = m.BeginAtom(i); atom; atom = m.NextAtom(i)) { if (!atom->IsInRing()) nonRingAtoms.push_back(atom); } for (unsigned int i(0); i < nonRingAtoms.size(); ++i) { m.DeleteAtom(nonRingAtoms[i]); } // Remove all bonds that are not part of a ring std::vector<OpenBabel::OBBond*> nonRingBonds; nonRingBonds.clear(); OpenBabel::OBBond* bond; std::vector<OpenBabel::OBBond*>::iterator j; for (bond = m.BeginBond(j); bond; bond = m.NextBond(j)) { if (!bond->IsInRing()) nonRingBonds.push_back(bond); } for (unsigned int i(0); i < nonRingBonds.size(); ++i) { m.DeleteBond(nonRingBonds[i]); } // Count ringsystems std::vector<std::vector< int > > ringsystems; m.ContigFragList(ringsystems); _result = ringsystems.size(); } else { _result = 0; } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } }