Logo ROOT   6.10/00
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TTreeReaderValue.cxx
Go to the documentation of this file.
1 // @(#)root/treeplayer:$Id$
2 // Author: Axel Naumann, 2011-09-28
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers and al. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TTreeReaderValue.h"
13 
14 #include "TTreeReader.h"
15 #include "TBranchClones.h"
16 #include "TBranchElement.h"
17 #include "TBranchRef.h"
18 #include "TBranchSTL.h"
19 #include "TBranchProxyDirector.h"
20 #include "TClassEdit.h"
21 #include "TLeaf.h"
22 #include "TTreeProxyGenerator.h"
23 #include "TTreeReaderValue.h"
24 #include "TRegexp.h"
25 #include "TStreamerInfo.h"
26 #include "TStreamerElement.h"
27 #include "TNtuple.h"
28 #include <vector>
29 
30 /** \class TTreeReaderValue
31 
32 Extracts data from a TTree.
33 */
34 
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 /// Construct a tree value reader and register it with the reader object.
39 
41  const char* branchname /*= 0*/,
42  TDictionary* dict /*= 0*/):
43  fBranchName(branchname),
44  fTreeReader(reader),
45  fDict(dict),
46  fProxy(NULL),
47  fLeaf(NULL),
48  fSetupStatus(kSetupNotSetup),
49  fReadStatus(kReadNothingYet)
50 {
51  RegisterWithTreeReader();
52 }
53 
54 ////////////////////////////////////////////////////////////////////////////////
55 /// Copy-construct.
56 
58  fBranchName(rhs.fBranchName),
59  fLeafName(rhs.fLeafName),
60  fTreeReader(rhs.fTreeReader),
61  fDict(rhs.fDict),
62  fProxy(rhs.fProxy),
63  fLeaf(rhs.fLeaf),
64  fSetupStatus(rhs.fSetupStatus),
65  fReadStatus(rhs.fReadStatus),
66  fStaticClassOffsets(rhs.fStaticClassOffsets)
67 {
69 }
70 
71 ////////////////////////////////////////////////////////////////////////////////
72 /// Copy-assign.
73 
76  if (&rhs != this) {
77  fBranchName = rhs.fBranchName;
78  fLeafName = rhs.fLeafName;
79  if (fTreeReader != rhs.fTreeReader) {
80  if (fTreeReader)
81  fTreeReader->DeregisterValueReader(this);
82  fTreeReader = rhs.fTreeReader;
83  RegisterWithTreeReader();
84  }
85  fDict = rhs.fDict;
86  fProxy = rhs.fProxy;
87  fLeaf = rhs.fLeaf;
88  fSetupStatus = rhs.fSetupStatus;
89  fReadStatus = rhs.fReadStatus;
90  fStaticClassOffsets = rhs.fStaticClassOffsets;
91  }
92  return *this;
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// Unregister from tree reader, cleanup.
97 
99 {
100  if (fTreeReader) fTreeReader->DeregisterValueReader(this);
101 }
102 
103 ////////////////////////////////////////////////////////////////////////////////
104 /// Register with tree reader.
105 
107  if (fTreeReader) {
108  if (!fTreeReader->RegisterValueReader(this)) {
109  fTreeReader = nullptr;
110  }
111  }
112 }
113 
114 ////////////////////////////////////////////////////////////////////////////////
115 /// Try to read the value from the TBranchProxy, returns
116 /// the status of the read.
117 
120  if (!fProxy) return kReadNothingYet;
121  if (fProxy->Read()) {
122  fReadStatus = kReadSuccess;
123  } else {
124  fReadStatus = kReadError;
125  }
126  return fReadStatus;
127 }
128 
129 ////////////////////////////////////////////////////////////////////////////////
130 /// Stringify the template argument.
131 std::string ROOT::Internal::TTreeReaderValueBase::GetElementTypeName(const std::type_info& ti) {
132  int err;
133  char* buf = TClassEdit::DemangleTypeIdName(ti, err);
134  std::string ret = buf;
135  free(buf);
136  return ret;
137 }
138 
139 ////////////////////////////////////////////////////////////////////////////////
140 /// The TTreeReader has switched to a new TTree. Update the leaf.
141 
143  if (fLeafName.Length() == 0)
144  return;
145 
146  TBranch *myBranch = newTree->GetBranch(fBranchName);
147 
148  if (!myBranch) {
149  fReadStatus = kReadError;
150  Error("TTreeReaderValueBase::GetLeaf()", "Unable to get the branch from the tree");
151  return;
152  }
153 
154  fLeaf = myBranch->GetLeaf(fLeafName);
155  if (!fLeaf) {
156  Error("TTreeReaderValueBase::GetLeaf()", "Failed to get the leaf from the branch");
157  }
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 /// Returns the memory address of the object being read.
162 
164  if (ProxyRead() != kReadSuccess) return 0;
165 
166  if (fLeafName.Length() > 0){
167  if (GetLeaf()){
168  return fLeaf->GetValuePointer();
169  }
170  else {
171  fReadStatus = kReadError;
172  Error("TTreeReaderValueBase::GetAddress()", "Unable to get the leaf");
173  return 0;
174  }
175  }
176  if (!fStaticClassOffsets.empty()){ // Follow all the pointers
177  Byte_t *address = (Byte_t*)fProxy->GetWhere();
178 
179  for (unsigned int i = 0; i < fStaticClassOffsets.size() - 1; ++i){
180  address = *(Byte_t**)(address + fStaticClassOffsets[i]);
181  }
182 
183  return address + fStaticClassOffsets.back();
184  }
185  return fProxy ? (Byte_t*)fProxy->GetWhere() : 0;
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////
189 /// Create the proxy object for our branch.
190 
192  if (fProxy) {
193  return;
194  }
195 
196  fSetupStatus = kSetupInternalError; // Fallback; set to something concrete below.
197  if (!fTreeReader) {
198  Error("TTreeReaderValueBase::CreateProxy()", "TTreeReader object not set / available for branch %s!",
199  fBranchName.Data());
200  fSetupStatus = kSetupTreeDestructed;
201  return;
202  }
203  if (!fDict) {
204  TBranch* br = fTreeReader->GetTree()->GetBranch(fBranchName);
205  const char* brDataType = "{UNDETERMINED}";
206  if (br) {
207  TDictionary* brDictUnused = 0;
208  brDataType = GetBranchDataType(br, brDictUnused);
209  }
210  Error("TTreeReaderValueBase::CreateProxy()", "The template argument type T of %s accessing branch %s (which contains data of type %s) is not known to ROOT. You will need to create a dictionary for it.",
211  GetDerivedTypeName(), fBranchName.Data(), brDataType);
212  fSetupStatus = kSetupMissingDictionary;
213  return;
214  }
215 
216  // Search for the branchname, determine what it contains, and wire the
217  // TBranchProxy representing it to us so we can access its data.
218 
219  TNamedBranchProxy* namedProxy
220  = (TNamedBranchProxy*)fTreeReader->FindObject(fBranchName);
221  if (namedProxy && namedProxy->GetDict() == fDict) {
222  fProxy = namedProxy->GetProxy();
223  fSetupStatus = kSetupMatch;
224  return;
225  }
226 
227  TBranch* branch = fTreeReader->GetTree()->GetBranch(fBranchName);
228  TLeaf *myLeaf = NULL;
229  TDictionary* branchActualType = 0;
230 
231  if (!branch) {
232  if (fBranchName.Contains(".")){
233  TRegexp leafNameExpression ("\\.[a-zA-Z0-9_]+$");
234  TString leafName (fBranchName(leafNameExpression));
235  TString branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
236  branch = fTreeReader->GetTree()->GetBranch(branchName);
237  if (!branch){
238  std::vector<TString> nameStack;
239  nameStack.push_back(TString()); //Trust me
240  nameStack.push_back(leafName.Strip(TString::kBoth, '.'));
241  leafName = branchName(leafNameExpression);
242  branchName = branchName(0, branchName.Length() - leafName.Length());
243 
244  branch = fTreeReader->GetTree()->GetBranch(branchName);
245  if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName + ".");
246  if (leafName.Length()) nameStack.push_back(leafName.Strip(TString::kBoth, '.'));
247 
248  while (!branch && branchName.Contains(".")){
249  leafName = branchName(leafNameExpression);
250  branchName = branchName(0, fBranchName.Length() - leafName.Length());
251  branch = fTreeReader->GetTree()->GetBranch(branchName);
252  if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName + ".");
253  nameStack.push_back(leafName.Strip(TString::kBoth, '.'));
254  }
255 
256  if (branch && branch->IsA() == TBranchElement::Class()){
257  TBranchElement *myBranchElement = (TBranchElement*)branch;
258 
259  TString traversingBranch = nameStack.back();
260  nameStack.pop_back();
261 
262  bool found = true;
263 
264  TDataType *finalDataType = 0;
265 
266  std::vector<Long64_t> offsets;
267  Long64_t offset = 0;
268  TClass *elementClass = 0;
269 
270  TObjArray *myObjArray = myBranchElement->GetInfo()->GetElements();
271  TVirtualStreamerInfo *myInfo = myBranchElement->GetInfo();
272 
273  while (nameStack.size() && found){
274  found = false;
275 
276  for (int i = 0; i < myObjArray->GetEntries(); ++i){
277 
278  TStreamerElement *tempStreamerElement = (TStreamerElement*)myObjArray->At(i);
279 
280  if (!strcmp(tempStreamerElement->GetName(), traversingBranch.Data())){
281  offset += myInfo->GetElementOffset(i);
282 
283  traversingBranch = nameStack.back();
284  nameStack.pop_back();
285 
286  elementClass = tempStreamerElement->GetClass();
287  if (elementClass) {
288  myInfo = elementClass->GetStreamerInfo(0);
289  myObjArray = myInfo->GetElements();
290  // FIXME: this is odd, why is 'i' not also reset????
291  }
292  else {
293  finalDataType = TDataType::GetDataType((EDataType)tempStreamerElement->GetType());
294  if (!finalDataType) {
295  TDictionary* seType = TDictionary::GetDictionary(tempStreamerElement->GetTypeName());
296  if (seType && seType->IsA() == TDataType::Class()) {
297  finalDataType = TDataType::GetDataType((EDataType)((TDataType*)seType)->GetType());
298  }
299  }
300  }
301 
302  if (tempStreamerElement->IsaPointer()){
303  offsets.push_back(offset);
304  offset = 0;
305  }
306 
307  found = true;
308  break;
309  }
310  }
311  }
312 
313  offsets.push_back(offset);
314 
315  if (found){
316  fStaticClassOffsets = offsets;
317 
318  if (fDict != finalDataType && fDict != elementClass){
319  Error("TTreeReaderValueBase::CreateProxy", "Wrong data type %s", finalDataType ? finalDataType->GetName() : elementClass ? elementClass->GetName() : "UNKNOWN");
320  fSetupStatus = kSetupMismatch;
321  fProxy = 0;
322  return;
323  }
324  }
325  }
326 
327 
328  if (!fStaticClassOffsets.size()) {
329  Error("TTreeReaderValueBase::CreateProxy()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
330  fSetupStatus = kSetupMissingBranch;
331  fProxy = 0;
332  return;
333  }
334  }
335  else {
336  myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
337  if (!myLeaf){
338  Error("TTreeReaderValueBase::CreateProxy()",
339  "The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
340  fSetupStatus = kSetupMissingBranch;
341  fProxy = 0;
342  return;
343  }
344  else {
345  TDictionary *tempDict = TDictionary::GetDictionary(myLeaf->GetTypeName());
346  if (tempDict && tempDict->IsA() == TDataType::Class() && TDictionary::GetDictionary(((TDataType*)tempDict)->GetTypeName()) == fDict){
347  //fLeafOffset = myLeaf->GetOffset() / 4;
348  branchActualType = fDict;
349  fLeaf = myLeaf;
350  fBranchName = branchName;
351  fLeafName = leafName(1, leafName.Length());
352  fSetupStatus = kSetupMatchLeaf;
353  }
354  else {
355  Error("TTreeReaderValueBase::CreateProxy()",
356  "Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->GetTypeName(), fDict->GetName());
357  fSetupStatus = kSetupMismatch;
358  }
359  }
360  }
361  }
362  else {
363  Error("TTreeReaderValueBase::CreateProxy()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
364  fProxy = 0;
365  return;
366  }
367  }
368 
369  if (!myLeaf && !fStaticClassOffsets.size()) {
370  const char* branchActualTypeName = GetBranchDataType(branch, branchActualType);
371 
372  if (!branchActualType) {
373  Error("TTreeReaderValueBase::CreateProxy()", "The branch %s contains data of type %s, which does not have a dictionary.",
374  fBranchName.Data(), branchActualTypeName ? branchActualTypeName : "{UNDETERMINED TYPE}");
375  fProxy = 0;
376  return;
377  }
378 
379  if (fDict != branchActualType) {
380  TDataType *dictdt = dynamic_cast<TDataType*>(fDict);
381  TDataType *actualdt = dynamic_cast<TDataType*>(branchActualType);
382  bool complainAboutMismatch = true;
383  if (dictdt && actualdt) {
384  if (dictdt->GetType() > 0 && dictdt->GetType() == actualdt->GetType()) {
385  // Same numerical type but different TDataType, likely Long64_t
386  complainAboutMismatch = false;
387  } else if ((actualdt->GetType() == kDouble32_t && dictdt->GetType() == kDouble_t)
388  || (actualdt->GetType() == kFloat16_t && dictdt->GetType() == kFloat_t)) {
389  // Double32_t and Float16_t never "decay" to their underlying type;
390  // we need to identify them manually here (ROOT-8731).
391  complainAboutMismatch = false;
392  }
393  }
394  if (complainAboutMismatch) {
395  Error("TTreeReaderValueBase::CreateProxy()",
396  "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderValue<%s>",
397  fBranchName.Data(), branchActualType->GetName(),
398  fDict->GetName());
399  return;
400  }
401  }
402  }
403 
404 
405  // Update named proxy's dictionary
406  if (namedProxy && !namedProxy->GetDict()) {
407  namedProxy->SetDict(fDict);
408  fProxy = namedProxy->GetProxy();
409  if (fProxy)
410  fSetupStatus = kSetupMatch;
411  return;
412  }
413 
414  // Search for the branchname, determine what it contains, and wire the
415  // TBranchProxy representing it to us so we can access its data.
416  // A proxy for branch must not have been created before (i.e. check
417  // fProxies before calling this function!)
418 
419  TString membername;
420 
421  bool isTopLevel = branch->GetMother() == branch;
422  if (!isTopLevel) {
423  membername = strrchr(branch->GetName(), '.');
424  if (membername.IsNull()) {
425  membername = branch->GetName();
426  }
427  }
428  namedProxy = new TNamedBranchProxy(fTreeReader->fDirector, branch, membername);
429  fTreeReader->GetProxies()->Add(namedProxy);
430  fProxy = namedProxy->GetProxy();
431  if (fProxy) {
432  fSetupStatus = kSetupMatch;
433  } else {
434  fSetupStatus = kSetupMismatch;
435  }
436 }
437 
438 ////////////////////////////////////////////////////////////////////////////////
439 /// Retrieve the type of data stored by branch; put its dictionary into
440 /// dict, return its type name. If no dictionary is available, at least
441 /// its type name should be returned.
442 
444  TDictionary* &dict) const
445 {
446  dict = 0;
447  if (branch->IsA() == TBranchElement::Class()) {
448  TBranchElement* brElement = (TBranchElement*)branch;
449 
450  auto ResolveTypedef = [&]() -> void {
451  if (dict->IsA() != TDataType::Class())
452  return;
453  // Resolve the typedef.
454  dict = TDictionary::GetDictionary(((TDataType*)dict)->GetTypeName());
455  if (dict->IsA() != TDataType::Class()) {
456  // Might be a class.
457  if (dict != fDict) {
458  dict = TClass::GetClass(brElement->GetTypeName());
459  }
460  if (dict != fDict) {
461  dict = brElement->GetCurrentClass();
462  }
463  }
464  };
465 
466  if (brElement->GetType() == TBranchElement::kSTLNode ||
467  brElement->GetType() == TBranchElement::kLeafNode ||
468  brElement->GetType() == TBranchElement::kObjectNode) {
469 
470  TStreamerInfo *streamerInfo = brElement->GetInfo();
471  Int_t id = brElement->GetID();
472 
473  if (id >= 0){
474  TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(id);
475  if (element->IsA() == TStreamerSTL::Class()){
476  TStreamerSTL *myStl = (TStreamerSTL*)element;
477  dict = myStl->GetClass();
478  return 0;
479  }
480  }
481 
482  if (brElement->GetType() == 3 || brElement->GetType() == 4) {
483  dict = brElement->GetCurrentClass();
484  return brElement->GetTypeName();
485  }
486 
487  if (brElement->GetTypeName())
488  dict = TDictionary::GetDictionary(brElement->GetTypeName());
489 
490  if (dict)
491  ResolveTypedef();
492  else
493  dict = brElement->GetCurrentClass();
494 
495  return brElement->GetTypeName();
496  } else if (brElement->GetType() == TBranchElement::kClonesNode) {
497  dict = TClonesArray::Class();
498  return "TClonesArray";
499  } else if (brElement->GetType() == 31
500  || brElement->GetType() == 41) {
501  // it's a member, extract from GetClass()'s streamer info
502  Error("TTreeReaderValueBase::GetBranchDataType()", "Must use TTreeReaderArray to access a member of an object that is stored in a collection.");
503  } else if (brElement->GetType() == -1 && brElement->GetTypeName()) {
504  dict = TDictionary::GetDictionary(brElement->GetTypeName());
505  ResolveTypedef();
506  return brElement->GetTypeName();
507  } else {
508  Error("TTreeReaderValueBase::GetBranchDataType()", "Unknown type and class combination: %i, %s", brElement->GetType(), brElement->GetClassName());
509  }
510  return 0;
511  } else if (branch->IsA() == TBranch::Class()
512  || branch->IsA() == TBranchObject::Class()
513  || branch->IsA() == TBranchSTL::Class()) {
514  if (branch->GetTree()->IsA() == TNtuple::Class()){
516  return dict->GetName();
517  }
518  const char* dataTypeName = branch->GetClassName();
519  if ((!dataTypeName || !dataTypeName[0])
520  && branch->IsA() == TBranch::Class()) {
521  TLeaf *myLeaf = branch->GetLeaf(branch->GetName());
522  if (myLeaf){
523  TDictionary *myDataType = TDictionary::GetDictionary(myLeaf->GetTypeName());
524  if (myDataType && myDataType->IsA() == TDataType::Class()){
525  dict = TDataType::GetDataType((EDataType)((TDataType*)myDataType)->GetType());
526  return myLeaf->GetTypeName();
527  }
528  }
529 
530 
531  // leaflist. Can't represent.
532  Error("TTreeReaderValueBase::GetBranchDataType()", "The branch %s was created using a leaf list and cannot be represented as a C++ type. Please access one of its siblings using a TTreeReaderArray:", branch->GetName());
533  TIter iLeaves(branch->GetListOfLeaves());
534  TLeaf* leaf = 0;
535  while ((leaf = (TLeaf*) iLeaves())) {
536  Error("TTreeReaderValueBase::GetBranchDataType()", " %s.%s", branch->GetName(), leaf->GetName());
537  }
538  return 0;
539  }
540  if (dataTypeName) dict = TDictionary::GetDictionary(dataTypeName);
541  return dataTypeName;
542  } else if (branch->IsA() == TBranchClones::Class()) {
543  dict = TClonesArray::Class();
544  return "TClonesArray";
545  } else if (branch->IsA() == TBranchRef::Class()) {
546  // Can't represent.
547  Error("TTreeReaderValueBase::GetBranchDataType()", "The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->GetName());
548  return 0;
549  } else {
550  Error("TTreeReaderValueBase::GetBranchDataType()", "The branch %s is of type %s - something that is not handled yet.", branch->GetName(), branch->IsA()->GetName());
551  return 0;
552  }
553 
554  return 0;
555 }
556 
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:43
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:32
An array of TObjects.
Definition: TObjArray.h:37
static TDataType * GetDataType(EDataType type)
Given a EDataType type, get the TDataType* that represents it.
Definition: TDataType.cxx:440
long long Long64_t
Definition: RtypesCore.h:69
Int_t GetID() const
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
Definition: TBranch.cxx:1495
const char * GetTypeName() const
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Definition: TTreeReader.h:42
Int_t GetType() const
Definition: TDataType.h:68
Ssiz_t Length() const
Definition: TString.h:385
const char * GetBranchDataType(TBranch *branch, TDictionary *&dict) const
Retrieve the type of data stored by branch; put its dictionary into dict, return its type name...
virtual ~TTreeReaderValueBase()
Unregister from tree reader, cleanup.
Regular expression class.
Definition: TRegexp.h:31
static TDictionary * GetDictionary(const char *name)
Definition: TDictionary.cxx:84
Basic string class.
Definition: TString.h:129
EReadStatus ProxyRead()
Try to read the value from the TBranchProxy, returns the status of the read.
int Int_t
Definition: RtypesCore.h:41
std::vector< Long64_t > fStaticClassOffsets
Type GetType(const std::string &Name)
Definition: Systematics.cxx:34
#define NULL
Definition: RtypesCore.h:88
const Detail::TBranchProxy * GetProxy() const
const char * Data() const
Definition: TString.h:344
void Class()
Definition: Class.C:29
unsigned char Byte_t
Definition: RtypesCore.h:60
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
virtual Bool_t IsaPointer() const
TTreeReaderValueBase & operator=(const TTreeReaderValueBase &)
Copy-assign.
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition: TTree.cxx:4979
void SetDict(TDictionary *dict)
void RegisterWithTreeReader()
Register with tree reader.
virtual const char * GetTypeName() const
Definition: TLeaf.h:76
TObjArray * GetElements() const
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist...
Definition: TClass.cxx:4359
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:44
This class defines an abstract interface that must be implemented by all classes that contain diction...
Definition: TDictionary.h:158
TBranch * GetMother() const
Get our top-level parent branch in the tree.
Definition: TBranch.cxx:1568
virtual void CreateProxy()
Create the proxy object for our branch.
TClass * GetCurrentClass()
Return a pointer to the current type of the data member corresponding to branch element.
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
void * GetAddress()
Returns the memory address of the object being read.
TSubString Strip(EStripType s=kTrailing, char c= ' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1080
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:71
Bool_t IsNull() const
Definition: TString.h:382
TTree * GetTree() const
Definition: TBranch.h:187
A Branch for the case of an object.
virtual const char * GetTypeName() const
Return type name of element in the branch.
static std::string GetElementTypeName(const std::type_info &ti)
Stringify the template argument.
#define ClassImp(name)
Definition: Rtypes.h:336
virtual TObjArray * GetElements() const =0
#define free
Definition: civetweb.c:821
EDataType
Definition: TDataType.h:28
TObjArray * GetListOfLeaves()
Definition: TBranch.h:182
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2885
TClass * GetClass() const
Int_t GetType() const
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:568
TTreeReaderValueBase(TTreeReader *reader=0, const char *branchname=0, TDictionary *dict=0)
Construct a tree value reader and register it with the reader object.
void NotifyNewTree(TTree *newTree)
The TTreeReader has switched to a new TTree. Update the leaf.
Int_t GetType() const
A TTree object has a header with a name and a title.
Definition: TTree.h:78
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
A TTree is a list of TBranches.
Definition: TBranch.h:57
Abstract Interface class describing Streamer information for one class.
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
Definition: TBranch.cxx:1199
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:328
TDictionary * GetDict() const
virtual Int_t GetElementOffset(Int_t id) const =0
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.