bool Oprea_1::CalculateScaffold(const OpenBabel::OBMol& mol, Options* o) { OpenBabel::OBMol m(mol); OpenBabel::OBAtom* atom; OpenBabel::OBAtom* nbrAtom[2]; OpenBabel::OBBondIterator bi; std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBBond* bond; std::vector<OpenBabel::OBBond*>::iterator bvi; bool removed(true); while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if (IsEndStanding(atom, false, false)) { m.DeleteAtom(atom); removed = true; break; } } } // Make all atoms as neutral C and all bond orders equal to 1 m.BeginModify(); for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { atom->SetAtomicNum(6); atom->SetFormalCharge(0); } for (bond = m.BeginBond(bvi); bond; bond = m.NextBond(bvi)) { bond->SetBondOrder(1); } m.EndModify(); // Transform all neighbouring linker atoms into a single bond removed = true; while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if (!atom->IsInRing() && (atom->GetValence() == 2)) { nbrAtom[0] = atom->BeginNbrAtom(bi); nbrAtom[1] = atom->NextNbrAtom(bi); if (nbrAtom[0] && nbrAtom[1]) { m.BeginModify(); m.AddBond(nbrAtom[0]->GetIdx(), nbrAtom[1]->GetIdx(), 1); m.DeleteAtom(atom); m.EndModify(); removed = true; break; } } } } // Shrink all rings to their minimum size removed = true; while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if ((atom->MemberOfRingSize() > 3) && (atom->GetValence() == 2)) { nbrAtom[0] = atom->BeginNbrAtom(bi); nbrAtom[1] = atom->NextNbrAtom(bi); if (nbrAtom[0] && nbrAtom[1]) { m.BeginModify(); m.AddBond(nbrAtom[0]->GetIdx(), nbrAtom[1]->GetIdx(), 1); m.DeleteAtom(atom); m.EndModify(); removed = true; break; } } } } if (!m.Empty()) { _smiles = _mol2can.WriteString(&m, true); } else { _smiles = "-"; return false; } return true; }
bool Oprea_2::CalculateScaffold(const OpenBabel::OBMol& mol, Options* o) { OpenBabel::OBMol m(mol); // Tag all HBD std::vector<bool> hbd(m.NumAtoms() + 1); for (OpenBabel::OBMolAtomIter atom(m); atom; ++atom) { if (atom->MatchesSMARTS("[NH,NH2,NH3,OH,nH]")) { hbd[atom->GetIdx()] = true; } else { hbd[atom->GetIdx()] = false; } } // Tag all HBA std::vector<bool> hba(m.NumAtoms() + 1); for (OpenBabel::OBMolAtomIter atom(m); atom; ++atom) { if (!atom->IsAmideNitrogen() && // No amide nitrogen !atom->IsAromatic() && // Not aromatic (atom->GetFormalCharge() <= 0) && // No + charge atom->MatchesSMARTS("[NH0]")) // No hydrogens { hba[atom->GetIdx()] = true; } else if (atom->IsNitrogen() && // Nitrogen atom->IsAromatic() && // Aromatic atom->MatchesSMARTS("[nH0]") && // No hydrogens (atom->GetHvyValence() <= 2) && // Maximal two non-H atoms connected (atom->GetFormalCharge() <= 0)) // No + charge { hba[atom->GetIdx()] = true; } else if (atom->IsOxygen() && // Oxygen (atom->GetFormalCharge() <= 0)) // No + charge { hba[atom->GetIdx()] = true; } else { hba[atom->GetIdx()] = false; } } // Mark the C(=O) or S(=O) also as HBA for (OpenBabel::OBMolAtomIter atom(m); atom; ++atom) { if (atom->MatchesSMARTS("C=O")) { hba[atom->GetIdx()] = true; } else if (atom->MatchesSMARTS("S=O")) { hba[atom->GetIdx()] = true; } } // Make all atoms as neutral C, N (HBD), or O (HBA) m.BeginModify(); std::vector<OpenBabel::OBAtom*>::iterator avi; OpenBabel::OBAtom* atom; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if (hba[atom->GetIdx()]) { atom->SetAtomicNum(8); } else if (hbd[atom->GetIdx()]) { atom->SetAtomicNum(7); } else { atom->SetAtomicNum(6); } atom->SetFormalCharge(0); } m.EndModify(); // Remove all endstanding atoms OpenBabel::OBBondIterator bi; OpenBabel::OBBond* bond; std::vector<OpenBabel::OBBond*>::iterator bvi; bool removed(true); while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if (IsEndStanding(atom, false, false)) { m.DeleteAtom(atom); removed = true; break; } } } // Set all bond orders equal to 1 m.BeginModify(); for (bond = m.BeginBond(bvi); bond; bond = m.NextBond(bvi)) { bond->SetBondOrder(1); } m.EndModify(); // Transform all neighbouring linker atoms into a single bond removed = true; OpenBabel::OBAtom* nbrAtom[2]; while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if (!atom->IsInRing() && (atom->GetValence() == 2)) { m.BeginModify(); nbrAtom[0] = atom->BeginNbrAtom(bi); nbrAtom[1] = atom->NextNbrAtom(bi); if (nbrAtom[0] && nbrAtom[1]) { m.AddBond(nbrAtom[0]->GetIdx(), nbrAtom[1]->GetIdx(), 1); m.DeleteAtom(atom); m.EndModify(); removed = true; break; } } } } // Shrink all rings to their minimum size removed = true; while (removed) { removed = false; for (atom = m.BeginAtom(avi); atom; atom = m.NextAtom(avi)) { if ((atom->MemberOfRingSize() > 3) && (atom->GetValence() == 2)) { nbrAtom[0] = atom->BeginNbrAtom(bi); nbrAtom[1] = atom->NextNbrAtom(bi); if (nbrAtom[0] && nbrAtom[1]) { if (nbrAtom[0]->GetAtomicNum() == atom->GetAtomicNum()) { m.BeginModify(); m.AddBond(nbrAtom[0]->GetIdx(), nbrAtom[1]->GetIdx(), 1); m.DeleteAtom(atom); m.EndModify(); removed = true; break; } else if (nbrAtom[1]->GetAtomicNum() == atom->GetAtomicNum()) { m.BeginModify(); m.AddBond(nbrAtom[0]->GetIdx(), nbrAtom[1]->GetIdx(), 1); m.DeleteAtom(atom); m.EndModify(); removed = true; break; } } } } } if (!m.Empty()) { _smiles = _mol2can.WriteString(&m, true); } else { _smiles = "-"; return false; } return true; }