bool MacroModFormat::ReadMolecule(OBBase* pOb, OBConversion* pConv) { OBMol* pmol = pOb->CastAndClear<OBMol>(); if(pmol==NULL) return false; //Define some references so we can use the old parameter names istream &ifs = *pConv->GetInStream(); OBMol &mol = *pmol; const char* defaultTitle = pConv->GetTitle(); // Get Title char buffer[BUFF_SIZE]; int natoms; vector<vector<pair<int,int> > > connections; if (ifs.getline(buffer,BUFF_SIZE)) { vector<string> vs; tokenize(vs,buffer," \n"); if ( !vs.empty() && vs.size() > 0) sscanf(buffer,"%i%*s",&natoms); if (natoms == 0) return false; if ( !vs.empty() && vs.size() > 1) mol.SetTitle(vs[1]); else { string s = defaultTitle; mol.SetTitle(defaultTitle); } } else return(false); mol.BeginModify(); mol.ReserveAtoms(natoms); connections.resize(natoms+1); /***********************************************************************/ // Get Type Bonds, BondOrder, X, Y, Z double x,y,z; vector3 v; char temp_type[10]; int i,j; double charge; OBAtom atom; ttab.SetFromType("MMD"); for (i = 1; i <= natoms; i++) { if (!ifs.getline(buffer,BUFF_SIZE)) break; int end[6], order[6]; sscanf(buffer,"%9s%d%d%d%d%d%d%d%d%d%d%d%d%lf%lf%lf", temp_type,&end[0],&order[0],&end[1],&order[1],&end[2],&order[2], &end[3], &order[3], &end[4], &order[4], &end[5], &order[5], &x, &y, &z); pair<int,int> tmp; for ( j = 0 ; j <=5 ; j++ ) { if ( end[j] > 0 && end[j] > i) { tmp.first = end[j]; tmp.second = order[j]; connections[i].push_back(tmp); } } v.SetX(x); v.SetY(y); v.SetZ(z); atom.SetVector(v); string str = temp_type,str1; ttab.SetToType("ATN"); ttab.Translate(str1,str); atom.SetAtomicNum(atoi(str1.c_str())); ttab.SetToType("INT"); ttab.Translate(str1,str); atom.SetType(str1); // stuff for optional fields buffer[109]='\0'; sscanf(&buffer[101],"%lf", &charge); atom.SetPartialCharge(charge); mol.AddAtom(atom); } for (i = 1; i <= natoms; i++) for (j = 0; j < (signed)connections[i].size(); j++) mol.AddBond(i, connections[i][j].first, connections[i][j].second); mol.EndModify(); OBBond *bond; vector<OBBond*>::iterator bi; for (bond = mol.BeginBond(bi);bond;bond = mol.NextBond(bi)) if (bond->GetBO() == 5 && !bond->IsInRing()) bond->SetBO(1); if ( natoms != (signed)mol.NumAtoms() ) return(false); // clean out remaining blank lines while(ifs.peek() != EOF && ifs.good() && (ifs.peek() == '\n' || ifs.peek() == '\r')) ifs.getline(buffer,BUFF_SIZE); return(true); }
bool OBChemTsfm::Apply(OBMol &mol) { if (!_bgn.Match(mol)) return(false); vector<vector<int> > mlist = _bgn.GetUMapList(); obErrorLog.ThrowError(__FUNCTION__, "Ran OpenBabel::OBChemTransform", obAuditMsg); if (!_vchrg.empty()) //modify charges { vector<vector<int> >::iterator i; vector<pair<int,int> >::iterator j; for (i = mlist.begin();i != mlist.end();++i) for (j = _vchrg.begin();j != _vchrg.end();++j) if (j->first < (signed)i->size()) //goof proofing mol.GetAtom((*i)[j->first])->SetFormalCharge(j->second); mol.UnsetImplicitValencePerceived(); } if (!_vbond.empty()) //modify bond orders { OBBond *bond; vector<vector<int> >::iterator i; vector<pair<pair<int,int>,int> >::iterator j; for (i = mlist.begin();i != mlist.end();++i) for (j = _vbond.begin();j != _vbond.end();++j) { bond = mol.GetBond((*i)[j->first.first],(*i)[j->first.second]); if (!bond) { obErrorLog.ThrowError(__FUNCTION__, "unable to find bond", obDebug); continue; } bond->SetBO(j->second); } } if (!_vadel.empty() || !_vele.empty()) //delete atoms and change elements { vector<int>::iterator j; vector<vector<int> >::iterator i; if (!_vele.empty()) { vector<pair<int,int> >::iterator k; for (i = mlist.begin();i != mlist.end();++i) for (k = _vele.begin();k != _vele.end();++k) mol.GetAtom((*i)[k->first])->SetAtomicNum(k->second); } //make sure same atom isn't deleted twice vector<bool> vda; vector<OBAtom*> vdel; vda.resize(mol.NumAtoms()+1,false); for (i = mlist.begin();i != mlist.end();++i) for (j = _vadel.begin();j != _vadel.end();++j) if (!vda[(*i)[*j]]) { vda[(*i)[*j]] = true; vdel.push_back(mol.GetAtom((*i)[*j])); } vector<OBAtom*>::iterator k; for (k = vdel.begin();k != vdel.end();++k) mol.DeleteAtom((OBAtom*)*k); } return(true); }