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 
00033     class EventBase {
00034     public:
00035         EventBase();
00036         virtual ~EventBase();
00037 
00039 
00040         
00045         template<typename T>
00046         const T *get(const std::string& branchName, const Variables& vars = cafe::detail::empty) const;
00047 
00052         template<typename T>
00053         Collection<T> getCollection(const std::string& branchName, const Variables& vars = cafe::detail::empty) const;
00054 
00058         const TClonesArray *getClonesArray(const std::string& branchName, const Variables& vars = cafe::detail::empty) const;
00059 
00063         bool readBranch(const std::string& branchName);
00064 
00067         void setBranchAddresses(TTree *tree);
00068 
00071         bool setPartialRead(bool allow);
00072 
00074         bool getPartialRead() const;
00075 
00077 
00079 
00080 
00105         
00106         template<typename T>
00107         void put(const std::string& key, const T& value);
00108 
00109         void clear (const std::string &key);
00110 
00112         template<typename T>
00113         bool get(const std::string& key, T& value) const;
00114 
00116         void clear();
00117 
00118         std::vector<std::string> *varnames();
00119         std::vector<std::string> *vartypes();
00120 
00122 
00124 
00125 
00127         void tag(const std::string& name);
00128 
00130         template<typename ITER>
00131         void tag(ITER from, ITER to);
00132 
00134         bool hasTag(const std::string& name) const;
00135 
00137         bool hasTag(const char *name) const;
00138 
00141         template<typename C>
00142         bool hasTag(const C& c) const;
00143 
00145         void untag(const std::string& name);
00146 
00148         template<typename ITER>
00149         void untag(ITER from, ITER to);
00150 
00152         ostream& printTags(ostream& os) const ;
00153 
00155 
00157         TTree *getTree() const;
00158 
00160         int   getCookie() const;
00161     
00162     private:
00163         
00164         // Internal class for event store
00165         class BaseHolder {
00166         public:
00167             virtual ~BaseHolder() {}
00168             virtual void clear() = 0;
00169         };
00170 
00171         template<typename T>
00172         class Holder : public BaseHolder {
00173         public:
00174             Holder(const T& value) : _value(value) {}
00175             virtual ~Holder()      {}
00176             virtual void clear()   { delete_it(_value); }
00177             const T& value() const { return _value; }
00178         private:
00179             template<class U>
00180             void delete_it(U *p) { delete p;}
00181 
00182             template<class U>
00183             void delete_it(const U&p) {}
00184             T     _value;
00185         };
00186 
00187         typedef std::map<std::string, BaseHolder*> Map;
00188         Map _map;
00189 
00190     private:
00191 
00192         // Internal base class for a BranchHolder
00193         // Only used to keep pointers to it in a map<>
00194         class BranchHolderBase {
00195         public:
00196             virtual ~BranchHolderBase() {}
00197             virtual void setBranchAddress(TTree *tree) = 0;   
00198             virtual void readBranch(TTree *tree) = 0;
00199         };
00200 
00201 
00202         // A map of all know branches.
00203         typedef std::map<std::string,BranchHolderBase*> BranchMap;
00204 
00205         template<typename T>
00206         class BranchHolder : public BranchHolderBase {
00207         public:
00208             BranchHolder(const std::string& branchName);
00209             ~BranchHolder();
00210             void setBranchAddress(TTree *tree);
00211             T *getObject(TTree *tree, const Variables& vars, int cookie) const;
00212             void readBranch(TTree *tree);
00213         private:
00214             std::string _branchName;
00215             T           *_branchObject; // pointer to object
00216             TBranch     *_branch;       // pointer to branch
00217             mutable Long64_t  _entry;   // cached entry number
00218         };
00219 
00220 
00221         TTree                *_tree;         // the current tree
00222         mutable BranchMap     _branches;     // a map of branches we know about
00223         std::set<std::string> _tags;
00224         int                   _cookie;       // increment for every new tree
00225         bool                  _partial_read; // if false, no optimized reading by member variable
00226         UInt_t                _objectCount;  // TProcessID::GetObjectCount()
00227 
00228     public:
00229         ClassDef(EventBase, 0);
00230     };
00231 
00241 
00242     namespace detail {
00243         template<class T>
00244         struct keeper {
00245             keeper(T *ptr) : _ptr(ptr) {}
00246             T *_ptr;
00247         };
00248     }
00249 
00250     template<class T>
00251     detail::keeper<T> keep(T *ptr) 
00252     {
00253         return detail::keeper<T>(ptr);
00254     }
00255 
00256 
00257 #ifndef __CINT__
00258 
00259     /*
00260      * Implementation of templated methods and classes.
00261      */
00262     template<typename T>
00263     const T *EventBase::get(const std::string& branchName, const Variables& vars) const
00264     {
00265         BranchHolder<T> *branch = dynamic_cast<BranchHolder<T>*>(_branches[branchName]);
00266         if(branch == 0) {
00267             _branches[branchName] = branch = new BranchHolder<T>(branchName);
00268             branch->setBranchAddress(_tree);
00269         }
00270         return branch->getObject(_tree, _partial_read ? vars : cafe::detail::empty, _cookie);
00271     }
00272 
00273 
00274     template<typename T>
00275     Collection<T> EventBase::getCollection(const std::string& branchName, const Variables& vars) const
00276     {
00277         BranchHolder<TClonesArray> *branch = dynamic_cast<BranchHolder<TClonesArray>*>(_branches[branchName]);
00278         if(branch == 0) {
00279             _branches[branchName] = branch = new BranchHolder<TClonesArray>(branchName);
00280             branch->setBranchAddress(_tree);
00281         }
00282         return Collection<T>(branch->getObject(_tree, _partial_read ? vars : cafe::detail::empty, _cookie));
00283     }
00284 
00285     template<typename T>
00286     EventBase::BranchHolder<T>::BranchHolder(const std::string& branchName)
00287         : _branchName(branchName),
00288           _branchObject(0),
00289           _branch(0),
00290           _entry(-1)
00291     {}
00292 
00293     template<typename T>
00294     EventBase::BranchHolder<T>::~BranchHolder() 
00295     { 
00296         // do we have to delete it ?  
00297         delete _branchObject;
00298     }
00299 
00300     template<typename T>
00301     void EventBase::BranchHolder<T>::setBranchAddress(TTree *tree)
00302     {
00303         _branch = tree->GetBranch(_branchName.c_str());
00304         if(_branch != 0) {
00305             char **addr = reinterpret_cast<char **>(_branch->GetAddress());
00306             if(addr != 0 && *addr != 0) {
00307                 _branchObject = reinterpret_cast<T*>(*addr);
00308             } else {
00309                 tree->SetBranchAddress(_branchName.c_str(), &_branchObject);
00310             }
00311         }
00312         _entry = -1;
00313     }
00314 
00315     template<typename T>
00316     T *EventBase::BranchHolder<T>::getObject(TTree *tree, const Variables& vars, int cookie) const
00317     {
00318         if(!_branch) return 0;
00319 
00320         Long64_t current = tree->GetReadEntry();
00321 
00322         if(vars.empty()) {
00323             if(current != _entry) {
00324                 TIter iter(_branch->GetListOfBranches());
00325                 while(TBranch *br = (TBranch *)iter.Next()) {
00326                     if(current != br->GetReadEntry()) {
00327                         br->GetEntry(current);
00328                     }
00329                 }
00330                 _entry = current;
00331             }
00332         } else {
00333             vars.get(tree, _branch, cookie);
00334         }
00335 
00336         return _branchObject;
00337     }
00338 
00339     template<typename T>
00340     void EventBase::BranchHolder<T>::readBranch(TTree *tree)
00341     {
00342         Long64_t current = tree->GetReadEntry();
00343 
00344         if(current != _entry) {
00345             _branch->GetEntry(current);
00346             _entry = current;
00347         }
00348     }
00349 
00350     template<typename T>
00351     void EventBase::put(const std::string& key, const T& value)
00352     {
00353         Map::iterator it = _map.find(key);
00354         if(it != _map.end()) {
00355             (*it).second->clear();
00356             delete (*it).second;
00357         }
00358         _map[key] = new Holder<T>(value);
00359     }
00360 
00361     template<typename T>
00362     bool EventBase::get(const std::string& key, T& value) const
00363     {
00364         Map::const_iterator it = _map.find(key);
00365         if(it != _map.end()) {
00366             if(Holder<T>* p = dynamic_cast<Holder<T>*>((*it).second)) {
00367                 value = p->value();
00368                 return true;
00369             }
00370             if (Holder<detail::keeper<T> >* p = 
00371                dynamic_cast<Holder<detail::keeper<T> >*>((*it).second)) {
00372                 value = *(p->value()._ptr);
00373                 return true;
00374             }
00375         }
00376         return false;
00377     }
00378 
00379     template<typename C>
00380     bool EventBase::hasTag(const C& c) const
00381     {
00382         for(typename C::const_iterator it = c.begin();
00383             it != c.end();
00384             ++it) {
00385             if(_tags.count(*it) > 0) return true;
00386         }
00387         return false;
00388     }
00389 
00392     template<typename ITER>
00393     void EventBase::tag(ITER from, ITER to)
00394     {
00395         for(;from != to; ++from) {
00396             tag(*from);
00397         }
00398     }
00399 
00402     template<typename ITER>
00403     void EventBase::untag(ITER from, ITER to)
00404     {
00405         for(;from != to; ++from) {
00406             untag(*from);
00407         }
00408     }
00409         
00410 #endif // __CINT__
00411 
00412 }
00413 
00414 #endif // EVENTBASE_HPP__

Generated on Thu Apr 3 04:14:23 2008 for CAF by doxygen 1.3.4