19 #include "TClassEdit.h"
32 using namespace ROOT::Internal;
41 Error(
"TClonesReader::GetCA()",
"Read error in TBranchProxy.");
70 Error(
"TSTLReader::GetCP()",
"Read error in TBranchProxy.");
74 Error(
"TSTLReader::GetCP()",
"Logic error, proxy object not set in TBranchProxy.");
83 if (!myCollectionProxy)
return 0;
84 return myCollectionProxy->
Size();
89 if (!myCollectionProxy)
return 0;
91 return *(
void**)myCollectionProxy->
At(idx);
94 return myCollectionProxy->
At(idx);
106 if (!proxy->
Read()) {
108 Error(
"TCollectionLessSTLReader::GetCP()",
"Read error in TBranchProxy.");
112 Error(
"TCollectionLessSTLReader::GetCP()",
"Logic error, proxy object not set in TBranchProxy.");
116 return fLocalCollection;
121 if (!myCollectionProxy)
return 0;
123 return myCollectionProxy->
Size();
128 if (!myCollectionProxy)
return 0;
131 return *(
void**)myCollectionProxy->
At(idx);
133 return myCollectionProxy->
At(idx);
143 Int_t fBasicTypeSize;
145 TObjectArrayReader() : fBasicTypeSize(-1) { }
146 ~TObjectArrayReader() {}
150 Error(
"TObjectArrayReader::GetCP()",
"Read error in TBranchProxy.");
158 if (!myCollectionProxy)
return 0;
159 return myCollectionProxy->
Size();
162 if (!proxy->
Read())
return 0;
165 void *array = (
void*)proxy->
GetStart();
167 if (fBasicTypeSize == -1){
170 Error(
"TObjectArrayReader::At()",
"Cannot get class info from branch proxy.");
176 objectSize = fBasicTypeSize;
178 return (
void*)((
Byte_t*)array + (objectSize * idx));
181 void SetBasicTypeSize(
Int_t size){
182 fBasicTypeSize = size;
186 template <
class BASE>
187 class TUIntOrIntReader:
public BASE {
191 bool fIsUnsigned =
false;
200 template <
class...
ARGS>
201 TUIntOrIntReader(
TTreeReader *treeReader,
const char *leafName,
205 if (
TLeaf* sizeLeaf = treeReader->
GetTree()->FindLeaf(leafName)) {
206 fIsUnsigned = sizeLeaf->IsUnsigned();
217 return *GetSizeReader<UInt_t>();
218 return *GetSizeReader<Int_t>();
222 class TArrayParameterSizeReader:
public TUIntOrIntReader<TObjectArrayReader> {
225 TUIntOrIntReader<TObjectArrayReader>(treeReader, branchName) {}
229 class TArrayFixedSizeReader :
public TObjectArrayReader {
234 TArrayFixedSizeReader(
Int_t sizeArg) : fSize(sizeArg) {}
241 ~TBasicTypeArrayReader() {}
246 Error(
"TBasicTypeArrayReader::GetCP()",
"Read error in TBranchProxy.");
255 if (!myCollectionProxy)
return 0;
256 return myCollectionProxy->
Size();
261 if (!myCollectionProxy)
return 0;
266 class TBasicTypeClonesReader :
public TClonesReader {
270 TBasicTypeClonesReader(
Int_t offsetArg) : fOffset(offsetArg) {}
274 if (!myClonesArray)
return 0;
275 return (
Byte_t*)myClonesArray->
At(idx) + fOffset;
284 TLeafReader(
TTreeReaderValueBase *valueReaderArg) : fValueReader(valueReaderArg), fElementSize(-1) {}
287 TLeaf *myLeaf = fValueReader->GetLeaf();
288 return myLeaf ? myLeaf->
GetLen() : 0;
293 void *address = fValueReader->GetAddress();
294 if (fElementSize == -1){
295 TLeaf *myLeaf = fValueReader->GetLeaf();
296 if (!myLeaf)
return 0;
299 return (
Byte_t*)address + (fElementSize * idx);
304 fValueReader->ProxyRead();
308 class TLeafParameterSizeReader:
public TUIntOrIntReader<TLeafReader> {
310 TLeafParameterSizeReader(
TTreeReader *treeReader,
const char *leafName,
312 TUIntOrIntReader<TLeafReader>(treeReader, leafName, valueReaderArg) {}
316 return TUIntOrIntReader<TLeafReader>::GetSize(proxy);
337 fSetupStatus = kSetupInternalError;
339 Error(
"TTreeReaderArrayBase::CreateProxy()",
"TTreeReader object not set / available for branch %s!",
341 fSetupStatus = kSetupTreeDestructed;
346 const char* brDataType =
"{UNDETERMINED}";
349 brDataType = GetBranchDataType(br, dictUnused);
351 Error(
"TTreeReaderArrayBase::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.",
352 GetDerivedTypeName(), fBranchName.Data(), brDataType);
353 fSetupStatus = kSetupMissingDictionary;
364 TLeaf *myLeaf =
nullptr;
365 if (!GetBranchAndLeaf(branch, myLeaf, branchActualType))
369 Error(
"TTreeReaderArrayBase::CreateProxy()",
370 "No dictionary for branch %s.", fBranchName.Data());
377 fSetupStatus = kSetupMatch;
379 SetImpl(branch, myLeaf);
388 fSetupStatus = kSetupMatch;
390 Error(
"TTreeReaderArrayBase::CreateProxy()",
391 "Type ambiguity (want %s, have %s) for branch %s.",
398 bool isTopLevel = branch->
GetMother() == branch;
400 membername = strrchr(branch->
GetName(),
'.');
401 if (membername.IsNull()) {
402 membername = branch->
GetName();
406 fTreeReader->GetProxies()->Add(namedProxy);
409 fSetupStatus = kSetupMatch;
411 fSetupStatus = kSetupMismatch;
415 TString branchActualTypeName;
416 const char* nonCollTypeName = GetBranchContentDataType(branch, branchActualTypeName, branchActualType);
417 if (nonCollTypeName) {
418 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s, which should be accessed through a TTreeReaderValue< %s >.",
419 fBranchName.Data(), nonCollTypeName, nonCollTypeName);
420 if (fSetupStatus == kSetupInternalError)
421 fSetupStatus = kSetupNotACollection;
425 if (!branchActualType) {
426 if (branchActualTypeName.IsNull()) {
427 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"Cannot determine the type contained in the collection of branch %s. That's weird - please report!",
430 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s, which does not have a dictionary.",
431 fBranchName.Data(), branchActualTypeName.Data());
432 if (fSetupStatus == kSetupInternalError)
433 fSetupStatus = kSetupMissingDictionary;
439 if (fDict != branchActualType) {
440 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderArray<%s>",
441 fBranchName.Data(), branchActualType->
GetName(), fDict->GetName());
442 if (fSetupStatus == kSetupInternalError || fSetupStatus >= 0)
443 fSetupStatus = kSetupMismatch;
455 SetImpl(branch, myLeaf);
464 branch = fTreeReader->
GetTree()->GetBranch(fBranchName);
468 if (!fBranchName.Contains(
".")) {
469 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
470 fSetupStatus = kSetupMissingBranch;
475 TRegexp leafNameExpression (
"\\.[a-zA-Z0-9_]+$");
476 TString leafName (fBranchName(leafNameExpression));
477 TString
branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
478 branch = fTreeReader->
GetTree()->GetBranch(branchName);
480 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
481 fSetupStatus = kSetupMissingBranch;
486 myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
488 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
489 fSetupStatus = kSetupMissingBranch;
496 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"Failed to get the dictionary for %s.", myLeaf->
GetTypeName());
497 fSetupStatus = kSetupMissingDictionary;
504 branchActualType = fDict;
507 fLeafName = leafName(1, leafName.Length());
508 fSetupStatus = kSetupMatchLeaf;
511 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->
GetTypeName(), fDict->GetName());
513 fSetupStatus = kSetupMismatch;
539 fImpl =
new TLeafReader(
this);
545 fImpl =
new TLeafParameterSizeReader(fTreeReader, leafFullName.Data(),
this);
547 fSetupStatus = kSetupMatchLeaf;
561 if (fSetupStatus == kSetupInternalError)
562 fSetupStatus = kSetupMatch;
564 fImpl =
new TSTLReader();
570 fImpl =
new TClonesReader();
581 fImpl =
new TBasicTypeArrayReader();
584 fImpl =
new TBasicTypeClonesReader(element->
GetOffset());
588 ((TObjectArrayReader*)fImpl)->SetBasicTypeSize(((
TDataType*)fDict)->
Size());
593 ((TArrayParameterSizeReader*)fImpl)->SetBasicTypeSize(((
TDataType*)fDict)->
Size());
596 fImpl =
new TClonesReader();
598 Error(
"TTreeReaderArrayBase::SetImpl()",
599 "Cannot read branch %s: unhandled streamer element type %s",
600 fBranchName.Data(), element->IsA()->
GetName());
601 fSetupStatus = kSetupInternalError;
612 Error(
"TTreeReaderArrayBase::SetImpl",
"Failed to get the top leaf from the branch");
613 fSetupStatus = kSetupMissingBranch;
618 if (fSetupStatus == kSetupInternalError)
619 fSetupStatus = kSetupMatch;
621 fImpl =
new TArrayFixedSizeReader(size);
624 fImpl =
new TArrayParameterSizeReader(fTreeReader, sizeLeaf->
GetName());
626 ((TObjectArrayReader*)fImpl)->SetBasicTypeSize(((
TDataType*)fDict)->
Size());
628 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchClones not implemented");
629 fSetupStatus = kSetupInternalError;
631 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchObject not implemented");
632 fSetupStatus = kSetupInternalError;
634 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchSTL not implemented");
635 fImpl =
new TSTLReader();
636 fSetupStatus = kSetupInternalError;
638 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchRef not implemented");
639 fSetupStatus = kSetupInternalError;
654 TString& contentTypeName,
658 contentTypeName =
"";
662 || brElement->
GetType() == 3) {
667 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Could not get value class.");
676 if (brElement->
GetType() == 3) {
682 TClassEdit::TSplitType splitType(brElement->
GetClassName());
683 int isSTLCont = splitType.IsSTLCont();
685 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Cannot determine STL collection type of %s stored in branch %s", brElement->
GetClassName(), branch->
GetName());
688 bool isMap = isSTLCont == ROOT::kSTLmap
689 || isSTLCont == ROOT::kSTLmultimap;
690 if (isMap) contentTypeName =
"std::pair< ";
691 contentTypeName += splitType.fElements[1];
693 contentTypeName += splitType.fElements[2];
694 contentTypeName +=
" >";
699 }
else if (brElement->
GetType() == 31
700 || brElement->
GetType() == 41) {
705 if (ExpectedTypeRet == 0) {
711 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s contains a data type %d for which the dictionary cannot be retrieved.",
712 branch->
GetName(), (int)dtData);
717 }
else if (ExpectedTypeRet == 1) {
718 int brID = brElement->
GetID();
721 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s contains data of type %s for which the dictionary does not exist. It's needed.",
736 return "{CANNOT DETERMINE TBranchElement DATA TYPE}";
748 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get class from branch element.");
752 if (!myCollectionProxy){
753 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get collection proxy from STL class");
761 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get valueClass from collectionProxy.");
764 contentTypeName = dict->
GetName();
768 if (!fProxy->Setup() || !fProxy->Read()){
769 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Failed to get type from proxy, unable to check type");
770 contentTypeName =
"UNKNOWN";
772 return contentTypeName;
776 contentTypeName = dict->
GetName();
790 contentTypeName =
"TClonesArray";
791 Warning(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Not able to check type correctness, ignoring check");
793 fSetupStatus = kSetupNoCheck;
800 if (dict) contentTypeName = dict->
GetName();
805 contentTypeName = dict->
GetName();
816 if ((!dataTypeName || !dataTypeName[0])
829 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"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());
832 while ((leaf = (
TLeaf*) iLeaves())) {
833 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
" %s.%s", branch->
GetName(), leaf->GetName());
839 Warning(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Not able to check type correctness, ignoring check");
841 fSetupStatus = kSetupNoCheck;
847 return "TClonesArray";
850 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->
GetName());
853 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s is of type %s - something that is not handled yet.", branch->
GetName(), branch->IsA()->
GetName());
virtual Int_t GetLen() const
Return the number of effective elements of this leaf.
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.
TVirtualCollectionProxy * GetCollectionProxy()
Return the collection proxy describing the branch content, if any.
const char * GetBranchContentDataType(TBranch *branch, TString &contentTypeName, TDictionary *&dict)
Access a branch's collection content (not the collection itself) through a proxy. ...
TString GetTypeName()
Get basic type of typedef, e,g.
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
virtual Int_t GetExpectedType(TClass *&clptr, EDataType &type)
Fill expectedClass and expectedType with information on the data type of the object/values contained ...
const char * GetTypeName() const
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
virtual TClass * GetValueClass() const =0
Regular expression class.
static TDictionary * GetDictionary(const char *name)
virtual void * GetStart(UInt_t=0)
TBranch * GetBranch() const
Type GetType(const std::string &Name)
Int_t GetSplitLevel() const
virtual EDataType GetType() const =0
Int_t GetClassSize() const
const Detail::TBranchProxy * GetProxy() const
void SetContentDict(TDictionary *dict)
virtual const char * GetClonesName() const
TBranchElement * GetBranchCount() const
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
virtual TLeaf * GetLeafCounter(Int_t &countval) const
Return a pointer to the counter of this leaf.
TObject * UncheckedAt(Int_t i) const
bool GetBranchAndLeaf(TBranch *&branch, TLeaf *&myLeaf, TDictionary *&branchActualType)
Determine the branch / leaf and its type; reset fProxy / fSetupStatus on error.
virtual const char * GetTypeName() const
TObjArray * GetElements() const
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...
virtual Bool_t HasPointers() const =0
TBranch * GetMother() const
Get our top-level parent branch in the tree.
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.
The ROOT global object gROOT contains a list of all defined classes.
void Warning(const char *location, const char *msgfmt,...)
virtual TClass * GetClass() const
virtual TLeaf * GetLeafCount() const
A Branch for the case of an object.
virtual const char * GetTypeName() const
Return type name of element in the branch.
TVirtualCollectionProxy * GetCollection()
virtual Int_t GetLenType() const
TClass * GetClass() const
virtual void * At(UInt_t idx)=0
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN
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. ...
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
TClass * GetClass() const
virtual UInt_t Size() const =0
typedef void((*Func_t)())
An array of clone (identical) objects.
virtual ~TVirtualCollectionReader()
TStreamerElement * GetElement(Int_t id) const
TObject * At(Int_t idx) const
Base class for all the proxy object.
TDictionary * GetContentDict() const
A TTree is a list of TBranches.
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.
Int_t GetArrayLength() const
void SetImpl(TBranch *branch, TLeaf *myLeaf)
Create the TVirtualCollectionReader object for our branch.