OpenBabel::OBMol Schuffenhauer::Rule_11(OpenBabel::OBMol& oldMol) { // Return if the molecule contains an acyclic linker std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBAtom* atom; for (atom = oldMol.BeginAtom(avi); atom; atom = oldMol.NextAtom(avi)) { if (!atom->IsInRing() && atom->GetValence() >= 2) { return oldMol; } } // Make sure we are dealing with a mixed aromatic/nonaromatic system bool notaromatic(false); bool aromatic(false); for (atom = oldMol.BeginAtom(avi); atom; atom = oldMol.NextAtom(avi)) { if (atom->IsAromatic()) { aromatic = true; } else { notaromatic = true; } } if (aromatic && notaromatic) { std::vector<OpenBabel::OBRing*> allrings(oldMol.GetSSSR()); if (allrings.size() <= _ringsToBeRetained) { return oldMol; } std::vector<OpenBabel::OBMol> mols; std::vector<unsigned int> aromaticRings; for (unsigned int i(0); i < allrings.size(); ++i) { if (allrings[i]->IsAromatic()) { mols.push_back(oldMol); aromaticRings.push_back(i); } } std::vector<OpenBabel::OBMol> validMols; for (unsigned int i(0); i < aromaticRings.size(); ++i) { mols[i] = RemoveRing(mols[i], allrings, aromaticRings[i]); if (!mols[i].Empty()) { validMols.push_back(mols[i]); } } if (validMols.size() == 1) { return validMols[0]; } } return oldMol; }
bool _hAccDelocalized(OpenBabel::OBAtom* a) { if (a->GetAtomicNum() != 7) { return false; } if (a->IsAromatic() && a->GetImplicitValence() == 3) { return true; } std::vector<OpenBabel::OBBond*>::iterator bi1; for (OpenBabel::OBBond* b1 = a->BeginBond(bi1); b1; b1 = a->NextBond(bi1)) { OpenBabel::OBAtom* aa = b1->GetNbrAtom(a); if (aa->IsAromatic() && a->GetImplicitValence() == 3) { return true; } if (aa->GetAtomicNum() == 6) { std::vector<OpenBabel::OBBond*>::iterator bi2; for (OpenBabel::OBBond* b2 = aa->BeginBond(bi2); b2; b2 = aa->NextBond(bi2)) { OpenBabel::OBAtom* aaa = b2->GetNbrAtom(aa); if (aaa == a) { continue; } if (b2->GetBO() == 2) { if (aaa->GetAtomicNum() == 8) return true; if (aaa->GetAtomicNum() == 7) return true; if (aaa->GetAtomicNum() == 16) return true; } } } else if (aa->GetAtomicNum() == 16) { std::vector<OpenBabel::OBBond*>::iterator bi2; for (OpenBabel::OBBond* b2 = aa->BeginBond(bi2); b2; b2 = aa->NextBond(bi2)) { OpenBabel::OBAtom* aaa = b2->GetNbrAtom(aa); if (aaa == a) { continue; } if ((b2->GetBO() == 2) && (aaa->GetAtomicNum() == 8)) { 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; }