void FilterRings::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) { std::vector<OpenBabel::OBRing* > nrings = mol->GetSSSR(); _result = nrings.size(); } else { _result = 0; } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } }
void FilterNonaromaticRingFraction::Calculate(OpenBabel::OBMol* mol) { // Are there atoms and rings? unsigned int rings(0); unsigned int natoms(0); OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; for (atom = mol->BeginAtom(i); atom; atom = mol->NextAtom(i)) { if (atom->IsHydrogen()) continue; if (atom->IsInRing()) ++rings; ++natoms; } if (!natoms) { _result = 0.0; _passed = false; return; } std::set<int> uniqRingIdx; if (rings) { std::vector<OpenBabel::OBRing*> nrings = mol->GetSSSR(); uniqRingIdx.clear(); std::vector<int>::iterator path; std::vector<OpenBabel::OBRing*>::iterator ri; for (ri = nrings.begin(); ri != nrings.end(); ++ri) { if (!(*ri)->IsAromatic()) { for (path = (*ri)->_path.begin(); path != (*ri)->_path.end(); ++path) { uniqRingIdx.insert(*path); } } } } unsigned int ar(uniqRingIdx.size()); if (ar) { _result = (double) ar / (double) natoms; } else { _result = 0.0; } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } }
void FilterCores::Calculate(OpenBabel::OBMol* mol) { // Any rings? OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool rings(false); 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(); // Iteratively remove all endstanding atoms until none are left OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool endstanding(true); while (endstanding && m.NumAtoms()) { endstanding = false; for (atom = m.BeginAtom(i); atom; atom = m.NextAtom(i)) { if (atom->GetValence() < 2) { if (m.DeleteAtom(atom)) { endstanding = true; break; } } } } if (m.NumAtoms()) _result = 1; else _result = 0; } else { _result = 0; } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } }
void FilterAtomsInLargestNonaromaticRing::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) { std::vector<OpenBabel::OBRing*> nrings = mol->GetSSSR(); _result = 0; std::vector<OpenBabel::OBRing*>::iterator ri; for (ri = nrings.begin(); ri != nrings.end(); ++ri) { if ( !(*ri)->IsAromatic() && ((*ri)->Size() > _result)) { _result = (*ri)->Size(); } } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } } else { _result = 0; _passed = true; } }
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; }
void FilterBridgeFraction::Calculate(OpenBabel::OBMol* mol) { // Are there rings? OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool rings(false); 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(); unsigned int natoms(m.NumAtoms()); if (!natoms) { _result = 0.0; _passed = false; return; } // Iteratively remove all endstanding atoms until none are left OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool endstanding(true); while (endstanding && m.NumAtoms()) { endstanding = false; for (atom = m.BeginAtom(i); atom; atom = m.NextAtom(i)) { if (atom->GetValence() < 2) { if (m.DeleteAtom(atom)) { endstanding = true; break; } } } } // Now remove all ring atoms rings = true; while (rings && m.NumAtoms()) { rings = false; for (atom = m.BeginAtom(i); atom; atom = m.NextAtom(i)) { if (atom->IsInRing()) { if (m.DeleteAtom(atom)) { rings = true; break; } } } } _result = (double) m.NumAtoms() / (double) natoms; } else { _result = 0.0; } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } }
void FilterAtomsInSmallestBridge::Calculate(OpenBabel::OBMol* mol) { // Are there rings? OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool rings(false); 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(); // Iteratively remove all endstanding atoms until none are left OpenBabel::OBAtom* atom; std::vector<OpenBabel::OBAtom*>::iterator i; bool endstanding(true); while (endstanding && m.NumAtoms()) { endstanding = false; for (atom = m.BeginAtom(i); atom; atom = m.NextAtom(i)) { if (atom->GetValence() < 2) { if (m.DeleteAtom(atom)) { endstanding = true; break; } } } } // Now remove all ring atoms rings = true; while (rings && m.NumAtoms()) { rings = false; for (atom = m.BeginAtom(i); atom; atom = m.NextAtom(i)) { if (atom->IsInRing()) { if (m.DeleteAtom(atom)) { rings = true; break; } } } } // Separate into fragments if (m.NumAtoms()) { std::vector<std::vector<int> > bridges; m.ContigFragList(bridges); _result = bridges[0].size(); for (unsigned int i(1); i < bridges.size(); ++i) { if (bridges[i].size() < _result) _result = bridges[i].size(); } } if ((_minLimit && (_result < _min)) || (_maxLimit && (_result > _max))) { _passed = false; } else { _passed = true; } } else { _result = 0; _passed = true; } }
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; }
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; } }