Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TTreeProxyGenerator.cxx
Go to the documentation of this file.
1// @(#)root/treeplayer:$Id$
2// Author: Philippe Canal 06/06/2004
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, 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/*
13 TODO:
14 Have separate names for the wrapper classes in the cases of: [done]
15 clones/non clones
16 split/non split
17 split levels
18
19 Have a solution for passing top+"."+middle to the parents classes [probably done .. need testing]
20
21 Have a solution for the return by references of abstract classes [not done]
22
23 Have object inside ClonesArray properly treated! [done]
24 Why is there 2 TRef proxy classes? [done]
25
26 check why some inheritance are TObjProxy and not TPx_
27
28 Be smart enough to avoid issue about having 2 classes one unrolled and one non unrolled!
29
30 When using in interpreted mode understand why the reloading reloads the calling script and then crashes :(
31
32 TODO check now with Cling: CINT did not properly call the custom operators when doing return fNtrack.
33
34 TODO check with Cling: CINT did not handle fMatrix[2][1] well.
35
36 The user's function in script.h are not exposed by ACLiC.
37
38 Review the method to avoid the useless refreshing of the generated file
39 - for most efficiency it would require a different name for each tree
40*/
41
42#include "TTreeProxyGenerator.h"
43
47
48#include "TList.h"
49
50class TTree;
51class TBranch;
53
54#include "TClass.h"
55#include "TClassEdit.h"
56#include "TClonesArray.h"
57#include "TError.h"
58#include "TROOT.h"
59#include "TObjString.h"
60
61#include "TTreeFormula.h"
62#include "TFormLeafInfo.h"
63
64#include "TBranchElement.h"
65#include "TChain.h"
66#include "TFile.h"
67#include "TFriendElement.h"
68#include "TLeaf.h"
69#include "TLeafC.h"
70#include "TTree.h"
72#include "TStreamerElement.h"
73#include "TSystem.h"
74#include "TLeafObject.h"
76
77#include <cstdarg>
78#include <cstdio>
79
80void Debug(Int_t level, const char *fmt, ...)
81{
82 // Use this function in case an error occurred.
83
84 if (gDebug>=level) {
85 va_list ap;
86 va_start(ap, fmt);
87 ErrorHandler(kInfo, "TTreeProxyGenerator", fmt, ap);
88 va_end(ap);
89 }
90}
91
92namespace {
93
94 bool AreDifferent(const TString& from, const TString& to)
95 {
96 FILE *left = fopen(from.Data(),"r");
97 FILE *right = fopen(to.Data(),"r");
98
99 char leftbuffer[256];
100 char rightbuffer[256];
101
102 char *lvalue,*rvalue;
103
104 bool areEqual = true;
105
106 do {
107 lvalue = fgets(leftbuffer, sizeof(leftbuffer), left);
108 rvalue = fgets(rightbuffer, sizeof(rightbuffer), right);
109
110 if (lvalue&&rvalue) {
111 if (strstr(lvalue,"by ROOT version")) {
112 // skip the comment line with the time and date
113 } else {
114 areEqual = areEqual && (0 == strncmp(lvalue,rvalue,sizeof(leftbuffer)));
115 }
116 }
117 if (lvalue&&!rvalue) areEqual = false;
118 if (rvalue&&!lvalue) areEqual = false;
119
120 } while(areEqual && lvalue && rvalue);
121
122 fclose(left);
123 fclose(right);
124
125 return !areEqual;
126 }
127}
128
129namespace ROOT {
130namespace Internal {
131
134 {
136 int ndim = 0;
137 if (element->InheritsFrom(TStreamerBasicPointer::Class())) {
139 const char *countname = elem->GetCountName();
140 if (countname && strlen(countname)>0) ndim = 1;
141 }
142 ndim += element->GetArrayDim();
143
146 middle = "Cla";
147 } else if (container == TTreeProxyGenerator::kSTL) {
148 middle = "Stl";
149 }
150
151 if (ndim==0) {
152 result = "T";
153 result += middle;
154 result += subtype;
155 result += "Proxy";
156 } else if (ndim==1) {
157 result = "T";
158 result += middle;
159 result += "Array";
160 result += subtype;
161 result += "Proxy";
162 } else {
163 result = "T";
164 result += middle;
165 result += "ArrayProxy<";
166 for(Int_t ind = ndim - 2; ind > 0; --ind) {
167 result += "TMultiArrayType<";
168 }
169 result += "TArrayType<";
170 result += element->GetTypeName();
171 result += ",";
172 result += element->GetMaxIndex(ndim-1);
173 result += "> ";
174 for(Int_t ind = ndim - 2; ind > 0; --ind) {
175 result += ",";
176 result += element->GetMaxIndex(ind);
177 result += "> ";
178 }
179 result += ">";
180 }
181 return result;
182
183 /*
184 if (!strcmp("unsigned int", name))
185 sprintf(line, "%u", *(unsigned int *)buf);
186 else if (!strcmp("int", name))
187 sprintf(line, "%d", *(int *)buf);
188 else if (!strcmp("unsigned long", name))
189 sprintf(line, "%lu", *(unsigned long *)buf);
190 else if (!strcmp("long", name))
191 sprintf(line, "%ld", *(long *)buf);
192 else if (!strcmp("unsigned short", name))
193 sprintf(line, "%hu", *(unsigned short *)buf);
194 else if (!strcmp("short", name))
195 sprintf(line, "%hd", *(short *)buf);
196 else if (!strcmp("unsigned char", name))
197 sprintf(line, "%u", *(unsigned char *)buf);
198 else if (!strcmp("bool", name))
199 sprintf(line, "%u", *(unsigned char *)buf);
200 else if (!strcmp("char", name))
201 sprintf(line, "%d", *(char *)buf);
202 else if (!strcmp("float", name))
203 sprintf(line, "%g", *(float *)buf);
204 else if (!strcmp("double", name))
205 sprintf(line, "%g", *(double *)buf);
206 */
207 }
208
209 ////////////////////////////////////////////////////////////////////////////////
210 /// Constructor.
211
213 const char *script,
214 const char *fileprefix,
215 const char *option, UInt_t maxUnrolling) :
217 fMaxDatamemberType(2),
218 fScript(script),
219 fCutScript(),
220 fPrefix(fileprefix),
221 fHeaderFileName(),
222 fOptions(0),
223 fMaxUnrolling(maxUnrolling),
224 fCurrentListOfTopProxies(&fListOfTopProxies)
225 {
226 ParseOptions();
227
229
230 WriteProxy();
231 }
232
233 ////////////////////////////////////////////////////////////////////////////////
234 /// Constructor.
235
237 const char *script, const char *cutscript,
238 const char *fileprefix,
239 const char *option, UInt_t maxUnrolling) :
241 fMaxDatamemberType(2),
242 fScript(script),
243 fCutScript(cutscript),
244 fPrefix(fileprefix),
245 fHeaderFileName(),
246 fOptions(0),
247 fMaxUnrolling(maxUnrolling),
248 fCurrentListOfTopProxies(&fListOfTopProxies)
249 {
250 ParseOptions();
251
253
254 WriteProxy();
255 }
256
257 ////////////////////////////////////////////////////////////////////////////////
258 /// Return true if we should create a nested class representing this class
259
261 {
262 return cl && (cl->GetState() <= TClass::kEmulated);
263 }
264
265 ////////////////////////////////////////////////////////////////////////////////
266 /// Add a Class Descriptor.
267
270 {
271 if (desc==nullptr) return nullptr;
272
275
276 int count = 0;
277 while (existing) {
278 if (! existing->IsEquivalent( desc ) ) {
279 TString newname = desc->GetRawSymbol();
280 count++;
281 newname += "_";
282 newname += count;
283
284 desc->SetName(newname);
286 } else {
287 // we already have the exact same class
288 delete desc;
289 return existing;
290 }
291 }
293 return desc;
294 }
295
296 ////////////////////////////////////////////////////////////////////////////////
297 /// Add Friend descriptor.
298
300 {
301 if (desc==nullptr) return;
302
305
306 int count = 0;
307 while (existing) {
308 if (! existing->IsEquivalent( desc ) ) {
309 TString newname = desc->GetName();
310 count++;
311 newname += "_";
312 newname += count;
313
314 desc->SetName(newname);
316
317 } else {
318
319 desc->SetDuplicate();
320 break;
321 }
322 }
323
324 // Insure uniqueness of the title also.
325 TString basetitle = desc->GetTitle();
326 TIter next( &fListOfFriends );
327 while ( (existing = (TFriendProxyDescriptor*)next()) ) {
328 if (strcmp(existing->GetTitle(),desc->GetTitle())==0) {
329
331 count++;
332 newtitle += "_";
333 newtitle += count;
334
335 desc->SetTitle(newtitle);
336
337 // Restart of the beginning of the loop.
338 next = &fListOfFriends;
339 }
340 }
341
343 }
344
345 ////////////////////////////////////////////////////////////////////////////////
346 /// Add a forward declaration request.
347
348 void TTreeProxyGenerator::AddForward( const char *classname )
349 {
350 TObject *obj = fListOfForwards.FindObject(classname);
351 if (obj) return;
352
353 if (strstr(classname,"<")!=nullptr) {
354 // this is a template instantiation.
355 // let's ignore it for now
356
357 if (gDebug>=6) Warning("AddForward","Forward declaration of templated class not implemented yet.");
358 } else if (strcmp(classname,"string")==0) {
359 // no need to forward declare string
360 } else {
361 fListOfForwards.Add(new TNamed(classname,Form("class %s;\n",classname)));
362 }
363 return;
364 }
365
366 ////////////////////////////////////////////////////////////////////////////////
367 /// Add a forward declaration request.
368
370 {
371 if (cl) AddForward(cl->GetName());
372 }
373
374 ////////////////////////////////////////////////////////////////////////////////
375 /// Add a forward declaration request.
376
378 {
379 TIter i( &fListOfPragmas );
380 for(TObjString *n = (TObjString*) i(); n; n = (TObjString*)i() ) {
381 if (pragma_text == n->GetString()) {
382 return;
383 }
384 }
385
387
388 }
389
390 ////////////////////////////////////////////////////////////////////////////////
391 /// Add a branch descriptor.
392
394 {
395 if (desc) {
398 if (existing) {
399 Warning("TTreeProxyGenerator","The branch name \"%s\" is duplicated. Only the first instance \n"
400 "\twill be available directly. The other instance(s) might be available via their complete name\n"
401 "\t(including the name of their mother branche's name).",desc->GetName());
402 } else {
404 UInt_t len = strlen(desc->GetTypeName());
406 }
407 }
408 }
409
410 ////////////////////////////////////////////////////////////////////////////////
411 /// Generate an enum for a given type if it is not known in the list of class
412 /// unless the type itself a template.
413
415 {
416 if (!TClassEdit::IsStdClass(clname) && !TClass::GetClass(clname) && gROOT->GetType(clname) == nullptr) {
417
419 if (obj) return;
420
421 // The class does not exist, let's create it if ew can.
422 if (clname[strlen(clname)-1]=='>') {
423 // Template instantiation.
424 fListOfForwards.Add(new TNamed(clname,TString::Format("template <> class %s { public: operator int() { return 0; } };\n", clname).Data()));
425 } else if (isscope) {
426 // a scope
427
428 } else {
429 // Class or enum we know nothing about, let's assume it is an enum.
430 fListOfForwards.Add(new TNamed(clname,TString::Format("enum %s { kDefault_%s };\n", clname, clname).Data()));
431 }
432 }
433 }
434
435 ////////////////////////////////////////////////////////////////////////////////
436 /// Check if the template parameter refers to an enum and/or a missing class (we can't tell those 2 apart unless
437 /// the name as template syntax).
438
440 {
442 UInt_t nest = 0;
443 UInt_t last = 0;
444 //bool istemplate = false; // mark whether the current right most entity is a class template.
445
446 for (UInt_t i = 0; i < len; ++i) {
447 switch (clname[i]) {
448 case ':':
449 if (nest == 0 && clname[i+1] == ':') {
451 AddMissingClassAsEnum(incName.Data(), true);
452 //istemplate = false;
453 }
454 break;
455 case '<':
456 ++nest;
457 if (nest == 1) last = i + 1;
458 break;
459 case '>':
460 if (nest == 0) return; // The name is not well formed, give up.
461 --nest; /* intentional fall through to the next case */
462 case ',':
463 if ((clname[i] == ',' && nest == 1) || (clname[i] == '>' && nest == 0)) {
464 TString incName(clname + last, i - last);
466 if (clname[i] == '>' && nest == 1) incName.Append(">");
467
468 if (isdigit(incName[0])) {
469 // Not a class name, nothing to do.
470 } else {
471 AddMissingClassAsEnum(incName.Data(),false);
472 }
473 last = i + 1;
474 }
475 }
476 }
478 }
479
480 ////////////////////////////////////////////////////////////////////////////////
481 /// Analyze the sub-branch and populate the TTreeProxyGenerator or the topdesc with
482 /// its findings.
483
486 {
487 if (info==nullptr) info = branch->GetInfo();
488
489 TIter branches( branch->GetListOfBranches() );
490
491 return AnalyzeBranches( level, topdesc, branches, info );
492 }
493
494 ////////////////////////////////////////////////////////////////////////////////
495 /// Analyze the list of sub branches of a TBranchElement by looping over
496 /// the streamer elements and create the appropriate class proxies.
497
502 {
503/*
504
505 Find the content class name (GetClassName)
506 Record wether this is a collection or not
507
508 Find the StreamerInfo
509
510 For each streamerelement
511 if element is base
512 if name match, loop over subbranches
513 otherwise loop over current branches
514 else if eleement is object (or pointer to object?)
515 if name match go ahead, loop over subbranches
516 if name does not match. loop over current branches (fix names).
517 else
518 add branch.
519
520*/
521 UInt_t lookedAt = 0;
528 bool skipped = false;
529
530 {
533 if (topdesc && topdesc->IsClones()) {
535 middle = "Cla";
537 containerName = "TClonesArray";
538 } else if (topdesc && topdesc->IsSTL()) {
539 container = kSTL;
540 middle = "Stl";
542 containerName = topdesc->GetContainerName();
543 } else if (!topdesc && branch && branch->GetBranchCount() == branch->GetMother()) {
544 if ( ((TBranchElement*)(branch->GetMother()))->GetType()==3) {
546 middle = "Cla";
548 containerName = "TClonesArray";
549 } else {
550 container = kSTL;
551 middle = "Stl";
553 containerName = branch->GetMother()->GetClassName();
554 }
555 } else if (branch->GetType() == 3) {
557 containerName = "TClonesArray";
558 } else if (branch->GetType() == 4) {
560 containerName = branch->GetMother()->GetSubBranch(branch)->GetClassName();
561 }
562 if (topdesc) {
563 subBranchPrefix = topdesc->GetSubBranchPrefix();
564 } else {
565 TBranchElement *mom = (TBranchElement*)branch->GetMother();
566 subBranchPrefix = mom->GetName();
567 if (subBranchPrefix[subBranchPrefix.Length()-1]=='.') {
568 subBranchPrefix.Remove(subBranchPrefix.Length()-1);
569 } else if (mom->GetType()!=3 && mom->GetType() != 4) {
570 subBranchPrefix = "";
571 }
572 }
573 }
574 TIter elements( info->GetElements() );
575 for( TStreamerElement *element = (TStreamerElement*)elements();
576 element;
577 element = (TStreamerElement*)elements() )
578 {
579 bool isBase = false;
580 bool usedBranch = true;
581 TString prefix;
584
585 if (branch==nullptr) {
586 if (topdesc) {
587 Error("AnalyzeBranches","Ran out of branches when looking in branch %s, class %s",
588 topdesc->GetBranchName(), info->GetName());
589 } else {
590 Error("AnalyzeBranches","Ran out of branches when looking in class %s, element %s",
591 info->GetName(),element->GetName());
592 }
593 return lookedAt;
594 }
595
596 if (info->GetClass()->GetCollectionProxy() && strcmp(element->GetName(),"This")==0) {
597 // Skip the artificial streamer element.
598 continue;
599 }
600
601 if (element->GetType()==-1) {
602 // This is an ignored TObject base class.
603 continue;
604 }
605
606 TString branchname = branch->GetName();
608 {
609 TLeaf *leaf = (TLeaf*)branch->GetListOfLeaves()->At(0);
611 && !(branch->GetType() == 3 || branch->GetType() == 4)) branchEndname = leaf->GetName();
612 else branchEndname = branch->GetName();
613 Int_t pos;
614 pos = branchEndname.Index(".");
615 if (pos!=-1) {
616 if (subBranchPrefix.Length() &&
617 branchEndname.BeginsWith( subBranchPrefix ) ) {
618 // brprefix += topdesc->GetSubBranchPrefix();
619 branchEndname.Remove(0,subBranchPrefix.Length()+1);
620 }
621 }
622 }
623
624 bool ispointer = false;
625 switch(element->GetType()) {
626
627 case TVirtualStreamerInfo::kBool: { proxyTypeName = "T" + middle + "BoolProxy"; break; }
628 case TVirtualStreamerInfo::kChar: { proxyTypeName = "T" + middle + "CharProxy"; break; }
629 case TVirtualStreamerInfo::kShort: { proxyTypeName = "T" + middle + "ShortProxy"; break; }
630 case TVirtualStreamerInfo::kInt: { proxyTypeName = "T" + middle + "IntProxy"; break; }
631 case TVirtualStreamerInfo::kLong: { proxyTypeName = "T" + middle + "LongProxy"; break; }
632 case TVirtualStreamerInfo::kLong64: { proxyTypeName = "T" + middle + "Long64Proxy"; break; }
633 case TVirtualStreamerInfo::kFloat: { proxyTypeName = "T" + middle + "FloatProxy"; break; }
634 case TVirtualStreamerInfo::kFloat16: { proxyTypeName = "T" + middle + "Float16Proxy"; break; }
635 case TVirtualStreamerInfo::kDouble: { proxyTypeName = "T" + middle + "DoubleProxy"; break; }
636 case TVirtualStreamerInfo::kDouble32:{ proxyTypeName = "T" + middle + "Double32Proxy"; break; }
637 case TVirtualStreamerInfo::kUChar: { proxyTypeName = "T" + middle + "UCharProxy"; break; }
638 case TVirtualStreamerInfo::kUShort: { proxyTypeName = "T" + middle + "UShortProxy"; break; }
639 case TVirtualStreamerInfo::kUInt: { proxyTypeName = "T" + middle + "UIntProxy"; break; }
640 case TVirtualStreamerInfo::kULong: { proxyTypeName = "T" + middle + "ULongProxy"; break; }
641 case TVirtualStreamerInfo::kULong64: { proxyTypeName = "T" + middle + "ULong64Proxy"; break; }
642 case TVirtualStreamerInfo::kBits: { proxyTypeName = "T" + middle + "UIntProxy"; break; }
643
645
646 // array of basic types array[8]
663
664 // pointer to an array of basic types array[n]
681
682 // array counter //[n]
683 case TVirtualStreamerInfo::kCounter: { proxyTypeName = "T" + middle + "IntProxy"; break; }
684
685
694 // set as pointers and fall through to the next switches
695 ispointer = true;
704 TClass *cl = element->GetClassPointer();
705 R__ASSERT(cl);
706
707 proxyTypeName = Form("T%sObjProxy<%s >", middle.Data(), cl->GetName());
708 TString cname = cl->GetName();
710 if (cl==TClonesArray::Class()) {
713 containerName = "TClonesArray";
714 } else if (cl->GetCollectionProxy()) {
716 containerName = cl->GetName();
718 if (valueClass) cname = valueClass->GetName();
719 else {
721 proxyTypeName = Form("TStlSimpleProxy<%s >", cl->GetName());
722// AddPragma(Form("#pragma create TClass %s;\n", cl->GetName()));
723 if (!cl->IsLoaded()) AddPragma(Form("#pragma link C++ class %s;\n", cl->GetName()));
724 }
725 }
726
727 TBranch *parent = branch->GetMother()->GetSubBranch(branch);
728 TVirtualStreamerInfo *objInfo = nullptr;
729 if (branch->GetListOfBranches()->GetEntries()) {
730 objInfo = ((TBranchElement*)branch->GetListOfBranches()->At(0))->GetInfo();
731 } else {
732 objInfo = branch->GetInfo();
733 }
734 if (element->IsBase()) {
735 isBase = true;
736 prefix = "base";
737
738 if (cl == TObject::Class() && info->GetClass()->CanIgnoreTObjectStreamer())
739 {
740 continue;
741 }
742
744
745 if (branchEndname == element->GetName()) {
746 // We have a proper node for the base class, recurse
747
748 if (branch->GetListOfBranches()->GetEntries() == 0) {
749 // The branch contains a non-split base class that we are unfolding!
750
751 // See AnalyzeTree for similar code!
753
754 TVirtualStreamerInfo *binfo = branch->GetInfo();
755 if (strcmp(cl->GetName(),binfo->GetName())!=0) {
756 binfo = cl->GetStreamerInfo(); // might be the wrong version
757 }
759 branch->GetName(),
760 isclones, 0 /* unsplit object */,
762
763 TStreamerElement *elem = nullptr;
764
765 TIter next(binfo->GetElements());
766 while( (elem = (TStreamerElement*)next()) ) {
768
769 }
770 if (NeedToEmulate(cl,0)) {
771 proxyTypeName = local_cldesc->GetName();
773 }
774
775 } else {
776
777 Int_t pos = branchname.Last('.');
778 if (pos != -1) {
779 branchname.Remove(pos);
780 }
781 TString local_prefix = topdesc ? topdesc->GetSubBranchPrefix() : parent->GetName();
785 isclones, branch->GetSplitLevel(),
788 }
789 } else {
790 // We do not have a proper node for the base class, we need to loop over
791 // the next branches
792 Int_t pos = branchname.Last('.');
793 if (pos != -1) {
794 branchname.Remove(pos);
795 }
796 TString local_prefix = topdesc ? topdesc->GetSubBranchPrefix() : parent->GetName();
798 if (objInfo == nullptr) {
799 // There is no data in this base class
800 continue;
801 }
802 cl = objInfo->GetClass();
806 isclones, branch->GetSplitLevel(),
808 usedBranch = false;
810 }
811
813 if (added) proxyTypeName = added->GetName();
814
815 } else {
817
818 if (branchEndname == element->GetName()) {
819
820 // We have a proper node for the base class, recurse
821 if (branch->GetListOfBranches()->GetEntries() == 0) {
822 // The branch contains a non-split object that we are unfolding!
823
824 // See AnalyzeTree for similar code!
826
827 TVirtualStreamerInfo *binfo = branch->GetInfo();
828 if (strcmp(cl->GetName(),binfo->GetName())!=0) {
829 binfo = cl->GetStreamerInfo(); // might be the wrong version
830 }
832 branch->GetName(),
833 isclones, 0 /* unsplit object */,
835
836 TStreamerElement *elem = nullptr;
837
838 TIter next(binfo->GetElements());
839 while( (elem = (TStreamerElement*)next()) ) {
841 }
842
843 if (NeedToEmulate(cl,0)) {
844 proxyTypeName = local_cldesc->GetName();
846 }
847
848 } else {
849
851 // We have to guess the version number!
853 objInfo = GetStreamerInfo(branch,branch->GetListOfBranches(),cl);
854 }
856 branch->GetName(),
857 branch->GetName(),
858 isclones, branch->GetSplitLevel(),
861 }
862 } else {
863 // We do not have a proper node for the base class, we need to loop over
864 // the next branches
865 TString local_prefix = topdesc ? topdesc->GetSubBranchPrefix() : parent->GetName();
866 if (local_prefix.Length()) local_prefix += ".";
867 local_prefix += element->GetName();
868 objInfo = branch->GetInfo();
869 Int_t pos = branchname.Last('.');
870 if (pos != -1) {
871 branchname.Remove(pos);
872 }
874 // We have to guess the version number!
877 }
881 isclones, branch->GetSplitLevel(),
883 usedBranch = false;
884 skipped = true;
886 }
887
889 if (added) proxyTypeName = added->GetName();
890
891 }
892
893 AddForward(cl);
894 AddHeader(cl);
895 break;
896 }
897
898 default:
899 Error("AnalyzeBranch",
900 "Unsupported type for %s (%d).",
901 branch->GetName(),element->GetType());
902
903 }
904
905 TString dataMemberName = element->GetName();
906 if (topdesc) {
907 topdesc->AddDescriptor( new TBranchProxyDescriptor( dataMemberName.Data(),
909 } else {
910 dataMemberName.Prepend(prefix);
912 proxyTypeName, branchname, true, skipped ) );
913 }
914
915 if (usedBranch) {
916 branches.Next();
917 ++lookedAt;
918 }
919 }
920 return lookedAt;
921 }
922
923 ////////////////////////////////////////////////////////////////////////////////
924 /// Analyze the leaf and populate the `TTreeProxyGenerator or
925 /// the topdesc with its findings.
926
929 {
930 if (leaf->IsA()==TLeafObject::Class()) {
931 Error("AnalyzeOldLeaf","TLeafObject not supported yet");
932 return 0;
933 }
934
935 TString leafTypeName = leaf->GetTypeName();
936 Int_t pos = leafTypeName.Last('_');
937 if (pos!=-1) leafTypeName.Remove(pos);
938
939 // Int_t len = leaf->GetLen();
940 // TLeaf *leafcount = leaf->GetLeafCount();
941
942 UInt_t dim = 0;
943 std::vector<Int_t> maxDim;
944 //maxDim[0] = maxDim[1] = maxDim[2] = 1;
945
947 TString temp = leaf->GetName();
948 pos = temp.Index("[");
949 if (pos!=-1) {
950 if (pos) temp.Remove(0,pos);
951 dimensions.Append(temp);
952 }
953 temp = leaf->GetTitle();
954 pos = temp.Index("[");
955 if (pos!=-1) {
956 if (pos) temp.Remove(0,pos);
957 dimensions.Append(temp);
958 }
959
960 Int_t dimlen = dimensions.Length();
961
962 if (dimlen) {
963 const char *current = dimensions.Data();
964
965 Int_t index;
967 while (current) {
968 current++;
969 if (current[0] == ']') {
970 maxDim.push_back(-1); // maxDim[dim] = -1; // Loop over all elements;
971 } else {
972 scanindex = sscanf(current,"%d",&index);
973 if (scanindex) {
974 maxDim.push_back(index); // maxDim[dim] = index;
975 } else {
976 maxDim.push_back(-2); // maxDim[dim] = -2; // Index is calculated via a variable.
977 }
978 }
979 dim ++;
980 current = (char*)strstr( current, "[" );
981 }
982
983 }
984 //char *twodim = (char*)strstr(leaf->GetTitle(),"][");
985
986 //if (leafcount) {
987 // len = leafcount->GetMaximum();
988 //}
989 if (dim == 0 && leaf->IsA() == TLeafC::Class()) {
990 // For C style strings.
991 dim = 1;
992 }
993
995 switch (dim) {
996 case 0: {
997 type = "T";
999 type += "Proxy";
1000 break;
1001 }
1002 case 1: {
1003 type = "TArray";
1004 type += leafTypeName;
1005 type += "Proxy";
1006 break;
1007 }
1008 default: {
1009 type = "TArrayProxy<";
1010 for(Int_t ind = dim - 2; ind > 0; --ind) {
1011 type += "TMultiArrayType<";
1012 }
1013 type += "TArrayType<";
1014 type += leaf->GetTypeName();
1015 type += ",";
1016 type += maxDim[dim-1];
1017 type += "> ";
1018 for(Int_t ind = dim - 2; ind > 0; --ind) {
1019 type += ",";
1020 type += maxDim[ind];
1021 type += "> ";
1022 }
1023 type += ">";
1024 break;
1025 }
1026 }
1027
1028 TString branchName = leaf->GetBranch()->GetName();
1029 TString dataMemberName = leaf->GetName();
1030
1031 if (topdesc) {
1032 topdesc->AddDescriptor( new TBranchProxyDescriptor( dataMemberName.Data(),
1033 type,
1034 branchName.Data(),
1035 true, false, true ),
1036 false );
1037 } else {
1039 type,
1040 branchName.Data(),
1041 true, false, true ) );
1042 }
1043
1044 return 0;
1045
1046 }
1047
1048 ////////////////////////////////////////////////////////////////////////////////
1049 /// Analyze the branch and populate the TTreeProxyGenerator or the topdesc with
1050 /// its findings. Sometimes several branch of the mom are also analyzed,
1051 /// the number of such branches is returned (this happens in the case of
1052 /// embedded objects inside an object inside a clones array split more than
1053 /// one level.
1054
1057 {
1059 TString prefix;
1060
1061 TString branchName = branch->GetName();
1062
1063 TObjArray *leaves = branch->GetListOfLeaves();
1064 Int_t nleaves = leaves ? leaves->GetEntriesFast() : 0;
1065
1066 if (nleaves>1) {
1067
1068 // Create a holder
1069 TString type = "unknown";
1071 if (cldesc) {
1072 type = cldesc->GetName();
1073
1074 for(int l=0;l<nleaves;l++) {
1075 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
1077 }
1078 }
1079
1080 TString dataMemberName = branchName;
1081
1082 if (topdesc) {
1083 topdesc->AddDescriptor( new TBranchProxyDescriptor( dataMemberName.Data(),
1084 type,
1085 branchName.Data() ),
1086 false );
1087 } else {
1088 // leafname.Prepend(prefix);
1090 type,
1091 branchName.Data() ) );
1092 }
1093
1094 } else {
1095
1096 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(0);
1098
1099 }
1100
1101
1102 return extraLookedAt;
1103
1104 }
1105
1106 ////////////////////////////////////////////////////////////////////////////////
1107 /// Analyze a TTree and its (potential) friends.
1108
1110 {
1111 TIter next( tree->GetListOfBranches() );
1112 TBranch *branch;
1113 while ( (branch = (TBranch*)next()) ) {
1114 TVirtualStreamerInfo *info = nullptr;
1115 const char *branchname = branch->GetName();
1116 const char *classname = branch->GetClassName();
1117 if (classname && strlen(classname)) {
1118 AddForward( classname );
1119 AddHeader( classname );
1120 }
1121
1123 TClass *cl = TClass::GetClass(classname);
1124 TString type = "unknown";
1125 if (cl) {
1128 if (cl==TClonesArray::Class()) {
1130 containerName = "TClonesArray";
1131 if (branch->IsA()==TBranchElement::Class()) {
1132 const char *cname = ((TBranchElement*)branch)->GetClonesName();
1134 if (ncl) {
1135 cl = ncl;
1136 info = GetStreamerInfo(branch,branch->GetListOfBranches(),cl);
1137 } else {
1138 Error("AnalyzeTree",
1139 "Introspection of TClonesArray in older file not implemented yet.");
1140 }
1141 } else {
1142 TClonesArray **ptr = (TClonesArray**)branch->GetAddress();
1143 TClonesArray *clones = nullptr;
1144 if (ptr==nullptr) {
1145 clones = new TClonesArray;
1146 branch->SetAddress(&clones);
1147 ptr = &clones;
1148 }
1149 branch->GetEntry(0);
1150 TClass *ncl = *ptr ? (*ptr)->GetClass() : nullptr;
1151 if (ncl) {
1152 cl = ncl;
1153 } else {
1154 Error("AnalyzeTree",
1155 "Introspection of TClonesArray for %s failed.",branch->GetName());
1156 }
1157 }
1158 } else if (cl->GetCollectionProxy()) {
1160 containerName = cl->GetName();
1161 if (cl->GetCollectionProxy()->GetValueClass()) {
1162 cl = cl->GetCollectionProxy()->GetValueClass();
1163 } else {
1165 type = Form("TStlSimpleProxy<%s >", cl->GetName());
1166 AddHeader(cl);
1167 if (!cl->IsLoaded()) AddPragma(Form("#pragma link C++ class %s;\n", cl->GetName()));
1169 continue;
1170 }
1171 }
1172 if (cl) {
1173 if (NeedToEmulate(cl,0) || branch->GetListOfBranches()->GetEntries() || branch->GetSplitLevel() || fMaxUnrolling) {
1174 TBranchElement *be = dynamic_cast<TBranchElement*>(branch);
1176 ? be->GetInfo() : cl->GetStreamerInfo(); // the 2nd hand need to be fixed
1178 isclones, branch->GetSplitLevel(),containerName);
1179 info = beinfo;
1180 } else {
1181 type = Form("TObjProxy<%s >",cl->GetName());
1182 }
1183 }
1184 }
1185
1186 if ( branch->GetListOfBranches()->GetEntries() == 0 ) {
1187
1188 if (cl) {
1189 // We have a non-split object!
1190
1191 if (desc) {
1193 TStreamerElement *elem = nullptr;
1194
1195 TIter cnext(cinfo->GetElements());
1196 while( (elem = (TStreamerElement*)cnext()) ) {
1198 }
1199
1200 desc = AddClass(desc);
1201 if (desc) {
1202 type = desc->GetName();
1203
1205
1207 }
1208 } else {
1209 // We have a top level non split.
1211 type,
1212 branch->GetName(),
1213 true, false, false ) );
1214 }
1215 } else {
1216
1217 // We have a top level raw type.
1218 AnalyzeOldBranch(branch, 0, nullptr);
1219 }
1220
1221 } else {
1222
1223 // We have a split object
1224
1225 TIter subnext( branch->GetListOfBranches() );
1226 if (desc) {
1227 AnalyzeBranches(1,desc,dynamic_cast<TBranchElement*>(branch),info);
1228 }
1229 desc = AddClass(desc);
1230 if (desc) {
1231 type = desc->GetName();
1234 }
1235 if ( branchname[strlen(branchname)-1] != '.' ) {
1236 // If there is no dot also include the data member directly
1237
1238 AnalyzeBranches(1,nullptr,dynamic_cast<TBranchElement*>(branch),info);
1239
1240 subnext.Reset();
1241 }
1242
1243 } // if split or non split
1244 }
1245
1246 // Now let's add the TTreeFriend (if any)
1247 if (tree->GetTree()->GetListOfFriends()) {
1249 Int_t count = 0;
1250
1251 TIter nextfriend(tree->GetTree()->GetListOfFriends());
1252 while ((fe = (TFriendElement*)nextfriend())) {
1253 TTree *t = fe->GetTree();
1255 desc = new TFriendProxyDescriptor(t->GetName(), fe->GetName(), count);
1256
1257 AddFriend( desc );
1258
1259 fCurrentListOfTopProxies = desc->GetListOfTopProxies();
1260 AnalyzeTree(t);
1261
1262 count++;
1263 }
1264 }
1266 }
1267
1268 ////////////////////////////////////////////////////////////////////////////////
1269 /// Analyze the element and populate the TTreeProxyGenerator or the topdesc with
1270 /// its findings.
1271
1274 const char *path)
1275 {
1278 TString type;
1279
1280 // TString prefix;
1281 bool isBase = false;
1282 TString cname;
1287 if (topdesc) {
1288 if (topdesc->IsClones()) {
1290 middle = "Cla";
1292 containerName = "TClonesArray";
1293 } else if (topdesc->IsSTL()) {
1294 container = kSTL;
1295 middle = "Stl";
1297 containerName = topdesc->GetContainerName();
1298 }
1299 }
1300
1301 if (!element) return;
1302
1303 if (strcmp(element->GetName(),"This")==0) {
1304 TClass *cl = element->GetClassPointer();
1305 containerName = cl->GetName();
1306 cl = cl->GetCollectionProxy()->GetValueClass();
1307 if (!cl) {
1308 // Skip the artificial streamer element.
1309 return;
1310 }
1311 // else return;
1312
1313 // In case the content is a class, move forward
1314 AddForward(cl);
1315 AddHeader(cl);
1316
1317 if (level<=fMaxUnrolling) {
1318
1319 // See AnalyzeTree for similar code!
1320 // TBranchProxyClassDescriptor *cldesc;
1321 if (cl && cl->CanSplit()) {
1322 // cldesc = new TBranchProxyClassDescriptor(cl->GetName(), cl->GetStreamerInfo(),
1323 // branch->GetName(),
1324 // isclones, 0 /* non-split object */,
1325 // containerName);
1326
1328 TStreamerElement *elem = nullptr;
1329
1330 TString subpath = path;
1331 if (subpath.Length()>0) subpath += ".";
1333
1334 TIter next(info->GetElements());
1335 while( (elem = (TStreamerElement*)next()) ) {
1336 AnalyzeElement(branch, elem, level+1, topdesc, subpath.Data());
1337 }
1338
1339 // TBranchProxyClassDescriptor *added = AddClass(cldesc);
1340 // if (added) type = added->GetName();
1341 }
1342 }
1343 return;
1344 }
1345
1346 if (element->GetType()==-1) {
1347 // This is an ignored TObject base class.
1348 return;
1349 }
1350
1351
1352 // bool ispointer = false;
1353 switch(element->GetType()) {
1354
1355 case TVirtualStreamerInfo::kBool: { type = "T" + middle + "BoolProxy"; break; }
1356 case TVirtualStreamerInfo::kChar: { type = "T" + middle + "CharProxy"; break; }
1357 case TVirtualStreamerInfo::kShort: { type = "T" + middle + "ShortProxy"; break; }
1358 case TVirtualStreamerInfo::kInt: { type = "T" + middle + "IntProxy"; break; }
1359 case TVirtualStreamerInfo::kLong: { type = "T" + middle + "LongProxy"; break; }
1360 case TVirtualStreamerInfo::kLong64: { type = "T" + middle + "Long64Proxy"; break; }
1361 case TVirtualStreamerInfo::kFloat: { type = "T" + middle + "FloatProxy"; break; }
1362 case TVirtualStreamerInfo::kFloat16: { type = "T" + middle + "Float16Proxy"; break; }
1363 case TVirtualStreamerInfo::kDouble: { type = "T" + middle + "DoubleProxy"; break; }
1364 case TVirtualStreamerInfo::kDouble32:{ type = "T" + middle + "Double32Proxy"; break; }
1365 case TVirtualStreamerInfo::kUChar: { type = "T" + middle + "UCharProxy"; break; }
1366 case TVirtualStreamerInfo::kUShort: { type = "T" + middle + "UShortProxy"; break; }
1367 case TVirtualStreamerInfo::kUInt: { type = "T" + middle + "UIntProxy"; break; }
1368 case TVirtualStreamerInfo::kULong: { type = "T" + middle + "ULongProxy"; break; }
1369 case TVirtualStreamerInfo::kULong64: { type = "T" + middle + "ULong64Proxy"; break; }
1370 case TVirtualStreamerInfo::kBits: { type = "T" + middle + "UIntProxy"; break; }
1371
1373
1374 // array of basic types array[8]
1391
1392 // pointer to an array of basic types array[n]
1409
1410 // array counter //[n]
1411 case TVirtualStreamerInfo::kCounter: { type = "T" + middle + "IntProxy"; break; }
1412
1413
1422 // set as pointers and fall through to the next switches
1423 // ispointer = true;
1433 TClass *cl = element->GetClassPointer();
1434 if (cl) {
1435 type = Form("T%sObjProxy<%s >",
1436 middle.Data(),cl->GetName());
1437 cname = cl->GetName();
1438 if (cl==TClonesArray::Class()) {
1440 containerName = "TClonesArray";
1441
1442 Long64_t i = branch->GetTree()->GetReadEntry();
1443 if (i<0) i = 0;
1444 branch->GetEntry(i);
1445
1446 //char *obj = branch->GetObject();
1447
1448 // now need to follow it through to this pointer!
1449
1451
1452 TString fullpath = branch->GetName();
1453 fullpath += ".";
1454 if (path && strlen(path)>0) fullpath.Append(path).Append(".");
1455 fullpath += element->GetName();
1456
1457 TTreeFormula *formula = new TTreeFormula("clones",fullpath,branch->GetTree());
1458
1459 TFormLeafInfo *leafinfo = formula->GetLeafInfo(0);
1460 TLeaf *leaf = formula->GetLeaf(0);
1462
1463 arr = (TClonesArray*)leafinfo->GetLocalValuePointer(leaf,0);
1464
1465 /*
1466 if (ispointer) {
1467 arr = (TClonesArray*)*(void**)(obj+lOffset);
1468 } else {
1469 arr = (TClonesArray*)(obj+lOffset);
1470 }
1471 */
1472 if (arr) cname = arr->GetClass()->GetName();
1473
1474 if (cname.Length()==0) {
1475 Error("AnalyzeTree",
1476 "Introspection of TClonesArray in older file not implemented yet.");
1477 }
1478 delete formula;
1479 } else if (cl->GetCollectionProxy()) {
1481 containerName = cl->GetName();
1482 cl = cl->GetCollectionProxy()->GetValueClass();
1483 }
1484 }
1485 else Error("AnalyzeTree","missing class for %s.",branch->GetName());
1486 if (element->IsA()==TStreamerBase::Class()) {
1487 // prefix = "base";
1488 isBase = true;
1489 }
1490 AddForward(cl);
1491 AddHeader(cl);
1492 break;
1493 }
1494
1495 default:
1496 Error("AnalyzeTree",
1497 "Unsupported type for %s %s %d",
1498 branch->GetName(), element->GetName(), element->GetType());
1499
1500 }
1501
1502 dataMemberName = element->GetName();
1503
1504 if (level<=fMaxUnrolling) {
1505
1506 // See AnalyzeTree for similar code!
1508
1510 if (cl && cl->CanSplit()) {
1512 branch->GetName(),
1513 isclones, 0 /* non-split object */,
1515
1517 TStreamerElement *elem = nullptr;
1518
1519 TString subpath = path;
1520 if (subpath.Length()>0) subpath += ".";
1522
1523 TIter next(info->GetElements());
1524 while( (elem = (TStreamerElement*)next()) ) {
1525 AnalyzeElement(branch, elem, level+1, cldesc, subpath.Data());
1526 }
1527
1529 if (added) type = added->GetName();
1530 }
1531
1532 }
1533
1534 pxDataMemberName = /* prefix + */ dataMemberName;
1535 if (topdesc) {
1536 topdesc->AddDescriptor( new TBranchProxyDescriptor( pxDataMemberName.Data(), type,
1537 dataMemberName.Data(), false),
1538 isBase );
1539 } else {
1540 Error("AnalyzeTree","topdesc should not be null in TTreeProxyGenerator::AnalyzeElement.");
1541 }
1542 }
1543
1544 ////////////////////////////////////////////////////////////////////////////////
1545 /// Parse the options string.
1546
1548 {
1549 TString opt = fOptionStr;
1550
1551 fOptions = 0;
1552 if ( opt.Contains("nohist") ) {
1553 opt.ReplaceAll("nohist","");
1554 fOptions |= kNoHist;
1555 }
1556 }
1557
1558 ////////////////////////////////////////////////////////////////////////////////
1559 /// Add the "pragma C++ class" if needed and return
1560 /// true if it has been added _or_ if it is known to
1561 /// not be needed.
1562 /// (I.e. return false if a container of this class
1563 /// can not have a "pragma C++ class"
1564
1566 {
1567 if (!cl) return false;
1568 if (cl->GetCollectionProxy()) {
1570 if (!valcl) {
1571 if (!cl->IsLoaded()) gen->AddPragma(Form("#pragma link C++ class %s;\n", cl->GetName()));
1572 return true;
1573 } else if (R__AddPragmaForClass(gen, valcl)) {
1574 if (!cl->IsLoaded()) gen->AddPragma(Form("#pragma link C++ class %s;\n", cl->GetName()));
1575 return true;
1576 }
1577 }
1578 if (cl->IsLoaded()) return true;
1579 return false;
1580 }
1581
1582 ////////////////////////////////////////////////////////////////////////////////
1583 /// Add the "pragma C++ class" if needed and return
1584 /// true if it has been added _or_ if it is known to
1585 /// not be needed.
1586 /// (I.e. return false if a container of this class
1587 /// can not have a "pragma C++ class"
1588
1589 static bool R__AddPragmaForClass(TTreeProxyGenerator *gen, const char *classname)
1590 {
1591 return R__AddPragmaForClass( gen, TClass::GetClass(classname) );
1592
1593 }
1594
1595 ////////////////////////////////////////////////////////////////////////////////
1596 /// Check whether the file exist and do something useful if it does
1597
1599 {
1600 if (fScript.Length()==0) {
1601 Error("WriteProxy","No user script has been specified.");
1602 return;
1603 }
1604
1606
1607 TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
1608 incPath.Append(":").Prepend(" ");
1609 incPath.ReplaceAll(" -I",":"); // of form :dir1 :dir2:dir3
1610 while ( incPath.Index(" :") != -1 ) {
1611 incPath.ReplaceAll(" :",":");
1612 }
1613 incPath.Prepend(fileLocation+":.:");
1614
1615 const char *filename = gSystem->Which(incPath,fScript);
1616 if (!filename) {
1617 Error("WriteProxy","Can not find the user's script: %s",fScript.Data());
1618 return;
1619 }
1620 const char *cutfilename = nullptr;
1621 if (fCutScript.Length()) {
1623 incPath.Prepend(fileLocation+":.:");
1625 if (!cutfilename) {
1626 Error("WriteProxy","Can not find the user's cut script: %s",fCutScript.Data());
1627 delete [] filename;
1628 return;
1629 }
1630 }
1631
1633 TString classname = gSystem->BaseName(fPrefix);
1634
1635 // Check if there is already an extension and extract it.
1636 Ssiz_t pos = classname.Last('.');
1637 if (pos != kNPOS) {
1638 classname.Remove(pos);
1639 } else {
1640 fHeaderFileName.Append(".h");
1641 }
1642
1643 // Check to see if the target file exist.
1644 // If they do we will generate the proxy in temporary file and modify the original
1645 // if and only if it is different.
1646
1647 bool updating = false;
1648 if (gSystem->GetPathInfo( fHeaderFileName, nullptr, (Long_t*)nullptr, nullptr, nullptr ) == 0) {
1649 // file already exist
1650 updating = true;
1651 }
1652
1653
1657 treefile = fTree->GetDirectory()->GetFile()->GetName();
1658 else
1659 treefile = "Memory Directory";
1660
1662 Ssiz_t dot_pos = scriptfunc.Last('.');
1663 if (dot_pos == kNPOS) {
1664 Error("WriteProxy","User's script (%s) has no extension! Nothing will be written.",scriptfunc.Data());
1665 delete [] filename;
1666 delete [] cutfilename;
1667 return;
1668 }
1669 scriptfunc.Replace( dot_pos, fScript.Length()-dot_pos, "");
1671 const char * extensions[] = { ".h", ".hh", ".hpp", ".hxx", ".hPP", ".hXX" };
1672
1673 int i;
1674 for (i = 0; i < 6; i++ ) {
1676 possible.Append(extensions[i]);
1677 const char *name = gSystem->Which(incPath,possible);
1678 if (name) {
1680 fListOfHeaders.Add(new TNamed("script",Form("#include \"%s\"\n",
1681 scriptHeader.Data())));
1682 delete [] name;
1683 break;
1684 }
1685 }
1687
1688
1690 if (cutfilename) {
1691 dot_pos = cutscriptfunc.Last('.');
1694
1695 for (i = 0; i < 6; i++ ) {
1697 possible.Append(extensions[i]);
1698 const char *name = gSystem->Which(incPath,possible);
1699 if (name) {
1701 fListOfHeaders.Add(new TNamed("cutscript",Form("#include \"%s\"\n",
1702 cutscriptHeader.Data())));
1703 delete [] name;
1704 break;
1705 }
1706 }
1708 }
1709
1710 FILE *hf;
1711 TString tmpfilename = ".Proxy-";
1712 if (updating) {
1714 } else {
1715 hf = fopen(fHeaderFileName, "w");
1716 }
1717 if (hf == nullptr) {
1718 Error("WriteProxy","Unable to open the file %s for writing.",
1720 delete [] filename;
1721 delete [] cutfilename;
1722 return;
1723 }
1724
1725 TDatime td;
1726 fprintf(hf, "/////////////////////////////////////////////////////////////////////////\n");
1727 fprintf(hf, "// This class has been automatically generated \n");
1728 fprintf(hf, "// (at %s by ROOT version %s)\n",td.AsString(),gROOT->GetVersion());
1729 if (!ischain) {
1730 fprintf(hf,"// from TTree %s/%s\n",fTree->GetName(),fTree->GetTitle());
1731 fprintf(hf,"// found on file: %s\n",treefile.Data());
1732 } else {
1733 fprintf(hf,"// from TChain %s/%s\n",fTree->GetName(),fTree->GetTitle());
1734 }
1735 fprintf(hf, "/////////////////////////////////////////////////////////////////////////\n");
1736 fprintf(hf,"\n");
1737 fprintf(hf,"\n");
1738
1739 fprintf(hf,"#ifndef %s_h\n",classname.Data());
1740 fprintf(hf,"#define %s_h\n",classname.Data());
1741 fprintf(hf,"\n");
1742
1743
1744 // Interface versioning
1745 fprintf(hf,"#define R__BRANCHPROXY_GENERATOR_VERSION 2\n\n");
1746 fprintf(hf,"// ROOT headers needed by the proxy\n");
1747 fprintf(hf,"#include <TROOT.h>\n");
1748 fprintf(hf,"#include <TChain.h>\n");
1749 fprintf(hf,"#include <TFile.h>\n");
1750 fprintf(hf,"#include <TPad.h>\n");
1751 fprintf(hf,"#include <TH1.h>\n");
1752 fprintf(hf,"#include <TSelector.h>\n");
1753 fprintf(hf,"#include <TBranchProxy.h>\n");
1754 fprintf(hf,"#include <TBranchProxyDirector.h>\n");
1755 fprintf(hf,"#include <TBranchProxyTemplate.h>\n");
1756 fprintf(hf,"#include <TFriendProxy.h>\n");
1757 fprintf(hf,"using namespace ROOT::Internal;\n"); // questionable
1758 fprintf(hf,"using ROOT::Detail::TBranchProxy;\n"); // questionable
1759 fprintf(hf,"\n");
1760
1761 fprintf(hf,"// forward declarations needed by this particular proxy\n");
1762 TIter next( &fListOfForwards );
1763 TObject *current;
1764 while ( (current=next()) ) {
1765 if (strstr(current->GetTitle(),"::")==nullptr) {
1766 // We can not forward declared nested classes (well we might be able to do so for
1767 // the one nested in a namespace but it is not clear yet if we can really reliably
1768 // find this information)
1769 fprintf(hf,"%s",current->GetTitle());
1770 }
1771 }
1772
1773 fprintf(hf,"\n\n");
1774 fprintf(hf,"// Header needed by this particular proxy\n");
1775 next = &fListOfHeaders;
1776 TObject *header;
1777 while ( (header = next()) ) {
1778 fprintf(hf,"%s",header->GetTitle());
1779 }
1780 fprintf(hf,"\n\n");
1781
1782 fprintf(hf,"class %s_Interface {\n", scriptfunc.Data());
1783 fprintf(hf," // This class defines the list of methods that are directly used by %s,\n",classname.Data());
1784 fprintf(hf," // and that can be overloaded in the user's script\n");
1785 fprintf(hf,"public:\n");
1786 fprintf(hf," void %s_Begin(TTree*) {}\n",scriptfunc.Data());
1787 fprintf(hf," void %s_SlaveBegin(TTree*) {}\n",scriptfunc.Data());
1788 fprintf(hf," bool %s_Notify() { return true; }\n",scriptfunc.Data());
1789 fprintf(hf," bool %s_Process(Long64_t) { return true; }\n",scriptfunc.Data());
1790 fprintf(hf," void %s_SlaveTerminate() {}\n",scriptfunc.Data());
1791 fprintf(hf," void %s_Terminate() {}\n",scriptfunc.Data());
1792 fprintf(hf,"};\n");
1793 fprintf(hf,"\n\n");
1794
1795 fprintf(hf, "class %s : public TSelector, public %s_Interface {\n", classname.Data(), scriptfunc.Data());
1796 fprintf(hf, "public :\n");
1797 fprintf(hf, " TTree *fChain; ///<!pointer to the analyzed TTree or TChain\n");
1798 fprintf(hf, " TH1 *htemp; ///<!pointer to the histogram\n");
1799 fprintf(hf, " TBranchProxyDirector fDirector; ///<!Manages the proxys\n\n");
1800
1801 fprintf(hf, " // Optional User methods\n");
1802 fprintf(hf, " TClass *fClass; // Pointer to this class's description\n");
1803
1804 if (fListOfClasses.LastIndex()>=0) {
1805 fprintf(hf, "\n // Wrapper class for each unwounded class\n");
1806 next = &fListOfClasses;
1808 while ( (clp = (TBranchProxyClassDescriptor*)next()) ) {
1809 clp->OutputDecl(hf, 3, fMaxDatamemberType);
1810 }
1811 }
1812
1813 if (fListOfFriends.LastIndex()>=0) {
1814 fprintf(hf, "\n // Wrapper class for each friend TTree\n");
1815 next = &fListOfFriends;
1817 while ( (clp = (TFriendProxyDescriptor*)next()) ) {
1818 if (!clp->IsDuplicate()) clp->OutputClassDecl(hf, 3, fMaxDatamemberType);
1819 }
1820 }
1821
1822 fprintf(hf, "\n // Proxy for each of the branches, leaves and friends of the tree\n");
1823 next = &fListOfTopProxies;
1825 while ( (data = (TBranchProxyDescriptor*)next()) ) {
1826 data->OutputDecl(hf, 3, fMaxDatamemberType);
1827 }
1828 if (fListOfFriends.LastIndex()>=0) {
1829 next = &fListOfFriends;
1831 while ( (clp = (TFriendProxyDescriptor*)next()) ) {
1832 clp->OutputDecl(hf, 3, fMaxDatamemberType);
1833 }
1834 }
1835 fprintf(hf,"\n\n");
1836
1837 // Constructor
1838 fprintf(hf, " %s(TTree *tree=0) : \n",classname.Data());
1839 fprintf(hf, " fChain(0)");
1840 fprintf(hf, ",\n htemp(0)");
1841 fprintf(hf, ",\n fDirector(tree,-1)");
1842 fprintf(hf, ",\n fClass (TClass::GetClass(\"%s\"))",classname.Data());
1843 next = &fListOfTopProxies;
1844 while ( (data = (TBranchProxyDescriptor*)next()) ) {
1845 fprintf(hf,",\n %-*s(&fDirector,\"%s\")",
1846 fMaxDatamemberType, data->GetDataName(), data->GetBranchName());
1847 }
1848 next = &fListOfFriends;
1850 while ( (fpd = (TFriendProxyDescriptor*)next()) ) {
1851 fprintf(hf,",\n %-*s(&fDirector,tree,%d)",
1852 fMaxDatamemberType, fpd->GetTitle(), fpd->GetIndex());
1853 }
1854
1855 fprintf(hf, "\n { }\n");
1856
1857 // Other functions.
1858 fprintf(hf," ~%s() override;\n",classname.Data());
1859 fprintf(hf," Int_t Version() const override {return 1;}\n");
1860 fprintf(hf," void Begin(::TTree *tree) override;\n");
1861 fprintf(hf," void SlaveBegin(::TTree *tree) override;\n");
1862 fprintf(hf," void Init(::TTree *tree) override;\n");
1863 fprintf(hf," bool Notify() override;\n");
1864 fprintf(hf," bool Process(Long64_t entry) override;\n");
1865 fprintf(hf," void SlaveTerminate() override;\n");
1866 fprintf(hf," void Terminate() override;\n");
1867 fprintf(hf,"\n");
1868 fprintf(hf," ClassDefOverride(%s,0);\n",classname.Data());
1869 fprintf(hf,"\n\n");
1870
1871 fprintf(hf,"//inject the user's code\n");
1872 fprintf(hf,"#include \"%s\"\n",fScript.Data());
1873
1874 if (cutfilename) {
1875 fprintf(hf,"#include \"%s\"\n",fCutScript.Data());
1876 }
1877
1878 // Close the class.
1879 fprintf(hf,"};\n");
1880 fprintf(hf,"\n");
1881 fprintf(hf,"#endif\n");
1882 fprintf(hf,"\n\n");
1883
1884 fprintf(hf,"#ifdef __ROOTCLING__\n");
1885 if (fListOfClasses.LastIndex()>=0) {
1887 next = &fListOfClasses;
1888 while ( (clp = (TBranchProxyClassDescriptor*)next()) ) {
1889 fprintf(hf,"#pragma link C++ class %s::%s-;\n",classname.Data(),clp->GetName());
1890 if (clp->GetContainerName().Length()) {
1891 R__AddPragmaForClass(this, clp->GetContainerName());
1892 }
1893 }
1894 next = &fListOfPragmas;
1896 while ( (prag = (TObjString*)next()) ) {
1897 fprintf(hf,"%s",prag->String().Data());
1898 }
1899 }
1900 fprintf(hf,"#pragma link C++ class %s;\n",classname.Data());
1901 fprintf(hf,"#endif\n");
1902 fprintf(hf,"\n\n");
1903
1904 // Write the implementations.
1905 fprintf(hf,"inline %s::~%s() {\n",classname.Data(),classname.Data());
1906 fprintf(hf," // destructor. Clean up helpers.\n");
1907 fprintf(hf,"\n");
1908 fprintf(hf,"}\n");
1909 fprintf(hf,"\n");
1910 fprintf(hf,"inline void %s::Init(TTree *tree)\n",classname.Data());
1911 fprintf(hf,"{\n");
1912 fprintf(hf,"// Set branch addresses\n");
1913 fprintf(hf," if (tree == 0) return;\n");
1914 fprintf(hf," fChain = tree;\n");
1915 fprintf(hf," fDirector.SetTree(fChain);\n");
1916 fprintf(hf," if (htemp == 0) {\n");
1917 fprintf(hf," htemp = fDirector.CreateHistogram(GetOption());\n");
1918 if (cutfilename) {
1919 fprintf(hf," htemp->SetTitle(\"%s {%s}\");\n",fScript.Data(),fCutScript.Data());
1920 } else {
1921 fprintf(hf," htemp->SetTitle(\"%s\");\n",fScript.Data());
1922 }
1923 fprintf(hf," fObject = htemp;\n");
1924 fprintf(hf," }\n");
1925 fprintf(hf,"}\n");
1926 fprintf(hf,"\n");
1927 fprintf(hf,"bool %s::Notify()\n",classname.Data());
1928 fprintf(hf,"{\n");
1929 fprintf(hf," // Called when loading a new file.\n");
1930 fprintf(hf," // Get branch pointers.\n");
1931 fprintf(hf," fDirector.SetTree(fChain);\n");
1932 fprintf(hf," %s_Notify();\n",scriptfunc.Data());
1933 fprintf(hf," \n");
1934 fprintf(hf," return true;\n");
1935 fprintf(hf,"}\n");
1936 fprintf(hf," \n");
1937
1938 // generate code for class member function Begin
1939 fprintf(hf,"\n");
1940 fprintf(hf,"inline void %s::Begin(TTree *tree)\n",classname.Data());
1941 fprintf(hf,"{\n");
1942 fprintf(hf," // The Begin() function is called at the start of the query.\n");
1943 fprintf(hf," // The tree argument is deprecated.\n");
1944 fprintf(hf,"\n");
1945 fprintf(hf," TString option = GetOption();\n");
1946 fprintf(hf," %s_Begin(tree);\n",scriptfunc.Data());
1947 fprintf(hf,"\n");
1948 fprintf(hf,"}\n");
1949
1950 // generate code for class member function SlaveBegin
1951 fprintf(hf,"\n");
1952 fprintf(hf,"inline void %s::SlaveBegin(TTree *tree)\n",classname.Data());
1953 fprintf(hf,"{\n");
1954 fprintf(hf," // The SlaveBegin() function is called after the Begin() function.\n");
1955 fprintf(hf," // The tree argument is deprecated.\n");
1956 fprintf(hf,"\n");
1957 fprintf(hf," Init(tree);\n");
1958 fprintf(hf,"\n");
1959 fprintf(hf," %s_SlaveBegin(tree);\n",scriptfunc.Data());
1960 fprintf(hf,"\n");
1961 fprintf(hf,"}\n");
1962 fprintf(hf,"\n");
1963
1964 // generate code for class member function Process
1965 fprintf(hf,"inline bool %s::Process(Long64_t entry)\n",classname.Data());
1966 fprintf(hf,"{\n");
1967
1968 fprintf(hf," // The Process() function is called for each entry in the tree to be processed.\n"
1969 " // The entry argument specifies which entry in the currently loaded tree is to be processed.\n"
1970 " // It can be passed to either TTree::GetEntry() or TBranch::GetEntry()\n"
1971 " // to read either all or the required parts of the data.\n"
1972 " //\n"
1973 " // This function should contain the \"body\" of the analysis. It can contain\n"
1974 " // simple or elaborate selection criteria, run algorithms on the data\n"
1975 " // of the event and typically fill histograms.\n\n");
1976 fprintf(hf," // WARNING when a selector is used with a TChain, you must use\n");
1977 fprintf(hf," // the pointer to the current TTree to call GetEntry(entry).\n");
1978 fprintf(hf," // The entry is always the local entry number in the current tree.\n");
1979 fprintf(hf," // Assuming that fChain is the pointer to the TChain being processed,\n");
1980 fprintf(hf," // use fChain->GetTree()->GetEntry(entry).\n");
1981 fprintf(hf,"\n");
1982 fprintf(hf,"\n");
1983 fprintf(hf," fDirector.SetReadEntry(entry);\n");
1984 if (fOptions & kNoHist) {
1985 if (cutfilename) {
1986 fprintf(hf," if (%s()) %s();\n",cutscriptfunc.Data(),scriptfunc.Data());
1987 } else {
1988 fprintf(hf," %s();\n",scriptfunc.Data());
1989 }
1990 } else {
1991 if (cutfilename) {
1992 fprintf(hf," if (%s()) htemp->Fill(%s());\n",cutscriptfunc.Data(),scriptfunc.Data());
1993 } else {
1994 fprintf(hf," htemp->Fill(%s());\n",scriptfunc.Data());
1995 }
1996 }
1997 fprintf(hf," %s_Process(entry);\n",scriptfunc.Data());
1998 fprintf(hf," return true;\n");
1999 fprintf(hf,"\n");
2000 fprintf(hf,"}\n\n");
2001
2002 // generate code for class member function SlaveTerminate
2003 fprintf(hf,"inline void %s::SlaveTerminate()\n",classname.Data());
2004 fprintf(hf,"{\n");
2005 fprintf(hf," // The SlaveTerminate() function is called after all entries or objects\n"
2006 " // have been processed.");
2007 fprintf(hf,"\n");
2008 fprintf(hf," %s_SlaveTerminate();\n",scriptfunc.Data());
2009 fprintf(hf,"}\n\n");
2010
2011 // generate code for class member function Terminate
2012 fprintf(hf,"inline void %s::Terminate()\n",classname.Data());
2013 fprintf(hf,"{\n");
2014 fprintf(hf," // Function called at the end of the event loop.\n");
2015 fprintf(hf," htemp = (TH1*)fObject;\n");
2016 fprintf(hf," Int_t drawflag = (htemp && htemp->GetEntries()>0);\n");
2017 fprintf(hf," \n");
2018 fprintf(hf," if (gPad && !drawflag && !fOption.Contains(\"goff\") && !fOption.Contains(\"same\")) {\n");
2019 fprintf(hf," gPad->Clear();\n");
2020 fprintf(hf," } else {\n");
2021 fprintf(hf," if (fOption.Contains(\"goff\")) drawflag = false;\n");
2022 fprintf(hf," if (drawflag) htemp->Draw(fOption);\n");
2023 fprintf(hf," }\n");
2024 fprintf(hf," %s_Terminate();\n",scriptfunc.Data());
2025 fprintf(hf,"}\n");
2026
2027 fclose(hf);
2028
2029 if (updating) {
2030 // over-write existing file only if needed.
2034 } else gSystem->Unlink(tmpfilename);
2035 }
2036 delete [] filename;
2037 delete [] cutfilename;
2038 }
2039
2040} // namespace Internal
2041} // namespace ROOT
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:69
constexpr Ssiz_t kNPOS
The equivalent of std::string::npos for the ROOT class TString.
Definition RtypesCore.h:132
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:130
void ErrorHandler(int level, const char *location, const char *fmt, std::va_list va)
General error handler function. It calls the user set error handler.
Definition TError.cxx:111
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
constexpr Int_t kInfo
Definition TError.h:45
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:252
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
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
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char cname
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:142
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:792
#define gROOT
Definition TROOT.h:417
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2571
R__EXTERN TSystem * gSystem
Definition TSystem.h:582
void Debug(Int_t level, const char *fmt,...)
Base class for code generators like TTreeProxyGenerator and TTreeReaderGenerator.
TList fListOfHeaders
List of included headers.
void AddHeader(TClass *cl)
Add a header inclusion request.
TVirtualStreamerInfo * GetStreamerInfo(TBranch *branch, TIter current, TClass *cl)
Return the correct TStreamerInfo of class 'cl' in the list of branches (current) [Assuming these bran...
TVirtualStreamerInfo * GetBaseClass(TStreamerElement *element)
Check if element is a base class and if yes, return the base class.
TTree * fTree
Pointer to the tree.
TString fOptionStr
User options as a string.
TString GetContainedClassName(TBranchElement *branch, TStreamerElement *element, bool ispointer)
Get name of class inside a container.
void AnalyzeTree(TTree *tree)
Analyze a TTree and its (potential) friends.
TBranchProxyClassDescriptor * AddClass(TBranchProxyClassDescriptor *desc)
Add a Class Descriptor.
void AddDescriptor(TBranchProxyDescriptor *desc)
Add a branch descriptor.
void AddPragma(const char *pragma_text)
Add a forward declaration request.
UInt_t AnalyzeOldLeaf(TLeaf *leaf, UInt_t level, TBranchProxyClassDescriptor *topdesc)
Analyze the leaf and populate the `TTreeProxyGenerator or the topdesc with its findings.
UInt_t AnalyzeOldBranch(TBranch *branch, UInt_t level, TBranchProxyClassDescriptor *desc)
Analyze the branch and populate the TTreeProxyGenerator or the topdesc with its findings.
void AnalyzeElement(TBranch *branch, TStreamerElement *element, UInt_t level, TBranchProxyClassDescriptor *desc, const char *path)
Analyze the element and populate the TTreeProxyGenerator or the topdesc with its findings.
TTreeProxyGenerator(TTree *tree, const char *script, const char *fileprefix, const char *option, UInt_t maxUnrolling)
Constructor.
void AddFriend(TFriendProxyDescriptor *desc)
Add Friend descriptor.
void CheckForMissingClass(const char *clname)
Check if the template parameter refers to an enum and/or a missing class (we can't tell those 2 apart...
void ParseOptions()
Parse the options string.
void AddForward(TClass *cl)
Add a forward declaration request.
bool NeedToEmulate(TClass *cl, UInt_t level)
Return true if we should create a nested class representing this class.
void AddMissingClassAsEnum(const char *clname, bool isscope)
Generate an enum for a given type if it is not known in the list of class unless the type itself a te...
UInt_t AnalyzeBranches(UInt_t level, TBranchProxyClassDescriptor *topdesc, TBranchElement *branch, TVirtualStreamerInfo *info=nullptr)
Analyze the sub-branch and populate the TTreeProxyGenerator or the topdesc with its findings.
void WriteProxy()
Check whether the file exist and do something useful if it does.
A Branch for the case of an object.
static TClass * Class()
A TTree is a list of TBranches.
Definition TBranch.h:93
static TClass * Class()
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
Bool_t CanSplit() const
Return true if the data member of this TClass can be saved separately.
Definition TClass.cxx:2331
EState GetState() const
Definition TClass.h:504
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition TClass.cxx:6080
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0, Bool_t isTransient=kFALSE) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist,...
Definition TClass.cxx:4720
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2923
@ kEmulated
Definition TClass.h:128
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition TClass.cxx:2999
An array of clone (identical) objects.
TClass * GetClass() const
static TClass * Class()
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition TDatime.h:37
virtual TFile * GetFile() const
Definition TDirectory.h:221
This class is a small helper class to implement reading a data member on an object stored in a TTree.
A TFriendElement TF describes a TTree object TF in a file.
static TClass * Class()
static TClass * Class()
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition TLeaf.h:57
TObject * FindObject(const char *name) const override
Find an object in this list using its name.
Definition TList.cxx:708
void Add(TObject *obj) override
Definition TList.h:81
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
An array of TObjects.
Definition TObjArray.h:31
Collectable string class.
Definition TObjString.h:28
Mother of all ROOT objects.
Definition TObject.h:42
static TClass * Class()
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:548
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:506
Int_t LastIndex() const
static TClass * Class()
static TClass * Class()
Describe one element (data member) to be Streamed.
Basic string class.
Definition TString.h:137
Ssiz_t Length() const
Definition TString.h:426
const char * Data() const
Definition TString.h:385
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:714
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition TString.cxx:939
TString & Remove(Ssiz_t pos)
Definition TString.h:695
TString & Append(const char *cs)
Definition TString.h:582
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2460
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:642
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:661
virtual FILE * TempFileName(TString &base, const char *dir=nullptr, const char *suffix=nullptr)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition TSystem.cxx:1514
virtual const char * GetIncludePath()
Get the list of include path.
Definition TSystem.cxx:4056
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition TSystem.cxx:1413
virtual int Rename(const char *from, const char *to)
Rename a file.
Definition TSystem.cxx:1365
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition TSystem.cxx:948
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1563
virtual TString GetDirName(const char *pathname)
Return the directory name in pathname.
Definition TSystem.cxx:1046
virtual int Unlink(const char *name)
Unlink, i.e.
Definition TSystem.cxx:1396
Used to pass a selection expression to the Tree drawing routine.
A TTree represents a columnar dataset.
Definition TTree.h:89
TDirectory * GetDirectory() const
Definition TTree.h:517
virtual TObjArray * GetListOfBranches()
Definition TTree.h:583
virtual TTree * GetTree() const
Definition TTree.h:612
virtual TClass * GetValueClass() const =0
If the value type is a user-defined class, return a pointer to the TClass representing the value type...
Abstract Interface class describing Streamer information for one class.
@ kUChar
Equal to TDataType's kchar.
const Int_t n
Definition legend1.C:16
TString GetArrayType(TStreamerElement *element, const char *subtype, TTreeProxyGenerator::EContainer container)
static bool R__AddPragmaForClass(TTreeProxyGenerator *gen, TClass *cl)
Add the "pragma C++ class" if needed and return true if it has been added or if it is known to not be...
bool areEqual(const RULE *r1, const RULE *r2, bool moduloNameOrPattern=false)
bool IsStdClass(const char *type)
return true if the class belongs to the std namespace
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.
TLine l
Definition textangle.C:4