Logo ROOT   6.14/05
Reference Guide
TTreeReaderValue.h
Go to the documentation of this file.
1 // @(#)root/tree:$Id$
2 // Author: Axel Naumann, 2010-08-02
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers. *
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 #ifndef ROOT_TTreeReaderValue
13 #define ROOT_TTreeReaderValue
14 
15 
16 ////////////////////////////////////////////////////////////////////////////
17 // //
18 // TTreeReaderValue //
19 // //
20 // A simple interface for reading data from trees or chains. //
21 // //
22 // //
23 ////////////////////////////////////////////////////////////////////////////
24 
25 #include "TString.h"
26 #include "TDictionary.h"
27 #include "TBranchProxy.h"
28 
29 #include <type_traits>
30 
31 class TBranch;
32 class TBranchElement;
33 class TLeaf;
34 class TTreeReader;
35 
36 namespace ROOT {
37 namespace Internal {
38 
40  public:
41 
42  // Status flags, 0 is good
43  enum ESetupStatus {
44  kSetupNotSetup = -7, /// No initialization has happened yet.
45  kSetupTreeDestructed = -8, /// The TTreeReader has been destructed / not set.
46  kSetupMakeClassModeMismatch = -7, // readers disagree on whether TTree::SetMakeBranch() should be on
47  kSetupMissingCounterBranch = -6, /// The array cannot find its counter branch: Array[CounterBranch]
48  kSetupMissingBranch = -5, /// The specified branch cannot be found.
49  kSetupInternalError = -4, /// Some other error - hopefully the error message helps.
50  kSetupMissingDictionary = -3, /// To read this branch, we need a dictionary.
51  kSetupMismatch = -2, /// Mismatch of branch type and reader template type.
52  kSetupNotACollection = -1, /// The branch class type is not a collection.
53  kSetupMatch = 0, /// This branch has been set up, branch data type and reader template type match, reading should succeed.
54  kSetupMatchBranch = 0, /// This branch has been set up, branch data type and reader template type match, reading should succeed.
55  //kSetupMatchConversion = 1, /// This branch has been set up, the branch data type can be converted to the reader template type, reading should succeed.
56  //kSetupMatchConversionCollection = 2, /// This branch has been set up, the data type of the branch's collection elements can be converted to the reader template type, reading should succeed.
57  //kSetupMakeClass = 3, /// This branch has been set up, enabling MakeClass mode for it, reading should succeed.
58  // kSetupVoidPtr = 4,
60  kSetupMatchLeaf = 6 /// This branch (or TLeaf, really) has been set up, reading should succeed.
61  };
62  enum EReadStatus {
63  kReadSuccess = 0, // data read okay
64  kReadNothingYet, // data now yet accessed
65  kReadError // problem reading data
66  };
67 
69 
70  Bool_t IsValid() const { return fProxy && 0 == (int)fSetupStatus && 0 == (int)fReadStatus; }
72  virtual EReadStatus GetReadStatus() const { return fReadStatus; }
73 
74  /// If we are reading a leaf, return the corresponding TLeaf.
75  TLeaf* GetLeaf() { return fLeaf; }
76 
77  void* GetAddress();
78 
79  const char* GetBranchName() const { return fBranchName; }
80 
81  virtual ~TTreeReaderValueBase();
82 
83  protected:
84  TTreeReaderValueBase(TTreeReader* reader, const char* branchname, TDictionary* dict);
87 
89  void NotifyNewTree(TTree* newTree);
90 
91  TBranch* SearchBranchWithCompositeName(TLeaf *&myleaf, TDictionary *&branchActualType, std::string &err);
92  virtual void CreateProxy();
93  const char* GetBranchDataType(TBranch* branch,
94  TDictionary* &dict) const;
95 
96  virtual const char* GetDerivedTypeName() const = 0;
97 
98  Detail::TBranchProxy* GetProxy() const { return fProxy; }
99 
101 
102  /// Stringify the template argument.
103  static std::string GetElementTypeName(const std::type_info& ti);
104 
105  int fHaveLeaf : 1; // Whether the data is in a leaf
106  int fHaveStaticClassOffsets : 1; // Whether !fStaticClassOffsets.empty()
107  EReadStatus fReadStatus : 2; // read status of this data access
108  ESetupStatus fSetupStatus = kSetupNotSetup; // setup status of this data access
109  TString fBranchName; // name of the branch to read data from.
111  TTreeReader* fTreeReader; // tree reader we belong to
112  TDictionary* fDict; // type that the branch should contain
113  Detail::TBranchProxy* fProxy = nullptr; // proxy for this branch, owned by TTreeReader
114  TLeaf* fLeaf = nullptr;
115  std::vector<Long64_t> fStaticClassOffsets;
116 
117  // FIXME: re-introduce once we have ClassDefInline!
118  //ClassDef(TTreeReaderValueBase, 0);//Base class for accessors to data via TTreeReader
119 
120  friend class ::TTreeReader;
121  };
122 
123 } // namespace Internal
124 } // namespace ROOT
125 
126 
127 template <typename T>
129 public:
131  TTreeReaderValue() = delete;
132  TTreeReaderValue(TTreeReader& tr, const char* branchname):
133  TTreeReaderValueBase(&tr, branchname,
134  TDictionary::GetDictionary(typeid(NonConstT_t))) {}
135 
136  /// Return a pointer to the value of the current entry.
137  /// Return a nullptr and print an error if no entry has been loaded yet.
138  /// The returned address is guaranteed to stay constant while a given TTree is being read from a given file,
139  /// unless the branch addresses are manipulated directly (e.g. through TTree::SetBranchAddress()).
140  /// The address might also change when the underlying TTree/TFile is switched, e.g. when a TChain switches files.
141  T* Get() {
142  if (!fProxy){
143  Error("TTreeReaderValue::Get()", "Value reader not properly initialized, did you remember to call TTreeReader.Set(Next)Entry()?");
144  return nullptr;
145  }
146  void *address = GetAddress(); // Needed to figure out if it's a pointer
147  return fProxy->IsaPointer() ? *(T**)address : (T*)address; }
148  /// Return a pointer to the value of the current entry.
149  /// Equivalent to Get().
150  T* operator->() { return Get(); }
151  /// Return a reference to the value of the current entry.
152  /// Equivalent to dereferencing the pointer returned by Get(). Behavior is undefined if no entry has been loaded yet.
153  /// Most likely a crash will occur.
154  T& operator*() { return *Get(); }
155 
156 protected:
157  // FIXME: use IsA() instead once we have ClassDefTInline
158  /// Get the template argument as a string.
159  virtual const char* GetDerivedTypeName() const {
160  static const std::string sElementTypeName = GetElementTypeName(typeid(T));
161  return sElementTypeName.data();
162  }
163 
164  // FIXME: re-introduce once we have ClassDefTInline!
165  //ClassDefT(TTreeReaderValue, 0);//Accessor to data via TTreeReader
166 };
167 
168 #endif // ROOT_TTreeReaderValue
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:32
virtual const char * GetDerivedTypeName() const
Get the template argument as a string.
To read this branch, we need a dictionary.
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Definition: TTreeReader.h:43
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
The branch class type is not a collection.
double T(double x)
Definition: ChebyshevPol.h:34
virtual ~TTreeReaderValueBase()
Unregister from tree reader, cleanup.
Basic string class.
Definition: TString.h:131
EReadStatus ProxyRead()
Try to read the value from the TBranchProxy, returns the status of the read.
bool Bool_t
Definition: RtypesCore.h:59
TTreeReaderValue(TTreeReader &tr, const char *branchname)
std::vector< Long64_t > fStaticClassOffsets
This branch has been set up, branch data type and reader template type match, reading should succeed...
The array cannot find its counter branch: Array[CounterBranch].
Mismatch of branch type and reader template type.
T * Get()
Return a pointer to the value of the current entry.
Detail::TBranchProxy * GetProxy() const
virtual EReadStatus GetReadStatus() const
TTreeReaderValueBase & operator=(const TTreeReaderValueBase &)
Copy-assign.
Extracts data from a TTree.
typename std::remove_const< Int_t >::type NonConstT_t
This branch has been set up, branch data type and reader template type match, reading should succeed...
void RegisterWithTreeReader()
Register with tree reader.
TTreeReaderValueBase(TTreeReader *reader, const char *branchname, TDictionary *dict)
Construct a tree value reader and register it with the reader object.
T & operator*()
Return a reference to the value of the current entry.
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.
Some other error - hopefully the error message helps.
void * GetAddress()
Returns the memory address of the object being read.
A Branch for the case of an object.
static std::string GetElementTypeName(const std::type_info &ti)
Stringify the template argument.
int type
Definition: TGX11.cxx:120
TBranch * SearchBranchWithCompositeName(TLeaf *&myleaf, TDictionary *&branchActualType, std::string &err)
Search a branch the name of which contains a ".".
TLeaf * GetLeaf()
If we are reading a leaf, return the corresponding TLeaf.
The TTreeReader has been destructed / not set.
virtual const char * GetDerivedTypeName() const =0
void NotifyNewTree(TTree *newTree)
The TTreeReader has switched to a new TTree. Update the leaf.
A TTree object has a header with a name and a title.
Definition: TTree.h:70
Base class for all the proxy object.
Definition: TBranchProxy.h:66
A TTree is a list of TBranches.
Definition: TBranch.h:62
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...
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.
T * operator->()
Return a pointer to the value of the current entry.