int main(int argc,char **argv) { // Create a test molecule OpenBabel::OBMol mol; OpenBabel::OBAtom* a[5]; a[0] = mol.NewAtom(); a[0]->SetAtomicNum(6); a[0]->SetVector(-0.013, 1.086, 0.008); a[1] = mol.NewAtom(); a[1]->SetAtomicNum(1); a[1]->SetVector( 0.002, -0.004, 0.002); a[2] = mol.NewAtom(); a[2]->SetAtomicNum(9); a[2]->SetVector( 1.300, 1.570, -0.002); a[3] = mol.NewAtom(); a[3]->SetAtomicNum(35); a[3]->SetVector(-0.964, 1.737, -1.585); a[4] = mol.NewAtom(); a[4]->SetAtomicNum(17); a[4]->SetVector(-0.857, 1.667, 1.491); OpenBabel::OBBond* b; for (int i(1); i < 5; ++i) { b = mol.NewBond(); b->SetBegin(a[0]); b->SetEnd(a[i]); b->SetBondOrder(1); } // Run the tests test01(&mol); test02(&mol); test03(&mol); test04(&mol); test05(&mol); test06(&mol); test07(&mol); test08(&mol); test09(&mol); // End return 0; }
int spectrophoretest(int argc, char* argv[]) { int defaultchoice = 1; int choice = defaultchoice; if (argc > 1) { if(sscanf(argv[1], "%d", &choice) != 1) { printf("Couldn't parse that input as a number\n"); return -1; } } // Create a test molecule OpenBabel::OBMol mol; OpenBabel::OBAtom* a[5]; a[0] = mol.NewAtom(); a[0]->SetAtomicNum(6); a[0]->SetVector(-0.013, 1.086, 0.008); a[1] = mol.NewAtom(); a[1]->SetAtomicNum(1); a[1]->SetVector( 0.002, -0.004, 0.002); a[2] = mol.NewAtom(); a[2]->SetAtomicNum(9); a[2]->SetVector( 1.300, 1.570, -0.002); a[3] = mol.NewAtom(); a[3]->SetAtomicNum(35); a[3]->SetVector(-0.964, 1.737, -1.585); a[4] = mol.NewAtom(); a[4]->SetAtomicNum(17); a[4]->SetVector(-0.857, 1.667, 1.491); OpenBabel::OBBond* b; for (int i(1); i < 5; ++i) { b = mol.NewBond(); b->SetBegin(a[0]); b->SetEnd(a[i]); b->SetBondOrder(1); } switch(choice) { case 1: test01(&mol); test02(&mol); break; case 2: test03(&mol); test04(&mol); break; case 3: test05(&mol); test06(&mol); break; case 4: test07(&mol); test08(&mol); break; case 5: test09(&mol); break; default: std::cout << "Test number " << choice << " does not exist!\n"; return -1; } return 0; }
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; }
OpenBabel::OBMol Schuffenhauer::RemoveRing(OpenBabel::OBMol& oldMol, std::vector<OpenBabel::OBRing*>& rings, unsigned int ringIdx) { OpenBabel::OBMol newMol(oldMol); // Make list of the ring bonds std::set<OpenBabel::OBBond*> ringBonds; OpenBabel::OBBond* bond; std::vector<OpenBabel::OBBond*>::iterator bvi; for (bond = newMol.BeginBond(bvi); bond; bond = newMol.NextBond(bvi)) { if (rings[ringIdx]->IsMember(bond)) { ringBonds.insert(bond); } } // Make list of delocalizable bonds (aromatic, single and flanked by two double bonds) std::set<OpenBabel::OBBond*> delocalizableBonds; std::set<OpenBabel::OBBond*>::iterator bli; OpenBabel::OBBondIterator bi; OpenBabel::OBAtom* atom; OpenBabel::OBBond* nbrBond; unsigned int n; for (bli = ringBonds.begin(); bli != ringBonds.end(); ++bli) { bond = *bli; if ((bond->GetBondOrder() == 1) && bond->IsAromatic()) { n = 0; atom = bond->GetBeginAtom(); for (nbrBond = atom->BeginBond(bi); nbrBond; nbrBond = atom->NextBond(bi)) { if ((nbrBond != bond) && ringBonds.count(nbrBond) && (nbrBond->GetBondOrder() == 2)) { ++n; } } atom = bond->GetEndAtom(); for (nbrBond = atom->BeginBond(bi); nbrBond; nbrBond = atom->NextBond(bi)) { if ((nbrBond != bond) && ringBonds.count(nbrBond) && (nbrBond->GetBondOrder() == 2)) { ++n; } } } if (n == 2) { delocalizableBonds.insert(bond); } } // Make list of bonds which form the fusion with other rings std::set<OpenBabel::OBBond*> fusionBonds; for (bli = ringBonds.begin(); bli != ringBonds.end(); ++bli) { bond = *bli; for (unsigned int i(0); i < rings.size(); ++i) { if (i != ringIdx) { if (rings[i]->IsMember(bond)) { fusionBonds.insert(bond); } } } } // Make list of bonds which are the fusion between aromatic and non-aromatic std::set<OpenBabel::OBBond*> aromaticNonaromaticFusionBonds; if (rings[ringIdx]->IsAromatic()) { for (bli = fusionBonds.begin(); bli != fusionBonds.end(); ++bli) { bond = *bli; for (unsigned int i(0); i < rings.size(); ++i) { if (i != ringIdx) { if (rings[i]->IsMember(bond) && !rings[i]->IsAromatic()) { aromaticNonaromaticFusionBonds.insert(bond); } } } } } // Make list of bonds which are the fusion between aromatic and aromatic std::set<OpenBabel::OBBond*> aromaticAromaticFusionBonds; if (rings[ringIdx]->IsAromatic()) { for (bli = fusionBonds.begin(); bli != fusionBonds.end(); ++bli) { bond = *bli; for (unsigned int i(0); i < rings.size(); ++i) { if (i != ringIdx) { if (rings[i]->IsMember(bond) && rings[i]->IsAromatic()) { aromaticAromaticFusionBonds.insert(bond); } } } } } // Remove ring std::set<OpenBabel::OBBond*> bondsToBeDeleted; std::set<OpenBabel::OBAtom*> atomsToBeDeleted; OpenBabel::OBAtom* nbrAtom[2]; for (bli = ringBonds.begin(); bli != ringBonds.end(); ++bli) { bond = *bli; if (fusionBonds.count(bond)) { continue; } else { bondsToBeDeleted.insert(bond); nbrAtom[0] = bond->GetBeginAtom(); nbrAtom[1] = bond->GetEndAtom(); if (nbrAtom[0] && nbrAtom[1]) { if (nbrAtom[0]->MemberOfRingCount() == 1) { atomsToBeDeleted.insert(nbrAtom[0]); } if (nbrAtom[1]->MemberOfRingCount() == 1) { atomsToBeDeleted.insert(nbrAtom[1]); } } } } newMol.BeginModify(); for (bli = bondsToBeDeleted.begin(); bli != bondsToBeDeleted.end(); ++bli) { newMol.DeleteBond(*bli); } newMol.EndModify(); newMol.BeginModify(); std::set<OpenBabel::OBAtom*>::iterator ali; for (ali = atomsToBeDeleted.begin(); ali != atomsToBeDeleted.end(); ++ali) { newMol.DeleteAtom(*ali); } newMol.EndModify(); // Correct the bond orders of the ex-fusion bond(s) newMol.BeginModify(); for (bond = newMol.BeginBond(bvi); bond; bond = newMol.NextBond(bvi)) { if (aromaticNonaromaticFusionBonds.count(bond)) { bond->SetBondOrder(2); } else if (aromaticAromaticFusionBonds.count(bond) && delocalizableBonds.count(bond)) { bond->SetBondOrder(2); } } newMol.EndModify(); // Remove single atoms that originate from exocyclic bonds at ring (void) RemoveSidechains(&newMol); // Check if there are atoms with valences that are not allowed std::vector<OpenBabel::OBAtom*>::iterator avi; for (atom = newMol.BeginAtom(avi); atom; atom = newMol.NextAtom(avi)) { if (atom->IsCarbon() && (atom->BOSum() > 4)) { newMol.Clear(); break; } else if (atom->IsNitrogen() && (atom->BOSum() > 3)) { newMol.Clear(); break; } else if (atom->IsOxygen() && (atom->BOSum() > 2)) { newMol.Clear(); break; } } // Check if there are no discontinuous fragments if (newMol.Separate().size() > 1) { newMol.Clear(); } return newMol; }