00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef __RD_SLNPARSEOPS_H__
00035 #define __RD_SLNPARSEOPS_H__
00036
00037 #include <vector>
00038 #include <GraphMol/SLNParse/SLNParse.h>
00039 #include <GraphMol/SLNParse/SLNAttribs.h>
00040 #include <GraphMol/RDKitBase.h>
00041 #include <GraphMol/RDKitQueries.h>
00042 #include <boost/lexical_cast.hpp>
00043
00044 namespace RDKit{
00045 namespace SLNParse{
00046 namespace {
00047
00048 void bookmarkAtomID(RWMol *mp,Atom *atom){
00049 PRECONDITION(mp,"bad molecule");
00050 PRECONDITION(atom,"bad atom");
00051 if(atom->hasProp("_AtomID")){
00052 unsigned int label;
00053 atom->getProp("_AtomID",label);
00054 if(mp->hasAtomBookmark(label)){
00055 std::stringstream err;
00056 err << "SLN Parser error: Atom ID " << label << " used a second time.";
00057 throw SLNParseException(err.str());
00058 }
00059 if(mp->hasBondBookmark(label)){
00060 std::stringstream err;
00061 err << "SLN Parser error: Atom ID " << label << " appears *after* its ring closure.";
00062 throw SLNParseException(err.str());
00063 }
00064 mp->setAtomBookmark(atom,label);
00065 }
00066 }
00067
00068
00069 template<typename BondType>
00070 void addBondToMol(RWMol *mp,BondType *bond){
00071 PRECONDITION(mp,"null molecule");
00072 PRECONDITION(bond,"null bond");
00073 mp->addBond(bond,true);
00074 if(bond->getBondType()==Bond::AROMATIC){
00075
00076
00077 bond->setIsAromatic(true);
00078 bond->getBeginAtom()->setIsAromatic(true);
00079 bond->getEndAtom()->setIsAromatic(true);
00080 }
00081 }
00082 }
00083
00084
00085
00086 template <typename AtomType>
00087 int startMol(std::vector<RWMol *> &molList,AtomType *firstAtom,bool doingQuery){
00088 PRECONDITION(firstAtom,"empty atom");
00089 RWMol *mp = new RWMol();
00090 mp->addAtom(firstAtom,true,true);
00091 bookmarkAtomID(mp,firstAtom);
00092
00093 if(!doingQuery){
00094
00095
00096 for(unsigned int i=0;i<firstAtom->getNumExplicitHs();++i){
00097 int hIdx=mp->addAtom(new Atom(1),false,true);
00098 mp->addBond(0,hIdx,Bond::SINGLE);
00099 }
00100 firstAtom->setNumExplicitHs(0);
00101 }
00102
00103 int sz = molList.size();
00104 molList.push_back(mp);
00105 return sz;
00106 };
00107
00108
00109
00110 template<typename AtomType,typename BondType>
00111 void addAtomToMol(std::vector<RWMol *> &molList,unsigned int idx,AtomType *atom,
00112 BondType *bond,bool doingQuery){
00113 PRECONDITION(idx<molList.size(),"bad index");
00114 RWMol *mp=molList[idx];
00115 PRECONDITION(mp,"null molecule");
00116 PRECONDITION(atom,"empty atom");
00117 PRECONDITION(bond,"null bond");
00118
00119 Atom *a1 = mp->getActiveAtom();
00120 int atomIdx1=a1->getIdx();
00121 int atomIdx2=mp->addAtom(atom,true,true);
00122 bookmarkAtomID(mp,atom);
00123 bond->setOwningMol(mp);
00124 bond->setBeginAtomIdx(atomIdx1);
00125 bond->setEndAtomIdx(atomIdx2);
00126 addBondToMol(mp,bond);
00127
00128 if(!doingQuery){
00129
00130
00131 for(unsigned int i=0;i<atom->getNumExplicitHs();++i){
00132 int hIdx=mp->addAtom(new Atom(1),false,true);
00133 mp->addBond(atomIdx2,hIdx,Bond::SINGLE);
00134 }
00135 atom->setNumExplicitHs(0);
00136 }
00137 }
00138
00139 template<typename AtomType>
00140 void addAtomToMol(std::vector<RWMol *> &molList,unsigned int idx,AtomType *atom,bool doingQuery){
00141 addAtomToMol(molList,idx,atom,new Bond(Bond::SINGLE),doingQuery);
00142 }
00143
00144
00145
00146
00147
00148
00149 template <typename BondType>
00150 void closeRingBond(std::vector<RWMol *> &molList,unsigned int molIdx,
00151 unsigned int ringIdx,BondType *bond,
00152 bool postponeAllowed=true){
00153 PRECONDITION(molIdx<molList.size(),"bad index");
00154 RWMol *mp=molList[molIdx];
00155 PRECONDITION(mp,"null molecule");
00156 PRECONDITION(bond,"Null bond");
00157
00158 if(!mp->hasAtomBookmark(ringIdx)){
00159 if(postponeAllowed){
00160
00161 bond->setOwningMol(mp);
00162 bond->setEndAtomIdx(mp->getActiveAtom()->getIdx());
00163 mp->setBondBookmark(bond,ringIdx);
00164 return;
00165 } else {
00166 std::stringstream err;
00167 err << "SLN Parser error: Ring closure " << ringIdx << " does not have a corresponding opener.";
00168 throw SLNParseException(err.str());
00169 }
00170 }
00171 Atom *opener=mp->getAtomWithBookmark(ringIdx);
00172 CHECK_INVARIANT(opener,"invalid atom");
00173
00174 Atom *closer=mp->getActiveAtom();
00175 bond->setOwningMol(mp);
00176 bond->setBeginAtom(opener);
00177 bond->setEndAtom(closer);
00178 addBondToMol(mp,bond);
00179 };
00180
00181 void closeRingBond(std::vector<RWMol *> &molList,unsigned int molIdx,unsigned int ringIdx){
00182 closeRingBond(molList,molIdx,ringIdx,new Bond(Bond::SINGLE));
00183 };
00184
00185
00186
00187 template <typename BondType>
00188 int addBranchToMol(std::vector<RWMol *> &molList,unsigned int molIdx,
00189 unsigned int branchIdx,BondType *&bond){
00190 PRECONDITION(molIdx<molList.size(),"bad index");
00191 RWMol *mp=molList[molIdx];
00192 PRECONDITION(mp,"null molecule");
00193 PRECONDITION(branchIdx<molList.size(),"bad index");
00194 RWMol *branch=molList[branchIdx];
00195 PRECONDITION(branch,"null branch");
00196 PRECONDITION(bond,"null bond");
00197
00198 unsigned int activeAtomIdx=mp->getActiveAtom()->getIdx();
00199 unsigned int nOrigAtoms=mp->getNumAtoms();
00200
00201
00202
00203
00204 mp->insertMol(*branch);
00205
00206
00207 for(ROMol::ATOM_BOOKMARK_MAP::const_iterator bmIt=branch->getAtomBookmarks()->begin();
00208 bmIt != branch->getAtomBookmarks()->end();++bmIt){
00209 if(bmIt->first<0) continue;
00210 if(mp->hasAtomBookmark(bmIt->first)){
00211 std::stringstream err;
00212 err << "SLN Parser error: Atom ID " << bmIt->first << " used a second time.";
00213 throw SLNParseException(err.str());
00214 } else if(mp->hasBondBookmark(bmIt->first)){
00215 std::stringstream err;
00216 err << "SLN Parser error: Atom ID " << bmIt->first << " appears *after* its ring closure.";
00217 throw SLNParseException(err.str());
00218 }
00219 else {
00220 CHECK_INVARIANT(bmIt->second.size()==1,"bad atom bookmark list on branch");
00221 Atom *tgtAtom=mp->getAtomWithIdx((*bmIt->second.begin())->getIdx()+nOrigAtoms);
00222 mp->setAtomBookmark(tgtAtom,bmIt->first);
00223 }
00224 }
00225
00226
00227 for(ROMol::BOND_BOOKMARK_MAP::const_iterator bmIt=branch->getBondBookmarks()->begin();
00228 bmIt != branch->getBondBookmarks()->end();++bmIt){
00229 CHECK_INVARIANT(bmIt->second.size()>=1,"bad bond bookmark list on branch");
00230 for(ROMol::BOND_PTR_LIST::const_iterator bondIt=bmIt->second.begin();
00231 bondIt!=bmIt->second.end();++bondIt){
00232 Bond *tgtBond=*bondIt;
00233 if(bmIt->first>0 && mp->hasAtomBookmark(bmIt->first)){
00234 Atom *tmpAtom=mp->getActiveAtom();
00235 mp->setActiveAtom(mp->getAtomWithIdx(tgtBond->getEndAtomIdx()+nOrigAtoms));
00236 closeRingBond(molList,molIdx,bmIt->first,tgtBond,false);
00237 mp->setActiveAtom(tmpAtom);
00238 } else {
00239
00240 tgtBond->setOwningMol(mp);
00241 tgtBond->setEndAtomIdx(tgtBond->getEndAtomIdx()+nOrigAtoms);
00242 mp->setBondBookmark(tgtBond,bmIt->first);
00243 }
00244 }
00245 }
00246
00247
00248 if(bond->getBondType()!=Bond::IONIC){
00249 bond->setOwningMol(mp);
00250 bond->setBeginAtomIdx(activeAtomIdx);
00251 bond->setEndAtomIdx(nOrigAtoms);
00252 addBondToMol(mp,bond);
00253 } else {
00254 delete bond;
00255 }
00256 bond=0;
00257
00258 delete branch;
00259 unsigned int sz = molList.size();
00260 if ( sz==branchIdx+1) {
00261 molList.resize( sz-1 );
00262 }
00263 return molIdx;
00264 };
00265
00266 int addBranchToMol(std::vector<RWMol *> &molList,unsigned int molIdx,unsigned int branchIdx){
00267 Bond *newBond=new Bond(Bond::SINGLE);
00268 return addBranchToMol(molList,molIdx,branchIdx,newBond);
00269 };
00270
00271
00272
00273 int addFragToMol(std::vector<RWMol *> &molList,unsigned int molIdx,unsigned int fragIdx){
00274 Bond *newBond=new Bond(Bond::IONIC);
00275 return addBranchToMol(molList,molIdx,fragIdx,newBond);
00276 }
00277
00278
00279 template <typename T>
00280 std::string convertToString(T val){
00281 std::string res=boost::lexical_cast<std::string>(val);
00282 return res;
00283 }
00284
00285 void CleanupAfterParseError(RWMol *mol){
00286 PRECONDITION(mol,"no molecule");
00287
00288 RWMol::BOND_BOOKMARK_MAP *marks = mol->getBondBookmarks();
00289 RWMol::BOND_BOOKMARK_MAP::iterator markI=marks->begin();
00290 while(markI != marks->end()){
00291 RWMol::BOND_PTR_LIST &bonds=markI->second;
00292 for(RWMol::BOND_PTR_LIST::iterator bondIt=bonds.begin();
00293 bondIt!=bonds.end();++bondIt){
00294 delete *bondIt;
00295 }
00296 ++markI;
00297 }
00298 }
00299 }
00300 }
00301 #endif