//preprocess molecule into a standardized state for heavy atom rmsd computation static void processMol(OBMol& mol) { //isomorphismmapper wants isomorphic atoms to have the same aromatic and ring state, //but these proporties aren't reliable enough to be trusted in evaluating molecules //should be considered the same based solely on connectivity mol.DeleteHydrogens(); //heavy atom rmsd for(OBAtomIterator aitr = mol.BeginAtoms(); aitr != mol.EndAtoms(); aitr++) { OBAtom *a = *aitr; a->UnsetAromatic(); a->SetInRing(); } for(OBBondIterator bitr = mol.BeginBonds(); bitr != mol.EndBonds(); bitr++) { OBBond *b = *bitr; b->UnsetAromatic(); b->SetBondOrder(1); b->SetInRing(); } //avoid recomputations mol.SetHybridizationPerceived(); mol.SetRingAtomsAndBondsPerceived(); mol.SetAromaticPerceived(); }
static void FindRings(OBMol &mol,vector<int> &path,OBBitVec &avisit, OBBitVec &bvisit, int natom,int depth ) { OBAtom *atom; OBBond *bond; vector<OBBond*>::iterator k; // don't return if all atoms are visited // (For example, some atoms are in multiple rings!) -GRH if (avisit[natom]) { int j = depth-1; bond=mol.GetBond(path[j--]); bond->SetInRing(); while( j >= 0 ) { bond=mol.GetBond(path[j--]); bond->SetInRing(); (bond->GetBeginAtom())->SetInRing(); (bond->GetEndAtom())->SetInRing(); if(bond->GetBeginAtomIdx()==static_cast<unsigned int>(natom) || bond-> GetEndAtomIdx()==static_cast<unsigned int>(natom)) break; } } else { avisit.SetBitOn(natom); atom = mol.GetAtom(natom); for(bond = atom->BeginBond(k);bond;bond=atom->NextBond(k)) if( !bvisit[bond->GetIdx()]) { path[depth] = bond->GetIdx(); bvisit.SetBitOn(bond->GetIdx()); FindRings(mol,path,avisit,bvisit,bond->GetNbrAtomIdx(atom), depth+1); } } }
/* A recursive O(N) traversal of the molecule */ static int FindRings(OBAtom *atom, int *avisit, unsigned char *bvisit, unsigned int &frj, int depth) { OBBond *bond; int result = -1; vector<OBBond*>::iterator k; for(bond = atom->BeginBond(k);bond;bond=atom->NextBond(k)) { unsigned int bidx = bond->GetIdx(); if (bvisit[bidx] == 0) { bvisit[bidx] = 1; OBAtom *nbor = bond->GetNbrAtom(atom); unsigned int nidx = nbor->GetIdx(); int nvisit = avisit[nidx]; if (nvisit == 0) { avisit[nidx] = depth+1; nvisit = FindRings(nbor,avisit,bvisit,frj,depth+1); if (nvisit > 0) { if (nvisit <= depth) { bond->SetInRing(); if (result < 0 || nvisit < result) result = nvisit; } } } else { if (result < 0 || nvisit < result) result = nvisit; bond->SetClosure(); bond->SetInRing(); frj++; } } } if (result > 0 && result <= depth) atom->SetInRing(); return result; }