//! Sets atom->IsChiral() to true for chiral atoms void OBMol::FindChiralCenters() { if (HasChiralityPerceived()) return; SetChiralityPerceived(); obErrorLog.ThrowError(__FUNCTION__, "Ran OpenBabel::FindChiralCenters", obAuditMsg); //do quick test to see if there are any possible chiral centers bool mayHaveChiralCenter=false; OBAtom *atom,*nbr; vector<OBAtom*>::iterator i; for (atom = BeginAtom(i);atom;atom = NextAtom(i)) if (atom->GetHyb() == 3 && atom->GetHvyValence() >= 3) { mayHaveChiralCenter=true; break; } if (!mayHaveChiralCenter) return; OBBond *bond; vector<OBBond*>::iterator j; for (bond = BeginBond(j);bond;bond = NextBond(j)) if (bond->IsWedge() || bond->IsHash()) (bond->GetBeginAtom())->SetChiral(); vector<unsigned int> vgid; GetGIDVector(vgid); vector<unsigned int> tlist; vector<unsigned int>::iterator k; bool ischiral; for (atom = BeginAtom(i);atom;atom = NextAtom(i)) if (atom->GetHyb() == 3 && atom->GetHvyValence() >= 3 && !atom->IsChiral()) { tlist.clear(); ischiral = true; for (nbr = atom->BeginNbrAtom(j);nbr;nbr = atom->NextNbrAtom(j)) { for (k = tlist.begin();k != tlist.end();++k) if (vgid[nbr->GetIdx()-1] == *k) ischiral = false; if (ischiral) tlist.push_back(vgid[nbr->GetIdx()-1]); else break; } if (ischiral) atom->SetChiral(); } }
void OBMol::FindSSSR() { if (HasSSSRPerceived()) return; SetSSSRPerceived(); obErrorLog.ThrowError(__FUNCTION__, "Ran OpenBabel::FindSSSR", obAuditMsg); // Delete any old data before we start finding new rings // The following procedure is slow // So if client code is multi-threaded, we don't want to make them wait if (HasData("SSSR")) { DeleteData("SSSR"); } OBRing *ring; vector<OBRing*>::iterator j; //get Frèrejacque taking int account multiple possible spanning graphs int frj = DetermineFRJ(*this); if (frj) { vector<OBRing*> vr; FindRingAtomsAndBonds(); OBBond *bond; vector<OBBond*> cbonds; vector<OBBond*>::iterator k; //restrict search for rings around closure bonds for (bond = BeginBond(k);bond;bond = NextBond(k)) if (bond->IsClosure()) cbonds.push_back(bond); if (!cbonds.empty()) { OBRingSearch rs; //search for all rings about closures vector<OBBond*>::iterator i; for (i = cbonds.begin();i != cbonds.end();++i) rs.AddRingFromClosure(*this,(OBBond*)*i); rs.SortRings(); rs.RemoveRedundant(frj); //store the SSSR set for (j = rs.BeginRings();j != rs.EndRings();++j) { ring = new OBRing ((*j)->_path,NumAtoms()+1); ring->SetParent(this); vr.push_back(ring); } //rs.WriteRings(); } OBRingData *rd = new OBRingData(); rd->SetOrigin(perceived); // to separate from user or file input rd->SetAttribute("SSSR"); rd->SetData(vr); SetData(rd); } }