Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

EventBase.hpp

Go to the documentation of this file.
00001 #ifndef EVENTBASE_HPP__
00002 #define EVENTBASE_HPP__
00003 
00004 #include <map>
00005 #include <set>
00006 #include <string>
00007 
00008 #include "TClonesArray.h"
00009 #include "TIterator.h"
00010 #include "TBranch.h"
00011 #include "TTree.h"
00012 
00013 #include "cafe/Collection.hpp"
00014 #include "cafe/Variables.hpp"
00015 
00016 namespace cafe { 
00017 
00018     namespace detail {
00019         extern const Variables empty;
00020     }
00021 
00034     class EventBase {
00035     public:
00036         EventBase();
00037         virtual ~EventBase();
00038 
00040 
00041         
00046         template<typename T>
00047         const T *get(const std::string& branchName, const Variables& vars = cafe::detail::empty) const;
00048 
00053         template<typename T>
00054         Collection<T> getCollection(const std::string& branchName, const Variables& vars = cafe::detail::empty) const;
00055 
00059         const TClonesArray *getClonesArray(const std::string& branchName, const Variables& vars = cafe::detail::empty) const;
00060 
00064         bool readBranch(const std::string& branchName);
00065 
00068         void setBranchAddresses(TTree *tree);
00069 
00072         bool setPartialRead(bool allow);
00073 
00075         bool getPartialRead() const;
00076 
00078 
00080 
00081 
00106         
00107         template<typename T>
00108         void put(const std::string& key, const T& value);
00109 
00110         inline void clear (const std::string &key);
00111 
00113         template<typename T>
00114         bool get(const std::string& key, T& value) const;
00115 
00117         void clear();
00118 
00120 
00122 
00123 
00125         void tag(const std::string& name);
00126 
00128         template<typename ITER>
00129         void tag(ITER from, ITER to);
00130 
00132         bool hasTag(const std::string& name) const;
00133 
00135         bool hasTag(const char *name) const;
00136 
00139         template<typename C>
00140         bool hasTag(const C& c) const;
00141 
00143         void untag(const std::string& name);
00144 
00146         template<typename ITER>
00147         void untag(ITER from, ITER to);
00148 
00150 
00152         TTree *getTree() const;
00153 
00155         int   getCookie() const;
00156 
00157     private:
00158         
00159         // Internal class for event store
00160         class BaseHolder {
00161         public:
00162             virtual ~BaseHolder() {}
00163             virtual void clear() = 0;
00164         };
00165 
00166         template<typename T>
00167         class Holder : public BaseHolder {
00168         public:
00169             Holder(const T& value) : _value(value) {}
00170             virtual ~Holder()      {}
00171             virtual void clear()   { delete_it(_value); }
00172             const T& value() const { return _value; }
00173         private:
00174             template<class U>
00175             void delete_it(U *p) { delete p;}
00176 
00177             template<class U>
00178             void delete_it(const U&p) {}
00179             T     _value;
00180         };
00181 
00182         typedef std::map<std::string, BaseHolder*> Map;
00183         Map _map;
00184 
00185     private:
00186 
00187         // Internal base class for a BranchHolder
00188         // Only used to keep pointers to it in a map<>
00189         class BranchHolderBase {
00190         public:
00191             virtual ~BranchHolderBase() {}
00192             virtual void setBranchAddress(TTree *tree) = 0;   
00193             virtual void readBranch(TTree *tree) = 0;
00194         };
00195 
00196 
00197         // A map of all know branches.
00198         typedef std::map<std::string,BranchHolderBase*> BranchMap;
00199 
00200         template<typename T>
00201         class BranchHolder : public BranchHolderBase {
00202         public:
00203             BranchHolder(const std::string& branchName);
00204             ~BranchHolder();
00205             void setBranchAddress(TTree *tree);
00206             T *getObject(TTree *tree, const Variables& vars, int cookie) const;
00207             void readBranch(TTree *tree);
00208         private:
00209             std::string _branchName;
00210             T           *_branchObject; // pointer to object
00211             TBranch     *_branch;       // pointer to branch
00212             mutable Long64_t  _entry;   // cached entry number
00213         };
00214 
00215 
00216         TTree                *_tree;         // the current tree
00217         mutable BranchMap     _branches;     // a map of branches we know about
00218         std::set<std::string> _tags;
00219         int                   _cookie;       // increment for every new tree
00220         bool                  _partial_read; // if false, no optimized reading by member variable
00221 
00222     public:
00223         ClassDef(EventBase, 0);
00224     };
00225 
00235 
00236     namespace detail {
00237         template<class T>
00238         struct keeper {
00239             keeper(T *ptr) : _ptr(ptr) {}
00240             T *_ptr;
00241         };
00242     }
00243 
00244     template<class T>
00245     detail::keeper<T> keep(T *ptr) 
00246     {
00247         return detail::keeper<T>(ptr);
00248     }
00249 
00250 
00251 #ifndef __CINT__
00252 
00253     /*
00254      * Implementation of templated methods and classes.
00255      */
00256     template<typename T>
00257     const T *EventBase::get(const std::string& branchName, const Variables& vars) const
00258     {
00259         BranchHolder<T> *branch = dynamic_cast<BranchHolder<T>*>(_branches[branchName]);
00260         if(branch == 0) {
00261             _branches[branchName] = branch = new BranchHolder<T>(branchName);
00262             branch->setBranchAddress(_tree);
00263         }
00264         return branch->getObject(_tree, _partial_read ? vars : cafe::detail::empty, _cookie);
00265     }
00266 
00267 
00268     template<typename T>
00269     Collection<T> EventBase::getCollection(const std::string& branchName, const Variables& vars) const
00270     {
00271         BranchHolder<TClonesArray> *branch = dynamic_cast<BranchHolder<TClonesArray>*>(_branches[branchName]);
00272         if(branch == 0) {
00273             _branches[branchName] = branch = new BranchHolder<TClonesArray>(branchName);
00274             branch->setBranchAddress(_tree);
00275         }
00276         return Collection<T>(branch->getObject(_tree, _partial_read ? vars : cafe::detail::empty, _cookie));
00277     }
00278 
00279     template<typename T>
00280     EventBase::BranchHolder<T>::BranchHolder(const std::string& branchName)
00281         : _branchName(branchName),
00282           _branchObject(0),
00283           _branch(0),
00284           _entry(-1)
00285     {}
00286 
00287     template<typename T>
00288     EventBase::BranchHolder<T>::~BranchHolder() 
00289     { 
00290         // do we have to delete it ?  
00291         delete _branchObject;
00292     }
00293 
00294     template<typename T>
00295     void EventBase::BranchHolder<T>::setBranchAddress(TTree *tree)
00296     {
00297         _branch = tree->GetBranch(_branchName.c_str());
00298         if(_branch != 0) {
00299             char **addr = reinterpret_cast<char **>(_branch->GetAddress());
00300             if(addr != 0 && *addr != 0) {
00301                 _branchObject = reinterpret_cast<T*>(*addr);
00302             } else {
00303                 tree->SetBranchAddress(_branchName.c_str(), &_branchObject);
00304             }
00305         }
00306         _entry = -1;
00307     }
00308 
00309     template<typename T>
00310     T *EventBase::BranchHolder<T>::getObject(TTree *tree, const Variables& vars, int cookie) const
00311     {
00312         if(!_branch) return 0;
00313 
00314         Long64_t current = tree->GetReadEntry();
00315 
00316         if(vars.empty()) {
00317             if(current != _entry) {
00318                 _branch->GetEntry(current);
00319                 _entry = current;
00320             }
00321         } else {
00322             vars.get(tree, _branch, cookie);
00323         }
00324 
00325         return _branchObject;
00326     }
00327 
00328     template<typename T>
00329     void EventBase::BranchHolder<T>::readBranch(TTree *tree)
00330     {
00331         Long64_t current = tree->GetReadEntry();
00332 
00333         if(current != _entry) {
00334             _branch->GetEntry(current);
00335             _entry = current;
00336         }
00337     }
00338 
00339     template<typename T>
00340     void EventBase::put(const std::string& key, const T& value)
00341     {
00342         _map[key] = new Holder<T>(value);
00343     }
00344 
00345     void EventBase::clear(const std::string& key)
00346     {
00347           Map::iterator it = _map.find(key);
00348           if(it != _map.end()) {
00349                 _map.erase (it);
00350           }
00351     }
00352 
00353         template<typename T>
00354     bool EventBase::get(const std::string& key, T& value) const
00355     {
00356         Map::const_iterator it = _map.find(key);
00357         if(it != _map.end()) {
00358             if(Holder<T>* p = dynamic_cast<Holder<T>*>((*it).second)) {
00359                 value = p->value();
00360                 return true;
00361             }
00362             if (Holder<detail::keeper<T> >* p = 
00363                dynamic_cast<Holder<detail::keeper<T> >*>((*it).second)) {
00364                 value = *(p->value()._ptr);
00365                 return true;
00366             }
00367         }
00368         return false;
00369     }
00370 
00371     template<typename C>
00372     bool EventBase::hasTag(const C& c) const
00373     {
00374         for(typename C::const_iterator it = c.begin();
00375             it != c.end();
00376             ++it) {
00377             if(_tags.count(*it) > 0) return true;
00378         }
00379         return false;
00380     }
00381 
00384     template<typename ITER>
00385     void EventBase::tag(ITER from, ITER to)
00386     {
00387         for(;from != to; ++from) {
00388             tag(*from);
00389         }
00390     }
00391 
00394     template<typename ITER>
00395     void EventBase::untag(ITER from, ITER to)
00396     {
00397         for(;from != to; ++from) {
00398             untag(*from);
00399         }
00400     }
00401     
00402     
00403 #endif // __CINT__
00404 
00405 }
00406 
00407 #endif // EVENTBASE_HPP__

Generated on Tue Mar 28 10:13:03 2006 for CAF by doxygen 1.3.4