00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __RD_CATALOG_H__
00012 #define __RD_CATALOG_H__
00013
00014
00015 #include <boost/graph/graph_traits.hpp>
00016 #include <boost/graph/adjacency_list.hpp>
00017 #include <boost/version.hpp>
00018 #if BOOST_VERSION >= 104000
00019 #include <boost/property_map/property_map.hpp>
00020 #else
00021 #include <boost/property_map.hpp>
00022 #endif
00023
00024
00025
00026 #include <RDGeneral/types.h>
00027 #include <RDGeneral/StreamOps.h>
00028
00029 namespace RDCatalog {
00030 const int versionMajor=1;
00031 const int versionMinor=0;
00032 const int versionPatch=0;
00033 const int endianId=0xDEADBEEF;
00034
00035
00036
00037 template <class entryType, class paramType>
00038 class Catalog {
00039 public:
00040
00041 Catalog() : d_fpLength(0), dp_cParams(0) {};
00042
00043
00044 virtual ~Catalog(){
00045 if (dp_cParams) {
00046 delete dp_cParams;
00047 }
00048 }
00049
00050
00051
00052 virtual std::string Serialize() const = 0;
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 virtual unsigned int addEntry(entryType *entry, bool updateFPLength = true) = 0;
00064
00065
00066
00067 virtual const entryType* getEntryWithIdx(unsigned int idx) const = 0;
00068
00069
00070
00071 virtual unsigned int getNumEntries() const = 0;
00072
00073
00074
00075 unsigned int getFPLength() const {return d_fpLength;}
00076
00077
00078
00079 void setFPLength(unsigned int val) {d_fpLength = val;}
00080
00081
00082
00083 void setCatalogParams(paramType *params) {
00084 PRECONDITION(params,"bad parameter object");
00085
00086 PRECONDITION(!dp_cParams,"A parameter object already exists on the catalog" );
00087
00088
00089
00090
00091
00092
00093 dp_cParams = new paramType(*params);
00094 }
00095
00096
00097
00098 const paramType *getCatalogParams() const { return dp_cParams;}
00099
00100 protected:
00101
00102
00103
00104
00105
00106 unsigned int d_fpLength;
00107 paramType *dp_cParams;
00108
00109 };
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 template <class entryType, class paramType, class orderType>
00135 class HierarchCatalog : public Catalog <entryType, paramType> {
00136
00137
00138 public:
00139
00140 struct vertex_entry_t {
00141 enum { num=1003 };
00142 typedef boost::vertex_property_tag kind;
00143 };
00144 typedef boost::property<vertex_entry_t, entryType *> EntryProperty;
00145
00146
00147 typedef boost::adjacency_list<boost::vecS,
00148 boost::vecS,
00149
00150 boost::bidirectionalS,
00151 EntryProperty> CatalogGraph;
00152
00153 typedef boost::graph_traits<CatalogGraph> CAT_GRAPH_TRAITS;
00154 typedef typename CAT_GRAPH_TRAITS::vertex_iterator VER_ITER;
00155 typedef std::pair<VER_ITER, VER_ITER> ENT_ITER_PAIR;
00156 typedef typename CAT_GRAPH_TRAITS::adjacency_iterator DOWN_ENT_ITER;
00157 typedef std::pair<DOWN_ENT_ITER, DOWN_ENT_ITER> DOWN_ENT_ITER_PAIR;
00158
00159
00160 HierarchCatalog<entryType, paramType, orderType>() {};
00161
00162
00163
00164 HierarchCatalog<entryType, paramType, orderType>(paramType *params) : Catalog<entryType,paramType>() {
00165 this->setCatalogParams(params);
00166 }
00167
00168
00169
00170 HierarchCatalog<entryType, paramType, orderType>(const std::string &pickle) {
00171 this->initFromString(pickle);
00172 }
00173
00174
00175 ~HierarchCatalog() {
00176 destroy();
00177 }
00178
00179
00180
00181 void toStream(std::ostream &ss) const {
00182 PRECONDITION(this->getCatalogParams(),"NULL parameter object");
00183
00184
00185 RDKit::streamWrite(ss,endianId);
00186 RDKit::streamWrite(ss,versionMajor);
00187 RDKit::streamWrite(ss,versionMinor);
00188 RDKit::streamWrite(ss,versionPatch);
00189
00190
00191 int tmpUInt;
00192 tmpUInt = this->getFPLength();
00193 RDKit::streamWrite(ss,tmpUInt);
00194 tmpUInt = this->getNumEntries();
00195 RDKit::streamWrite(ss,tmpUInt);
00196
00197
00198
00199
00200
00201 this->getCatalogParams()->toStream(ss);
00202
00203
00204
00205
00206
00207
00208 for(unsigned int i=0;i<getNumEntries();i++){
00209 this->getEntryWithIdx(i)->toStream(ss);
00210 }
00211
00212
00213 for(unsigned int i=0;i<getNumEntries();i++){
00214 RDKit::INT_VECT children=this->getDownEntryList(i);
00215 tmpUInt = children.size();
00216 RDKit::streamWrite(ss,tmpUInt);
00217 for(RDKit::INT_VECT::const_iterator ivci=children.begin();
00218 ivci!=children.end();
00219 ivci++){
00220 RDKit::streamWrite(ss,*ivci);
00221 }
00222 }
00223 }
00224
00225
00226
00227 std::string Serialize() const {
00228 std::stringstream ss(std::ios_base::binary|std::ios_base::out|std::ios_base::in);
00229 this->toStream(ss);
00230 return ss.str();
00231 }
00232
00233
00234
00235 void initFromStream(std::istream &ss) {
00236 int tmpInt;
00237
00238 RDKit::streamRead(ss,tmpInt);
00239 RDKit::streamRead(ss,tmpInt);
00240 RDKit::streamRead(ss,tmpInt);
00241 RDKit::streamRead(ss,tmpInt);
00242
00243 unsigned int tmpUInt;
00244 RDKit::streamRead(ss,tmpUInt);
00245 this->setFPLength(tmpUInt);
00246
00247 unsigned int numEntries;
00248 RDKit::streamRead(ss,numEntries);
00249
00250
00251
00252
00253
00254 paramType *params = new paramType();
00255 params->initFromStream(ss);
00256 this->setCatalogParams(params);
00257
00258
00259
00260
00261
00262
00263
00264 for(unsigned int i=0;i<numEntries;i++){
00265 entryType *entry = new entryType();
00266 entry->initFromStream(ss);
00267 this->addEntry(entry,false);
00268 }
00269
00270
00271 for(unsigned int i=0;i<numEntries;i++){
00272 unsigned int nNeighbors;
00273 RDKit::streamRead(ss,nNeighbors);
00274 for(unsigned int j=0;j<nNeighbors;j++){
00275 RDKit::streamRead(ss,tmpInt);
00276 this->addEdge(i,tmpInt);
00277 }
00278 }
00279 }
00280
00281
00282 unsigned int getNumEntries() const {
00283 return boost::num_vertices(d_graph);
00284 }
00285
00286
00287
00288 void initFromString(const std::string &text){
00289 std::stringstream ss(std::ios_base::binary|std::ios_base::out|std::ios_base::in);
00290
00291 ss.write(text.c_str(),text.length());
00292
00293 this->initFromStream(ss);
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 unsigned int addEntry(entryType *entry, bool updateFPLength = true){
00306 PRECONDITION(entry,"bad arguments");
00307 if (updateFPLength) {
00308 unsigned int fpl = this->getFPLength();
00309 entry->setBitId(fpl);
00310 fpl++;
00311 this->setFPLength(fpl);
00312 }
00313 unsigned int eid = boost::add_vertex(EntryProperty(entry), d_graph);
00314 orderType etype = entry->getOrder();
00315
00316
00317
00318 if (d_orderMap.find(etype) == d_orderMap.end()) {
00319 RDKit::INT_VECT nets;
00320 d_orderMap[etype] = nets;
00321 }
00322 d_orderMap[etype].push_back(eid);
00323 return eid;
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 void addEdge(unsigned int id1, unsigned int id2) {
00337 unsigned int nents = getNumEntries();
00338 RANGE_CHECK(0, id1, nents-1);
00339 RANGE_CHECK(0, id2, nents-1);
00340
00341
00342
00343
00344 typename CAT_GRAPH_TRAITS::edge_descriptor edge;
00345 bool found;
00346 boost::tie(edge,found) = boost::edge(boost::vertex(id1,d_graph),
00347 boost::vertex(id2,d_graph),
00348 d_graph);
00349 if (!found) {
00350 boost::add_edge(id1, id2, d_graph);
00351 }
00352 }
00353
00354
00355
00356 const entryType *getEntryWithIdx(unsigned int idx) const {
00357 RANGE_CHECK(0,idx,getNumEntries()-1);
00358 int vd = boost::vertex(idx, d_graph);
00359 typename boost::property_map < CatalogGraph, vertex_entry_t>::const_type
00360 pMap = boost::get(vertex_entry_t(), d_graph);
00361 return pMap[vd];
00362 }
00363
00364
00365
00366 const entryType *getEntryWithBitId(unsigned int idx) const {
00367 RANGE_CHECK(0,idx,this->getFPLength()-1);
00368 typename boost::property_map < CatalogGraph, vertex_entry_t>::const_type
00369 pMap = boost::get(vertex_entry_t(), d_graph);
00370 const entryType *res=NULL;
00371 for(unsigned int i=idx;i<this->getNumEntries();i++){
00372 const entryType *e=pMap[i];
00373 if(e->getBitId()==static_cast<int>(idx)){
00374 res=e;
00375 break;
00376 }
00377 }
00378 return res;
00379 }
00380
00381
00382
00383 int getIdOfEntryWithBitId(unsigned int idx) const {
00384 RANGE_CHECK(0,idx,this->getFPLength()-1);
00385 typename boost::property_map < CatalogGraph, vertex_entry_t>::const_type
00386 pMap = boost::get(vertex_entry_t(), d_graph);
00387 int res=-1;
00388 for(unsigned int i=idx;i<this->getNumEntries();i++){
00389 const entryType *e=pMap[i];
00390 if(static_cast<unsigned int>(e->getBitId())==idx){
00391 res=i;
00392 break;
00393 }
00394 }
00395 return res;
00396 }
00397
00398
00399
00400 RDKit::INT_VECT getDownEntryList(unsigned int idx) const {
00401 RDKit::INT_VECT res;
00402 DOWN_ENT_ITER nbrIdx, endIdx;
00403 boost::tie(nbrIdx, endIdx) = boost::adjacent_vertices(idx, d_graph);
00404 while (nbrIdx != endIdx) {
00405 res.push_back(*nbrIdx);
00406 nbrIdx++;
00407 }
00408
00409 return res;
00410 }
00411
00412
00413
00414 const RDKit::INT_VECT &getEntriesOfOrder(orderType ord) {
00415 return d_orderMap[ord];
00416 }
00417
00418
00419
00420
00421
00422
00423 const RDKit::INT_VECT &getEntriesOfOrder(orderType ord) const {
00424 typename std::map<orderType, RDKit::INT_VECT>::const_iterator elem;
00425 elem = d_orderMap.find(ord);
00426 CHECK_INVARIANT(elem!=d_orderMap.end()," catalog does not contain any entries of the order specified");
00427 return elem->second;
00428 }
00429
00430
00431 private:
00432
00433 CatalogGraph d_graph;
00434
00435
00436
00437
00438
00439 std::map<orderType, RDKit::INT_VECT> d_orderMap;
00440
00441
00442
00443 void destroy() {
00444 ENT_ITER_PAIR entItP = boost::vertices(d_graph);
00445 typename boost::property_map < CatalogGraph, vertex_entry_t>::type
00446 pMap = boost::get(vertex_entry_t(), d_graph);
00447 while (entItP.first != entItP.second) {
00448 delete pMap[*(entItP.first++)];
00449 }
00450 }
00451
00452
00453
00454 };
00455
00456
00457
00458
00459
00460
00461
00462
00463 template <class entryType, class orderType>
00464 class LinearCatalog : public Catalog <entryType, orderType> {
00465
00466
00467
00468
00469 public:
00470 std::string Serialize();
00471
00472 unsigned int addEntry(entryType *entry, bool updateFPLength = true);
00473
00474 const entryType *getEntryWithIdx(unsigned int idx) const;
00475
00476 private:
00477 std::vector<entryType*> d_vector;
00478 };
00479 }
00480
00481 #endif