60 fHaveStaticClassOffsets(false),
61 fReadStatus(kReadNothingYet),
62 fBranchName(branchname),
65 fOpaqueRead(opaqueRead)
74 fHaveLeaf(rhs.fHaveLeaf),
75 fHaveStaticClassOffsets(rhs.fHaveStaticClassOffsets),
76 fReadStatus(rhs.fReadStatus),
77 fSetupStatus(rhs.fSetupStatus),
78 fBranchName(rhs.fBranchName),
79 fLeafName(rhs.fLeafName),
80 fTreeReader(rhs.fTreeReader),
84 fStaticClassOffsets(rhs.fStaticClassOffsets)
101 fTreeReader->DeregisterValueReader(
this);
103 RegisterWithTreeReader();
120 if (fTreeReader) fTreeReader->DeregisterValueReader(
this);
121 R__ASSERT((fLeafName.Length() == 0 ) == !fHaveLeaf
122 &&
"leafness disagreement");
123 R__ASSERT(fStaticClassOffsets.empty() == !fHaveStaticClassOffsets
124 &&
"static class offset disagreement");
132 if (!fTreeReader->RegisterValueReader(
this)) {
133 fTreeReader =
nullptr;
144template <ROOT::Internal::TTreeReaderValueBase::BranchProxyRead_t Func>
147 if ((fProxy->*Func)()) {
148 fReadStatus = kReadSuccess;
150 fReadStatus = kReadError;
157 if (!fProxy)
return kReadNothingYet;
158 if (fProxy->IsInitialized() || fProxy->Setup()) {
163 EReadType readtype = EReadType::kNoDirector;
167 case EReadType::kNoDirector:
168 fProxyReadFunc = &TTreeReaderValueBase::ProxyReadTemplate<&TBranchPoxy::ReadNoDirector>;
170 case EReadType::kReadParentNoCollection:
171 fProxyReadFunc = &TTreeReaderValueBase::ProxyReadTemplate<&TBranchPoxy::ReadParentNoCollection>;
173 case EReadType::kReadParentCollectionNoPointer:
174 fProxyReadFunc = &TTreeReaderValueBase::ProxyReadTemplate<&TBranchPoxy::ReadParentCollectionNoPointer>;
176 case EReadType::kReadParentCollectionPointer:
177 fProxyReadFunc = &TTreeReaderValueBase::ProxyReadTemplate<&TBranchPoxy::ReadParentCollectionPointer>;
179 case EReadType::kReadNoParentNoBranchCountCollectionPointer:
180 fProxyReadFunc = &TTreeReaderValueBase::ProxyReadTemplate<&TBranchPoxy::ReadNoParentNoBranchCountCollectionPointer>;
182 case EReadType::kReadNoParentNoBranchCountCollectionNoPointer:
183 fProxyReadFunc = &TTreeReaderValueBase::ProxyReadTemplate<&TBranchPoxy::ReadNoParentNoBranchCountCollectionNoPointer>;
185 case EReadType::kReadNoParentNoBranchCountNoCollection:
186 fProxyReadFunc = &TTreeReaderValueBase::ProxyReadTemplate<&TBranchPoxy::ReadNoParentNoBranchCountNoCollection>;
188 case EReadType::kReadNoParentBranchCountCollectionPointer:
189 fProxyReadFunc = &TTreeReaderValueBase::ProxyReadTemplate<&TBranchPoxy::ReadNoParentBranchCountCollectionPointer>;
191 case EReadType::kReadNoParentBranchCountCollectionNoPointer:
192 fProxyReadFunc = &TTreeReaderValueBase::ProxyReadTemplate<&TBranchPoxy::ReadNoParentBranchCountCollectionNoPointer>;
194 case EReadType::kReadNoParentBranchCountNoCollection:
195 fProxyReadFunc = &TTreeReaderValueBase::ProxyReadTemplate<&TBranchPoxy::ReadNoParentBranchCountNoCollection>;
197 case EReadType::kDefault:
201 return (this->*fProxyReadFunc)();
207 if (fProxy->Read()) {
208 fReadStatus = kReadSuccess;
210 fReadStatus = kReadError;
220 std::string ret = buf;
233 if (!fHaveLeaf || !newTree) {
241 fReadStatus = kReadError;
242 Error(
"TTreeReaderValueBase::GetLeaf()",
"Unable to get the branch from the tree");
246 fLeaf = myBranch->
GetLeaf(fLeafName);
248 Error(
"TTreeReaderValueBase::GetLeaf()",
"Failed to get the leaf from the branch");
261 fProxy->fDirector->GetReadEntry() == -1)
264 if (ProxyRead() != kReadSuccess)
return nullptr;
268 return fLeaf->GetValuePointer();
271 fReadStatus = kReadError;
272 Error(
"TTreeReaderValueBase::GetAddress()",
"Unable to get the leaf");
276 if (fHaveStaticClassOffsets){
279 for (
unsigned int i = 0; i < fStaticClassOffsets.size() - 1; ++i){
280 address = *(
Byte_t**)(address + fStaticClassOffsets[i]);
283 return address + fStaticClassOffsets.back();
285 return (
Byte_t*)fProxy->GetWhere();
305 TRegexp leafNameExpression (
"\\.[a-zA-Z0-9_]+$");
306 TString leafName (fBranchName(leafNameExpression));
307 TString branchName = fBranchName(0, fBranchName.Length() - leafName.
Length());
308 auto branch = fTreeReader->GetTree()->GetBranch(branchName);
310 std::vector<TString> nameStack;
311 nameStack.push_back(
TString());
313 leafName = branchName(leafNameExpression);
314 branchName = branchName(0, branchName.
Length() - leafName.
Length());
316 branch = fTreeReader->GetTree()->GetBranch(branchName);
317 if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName +
".");
320 while (!branch && branchName.
Contains(
".")){
321 leafName = branchName(leafNameExpression);
322 branchName = branchName(0, branchName.
Length() - leafName.
Length());
323 branch = fTreeReader->GetTree()->GetBranch(branchName);
324 if (!branch) branch = fTreeReader->GetTree()->GetBranch(branchName +
".");
331 TString traversingBranch = nameStack.back();
332 nameStack.pop_back();
338 std::vector<Long64_t> offsets;
340 TClass *elementClass =
nullptr;
345 while (!nameStack.empty() && found){
348 for (
int i = 0; i < myObjArray->
GetEntries(); ++i){
352 if (!strcmp(tempStreamerElement->
GetName(), traversingBranch.
Data())){
355 traversingBranch = nameStack.back();
356 nameStack.pop_back();
358 elementClass = tempStreamerElement->
GetClass();
366 if (!finalDataType) {
375 offsets.push_back(
offset);
385 offsets.push_back(
offset);
388 fStaticClassOffsets = offsets;
389 fHaveStaticClassOffsets =
true;
391 if (fDict != finalDataType && fDict != elementClass){
392 errMsg =
"Wrong data type ";
393 errMsg += finalDataType ? finalDataType->
GetName() : elementClass ? elementClass->
GetName() :
"UNKNOWN";
394 fSetupStatus = kSetupMismatch;
402 if (!fHaveStaticClassOffsets) {
403 errMsg =
"The tree does not have a branch called ";
404 errMsg += fBranchName;
405 errMsg +=
". You could check with TTree::Print() for available branches.";
406 fSetupStatus = kSetupMissingBranch;
412 myLeaf = branch->GetLeaf(
TString(leafName(1, leafName.
Length())));
414 errMsg =
"The tree does not have a branch, nor a sub-branch called ";
415 errMsg += fBranchName;
416 errMsg +=
". You could check with TTree::Print() for available branches.";
417 fSetupStatus = kSetupMissingBranch;
425 branchActualType = fDict;
427 fBranchName = branchName;
428 fLeafName = leafName(1, leafName.
Length());
429 fHaveLeaf = fLeafName.Length() > 0;
430 fSetupStatus = kSetupMatchLeaf;
433 errMsg =
"Leaf of type ";
435 errMsg +=
" cannot be read by TTreeReaderValue<";
438 fSetupStatus = kSetupMismatch;
452 constexpr const char* errPrefix =
"TTreeReaderValueBase::CreateProxy()";
458 fSetupStatus = kSetupInternalError;
460 Error(errPrefix,
"TTreeReader object not set / available for branch %s!",
462 fSetupStatus = kSetupTreeDestructed;
466 auto branchFromFullName = fTreeReader->GetTree()->GetBranch(fBranchName);
467 if (branchFromFullName ==
nullptr)
468 branchFromFullName = fTreeReader->GetTree()->FindBranch(fBranchName);
472 const char *brDataType =
"{UNDETERMINED}";
473 if (branchFromFullName) {
475 brDataType = GetBranchDataType(branchFromFullName, brDictUnused, fDict);
478 "The template argument type T of %s accessing branch %s (which contains data of type %s) is not known "
479 "to ROOT. You will need to create a dictionary for it.",
480 GetDerivedTypeName(), fBranchName.Data(), brDataType);
481 fSetupStatus = kSetupMissingDictionary;
486 if (branchFromFullName) {
487 GetBranchDataType(branchFromFullName, fDict,
nullptr);
496 if (namedProxy && namedProxy->
GetDict() == fDict) {
501 const std::string originalBranchName = fBranchName.Data();
503 TLeaf *myLeaf =
nullptr;
514 if (fBranchName.Contains(
".")) {
515 branch = SearchBranchWithCompositeName(myLeaf, branchActualType, errMsg);
524 branch = branchFromFullName;
525 fStaticClassOffsets = {};
526 fHaveStaticClassOffsets =
false;
538 const auto &suppressErrorsForMissingBranches = fTreeReader->fSuppressErrorsForMissingBranches;
539 const bool suppressErrorsForThisBranch =
540 (std::find(suppressErrorsForMissingBranches.cbegin(), suppressErrorsForMissingBranches.cend(),
541 originalBranchName) != suppressErrorsForMissingBranches.cend());
546 branch = branchFromFullName;
550 fSetupStatus = kSetupMissingBranch;
552 if (suppressErrorsForThisBranch)
558 if (errMsg.empty()) {
559 errMsg =
"The tree does not have a branch called ";
560 errMsg += fBranchName.Data();
561 errMsg +=
". You could check with TTree::Print() for available branches.";
563#if !defined(_MSC_VER)
564#pragma GCC diagnostic push
565#pragma GCC diagnostic ignored "-Wformat-security"
567 Error(errPrefix, errMsg.c_str());
568#if !defined(_MSC_VER)
569#pragma GCC diagnostic pop
575 fSetupStatus = kSetupInternalError;
576 fStaticClassOffsets = {};
577 fHaveStaticClassOffsets =
false;
580 if (!myLeaf && !fHaveStaticClassOffsets) {
583 const char* branchActualTypeName = GetBranchDataType(branch, branchActualType, fDict);
584 if (!branchActualType) {
585 Error(errPrefix,
"The branch %s contains data of type %s, which does not have a dictionary.",
586 fBranchName.Data(), branchActualTypeName ? branchActualTypeName :
"{UNDETERMINED TYPE}");
593 auto dictAsClass =
dynamic_cast<TClass*
>(fDict);
594 auto branchActualTypeAsClass =
dynamic_cast<TClass*
>(branchActualType);
595 auto inheritance = dictAsClass && branchActualTypeAsClass && branchActualTypeAsClass->
InheritsFrom(dictAsClass);
596 bool typeinfoMatch = dictAsClass && dictAsClass->GetTypeInfo() && dictAsClass->GetTypeInfo() == branchActualTypeAsClass->GetTypeInfo();
598 if (!inheritance && !typeinfoMatch && fDict != branchActualType) {
601 TEnum *dictenum =
dynamic_cast<TEnum*
>(fDict);
602 TEnum *actualenum =
dynamic_cast<TEnum*
>(branchActualType);
603 bool complainAboutMismatch =
true;
604 if (dictdt && actualdt) {
607 complainAboutMismatch =
false;
612 complainAboutMismatch =
false;
614 }
else if ( (dictdt || dictenum) && (actualdt || actualenum) ) {
617 complainAboutMismatch =
false;
619 if (complainAboutMismatch) {
621 "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderValue<%s>",
622 fBranchName.Data(), branchActualType->
GetName(),
637 bool isTopLevel = branch->
GetMother() == branch;
639 membername = strrchr(branch->
GetName(),
'.');
640 if (membername.
IsNull()) {
641 membername = branch->
GetName();
644 auto director = fTreeReader->fDirector.get();
648 std::optional<std::size_t>
index;
649 std::size_t current{};
650 auto &&friends = fTreeReader->GetTree()->GetTree()->GetListOfFriends();
658 if (!
index.has_value()) {
660 "The branch %s is contained in a Friend TTree that is not directly attached to the main.\n"
661 "This is not yet supported by TTreeReader.",
665 auto &&friendProxy = fTreeReader->AddFriendProxy(
index.value());
666 fTreeReader->AddProxy(std::make_unique<TNamedBranchProxy>(friendProxy.GetDirector(), branch,
667 originalBranchName.c_str(), branch->
GetName(),
668 membername, suppressErrorsForThisBranch));
670 fTreeReader->AddProxy(std::make_unique<TNamedBranchProxy>(director, branch, originalBranchName.c_str(),
671 membername, suppressErrorsForThisBranch));
673 namedProxy = fTreeReader->FindProxy(originalBranchName.c_str());
682 fSetupStatus = kSetupMatch;
684 fSetupStatus = kSetupMismatch;
701 auto ResolveTypedef = [&]() ->
void {
708 if (dict != curDict) {
711 if (dict != curDict) {
749 return "TClonesArray";
750 }
else if (brElement->
GetType() == 31
751 || brElement->
GetType() == 41) {
753 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"Must use TTreeReaderArray to access a member of an object that is stored in a collection.");
759 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"Unknown type and class combination: %i, %s", brElement->
GetType(), brElement->
GetClassName());
770 if ((!dataTypeName || !dataTypeName[0])
783 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"Must use TTreeReaderArray to read branch %s: it contains an array or a collection.", branch->
GetName());
792 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());
794 TLeaf* leaf =
nullptr;
795 while ((leaf = (
TLeaf*) iLeaves())) {
796 Error(
"TTreeReaderValueBase::GetBranchDataType()",
" %s.%s", branch->
GetName(), leaf->
GetName());
804 return "TClonesArray";
807 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->
GetName());
810 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"The branch %s is of type %s - something that is not handled yet.", branch->
GetName(), branch->
IsA()->
GetName());
821 if (std::find(fTreeReader->fMissingProxies.cbegin(), fTreeReader->fMissingProxies.cend(), fBranchName.Data()) ==
822 fTreeReader->fMissingProxies.cend())
823 Error(
"TTreeReaderValue::Get()",
"Value reader not properly initialized, did you call "
824 "TTreeReader::Set(Next)Entry() or TTreeReader::Next()?");
836 std::string str = cl->GetName();
837 str +=
" instance associated to column ";
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Base class for all the proxy object.
void SetDict(TDictionary *dict)
const Detail::TBranchProxy * GetProxy() const
TDictionary * GetDict() const
Base class of TTreeReaderValue.
void RegisterWithTreeReader()
Register with tree reader.
void NotifyNewTree(TTree *newTree)
The TTreeReader has switched to a new TTree. Update the leaf.
bool fHaveLeaf
Whether the data is in a leaf.
bool fHaveStaticClassOffsets
Whether !fStaticClassOffsets.empty()
void * GetAddress()
Returns the memory address of the object being read.
static std::string GetElementTypeName(const std::type_info &ti)
Stringify the template argument.
ESetupStatus fSetupStatus
Setup status of this data access.
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.
const char * GetBranchName() const
void ErrorAboutMissingProxyIfNeeded()
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.
EReadStatus ProxyReadDefaultImpl()
virtual void CreateProxy()
Create the proxy object for our branch.
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.
const char * GetClassName() const override
Return the name of the user class whose content is stored in this branch, if any.
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
TClass * GetCurrentClass()
Return a pointer to the current type of the data member corresponding to branch element.
virtual const char * GetTypeName() const
Return type name of element in the branch.
A TTree is a list of TBranches.
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any.
TClass * IsA() const override
virtual TLeaf * FindLeaf(const char *name)
Find the leaf corresponding to the name 'searchname'.
TObjArray * GetListOfLeaves()
TBranch * GetMother() const
Get our top-level parent branch in the tree.
TClass instances represent classes, structs and namespaces in the ROOT type system.
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0, Bool_t isTransient=kFALSE) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist,...
Bool_t InheritsFrom(const char *cl) const override
Return kTRUE if this class inherits from a class with name "classname".
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.
Basic data type descriptor (datatype information is obtained from CINT).
static TDataType * GetDataType(EDataType type)
Given a EDataType type, get the TDataType* that represents it.
TClass * IsA() const override
This class defines an abstract interface that must be implemented by all classes that contain diction...
TClass * IsA() const override
static TDictionary * GetDictionary(const char *name)
Retrieve the type (class, fundamental type, typedef etc) named "name".
The TEnum class implements the enum type.
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
virtual const char * GetTypeName() const
virtual TLeaf * GetLeafCount() const
If this leaf stores a variable-sized array or a multi-dimensional array whose last dimension has vari...
virtual Int_t GetLenStatic() const
Return the fixed length of this leaf.
const char * GetName() const override
Returns name of object.
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
TObject * UncheckedAt(Int_t i) const
Regular expression class.
virtual Bool_t IsaPointer() const
const char * GetTypeName() const
TClass * GetClass() const
TClass * IsA() const override
Describes a persistent version of a class.
TObjArray * GetElements() const override
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
const char * Data() const
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
@ kIndexedFriendNoMatch
A friend with TTreeIndex doesn't have an entry for this index.
A TTree represents a columnar dataset.
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
virtual TTree * GetTree() const
TClass * IsA() const override
Abstract Interface class describing Streamer information for one class.
virtual TObjArray * GetElements() const =0
virtual Int_t GetElementOffset(Int_t id) const =0
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.