Logo ROOT  
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// TTreeReaderValue //
18// //
19// A simple interface for reading data from trees or chains. //
20// //
21// //
22////////////////////////////////////////////////////////////////////////////
23
24#include "TString.h"
25#include "TDictionary.h"
26#include "TBranchProxy.h"
27
28#include <type_traits>
29#include <vector>
30#include <string>
31
32class TBranch;
33class TBranchElement;
34class TLeaf;
35class TTreeReader;
36
37namespace ROOT {
38namespace Internal {
39
40/** \class TTreeReaderValueBase
41Base class of TTreeReaderValue.
42*/
43
45 public:
46
47 /// Status flags, 0 is good
49 kSetupNotSetup = -7, ///< No initialization has happened yet.
50 kSetupTreeDestructed = -8, ///< The TTreeReader has been destructed / not set.
51 kSetupMakeClassModeMismatch = -9, ///< readers disagree on whether TTree::SetMakeBranch() should be on
52 kSetupMissingCounterBranch = -6, ///< The array cannot find its counter branch: Array[CounterBranch]
53 kSetupMissingBranch = -5, ///< The specified branch cannot be found.
54 kSetupInternalError = -4, ///< Some other error - hopefully the error message helps.
55 kSetupMissingDictionary = -3, ///< To read this branch, we need a dictionary.
56 kSetupMismatch = -2, ///< Mismatch of branch type and reader template type.
57 kSetupNotACollection = -1, ///< The branch class type is not a collection.
58 kSetupMatch = 0, ///< This branch has been set up, branch data type and reader template type match, reading should succeed.
59 kSetupMatchBranch = 7, ///< This branch has been set up, branch data type and reader template type match, reading should succeed.
60 //kSetupMatchConversion = 1, /// This branch has been set up, the branch data type can be converted to the reader template type, reading should succeed.
61 //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.
62 //kSetupMakeClass = 3, /// This branch has been set up, enabling MakeClass mode for it, reading should succeed.
63 // kSetupVoidPtr = 4,
65 kSetupMatchLeaf = 6 ///< This branch (or TLeaf, really) has been set up, reading should succeed.
66 };
68 kReadSuccess = 0, ///< Data read okay
69 kReadNothingYet, ///< Data now yet accessed
70 kReadError ///< Problem reading data
71 };
72
73 EReadStatus ProxyRead() { return (this->*fProxyReadFunc)(); }
74
76
78 template <BranchProxyRead_t Func>
80
81 /// Return true if the branch was setup \em and \em read correctly.
82 /// Use GetSetupStatus() to only check the setup status.
83 Bool_t IsValid() const { return fProxy && 0 == (int)fSetupStatus && 0 == (int)fReadStatus; }
84 /// Return this TTreeReaderValue's setup status.
85 /// Use this method to check e.g. whether the TTreeReaderValue is correctly setup and ready for reading.
87 virtual EReadStatus GetReadStatus() const { return fReadStatus; }
88
89 /// If we are reading a leaf, return the corresponding TLeaf.
90 TLeaf* GetLeaf() { return fLeaf; }
91
92 void* GetAddress();
93
94 const char* GetBranchName() const { return fBranchName; }
95
96 virtual ~TTreeReaderValueBase();
97
98 protected:
99 TTreeReaderValueBase(TTreeReader* reader, const char* branchname, TDictionary* dict);
102
104 void NotifyNewTree(TTree* newTree);
105
106 TBranch* SearchBranchWithCompositeName(TLeaf *&myleaf, TDictionary *&branchActualType, std::string &err);
107 virtual void CreateProxy();
108 static const char* GetBranchDataType(TBranch* branch,
109 TDictionary* &dict,
110 TDictionary const *curDict);
111
112 virtual const char* GetDerivedTypeName() const = 0;
113
115
117
118 /// Stringify the template argument.
119 static std::string GetElementTypeName(const std::type_info& ti);
120
121 int fHaveLeaf : 1; ///< Whether the data is in a leaf
122 int fHaveStaticClassOffsets : 1; ///< Whether !fStaticClassOffsets.empty()
123 EReadStatus fReadStatus : 2; ///< Read status of this data access
124 ESetupStatus fSetupStatus = kSetupNotSetup; ///< Setup status of this data access
125 TString fBranchName; ///< Name of the branch to read data from.
127 TTreeReader* fTreeReader; ///< Tree reader we belong to
128 TDictionary* fDict; ///< Type that the branch should contain
129 Detail::TBranchProxy* fProxy = nullptr; ///< Proxy for this branch, owned by TTreeReader
130 TLeaf* fLeaf = nullptr;
131 std::vector<Long64_t> fStaticClassOffsets;
133 Read_t fProxyReadFunc = &TTreeReaderValueBase::ProxyReadDefaultImpl; ///<! Pointer to the Read implementation to use.
134
135 // FIXME: re-introduce once we have ClassDefInline!
136 //ClassDef(TTreeReaderValueBase, 0);//Base class for accessors to data via TTreeReader
137
138 friend class ::TTreeReader;
139 };
140
141} // namespace Internal
142} // namespace ROOT
143
144
145template <typename T>
146class R__CLING_PTRCHECK(off) TTreeReaderValue final: public ROOT::Internal::TTreeReaderValueBase {
147// R__CLING_PTRCHECK is disabled because pointer / types are checked by CreateProxy().
148
149public:
152 TTreeReaderValue(TTreeReader& tr, const char* branchname):
153 TTreeReaderValueBase(&tr, branchname,
154 TDictionary::GetDictionary(typeid(NonConstT_t))) {}
155
156 /// Return a pointer to the value of the current entry.
157 /// Return a nullptr and print an error if no entry has been loaded yet.
158 /// The returned address is guaranteed to stay constant while a given TTree is being read from a given file,
159 /// unless the branch addresses are manipulated directly (e.g. through TTree::SetBranchAddress()).
160 /// The address might also change when the underlying TTree/TFile is switched, e.g. when a TChain switches files.
162 {
163 if (!fProxy) {
164 Error("TTreeReaderValue::Get()", "Value reader not properly initialized, did you call "
165 "TTreeReader::Set(Next)Entry() or TTreeReader::Next()?");
166 return nullptr;
167 }
168 void *address = GetAddress(); // Needed to figure out if it's a pointer
169 return fProxy->IsaPointer() ? *(T **)address : (T *)address;
170 }
171
172 /// Return a pointer to the value of the current entry.
173 /// Equivalent to Get().
174 T* operator->() { return Get(); }
175
176 /// Return a reference to the value of the current entry.
177 /// Equivalent to dereferencing the pointer returned by Get(). Behavior is undefined if no entry has been loaded yet.
178 /// Most likely a crash will occur.
179 T& operator*() { return *Get(); }
180
181protected:
182 // FIXME: use IsA() instead once we have ClassDefTInline
183 /// Get the template argument as a string.
184 virtual const char* GetDerivedTypeName() const {
185 static const std::string sElementTypeName = GetElementTypeName(typeid(T));
186 return sElementTypeName.data();
187 }
188
189 // FIXME: re-introduce once we have ClassDefTInline!
190 //ClassDefT(TTreeReaderValue, 0);//Accessor to data via TTreeReader
191};
192
193#endif // ROOT_TTreeReaderValue
bool Bool_t
Definition: RtypesCore.h:63
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition: TError.cxx:187
int type
Definition: TGX11.cxx:121
Base class for all the proxy object.
Definition: TBranchProxy.h:69
Base class of TTreeReaderValue.
void RegisterWithTreeReader()
Register with tree reader.
ESetupStatus
Status flags, 0 is good.
@ kSetupMatchBranch
This branch has been set up, branch data type and reader template type match, reading should succeed.
@ kSetupInternalError
Some other error - hopefully the error message helps.
@ kSetupMissingBranch
The specified branch cannot be found.
@ kSetupNotSetup
No initialization has happened yet.
@ kSetupMakeClassModeMismatch
readers disagree on whether TTree::SetMakeBranch() should be on
@ kSetupNotACollection
The branch class type is not a collection.
@ kSetupMissingDictionary
To read this branch, we need a dictionary.
@ kSetupMissingCounterBranch
The array cannot find its counter branch: Array[CounterBranch].
@ kSetupMismatch
Mismatch of branch type and reader template type.
@ kSetupTreeDestructed
The TTreeReader has been destructed / not set.
@ kSetupMatchLeaf
This branch (or TLeaf, really) has been set up, reading should succeed.
@ kSetupMatch
This branch has been set up, branch data type and reader template type match, reading should succeed.
Bool_t IsValid() const
Return true if the branch was setup and read correctly.
ESetupStatus GetSetupStatus() const
Return this TTreeReaderValue's setup status.
Read_t fProxyReadFunc
! Pointer to the Read implementation to use.
EReadStatus(TTreeReaderValueBase::* Read_t)()
void NotifyNewTree(TTree *newTree)
The TTreeReader has switched to a new TTree. Update the leaf.
Detail::TBranchProxy * GetProxy() const
void * GetAddress()
Returns the memory address of the object being read.
@ kReadNothingYet
Data now yet accessed.
static std::string GetElementTypeName(const std::type_info &ti)
Stringify the template argument.
ESetupStatus fSetupStatus
Setup status of this data access.
virtual const char * GetDerivedTypeName() const =0
TTreeReaderValueBase(TTreeReader *reader, const char *branchname, TDictionary *dict)
Construct a tree value reader and register it with the reader object.
Bool_t(ROOT::Detail::TBranchProxy::* BranchProxyRead_t)()
TString fBranchName
Name of the branch to read data from.
ROOT::Internal::TTreeReaderValueBase::EReadStatus ProxyReadTemplate()
Try to read the value from the TBranchProxy, returns the status of the read.
TTreeReader * fTreeReader
Tree reader we belong to.
TDictionary * fDict
Type that the branch should contain.
TTreeReaderValueBase & operator=(const TTreeReaderValueBase &)
Copy-assign.
EReadStatus fReadStatus
Read status of this data access.
int fHaveLeaf
Whether the data is in a leaf.
TLeaf * GetLeaf()
If we are reading a leaf, return the corresponding TLeaf.
virtual ~TTreeReaderValueBase()
Unregister from tree reader, cleanup.
virtual void CreateProxy()
Create the proxy object for our branch.
int fHaveStaticClassOffsets
Whether !fStaticClassOffsets.empty()
virtual EReadStatus GetReadStatus() const
Detail::TBranchProxy * fProxy
Proxy for this branch, owned by TTreeReader.
std::vector< Long64_t > fStaticClassOffsets
TBranch * SearchBranchWithCompositeName(TLeaf *&myleaf, TDictionary *&branchActualType, std::string &err)
Search a branch the name of which contains a ".".
static const char * GetBranchDataType(TBranch *branch, TDictionary *&dict, TDictionary const *curDict)
Retrieve the type of data stored by branch; put its dictionary into dict, return its type name.
A Branch for the case of an object.
A TTree is a list of TBranches.
Definition: TBranch.h:89
This class defines an abstract interface that must be implemented by all classes that contain diction...
Definition: TDictionary.h:167
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:57
Basic string class.
Definition: TString.h:136
An interface for reading values stored in ROOT columnar datasets.
T * operator->()
Return a pointer to the value of the current entry.
TTreeReaderValue()=delete
T * Get()
Return a pointer to the value of the current entry.
virtual const char * GetDerivedTypeName() const
Get the template argument as a string.
TTreeReaderValue(TTreeReader &tr, const char *branchname)
T & operator*()
Return a reference to the value of the current entry.
typename std::remove_const< T >::type NonConstT_t
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition: TTreeReader.h:44
A TTree represents a columnar dataset.
Definition: TTree.h:79
double T(double x)
Definition: ChebyshevPol.h:34
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...