CMS 3D CMS Logo

TreeReader.cc
Go to the documentation of this file.
1 #include <cstdint>
2 #include <utility>
3 #include <cstring>
4 #include <string>
5 #include <vector>
6 #include <map>
7 
8 #include <TString.h>
9 #include <TTree.h>
10 #include <TBranch.h>
11 #include <TLeaf.h>
12 #include <TList.h>
13 #include <TKey.h>
14 
16 
20 
21 namespace PhysicsTools {
22 
23 const double TreeReader::kOptVal = -999.0;
24 
26  tree(nullptr), upToDate(false)
27 {
28 }
29 
31 {
32  this->operator = (orig);
33 }
34 
35 TreeReader::TreeReader(TTree *tree, bool skipTarget, bool skipWeight) :
36  tree(tree), upToDate(false)
37 {
38  automaticAdd(skipTarget, skipWeight);
39 }
40 
42 {
43 }
44 
46 {
47  reset();
48 
49  tree = orig.tree;
50 
51  multiDouble.resize(orig.multiDouble.size());
52  multiFloat.resize(orig.multiFloat.size());
53  multiInt.resize(orig.multiInt.size());
54  multiBool.resize(orig.multiBool.size());
55 
56  singleDouble.resize(orig.singleDouble.size());
57  singleFloat.resize(orig.singleFloat.size());
58  singleInt.resize(orig.singleInt.size());
59  singleBool.resize(orig.singleBool.size());
60 
61  valueMap = orig.valueMap;
62 
63  return *this;
64 }
65 
67 {
68  this->tree = tree;
69  upToDate = false;
70 }
71 
72 void TreeReader::addBranch(const std::string &expression,
73  AtomicId name, bool opt)
74 {
75  if (!tree)
76  throw cms::Exception("NoTreeAvailable")
77  << "No TTree set in TreeReader::addBranch."
78  << std::endl;
79 
80  TBranch *branch = tree->GetBranch(expression.c_str());
81  if (!branch)
82  throw cms::Exception("BranchMissing")
83  << "Tree branch \"" << expression << "\" missing."
84  << std::endl;
85 
86  addBranch(branch, name, opt);
87 }
88 
89 void TreeReader::addBranch(TBranch *branch, AtomicId name, bool opt)
90 {
91  TString branchName = branch->GetName();
92  if (!name)
93  name = (const char*)branchName;
94 
95  TLeaf *leaf = dynamic_cast<TLeaf*>(branch->GetLeaf(branchName));
96  if (!leaf)
97  throw cms::Exception("InvalidBranch")
98  << "Tree branch \"" << branchName << "\" has no leaf."
99  << std::endl;
100 
101  TString typeName = leaf->GetTypeName();
102  char typeId = 0;
103  bool multi = false;
104  if (typeName == "Double_t" || typeName == "double")
105  typeId = 'D';
106  else if (typeName == "Float_t" || typeName == "float")
107  typeId = 'F';
108  else if (typeName == "Int_t" || typeName == "int")
109  typeId = 'I';
110  else if (typeName == "Bool_t" || typeName == "bool")
111  typeId = 'B';
112  else {
113  multi = true;
114  if (typeName == "vector<double>" ||
115  typeName == "Vector<Double_t>")
116  typeId = 'D';
117  else if (typeName == "vector<float>" ||
118  typeName == "Vector<Float_t>")
119  typeId = 'F';
120  else if (typeName == "vector<int>" ||
121  typeName == "Vector<Int_t>")
122  typeId = 'I';
123  else if (typeName == "vector<bool>" ||
124  typeName == "Vector<Bool_t>")
125  typeId = 'B';
126  }
127 
128  if (!typeId)
129  throw cms::Exception("InvalidBranch")
130  << "Tree branch \"" << branchName << "\" is of "
131  "unsupported type \"" << typeName << "\"."
132  << std::endl;
133 
134  if (multi)
135  addTypeMulti(name, nullptr, typeId);
136  else
137  addTypeSingle(name, nullptr, typeId, opt);
138 
139  valueMap[name].setBranchName(branch->GetName());
140 }
141 
142 void TreeReader::setOptional(AtomicId name, bool opt, double optVal)
143 {
144  std::map<AtomicId, Value>::iterator pos = valueMap.find(name);
145  if (pos == valueMap.end())
146  throw cms::Exception("UnknownVariable")
147  << "Variable \"" <<name << "\" is not known to the "
148  "TreeReader." << std::endl;
149 
150  pos->second.setOpt(opt, optVal);
151 }
152 
153 void TreeReader::addTypeSingle(AtomicId name, const void *value, char type, bool opt)
154 {
155  std::map<AtomicId, Value>::const_iterator pos = valueMap.find(name);
156  if (pos != valueMap.end())
157  throw cms::Exception("DuplicateVariable")
158  << "Duplicate Variable \"" << name << "\"."
159  << std::endl;
160 
161  if (type != 'D' && type != 'F' && type != 'I' && type != 'B')
162  throw cms::Exception("InvalidType")
163  << "Unsupported type '" << type << "' in call to"
164  "TreeReader::addTypeSingle." << std::endl;
165 
166  int index = -1;
167  if (!value) {
168  switch(type) {
169  case 'D':
170  index = (int)singleDouble.size();
171  singleDouble.push_back(Double_t());
172  break;
173  case 'F':
174  index = (int)singleFloat.size();
175  singleFloat.push_back(Float_t());
176  break;
177  case 'I':
178  index = (int)singleInt.size();
179  singleInt.push_back(Int_t());
180  break;
181  case 'B':
182  index = (int)singleBool.size();
183  singleBool.push_back(Bool());
184  break;
185  }
186  }
187 
188  valueMap[name] = Value(index, false, opt, type);
189  if (value)
190  valueMap[name].setPtr(value);
191 
192  upToDate = false;
193 }
194 
195 template<typename T>
196 static std::pair<void*, std::vector<T> > makeMulti()
197 { return std::pair<void*, std::vector<T> >(nullptr, std::vector<T>()); }
198 
200 {
201  std::map<AtomicId, Value>::const_iterator pos = valueMap.find(name);
202  if (pos != valueMap.end())
203  throw cms::Exception("DuplicateVariable")
204  << "Duplicate Variable \"" << name << "\"."
205  << std::endl;
206 
207  if (type != 'D' && type != 'F' && type != 'I' && type != 'B')
208  throw cms::Exception("InvalidType")
209  << "Unsupported type '" << type << "' in call to"
210  "TreeReader::addTypeMulti." << std::endl;
211 
212  int index = -1;
213  if (!value) {
214  switch(type) {
215  case 'D':
216  index = (int)multiDouble.size();
217  multiDouble.push_back(makeMulti<Double_t>());
218  break;
219  case 'F':
220  index = (int)multiFloat.size();
221  multiFloat.push_back(makeMulti<Float_t>());
222  break;
223  case 'I':
224  index = (int)multiInt.size();
225  multiInt.push_back(makeMulti<Int_t>());
226  break;
227  case 'B':
228  index = (int)multiBool.size();
229  multiBool.push_back(makeMulti<Bool_t>());
230  break;
231  }
232  }
233 
234  valueMap[name] = Value(index, true, false, type);
235  if (value)
236  valueMap[name].setPtr(value);
237 
238  upToDate = false;
239 }
240 
241 void TreeReader::automaticAdd(bool skipTarget, bool skipWeight)
242 {
243  if (!tree)
244  throw cms::Exception("NoTreeAvailable")
245  << "No TTree set in TreeReader::automaticAdd."
246  << std::endl;
247 
248  TIter iter(tree->GetListOfBranches());
249  TObject *obj;
250  while((obj = iter())) {
251  TBranch *branch = dynamic_cast<TBranch*>(obj);
252  if (!branch)
253  continue;
254 
255  if (skipTarget &&
256  !std::strcmp(branch->GetName(), "__TARGET__"))
257  continue;
258 
259  if (skipWeight &&
260  !std::strcmp(branch->GetName(), "__WEIGHT__"))
261  continue;
262 
263  addBranch(branch);
264  }
265 }
266 
268 {
269  multiDouble.clear();
270  multiFloat.clear();
271  multiInt.clear();
272  multiBool.clear();
273 
274  singleDouble.clear();
275  singleFloat.clear();
276  singleInt.clear();
277  singleBool.clear();
278 
279  valueMap.clear();
280 
281  upToDate = false;
282 }
283 
285 {
286  if (!tree)
287  throw cms::Exception("NoTreeAvailable")
288  << "No TTree set in TreeReader::automaticAdd."
289  << std::endl;
290 
291  for(std::map<AtomicId, Value>::iterator iter = valueMap.begin();
292  iter != valueMap.end(); iter++)
293  iter->second.update(this);
294 
295  upToDate = true;
296 }
297 
299 {
300  if (!tree)
301  throw cms::Exception("NoTreeAvailable")
302  << "No TTree set in TreeReader::automaticAdd."
303  << std::endl;
304 
305  if (!upToDate)
306  update();
307 
308  Long64_t entries = tree->GetEntries();
309  for(Long64_t entry = 0; entry < entries; entry++)
310  {
311  tree->GetEntry(entry);
312  fill(mva);
313  }
314 
315  return entries;
316 }
317 
319 {
320  for(std::map<AtomicId, Value>::const_iterator iter = valueMap.begin();
321  iter != valueMap.end(); iter++)
322  iter->second.fill(iter->first, this);
323 
324  double result = mva->eval(values);
325  values.clear();
326 
327  return result;
328 }
329 
331 {
332  for(std::map<AtomicId, Value>::const_iterator iter = valueMap.begin();
333  iter != valueMap.end(); iter++)
334  iter->second.fill(iter->first, this);
335 
337  values.clear();
338 
339  return result;
340 }
341 
342 std::vector<AtomicId> TreeReader::variables() const
343 {
344  std::vector<AtomicId> result;
345  for(std::map<AtomicId, Value>::const_iterator iter = valueMap.begin();
346  iter != valueMap.end(); iter++)
347  result.push_back(iter->first);
348 
349  return result;
350 }
351 
353 {
354  if (ptr)
355  return;
356 
357  void *value = nullptr;
358  if (multiple) {
359  switch(type) {
360  case 'D':
361  reader->multiDouble[index].first =
362  &reader->multiDouble[index].second;
363  value = &reader->multiDouble[index].first;
364  break;
365  case 'F':
366  reader->multiFloat[index].first =
367  &reader->multiFloat[index].second;
368  value = &reader->multiFloat[index].first;
369  break;
370  case 'I':
371  reader->multiInt[index].first =
372  &reader->multiInt[index].second;
373  value = &reader->multiInt[index].first;
374  break;
375  case 'B':
376  reader->multiBool[index].first = value;
377  value = &reader->multiBool[index].first;
378  break;
379  }
380  } else {
381  switch(type) {
382  case 'D':
383  value = &reader->singleDouble[index];
384  break;
385  case 'F':
386  value = &reader->singleFloat[index];
387  break;
388  case 'I':
389  value = &reader->singleInt[index];
390  break;
391  case 'B':
392  value = &reader->singleBool[index];
393  break;
394  }
395  }
396 
397  reader->tree->SetBranchAddress(name, value);
398 }
399 
401 {
402  if (multiple) {
403  switch(type) {
404  case 'D': {
405  const std::vector<Double_t> *values =
406  static_cast<const std::vector<Double_t>*>(ptr);
407  if (!values)
408  values = &reader->multiDouble[index].second;
409  for(std::vector<Double_t>::const_iterator iter =
410  values->begin(); iter != values->end(); iter++)
411  reader->values.add(name, *iter);
412  break;
413  }
414  case 'F': {
415  const std::vector<Float_t> *values =
416  static_cast<const std::vector<Float_t>*>(ptr);
417  if (!values)
418  values = &reader->multiFloat[index].second;
419  for(std::vector<Float_t>::const_iterator iter =
420  values->begin(); iter != values->end(); iter++)
421  reader->values.add(name, *iter);
422  break;
423  }
424  case 'I': {
425  const std::vector<Int_t> *values =
426  static_cast<const std::vector<Int_t>*>(ptr);
427  if (!values)
428  values = &reader->multiInt[index].second;
429  for(std::vector<Int_t>::const_iterator iter =
430  values->begin(); iter != values->end(); iter++)
431  reader->values.add(name, *iter);
432  break;
433  }
434  case 'B': {
435  const std::vector<Bool_t> *values =
436  static_cast<const std::vector<Bool_t>*>(ptr);
437  if (!values)
438  values = &reader->multiBool[index].second;
439  for(std::vector<Bool_t>::const_iterator iter =
440  values->begin(); iter != values->end(); iter++)
441  reader->values.add(name, *iter);
442  break;
443  }
444  }
445  } else {
446  double value = 0.0;
447 
448  switch(type) {
449  case 'D':
450  value = ptr ? *(const Double_t*)ptr
451  : reader->singleDouble[index];
452  break;
453  case 'F':
454  value = ptr ? *(const Float_t*)ptr
455  : reader->singleFloat[index];
456  break;
457  case 'I':
458  value = ptr ? *(const Int_t*)ptr
459  : reader->singleInt[index];
460  break;
461  case 'B':
462  value = ptr ? *(const Bool_t*)ptr
463  : reader->singleBool[index];
464  break;
465  }
466 
467  if (!optional || value != optVal)
468  reader->values.add(name, value);
469  }
470 }
471 
472 #define TREEREADER_ADD_IMPL(T, C) \
473 template<> \
474 void TreeReader::addSingle<T>(AtomicId name, const T *value, bool opt) \
475 { addTypeSingle(name, value, C, opt); } \
476 \
477 template<> \
478 void TreeReader::addMulti(AtomicId name, const std::vector<T> *value) \
479 { addTypeMulti(name, value, C); }
480 
481 TREEREADER_ADD_IMPL(Double_t, 'D')
485 
486 #undef TREEREADER_ADD_IMPL
487 
488 } // namespace PhysicsTools
type
Definition: HCALResponse.h:21
double eval(Iterator_t first, Iterator_t last) const
evaluate variables given by a range of iterators given by first and last
Variable::ValueList fill()
Definition: TreeReader.cc:330
#define nullptr
std::vector< AtomicId > variables() const
Definition: TreeReader.cc:342
int Bool
Definition: Types.h:95
Variable::ValueList values
Definition: TreeReader.h:109
void setTree(TTree *tree)
Definition: TreeReader.cc:66
Cheap generic unique keyword identifier class.
Definition: AtomicId.h:31
std::vector< Bool > singleBool
Definition: TreeReader.h:106
Main interface class to the generic discriminator computer framework.
Definition: MVAComputer.h:39
void automaticAdd(bool skipTarget=false, bool skipWeight=false)
Definition: TreeReader.cc:241
std::vector< std::pair< void *, std::vector< Bool_t > > > multiBool
Definition: TreeReader.h:101
const std::complex< double > I
Definition: I.h:8
Definition: value.py:1
static const std::string B
Helper class that can contain an list of identifier-value pairs.
Definition: Variable.h:81
void setOptional(AtomicId name, bool opt, double optVal=kOptVal)
Definition: TreeReader.cc:142
void addTypeSingle(AtomicId name, const void *value, char type, bool opt)
Definition: TreeReader.cc:153
void update(TreeReader *reader) const
Definition: TreeReader.cc:352
uint64_t loop(const MVAComputer *mva)
Definition: TreeReader.cc:298
static const double kOptVal
Definition: TreeReader.h:57
unsigned long long uint64_t
Definition: Time.h:15
void addBranch(const std::string &expression, AtomicId name=AtomicId(), bool opt=true)
Definition: TreeReader.cc:72
std::map< AtomicId, Value > valueMap
Definition: TreeReader.h:108
std::vector< std::pair< void *, std::vector< Int_t > > > multiInt
Definition: TreeReader.h:100
std::vector< Double_t > singleDouble
Definition: TreeReader.h:103
void fill(AtomicId name, TreeReader *reader) const
Definition: TreeReader.cc:400
std::vector< Float_t > singleFloat
Definition: TreeReader.h:104
Definition: tree.py:1
TreeReader & operator=(const TreeReader &orig)
Definition: TreeReader.cc:45
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
void addTypeMulti(AtomicId name, const void *value, char type)
Definition: TreeReader.cc:199
#define TREEREADER_ADD_IMPL(T, C)
Definition: TreeReader.cc:472
std::vector< std::pair< void *, std::vector< Double_t > > > multiDouble
Definition: TreeReader.h:98
std::vector< Int_t > singleInt
Definition: TreeReader.h:105
std::vector< std::pair< void *, std::vector< Float_t > > > multiFloat
Definition: TreeReader.h:99
static std::pair< void *, std::vector< T > > makeMulti()
Definition: TreeReader.cc:196
void add(AtomicId id, double value)
Definition: Variable.h:106