Logo ROOT   6.07/09
Reference Guide
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 "TBranchProxyDirector.h"
19 #include "TClassEdit.h"
20 #include "TLeaf.h"
21 #include "TROOT.h"
22 #include "TStreamerInfo.h"
23 #include "TStreamerElement.h"
24 #include "TTreeReader.h"
25 #include "TGenCollectionProxy.h"
26 #include "TRegexp.h"
27 
28 // pin vtable
30 
31 namespace {
32  using namespace ROOT::Internal;
33 
34  // Reader interface for clones arrays
35  class TClonesReader: public TVirtualCollectionReader {
36  public:
37  ~TClonesReader() {}
39  if (!proxy->Read()){
41  Error("TClonesReader::GetCA()", "Read error in TBranchProxy.");
42  return 0;
43  }
45  return (TClonesArray*) proxy->GetWhere();
46  }
47  virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
48  TClonesArray *myClonesArray = GetCA(proxy);
49  if (myClonesArray){
50  return myClonesArray->GetEntries();
51  }
52  else return 0;
53  }
54  virtual void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) {
55  TClonesArray *myClonesArray = GetCA(proxy);
56  if (myClonesArray){
57  return myClonesArray->UncheckedAt(idx);
58  }
59  else return 0;
60  }
61  };
62 
63  // Reader interface for STL
64  class TSTLReader: public TVirtualCollectionReader {
65  public:
66  ~TSTLReader() {}
68  if (!proxy->Read()) {
70  Error("TSTLReader::GetCP()", "Read error in TBranchProxy.");
71  return 0;
72  }
73  if (!proxy->GetWhere()) {
74  Error("TSTLReader::GetCP()", "Logic error, proxy object not set in TBranchProxy.");
75  return 0;
76  }
77  if (proxy->IsaPointer()) {
78  if (proxy->GetWhere() && *(void**)proxy->GetWhere()){
79  ((TGenCollectionProxy*)proxy->GetCollection())->PopProxy();
80  ((TGenCollectionProxy*)proxy->GetCollection())->PushProxy(*(void**)proxy->GetWhere());
81  }
82  else return 0;
83  }
85  return (TVirtualCollectionProxy*) proxy->GetCollection();
86  }
87 
88  virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
89  TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
90  if (!myCollectionProxy) return 0;
91  return myCollectionProxy->Size();
92  }
93 
94  virtual void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) {
95  TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
96  if (!myCollectionProxy) return 0;
97  if (myCollectionProxy->HasPointers()){
98  return *(void**)myCollectionProxy->At(idx);
99  }
100  else {
101  return myCollectionProxy->At(idx);
102  }
103  }
104  };
105 
106  class TCollectionLessSTLReader : public TVirtualCollectionReader {
107  private:
108  TVirtualCollectionProxy *localCollection;
109  public:
110  TCollectionLessSTLReader(TVirtualCollectionProxy *proxy) : localCollection(proxy) {}
111 
113  if (!proxy->Read()) {
115  Error("TCollectionLessSTLReader::GetCP()", "Read error in TBranchProxy.");
116  return 0;
117  }
118  if (!proxy->GetWhere()) {
119  Error("TCollectionLessSTLReader::GetCP()", "Logic error, proxy object not set in TBranchProxy.");
120  return 0;
121  }
123  return localCollection;
124  }
125 
126  virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
127  TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
128  if (!myCollectionProxy) return 0;
129  TVirtualCollectionProxy::TPushPop ppRaii(myCollectionProxy, proxy->GetWhere());
130  return myCollectionProxy->Size();
131  }
132 
133  virtual void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) {
134  TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
135  if (!myCollectionProxy) return 0;
136  TVirtualCollectionProxy::TPushPop ppRaii(myCollectionProxy, proxy->GetWhere());
137  if (myCollectionProxy->HasPointers()){
138  return *(void**)myCollectionProxy->At(idx);
139  } else {
140  return myCollectionProxy->At(idx);
141  }
142  }
143  };
144 
145 
146  // Reader interface for leaf list
147  // SEE TTreeProxyGenerator.cxx:1319: '//We have a top level raw type'
148  class TObjectArrayReader: public TVirtualCollectionReader {
149  private:
150  Int_t basicTypeSize;
151  public:
152  TObjectArrayReader() : basicTypeSize(-1) { }
153  ~TObjectArrayReader() {}
155  if (!proxy->Read()){
157  Error("TObjectArrayReader::GetCP()", "Read error in TBranchProxy.");
158  return 0;
159  }
161  return (TVirtualCollectionProxy*) proxy->GetCollection();
162  }
163  virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy) {
164  TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
165  if (!myCollectionProxy) return 0;
166  return myCollectionProxy->Size();
167  }
168  virtual void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx) {
169  if (!proxy->Read()) return 0;
170 
171  Int_t objectSize;
172  void *array = (void*)proxy->GetStart();
173 
174  if (basicTypeSize == -1){
175  TClass *myClass = proxy->GetClass();
176  if (!myClass){
177  Error("TObjectArrayReader::At()", "Cannot get class info from branch proxy.");
178  return 0;
179  }
180  objectSize = myClass->GetClassSize();
181  }
182  else {
183  objectSize = basicTypeSize;
184  }
185  return (void*)((Byte_t*)array + (objectSize * idx));
186  }
187 
188  void SetBasicTypeSize(Int_t size){
189  basicTypeSize = size;
190  }
191  };
192 
193  class TArrayParameterSizeReader : public TObjectArrayReader {
194  private:
195  TTreeReaderValue<Int_t> indexReader;
196  public:
197  TArrayParameterSizeReader(TTreeReader *treeReader, const char *branchName) : indexReader(*treeReader, branchName) {}
198 
199  virtual size_t GetSize(ROOT::Detail::TBranchProxy* /*proxy*/){ return *indexReader; }
200  };
201 
202  // Reader interface for fixed size arrays
203  class TArrayFixedSizeReader : public TObjectArrayReader {
204  private:
205  Int_t size;
206 
207  public:
208  TArrayFixedSizeReader(Int_t sizeArg) : size(sizeArg) {}
209 
210  virtual size_t GetSize(ROOT::Detail::TBranchProxy* /*proxy*/) { return size; }
211  };
212 
213  class TBasicTypeArrayReader : public TVirtualCollectionReader {
214  public:
215  ~TBasicTypeArrayReader() {}
216 
218  if (!proxy->Read()){
220  Error("TBasicTypeArrayReader::GetCP()", "Read error in TBranchProxy.");
221  return 0;
222  }
224  return (TVirtualCollectionProxy*) proxy->GetCollection();
225  }
226 
227  virtual size_t GetSize(ROOT::Detail::TBranchProxy* proxy){
228  TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
229  if (!myCollectionProxy) return 0;
230  return myCollectionProxy->Size();
231  }
232 
233  virtual void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx){
234  TVirtualCollectionProxy *myCollectionProxy = GetCP(proxy);
235  if (!myCollectionProxy) return 0;
236  return (Byte_t*)myCollectionProxy->At(idx) + proxy->GetOffset();
237  }
238  };
239 
240  class TBasicTypeClonesReader : public TClonesReader {
241  private:
242  Int_t offset;
243  public:
244  TBasicTypeClonesReader(Int_t offsetArg) : offset(offsetArg) {}
245 
246  virtual void* At(ROOT::Detail::TBranchProxy* proxy, size_t idx){
247  TClonesArray *myClonesArray = GetCA(proxy);
248  if (!myClonesArray) return 0;
249  return (Byte_t*)myClonesArray->At(idx) + offset;
250  }
251  };
252 
253  class TLeafReader : public TVirtualCollectionReader {
254  private:
255  TTreeReaderValueBase *valueReader;
256  Int_t elementSize;
257  public:
258  TLeafReader(TTreeReaderValueBase *valueReaderArg) : valueReader(valueReaderArg), elementSize(-1) {}
259 
260  virtual size_t GetSize(ROOT::Detail::TBranchProxy* /*proxy*/){
261  TLeaf *myLeaf = valueReader->GetLeaf();
262  return myLeaf ? myLeaf->GetLen() : 0; // Error will be printed by GetLeaf
263  }
264 
265  virtual void* At(ROOT::Detail::TBranchProxy* /*proxy*/, size_t idx){
266  ProxyRead();
267  void *address = valueReader->GetAddress();
268  if (elementSize == -1){
269  TLeaf *myLeaf = valueReader->GetLeaf();
270  if (!myLeaf) return 0; // Error will be printed by GetLeaf
271  elementSize = myLeaf->GetLenType();
272  }
273  return (Byte_t*)address + (elementSize * idx);
274  }
275 
276  protected:
277  void ProxyRead(){
278  valueReader->ProxyRead();
279  }
280  };
281 
282  class TLeafParameterSizeReader : public TLeafReader {
283  private:
284  TTreeReaderValue<Int_t> sizeReader;
285  public:
286  TLeafParameterSizeReader(TTreeReader *treeReader, const char *leafName, TTreeReaderValueBase *valueReaderArg) : TLeafReader(valueReaderArg), sizeReader(*treeReader, leafName) {}
287 
288  virtual size_t GetSize(ROOT::Detail::TBranchProxy* /*proxy*/){
289  ProxyRead();
290  return *sizeReader;
291  }
292  };
293 }
294 
295 /** \class TTreeReaderArray
296 
297 Extracts array data from a TTree.
298 */
299 
301 
302 ////////////////////////////////////////////////////////////////////////////////
303 /// Create the proxy object for our branch.
304 
305 void ROOT::Internal::TTreeReaderArrayBase::CreateProxy()
306 {
307  if (fProxy) {
308  return;
309  }
310  if (!fTreeReader) {
311  Error("TTreeReaderArrayBase::CreateProxy()", "TTreeReader object not set / available for branch %s!",
312  fBranchName.Data());
313  return;
314  }
315  if (!fDict) {
316  TBranch* br = fTreeReader->GetTree()->GetBranch(fBranchName);
317  const char* brDataType = "{UNDETERMINED}";
318  if (br) {
319  TDictionary* dictUnused = 0;
320  brDataType = GetBranchDataType(br, dictUnused);
321  }
322  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.",
323  GetDerivedTypeName(), fBranchName.Data(), brDataType);
324  return;
325  }
326 
327  // Access a branch's collection content (not the collection itself)
328  // through a proxy.
329  // Search for the branchname, determine what it contains, and wire the
330  // TBranchProxy representing it to us so we can access its data.
331 
332  TNamedBranchProxy* namedProxy = fTreeReader->FindProxy(fBranchName);
333  if (namedProxy && namedProxy->GetContentDict() == fDict) {
334  fProxy = namedProxy->GetProxy();
335  if (!fImpl){
336  Fatal("TTreeReaderArrayBase::CreateProxy()", "No fImpl set!");
337  }
338  return;
339  }
340 
341 
342  TDictionary* branchActualType = 0;
343  TBranch* branch = fTreeReader->GetTree()->GetBranch(fBranchName);
344  TLeaf *myLeaf = NULL;
345  if (!branch) {
346  if (fBranchName.Contains(".")){
347  TRegexp leafNameExpression ("\\.[a-zA-Z0-9_]+$");
348  TString leafName (fBranchName(leafNameExpression));
349  TString branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
350  branch = fTreeReader->GetTree()->GetBranch(branchName);
351  if (!branch){
352  Error("TTreeReaderArrayBase::CreateProxy()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
353  fProxy = 0;
354  return;
355  }
356  else {
357  myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
358  if (!myLeaf){
359  Error("TTreeReaderArrayBase::CreateProxy()", "The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
360  fProxy = 0;
361  return;
362  }
363  else {
364  TDictionary *tempDict = TDictionary::GetDictionary(myLeaf->GetTypeName());
365  if (!tempDict){
366  Error("TTreeReaderArrayBase::CreateProxy()", "Failed to get the dictionary for %s.", myLeaf->GetTypeName());
367  fProxy = 0;
368  return;
369  }
370  else if (tempDict->IsA() == TDataType::Class() && TDictionary::GetDictionary(((TDataType*)tempDict)->GetTypeName()) == fDict){
371  //fLeafOffset = myLeaf->GetOffset() / 4;
372  branchActualType = fDict;
373  fLeaf = myLeaf;
374  fBranchName = branchName;
375  fLeafName = leafName(1, leafName.Length());
376  }
377  else {
378  Error("TTreeReaderArrayBase::CreateProxy()", "Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->GetTypeName(), fDict->GetName());
379  fProxy = 0;
380  return;
381  }
382  }
383  }
384  }
385  else {
386  Error("TTreeReaderArrayBase::CreateProxy()", "The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
387  fProxy = 0;
388  return;
389  }
390  }
391 
392  // Update named proxy's dictionary
393  if (namedProxy && !namedProxy->GetContentDict()) {
394  namedProxy->SetContentDict(fDict);
395  fProxy = namedProxy->GetProxy();
396  }
397  else {
398  TString membername;
399 
400  bool isTopLevel = branch->GetMother() == branch;
401  if (!isTopLevel) {
402  membername = strrchr(branch->GetName(), '.');
403  if (membername.IsNull()) {
404  membername = branch->GetName();
405  }
406  }
407  namedProxy = new TNamedBranchProxy(fTreeReader->fDirector, branch, membername);
408  fTreeReader->GetProxies()->Add(namedProxy);
409  fProxy = namedProxy->GetProxy();
410  }
411 
412  if (!myLeaf){
413  TString branchActualTypeName;
414  const char* nonCollTypeName = GetBranchContentDataType(branch, branchActualTypeName, branchActualType);
415  if (nonCollTypeName) {
416  Error("TTreeReaderArrayBase::CreateContentProxy()", "The branch %s contains data of type %s, which should be accessed through a TTreeReaderValue< %s >.",
417  fBranchName.Data(), nonCollTypeName, nonCollTypeName);
418  fProxy = 0;
419  return;
420  }
421  if (!branchActualType) {
422  if (branchActualTypeName.IsNull()) {
423  Error("TTreeReaderArrayBase::CreateContentProxy()", "Cannot determine the type contained in the collection of branch %s. That's weird - please report!",
424  fBranchName.Data());
425  } else {
426  Error("TTreeReaderArrayBase::CreateContentProxy()", "The branch %s contains data of type %s, which does not have a dictionary.",
427  fBranchName.Data(), branchActualTypeName.Data());
428  }
429  fProxy = 0;
430  return;
431  }
432 
433  if (fDict != branchActualType) {
434  Error("TTreeReaderArrayBase::CreateContentProxy()", "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderArray<%s>",
435  fBranchName.Data(), branchActualType->GetName(), fDict->GetName());
436 
437  // Update named proxy's dictionary
438  if (namedProxy && !namedProxy->GetContentDict()) {
439  namedProxy->SetContentDict(fDict);
440  }
441 
442  // fProxy = 0;
443  // return;
444  }
445  }
446 
447 
448 
449  // Access a branch's collection content (not the collection itself)
450  // through a proxy.
451  // Search for the branchname, determine what it contains, and wire the
452  // TBranchProxy representing it to us so we can access its data.
453  // A proxy for branch must not have been created before (i.e. check
454  // fProxies before calling this function!)
455 
456  if (myLeaf){
457  if (!myLeaf->GetLeafCount()){
458  fImpl = new TLeafReader(this);
459  }
460  else {
461  TString leafFullName = myLeaf->GetBranch()->GetName();
462  leafFullName += ".";
463  leafFullName += myLeaf->GetLeafCount()->GetName();
464  fImpl = new TLeafParameterSizeReader(fTreeReader, leafFullName.Data(), this);
465  }
466  }
467  else if (branch->IsA() == TBranchElement::Class()) {
468  TBranchElement* branchElement = ((TBranchElement*)branch);
469 
470  TStreamerInfo *streamerInfo = branchElement->GetInfo();
471  Int_t id = branchElement->GetID();
472 
473  if (id >= 0){ // Not root node?
474  // Int_t offset = streamerInfo->GetOffsets()[id];
475  TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(id);
476  // Bool_t isPointer = element->IsaPointer();
477  // TClass *classPointer = element->GetClassPointer();
478 
479  if (element->IsA() == TStreamerSTL::Class()){
480  fImpl = new TSTLReader();
481  }
482  else if (element->IsA() == TStreamerObject::Class()){
483  //fImpl = new TObjectArrayReader(); // BArray[12]
484 
485  if (element->GetClass() == TClonesArray::Class()){
486  fImpl = new TClonesReader();
487  }
488  else {
489  fImpl = new TArrayFixedSizeReader(element->GetArrayLength());
490  }
491  }
492  else if (element->IsA() == TStreamerLoop::Class()) {
493  fImpl = new TArrayParameterSizeReader(fTreeReader, branchElement->GetBranchCount()->GetName());
494  }
495  else if (element->IsA() == TStreamerBasicType::Class()){
496  if (branchElement->GetType() == TBranchElement::kSTLMemberNode){
497  fImpl = new TBasicTypeArrayReader();
498  }
499  else if (branchElement->GetType() == TBranchElement::kClonesMemberNode){
500  fImpl = new TBasicTypeClonesReader(element->GetOffset());
501  }
502  else {
503  fImpl = new TArrayFixedSizeReader(element->GetArrayLength());
504  ((TObjectArrayReader*)fImpl)->SetBasicTypeSize(((TDataType*)fDict)->Size());
505  }
506  }
507  else if (element->IsA() == TStreamerBase::Class()){
508  fImpl = new TClonesReader();
509  }
510  }
511  else { // We are at root node?
512  if (branchElement->GetClass()->GetCollectionProxy()){
513  fImpl = new TCollectionLessSTLReader(branchElement->GetClass()->GetCollectionProxy());
514  }
515  }
516  } else if (branch->IsA() == TBranch::Class()) {
517  TLeaf *topLeaf = branch->GetLeaf(branch->GetName());
518  if (!topLeaf) {
519  Error("TTreeReaderArrayBase::CreateProxy", "Failed to get the top leaf from the branch");
520  return;
521  }
522  Int_t size = 0;
523  TLeaf *sizeLeaf = topLeaf->GetLeafCounter(size);
524  if (!sizeLeaf) {
525  fImpl = new TArrayFixedSizeReader(size);
526  }
527  else {
528  fImpl = new TArrayParameterSizeReader(fTreeReader, sizeLeaf->GetName());
529  }
530  ((TObjectArrayReader*)fImpl)->SetBasicTypeSize(((TDataType*)fDict)->Size());
531  } else if (branch->IsA() == TBranchClones::Class()) {
532  Error("TTreeReaderArrayBase::CreateProxy", "Support for branches of type TBranchClones not implemented");
533  } else if (branch->IsA() == TBranchObject::Class()) {
534  Error("TTreeReaderArrayBase::CreateProxy", "Support for branches of type TBranchObject not implemented");
535  } else if (branch->IsA() == TBranchSTL::Class()) {
536  Error("TTreeReaderArrayBase::CreateProxy", "Support for branches of type TBranchSTL not implemented");
537  fImpl = new TSTLReader();
538  } else if (branch->IsA() == TBranchRef::Class()) {
539  Error("TTreeReaderArrayBase::CreateProxy", "Support for branches of type TBranchRef not implemented");
540  }
541 }
542 
543 ////////////////////////////////////////////////////////////////////////////////
544 /// Access a branch's collection content (not the collection itself)
545 /// through a proxy.
546 /// Retrieve the type of data contained in the collection stored by branch;
547 /// put its dictionary into dict, If there is no dictionary, put its type
548 /// name into contentTypeName.
549 /// The contentTypeName is set to NULL if the branch does not
550 /// contain a collection; in that case, the type of the branch is returned.
551 /// In all other cases, NULL is returned.
552 
554  TString& contentTypeName,
555  TDictionary* &dict) const
556 {
557  dict = 0;
558  contentTypeName = "";
559  if (branch->IsA() == TBranchElement::Class()) {
560  TBranchElement* brElement = (TBranchElement*)branch;
561  if (brElement->GetType() == 4
562  || brElement->GetType() == 3) {
563  TVirtualCollectionProxy* collProxy = brElement->GetCollectionProxy();
564  if (collProxy) {
565  TClass *myClass = collProxy->GetValueClass();
566  if (!myClass){
567  Error("TTreeReaderArrayBase::GetBranchContentDataType()", "Could not get value class.");
568  return 0;
569  }
570  dict = TDictionary::GetDictionary(myClass->GetName());
571  if (!dict) dict = TDataType::GetDataType(collProxy->GetType());
572  }
573  if (!dict) {
574  // We don't know the dictionary, thus we need the content's type name.
575  // Determine it.
576  if (brElement->GetType() == 3) {
577  contentTypeName = brElement->GetClonesName();
578  dict = TDictionary::GetDictionary(brElement->GetClonesName());
579  return 0;
580  }
581  // STL:
582  TClassEdit::TSplitType splitType(brElement->GetClassName());
583  int isSTLCont = splitType.IsSTLCont();
584  if (!isSTLCont) {
585  Error("TTreeReaderArrayBase::GetBranchContentDataType()", "Cannot determine STL collection type of %s stored in branch %s", brElement->GetClassName(), branch->GetName());
586  return brElement->GetClassName();
587  }
588  bool isMap = isSTLCont == ROOT::kSTLmap
589  || isSTLCont == ROOT::kSTLmultimap;
590  if (isMap) contentTypeName = "std::pair< ";
591  contentTypeName += splitType.fElements[1];
592  if (isMap) {
593  contentTypeName += splitType.fElements[2];
594  contentTypeName += " >";
595  }
596  return 0;
597  }
598  return 0;
599  } else if (brElement->GetType() == 31
600  || brElement->GetType() == 41) {
601  // it's a member, extract from GetClass()'s streamer info
602  TClass* clData = 0;
603  EDataType dtData = kOther_t;
604  int ExpectedTypeRet = brElement->GetExpectedType(clData, dtData);
605  if (ExpectedTypeRet == 0) {
606  dict = clData;
607  if (!dict) {
608  dict = TDataType::GetDataType(dtData);
609  }
610  if (!dict) {
611  Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s contains a data type %d for which the dictionary cannot be retrieved.",
612  branch->GetName(), (int)dtData);
613  contentTypeName = TDataType::GetTypeName(dtData);
614  return 0;
615  }
616  return 0;
617  } else if (ExpectedTypeRet == 1) {
618  int brID = brElement->GetID();
619  if (brID == -1) {
620  // top
621  Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s contains data of type %s for which the dictionary does not exist. It's needed.",
622  branch->GetName(), brElement->GetClassName());
623  contentTypeName = brElement->GetClassName();
624  return 0;
625  }
626  // Either the data type name doesn't have an EDataType entry
627  // or the streamer info doesn't have a TClass* attached.
628  TStreamerElement* element =
629  (TStreamerElement*) brElement->GetInfo()->GetElement(brID);
630  contentTypeName = element->GetTypeName();
631  return 0;
632  }
633  /* else (ExpectedTypeRet == 2)*/
634  // The streamer info entry cannot be found.
635  // TBranchElement::GetExpectedType() has already complained.
636  return "{CANNOT DETERMINE TBranchElement DATA TYPE}";
637  }
638  else if (brElement->GetType() == TBranchElement::kLeafNode){
639  TStreamerInfo *streamerInfo = brElement->GetInfo();
640  Int_t id = brElement->GetID();
641 
642  if (id >= 0){
643  TStreamerElement *element = (TStreamerElement*)streamerInfo->GetElements()->At(id);
644 
645  if (element->IsA() == TStreamerSTL::Class()){
646  TClass *myClass = brElement->GetCurrentClass();
647  if (!myClass){
648  Error("TTreeReaderArrayBase::GetBranchDataType()", "Could not get class from branch element.");
649  return 0;
650  }
651  TVirtualCollectionProxy *myCollectionProxy = myClass->GetCollectionProxy();
652  if (!myCollectionProxy){
653  Error("TTreeReaderArrayBase::GetBranchDataType()", "Could not get collection proxy from STL class");
654  return 0;
655  }
656  // Try getting the contained class
657  dict = myCollectionProxy->GetValueClass();
658  // If it fails, try to get the contained type as a primitive type
659  if (!dict) dict = TDataType::GetDataType(myCollectionProxy->GetType());
660  if (!dict){
661  Error("TTreeReaderArrayBase::GetBranchDataType()", "Could not get valueClass from collectionProxy.");
662  return 0;
663  }
664  contentTypeName = dict->GetName();
665  return 0;
666  }
667  else if (element->IsA() == TStreamerObject::Class() && !strcmp(element->GetTypeName(), "TClonesArray")){
668  if (!fProxy->Setup() || !fProxy->Read()){
669  Error("TTreeReaderArrayBase::GetBranchContentDataType()", "Failed to get type from proxy, unable to check type");
670  contentTypeName = "UNKNOWN";
671  dict = 0;
672  return contentTypeName;
673  }
674  TClonesArray *myArray = (TClonesArray*)fProxy->GetWhere();
675  dict = myArray->GetClass();
676  contentTypeName = dict->GetName();
677  return 0;
678  }
679  else {
680  dict = brElement->GetCurrentClass();
681  if (!dict) {
682  TDictionary *myDataType = TDictionary::GetDictionary(brElement->GetTypeName());
683  dict = TDataType::GetDataType((EDataType)((TDataType*)myDataType)->GetType());
684  }
685  contentTypeName = brElement->GetTypeName();
686  return 0;
687  }
688  }
689  if (brElement->GetCurrentClass() == TClonesArray::Class()){
690  contentTypeName = "TClonesArray";
691  Warning("TTreeReaderArrayBase::GetBranchContentDataType()", "Not able to check type correctness, ignoring check");
692  dict = fDict;
693  }
694  else if (!dict && (branch->GetSplitLevel() == 0 || brElement->GetClass()->GetCollectionProxy())){
695  // Try getting the contained class
696  dict = brElement->GetClass()->GetCollectionProxy()->GetValueClass();
697  // If it fails, try to get the contained type as a primitive type
698  if (!dict) dict = TDataType::GetDataType(brElement->GetClass()->GetCollectionProxy()->GetType());
699  if (dict) contentTypeName = dict->GetName();
700  return 0;
701  }
702  else if (!dict){
703  dict = brElement->GetClass();
704  contentTypeName = dict->GetName();
705  return 0;
706  }
707 
708  return 0;
709  }
710  return 0;
711  } else if (branch->IsA() == TBranch::Class()
712  || branch->IsA() == TBranchObject::Class()
713  || branch->IsA() == TBranchSTL::Class()) {
714  const char* dataTypeName = branch->GetClassName();
715  if ((!dataTypeName || !dataTypeName[0])
716  && branch->IsA() == TBranch::Class()) {
717  TLeaf *myLeaf = branch->GetLeaf(branch->GetName());
718  if (myLeaf){
719  TDictionary *myDataType = TDictionary::GetDictionary(myLeaf->GetTypeName());
720  if (myDataType && myDataType->IsA() == TDataType::Class()){
721  dict = TDataType::GetDataType((EDataType)((TDataType*)myDataType)->GetType());
722  contentTypeName = myLeaf->GetTypeName();
723  return 0;
724  }
725  }
726 
727  // leaflist. Can't represent.
728  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 TTreeReaderValueArray:", branch->GetName());
729  TIter iLeaves(branch->GetListOfLeaves());
730  TLeaf* leaf = 0;
731  while ((leaf = (TLeaf*) iLeaves())) {
732  Error("TTreeReaderArrayBase::GetBranchContentDataType()", " %s.%s", branch->GetName(), leaf->GetName());
733  }
734  return 0;
735  }
736  if (dataTypeName) dict = TDictionary::GetDictionary(dataTypeName);
737  if (branch->IsA() == TBranchSTL::Class()){
738  Warning("TTreeReaderArrayBase::GetBranchContentDataType()", "Not able to check type correctness, ignoring check");
739  dict = fDict;
740  return 0;
741  }
742  return dataTypeName;
743  } else if (branch->IsA() == TBranchClones::Class()) {
744  dict = TClonesArray::Class();
745  return "TClonesArray";
746  } else if (branch->IsA() == TBranchRef::Class()) {
747  // Can't represent.
748  Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->GetName());
749  return 0;
750  } else {
751  Error("TTreeReaderArrayBase::GetBranchContentDataType()", "The branch %s is of type %s - something that is not handled yet.", branch->GetName(), branch->IsA()->GetName());
752  return 0;
753  }
754 
755  return 0;
756 }
virtual Int_t GetLen() const
Return the number of effective elements of this leaf.
Definition: TLeaf.cxx:278
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:47
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:37
static TDataType * GetDataType(EDataType type)
Given a EDataType type, get the TDataType* that represents it.
Definition: TDataType.cxx:440
TVirtualCollectionProxy * GetCollectionProxy()
Return the collection proxy describing the branch content, if any.
TString GetTypeName()
Get basic type of typedef, e,g.
Definition: TDataType.cxx:149
Int_t GetOffset() const
Int_t GetID() const
int IsSTLCont(int testAlloc=0) const
type : type name: vector<list<classA,allocator>,allocator> testAlloc: if true, we test allocator...
Definition: TClassEdit.cxx:154
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
Definition: TBranch.cxx:1478
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...
Definition: TTreeReader.h:48
This namespace contains pre-defined functions to be used in conjuction with TExecutor::Map and TExecu...
Definition: StringConv.hxx:21
Ssiz_t Length() const
Definition: TString.h:390
void Fatal(const char *location, const char *msgfmt,...)
const char * Size
Definition: TXMLSetup.cxx:56
virtual EDataType GetType() const =0
Regular expression class.
Definition: TRegexp.h:35
static TDictionary * GetDictionary(const char *name)
Definition: TDictionary.cxx:84
Basic string class.
Definition: TString.h:137
virtual void * GetStart(UInt_t=0)
Definition: TBranchProxy.h:205
EReadStatus ProxyRead()
Try to read the value from the TBranchProxy, returns the status of the read.
int Int_t
Definition: RtypesCore.h:41
TBranch * GetBranch() const
Definition: TLeaf.h:70
Type GetType(const std::string &Name)
Definition: Systematics.cxx:34
const char * Class
Definition: TXMLSetup.cxx:64
Int_t GetSplitLevel() const
Definition: TBranch.h:182
Int_t GetClassSize() const
Definition: TClass.h:383
const Detail::TBranchProxy * GetProxy() const
void SetContentDict(TDictionary *dict)
virtual const char * GetClonesName() const
TBranchElement * GetBranchCount() const
const char * Data() const
Definition: TString.h:349
virtual Bool_t HasPointers() const =0
unsigned char Byte_t
Definition: RtypesCore.h:60
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
TLeaf * GetLeaf()
If we are reading a leaf, return the corresponding TLeaf.
virtual TLeaf * GetLeafCounter(Int_t &countval) const
Return a pointer to the counter of this leaf.
Definition: TLeaf.cxx:167
TTreeReaderValueBase::EReadStatus fReadStatus
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition: TTree.cxx:4868
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:91
virtual const char * GetTypeName() const
Definition: TLeaf.h:81
TObjArray * GetElements() const
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:46
This class defines an abstract interface that must be implemented by all classes that contain diction...
Definition: TDictionary.h:162
TBranch * GetMother() const
Get our top-level parent branch in the tree.
Definition: TBranch.cxx:1551
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.
Definition: TNamed.h:51
void * GetAddress()
Returns the memory address of the object being read.
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
Bool_t IsNull() const
Definition: TString.h:387
void Warning(const char *location, const char *msgfmt,...)
virtual TClass * GetClass() const
TTree * GetTree() const
Definition: TBranch.h:184
virtual TLeaf * GetLeafCount() const
Definition: TLeaf.h:71
A Branch for the case of an object.
void * GetWhere() const
Definition: TBranchProxy.h:200
virtual const char * GetTypeName() const
Return type name of element in the branch.
#define ClassImp(name)
Definition: Rtypes.h:279
TVirtualCollectionProxy * GetCollection()
Definition: TBranchProxy.h:202
virtual TClass * GetValueClass() const =0
virtual Int_t GetLenType() const
Definition: TLeaf.h:75
TClass * GetClass() const
Definition: TClonesArray.h:57
Bool_t IsaPointer() const
Definition: TBranchProxy.h:135
EDataType
Definition: TDataType.h:30
virtual void * At(UInt_t idx)=0
TObjArray * GetListOfLeaves()
Definition: TBranch.h:179
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
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).
Definition: TClass.cxx:2811
TClass * GetClass() const
typedef void((*Func_t)())
An array of clone (identical) objects.
Definition: TClonesArray.h:32
Int_t GetType() const
Proxy around an arbitrary container, which implements basic functionality and iteration.
#define NULL
Definition: Rtypes.h:82
TStreamerElement * GetElement(Int_t id) const
const char * GetBranchContentDataType(TBranch *branch, TString &contentTypeName, TDictionary *&dict) const
Access a branch&#39;s collection content (not the collection itself) through a proxy. ...
virtual void * At(Detail::TBranchProxy *, size_t)=0
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
Base class for all the proxy object.
Definition: TBranchProxy.h:81
TDictionary * GetContentDict() const
A TTree is a list of TBranches.
Definition: TBranch.h:58
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
Definition: TBranch.cxx:1182
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.
virtual UInt_t Size() const =0
Int_t GetArrayLength() const
virtual size_t GetSize(Detail::TBranchProxy *)=0