00001 #ifndef CAFE_SELECTUSEROBJECTS_HPP__
00002 #define CAFE_SELECTUSEROBJECTS_HPP__
00003
00004 #include "cafe/Event.hpp"
00005 #include "cafe/Processor.hpp"
00006 #include "cafe/Config.hpp"
00007 #include "cafe/Variables.hpp"
00008
00009 #include "TFile.h"
00010 #include "TTree.h"
00011 #include "TBranch.h"
00012 #include "TBranchElement.h"
00013 #include "TDirectory.h"
00014 #include "TClonesArray.h"
00015
00016 #include <string>
00017 #include <stdexcept>
00018
00019 namespace cafe {
00020
00054 template<class T>
00055 class SelectUserObjects : public Processor {
00056 public:
00057 SelectUserObjects(const char *name);
00058 void inputFileOpened(TFile *file);
00059 void inputFileClosing(TFile *file);
00060 bool processEvent(cafe::Event& event);
00061 const std::string& treeName() const { return _treeName ;}
00062 protected:
00067 virtual bool selectObject(const T& obj) = 0;
00068
00071 virtual void before(Collection<T>& from);
00072
00074 virtual void after(Collection<T>& accepted, Collection<T>& rejected);
00075
00077 void addVariable(const std::string& name) {_vars.add(name);}
00078
00079 std::string _fromBranch;
00080 Event const* _event;
00081 Variables _vars;
00082
00083 private:
00084 std::string _toBranch;
00085 std::string _toRejectedBranch;
00086 std::string _treeName;
00087 bool _loadAll;
00088 TTree *_tree;
00089 TClonesArray *_result;
00090 TClonesArray *_resultRejected;
00091 TBranch *_branch;
00092 TBranch *_branchRejected;
00093 public:
00094 ClassDef(SelectUserObjects, 0);
00095 };
00096
00097
00098
00099
00100
00101
00102 template<class T>
00103 SelectUserObjects<T>::SelectUserObjects(const char *name)
00104 : Processor(name),
00105 _event(0),
00106 _loadAll(true),
00107 _tree(0),
00108 _result(0),
00109 _resultRejected(0),
00110 _branch(0),
00111 _branchRejected(0)
00112 {
00113 using namespace cafe;
00114
00115
00116 Config config(name);
00117
00118 _fromBranch = config.get("From", "");
00119 _toBranch = config.get("To", "");
00120 _toRejectedBranch = config.get("RejectedBranch", "");
00121 _treeName = config.get("Tree", "TMBTree");
00122 _vars.add(config.getVString("Variables", " ,"));
00123 _loadAll = config.get("LoadAll", 1);
00124
00125 if(_fromBranch.empty()) {
00126 throw std::runtime_error(std::string("SelectUserObject[") + name
00127 + "] : From: branch in config file not set");
00128 }
00129
00130 if(_toBranch.empty()) {
00131 throw std::runtime_error(std::string("SelectUserObject[") + name
00132 + "] : To: branch in config file not set");
00133 }
00134
00135 if(_fromBranch == _toBranch) {
00136 throw std::runtime_error(std::string("SelectUserObject[") + name
00137 + "] : From: branch has the same name as To: branch");
00138 }
00139
00140 if(_fromBranch == _toRejectedBranch) {
00141 throw std::runtime_error(std::string("SelectUserObject[") + name
00142 + "] : From: branch has the same name as RejectedBranch: branch");
00143 }
00144
00145 out() << "SelectUserObjects[" << name << "] From: " << _fromBranch
00146 << " To: " << _toBranch << std::endl ;
00147 if (_toRejectedBranch != "") {
00148 out () << " Rejected objects go to branch: " << _toRejectedBranch << std::endl;
00149 }
00150 out() << "SelectUserObjects[" << name << "] Output Tree: " << _treeName << std::endl;
00151 }
00152
00153 template<class T>
00154 void SelectUserObjects<T>::inputFileOpened(TFile *file)
00155 {
00156 if(TTree *tmb_tree = (TTree *)file->Get("TMBTree")) {
00157
00158 if ( _treeName=="TMBTree" ) _tree = dynamic_cast<TTree*>(file->Get("TMBTree"));
00159 else _tree = dynamic_cast<TTree *>(gROOT->Get(_treeName.c_str()));
00160
00161 if (_tree == 0) {
00162 gROOT->cd();
00163 _tree = new TTree(_treeName.c_str(), fullName().c_str());
00164 tmb_tree->AddFriend(_tree);
00165 }
00166
00167 _branch = _tree->GetBranch(_toBranch.c_str()) ;
00168 if (_branch == 0) {
00169 if(TBranchElement *br = (TBranchElement *)tmb_tree->GetBranch(_fromBranch.c_str())) {
00170 _result = new TClonesArray(br->GetClonesName());
00171 _branch = _tree->Branch(_toBranch.c_str(), &_result, 4096);
00172 if (_toRejectedBranch != "" && !_branchRejected) {
00173 _resultRejected = new TClonesArray(br->GetClonesName());
00174 _branchRejected = _tree->Branch(_toRejectedBranch.c_str(), &_resultRejected, 4096); }
00175 } else {
00176 err() << "SelectUserObjects[" << name() << "] No such branch: ["
00177 << _fromBranch << "]" << std::endl;
00178 }
00179 } else {
00180 throw std::runtime_error(std::string("SelectUserObject[") + name()
00181 + "] : You are trying to create the branch "
00182 + _toBranch + " which already exists!\n") ;
00183 }
00184 } else {
00185 err() << "SelectUserObjects[" << name() << "] No TMBTree" << std::endl;
00186 }
00187 }
00188
00189 template<class T>
00190 void SelectUserObjects<T>::inputFileClosing(TFile *file)
00191 {
00192
00193 if(TTree* oldtree =
00194 dynamic_cast<TTree *>(gROOT->Get(_treeName.c_str()))) {
00195 oldtree->Delete();
00196 }
00197 _tree = 0;
00198 _branch = 0;
00199 _branchRejected = 0;
00200 }
00201
00202 template<class T>
00203 void SelectUserObjects<T>::before(Collection<T>& from)
00204 {
00205 }
00206
00207 template<class T>
00208 void SelectUserObjects<T>::after(Collection<T>& accepted, Collection<T>& rejected)
00209 {
00210 }
00211
00212 template<class T>
00213 bool SelectUserObjects<T>::processEvent(Event& event)
00214 {
00215 using namespace cafe;
00216
00217 if(!_result) return true;
00218 _result->Delete() ;
00219 if(_resultRejected) _resultRejected->Delete() ;
00220
00221 _event = &event;
00222
00223 Collection<T> from(event.getCollection<T>(_fromBranch.c_str(), _vars));
00224
00225 before(from);
00226
00227 Int_t next = 0;
00228 Int_t nextr = 0;
00229
00230 for(typename Collection<T>::const_iterator it = from.begin();
00231 it != from.end();
00232 ++it) {
00233 if(selectObject(*it)) {
00234 if(_loadAll) {
00235 event.readBranch(_fromBranch);
00236 }
00237 new ((*_result)[next++]) T(*it);
00238 } else if (_resultRejected) {
00239 if(_loadAll) {
00240 event.readBranch(_fromBranch);
00241 }
00242 new ((*_resultRejected)[nextr++]) T(*it);
00243 }
00244 }
00245
00246 Collection<T> accepted(_result);
00247 Collection<T> rejected(_resultRejected);
00248
00249 after(accepted, rejected);
00250
00251 return true;
00252 }
00253
00254 }
00255
00256 #endif // CAFE_SELECTUSEROBJECTS_HPP__