00001
00002 #include "cafe/HistoGetter.hpp"
00003
00004 #include "TObject.h"
00005 #include "TTree.h"
00006 #include "TBranchElement.h"
00007 #include "TObjString.h"
00008
00009 #include "tmb_tree/TMBLorentzVector.hpp"
00010 #include "tmb_tree/TMBL2Base.hpp"
00011 #include "tmb_tree/TMBL3Base.hpp"
00012 #include <cassert>
00013
00014 namespace {
00015
00016 template<class T, class RET = float>
00017 class HistoGetterImpl : public cafe::HistoGetter {
00018 public:
00019 typedef RET (T::*GETTER)() const;
00020
00021 HistoGetterImpl(GETTER getter, const cafe::Variables& vars)
00022 : HistoGetter(vars),
00023 _getter(getter)
00024 {
00025 }
00026
00027 virtual float get(TObject *obj)
00028 {
00029 if(T *ptr = dynamic_cast<T*>(obj)) {
00030 return (float )(ptr->*_getter)();
00031 } else {
00032 assert(false);
00033 return 0.0;
00034 }
00035 }
00036 private:
00037 GETTER _getter;
00038 };
00039
00040 template<class BASE, class RET>
00041 HistoGetterImpl<BASE,RET> *make(const std::string& method, const cafe::Variables& vars)
00042 {
00043 struct Method {
00044 const char *name;
00045 typename HistoGetterImpl<BASE,RET>::GETTER getter;
00046 };
00047
00048 static Method methods[] = {
00049 { "Pt", &BASE::Pt },
00050 { "E", &BASE::E },
00051 { "Eta", &BASE::Eta },
00052 { "Phi", &BASE::Phi },
00053 { "Px", &BASE::Px },
00054 { "Py", &BASE::Py },
00055 { "Pz", &BASE::Pz },
00056 { 0, 0 }
00057 };
00058
00059 for(Method* ptr = methods; ptr->name != 0; ptr++) {
00060 if(method == ptr->name) {
00061 return new HistoGetterImpl<BASE,RET>(ptr->getter, vars);
00062 }
00063 }
00064
00065 return 0;
00066 }
00067 }
00068
00069 namespace cafe {
00070
00071 HistoGetter::HistoGetter(const cafe::Variables& vars)
00072 : _vars(vars)
00073 {
00074 }
00075
00076 HistoGetter::~HistoGetter()
00077 {
00078 }
00079
00080 void HistoGetter::parse(const std::string& expression,
00081 std::string& branch,
00082 std::string& method)
00083 {
00084
00085
00086
00087
00088 if(expression.find_first_of("[]->+/*&|<>!%$") != std::string::npos) {
00089 return;
00090 }
00091
00092 TString s(expression.c_str());
00093 TObjArray *a = s.Tokenize(".(");
00094 if(a->GetLast() == 2 &&
00095 ((TObjString *)(a->At(2)))->GetString() == ")") {
00096
00097 branch = ((TObjString *)a->At(0))->GetString().Data();
00098 method = ((TObjString *)a->At(1))->GetString().Data();
00099 }
00100 delete a;
00101 }
00102
00103
00104 HistoGetter *HistoGetter::create(TTree *tree, const std::string& branch,
00105 const std::string& method)
00106 {
00107 if(TBranchElement *br = dynamic_cast<TBranchElement*>(tree->GetBranch(branch.c_str()))) {
00108 if(TClass *cl = TClass::GetClass(br->GetClonesName())) {
00109 if(cl->InheritsFrom("TMBLorentzVector")) {
00110 return make<TMBLorentzVector,Double_t>(method, cafe::Variables("fX","fY","fZ", "fM"));
00111 } else if(cl->InheritsFrom("TMBL2Base")) {
00112 return make<TMBL2Base,float>(method, cafe::Variables("et", "ieta", "iphi" ));
00113 } else if(cl->InheritsFrom("TMBL3Base")) {
00114 return make<TMBL3Base,float>(method, cafe::Variables("et", "eta", "phi" ));
00115 }
00116 }
00117 }
00118
00119 return 0;
00120 }
00121
00122 const cafe::Variables& HistoGetter::vars() const
00123 {
00124 return _vars;
00125 }
00126
00127 }