Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TTreeReaderArray.cxx
Go to the documentation of this file.
1// @(#)root/treeplayer:$Id$
2// Author: Axel Naumann, 2011-09-28
3
4/*************************************************************************
5 * Copyright (C) 1995-2013, Rene Brun and Fons Rademakers and al. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TTreeReaderArray.h"
13
14#include "TBranchClones.h"
15#include "TBranchElement.h"
16#include "TBranchRef.h"
17#include "TBranchSTL.h"
18#include "TBranchObject.h"
20#include "TClassEdit.h"
21#include "TEnum.h"
22#include "TFriendElement.h"
23#include "TFriendProxy.h"
24#include "TLeaf.h"
25#include "TList.h"
26#include "TROOT.h"
27#include "TStreamerInfo.h"
28#include "TStreamerElement.h"
29#include "TTreeReader.h"
30#include "TGenCollectionProxy.h"
31#include "TRegexp.h"
32
33#include <memory>
34#include <optional>
35
36// pin vtable
38
39namespace {
40 using namespace ROOT::Internal;
41
42 // Reader interface for clones arrays
43 class TClonesReader: public TVirtualCollectionReader {
44 public:
45 ~TClonesReader() override {}
47 if (!proxy->Read()){
50 Error("TClonesReader::GetCA()", "Read error in TBranchProxy.");
51 return nullptr;
52 }
54 return (TClonesArray*) proxy->GetWhere();
55 }
56 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override {
57 TClonesArray *myClonesArray = GetCA(proxy);
58 if (myClonesArray){
59 return myClonesArray->GetEntries();
60 }
61 else return 0;
62 }
63 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override {
64 TClonesArray *myClonesArray = GetCA(proxy);
65 if (myClonesArray){
66 return myClonesArray->UncheckedAt(idx);
67 }
68 else return nullptr;
69 }
70 };
71
72 // Reader interface for STL
73 class TSTLReader final: public TVirtualCollectionReader {
74 public:
75 ~TSTLReader() override {}
77 if (!proxy->Read()) {
80 Error("TSTLReader::GetCP()", "Read error in TBranchProxy.");
81 return nullptr;
82 }
83 if (!proxy->GetWhere()) {
84 Error("TSTLReader::GetCP()", "Logic error, proxy object not set in TBranchProxy.");
85 return nullptr;
86 }
88 return (TVirtualCollectionProxy*) proxy->GetCollection();
89 }
90
91 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override {
92 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
93 if (!myCollectionProxy) return 0;
94 return myCollectionProxy->Size();
95 }
96
97 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override {
98 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
99 if (!myCollectionProxy) return nullptr;
100 if (myCollectionProxy->HasPointers()){
101 return *(void**)myCollectionProxy->At(idx);
102 }
103 else {
104 return myCollectionProxy->At(idx);
105 }
106 }
107 };
108
109 class TCollectionLessSTLReader final: public TVirtualCollectionReader {
110 private:
111 TVirtualCollectionProxy *fLocalCollection;
112 public:
113 TCollectionLessSTLReader(TVirtualCollectionProxy *proxy) : fLocalCollection(proxy) {}
114
116 if (!proxy->Read()) {
119 Error("TCollectionLessSTLReader::GetCP()", "Read error in TBranchProxy.");
120 return nullptr;
121 }
122 if (!proxy->GetWhere()) {
123 Error("TCollectionLessSTLReader::GetCP()", "Logic error, proxy object not set in TBranchProxy.");
124 return nullptr;
125 }
127 return fLocalCollection;
128 }
129
130 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override {
131 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
132 if (!myCollectionProxy) return 0;
133 /// In the case of std::vector<bool> `PushProxy` also creates a temporary bool variable the address of which
134 /// is returned from these calls.
135 myCollectionProxy->PopProxy();
136 myCollectionProxy->PushProxy(proxy->GetWhere());
137 return myCollectionProxy->Size();
138 }
139
140 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override {
141 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
142 if (!myCollectionProxy) return nullptr;
143 // Here we do not use a RAII but we empty the proxy to then fill it.
144 // This is done because we are returning a pointer and we need to keep
145 // alive the memory it points to.
146 myCollectionProxy->PopProxy();
147 myCollectionProxy->PushProxy(proxy->GetWhere());
148 if (myCollectionProxy->HasPointers()){
149 return *(void**)myCollectionProxy->At(idx);
150 } else {
151 return myCollectionProxy->At(idx);
152 }
153 }
154 };
155
156
157 // Reader interface for leaf list
158 // SEE TTreeProxyGenerator.cxx:1319: '//We have a top level raw type'
159 class TObjectArrayReader: public TVirtualCollectionReader {
160 private:
161 Int_t fBasicTypeSize;
162 public:
163 TObjectArrayReader() : fBasicTypeSize(-1) { }
164 ~TObjectArrayReader() override {}
166 if (!proxy->Read()){
169 Error("TObjectArrayReader::GetCP()", "Read error in TBranchProxy.");
170 return nullptr;
171 }
173 return (TVirtualCollectionProxy*) proxy->GetCollection();
174 }
175 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override {
176 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
177 if (!myCollectionProxy) return 0;
178 return myCollectionProxy->Size();
179 }
180 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override {
181 if (!proxy->Read()) return nullptr;
182
183 Int_t objectSize;
184 void *array = (void*)proxy->GetStart();
185
186 if (fBasicTypeSize == -1){
187 TClass *myClass = proxy->GetClass();
188 if (!myClass){
189 Error("TObjectArrayReader::At()", "Cannot get class info from branch proxy.");
190 return nullptr;
191 }
192 objectSize = myClass->GetClassSize();
193 }
194 else {
195 objectSize = fBasicTypeSize;
196 }
197 return (void*)((Byte_t*)array + (objectSize * idx));
198 }
199
200 void SetBasicTypeSize(Int_t size){
201 fBasicTypeSize = size;
202 }
203 };
204
205 template <class BASE>
206 class TDynamicArrayReader : public BASE {
207
208 // TVirtualSizeReaderImpl and TSizeReaderImpl type-erase the reading of the size leaf.
209 class TVirtualSizeReaderImpl {
210 public:
211 virtual ~TVirtualSizeReaderImpl() = default;
212 virtual size_t GetSize() = 0;
213 };
214
215 template <typename T>
216 class TSizeReaderImpl final : public TVirtualSizeReaderImpl {
217 TTreeReaderValue<T> fSizeReader;
218
219 public:
220 TSizeReaderImpl(TTreeReader &r, const char *leafName) : fSizeReader(r, leafName) {}
221 size_t GetSize() final { return *fSizeReader; }
222 };
223
224 std::unique_ptr<TVirtualSizeReaderImpl> fSizeReader;
225
226 public:
227 template <class... ARGS>
228 TDynamicArrayReader(TTreeReader *treeReader, const char *leafName, ARGS &&...args)
229 : BASE(std::forward<ARGS>(args)...)
230 {
231 std::string foundLeafName = leafName;
232 TLeaf* sizeLeaf = treeReader->GetTree()->FindLeaf(foundLeafName.c_str());
233
234 if (!sizeLeaf) {
235 // leafName might be "top.currentParent.N". But "N" might really be "top.N"!
236 // Strip parents until we find the leaf.
237 std::string leafNameNoParent = leafName;
238 std::string parent;
239 auto posLastDot = leafNameNoParent.rfind('.');
240 if (posLastDot != leafNameNoParent.npos) {
241 parent = leafNameNoParent.substr(0, posLastDot);
242 leafNameNoParent.erase(0, posLastDot + 1);
243 }
244
245 do {
246 if (!sizeLeaf && !parent.empty()) {
247 auto posLastDotParent = parent.rfind('.');
248 if (posLastDotParent != parent.npos)
249 parent = parent.substr(0, posLastDot);
250 else
251 parent.clear();
252 }
253
254 foundLeafName = parent;
255 if (!parent.empty())
256 foundLeafName += ".";
257 foundLeafName += leafNameNoParent;
258 sizeLeaf = treeReader->GetTree()->FindLeaf(foundLeafName.c_str());
259 } while (!sizeLeaf && !parent.empty());
260 }
261
262 if (!sizeLeaf) {
263 Error("TDynamicArrayReader ", "Cannot find leaf count for %s or any parent branch!", leafName);
264 return;
265 }
266
267 const std::string leafType = sizeLeaf->GetTypeName();
268 if (leafType == "Int_t") {
269 fSizeReader.reset(new TSizeReaderImpl<Int_t>(*treeReader, foundLeafName.c_str()));
270 } else if (leafType == "UInt_t") {
271 fSizeReader.reset(new TSizeReaderImpl<UInt_t>(*treeReader, foundLeafName.c_str()));
272 } else if (leafType == "Short_t") {
273 fSizeReader.reset(new TSizeReaderImpl<Short_t>(*treeReader, foundLeafName.c_str()));
274 } else if (leafType == "UShort_t") {
275 fSizeReader.reset(new TSizeReaderImpl<UShort_t>(*treeReader, foundLeafName.c_str()));
276 } else if (leafType == "Long_t") {
277 fSizeReader.reset(new TSizeReaderImpl<Long_t>(*treeReader, foundLeafName.c_str()));
278 } else if (leafType == "ULong_t") {
279 fSizeReader.reset(new TSizeReaderImpl<ULong_t>(*treeReader, foundLeafName.c_str()));
280 } else if (leafType == "Long64_t") {
281 fSizeReader.reset(new TSizeReaderImpl<Long64_t>(*treeReader, foundLeafName.c_str()));
282 } else if (leafType == "ULong64_t") {
283 fSizeReader.reset(new TSizeReaderImpl<ULong64_t>(*treeReader, foundLeafName.c_str()));
284 } else {
285 Error("TDynamicArrayReader ",
286 "Unsupported size type for leaf %s. Supported types are int, short int, long int, long long int and "
287 "their unsigned counterparts.",
288 leafName);
289 }
290 }
291
292 size_t GetSize(ROOT::Detail::TBranchProxy * /*proxy*/) override { return fSizeReader->GetSize(); }
293 };
294
295 class TArrayParameterSizeReader : public TDynamicArrayReader<TObjectArrayReader> {
296 public:
297 TArrayParameterSizeReader(TTreeReader *treeReader, const char *branchName)
298 : TDynamicArrayReader<TObjectArrayReader>(treeReader, branchName)
299 {
300 }
301 };
302
303 // Reader interface for fixed size arrays
304 class TArrayFixedSizeReader : public TObjectArrayReader {
305 private:
306 Int_t fSize;
307
308 public:
309 TArrayFixedSizeReader(Int_t sizeArg) : fSize(sizeArg) {}
310
311 size_t GetSize(ROOT::Detail::TBranchProxy* /*proxy*/) override { return fSize; }
312 };
313
314 class TBasicTypeArrayReader final: public TVirtualCollectionReader {
315 public:
316 ~TBasicTypeArrayReader() override {}
317
319 if (!proxy->Read()){
322 Error("TBasicTypeArrayReader::GetCP()", "Read error in TBranchProxy.");
323 return nullptr;
324 }
326 return (TVirtualCollectionProxy*) proxy->GetCollection();
327 }
328
329 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override{
330 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
331 if (!myCollectionProxy) return 0;
332 return myCollectionProxy->Size();
333 }
334
335 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override{
336 TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
337 if (!myCollectionProxy) return nullptr;
338 return (Byte_t*)myCollectionProxy->At(idx) + proxy->GetOffset();
339 }
340 };
341
342 class TBasicTypeClonesReader final: public TClonesReader {
343 private:
344 Int_t fOffset;
345 public:
346 TBasicTypeClonesReader(Int_t offsetArg) : fOffset(offsetArg) {}
347
348 void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) override{
349 TClonesArray *myClonesArray = GetCA(proxy);
350 if (!myClonesArray) return nullptr;
351 return (Byte_t*)myClonesArray->At(idx) + fOffset;
352 }
353 };
354
355 class TLeafReader : public TVirtualCollectionReader {
356 private:
357 TTreeReaderValueBase *fValueReader;
358 Int_t fElementSize;
359 public:
360 TLeafReader(TTreeReaderValueBase *valueReaderArg) : fValueReader(valueReaderArg), fElementSize(-1) {}
361
362 size_t GetSize(ROOT::Detail::TBranchProxy* /*proxy*/) override{
363 TLeaf *myLeaf = fValueReader->GetLeaf();
364 return myLeaf ? myLeaf->GetLen() : 0; // Error will be printed by GetLeaf
365 }
366
367 void* At(ROOT::Detail::TBranchProxy* /*proxy*/, size_t idx) override{
368 ProxyRead();
369 void *address = fValueReader->GetAddress();
370 if (fElementSize == -1){
371 TLeaf *myLeaf = fValueReader->GetLeaf();
372 if (!myLeaf) return nullptr; // Error will be printed by GetLeaf
373 fElementSize = myLeaf->GetLenType();
374 }
375 return (Byte_t*)address + (fElementSize * idx);
376 }
377
378 protected:
379 void ProxyRead(){
380 fValueReader->ProxyRead();
381 }
382 };
383
384 class TLeafParameterSizeReader : public TDynamicArrayReader<TLeafReader> {
385 public:
386 TLeafParameterSizeReader(TTreeReader *treeReader, const char *leafName, TTreeReaderValueBase *valueReaderArg)
387 : TDynamicArrayReader<TLeafReader>(treeReader, leafName, valueReaderArg)
388 {
389 }
390
391 size_t GetSize(ROOT::Detail::TBranchProxy* proxy) override {
392 ProxyRead();
393 return TDynamicArrayReader<TLeafReader>::GetSize(proxy);
394 }
395 };
396}
397
398
399
401
402////////////////////////////////////////////////////////////////////////////////
403/// Create the proxy object for our branch.
404
406{
407 if (fProxy) {
408 return;
409 }
410
411 fSetupStatus = kSetupInternalError; // Fallback; set to something concrete below.
412 if (!fTreeReader) {
413 Error("TTreeReaderArrayBase::CreateProxy()", "TTreeReader object not set / available for branch %s!",
414 fBranchName.Data());
415 fSetupStatus = kSetupTreeDestructed;
416 return;
417 }
418 if (!fDict) {
419 TBranch* br = fTreeReader->GetTree()->GetBranch(fBranchName);
420 const char* brDataType = "{UNDETERMINED}";
421 if (br) {
422 TDictionary* dictUnused = nullptr;
423 brDataType = GetBranchDataType(br, dictUnused, fDict);
424 }
425 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.",
426 GetDerivedTypeName(), fBranchName.Data(), brDataType);
427 fSetupStatus = kSetupMissingDictionary;
428 return;
429 }
430
431 // Access a branch's collection content (not the collection itself)
432 // through a proxy.
433 // Search for the branchname, determine what it contains, and wire the
434 // TBranchProxy representing it to us so we can access its data.
435
436 // Tell the branch proxy to suppress the errors for missing branch if this
437 // branch name is found in the list of suppressions
438 const bool suppressErrorsForThisBranch =
439 (std::find(fTreeReader->fSuppressErrorsForMissingBranches.cbegin(),
440 fTreeReader->fSuppressErrorsForMissingBranches.cend(),
441 fBranchName.Data()) != fTreeReader->fSuppressErrorsForMissingBranches.cend());
442
443 TDictionary* branchActualType = nullptr;
444 TBranch* branch = nullptr;
445 TLeaf *myLeaf = nullptr;
446 if (!GetBranchAndLeaf(branch, myLeaf, branchActualType, suppressErrorsForThisBranch))
447 return;
448
449 if (!fDict) {
450 Error("TTreeReaderArrayBase::CreateProxy()",
451 "No dictionary for branch %s.", fBranchName.Data());
452 return;
453 }
454
455 TNamedBranchProxy* namedProxy = fTreeReader->FindProxy(fBranchName);
456 if (namedProxy) {
457 if (namedProxy->GetContentDict() == fDict) {
458 fSetupStatus = kSetupMatch;
459 fProxy = namedProxy->GetProxy();
460 SetImpl(branch, myLeaf);
461 return;
462 }
463
464 // Update named proxy's dictionary
465 if (!namedProxy->GetContentDict()) {
466 namedProxy->SetContentDict(fDict);
467 fProxy = namedProxy->GetProxy();
468 if (fProxy)
469 fSetupStatus = kSetupMatch;
470 } else {
471 Error("TTreeReaderArrayBase::CreateProxy()",
472 "Type ambiguity (want %s, have %s) for branch %s.",
473 fDict->GetName(), namedProxy->GetContentDict()->GetName(), fBranchName.Data());
474 }
475 }
476 else {
477 TString membername;
478
479 bool isTopLevel = branch->GetMother() == branch;
480 if (!isTopLevel) {
481 membername = strrchr(branch->GetName(), '.');
482 if (membername.IsNull()) {
483 membername = branch->GetName();
484 }
485 }
486 auto *director = fTreeReader->fDirector.get();
487 // Determine if the branch is actually in a Friend TTree and if so which.
488 if (branch->GetTree() != fTreeReader->GetTree()->GetTree()) {
489 // It is in a friend, let's find the 'index' in the list of friend ...
490 std::optional<std::size_t> index;
491 std::size_t current{};
492 auto &&friends = fTreeReader->GetTree()->GetTree()->GetListOfFriends();
493 for (auto fe : TRangeDynCast<TFriendElement>(friends)) {
494 if (branch->GetTree() == fe->GetTree()) {
495 index = current;
496 break;
497 }
498 ++current;
499 }
500 if (!index.has_value()) {
501 Error("TTreeReaderArrayBase::CreateProxy()",
502 "The branch %s is contained in a Friend TTree that is not directly attached to the main.\n"
503 "This is not yet supported by TTreeReader.",
504 fBranchName.Data());
505 return;
506 }
507
508 auto &&friendProxy = fTreeReader->AddFriendProxy(index.value());
509 director = friendProxy.GetDirector();
510 }
511 fTreeReader->AddProxy(
512 std::make_unique<TNamedBranchProxy>(director, branch, fBranchName, membername, suppressErrorsForThisBranch));
513
514 namedProxy = fTreeReader->FindProxy(fBranchName);
515 fProxy = namedProxy->GetProxy();
516 if (fProxy)
517 fSetupStatus = kSetupMatch;
518 else
519 fSetupStatus = kSetupMismatch;
520 }
521
522 if (!myLeaf){
523 TString branchActualTypeName;
524 const char* nonCollTypeName = GetBranchContentDataType(branch, branchActualTypeName, branchActualType);
525 if (nonCollTypeName) {
526 Error("TTreeReaderArrayBase::CreateContentProxy()", "The branch %s contains data of type %s, which should be accessed through a TTreeReaderValue< %s >.",
527 fBranchName.Data(), nonCollTypeName, nonCollTypeName);
528 if (fSetupStatus == kSetupInternalError)
529 fSetupStatus = kSetupNotACollection;
530 fProxy = nullptr;
531 return;
532 }
533 if (!branchActualType) {
534 if (branchActualTypeName.IsNull()) {
535 Error("TTreeReaderArrayBase::CreateContentProxy()", "Cannot determine the type contained in the collection of branch %s. That's weird - please report!",
536 fBranchName.Data());
537 } else {
538 Error("TTreeReaderArrayBase::CreateContentProxy()", "The branch %s contains data of type %s, which does not have a dictionary.",
539 fBranchName.Data(), branchActualTypeName.Data());
540 if (fSetupStatus == kSetupInternalError)
541 fSetupStatus = kSetupMissingDictionary;
542 }
543 fProxy = nullptr;
544 return;
545 }
546
547 auto matchingDataType = [](TDictionary *left, TDictionary *right) -> bool {
548 if (left == right)
549 return true;
550 if (!left || !right)
551 return false;
552 auto left_datatype = dynamic_cast<TDataType *>(left);
553 auto right_datatype = dynamic_cast<TDataType *>(right);
554 auto left_enum = dynamic_cast<TEnum*>(left);
555 auto right_enum = dynamic_cast<TEnum*>(right);
556
557 if ((left_datatype && left_datatype->GetType() == kInt_t && right_enum)
558 || (right_datatype && right_datatype->GetType() == kInt_t && left_enum))
559 return true;
560 if (!left_datatype || !right_datatype)
561 return false;
562 auto l = left_datatype->GetType();
563 auto r = right_datatype->GetType();
564 if ( l > 0 && l == r)
565 return true;
566 else
567 return ( (l == kDouble32_t && r == kDouble_t)
568 || (l == kDouble_t && r == kDouble32_t)
569 || (l == kFloat16_t && r == kFloat_t)
570 || (l == kFloat_t && r == kFloat16_t));
571 };
572
573 if (! matchingDataType(fDict, branchActualType)) {
574 Error("TTreeReaderArrayBase::CreateContentProxy()", "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderArray<%s>",
575 fBranchName.Data(), branchActualType->GetName(), fDict->GetName());
576 if (fSetupStatus == kSetupInternalError || fSetupStatus >= 0)
577 fSetupStatus = kSetupMismatch;
578
579 // Update named proxy's dictionary
580 if (!namedProxy->GetContentDict()) {
581 namedProxy->SetContentDict(fDict);
582 }
583
584 // fProxy = 0;
585 // return;
586 }
587 }
588
589 SetImpl(branch, myLeaf);
590}
591
592////////////////////////////////////////////////////////////////////////////////
593/// Determine the branch / leaf and its type; reset fProxy / fSetupStatus on error.
594
596 TDictionary *&branchActualType,
597 bool suppressErrorsForMissingBranch)
598{
599 myLeaf = nullptr;
600 branch = fTreeReader->GetTree()->GetBranch(fBranchName);
601 if (branch)
602 return true;
603
604 if (!fBranchName.Contains(".")) {
605 if (!suppressErrorsForMissingBranch) {
606 Error("TTreeReaderArrayBase::GetBranchAndLeaf()",
607 "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.",
608 fBranchName.Data());
609 }
610 fSetupStatus = kSetupMissingBranch;
611 fProxy = nullptr;
612 return false;
613 }
614
615 TRegexp leafNameExpression ("\\.[a-zA-Z0-9_]+$");
616 TString leafName (fBranchName(leafNameExpression));
617 TString branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
618 branch = fTreeReader->GetTree()->GetBranch(branchName);
619 if (!branch) {
620 if (!suppressErrorsForMissingBranch) {
621 Error("TTreeReaderArrayBase::GetBranchAndLeaf()",
622 "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.",
623 fBranchName.Data());
624 }
625 fSetupStatus = kSetupMissingBranch;
626 fProxy = nullptr;
627 return false;
628 }
629
630 myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
631 if (!myLeaf){
632 if (!suppressErrorsForMissingBranch) {
633 Error("TTreeReaderArrayBase::GetBranchAndLeaf()",
634 "The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for "
635 "available branches.",
636 fBranchName.Data());
637 }
638 fSetupStatus = kSetupMissingBranch;
639 fProxy = nullptr;
640 return false;
641 }
642
644 if (!tempDict){
645 Error("TTreeReaderArrayBase::GetBranchAndLeaf()", "Failed to get the dictionary for %s.", myLeaf->GetTypeName());
646 fSetupStatus = kSetupMissingDictionary;
647 fProxy = nullptr;
648 return false;
649 }
650
651 if (tempDict->IsA() == TDataType::Class() && TDictionary::GetDictionary(((TDataType*)tempDict)->GetTypeName()) == fDict){
652 //fLeafOffset = myLeaf->GetOffset() / 4;
653 branchActualType = fDict;
654 fLeaf = myLeaf;
655 fBranchName = branchName;
656 fLeafName = leafName(1, leafName.Length());
657 fHaveLeaf = (fLeafName.Length() > 0);
658 fSetupStatus = kSetupMatchLeaf;
659 }
660 else {
661 Error("TTreeReaderArrayBase::GetBranchAndLeaf()", "Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->GetTypeName(), fDict->GetName());
662 fProxy = nullptr;
663 fSetupStatus = kSetupMismatch;
664 return false;
665 }
666 return true;
667}
668
669////////////////////////////////////////////////////////////////////////////////
670/// Create the TVirtualCollectionReader object for our branch.
671
673{
674 if (fImpl)
675 return;
676
677 // Access a branch's collection content (not the collection itself)
678 // through a proxy.
679 // Search for the branchname, determine what it contains, and wire the
680 // TBranchProxy representing it to us so we can access its data.
681 // A proxy for branch must not have been created before (i.e. check
682 // fProxies before calling this function!)
683
684 if (myLeaf){
685 if (!myLeaf->GetLeafCount()){
686 fImpl = std::make_unique<TLeafReader>(this);
687 }
688 else {
689 TString leafFullName = myLeaf->GetBranch()->GetName();
690 leafFullName += ".";
691 leafFullName += myLeaf->GetLeafCount()->GetName();
692 fImpl = std::make_unique<TLeafParameterSizeReader>(fTreeReader, leafFullName.Data(), this);
693 }
694 fSetupStatus = kSetupMatchLeaf;
695 }
696 else if (branch->IsA() == TBranchElement::Class()) {
697 TBranchElement* branchElement = ((TBranchElement*)branch);
698
699 TStreamerInfo *streamerInfo = branchElement->GetInfo();
700 Int_t id = branchElement->GetID();
701
702 if (id >= 0){ // Not root node?
703 // Int_t offset = streamerInfo->GetOffsets()[id];
704 TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(id);
705 // bool isPointer = element->IsaPointer();
706 // TClass *classPointer = element->GetClassPointer();
707
708 if (fSetupStatus == kSetupInternalError)
709 fSetupStatus = kSetupMatch;
710 if (element->IsA() == TStreamerSTL::Class()) {
711 if (branchElement->GetType() == 31) {
712 Error("TTreeReaderArrayBase::SetImpl",
713 "STL Collection nested in a TClonesArray not yet supported");
714 fSetupStatus = kSetupInternalError;
715 return;
716 }
717 fImpl = std::make_unique<TSTLReader>();
718 }
719 else if (element->IsA() == TStreamerObject::Class()){
720 //fImpl = new TObjectArrayReader(); // BArray[12]
721
722 if (element->GetClass() == TClonesArray::Class()){
723 fImpl = std::make_unique<TClonesReader>();
724 }
725 else if (branchElement->GetType() == TBranchElement::kSTLMemberNode){
726 fImpl = std::make_unique<TBasicTypeArrayReader>();
727 }
728 else if (branchElement->GetType() == TBranchElement::kClonesMemberNode){
729 // TBasicTypeClonesReader should work for object
730 fImpl = std::make_unique<TBasicTypeClonesReader>(element->GetOffset());
731 }
732 else {
733 fImpl = std::make_unique<TArrayFixedSizeReader>(element->GetArrayLength());
734 }
735 }
736 else if (element->IsA() == TStreamerLoop::Class()) {
737 fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, branchElement->GetBranchCount()->GetName());
738 }
739 else if (element->IsA() == TStreamerBasicType::Class()){
740 if (branchElement->GetType() == TBranchElement::kSTLMemberNode){
741 fImpl = std::make_unique<TBasicTypeArrayReader>();
742 }
743 else if (branchElement->GetType() == TBranchElement::kClonesMemberNode){
744 fImpl = std::make_unique<TBasicTypeClonesReader>(element->GetOffset());
745 }
746 else if (fDict->IsA() == TEnum::Class()) {
747 fImpl = std::make_unique<TArrayFixedSizeReader>(element->GetArrayLength());
748 ((TObjectArrayReader*)fImpl.get())->SetBasicTypeSize(sizeof(Int_t));
749 } else {
750 fImpl = std::make_unique<TArrayFixedSizeReader>(element->GetArrayLength());
751 ((TObjectArrayReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
752 }
753 }
754 else if (element->IsA() == TStreamerBasicPointer::Class()) {
755 fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, branchElement->GetBranchCount()->GetName());
756 ((TArrayParameterSizeReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
757 }
758 else if (element->IsA() == TStreamerBase::Class()){
759 fImpl = std::make_unique<TClonesReader>();
760 } else {
761 Error("TTreeReaderArrayBase::SetImpl()",
762 "Cannot read branch %s: unhandled streamer element type %s",
763 fBranchName.Data(), element->IsA()->GetName());
764 fSetupStatus = kSetupInternalError;
765 }
766 }
767 else { // We are at root node?
768 if (branchElement->GetClass()->GetCollectionProxy()){
769 fImpl = std::make_unique<TCollectionLessSTLReader>(branchElement->GetClass()->GetCollectionProxy());
770 }
771 }
772 } else if (branch->IsA() == TBranch::Class()) {
773 auto topLeaf = branch->GetLeaf(branch->GetName());
774 if (!topLeaf) {
775 Error("TTreeReaderArrayBase::SetImpl", "Failed to get the top leaf from the branch");
776 fSetupStatus = kSetupMissingBranch;
777 return;
778 }
779 // We could have used GetLeafCounter, but it does not work well with Double32_t and Float16_t: ROOT-10149
780 auto sizeLeaf = topLeaf->GetLeafCount();
781 if (fSetupStatus == kSetupInternalError)
782 fSetupStatus = kSetupMatch;
783 if (!sizeLeaf) {
784 fImpl = std::make_unique<TArrayFixedSizeReader>(topLeaf->GetLenStatic());
785 }
786 else {
787 fImpl = std::make_unique<TArrayParameterSizeReader>(fTreeReader, sizeLeaf->GetName());
788 }
789 ((TObjectArrayReader*)fImpl.get())->SetBasicTypeSize(((TDataType*)fDict)->Size());
790 } else if (branch->IsA() == TBranchClones::Class()) {
791 Error("TTreeReaderArrayBase::SetImpl", "Support for branches of type TBranchClones not implemented");
792 fSetupStatus = kSetupInternalError;
793 } else if (branch->IsA() == TBranchObject::Class()) {
794 Error("TTreeReaderArrayBase::SetImpl", "Support for branches of type TBranchObject not implemented");
795 fSetupStatus = kSetupInternalError;
796 } else if (branch->IsA() == TBranchSTL::Class()) {
797 Error("TTreeReaderArrayBase::SetImpl", "Support for branches of type TBranchSTL not implemented");
798 fImpl = std::make_unique<TSTLReader>();
799 fSetupStatus = kSetupInternalError;
800 } else if (branch->IsA() == TBranchRef::Class()) {
801 Error("TTreeReaderArrayBase::SetImpl", "Support for branches of type TBranchRef not implemented");
802 fSetupStatus = kSetupInternalError;
803 }
804}
805
806////////////////////////////////////////////////////////////////////////////////
807/// Access a branch's collection content (not the collection itself)
808/// through a proxy.
809/// Retrieve the type of data contained in the collection stored by branch;
810/// put its dictionary into dict, If there is no dictionary, put its type
811/// name into contentTypeName.
812/// The contentTypeName is set to NULL if the branch does not
813/// contain a collection; in that case, the type of the branch is returned.
814/// In all other cases, NULL is returned.
815
817 TString& contentTypeName,
818 TDictionary* &dict)
819{
820 dict = nullptr;
821 contentTypeName = "";
822 if (branch->IsA() == TBranchElement::Class()) {
823 TBranchElement* brElement = (TBranchElement*)branch;
824 if (brElement->GetType() == 4
825 || brElement->GetType() == 3) {
826 TVirtualCollectionProxy* collProxy = brElement->GetCollectionProxy();
827 if (collProxy) {
828 TClass *myClass = collProxy->GetValueClass();
829 if (!myClass){
830 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "Could not get value class.");
831 return nullptr;
832 }
833 dict = TDictionary::GetDictionary(myClass->GetName());
834 if (!dict) dict = TDataType::GetDataType(collProxy->GetType());
835 }
836 if (!dict) {
837 // We don't know the dictionary, thus we need the content's type name.
838 // Determine it.
839 if (brElement->GetType() == 3) {
840 contentTypeName = brElement->GetClonesName();
841 dict = TDictionary::GetDictionary(brElement->GetClonesName());
842 return nullptr;
843 }
844 // STL:
845 TClassEdit::TSplitType splitType(brElement->GetClassName());
846 int isSTLCont = splitType.IsSTLCont();
847 if (!isSTLCont) {
848 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "Cannot determine STL collection type of %s stored in branch %s", brElement->GetClassName(), branch->GetName());
849 return brElement->GetClassName();
850 }
851 bool isMap = isSTLCont == ROOT::kSTLmap
852 || isSTLCont == ROOT::kSTLmultimap;
853 if (isMap) contentTypeName = "std::pair< ";
854 contentTypeName += splitType.fElements[1];
855 if (isMap) {
856 contentTypeName += splitType.fElements[2];
857 contentTypeName += " >";
858 }
859 return nullptr;
860 }
861 return nullptr;
862 } else if (brElement->GetType() == 31
863 || brElement->GetType() == 41) {
864 // it's a member, extract from GetClass()'s streamer info
865 TClass* clData = nullptr;
866 EDataType dtData = kOther_t;
867 int ExpectedTypeRet = brElement->GetExpectedType(clData, dtData);
868 if (ExpectedTypeRet == 0) {
869 dict = clData;
870 if (!dict) {
871 if (dtData == kFloat16_t) {
872 dtData = kFloat_t;
873 }
874 if (dtData == kDouble32_t) {
875 dtData = kDouble_t;
876 }
877 dict = TDataType::GetDataType(dtData);
878 }
879 if (!dict) {
880 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s contains a data type %d for which the dictionary cannot be retrieved.",
881 branch->GetName(), (int)dtData);
882 contentTypeName = TDataType::GetTypeName(dtData);
883 return nullptr;
884 }
885 return nullptr;
886 } else if (ExpectedTypeRet == 1) {
887 int brID = brElement->GetID();
888 if (brID == -1) {
889 // top
890 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s contains data of type %s for which the dictionary does not exist. It's needed.",
891 branch->GetName(), brElement->GetClassName());
892 contentTypeName = brElement->GetClassName();
893 return nullptr;
894 }
895 // Either the data type name doesn't have an EDataType entry
896 // or the streamer info doesn't have a TClass* attached.
897 TStreamerElement* element =
898 (TStreamerElement*) brElement->GetInfo()->GetElement(brID);
899 contentTypeName = element->GetTypeName();
900 return nullptr;
901 }
902 /* else (ExpectedTypeRet == 2)*/
903 // The streamer info entry cannot be found.
904 // TBranchElement::GetExpectedType() has already complained.
905 return "{CANNOT DETERMINE TBranchElement DATA TYPE}";
906 }
907 else if (brElement->GetType() == TBranchElement::kLeafNode){
908 TStreamerInfo *streamerInfo = brElement->GetInfo();
909 Int_t id = brElement->GetID();
910
911 if (id >= 0){
912 TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(id);
913
914 if (element->IsA() == TStreamerSTL::Class()){
915 TClass *myClass = brElement->GetCurrentClass();
916 if (!myClass){
917 Error("TTreeReaderArrayBase::GetBranchDataType()", "Could not get class from branch element.");
918 return nullptr;
919 }
920 TVirtualCollectionProxy *myCollectionProxy = myClass->GetCollectionProxy();
921 if (!myCollectionProxy){
922 Error("TTreeReaderArrayBase::GetBranchDataType()", "Could not get collection proxy from STL class");
923 return nullptr;
924 }
925 // Try getting the contained class
926 dict = myCollectionProxy->GetValueClass();
927 // If it fails, try to get the contained type as a primitive type
928 if (!dict) dict = TDataType::GetDataType(myCollectionProxy->GetType());
929 if (!dict){
930 Error("TTreeReaderArrayBase::GetBranchDataType()", "Could not get valueClass from collectionProxy.");
931 return nullptr;
932 }
933 contentTypeName = dict->GetName();
934 return nullptr;
935 }
936 else if (element->IsA() == TStreamerObject::Class() && !strcmp(element->GetTypeName(), "TClonesArray")){
937 if (!fProxy->Setup() || !fProxy->Read()){
938 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "Failed to get type from proxy, unable to check type");
939 contentTypeName = "UNKNOWN";
940 dict = nullptr;
941 return contentTypeName;
942 }
943 TClonesArray *myArray = (TClonesArray*)fProxy->GetWhere();
944 dict = myArray->GetClass();
945 contentTypeName = dict->GetName();
946 return nullptr;
947 }
948 else {
949 dict = brElement->GetCurrentClass();
950 if (!dict) {
951 TDictionary *myDataType = TDictionary::GetDictionary(brElement->GetTypeName());
952 dict = TDataType::GetDataType((EDataType)((TDataType*)myDataType)->GetType());
953 }
954 contentTypeName = brElement->GetTypeName();
955 return nullptr;
956 }
957 }
958 if (brElement->GetCurrentClass() == TClonesArray::Class()){
959 contentTypeName = "TClonesArray";
960 Warning("TTreeReaderArrayBase::GetBranchContentDataType()", "Not able to check type correctness, ignoring check");
961 dict = fDict;
962 fSetupStatus = kSetupNoCheck;
963 }
964 else if (!dict && (branch->GetSplitLevel() == 0 || brElement->GetClass()->GetCollectionProxy())){
965 // Try getting the contained class
966 dict = brElement->GetClass()->GetCollectionProxy()->GetValueClass();
967 // If it fails, try to get the contained type as a primitive type
968 if (!dict) dict = TDataType::GetDataType(brElement->GetClass()->GetCollectionProxy()->GetType());
969 if (dict) contentTypeName = dict->GetName();
970 return nullptr;
971 }
972 else if (!dict){
973 dict = brElement->GetClass();
974 contentTypeName = dict->GetName();
975 return nullptr;
976 }
977
978 return nullptr;
979 }
980 return nullptr;
981 } else if (branch->IsA() == TBranch::Class()
982 || branch->IsA() == TBranchObject::Class()
983 || branch->IsA() == TBranchSTL::Class()) {
984 const char* dataTypeName = branch->GetClassName();
985 if ((!dataTypeName || !dataTypeName[0])
986 && branch->IsA() == TBranch::Class()) {
987 auto myLeaf = branch->GetLeaf(branch->GetName());
988 if (myLeaf){
989 auto myDataType = TDictionary::GetDictionary(myLeaf->GetTypeName());
990 if (myDataType && myDataType->IsA() == TDataType::Class()){
991 auto typeEnumConstant = EDataType(((TDataType*)myDataType)->GetType());
992 // We need to consider Double32_t and Float16_t as dounle and float respectively
993 // since this is the type the user uses to instantiate the TTreeReaderArray template.
994 if (typeEnumConstant == kDouble32_t) typeEnumConstant = kDouble_t;
995 else if (typeEnumConstant == kFloat16_t) typeEnumConstant = kFloat_t;
996 dict = TDataType::GetDataType(typeEnumConstant);
997 contentTypeName = myLeaf->GetTypeName();
998 return nullptr;
999 }
1000 }
1001
1002 // leaflist. Can't represent.
1003 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());
1004 TIter iLeaves(branch->GetListOfLeaves());
1005 TLeaf* leaf = nullptr;
1006 while ((leaf = (TLeaf*) iLeaves())) {
1007 Error("TTreeReaderArrayBase::GetBranchContentDataType()", " %s.%s", branch->GetName(), leaf->GetName());
1008 }
1009 return nullptr;
1010 }
1011 if (dataTypeName) dict = TDictionary::GetDictionary(dataTypeName);
1012 if (branch->IsA() == TBranchSTL::Class()){
1013 Warning("TTreeReaderArrayBase::GetBranchContentDataType()", "Not able to check type correctness, ignoring check");
1014 dict = fDict;
1015 fSetupStatus = kSetupNoCheck;
1016 return nullptr;
1017 }
1018 return dataTypeName;
1019 } else if (branch->IsA() == TBranchClones::Class()) {
1020 dict = TClonesArray::Class();
1021 return "TClonesArray";
1022 } else if (branch->IsA() == TBranchRef::Class()) {
1023 // Can't represent.
1024 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->GetName());
1025 return nullptr;
1026 } else {
1027 Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s is of type %s - something that is not handled yet.", branch->GetName(), branch->IsA()->GetName());
1028 return nullptr;
1029 }
1030
1031 return nullptr;
1032}
dim_t fSize
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
unsigned char Byte_t
Definition RtypesCore.h:64
#define ClassImp(name)
Definition Rtypes.h:382
EDataType
Definition TDataType.h:28
@ kFloat_t
Definition TDataType.h:31
@ kInt_t
Definition TDataType.h:30
@ kDouble32_t
Definition TDataType.h:31
@ kDouble_t
Definition TDataType.h:31
@ kFloat16_t
Definition TDataType.h:33
@ kOther_t
Definition TDataType.h:32
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
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 r
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.
virtual void * GetStart(UInt_t=0)
bool GetSuppressErrorsForMissingBranch() const
TVirtualCollectionProxy * GetCollection()
const Detail::TBranchProxy * GetProxy() const
TDictionary * GetContentDict() const
void SetContentDict(TDictionary *dict)
Base class of TTreeReaderArray.
void CreateProxy() override
Create the proxy object for our branch.
bool GetBranchAndLeaf(TBranch *&branch, TLeaf *&myLeaf, TDictionary *&branchActualType, bool suppressErrorsForMissingBranch=false)
Determine the branch / leaf and its type; reset fProxy / fSetupStatus on error.
void SetImpl(TBranch *branch, TLeaf *myLeaf)
Create the TVirtualCollectionReader object for our branch.
const char * GetBranchContentDataType(TBranch *branch, TString &contentTypeName, TDictionary *&dict)
Access a branch's collection content (not the collection itself) through a proxy.
Base class of TTreeReaderValue.
void * GetAddress()
Returns the memory address of the object being read.
TLeaf * GetLeaf()
If we are reading a leaf, return the corresponding TLeaf.
static TClass * Class()
A Branch for the case of an object.
TBranchElement * GetBranchCount() const
static TClass * Class()
Int_t GetID() const
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.
TVirtualCollectionProxy * GetCollectionProxy()
Return the collection proxy describing the branch content, if any.
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.
virtual const char * GetClonesName() const
virtual TClass * GetClass() const
Int_t GetType() const
Int_t GetExpectedType(TClass *&clptr, EDataType &type) override
Fill expectedClass and expectedType with information on the data type of the object/values contained ...
static TClass * Class()
static TClass * Class()
static TClass * Class()
A TTree is a list of TBranches.
Definition TBranch.h:93
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
Definition TBranch.cxx:2055
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any.
Definition TBranch.cxx:1324
TTree * GetTree() const
Definition TBranch.h:252
static TClass * Class()
Int_t GetSplitLevel() const
Definition TBranch.h:250
TClass * IsA() const override
Definition TBranch.h:295
TObjArray * GetListOfLeaves()
Definition TBranch.h:247
TBranch * GetMother() const
Get our top-level parent branch in the tree.
Definition TBranch.cxx:2127
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2966
Int_t GetClassSize() const
Definition TClass.h:426
An array of clone (identical) objects.
TClass * GetClass() const
static TClass * Class()
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
static TClass * Class()
TString GetTypeName()
Get basic type of typedef, e,g.: "class TDirectory*" -> "TDirectory".
static TDataType * GetDataType(EDataType type)
Given a EDataType type, get the TDataType* that represents it.
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.
Definition TEnum.h:33
static TClass * Class()
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition TLeaf.h:57
virtual Int_t GetLenType() const
Definition TLeaf.h:133
virtual const char * GetTypeName() const
Definition TLeaf.h:139
virtual Int_t GetLen() const
Return the number of effective elements of this leaf, for the current entry.
Definition TLeaf.cxx:404
virtual TLeaf * GetLeafCount() const
If this leaf stores a variable-sized array or a multi-dimensional array whose last dimension has vari...
Definition TLeaf.h:121
TBranch * GetBranch() const
Definition TLeaf.h:116
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
Int_t GetEntries() const override
Return the number of objects in array (i.e.
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
TObject * UncheckedAt(Int_t i) const
Definition TObjArray.h:84
Regular expression class.
Definition TRegexp.h:31
static TClass * Class()
static TClass * Class()
static TClass * Class()
Int_t GetArrayLength() const
const char * GetTypeName() const
TClass * GetClass() const
TClass * IsA() const override
Int_t GetOffset() const
Describes a persistent version of a class.
TStreamerElement * GetElement(Int_t id) const override
TObjArray * GetElements() const override
static TClass * Class()
static TClass * Class()
static TClass * Class()
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
const char * Data() const
Definition TString.h:376
Bool_t IsNull() const
Definition TString.h:414
An interface for reading values stored in ROOT columnar datasets.
A simple, robust and fast interface to read values from ROOT columnar datasets such as TTree,...
Definition TTreeReader.h:46
TTree * GetTree() const
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition TTree.cxx:5284
virtual TTree * GetTree() const
Definition TTree.h:557
virtual TLeaf * FindLeaf(const char *name)
Find leaf..
Definition TTree.cxx:4906
Defines a common interface to inspect/change the contents of an object that represents a collection.
virtual void PushProxy(void *objectstart)=0
Set the address of the container being proxied and keep track of the previous one.
virtual EDataType GetType() const =0
If the value type is a fundamental data type, return its type (see enumeration EDataType).
virtual void PopProxy()=0
Reset the address of the container being proxied to the previous container.
virtual TClass * GetValueClass() const =0
If the value type is a user-defined class, return a pointer to the TClass representing the value type...
virtual void * At(UInt_t idx)=0
Return the address of the value at index idx
virtual UInt_t Size() const =0
Return the current number of elements in the container.
virtual Bool_t HasPointers() const =0
Return true if the content is of type 'pointer to'.
@ kSTLmap
Definition ESTLType.h:33
@ kSTLmultimap
Definition ESTLType.h:34
void forward(const LAYERDATA &prevLayerData, LAYERDATA &currLayerData)
apply the weights (and functions) in forward direction of the DNN
int IsSTLCont(int testAlloc=0) const
type : type name: vector<list<classA,allocator>,allocator> testAlloc: if true, we test allocator,...
std::vector< std::string > fElements
Definition TClassEdit.h:141
TLine l
Definition textangle.C:4
#define ARGS(alist)
Definition gifencode.c:10