Example #1
0
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;
  }