20 #include "TClassEdit.h"
41 const
char* branchname ,
43 fBranchName(branchname),
48 fSetupStatus(kSetupNotSetup),
49 fReadStatus(kReadNothingYet)
51 RegisterWithTreeReader();
58 fBranchName(rhs.fBranchName),
59 fLeafName(rhs.fLeafName),
60 fTreeReader(rhs.fTreeReader),
64 fSetupStatus(rhs.fSetupStatus),
65 fReadStatus(rhs.fReadStatus),
66 fStaticClassOffsets(rhs.fStaticClassOffsets)
81 fTreeReader->DeregisterValueReader(
this);
83 RegisterWithTreeReader();
100 if (fTreeReader) fTreeReader->DeregisterValueReader(
this);
108 if (!fTreeReader->RegisterValueReader(
this)) {
109 fTreeReader =
nullptr;
120 if (!fProxy)
return kReadNothingYet;
121 if (fProxy->Read()) {
122 fReadStatus = kReadSuccess;
124 fReadStatus = kReadError;
133 char* buf = TClassEdit::DemangleTypeIdName(ti, err);
134 std::string ret = buf;
143 if (fLeafName.Length() == 0)
149 fReadStatus = kReadError;
150 Error(
"TTreeReaderValueBase::GetLeaf()",
"Unable to get the branch from the tree");
154 fLeaf = myBranch->
GetLeaf(fLeafName);
156 Error(
"TTreeReaderValueBase::GetLeaf()",
"Failed to get the leaf from the branch");
164 if (ProxyRead() != kReadSuccess)
return 0;
166 if (fLeafName.Length() > 0){
168 return fLeaf->GetValuePointer();
171 fReadStatus = kReadError;
172 Error(
"TTreeReaderValueBase::GetAddress()",
"Unable to get the leaf");
176 if (!fStaticClassOffsets.empty()){
179 for (
unsigned int i = 0; i < fStaticClassOffsets.size() - 1; ++i){
180 address = *(
Byte_t**)(address + fStaticClassOffsets[i]);
183 return address + fStaticClassOffsets.back();
185 return fProxy ? (
Byte_t*)fProxy->GetWhere() : 0;
196 fSetupStatus = kSetupInternalError;
198 Error(
"TTreeReaderValueBase::CreateProxy()",
"TTreeReader object not set / available for branch %s!",
200 fSetupStatus = kSetupTreeDestructed;
205 const char* brDataType =
"{UNDETERMINED}";
208 brDataType = GetBranchDataType(br, brDictUnused);
210 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.",
211 GetDerivedTypeName(), fBranchName.Data(), brDataType);
212 fSetupStatus = kSetupMissingDictionary;
221 if (namedProxy && namedProxy->
GetDict() == fDict) {
223 fSetupStatus = kSetupMatch;
232 if (fBranchName.Contains(
".")){
233 TRegexp leafNameExpression (
"\\.[a-zA-Z0-9_]+$");
234 TString leafName (fBranchName(leafNameExpression));
238 std::vector<TString> nameStack;
239 nameStack.push_back(
TString());
244 branch = fTreeReader->GetTree()->GetBranch(branchName);
245 if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName +
".");
248 while (!branch && branchName.
Contains(
".")){
251 branch = fTreeReader->GetTree()->GetBranch(branchName);
252 if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName +
".");
259 TString traversingBranch = nameStack.back();
260 nameStack.pop_back();
266 std::vector<Long64_t> offsets;
273 while (nameStack.size() && found){
276 for (
int i = 0; i < myObjArray->
GetEntries(); ++i){
280 if (!strcmp(tempStreamerElement->
GetName(), traversingBranch.
Data())){
283 traversingBranch = nameStack.back();
284 nameStack.pop_back();
286 elementClass = tempStreamerElement->
GetClass();
294 if (!finalDataType) {
303 offsets.push_back(offset);
313 offsets.push_back(offset);
316 fStaticClassOffsets = offsets;
318 if (fDict != finalDataType && fDict != elementClass){
319 Error(
"TTreeReaderValueBase::CreateProxy",
"Wrong data type %s", finalDataType ? finalDataType->
GetName() : elementClass ? elementClass->
GetName() :
"UNKNOWN");
320 fSetupStatus = kSetupMismatch;
328 if (!fStaticClassOffsets.size()) {
329 Error(
"TTreeReaderValueBase::CreateProxy()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
330 fSetupStatus = kSetupMissingBranch;
336 myLeaf = branch->GetLeaf(
TString(leafName(1, leafName.
Length())));
338 Error(
"TTreeReaderValueBase::CreateProxy()",
339 "The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
340 fSetupStatus = kSetupMissingBranch;
348 branchActualType = fDict;
351 fLeafName = leafName(1, leafName.
Length());
352 fSetupStatus = kSetupMatchLeaf;
355 Error(
"TTreeReaderValueBase::CreateProxy()",
356 "Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->
GetTypeName(), fDict->GetName());
357 fSetupStatus = kSetupMismatch;
363 Error(
"TTreeReaderValueBase::CreateProxy()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
369 if (!myLeaf && !fStaticClassOffsets.size()) {
370 const char* branchActualTypeName = GetBranchDataType(branch, branchActualType);
372 if (!branchActualType) {
373 Error(
"TTreeReaderValueBase::CreateProxy()",
"The branch %s contains data of type %s, which does not have a dictionary.",
374 fBranchName.Data(), branchActualTypeName ? branchActualTypeName :
"{UNDETERMINED TYPE}");
379 if (fDict != branchActualType) {
382 bool complainAboutMismatch =
true;
383 if (dictdt && actualdt) {
386 complainAboutMismatch =
false;
391 complainAboutMismatch =
false;
394 if (complainAboutMismatch) {
395 Error(
"TTreeReaderValueBase::CreateProxy()",
396 "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderValue<%s>",
397 fBranchName.Data(), branchActualType->
GetName(),
406 if (namedProxy && !namedProxy->
GetDict()) {
410 fSetupStatus = kSetupMatch;
421 bool isTopLevel = branch->
GetMother() == branch;
423 membername = strrchr(branch->
GetName(),
'.');
424 if (membername.
IsNull()) {
425 membername = branch->
GetName();
429 fTreeReader->GetProxies()->Add(namedProxy);
432 fSetupStatus = kSetupMatch;
434 fSetupStatus = kSetupMismatch;
450 auto ResolveTypedef = [&]() ->
void {
498 return "TClonesArray";
499 }
else if (brElement->
GetType() == 31
500 || brElement->
GetType() == 41) {
502 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"Must use TTreeReaderArray to access a member of an object that is stored in a collection.");
508 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"Unknown type and class combination: %i, %s", brElement->
GetType(), brElement->
GetClassName());
519 if ((!dataTypeName || !dataTypeName[0])
532 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());
535 while ((leaf = (
TLeaf*) iLeaves())) {
536 Error(
"TTreeReaderValueBase::GetBranchDataType()",
" %s.%s", branch->
GetName(), leaf->GetName());
544 return "TClonesArray";
547 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->
GetName());
550 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...
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.
std::vector< Long64_t > fStaticClassOffsets
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.
virtual Bool_t IsaPointer() const
ESetupStatus fSetupStatus
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.
void SetDict(TDictionary *dict)
void RegisterWithTreeReader()
Register with tree reader.
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.
static std::string GetElementTypeName(const std::type_info &ti)
Stringify the template argument.
virtual TObjArray * GetElements() const =0
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
Detail::TBranchProxy * fProxy
TTreeReaderValueBase(TTreeReader *reader=0, const char *branchname=0, TDictionary *dict=0)
Construct a tree value reader and register it with the reader object.
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.
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.