Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TTreeReaderValue.h
Go to the documentation of this file.
1// @(#)root/tree:$Id$
2// Author: Axel Naumann, 2010-08-02
3// Author: Vincenzo Eduardo Padulano CERN 09/2024
4
5/*************************************************************************
6 * Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#ifndef ROOT_TTreeReaderValue
14#define ROOT_TTreeReaderValue
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#include <vector>
31#include <string>
32
33class TBranch;
34class TBranchElement;
35class TLeaf;
36class TTreeReader;
37
38namespace ROOT {
39namespace Internal {
40
41/** \class TTreeReaderValueBase
42Base class of TTreeReaderValue.
43*/
44
46public:
47 /// Status flags, 0 is good
50 -10, ///< This branch has been setup, branch data type and reader template type match, but nothing can be read
51 ///< because we have already reached the end of the tree.
52 kSetupMakeClassModeMismatch = -9, ///< readers disagree on whether TTree::SetMakeBranch() should be on
53 kSetupTreeDestructed = -8, ///< The TTreeReader has been destructed / not set.
54 kSetupNotSetup = -7, ///< No initialization has happened yet.
55 kSetupMissingCounterBranch = -6, ///< The array cannot find its counter branch: Array[CounterBranch]
56 kSetupMissingBranch = -5, ///< The specified branch cannot be found.
57 kSetupInternalError = -4, ///< Some other error - hopefully the error message helps.
58 kSetupMissingDictionary = -3, ///< To read this branch, we need a dictionary.
59 kSetupMismatch = -2, ///< Mismatch of branch type and reader template type.
60 kSetupNotACollection = -1, ///< The branch class type is not a collection.
62 0, ///< This branch has been set up, branch data type and reader template type match, reading should succeed.
63 // kSetupMatchConversion = 1, /// This branch has been set up, the branch data type can be converted to the reader
64 // template type, reading should succeed. kSetupMatchConversionCollection = 2, /// This branch has been set up,
65 // the data type of the branch's collection elements can be converted to the reader template type, reading should
66 // succeed. kSetupMakeClass = 3, /// This branch has been set up, enabling MakeClass mode for it, reading should
67 // succeed.
68 // kSetupVoidPtr = 4,
70 kSetupMatchLeaf = 6, ///< This branch (or TLeaf, really) has been set up, reading should succeed.
72 7, ///< This branch has been set up, branch data type and reader template type match, reading should succeed.
73 };
75 kReadSuccess = 0, ///< Data read okay
76 kReadNothingYet, ///< Data now yet accessed
77 kReadError ///< Problem reading data
78 };
79
80 EReadStatus ProxyRead() { return (this->*fProxyReadFunc)(); }
81
82 EReadStatus ProxyReadDefaultImpl();
83
85 template <BranchProxyRead_t Func>
87
88 /// Return true if the branch was setup \em and \em read correctly.
89 /// Use GetSetupStatus() to only check the setup status.
90 bool IsValid() const { return fProxy && 0 == (int)fSetupStatus && 0 == (int)fReadStatus; }
91 /// Return this TTreeReaderValue's setup status.
92 /// Use this method to check e.g. whether the TTreeReaderValue is correctly setup and ready for reading.
94 virtual EReadStatus GetReadStatus() const { return fReadStatus; }
95
96 /// If we are reading a leaf, return the corresponding TLeaf.
97 TLeaf *GetLeaf() { return fLeaf; }
98
99 void *GetAddress();
100
101 const char *GetBranchName() const { return fBranchName; }
102
103 virtual ~TTreeReaderValueBase();
104
105protected:
106 TTreeReaderValueBase(TTreeReader *reader, const char *branchname, TDictionary *dict, bool opaqueRead = false);
109
112
114 virtual void CreateProxy();
115 static const char *GetBranchDataType(TBranch *branch, TDictionary *&dict, TDictionary const *curDict);
116
117 virtual const char *GetDerivedTypeName() const = 0;
118
120
126
127 /// Stringify the template argument.
128 static std::string GetElementTypeName(const std::type_info &ti);
129
131
132 bool fHaveLeaf : 1; ///< Whether the data is in a leaf
133 bool fHaveStaticClassOffsets : 1; ///< Whether !fStaticClassOffsets.empty()
134 EReadStatus fReadStatus : 2; ///< Read status of this data access
135 ESetupStatus fSetupStatus = kSetupNotSetup; ///< Setup status of this data access
136 TString fBranchName; ///< Name of the branch to read data from.
138 TTreeReader *fTreeReader; ///< Tree reader we belong to
139 TDictionary *fDict; ///< Type that the branch should contain
140 Detail::TBranchProxy *fProxy = nullptr; ///< Proxy for this branch, owned by TTreeReader
141 TLeaf *fLeaf = nullptr;
142 std::vector<Long64_t> fStaticClassOffsets;
144 Read_t fProxyReadFunc = &TTreeReaderValueBase::ProxyReadDefaultImpl; ///<! Pointer to the Read implementation to use.
145 /**
146 * If true, the reader will not do any type-checking against the actual
147 * type held by the branch. Useful to just check if the current entry can
148 * be read or not without caring about its value.
149 * \note Only used by TTreeReaderOpaqueValue.
150 */
151 bool fOpaqueRead{false};
152
153 // FIXME: re-introduce once we have ClassDefInline!
154 // ClassDefOverride(TTreeReaderValueBase, 0);//Base class for accessors to data via TTreeReader
155
156 friend class ::TTreeReader;
157};
158
159/**
160 * \brief Read a value in a branch without knowledge of its type
161 *
162 * This class is helpful in situations where the actual contents of the branch
163 * at the current entry are not relevant and one only wants to know whether
164 * the entry can be read.
165 */
167public:
169 : TTreeReaderValueBase(&tr, branchname, /*dict*/ nullptr, /*opaqueRead*/ true)
170 {
171 }
172
173protected:
174 const char *GetDerivedTypeName() const { return ""; }
175};
176
178 std::string fElementTypeName;
179
180public:
181 TTreeReaderUntypedValue(TTreeReader &tr, std::string_view branchName, std::string_view typeName)
182 : TTreeReaderValueBase(&tr, branchName.data(), TDictionary::GetDictionary(typeName.data())),
183 fElementTypeName(typeName)
184 {
185 }
186
187 void *Get()
188 {
189 if (!fProxy) {
190 ErrorAboutMissingProxyIfNeeded();
191 return nullptr;
192 }
193 void *address = GetAddress(); // Needed to figure out if it's a pointer
194 return fProxy->IsaPointer() ? *(void **)address : (void *)address;
195 }
196
197protected:
198 const char *GetDerivedTypeName() const final { return fElementTypeName.c_str(); }
199};
200
201} // namespace Internal
202} // namespace ROOT
203
204template <typename T>
206 // R__CLING_PTRCHECK is disabled because pointer / types are checked by CreateProxy().
207
208public:
209 using NonConstT_t = typename std::remove_const<T>::type;
212 : TTreeReaderValueBase(&tr, branchname, TDictionary::GetDictionary(typeid(NonConstT_t)))
213 {
214 }
215
216 /// Return a pointer to the value of the current entry.
217 /// Return a nullptr and print an error if no entry has been loaded yet.
218 /// The returned address is guaranteed to stay constant while a given TTree is being read from a given file,
219 /// unless the branch addresses are manipulated directly (e.g. through TTree::SetBranchAddress()).
220 /// The address might also change when the underlying TTree/TFile is switched, e.g. when a TChain switches files.
221 T *Get()
222 {
223 if (!fProxy) {
224 ErrorAboutMissingProxyIfNeeded();
225 return nullptr;
226 }
227 void *address = GetAddress(); // Needed to figure out if it's a pointer
228 return fProxy->IsaPointer() ? *(T **)address : (T *)address;
229 }
230
231 /// Return a pointer to the value of the current entry.
232 /// Equivalent to Get().
233 T *operator->() { return Get(); }
234
235 /// Return a reference to the value of the current entry.
236 /// Equivalent to dereferencing the pointer returned by Get(). Behavior is undefined if no entry has been loaded yet.
237 /// Most likely a crash will occur.
238 T &operator*() { return *Get(); }
239
240protected:
241 // FIXME: use IsA() instead once we have ClassDefTInline
242 /// Get the template argument as a string.
243 const char *GetDerivedTypeName() const override
244 {
245 static const std::string sElementTypeName = GetElementTypeName(typeid(T));
246 return sElementTypeName.data();
247 }
248
249 // FIXME: re-introduce once we have ClassDefTInline!
250 // ClassDefT(TTreeReaderValue, 0);//Accessor to data via TTreeReader
251};
252
253namespace cling {
254std::string printValue(ROOT::Internal::TTreeReaderValueBase *val);
255template <typename T>
256std::string printValue(TTreeReaderValue<T> *val)
257{
258 return printValue(static_cast<ROOT::Internal::TTreeReaderValueBase *>(val));
259}
260} // namespace cling
261
262#endif // ROOT_TTreeReaderValue
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Base class for all the proxy object.
Read a value in a branch without knowledge of its type.
TTreeReaderOpaqueValue(TTreeReader &tr, const char *branchname)
const char * GetDerivedTypeName() const final
TTreeReaderUntypedValue(TTreeReader &tr, std::string_view branchName, std::string_view typeName)
Base class of TTreeReaderValue.
void RegisterWithTreeReader()
Register with tree reader.
@ 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
@ kSetupMatchButEntryBeyondEnd
This branch has been setup, branch data type and reader template type match, but nothing can be read ...
@ 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.
ESetupStatus GetSetupStatus() const
Return this TTreeReaderValue's setup status.
Read_t fProxyReadFunc
! Pointer to the Read implementation to use.
bool fOpaqueRead
If true, the reader will not do any type-checking against the actual type held by the branch.
EReadStatus(TTreeReaderValueBase::* Read_t)()
void NotifyNewTree(TTree *newTree)
The TTreeReader has switched to a new TTree. Update the leaf.
bool fHaveLeaf
Whether the data is in a leaf.
Detail::TBranchProxy * GetProxy() const
bool fHaveStaticClassOffsets
Whether !fStaticClassOffsets.empty()
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.
bool IsValid() const
Return true if the branch was setup and read correctly.
virtual const char * GetDerivedTypeName() const =0
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.
TLeaf * GetLeaf()
If we are reading a leaf, return the corresponding TLeaf.
virtual ~TTreeReaderValueBase()
Unregister from tree reader, cleanup.
TTreeReaderValueBase(TTreeReader *reader, const char *branchname, TDictionary *dict, bool opaqueRead=false)
Construct a tree value reader and register it with the reader object.
bool(ROOT::Detail::TBranchProxy::* BranchProxyRead_t)()
virtual void CreateProxy()
Create the proxy object for our branch.
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:93
This class defines an abstract interface that must be implemented by all classes that contain diction...
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition TLeaf.h:57
Basic string class.
Definition TString.h:139
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.
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
const char * GetDerivedTypeName() const override
Get the template argument as a string.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition TTreeReader.h:46
A TTree represents a columnar dataset.
Definition TTree.h:84
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...