39 ROOT::Internal::TTreeReaderValueBase::TTreeReaderValueBase(
TTreeReader* reader ,
40 const
char* branchname ,
42 fBranchName(branchname),
48 fSetupStatus(kSetupNotSetup),
49 fReadStatus(kReadNothingYet)
51 if (fTreeReader) fTreeReader->RegisterValueReader(
this);
68 if (!fProxy)
return kReadNothingYet;
70 fReadStatus = kReadSuccess;
72 fReadStatus = kReadError;
81 if (fLeafName.Length() > 0){
83 Long64_t newChainOffset = fTreeReader->GetTree()->GetChainOffset();
85 if (newChainOffset != fTreeLastOffset){
86 fTreeLastOffset = newChainOffset;
91 fReadStatus = kReadError;
92 Error(
"TTreeReaderValueBase::GetLeaf()",
"Unable to get the tree from the TTreeReader");
99 fReadStatus = kReadError;
100 Error(
"TTreeReaderValueBase::GetLeaf()",
"Unable to get the branch from the tree");
104 fLeaf = myBranch->
GetLeaf(fLeafName);
106 Error(
"TTreeReaderValueBase::GetLeaf()",
"Failed to get the leaf from the branch");
112 Error(
"TTreeReaderValueBase::GetLeaf()",
"We are not reading a leaf");
121 if (ProxyRead() != kReadSuccess)
return 0;
123 if (fLeafName.Length() > 0){
125 return fLeaf->GetValuePointer();
128 fReadStatus = kReadError;
129 Error(
"TTreeReaderValueBase::GetAddress()",
"Unable to get the leaf");
133 if (!fStaticClassOffsets.empty()){
136 for (
unsigned int i = 0; i < fStaticClassOffsets.size() - 1; ++i){
137 address = *(
Byte_t**)(address + fStaticClassOffsets[i]);
140 return address + fStaticClassOffsets.back();
142 return fProxy ? (
Byte_t*)fProxy->GetWhere() : 0;
153 Error(
"TTreeReaderValueBase::CreateProxy()",
"TTreeReader object not set / available for branch %s!",
159 const char* brDataType =
"{UNDETERMINED}";
162 brDataType = GetBranchDataType(br, brDictUnused);
164 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.",
165 GetDerivedTypeName(), fBranchName.Data(), brDataType);
174 if (namedProxy && namedProxy->
GetDict() == fDict) {
184 if (fBranchName.Contains(
".")){
185 TRegexp leafNameExpression (
"\\.[a-zA-Z0-9_]+$");
186 TString leafName (fBranchName(leafNameExpression));
187 TString branchName = fBranchName(0, fBranchName.Length() - leafName.
Length());
190 std::vector<TString> nameStack;
191 nameStack.push_back(
TString());
193 leafName = branchName(leafNameExpression);
194 branchName = branchName(0, branchName.
Length() - leafName.
Length());
196 branch = fTreeReader->GetTree()->GetBranch(branchName);
197 if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName +
".");
200 while (!branch && branchName.
Contains(
".")){
201 leafName = branchName(leafNameExpression);
202 branchName = branchName(0, fBranchName.Length() - leafName.
Length());
203 branch = fTreeReader->GetTree()->GetBranch(branchName);
204 if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName +
".");
211 TString traversingBranch = nameStack.back();
212 nameStack.pop_back();
218 std::vector<Long64_t> offsets;
225 while (nameStack.size() && found){
228 for (
int i = 0; i < myObjArray->
GetEntries(); ++i){
232 if (!strcmp(tempStreamerElement->
GetName(), traversingBranch.
Data())){
235 traversingBranch = nameStack.back();
236 nameStack.pop_back();
238 elementClass = tempStreamerElement->
GetClass();
246 if (!finalDataType) {
255 offsets.push_back(offset);
265 offsets.push_back(offset);
268 fStaticClassOffsets = offsets;
270 if (fDict != finalDataType && fDict != elementClass){
271 Error(
"TTreeReaderValueBase::CreateProxy",
"Wrong data type %s", finalDataType ? finalDataType->
GetName() : elementClass ? elementClass->
GetName() :
"UNKNOWN");
279 if (!fStaticClassOffsets.size()) {
280 Error(
"TTreeReaderValueBase::CreateProxy()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
286 myLeaf = branch->GetLeaf(
TString(leafName(1, leafName.
Length())));
288 Error(
"TTreeReaderValueBase::CreateProxy()",
289 "The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
297 branchActualType = fDict;
299 fBranchName = branchName;
300 fLeafName = leafName(1, leafName.
Length());
303 Error(
"TTreeReaderValueBase::CreateProxy()",
304 "Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->
GetTypeName(), fDict->GetName());
310 Error(
"TTreeReaderValueBase::CreateProxy()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
316 if (!myLeaf && !fStaticClassOffsets.size()) {
317 const char* branchActualTypeName = GetBranchDataType(branch, branchActualType);
319 if (!branchActualType) {
320 Error(
"TTreeReaderValueBase::CreateProxy()",
"The branch %s contains data of type %s, which does not have a dictionary.",
321 fBranchName.Data(), branchActualTypeName ? branchActualTypeName :
"{UNDETERMINED TYPE}");
326 if (fDict != branchActualType) {
329 if (dictdt && actualdt && dictdt->
GetType()>0
333 Error(
"TTreeReaderValueBase::CreateProxy()",
334 "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderValue<%s>",
335 fBranchName.Data(), branchActualType->
GetName(),
344 if (namedProxy && !namedProxy->
GetDict()) {
357 bool isTopLevel = branch->
GetMother() == branch;
359 membername = strrchr(branch->
GetName(),
'.');
360 if (membername.
IsNull()) {
361 membername = branch->
GetName();
365 fTreeReader->GetProxies()->Add(namedProxy);
422 return "TClonesArray";
423 }
else if (brElement->
GetType() == 31
424 || brElement->
GetType() == 41) {
426 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"Must use TTreeReaderValueArray to access a member of an object that is stored in a collection.");
429 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"Unknown type and class combination: %i, %s", brElement->
GetType(), brElement->
GetClassName());
440 if ((!dataTypeName || !dataTypeName[0])
453 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 TTreeReaderValueArray:", branch->
GetName());
456 while ((leaf = (
TLeaf*) iLeaves())) {
457 Error(
"TTreeReaderValueBase::GetBranchDataType()",
" %s.%s", branch->
GetName(), leaf->GetName());
465 return "TClonesArray";
468 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->
GetName());
471 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"The branch %s is of type %s - something that is not handled yet.", branch->
GetName(), branch->IsA()->
GetName());
Describe Streamer information for one class version.
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
static TDataType * GetDataType(EDataType type)
Given a EDataType type, get the TDataType* that represents it.
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
const char * GetTypeName() const
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
Namespace for new ROOT classes and functions.
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...
virtual ~TTreeReaderValueBase()
Unregister from tree reader, cleanup.
Regular expression class.
static TDictionary * GetDictionary(const char *name)
EReadStatus ProxyRead()
Try to read the value from the TBranchProxy, returns the status of the read.
Type GetType(const std::string &Name)
const Detail::TBranchProxy * GetProxy() const
const char * Data() const
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
ClassImp(ROOT::Internal::TTreeReaderValueBase) ROOT
Construct a tree value reader and register it with the reader object.
TLeaf * GetLeaf()
If we are reading a leaf, return the corresponding TLeaf.
virtual Bool_t IsaPointer() const
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
void SetDict(TDictionary *dict)
virtual const char * GetTypeName() const
TTreeReader * fTreeReader
TObjArray * GetElements() const
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist...
Basic data type descriptor (datatype information is obtained from CINT).
This class defines an abstract interface that must be implemented by all classes that contain diction...
TBranch * GetMother() const
Get our top-level parent branch in the tree.
virtual void CreateProxy()
Create the proxy object for our branch.
TClass * GetCurrentClass()
Return a pointer to the current type of the data member corresponding to branch element.
virtual const char * GetName() const
Returns name of object.
void * GetAddress()
Returns the memory address of the object being read.
TSubString Strip(EStripType s=kTrailing, char c= ' ') const
Return a substring of self stripped at beginning and/or end.
The ROOT global object gROOT contains a list of all defined classes.
A Branch for the case of an object.
virtual const char * GetTypeName() const
Return type name of element in the branch.
virtual TObjArray * GetElements() const =0
void DeregisterValueReader(ROOT::Internal::TTreeReaderValueBase *reader)
Remove a value reader for this tree.
virtual TTree * GetTree() const
TObjArray * GetListOfLeaves()
Int_t GetEntries() const
Return the number of objects in array (i.e.
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
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.
TClass * GetClass() const
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
A TTree object has a header with a name and a title.
TObject * At(Int_t idx) const
A TTree is a list of TBranches.
Abstract Interface class describing Streamer information for one class.
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
TDictionary * GetDict() const
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.