Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

DataBucket.h

Go to the documentation of this file.
00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 #ifndef EDM_DATABUCKET_H
00009 #define EDM_DATABUCKET_H
00010 #include <cassert>
00011 #include <iostream>
00012 #include <list>
00013 #include <string>
00014 #include <vector>
00015 #include "TClonesArray.h"
00016 #include "TFolder.h"
00017 #include "TObjArray.h"
00018 #include "EventDataModel/Exception.h"
00019 
00020 namespace edm {
00022   class DataBucket {
00023   public:
00024     static const int kFixedSizeObject    = 0x01;
00025     static const int kVariableSizeObject = 0x02;
00026   public:
00029     DataBucket(TFolder* top);
00030 
00031     template<class T> int Get(const char* path, 
00032                               std::vector<const T*>& v) const;    
00033     template<class T> T* Put(const T& obj, const char* path, 
00034                              int opt=kFixedSizeObject);
00035     template<class T> int PutArray(const T* obj, const char* path, 
00036                                    int nObj, int opt=kFixedSizeObject);
00037     
00038     template<class T> int PutVector(const std::vector<T*>& obj, 
00039                                     const char* path,
00040                                     int opt=kFixedSizeObject);
00041     
00042     void          List(const char* opt="*")        const;
00043     TFolder*      GetFolder(const char* path)      const;
00044     TClonesArray* GetClonesArray(const char* path) const;
00045     TObjArray*    GetObjArray(const char* path)    const;
00046     
00047     void          ClearArrays(const TFolder* f = 0);
00048     TFolder*      MakeFolder(const char* path);
00049     int           MakeFolders(const char* dirs[]);
00050     int           Remove(const char* path);
00051     
00052   private:
00053     TClonesArray* NewClonesArray(const char* path, const char* classname);
00054     TObjArray*    NewObjArray(const char* path, const char* classname);
00055     static void   ListFolder(const TFolder& f, int lvl);
00056     static void   Split(const char* path, char* dir, char* base);
00057 
00058   private:
00059     TFolder* fTopFolder; 
00060   };
00061 }
00062 
00063 //......................................................................
00103 template<class T>
00104 int edm::DataBucket::Get(const char* path, std::vector<const T*>& v) const
00105 {
00106   // Try to find exactly the collection names by
00107   // user. eg. "./dir/Objects" If that fails, assume the user gave
00108   // only a directory. Guess the collection name based on the class
00109   // type
00110   static std::string newPath;
00111   register int i;
00112   
00113   TObjArray* c = 0;
00114   if (c==0) c = this->GetClonesArray(path);
00115   if (c==0) c = this->GetObjArray(path);
00116   if (c==0) {
00117     T tmpItem;
00118     newPath = path;
00119     newPath += "/";
00120     newPath += tmpItem.ClassName();
00121     newPath += "s"; // Object array names are plural.
00122   
00123     if (c==0) c = this->GetClonesArray(newPath.c_str());
00124     if (c==0) c = this->GetObjArray(newPath.c_str());
00125   }
00126   // By this time we need to have a collection in order to proceed
00127   if (c==0) {
00128     // std::cerr << "edm::DataBucket: Couldn't locate collection at "
00129     //           << path << std::endl;
00130     throw Exception(__FILE__,__LINE__,COLLECTION_NOT_FOUND);
00131     return 0;
00132   }
00133   
00134   const T* cc = 0;
00135   int nitem     = c->GetEntries();
00136   int ntot_size = nitem+v.size();
00137   if (ntot_size>(int)v.capacity()) v.reserve(ntot_size);
00138   for (i = 0; i<nitem; ++i) {
00139     cc = dynamic_cast<const T*>(c->At(i));
00140     if (cc==0) {
00141       std::cerr << "Failed to convert objects in array "
00142                 << c->GetName() << " to requested type.";
00143       throw Exception(__FILE__,__LINE__,TYPE_MISMATCH);
00144       assert(cc);
00145     }
00146     v.push_back(cc);
00147   }
00148 
00149   return nitem;
00150 }
00151 
00152 //======================================================================
00177 template<class T>
00178 T* edm::DataBucket::Put(const T& obj, const char* path, int opt)
00179 {
00180   static std::string collectName;
00181   static std::string fullPath;
00182   int indx;
00183 
00184   collectName = obj.ClassName();
00185   fullPath = path;
00186   fullPath += "/";
00187   fullPath += collectName;
00188   fullPath += "s";
00189   
00190   if (opt & kFixedSizeObject) {
00191     TClonesArray *c = this->GetClonesArray(fullPath.c_str());
00192     if (c == 0) {
00193       // No collection of this type of object. Make a new collection
00194       if ((c = this->NewClonesArray(path, collectName.c_str())) == 0) {
00195         std::cerr << "edm::DataBucket: no folder " << path << " found"
00196                   << std::endl;
00197         throw Exception(__FILE__,__LINE__,NO_FOLDER_FOUND);
00198       }
00199     }
00200     
00201     // Create new object of type T in event store. The "new with
00202     // placement" is a signature of the TClonesArray container
00203     assert(c!=0); // By this time we must have a home for the object
00204     indx = c->GetLast()+1;
00205     T* t = new ((*c)[indx]) T(obj);
00206     return t; // Add OK
00207   }
00208 
00209   if (opt & kVariableSizeObject) {
00210     TObjArray* c = this->GetObjArray(fullPath.c_str());
00211     if (c == 0) {
00212       // No collection of this type of object. Make a new collection
00213       if ((c = this->NewObjArray(path, collectName.c_str())) == 0) {
00214         std::cerr << "edm::DataBucket: no folder " << path << " found"
00215                   << std::endl;
00216         throw Exception(__FILE__,__LINE__,NO_FOLDER_FOUND);
00217       }
00218     }
00219     
00220     // Create new object of type T in event store.
00221     assert(c!=0); // By this time we must have a home for the object
00222     T* t = new T(obj);
00223     c->AddLast(t);
00224     return t; // Add OK
00225   }
00226 
00227   return 0;
00228 }
00229 
00230 //......................................................................
00243 template<class T>
00244 int edm::DataBucket::PutArray(const T* obj, const char* path, 
00245                               int nObj, int opt)
00246 {
00247   static std::string collectName;
00248   static std::string fullPath;
00249   int indx;
00250   register int i;
00251 
00252   collectName = obj[0].ClassName();
00253   fullPath = path;
00254   fullPath += "/";
00255   fullPath += collectName;
00256   fullPath += "s";
00257   
00258   if (opt & kFixedSizeObject) {
00259     TClonesArray *c = this->GetClonesArray(fullPath.c_str());
00260     if (c == 0) {
00261       // No collection of this type of object. Make a new collection
00262       if ((c = this->NewClonesArray(path, collectName.c_str())) == 0) {
00263         std::cerr << "edm::DataBucket: no folder " << path << " found"
00264                   << std::endl;
00265         throw Exception(__FILE__,__LINE__,NO_FOLDER_FOUND);
00266       }
00267     }
00268     
00269     // Create new object of type T in event store. The "new with
00270     // placement" is a signature of the TClonesArray container
00271     assert(c != 0); // By this time we must have a home for the object
00272     indx = c->GetLast() + 1;
00273     const T* objPtr = obj;
00274     for (i = 0; i < nObj; ++i) {
00275       new ((*c)[indx++]) T(*objPtr++);
00276     }
00277     return indx; // Add OK
00278   }
00279 
00280   if (opt & kVariableSizeObject) {
00281     TObjArray* c = this->GetObjArray(fullPath.c_str());
00282     if (c == 0) {
00283       // No collection of this type of object. Make a new collection
00284       if ((c = this->NewObjArray(path, collectName.c_str())) == 0) {
00285         std::cerr << "edm::DataBucket: no folder " << path << " found"
00286                   << std::endl;
00287         throw Exception(__FILE__,__LINE__,NO_FOLDER_FOUND);
00288       }
00289     }
00290     
00291     // Create new object of type T in event store.
00292     assert(c!=0); // By this time we must have a home for the object
00293     for (i = 0; i < nObj; ++i) {
00294       c->AddLast(new T(obj[i]));
00295     }
00296     return c->GetLast(); // Add OK
00297   }
00298 
00299   return 0;
00300 }
00301 
00302 //......................................................................
00314 template<class T> 
00315 int edm::DataBucket::PutVector(const std::vector<T*>& vec, 
00316                                const char* path, int opt)
00317 {
00318   static std::string collectName;
00319   static std::string fullPath;
00320   int indx;
00321 
00322   if (vec.empty()) return 0;
00323 
00324   unsigned int vecSize = vec.size();
00325 
00326   // This doesn't seem to work for some reason...
00327   // std::vector<const T*>::const_iterator itr(vec.begin());
00328   // std::vector<const T*>::const_iterator itrEnd(vec.end());
00329 
00330   collectName = vec[0]->ClassName();
00331   fullPath = path;
00332   fullPath += "/";
00333   fullPath += collectName;
00334   fullPath += "s";
00335   
00336   if (opt & kFixedSizeObject) {
00337     TClonesArray *c = this->GetClonesArray(fullPath.c_str());
00338     if (c == 0) {
00339       // No collection of this type of object. Make a new collection
00340       if ((c = this->NewClonesArray(path, collectName.c_str())) == 0) {
00341         std::cerr << "edm::DataBucket: no folder " << path << " found"
00342                   << std::endl;
00343         throw Exception(__FILE__,__LINE__,NO_FOLDER_FOUND);
00344       }
00345     }
00346     
00347     // Create new object of type T in event store. The "new with
00348     // placement" is a signature of the TClonesArray container
00349     assert(c != 0); // By this time we must have a home for the object
00350     indx = c->GetLast() + 1;
00351     for (unsigned int i = 0; i < vecSize; ++i) {// ; itr != itrEnd; ++itr) {
00352       new ((*c)[indx++]) T(*vec[i]);
00353     }
00354     return indx; // Add OK
00355   }
00356 
00357   if (opt & kVariableSizeObject) {
00358     TObjArray* c = this->GetObjArray(fullPath.c_str());
00359     if (c == 0) {
00360       // No collection of this type of object. Make a new collection
00361       if ((c = this->NewObjArray(path, collectName.c_str())) == 0) {
00362         std::cerr << "edm::DataBucket: no folder " << path << " found"
00363                   << std::endl;
00364         throw Exception(__FILE__,__LINE__,NO_FOLDER_FOUND);
00365       }
00366     }
00367     
00368     // Create new object of type T in event store.
00369     assert(c!=0); // By this time we must have a home for the object
00370     for (unsigned int i = 0; i < vecSize; ++i) {//; itr != itrEnd; ++itr) 
00371       c->AddLast(new T(*vec[i]));
00372     }
00373     return c->GetLast(); // Add OK
00374   }
00375 
00376   return 0;
00377 }
00378 
00379 #endif // EDM_DATABUCKET_H
00380 

Generated on Sat Oct 11 02:35:27 2008 for NOvA Offline by  doxygen 1.3.9.1