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