// $Id$ // // Copyright (c) 2007-2014, Novartis Institutes for BioMedical Research Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Novartis Institutes for BioMedical Research Inc. // nor the names of its contributors may be used to endorse or promote // products derived from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // #include #include #include #include #include #include #include "ReactionUtils.h" namespace RDKit { namespace DaylightParserUtils { std::vector splitSmartsIntoComponents(const std::string &reactText){ std::vector res; unsigned int pos=0; unsigned int blockStart=0; unsigned int level=0; unsigned int inBlock=0; while(pos *replacements, bool useSmiles) { std::size_t pos1=text.find(">"); std::size_t pos2=text.rfind(">"); if(pos1==std::string::npos){ throw ChemicalReactionParserException("a reaction requires at least one reactant and one product"); } if(text.find(">",pos1+1)!=pos2){ throw ChemicalReactionParserException("multi-step reactions not supported"); } std::string reactText=text.substr(0,pos1); std::string agentText=""; if(pos2!=pos1+1){ agentText=text.substr(pos1+1,(pos2-pos1)-1); } std::string productText=text.substr(pos2+1); // recognize changes within the same molecules, e.g., intra molecular bond formation // therefore we need to correctly interpret parenthesis and dots in the reaction smarts std::vector reactSmarts=DaylightParserUtils::splitSmartsIntoComponents(reactText); std::vector productSmarts=DaylightParserUtils::splitSmartsIntoComponents(productText); ChemicalReaction *rxn=new ChemicalReaction(); for(std::vector::const_iterator txtIt=reactSmarts.begin(); txtIt!=reactSmarts.end();++txtIt){ ROMol *mol; if(!useSmiles){ mol=SmartsToMol(*txtIt,0,false,replacements); } else{ mol=SmilesToMol(*txtIt,0,false,replacements); } if(!mol){ std::string errMsg="Problems constructing reactant from SMARTS: "; errMsg += *txtIt; throw ChemicalReactionParserException(errMsg); } rxn->addReactantTemplate(ROMOL_SPTR(mol)); } for(std::vector::const_iterator txtIt=productSmarts.begin(); txtIt!=productSmarts.end();++txtIt){ ROMol *mol; if(!useSmiles){ mol=SmartsToMol(*txtIt,0,false,replacements); } else{ mol=SmilesToMol(*txtIt,0,false,replacements); } if(!mol){ std::string errMsg="Problems constructing product from SMARTS: "; errMsg += *txtIt; throw ChemicalReactionParserException(errMsg); } rxn->addProductTemplate(ROMOL_SPTR(mol)); } updateProductsStereochem(rxn); ROMol *agentMol; //allow a reaction template to have no agent specified if(agentText.size() != 0){ if(!useSmiles) agentMol=SmartsToMol(agentText,0,false,replacements); else agentMol=SmilesToMol(agentText,0,false,replacements); if(!agentMol){ std::string errMsg="Problems constructing agent from SMARTS: "; errMsg += agentText; throw ChemicalReactionParserException(errMsg); } std::vector agents=MolOps::getMolFrags(*agentMol,false); delete agentMol; for(std::vector::iterator aIt=agents.begin(); aIt!=agents.end();++aIt){ rxn->addAgentTemplate(*aIt); } } // "SMARTS"-based reactions have implicit properties rxn->setImplicitPropertiesFlag(true); return rxn; } }