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
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
00188
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
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;
00211 TBranch *_branch;
00212 mutable Long64_t _entry;
00213 };
00214
00215
00216 TTree *_tree;
00217 mutable BranchMap _branches;
00218 std::set<std::string> _tags;
00219 int _cookie;
00220 bool _partial_read;
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
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
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__