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