OpenBabel::OBMol Schuffenhauer::Rule_1(OpenBabel::OBMol& oldMol) { if (oldMol.GetSSSR().size() <= _ringsToBeRetained) { return oldMol; } OpenBabel::OBMol newMol(oldMol); std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBBondIterator bi; OpenBabel::OBAtom* atom; OpenBabel::OBAtom* nbrAtom[2]; for (atom = newMol.BeginAtom(avi); atom; atom = newMol.NextAtom(avi)) { if ((atom->MemberOfRingSize() == 3) && (atom->IsNitrogen() || atom->IsOxygen()) && (atom->MemberOfRingCount() == 1) && (atom->GetHvyValence() == 2)) { nbrAtom[0] = atom->BeginNbrAtom(bi); nbrAtom[1] = atom->NextNbrAtom(bi); if (nbrAtom[0] && nbrAtom[1]) { newMol.DeleteAtom(atom); newMol.GetBond(nbrAtom[0], nbrAtom[1])->SetBondOrder(2); } } } return newMol; }
OpenBabel::OBMol Schuffenhauer::Rule_6(OpenBabel::OBMol& oldMol) { std::vector<OpenBabel::OBRing*> allrings(oldMol.GetSSSR()); if (allrings.size() <= _ringsToBeRetained) { return oldMol; } std::vector<OpenBabel::OBMol> mols; std::vector<int> rings; int size; for (unsigned int i(0); i < allrings.size(); ++i) { size = allrings[i]->Size(); if ((size == 3) || (size == 5) || (size == 6)) { mols.push_back(oldMol); rings.push_back(i); } } if (mols.empty()) { return oldMol; } // Only focus on ringsystems with more than one ring std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBAtom* atom; std::vector<int> fusedRings; for (unsigned int i(0); i < rings.size(); ++i) { for (atom = oldMol.BeginAtom(avi); atom; atom = oldMol.NextAtom(avi)) { if (allrings[rings[i]]->IsMember(atom) && (atom->MemberOfRingCount() > 1)) { fusedRings.push_back(rings[i]); break; } } } if (fusedRings.empty()) { return oldMol; } std::vector<OpenBabel::OBMol> validMols; for (unsigned int i(0); i < fusedRings.size(); ++i) { mols[i] = RemoveRing(mols[i], allrings, fusedRings[i]); if (!mols[i].Empty()) { validMols.push_back(mols[i]); } } if (validMols.size() == 1) { return validMols[0]; } return oldMol; }
OpenBabel::OBMol Schuffenhauer::Rule_4(OpenBabel::OBMol& oldMol) { std::vector<OpenBabel::OBRing*> allrings(oldMol.GetSSSR()); if (allrings.size() <= _ringsToBeRetained) { return oldMol; } // Only focus on ringsystems with more than one ring std::vector<OpenBabel::OBAtom*>::iterator avi; std::vector<OpenBabel::OBMol> mols; OpenBabel::OBAtom* atom; std::vector<int> fusedRings; for (unsigned int i(0); i < allrings.size(); ++i) { for (atom = oldMol.BeginAtom(avi); atom; atom = oldMol.NextAtom(avi)) { if (allrings[i]->IsMember(atom) && (atom->MemberOfRingCount() > 1)) { fusedRings.push_back(i); mols.push_back(oldMol); break; } } } if (fusedRings.empty()) { return oldMol; } std::vector<OpenBabel::OBMol> validMols; for (unsigned int i(0); i < fusedRings.size(); ++i) { mols[i] = RemoveRing(mols[i], allrings, fusedRings[i]); if (!mols[i].Empty()) { validMols.push_back(mols[i]); } } if (validMols.empty()) { return oldMol; } int delta; int absdelta; std::vector<int> score; for (unsigned int i(0); i < validMols.size(); ++i) { delta = CalculateDelta(validMols[i]); absdelta = abs(delta); score.push_back(1000 * absdelta + delta); } int maximum = score[0]; for (unsigned int i(1); i < validMols.size(); ++i) { if (score[i] > maximum) { maximum = score[i]; } } unsigned int oldMolecules = validMols.size(); std::vector<OpenBabel::OBMol> remainingMols; for (unsigned int i(0); i < validMols.size(); ++i) { if (score[i] == maximum) { remainingMols.push_back(validMols[i]); } } if (remainingMols.size() == 1) { return remainingMols[0]; } return oldMol; }