Logo ROOT   6.14/05
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),
62  fLeafName(rhs.fLeafName),
64  fDict(rhs.fDict),
65  fProxy(rhs.fProxy),
66  fLeaf(rhs.fLeaf),
68 {
70 }
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Copy-assign.
74 
77  if (&rhs != this) {
78  fHaveLeaf = rhs.fHaveLeaf;
81  fLeafName = rhs.fLeafName;
82  if (fTreeReader != rhs.fTreeReader) {
83  if (fTreeReader)
87  }
88  fDict = rhs.fDict;
89  fProxy = rhs.fProxy;
90  fLeaf = rhs.fLeaf;
94  }
95  return *this;
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// Unregister from tree reader, cleanup.
100 
102 {
104  R__ASSERT((fLeafName.Length() == 0 ) == !fHaveLeaf
105  && "leafness disagreement");
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()) {
130  } else {
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) {
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 {
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 /// \brief Search a branch the name of which contains a "."
197 /// \param[out] myLeaf The leaf identified by the name if found (can be untouched).
198 /// \param[out] branchActualType Dictionary associated to the type of the leaf (can be untouched).
199 /// \param[out] errMsg The error message (can be untouched).
200 /// \return The address of the branch if found, nullptr otherwise
201 /// This method allows to efficiently search for branches which have names which
202 /// contain "dots", for example "w.v.a" or "v.a".
203 /// Therefore, it allows to support names such as v.a where the branch was
204 /// created with this syntax:
205 /// ```{.cpp}
206 /// myTree->Branch("v", &v, "a/I:b:/I")
207 /// ```
208 /// The method has some side effects, namely it can modify fSetupStatus, fProxy
209 /// and fStaticClassOffsets/fHaveStaticClassOffsets.
211 {
212  TRegexp leafNameExpression ("\\.[a-zA-Z0-9_]+$");
213  TString leafName (fBranchName(leafNameExpression));
214  TString branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
215  auto branch = fTreeReader->GetTree()->GetBranch(branchName);
216  if (!branch){
217  std::vector<TString> nameStack;
218  nameStack.push_back(TString()); //Trust me
219  nameStack.push_back(leafName.Strip(TString::kBoth, '.'));
220  leafName = branchName(leafNameExpression);
221  branchName = branchName(0, branchName.Length() - leafName.Length());
222 
223  branch = fTreeReader->GetTree()->GetBranch(branchName);
224  if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName + ".");
225  if (leafName.Length()) nameStack.push_back(leafName.Strip(TString::kBoth, '.'));
226 
227  while (!branch && branchName.Contains(".")){
228  leafName = branchName(leafNameExpression);
229  branchName = branchName(0, fBranchName.Length() - leafName.Length());
230  branch = fTreeReader->GetTree()->GetBranch(branchName);
231  if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName + ".");
232  nameStack.push_back(leafName.Strip(TString::kBoth, '.'));
233  }
234 
235  if (branch && branch->IsA() == TBranchElement::Class()){
236  TBranchElement *myBranchElement = (TBranchElement*)branch;
237 
238  TString traversingBranch = nameStack.back();
239  nameStack.pop_back();
240 
241  bool found = true;
242 
243  TDataType *finalDataType = 0;
244 
245  std::vector<Long64_t> offsets;
246  Long64_t offset = 0;
247  TClass *elementClass = 0;
248 
249  TObjArray *myObjArray = myBranchElement->GetInfo()->GetElements();
250  TVirtualStreamerInfo *myInfo = myBranchElement->GetInfo();
251 
252  while (nameStack.size() && found){
253  found = false;
254 
255  for (int i = 0; i < myObjArray->GetEntries(); ++i){
256 
257  TStreamerElement *tempStreamerElement = (TStreamerElement*)myObjArray->At(i);
258 
259  if (!strcmp(tempStreamerElement->GetName(), traversingBranch.Data())){
260  offset += myInfo->GetElementOffset(i);
261 
262  traversingBranch = nameStack.back();
263  nameStack.pop_back();
264 
265  elementClass = tempStreamerElement->GetClass();
266  if (elementClass) {
267  myInfo = elementClass->GetStreamerInfo(0);
268  myObjArray = myInfo->GetElements();
269  // FIXME: this is odd, why is 'i' not also reset????
270  }
271  else {
272  finalDataType = TDataType::GetDataType((EDataType)tempStreamerElement->GetType());
273  if (!finalDataType) {
274  TDictionary* seType = TDictionary::GetDictionary(tempStreamerElement->GetTypeName());
275  if (seType && seType->IsA() == TDataType::Class()) {
276  finalDataType = TDataType::GetDataType((EDataType)((TDataType*)seType)->GetType());
277  }
278  }
279  }
280 
281  if (tempStreamerElement->IsaPointer()){
282  offsets.push_back(offset);
283  offset = 0;
284  }
285 
286  found = true;
287  break;
288  }
289  }
290  }
291 
292  offsets.push_back(offset);
293 
294  if (found){
295  fStaticClassOffsets = offsets;
297 
298  if (fDict != finalDataType && fDict != elementClass){
299  errMsg = "Wrong data type ";
300  errMsg += finalDataType ? finalDataType->GetName() : elementClass ? elementClass->GetName() : "UNKNOWN";
302  fProxy = 0;
303  return nullptr;
304  }
305  }
306  }
307 
308 
310  errMsg = "The tree does not have a branch called ";
311  errMsg += fBranchName;
312  errMsg += ". You could check with TTree::Print() for available branches.";
314  fProxy = 0;
315  return nullptr;
316  }
317  }
318  else {
319  myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
320  if (!myLeaf){
321  errMsg = "The tree does not have a branch, nor a sub-branch called ";
322  errMsg += fBranchName;
323  errMsg += ". You could check with TTree::Print() for available branches.";
325  fProxy = 0;
326  return nullptr;
327  }
328  else {
329  TDictionary *tempDict = TDictionary::GetDictionary(myLeaf->GetTypeName());
330  if (tempDict && tempDict->IsA() == TDataType::Class() && TDictionary::GetDictionary(((TDataType*)tempDict)->GetTypeName()) == fDict){
331  //fLeafOffset = myLeaf->GetOffset() / 4;
332  branchActualType = fDict;
333  fLeaf = myLeaf;
335  fLeafName = leafName(1, leafName.Length());
336  fHaveLeaf = fLeafName.Length() > 0;
338  }
339  else {
340  errMsg = "Leaf of type ";
341  errMsg += myLeaf->GetTypeName();
342  errMsg += " cannot be read by TTreeReaderValue<";
343  errMsg += fDict->GetName();
344  errMsg += ">.";
346  return nullptr;
347  }
348  }
349  }
350 
351  return branch;
352 }
353 
354 ////////////////////////////////////////////////////////////////////////////////
355 /// Create the proxy object for our branch.
356 
358 
359  constexpr const char* errPrefix = "TTreeReaderValueBase::CreateProxy()";
360 
361  if (fProxy) {
362  return;
363  }
364 
365  fSetupStatus = kSetupInternalError; // Fallback; set to something concrete below.
366  if (!fTreeReader) {
367  Error(errPrefix, "TTreeReader object not set / available for branch %s!",
368  fBranchName.Data());
370  return;
371  }
372 
373  auto branchFromFullName = fTreeReader->GetTree()->GetBranch(fBranchName);
374 
375  if (!fDict) {
376  const char* brDataType = "{UNDETERMINED}";
377  if (branchFromFullName) {
378  TDictionary* brDictUnused = 0;
379  brDataType = GetBranchDataType(branchFromFullName, brDictUnused);
380  }
381  Error(errPrefix, "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.",
382  GetDerivedTypeName(), fBranchName.Data(), brDataType);
384  return;
385  }
386 
387  // Search for the branchname, determine what it contains, and wire the
388  // TBranchProxy representing it to us so we can access its data.
389 
391  if (namedProxy && namedProxy->GetDict() == fDict) {
392  fProxy = namedProxy->GetProxy();
393  // But go on: we need to set fLeaf etc!
394  }
395 
396  const std::string originalBranchName = fBranchName.Data();
397 
398  TLeaf *myLeaf = nullptr;
399  TDictionary* branchActualType = nullptr;
400  std::string errMsg;
401 
402  TBranch *branch = nullptr;
403  // If the branch name contains at least a dot, we analyse it in detail and
404  // we give priority to the branch identified over the one which is found
405  // with the TTree::GetBranch method. This allow to correctly pick the desired
406  // branch in cases where a TTree has two branches, one called for example
407  // "w.v.a" and another one called "v.a".
408  // This behaviour is described in ROOT-9312.
409  if (fBranchName.Contains(".")) {
410  branch = SearchBranchWithCompositeName(myLeaf, branchActualType, errMsg);
411  }
412 
413  if (!branch) {
414  // We had an error, the branch name had no "." or we simply did not find anything.
415  // We check if we had a branch found with the full name with a dot in it.
416  branch = branchFromFullName;
417  if (!branch) {
418  // Also that one was empty. We need to error out. We do it properly: at
419  // first we check if the routine to find branches with names with a "."
420  // provided a specific error message. If not, we go with a generic message.
421  if (errMsg.empty()) {
422  errMsg = "The tree does not have a branch called ";
423  errMsg += fBranchName.Data();
424  errMsg += ". You could check with TTree::Print() for available branches.";
425  }
426 #pragma GCC diagnostic push
427 #pragma GCC diagnostic ignored "-Wformat-security"
428  Error(errPrefix, errMsg.c_str());
429 #pragma GCC diagnostic pop
430  return;
431  } else {
432  // The branch found with the simplest search approach was successful.
433  // We reset the state, we continue
435  fStaticClassOffsets = {};
437  }
438  }
439 
440  if (!myLeaf && !fHaveStaticClassOffsets) {
441  // The following two lines cannot be swapped. The GetBranchDataType can
442  // change the value of branchActualType
443  const char* branchActualTypeName = GetBranchDataType(branch, branchActualType);
444  if (!branchActualType) {
445  Error(errPrefix, "The branch %s contains data of type %s, which does not have a dictionary.",
446  fBranchName.Data(), branchActualTypeName ? branchActualTypeName : "{UNDETERMINED TYPE}");
447  fProxy = 0;
448  return;
449  }
450 
451  if (fDict != branchActualType) {
452  TDataType *dictdt = dynamic_cast<TDataType*>(fDict);
453  TDataType *actualdt = dynamic_cast<TDataType*>(branchActualType);
454  bool complainAboutMismatch = true;
455  if (dictdt && actualdt) {
456  if (dictdt->GetType() > 0 && dictdt->GetType() == actualdt->GetType()) {
457  // Same numerical type but different TDataType, likely Long64_t
458  complainAboutMismatch = false;
459  } else if ((actualdt->GetType() == kDouble32_t && dictdt->GetType() == kDouble_t)
460  || (actualdt->GetType() == kFloat16_t && dictdt->GetType() == kFloat_t)) {
461  // Double32_t and Float16_t never "decay" to their underlying type;
462  // we need to identify them manually here (ROOT-8731).
463  complainAboutMismatch = false;
464  }
465  }
466  if (complainAboutMismatch) {
467  Error(errPrefix,
468  "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderValue<%s>",
469  fBranchName.Data(), branchActualType->GetName(),
470  fDict->GetName());
471  return;
472  }
473  }
474  }
475 
476  if (!namedProxy) {
477  // Search for the branchname, determine what it contains, and wire the
478  // TBranchProxy representing it to us so we can access its data.
479  // A proxy for branch must not have been created before (i.e. check
480  // fProxies before calling this function!)
481 
482  TString membername;
483 
484  bool isTopLevel = branch->GetMother() == branch;
485  if (!isTopLevel) {
486  membername = strrchr(branch->GetName(), '.');
487  if (membername.IsNull()) {
488  membername = branch->GetName();
489  }
490  }
491  namedProxy = new TNamedBranchProxy(fTreeReader->fDirector, branch, originalBranchName.c_str(), membername);
492  fTreeReader->AddProxy(namedProxy);
493  }
494 
495  // Update named proxy's dictionary
496  if (!namedProxy->GetDict())
497  namedProxy->SetDict(fDict);
498 
499  fProxy = namedProxy->GetProxy();
500  if (fProxy) {
502  } else {
504  }
505 }
506 
507 ////////////////////////////////////////////////////////////////////////////////
508 /// Retrieve the type of data stored by branch; put its dictionary into
509 /// dict, return its type name. If no dictionary is available, at least
510 /// its type name should be returned.
511 
513  TDictionary* &dict) const
514 {
515  dict = 0;
516  if (branch->IsA() == TBranchElement::Class()) {
517  TBranchElement* brElement = (TBranchElement*)branch;
518 
519  auto ResolveTypedef = [&]() -> void {
520  if (dict->IsA() != TDataType::Class())
521  return;
522  // Resolve the typedef.
523  dict = TDictionary::GetDictionary(((TDataType*)dict)->GetTypeName());
524  if (dict->IsA() != TDataType::Class()) {
525  // Might be a class.
526  if (dict != fDict) {
527  dict = TClass::GetClass(brElement->GetTypeName());
528  }
529  if (dict != fDict) {
530  dict = brElement->GetCurrentClass();
531  }
532  }
533  };
534 
535  if (brElement->GetType() == TBranchElement::kSTLNode ||
536  brElement->GetType() == TBranchElement::kLeafNode ||
537  brElement->GetType() == TBranchElement::kObjectNode) {
538 
539  TStreamerInfo *streamerInfo = brElement->GetInfo();
540  Int_t id = brElement->GetID();
541 
542  if (id >= 0){
543  TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(id);
544  if (element->IsA() == TStreamerSTL::Class()){
545  TStreamerSTL *myStl = (TStreamerSTL*)element;
546  dict = myStl->GetClass();
547  return 0;
548  }
549  }
550 
551  if (brElement->GetType() == 3 || brElement->GetType() == 4) {
552  dict = brElement->GetCurrentClass();
553  return brElement->GetTypeName();
554  }
555 
556  if (brElement->GetTypeName())
557  dict = TDictionary::GetDictionary(brElement->GetTypeName());
558 
559  if (dict)
560  ResolveTypedef();
561  else
562  dict = brElement->GetCurrentClass();
563 
564  return brElement->GetTypeName();
565  } else if (brElement->GetType() == TBranchElement::kClonesNode) {
566  dict = TClonesArray::Class();
567  return "TClonesArray";
568  } else if (brElement->GetType() == 31
569  || brElement->GetType() == 41) {
570  // it's a member, extract from GetClass()'s streamer info
571  Error("TTreeReaderValueBase::GetBranchDataType()", "Must use TTreeReaderArray to access a member of an object that is stored in a collection.");
572  } else if (brElement->GetType() == -1 && brElement->GetTypeName()) {
573  dict = TDictionary::GetDictionary(brElement->GetTypeName());
574  ResolveTypedef();
575  return brElement->GetTypeName();
576  } else {
577  Error("TTreeReaderValueBase::GetBranchDataType()", "Unknown type and class combination: %i, %s", brElement->GetType(), brElement->GetClassName());
578  }
579  return 0;
580  } else if (branch->IsA() == TBranch::Class()
581  || branch->IsA() == TBranchObject::Class()
582  || branch->IsA() == TBranchSTL::Class()) {
583  if (branch->GetTree()->IsA() == TNtuple::Class()){
585  return dict->GetName();
586  }
587  const char* dataTypeName = branch->GetClassName();
588  if ((!dataTypeName || !dataTypeName[0])
589  && branch->IsA() == TBranch::Class()) {
590  TLeaf *myLeaf = branch->GetLeaf(branch->GetName());
591  if (myLeaf){
592  TDictionary *myDataType = TDictionary::GetDictionary(myLeaf->GetTypeName());
593  if (myDataType && myDataType->IsA() == TDataType::Class()){
594  if (myLeaf->GetLeafCount() != nullptr || myLeaf->GetLenStatic() > 1) {
595  Error("TTreeReaderValueBase::GetBranchDataType()", "Must use TTreeReaderArray to read branch %s: it contains an array or a collection.", branch->GetName());
596  return 0;
597  }
598  dict = TDataType::GetDataType((EDataType)((TDataType*)myDataType)->GetType());
599  return myLeaf->GetTypeName();
600  }
601  }
602 
603  // leaflist. Can't represent.
604  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());
605  TIter iLeaves(branch->GetListOfLeaves());
606  TLeaf* leaf = 0;
607  while ((leaf = (TLeaf*) iLeaves())) {
608  Error("TTreeReaderValueBase::GetBranchDataType()", " %s.%s", branch->GetName(), leaf->GetName());
609  }
610  return 0;
611  }
612  if (dataTypeName) dict = TDictionary::GetDictionary(dataTypeName);
613  return dataTypeName;
614  } else if (branch->IsA() == TBranchClones::Class()) {
615  dict = TClonesArray::Class();
616  return "TClonesArray";
617  } else if (branch->IsA() == TBranchRef::Class()) {
618  // Can't represent.
619  Error("TTreeReaderValueBase::GetBranchDataType()", "The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->GetName());
620  return 0;
621  } else {
622  Error("TTreeReaderValueBase::GetBranchDataType()", "The branch %s is of type %s - something that is not handled yet.", branch->GetName(), branch->IsA()->GetName());
623  return 0;
624  }
625 
626  return 0;
627 }
628 
ROOT::Internal::TNamedBranchProxy * FindProxy(const char *branchname) const
Definition: TTreeReader.h:227
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:1275
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
To read this branch, we need a dictionary.
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:43
The branch class type is not a collection.
virtual const char * GetTypeName() const
Definition: TLeaf.h:89
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:4420
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:131
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
The array cannot find its counter branch: Array[CounterBranch].
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
Bool_t RegisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader)
Add a value reader for this tree.
TTree * GetTree() const
Definition: TTreeReader.h:162
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:1645
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:5017
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.
ROOT::Internal::TBranchProxyDirector * fDirector
proxying director, owned
Definition: TTreeReader.h:269
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
void AddProxy(ROOT::Internal::TNamedBranchProxy *p)
Definition: TTreeReader.h:233
virtual void CreateProxy()
Create the proxy object for our branch.
Some other error - hopefully the error message helps.
Ssiz_t Length() const
Definition: TString.h:405
virtual TLeaf * GetLeafCount() const
If this leaf stores a variable-sized array or a multi-dimensional array whose last dimension has vari...
Definition: TLeaf.h:74
TClass * GetCurrentClass()
Return a pointer to the current type of the data member corresponding to branch element.
virtual void * GetValuePointer() const
Definition: TLeaf.h:88
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1081
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
virtual Int_t GetLenStatic() const
Return the fixed length of this leaf.
Definition: TLeaf.h:82
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:1350
EDataType
Definition: TDataType.h:28
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:619
void DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader)
Remove a value reader for this tree.
TObjArray * GetListOfLeaves()
Definition: TBranch.h:202
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
TBranch * SearchBranchWithCompositeName(TLeaf *&myleaf, TDictionary *&branchActualType, std::string &err)
Search a branch the name of which contains a ".".
Bool_t IsNull() const
Definition: TString.h:402
TLeaf * GetLeaf()
If we are reading a leaf, return the corresponding TLeaf.
TObjArray * GetElements() const
const char * GetTypeName() const
virtual const char * GetDerivedTypeName() const =0
void NotifyNewTree(TTree *newTree)
The TTreeReader has switched to a new TTree. Update the leaf.
TTree * GetTree() const
Definition: TBranch.h:207
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:62
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:1718
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:364