void test5() { // test working from SMILES std::cout << " ----------> Test5 " << std::endl; RWMol *m1 = SmilesToMol("[Xa]CC([Xb])CC", 0, 0); CHECK_INVARIANT(m1, ""); markAttachmentPoints(m1, 'X'); RWMOL_SPTR_VECT sidechains; sidechains.push_back(RWMOL_SPTR(SmilesToMol("[X]OC(=O)", 0, 0))); sidechains.push_back(RWMOL_SPTR(SmilesToMol("[X]OC(=O)C", 0, 0))); sidechains.push_back(RWMOL_SPTR(SmilesToMol("[X]OC(=O)CCC", 0, 0))); prepareSidechains(&sidechains, 'X'); VECT_RWMOL_SPTR_VECT allSideChains; allSideChains.push_back(sidechains); allSideChains.push_back(sidechains); RWMOL_SPTR_VECT library; library = enumerateLibrary(m1, allSideChains, false); CHECK_INVARIANT(library.size() == 9, ""); CHECK_INVARIANT(library[0]->getNumAtoms() == 10, ""); CHECK_INVARIANT(library[1]->getNumAtoms() == 11, ""); CHECK_INVARIANT(library[2]->getNumAtoms() == 13, ""); CHECK_INVARIANT(library[3]->getNumAtoms() == 11, ""); CHECK_INVARIANT(library[4]->getNumAtoms() == 12, ""); CHECK_INVARIANT(library[5]->getNumAtoms() == 14, ""); CHECK_INVARIANT(library[6]->getNumAtoms() == 13, ""); CHECK_INVARIANT(library[7]->getNumAtoms() == 14, ""); CHECK_INVARIANT(library[8]->getNumAtoms() == 16, ""); library.clear(); std::cout << " <---------- Done " << std::endl; }
// ------------------------------------------------------------------ // // Reads a template and library of sidechains from input files. // the template file should be a mol file and the sidechain files // SD files // // ------------------------------------------------------------------ RWMOL_SPTR_VECT enumFromFiles(const char *templateName, std::vector<const char *> &sidechainNames){ PRECONDITION(templateName,"bad template file name passed in"); // build and mark the template molecule RWMol *templ = MolFileToMol(templateName,false); if(!templ) throw EnumException("could not construct template molecule"); markAttachmentPoints(templ,'X'); // now build and mark each set of sidechains: RWMOL_SPTR_VECT sidechains; VECT_RWMOL_SPTR_VECT allSidechains; for(std::vector<const char*>::const_iterator i=sidechainNames.begin(); i!=sidechainNames.end();i++){ sidechains = SDFileToMols(*i,false); if(!sidechains.size()){ std::string err="no sidechains read from file: "; err += *i; throw EnumException(err.c_str()); } prepareSidechains(&sidechains,'X'); allSidechains.push_back(sidechains); } // enumerate the library: RWMOL_SPTR_VECT library=enumerateLibrary(templ,allSidechains); //-------------------------- // // Clean up the molecules and sidechains we constructed along the // way. // //-------------------------- delete templ; #if 0 VECT_RWMOL_SPTR_VECT::iterator vmpvI; for(vmpvI=allSidechains.begin();vmpvI!=allSidechains.end();vmpvI++){ RWMOL_SPTR_VECT::iterator mpvI; for(mpvI=vmpvI->begin();mpvI!=vmpvI->end();mpvI++){ delete *mpvI; } vmpvI->clear(); } #endif allSidechains.clear(); return library; }
// ------------------------------------------------------------------ // // Enumerates the library around a template and returns the result. // // // ------------------------------------------------------------------ RWMOL_SPTR_VECT enumerateLibrary(RWMol *templateMol, VECT_RWMOL_SPTR_VECT &sidechains, bool orientSidechains){ PRECONDITION(templateMol,"bad molecule"); RWMOL_SPTR_VECT res,tmp; res.push_back(RWMOL_SPTR(new RWMol(*templateMol))); // if there's no attachment point on the molecule or no // sidechains, return now: if(!templateMol->hasProp(common_properties::maxAttachIdx) || sidechains.size()==0 ) return res; int maxIdx; templateMol->getProp(common_properties::maxAttachIdx,maxIdx); tmp.clear(); // loop over the sidechains and attach them for(unsigned int i=0;i<sidechains.size();i++){ int tgtMark=CONNECT_BOOKMARK_START+i; // here's another boundary condition if(tgtMark>maxIdx) break; /// loop over all atoms with the appropriate mark // This means that if a mol has two attachment points with the // same name (e.g. two Xa's) they'll always have the same // sidechain attached to them. This is a feature. RWMOL_SPTR_VECT::iterator sidechainIt; for(sidechainIt=sidechains[i].begin(); sidechainIt!=sidechains[i].end(); sidechainIt++){ // we've got our sidechain, find the atom it attaches from if( (*sidechainIt)->hasAtomBookmark(CONNECT_BOOKMARK_START) ){ // // NOTE: If there's more than one marked atom in the sidechain, /// we'll only use the first for the moment. // int sidechainAtomIdx = (*sidechainIt)->getAtomWithBookmark(CONNECT_BOOKMARK_START)->getIdx(); // now add the sidechain to each molecule RWMOL_SPTR_VECT::iterator templMolIt; // loop over all the mols we've generated to this point for(templMolIt=res.begin();templMolIt!=res.end();templMolIt++){ RWMol *templ = new RWMol(**templMolIt); std::string name,tmpStr; if(templ->hasProp(common_properties::_Name)){ templ->getProp(common_properties::_Name,tmpStr); name = name + " " + tmpStr; } while(templ->hasAtomBookmark(tgtMark)){ // this is the atom we'll be replacing in the template Atom *at = templ->getAtomWithBookmark(tgtMark); // copy and transform the sidechain: RWMol *sidechain; if(orientSidechains){ sidechain = new RWMol(*(sidechainIt->get())); orientSidechain(templ,sidechain, at->getIdx(),sidechainAtomIdx); } else { sidechain = sidechainIt->get(); } // FIX: need to use the actual bond order here: molAddSidechain(templ,sidechain, at->getIdx(),sidechainAtomIdx, Bond::SINGLE); if(sidechain->hasProp(common_properties::_Name)){ sidechain->getProp(common_properties::_Name,tmpStr); name = name + " " + tmpStr; } templ->clearAtomBookmark(tgtMark,at); if(orientSidechains){ delete sidechain; } } //std::cout << templ << "> " << MolToSmiles(*templ) << std::endl; if(name != "") templ->setProp(common_properties::_Name,name); tmp.push_back(RWMOL_SPTR(templ)); } } } // // if we just made any molecules, free up the memory used by the // existing result set and move the molecules we just generated // over if(tmp.size()){ #if 0 RWMOL_SPTR_VECT::iterator tmpMolIt; for(tmpMolIt=res.begin();tmpMolIt!=res.end();tmpMolIt++){ delete *tmpMolIt; } #endif res = tmp; tmp.clear(); } } return res; }