void OBMol::FindRingAtomsAndBonds() { if (HasFlag(OB_RINGFLAGS_MOL)) return; SetFlag(OB_RINGFLAGS_MOL); obErrorLog.ThrowError(__FUNCTION__, "Ran OpenBabel::FindRingAtomsAndBonds", obAuditMsg); OBBitVec avisit,bvisit; avisit.Resize(NumAtoms()+1); bvisit.Resize(NumAtoms()+1); vector<int> path; path.resize(NumAtoms()+1); for(unsigned int i=1; i<= NumAtoms(); i++ ) if(!avisit[i]) FindRings(*this,path,avisit,bvisit,i,0); }
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); } }