void OBAtomTyper::AssignImplicitValence(OBMol &mol) { // FF Make sure that valence has not been perceived if(mol.HasImplicitValencePerceived()) return; if (!_init) Init(); mol.SetImplicitValencePerceived(); obErrorLog.ThrowError(__FUNCTION__, "Ran OpenBabel::AssignImplicitValence", obAuditMsg); // FF Ensure that the aromatic typer will not be called int oldflags = mol.GetFlags(); // save the current state flags mol.SetAromaticPerceived(); // and set the aromatic perceived flag on OBAtom *atom; vector<OBAtom*>::iterator k; for (atom = mol.BeginAtom(k);atom;atom = mol.NextAtom(k)) atom->SetImplicitValence(atom->GetValence()); vector<vector<int> >::iterator j; vector<pair<OBSmartsPattern*,int> >::iterator i; for (i = _vimpval.begin();i != _vimpval.end();++i) if (i->first->Match(mol)) { _mlist = i->first->GetMapList(); for (j = _mlist.begin();j != _mlist.end();++j) mol.GetAtom((*j)[0])->SetImplicitValence(i->second); } if (!mol.HasAromaticCorrected()) CorrectAromaticNitrogens(mol); for (atom = mol.BeginAtom(k);atom;atom = mol.NextAtom(k)) { if (atom->GetImplicitValence() < atom->GetValence()) atom->SetImplicitValence(atom->GetValence()); } // FF Come back to the initial flags mol.SetFlags(oldflags); return; }
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; }