1 // Copyright (c) 2015, Novartis Institutes for BioMedical Research Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above 11 // copyright notice, this list of conditions and the following 12 // disclaimer in the documentation and/or other materials provided 13 // with the distribution. 14 // * Neither the name of Novartis Institutes for BioMedical Research Inc. 15 // nor the names of its contributors may be used to endorse or promote 16 // products derived from this software without specific prior written 17 // permission. 18 // 19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 // 31 32 #include <RDGeneral/export.h> 33 #ifndef __RD_FILTER_CATALOG_H__ 34 #define __RD_FILTER_CATALOG_H__ 35 36 #include <RDGeneral/types.h> // For Dict 37 #include <GraphMol/RDKitBase.h> 38 #include <GraphMol/Substruct/SubstructMatch.h> 39 #include <Catalogs/CatalogEntry.h> 40 41 #ifdef RDK_USE_BOOST_SERIALIZATION 42 #include <RDGeneral/BoostStartInclude.h> 43 #include <boost/archive/text_oarchive.hpp> 44 #include <boost/archive/text_iarchive.hpp> 45 #include <boost/serialization/vector.hpp> 46 #include <boost/serialization/shared_ptr.hpp> 47 #include <RDGeneral/BoostEndInclude.h> 48 #endif 49 50 #include "FilterMatchers.h" 51 52 namespace RDKit { 53 typedef std::map<std::string, std::string> STRING_PROPS; 54 55 class RDKIT_FILTERCATALOG_EXPORT FilterCatalogEntry 56 : public RDCatalog::CatalogEntry { 57 private: 58 boost::shared_ptr<FilterMatcherBase> d_matcher; 59 Dict d_props; 60 61 public: FilterCatalogEntry()62 FilterCatalogEntry() : d_matcher(), d_props() {} 63 FilterCatalogEntry(const std::string & name,const FilterMatcherBase & matcher)64 FilterCatalogEntry(const std::string &name, const FilterMatcherBase &matcher) 65 : RDCatalog::CatalogEntry(), d_matcher(matcher.copy()) { 66 setDescription(name); 67 } 68 FilterCatalogEntry(const std::string & name,boost::shared_ptr<FilterMatcherBase> matcher)69 FilterCatalogEntry(const std::string &name, 70 boost::shared_ptr<FilterMatcherBase> matcher) 71 : RDCatalog::CatalogEntry(), d_matcher(matcher) { 72 setDescription(name); 73 } 74 FilterCatalogEntry(const FilterCatalogEntry & rhs)75 FilterCatalogEntry(const FilterCatalogEntry &rhs) 76 : RDCatalog::CatalogEntry(rhs), 77 d_matcher(rhs.d_matcher), 78 d_props(rhs.d_props) {} 79 ~FilterCatalogEntry()80 virtual ~FilterCatalogEntry() {} 81 82 //------------------------------------ 83 //! Returns true if the Filters stored in this catalog entry are valid 84 isValid()85 bool isValid() const { return d_matcher.get() && d_matcher->isValid(); } 86 87 //------------------------------------ 88 //! Returns the description of the catalog entry 89 std::string getDescription() const; 90 91 //------------------------------------ 92 //! Sets the description of the catalog entry 93 /* 94 \param const std::string & description 95 */ 96 void setDescription(const std::string &description); 97 98 //! \name Properties 99 //@{ 100 101 //! returns a list with the names of our \c properties getPropList()102 STR_VECT getPropList() const { return d_props.keys(); } 103 104 //! sets a \c property value 105 /*! 106 \param key the name under which the \c property should be stored. 107 If a \c property is already stored under this name, it will be 108 replaced. 109 \param val the value to be stored 110 */ 111 template <typename T> setProp(const char * key,T val)112 void setProp(const char *key, T val) { 113 std::string what(key); 114 setProp(what, val); 115 } 116 //! \overload 117 template <typename T> setProp(const std::string & key,T val)118 void setProp(const std::string &key, T val) { 119 d_props.setVal(key, val); 120 } 121 122 //! allows retrieval of a particular property value 123 /*! 124 125 \param key the name under which the \c property should be stored. 126 If a \c property is already stored under this name, it will be 127 replaced. 128 \param res a reference to the storage location for the value. 129 130 <b>Notes:</b> 131 - if no \c property with name \c key exists, a KeyErrorException will be 132 thrown. 133 - the \c boost::lexical_cast machinery is used to attempt type 134 conversions. 135 If this fails, a \c boost::bad_lexical_cast exception will be thrown. 136 137 */ 138 template <typename T> getProp(const char * key,T & res)139 void getProp(const char *key, T &res) const { 140 d_props.getVal(key, res); 141 } 142 //! \overload 143 template <typename T> getProp(const std::string & key,T & res)144 void getProp(const std::string &key, T &res) const { 145 d_props.getVal(key, res); 146 } 147 //! \overload 148 template <typename T> getProp(const char * key)149 T getProp(const char *key) const { 150 return d_props.getVal<T>(key); 151 } 152 //! \overload 153 template <typename T> getProp(const std::string & key)154 T getProp(const std::string &key) const { 155 return d_props.getVal<T>(key); 156 } 157 158 //! returns whether or not we have a \c property with name \c key 159 //! and assigns the value if we do 160 template <typename T> getPropIfPresent(const char * key,T & res)161 bool getPropIfPresent(const char *key, T &res) const { 162 return d_props.getValIfPresent(key, res); 163 } 164 //! \overload 165 template <typename T> getPropIfPresent(const std::string & key,T & res)166 bool getPropIfPresent(const std::string &key, T &res) const { 167 return d_props.getValIfPresent(key, res); 168 } 169 170 //! returns whether or not we have a \c property with name \c key hasProp(const char * key)171 bool hasProp(const char *key) const { return d_props.hasVal(key); } 172 //! \overload hasProp(const std::string & key)173 bool hasProp(const std::string &key) const { 174 return d_props.hasVal(key); 175 // return hasProp(key.c_str()); 176 } 177 178 //! clears the value of a \c property clearProp(const char * key)179 void clearProp(const char *key) { 180 std::string what(key); 181 clearProp(what); 182 }; 183 //! \overload clearProp(const std::string & key)184 void clearProp(const std::string &key) { d_props.clearVal(key); }; 185 186 // ------------------------------------------- 187 //! Properties usually contain the reference and source 188 //! for the catalog entry. 189 getProps()190 Dict &getProps() { return d_props; } getProps()191 const Dict &getProps() const { return d_props; } setProps(const Dict & props)192 void setProps(const Dict &props) { d_props = props; } 193 194 //------------------------------------ 195 //! Returns the matching filters for this catalog entry 196 /* 197 \param mol The molecule to match against 198 \param std::vector<FilterMatch> the resulting FilterMatches 199 */ getFilterMatches(const ROMol & mol,std::vector<FilterMatch> & matchVect)200 bool getFilterMatches(const ROMol &mol, 201 std::vector<FilterMatch> &matchVect) const { 202 return this->isValid() && d_matcher->getMatches(mol, matchVect); 203 } 204 205 //------------------------------------ 206 //! Returns true if the filters in this catalog entry match the molecule 207 /* 208 \param mol The molecule to match against 209 */ 210 hasFilterMatch(const ROMol & mol)211 bool hasFilterMatch(const ROMol &mol) const { 212 return this->isValid() && d_matcher->hasMatch(mol); 213 } 214 215 //! serializes (pickles) to a stream 216 virtual void toStream(std::ostream &ss) const; 217 //! returns a string with a serialized (pickled) representation 218 virtual std::string Serialize() const; 219 //! initializes from a stream pickle 220 virtual void initFromStream(std::istream &ss); 221 //! initializes from a string pickle 222 virtual void initFromString(const std::string &text); 223 224 private: 225 #ifdef RDK_USE_BOOST_SERIALIZATION 226 friend class boost::serialization::access; 227 template <class Archive> save(Archive & ar,const unsigned int version)228 void save(Archive &ar, const unsigned int version) const { 229 RDUNUSED_PARAM(version); 230 registerFilterMatcherTypes(ar); 231 232 ar &d_matcher; 233 // we only save string based props here... 234 STR_VECT keys = d_props.keys(); 235 std::vector<std::string> string_props; 236 for (size_t i = 0; i < keys.size(); ++i) { 237 std::string val; 238 try { 239 if (d_props.getValIfPresent<std::string>(keys[i], val)) { 240 string_props.push_back(keys[i]); 241 string_props.push_back(val); 242 } 243 } catch (const boost::bad_any_cast &) { 244 // pass, can't serialize 245 // warning, this changes properties types, see Dict.cpp 246 } 247 } 248 ar &string_props; 249 } 250 251 template <class Archive> load(Archive & ar,const unsigned int version)252 void load(Archive &ar, const unsigned int version) { 253 RDUNUSED_PARAM(version); 254 registerFilterMatcherTypes(ar); 255 256 ar &d_matcher; 257 std::vector<std::string> string_props; 258 ar &string_props; 259 d_props.reset(); 260 261 for (size_t i = 0; i < string_props.size() / 2; ++i) { 262 d_props.setVal(string_props[i * 2], string_props[i * 2 + 1]); 263 } 264 } 265 266 BOOST_SERIALIZATION_SPLIT_MEMBER(); 267 #endif 268 }; 269 } // namespace RDKit 270 271 #ifdef RDK_USE_BOOST_SERIALIZATION 272 BOOST_CLASS_VERSION(RDKit::FilterCatalogEntry, 1); 273 #endif 274 275 #endif //__RD_FILTER_CATALOG_H__ 276