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
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
00193
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
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;
00216 TBranch *_branch;
00217 mutable Long64_t _entry;
00218 };
00219
00220
00221 TTree *_tree;
00222 mutable BranchMap _branches;
00223 std::set<std::string> _tags;
00224 int _cookie;
00225 bool _partial_read;
00226 UInt_t _objectCount;
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
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
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__