//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(); }
void OBAromaticTyper::AssignAromaticFlags(OBMol &mol) { if (!_init) Init(); if (mol.HasAromaticPerceived()) return; mol.SetAromaticPerceived(); obErrorLog.ThrowError(__FUNCTION__, "Ran OpenBabel::AssignAromaticFlags", obAuditMsg); _vpa.clear(); _vpa.resize(mol.NumAtoms()+1); _velec.clear(); _velec.resize(mol.NumAtoms()+1); _root.clear(); _root.resize(mol.NumAtoms()+1); OBBond *bond; OBAtom *atom; vector<OBAtom*>::iterator i; vector<OBBond*>::iterator j; //unset all aromatic flags for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) atom->UnsetAromatic(); for (bond = mol.BeginBond(j);bond;bond = mol.NextBond(j)) bond->UnsetAromatic(); int idx; vector<vector<int> >::iterator m; vector<OBSmartsPattern*>::iterator k; //mark atoms as potentially aromatic for (idx=0,k = _vsp.begin();k != _vsp.end();++k,++idx) if ((*k)->Match(mol)) { _mlist = (*k)->GetMapList(); for (m = _mlist.begin();m != _mlist.end();++m) { _vpa[(*m)[0]] = true; _velec[(*m)[0]] = _verange[idx]; } } //sanity check - exclude all 4 substituted atoms and sp centers for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) { if (atom->GetImplicitValence() > 3) { _vpa[atom->GetIdx()] = false; continue; } switch(atom->GetAtomicNum()) { //phosphorus and sulfur may be initially typed as sp3 case 6: case 7: case 8: if (atom->GetHyb() != 2) _vpa[atom->GetIdx()] = false; break; } } //propagate potentially aromatic atoms for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) if (_vpa[atom->GetIdx()]) PropagatePotentialAromatic(atom); //select root atoms SelectRootAtoms(mol); ExcludeSmallRing(mol); //remove 3 membered rings from consideration //loop over root atoms and look for aromatic rings _visit.clear(); _visit.resize(mol.NumAtoms()+1); for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) if (_root[atom->GetIdx()]) CheckAromaticity(atom,14); //for (atom = mol.BeginAtom(i);atom;atom = mol.NextAtom(i)) // if (atom->IsAromatic()) // cerr << "aro = " <<atom->GetIdx() << endl; //for (bond = mol.BeginBond(j);bond;bond = mol.NextBond(j)) //if (bond->IsAromatic()) //cerr << bond->GetIdx() << ' ' << bond->IsAromatic() << endl; }