34 ROOT::Internal::TVirtualCollectionReader::~TVirtualCollectionReader() {}
37 using namespace ROOT::Internal;
40 class TClonesReader:
public TVirtualCollectionReader {
43 TClonesArray* GetCA(ROOT::Detail::TBranchProxy* proxy) {
45 fReadStatus = TTreeReaderValueBase::kReadError;
46 Error(
"TClonesReader::GetCA()",
"Read error in TBranchProxy.");
49 fReadStatus = TTreeReaderValueBase::kReadSuccess;
50 return (TClonesArray*) proxy->GetWhere();
52 virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
53 TClonesArray *myClonesArray = GetCA(proxy);
55 return myClonesArray->GetEntries();
59 virtual void* At(ROOT::Detail::TBranchProxy* proxy,
size_t idx) {
60 TClonesArray *myClonesArray = GetCA(proxy);
62 return myClonesArray->UncheckedAt(idx);
69 class TSTLReader final:
public TVirtualCollectionReader {
72 TVirtualCollectionProxy* GetCP(ROOT::Detail::TBranchProxy* proxy) {
74 fReadStatus = TTreeReaderValueBase::kReadError;
75 Error(
"TSTLReader::GetCP()",
"Read error in TBranchProxy.");
78 if (!proxy->GetWhere()) {
79 Error(
"TSTLReader::GetCP()",
"Logic error, proxy object not set in TBranchProxy.");
82 fReadStatus = TTreeReaderValueBase::kReadSuccess;
83 return (TVirtualCollectionProxy*) proxy->GetCollection();
86 virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
87 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
88 if (!myCollectionProxy)
return 0;
89 return myCollectionProxy->Size();
92 virtual void* At(ROOT::Detail::TBranchProxy* proxy,
size_t idx) {
93 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
94 if (!myCollectionProxy)
return 0;
95 if (myCollectionProxy->HasPointers()){
96 return *(
void**)myCollectionProxy->At(idx);
99 return myCollectionProxy->At(idx);
104 class TCollectionLessSTLReader final:
public TVirtualCollectionReader {
106 TVirtualCollectionProxy *fLocalCollection;
108 TCollectionLessSTLReader(TVirtualCollectionProxy *proxy) : fLocalCollection(proxy) {}
110 TVirtualCollectionProxy* GetCP(ROOT::Detail::TBranchProxy* proxy) {
111 if (!proxy->Read()) {
112 fReadStatus = TTreeReaderValueBase::kReadError;
113 Error(
"TCollectionLessSTLReader::GetCP()",
"Read error in TBranchProxy.");
116 if (!proxy->GetWhere()) {
117 Error(
"TCollectionLessSTLReader::GetCP()",
"Logic error, proxy object not set in TBranchProxy.");
120 fReadStatus = TTreeReaderValueBase::kReadSuccess;
121 return fLocalCollection;
124 virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
125 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
126 if (!myCollectionProxy)
return 0;
129 myCollectionProxy->PopProxy();
130 myCollectionProxy->PushProxy(proxy->GetWhere());
131 return myCollectionProxy->Size();
134 virtual void* At(ROOT::Detail::TBranchProxy* proxy,
size_t idx) {
135 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
136 if (!myCollectionProxy)
return 0;
140 myCollectionProxy->PopProxy();
141 myCollectionProxy->PushProxy(proxy->GetWhere());
142 if (myCollectionProxy->HasPointers()){
143 return *(
void**)myCollectionProxy->At(idx);
145 return myCollectionProxy->At(idx);
153 class TObjectArrayReader:
public TVirtualCollectionReader {
155 Int_t fBasicTypeSize;
157 TObjectArrayReader() : fBasicTypeSize(-1) { }
158 ~TObjectArrayReader() {}
159 TVirtualCollectionProxy* GetCP(ROOT::Detail::TBranchProxy* proxy) {
161 fReadStatus = TTreeReaderValueBase::kReadError;
162 Error(
"TObjectArrayReader::GetCP()",
"Read error in TBranchProxy.");
165 fReadStatus = TTreeReaderValueBase::kReadSuccess;
166 return (TVirtualCollectionProxy*) proxy->GetCollection();
168 virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
169 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
170 if (!myCollectionProxy)
return 0;
171 return myCollectionProxy->Size();
173 virtual void* At(ROOT::Detail::TBranchProxy* proxy,
size_t idx) {
174 if (!proxy->Read())
return 0;
177 void *array = (
void*)proxy->GetStart();
179 if (fBasicTypeSize == -1){
180 TClass *myClass = proxy->GetClass();
182 Error(
"TObjectArrayReader::At()",
"Cannot get class info from branch proxy.");
185 objectSize = myClass->GetClassSize();
188 objectSize = fBasicTypeSize;
190 return (
void*)((Byte_t*)array + (objectSize * idx));
193 void SetBasicTypeSize(Int_t size){
194 fBasicTypeSize = size;
198 template <
class BASE>
199 class TUIntOrIntReader:
public BASE {
202 std::unique_ptr<TTreeReaderValueBase> fSizeReader;
203 bool fIsUnsigned =
false;
207 TTreeReaderValue<T>& GetSizeReader() {
208 return *
static_cast<TTreeReaderValue<T>*
>(fSizeReader.get());
212 template <
class... ARGS>
213 TUIntOrIntReader(TTreeReader *treeReader,
const char *leafName,
215 BASE(std::forward<ARGS>(args)...)
217 if (TLeaf* sizeLeaf = treeReader->GetTree()->FindLeaf(leafName)) {
218 fIsUnsigned = sizeLeaf->IsUnsigned();
220 fSizeReader.reset(
new TTreeReaderValue<UInt_t>(*treeReader, leafName));
222 fSizeReader.reset(
new TTreeReaderValue<Int_t>(*treeReader, leafName));
227 size_t GetSize(ROOT::Detail::TBranchProxy* )
override {
229 return *GetSizeReader<UInt_t>();
230 return *GetSizeReader<Int_t>();
234 class TArrayParameterSizeReader:
public TUIntOrIntReader<TObjectArrayReader> {
236 TArrayParameterSizeReader(TTreeReader *treeReader,
const char *branchName):
237 TUIntOrIntReader<TObjectArrayReader>(treeReader, branchName) {}
241 class TArrayFixedSizeReader :
public TObjectArrayReader {
246 TArrayFixedSizeReader(Int_t sizeArg) : fSize(sizeArg) {}
248 virtual size_t GetSize(ROOT::Detail::TBranchProxy* ) {
return fSize; }
251 class TBasicTypeArrayReader final:
public TVirtualCollectionReader {
253 ~TBasicTypeArrayReader() {}
255 TVirtualCollectionProxy* GetCP (ROOT::Detail::TBranchProxy *proxy) {
257 fReadStatus = TTreeReaderValueBase::kReadError;
258 Error(
"TBasicTypeArrayReader::GetCP()",
"Read error in TBranchProxy.");
261 fReadStatus = TTreeReaderValueBase::kReadSuccess;
262 return (TVirtualCollectionProxy*) proxy->GetCollection();
265 virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy){
266 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
267 if (!myCollectionProxy)
return 0;
268 return myCollectionProxy->Size();
271 virtual void* At(ROOT::Detail::TBranchProxy* proxy,
size_t idx){
272 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
273 if (!myCollectionProxy)
return 0;
274 return (Byte_t*)myCollectionProxy->At(idx) + proxy->GetOffset();
278 class TBasicTypeClonesReader final:
public TClonesReader {
282 TBasicTypeClonesReader(Int_t offsetArg) : fOffset(offsetArg) {}
284 virtual void* At(ROOT::Detail::TBranchProxy* proxy,
size_t idx){
285 TClonesArray *myClonesArray = GetCA(proxy);
286 if (!myClonesArray)
return 0;
287 return (Byte_t*)myClonesArray->At(idx) + fOffset;
291 class TLeafReader :
public TVirtualCollectionReader {
293 TTreeReaderValueBase *fValueReader;
296 TLeafReader(TTreeReaderValueBase *valueReaderArg) : fValueReader(valueReaderArg), fElementSize(-1) {}
298 virtual size_t GetSize(ROOT::Detail::TBranchProxy* ){
299 TLeaf *myLeaf = fValueReader->GetLeaf();
300 return myLeaf ? myLeaf->GetLen() : 0;
303 virtual void* At(ROOT::Detail::TBranchProxy* ,
size_t idx){
305 void *address = fValueReader->GetAddress();
306 if (fElementSize == -1){
307 TLeaf *myLeaf = fValueReader->GetLeaf();
308 if (!myLeaf)
return 0;
309 fElementSize = myLeaf->GetLenType();
311 return (Byte_t*)address + (fElementSize * idx);
316 fValueReader->ProxyRead();
320 class TLeafParameterSizeReader:
public TUIntOrIntReader<TLeafReader> {
322 TLeafParameterSizeReader(TTreeReader *treeReader,
const char *leafName,
323 TTreeReaderValueBase *valueReaderArg) :
324 TUIntOrIntReader<TLeafReader>(treeReader, leafName, valueReaderArg) {}
326 size_t GetSize(ROOT::Detail::TBranchProxy* proxy)
override {
328 return TUIntOrIntReader<TLeafReader>::GetSize(proxy);
335 ClassImp(TTreeReaderArrayBase);
340 void ROOT::Internal::TTreeReaderArrayBase::CreateProxy()
346 fSetupStatus = kSetupInternalError;
348 Error(
"TTreeReaderArrayBase::CreateProxy()",
"TTreeReader object not set / available for branch %s!",
350 fSetupStatus = kSetupTreeDestructed;
354 TBranch* br = fTreeReader->GetTree()->GetBranch(fBranchName);
355 const char* brDataType =
"{UNDETERMINED}";
357 TDictionary* dictUnused = 0;
358 brDataType = GetBranchDataType(br, dictUnused, fDict);
360 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.",
361 GetDerivedTypeName(), fBranchName.Data(), brDataType);
362 fSetupStatus = kSetupMissingDictionary;
371 TDictionary* branchActualType = 0;
372 TBranch* branch =
nullptr;
373 TLeaf *myLeaf =
nullptr;
374 if (!GetBranchAndLeaf(branch, myLeaf, branchActualType))
378 Error(
"TTreeReaderArrayBase::CreateProxy()",
379 "No dictionary for branch %s.", fBranchName.Data());
383 TNamedBranchProxy* namedProxy = fTreeReader->FindProxy(fBranchName);
385 if (namedProxy->GetContentDict() == fDict) {
386 fSetupStatus = kSetupMatch;
387 fProxy = namedProxy->GetProxy();
388 SetImpl(branch, myLeaf);
393 if (!namedProxy->GetContentDict()) {
394 namedProxy->SetContentDict(fDict);
395 fProxy = namedProxy->GetProxy();
397 fSetupStatus = kSetupMatch;
399 Error(
"TTreeReaderArrayBase::CreateProxy()",
400 "Type ambiguity (want %s, have %s) for branch %s.",
401 fDict->GetName(), namedProxy->GetContentDict()->GetName(), fBranchName.Data());
407 bool isTopLevel = branch->GetMother() == branch;
409 membername = strrchr(branch->GetName(),
'.');
410 if (membername.IsNull()) {
411 membername = branch->GetName();
414 auto director = fTreeReader->fDirector;
416 if (branch->GetTree() != fTreeReader->GetTree()->GetTree()) {
420 for(
auto fe : TRangeDynCast<TFriendElement>( fTreeReader->GetTree()->GetTree()->GetListOfFriends())) {
421 if (branch->GetTree() == fe->GetTree()) {
427 Error(
"TTreeReaderArrayBase::CreateProxy()",
"The branch %s is contained in a Friend TTree that is not directly attached to the main.\n"
428 "This is not yet supported by TTreeReader.",
432 TFriendProxy *feproxy =
nullptr;
433 if ((
size_t)index < fTreeReader->fFriendProxies.size()) {
434 feproxy = fTreeReader->fFriendProxies.at(index);
437 feproxy =
new ROOT::Internal::TFriendProxy(director, fTreeReader->GetTree(), index);
438 fTreeReader->fFriendProxies.resize(index+1);
439 fTreeReader->fFriendProxies.at(index) = feproxy;
441 director = feproxy->GetDirector();
443 namedProxy =
new TNamedBranchProxy(director, branch, fBranchName, membername);
444 fTreeReader->AddProxy(namedProxy);
445 fProxy = namedProxy->GetProxy();
447 fSetupStatus = kSetupMatch;
449 fSetupStatus = kSetupMismatch;
453 TString branchActualTypeName;
454 const char* nonCollTypeName = GetBranchContentDataType(branch, branchActualTypeName, branchActualType);
455 if (nonCollTypeName) {
456 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s, which should be accessed through a TTreeReaderValue< %s >.",
457 fBranchName.Data(), nonCollTypeName, nonCollTypeName);
458 if (fSetupStatus == kSetupInternalError)
459 fSetupStatus = kSetupNotACollection;
463 if (!branchActualType) {
464 if (branchActualTypeName.IsNull()) {
465 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"Cannot determine the type contained in the collection of branch %s. That's weird - please report!",
468 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s, which does not have a dictionary.",
469 fBranchName.Data(), branchActualTypeName.Data());
470 if (fSetupStatus == kSetupInternalError)
471 fSetupStatus = kSetupMissingDictionary;
477 if (fDict != branchActualType) {
478 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderArray<%s>",
479 fBranchName.Data(), branchActualType->GetName(), fDict->GetName());
480 if (fSetupStatus == kSetupInternalError || fSetupStatus >= 0)
481 fSetupStatus = kSetupMismatch;
484 if (!namedProxy->GetContentDict()) {
485 namedProxy->SetContentDict(fDict);
493 SetImpl(branch, myLeaf);
499 bool ROOT::Internal::TTreeReaderArrayBase::GetBranchAndLeaf(TBranch* &branch, TLeaf* &myLeaf,
500 TDictionary* &branchActualType) {
502 branch = fTreeReader->GetTree()->GetBranch(fBranchName);
506 if (!fBranchName.Contains(
".")) {
507 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
508 fSetupStatus = kSetupMissingBranch;
513 TRegexp leafNameExpression (
"\\.[a-zA-Z0-9_]+$");
514 TString leafName (fBranchName(leafNameExpression));
515 TString branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
516 branch = fTreeReader->GetTree()->GetBranch(branchName);
518 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
519 fSetupStatus = kSetupMissingBranch;
524 myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
526 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());
527 fSetupStatus = kSetupMissingBranch;
532 TDictionary *tempDict = TDictionary::GetDictionary(myLeaf->GetTypeName());
534 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"Failed to get the dictionary for %s.", myLeaf->GetTypeName());
535 fSetupStatus = kSetupMissingDictionary;
540 if (tempDict->IsA() == TDataType::Class() && TDictionary::GetDictionary(((TDataType*)tempDict)->GetTypeName()) == fDict){
542 branchActualType = fDict;
544 fBranchName = branchName;
545 fLeafName = leafName(1, leafName.Length());
546 fHaveLeaf = (fLeafName.Length() > 0);
547 fSetupStatus = kSetupMatchLeaf;
550 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->GetTypeName(), fDict->GetName());
552 fSetupStatus = kSetupMismatch;
564 void ROOT::Internal::TTreeReaderArrayBase::SetImpl(TBranch* branch, TLeaf* myLeaf)
577 if (!myLeaf->GetLeafCount()){
578 fImpl = std::make_unique<TLeafReader>(
this);
581 TString leafFullName = myLeaf->GetBranch()->GetName();
583 leafFullName += myLeaf->GetLeafCount()->GetName();
584 fImpl = std::make_unique<TLeafParameterSizeReader>(fTreeReader, leafFullName.Data(),
this);
586 fSetupStatus = kSetupMatchLeaf;
588 else if (branch->IsA() == TBranchElement::Class()) {
589 TBranchElement* branchElement = ((TBranchElement*)branch);
591 TStreamerInfo *streamerInfo = branchElement->GetInfo();
592 Int_t
id = branchElement->GetID();
596 TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(
id);
600 if (fSetupStatus == kSetupInternalError)
601 fSetupStatus = kSetupMatch;
602 if (element->IsA() == TStreamerSTL::Class()){
603 fImpl = std::make_unique<TSTLReader>();
605 else if (element->IsA() == TStreamerObject::Class()){
608 if (element->GetClass() == TClonesArray::Class()){
609 fImpl = std::make_unique<TClonesReader>();
611 else if (branchElement->GetType() == TBranchElement::kSTLMemberNode){
612 fImpl = std::make_unique<TBasicTypeArrayReader>();
614 else if (branchElement->GetType() == TBranchElement::kClonesMemberNode){
616 fImpl = std::make_unique<TBasicTypeClonesReader>(element->GetOffset());
619 fImpl = std::make_unique<TArrayFixedSizeReader>(element->GetArrayLength());
622 else if (element->IsA() == TStreamerLoop::Class()) {
623 fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, branchElement->GetBranchCount()->GetName());
625 else if (element->IsA() == TStreamerBasicType::Class()){
626 if (branchElement->GetType() == TBranchElement::kSTLMemberNode){
627 fImpl = std::make_unique<TBasicTypeArrayReader>();
629 else if (branchElement->GetType() == TBranchElement::kClonesMemberNode){
630 fImpl = std::make_unique<TBasicTypeClonesReader>(element->GetOffset());
633 fImpl = std::make_unique<TArrayFixedSizeReader>(element->GetArrayLength());
634 ((TObjectArrayReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
637 else if (element->IsA() == TStreamerBasicPointer::Class()) {
638 fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, branchElement->GetBranchCount()->GetName());
639 ((TArrayParameterSizeReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
641 else if (element->IsA() == TStreamerBase::Class()){
642 fImpl = std::make_unique<TClonesReader>();
644 Error(
"TTreeReaderArrayBase::SetImpl()",
645 "Cannot read branch %s: unhandled streamer element type %s",
646 fBranchName.Data(), element->IsA()->GetName());
647 fSetupStatus = kSetupInternalError;
651 if (branchElement->GetClass()->GetCollectionProxy()){
652 fImpl = std::make_unique<TCollectionLessSTLReader>(branchElement->GetClass()->GetCollectionProxy());
655 }
else if (branch->IsA() == TBranch::Class()) {
656 auto topLeaf = branch->GetLeaf(branch->GetName());
658 Error(
"TTreeReaderArrayBase::SetImpl",
"Failed to get the top leaf from the branch");
659 fSetupStatus = kSetupMissingBranch;
663 auto sizeLeaf = topLeaf->GetLeafCount();
664 if (fSetupStatus == kSetupInternalError)
665 fSetupStatus = kSetupMatch;
667 fImpl = std::make_unique<TArrayFixedSizeReader>(topLeaf->GetLenStatic());
670 fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, sizeLeaf->GetName());
672 ((TObjectArrayReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
673 }
else if (branch->IsA() == TBranchClones::Class()) {
674 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchClones not implemented");
675 fSetupStatus = kSetupInternalError;
676 }
else if (branch->IsA() == TBranchObject::Class()) {
677 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchObject not implemented");
678 fSetupStatus = kSetupInternalError;
679 }
else if (branch->IsA() == TBranchSTL::Class()) {
680 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchSTL not implemented");
681 fImpl = std::make_unique<TSTLReader>();
682 fSetupStatus = kSetupInternalError;
683 }
else if (branch->IsA() == TBranchRef::Class()) {
684 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchRef not implemented");
685 fSetupStatus = kSetupInternalError;
699 const char* ROOT::Internal::TTreeReaderArrayBase::GetBranchContentDataType(TBranch* branch,
700 TString& contentTypeName,
704 contentTypeName =
"";
705 if (branch->IsA() == TBranchElement::Class()) {
706 TBranchElement* brElement = (TBranchElement*)branch;
707 if (brElement->GetType() == 4
708 || brElement->GetType() == 3) {
709 TVirtualCollectionProxy* collProxy = brElement->GetCollectionProxy();
711 TClass *myClass = collProxy->GetValueClass();
713 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Could not get value class.");
716 dict = TDictionary::GetDictionary(myClass->GetName());
717 if (!dict) dict = TDataType::GetDataType(collProxy->GetType());
722 if (brElement->GetType() == 3) {
723 contentTypeName = brElement->GetClonesName();
724 dict = TDictionary::GetDictionary(brElement->GetClonesName());
728 TClassEdit::TSplitType splitType(brElement->GetClassName());
729 int isSTLCont = splitType.IsSTLCont();
731 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Cannot determine STL collection type of %s stored in branch %s", brElement->GetClassName(), branch->GetName());
732 return brElement->GetClassName();
734 bool isMap = isSTLCont == ROOT::kSTLmap
735 || isSTLCont == ROOT::kSTLmultimap;
736 if (isMap) contentTypeName =
"std::pair< ";
737 contentTypeName += splitType.fElements[1];
739 contentTypeName += splitType.fElements[2];
740 contentTypeName +=
" >";
745 }
else if (brElement->GetType() == 31
746 || brElement->GetType() == 41) {
749 EDataType dtData = kOther_t;
750 int ExpectedTypeRet = brElement->GetExpectedType(clData, dtData);
751 if (ExpectedTypeRet == 0) {
754 dict = TDataType::GetDataType(dtData);
757 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s contains a data type %d for which the dictionary cannot be retrieved.",
758 branch->GetName(), (int)dtData);
759 contentTypeName = TDataType::GetTypeName(dtData);
763 }
else if (ExpectedTypeRet == 1) {
764 int brID = brElement->GetID();
767 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s contains data of type %s for which the dictionary does not exist. It's needed.",
768 branch->GetName(), brElement->GetClassName());
769 contentTypeName = brElement->GetClassName();
774 TStreamerElement* element =
775 (TStreamerElement*) brElement->GetInfo()->GetElement(brID);
776 contentTypeName = element->GetTypeName();
782 return "{CANNOT DETERMINE TBranchElement DATA TYPE}";
784 else if (brElement->GetType() == TBranchElement::kLeafNode){
785 TStreamerInfo *streamerInfo = brElement->GetInfo();
786 Int_t
id = brElement->GetID();
789 TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(
id);
791 if (element->IsA() == TStreamerSTL::Class()){
792 TClass *myClass = brElement->GetCurrentClass();
794 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get class from branch element.");
797 TVirtualCollectionProxy *myCollectionProxy = myClass->GetCollectionProxy();
798 if (!myCollectionProxy){
799 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get collection proxy from STL class");
803 dict = myCollectionProxy->GetValueClass();
805 if (!dict) dict = TDataType::GetDataType(myCollectionProxy->GetType());
807 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get valueClass from collectionProxy.");
810 contentTypeName = dict->GetName();
813 else if (element->IsA() == TStreamerObject::Class() && !strcmp(element->GetTypeName(),
"TClonesArray")){
814 if (!fProxy->Setup() || !fProxy->Read()){
815 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Failed to get type from proxy, unable to check type");
816 contentTypeName =
"UNKNOWN";
818 return contentTypeName;
820 TClonesArray *myArray = (TClonesArray*)fProxy->GetWhere();
821 dict = myArray->GetClass();
822 contentTypeName = dict->GetName();
826 dict = brElement->GetCurrentClass();
828 TDictionary *myDataType = TDictionary::GetDictionary(brElement->GetTypeName());
829 dict = TDataType::GetDataType((EDataType)((TDataType*)myDataType)->GetType());
831 contentTypeName = brElement->GetTypeName();
835 if (brElement->GetCurrentClass() == TClonesArray::Class()){
836 contentTypeName =
"TClonesArray";
837 Warning(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Not able to check type correctness, ignoring check");
839 fSetupStatus = kSetupNoCheck;
841 else if (!dict && (branch->GetSplitLevel() == 0 || brElement->GetClass()->GetCollectionProxy())){
843 dict = brElement->GetClass()->GetCollectionProxy()->GetValueClass();
845 if (!dict) dict = TDataType::GetDataType(brElement->GetClass()->GetCollectionProxy()->GetType());
846 if (dict) contentTypeName = dict->GetName();
850 dict = brElement->GetClass();
851 contentTypeName = dict->GetName();
858 }
else if (branch->IsA() == TBranch::Class()
859 || branch->IsA() == TBranchObject::Class()
860 || branch->IsA() == TBranchSTL::Class()) {
861 const char* dataTypeName = branch->GetClassName();
862 if ((!dataTypeName || !dataTypeName[0])
863 && branch->IsA() == TBranch::Class()) {
864 auto myLeaf = branch->GetLeaf(branch->GetName());
866 auto myDataType = TDictionary::GetDictionary(myLeaf->GetTypeName());
867 if (myDataType && myDataType->IsA() == TDataType::Class()){
868 auto typeEnumConstant = EDataType(((TDataType*)myDataType)->GetType());
871 if (typeEnumConstant == kDouble32_t) typeEnumConstant = kDouble_t;
872 else if (typeEnumConstant == kFloat16_t) typeEnumConstant = kFloat_t;
873 dict = TDataType::GetDataType(typeEnumConstant);
874 contentTypeName = myLeaf->GetTypeName();
880 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());
881 TIter iLeaves(branch->GetListOfLeaves());
883 while ((leaf = (TLeaf*) iLeaves())) {
884 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
" %s.%s", branch->GetName(), leaf->GetName());
888 if (dataTypeName) dict = TDictionary::GetDictionary(dataTypeName);
889 if (branch->IsA() == TBranchSTL::Class()){
890 Warning(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Not able to check type correctness, ignoring check");
892 fSetupStatus = kSetupNoCheck;
896 }
else if (branch->IsA() == TBranchClones::Class()) {
897 dict = TClonesArray::Class();
898 return "TClonesArray";
899 }
else if (branch->IsA() == TBranchRef::Class()) {
901 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->GetName());
904 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s is of type %s - something that is not handled yet.", branch->GetName(), branch->IsA()->GetName());