treeReader.h
Go to the documentation of this file.
1 // Templates to simplify reading TTrees. Constructor-getter pattern, modest
2 // efficiency considerations considered.
3 //
4 // The use of try-catch structures is for decorative purposes only; root v6
5 // does not hurl, it segfaults. See https://xkcd.com/371/
6 // The signature for TTree::SetBranchAddress in the vectorFromTree construtor is
7 // template <class T> Int_t SetBranchAddress(const char*, T**, TBranch** = 0)
8 // which means that you could call with a std::deque or perhaps some other
9 // container in the 2nd argument rather than a std::vector. And it would still
10 // compile. But then getData() actually will getGarbage(). Because root is so
11 // great.
12 //
13 // Honestly, I wouldn't try resizing the vector returned from getData() directly.
14 // maybe try a deep copy first or something. I suspect this only works because
15 // vectors are guaranteed to be contiguous storage, unlike other containers.
16 //
17 // Leo Bellantoni, 2019 copyright FRA.
18 //
19 // Use like so:
20 //
21 // Long64_t iEntry = 0;
22 // scalarFromTree<int> readRun(Oak,"Run",&iEntry);
23 // vectorFromTree<int> readVertN(Oak,"VertN",&iEntry);
24 // vectorFromTree<int> readVertQ(Oak,"VertQ",&iEntry);
25 // Int_t Run = readRun(); // cuz' you initialized iEntry to 0
26 // Int_t nEntry = Oak->GetEntries();
27 // for (iEntry=0; iEntry<nEntry; ++iEntry) {
28 // vector<int> VertN = readVertN();
29 // size_t nVertInEvent = VertN.size();
30 // vector<int> TwoTrackVerts = readVertN.findIndices(2);
31 // for (auto aTwoTrackVertIndex : TwoTrackVerts) {
32 // int Qvert = readVertQ.getData(aTwoTrackVertIndex);
33 // ... whatever
34 // }
35 // }
36 
37 
38 
39 #ifndef treeReader_h
40 #define treeReader_h
41 
42 
43 
44 #include <string>
45 using std::string;
46 #include <vector>
47 using std::vector;
48 //#include <algorithm>
49 
50 #include "Rtypes.h"
51 #include "TTree.h"
52 #include "TLeaf.h"
53 
54 
55 
56 
57 
58 // Read a scalar ===============================================================
59 // =============================================================================
60 template<typename T> class scalarFromTree {
61 public:
62 
63 
64 
65  scalarFromTree(TTree* whichTree, string varname, Long64_t* iEntry_in) :
66  thisTree(whichTree),thisVarname(varname),iEntry_local(iEntry_in) {
67  lastEntry = -1;
68  }
69 
70  // Compiler won't make a default constructor. Gotta do it here.
72  thisTree = NULL; iEntry_local = NULL; thisVarname = "";
73  lastEntry = -2;
74  }
75 
76 
77 
78  // Get that scalar! Get it! Here is the preferred signature
79  T operator()() {return getData();};
80 
81  // This signature deprecated but is nicer than (*scalarFromTree)(i)
82  T getData() {
83  if (*iEntry_local != lastEntry) {
85  try {
86  thisTree->GetEntry(*iEntry_local);
87  sData = thisTree->GetLeaf(thisVarname.c_str())->GetValue(0);
88  } catch (...) {
89  throw std::runtime_error("Can not GetLeaf in scalarFromTree.getData()");
90  }
91  }
92  return sData;
93  }
94 
95 
96 
97 private:
98  TTree* thisTree;
99  string thisVarname;
100  Long64_t* iEntry_local;
102  Long64_t lastEntry;
103 };
104 
105 
106 
107 
108 
109 // Read a std::vector ==========================================================
110 // =============================================================================
111 template<typename T> class vectorFromTree {
112 public:
113 
114 
115 
116  // Constructor only calls SetBranchAddress =================================
117  vectorFromTree(TTree* whichTree, string varname, Long64_t* iEntry_in) :
118  thisTree(whichTree),thisVarname(varname),iEntry_local(iEntry_in),
119  vData(NULL),bData(NULL) {
120  // EQUIVALENCE was a bad idea in FORTRAN IV, never mind C++14.
121  try {
122  thisTree->SetBranchAddress(thisVarname.c_str(),&vData,&bData);
123  } catch (...) {
124  throw std::runtime_error("SetBranchAddress fails in vectorFromTree constructor");
125  }
126  lastEntry = -1;
127  }
128 
129  // Compiler won't make a default constructor. Gotta do it here. ===========
131  thisTree = NULL; iEntry_local = NULL;
132  vData = NULL; bData = NULL;
133  thisVarname = "";
134  lastEntry = -2;
135  }
136 
137 
138 
139  // Get that vector! Get it! ===============================================
140  vector<T>& getDataVector() {
141  if (*iEntry_local != lastEntry) {
143  try {
144  Long64_t tEntry = thisTree->LoadTree(*iEntry_local);
145  bData->GetEntry(tEntry);
146  } catch (...) {
147  throw std::runtime_error("Can not GetEntry in vectorFromTree.getData()");
148  }
149  }
150  return (*vData);
151  }
152 
153 
154 
155  // Get something from that vector! Get that! ==============================
156  // This is the preferred signature
157  T operator()(int i) {
158  return getDataVector().at(i);
159  }
160  // This signature deprecated but is nicer than (*vectorFromTree)(i)
161  T getData(int i) {
162  return getDataVector().at(i);
163  }
164 
165 
166 
167  // Get that vector's size! Get him! =======================================
168  int size() {
169  return getDataVector().size();
170  }
171 
172 
173 
174  // Construct a vector with all indices where data matches searchval ========
175  vector<int> findIndices(T searchval) {
176  vector<int> retval;
177  int nData = getDataVector().size();
178  for (int iDatum=0; iDatum<nData; ++iDatum) {
179  if ( getDataVector().at(iDatum)==searchval ) retval.push_back(iDatum);
180  }
181  return retval;
182  }
183 
184 
185 
186 private:
187  TTree* thisTree;
188  string thisVarname;
189  Long64_t* iEntry_local;
190  vector<T>* vData;
191  TBranch* bData;
192  Long64_t lastEntry;
193 };
194 
195 
196 
197 #endif
vector< int > findIndices(T searchval)
Definition: treeReader.h:175
vector< T > * vData
Definition: treeReader.h:190
vectorFromTree(TTree *whichTree, string varname, Long64_t *iEntry_in)
Definition: treeReader.h:117
std::string string
Definition: nybbler.cc:12
string thisVarname
Definition: treeReader.h:188
struct vector vector
Long64_t lastEntry
Definition: treeReader.h:192
vector< T > & getDataVector()
Definition: treeReader.h:140
Long64_t lastEntry
Definition: treeReader.h:102
Long64_t * iEntry_local
Definition: treeReader.h:189
scalarFromTree(TTree *whichTree, string varname, Long64_t *iEntry_in)
Definition: treeReader.h:65
TTree * thisTree
Definition: treeReader.h:187
size_t size
Definition: lodepng.cpp:55
T operator()(int i)
Definition: treeReader.h:157
TBranch * bData
Definition: treeReader.h:191
Long64_t * iEntry_local
Definition: treeReader.h:100
T getData(int i)
Definition: treeReader.h:161
string thisVarname
Definition: treeReader.h:99
TTree * thisTree
Definition: treeReader.h:98