ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TTreePlayer.cxx
Go to the documentation of this file.
1 // @(#)root/treeplayer:$Id$
2 // Author: Rene Brun 12/01/96
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
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 /** \class TTreePlayer
13 
14 Implement some of the functionality of the class TTree requiring access to
15 extra libraries (Histogram, display, etc).
16 */
17 
18 #include <string.h>
19 #include <stdio.h>
20 #include <stdlib.h>
21 
22 #include "Riostream.h"
23 #include "TTreePlayer.h"
24 #include "TROOT.h"
25 #include "TSystem.h"
26 #include "TFile.h"
27 #include "TEventList.h"
28 #include "TEntryList.h"
29 #include "TBranchObject.h"
30 #include "TBranchElement.h"
31 #include "TStreamerInfo.h"
32 #include "TStreamerElement.h"
33 #include "TLeafObject.h"
34 #include "TLeafF.h"
35 #include "TLeafD.h"
36 #include "TLeafC.h"
37 #include "TLeafB.h"
38 #include "TLeafI.h"
39 #include "TLeafS.h"
40 #include "TMath.h"
41 #include "TH2.h"
42 #include "TH3.h"
43 #include "TPolyMarker.h"
44 #include "TPolyMarker3D.h"
45 #include "TText.h"
46 #include "TDirectory.h"
47 #include "TClonesArray.h"
48 #include "TClass.h"
49 #include "TVirtualPad.h"
50 #include "TProfile.h"
51 #include "TProfile2D.h"
52 #include "TTreeFormula.h"
53 #include "TTreeFormulaManager.h"
54 #include "TStyle.h"
55 #include "Foption.h"
56 #include "TTreeResult.h"
57 #include "TTreeRow.h"
58 #include "TPrincipal.h"
59 #include "TChain.h"
60 #include "TChainElement.h"
61 #include "TF1.h"
62 #include "TH1.h"
63 #include "TVirtualFitter.h"
64 #include "TEnv.h"
65 #include "THLimitsFinder.h"
66 #include "TSelectorDraw.h"
67 #include "TSelectorEntries.h"
68 #include "TPluginManager.h"
69 #include "TObjString.h"
70 #include "TTreeProxyGenerator.h"
71 #include "TTreeReaderGenerator.h"
72 #include "TTreeIndex.h"
73 #include "TChainIndex.h"
74 #include "TRefProxy.h"
75 #include "TRefArrayProxy.h"
76 #include "TVirtualMonitoring.h"
77 #include "TTreeCache.h"
78 #include "TStyle.h"
79 
80 #include "HFitInterface.h"
81 #include "Foption.h"
82 #include "Fit/DataVector.h"
83 #include "Fit/UnBinData.h"
84 #include "Math/MinimizerOptions.h"
85 
86 
87 
89 
90 TVirtualFitter *tFitter=0;
91 
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 /// Default Tree constructor.
96 
98 {
99  fTree = 0;
100  fScanFileName = 0;
101  fScanRedirect = kFALSE;
102  fSelectedRows = 0;
103  fDimension = 0;
104  fHistogram = 0;
105  fFormulaList = new TList();
106  fFormulaList->SetOwner(kTRUE);
107  fSelector = new TSelectorDraw();
108  fSelectorFromFile = 0;
109  fSelectorClass = 0;
110  fSelectorUpdate = 0;
111  fInput = new TList();
112  fInput->Add(new TNamed("varexp",""));
113  fInput->Add(new TNamed("selection",""));
114  fSelector->SetInputList(fInput);
115  gROOT->GetListOfCleanups()->Add(this);
118 }
119 
120 ////////////////////////////////////////////////////////////////////////////////
121 /// Tree destructor.
122 
124 {
125  delete fFormulaList;
126  delete fSelector;
128  fInput->Delete();
129  delete fInput;
130  gROOT->GetListOfCleanups()->Remove(this);
131 }
132 
133 ////////////////////////////////////////////////////////////////////////////////
134 /// Build the index for the tree (see TTree::BuildIndex)
135 
136 TVirtualIndex *TTreePlayer::BuildIndex(const TTree *T, const char *majorname, const char *minorname)
137 {
138  TVirtualIndex *index;
139  if (dynamic_cast<const TChain*>(T)) {
140  index = new TChainIndex(T, majorname, minorname);
141  if (index->IsZombie()) {
142  delete index;
143  Error("BuildIndex", "Creating a TChainIndex unsuccessfull - switching to TTreeIndex");
144  }
145  else
146  return index;
147  }
148  return new TTreeIndex(T,majorname,minorname);
149 }
150 
151 ////////////////////////////////////////////////////////////////////////////////
152 /// Copy a Tree with selection, make a clone of this Tree header, then copy the
153 /// selected entries.
154 ///
155 /// - selection is a standard selection expression (see TTreePlayer::Draw)
156 /// - option is reserved for possible future use
157 /// - nentries is the number of entries to process (default is all)
158 /// - first is the first entry to process (default is 0)
159 ///
160 /// IMPORTANT: The copied tree stays connected with this tree until this tree
161 /// is deleted. In particular, any changes in branch addresses
162 /// in this tree are forwarded to the clone trees. Any changes
163 /// made to the branch addresses of the copied trees are over-ridden
164 /// anytime this tree changes its branch addresses.
165 /// Once this tree is deleted, all the addresses of the copied tree
166 /// are reset to their default values.
167 ///
168 /// The following example illustrates how to copy some events from the Tree
169 /// generated in $ROOTSYS/test/Event
170 /// ~~~{.cpp}
171 /// gSystem->Load("libEvent");
172 /// TFile f("Event.root");
173 /// TTree *T = (TTree*)f.Get("T");
174 /// Event *event = new Event();
175 /// T->SetBranchAddress("event",&event);
176 /// TFile f2("Event2.root","recreate");
177 /// TTree *T2 = T->CopyTree("fNtrack<595");
178 /// T2->Write();
179 /// ~~~
180 
181 TTree *TTreePlayer::CopyTree(const char *selection, Option_t *, Long64_t nentries,
182  Long64_t firstentry)
183 {
184 
185  // we make a copy of the tree header
186  TTree *tree = fTree->CloneTree(0);
187  if (tree == 0) return 0;
188 
189  // The clone should not delete any shared i/o buffers.
190  TObjArray* branches = tree->GetListOfBranches();
191  Int_t nb = branches->GetEntriesFast();
192  for (Int_t i = 0; i < nb; ++i) {
193  TBranch* br = (TBranch*) branches->UncheckedAt(i);
194  if (br->InheritsFrom(TBranchElement::Class())) {
195  ((TBranchElement*) br)->ResetDeleteObject();
196  }
197  }
198 
199  Long64_t entry,entryNumber;
200  nentries = GetEntriesToProcess(firstentry, nentries);
201 
202  // Compile selection expression if there is one
203  TTreeFormula *select = 0; // no need to interfere with fSelect since we
204  // handle the loop explicitly below and can call
205  // UpdateFormulaLeaves ourselves.
206  if (strlen(selection)) {
207  select = new TTreeFormula("Selection",selection,fTree);
208  if (!select || !select->GetNdim()) {
209  delete select;
210  delete tree;
211  return 0;
212  }
213  fFormulaList->Add(select);
214  }
215 
216  //loop on the specified entries
217  Int_t tnumber = -1;
218  for (entry=firstentry;entry<firstentry+nentries;entry++) {
219  entryNumber = fTree->GetEntryNumber(entry);
220  if (entryNumber < 0) break;
221  Long64_t localEntry = fTree->LoadTree(entryNumber);
222  if (localEntry < 0) break;
223  if (tnumber != fTree->GetTreeNumber()) {
224  tnumber = fTree->GetTreeNumber();
225  if (select) select->UpdateFormulaLeaves();
226  }
227  if (select) {
228  Int_t ndata = select->GetNdata();
229  Bool_t keep = kFALSE;
230  for(Int_t current = 0; current<ndata && !keep; current++) {
231  keep |= (select->EvalInstance(current) != 0);
232  }
233  if (!keep) continue;
234  }
235  fTree->GetEntry(entryNumber);
236  tree->Fill();
237  }
238  fFormulaList->Clear();
239  return tree;
240 }
241 
242 ////////////////////////////////////////////////////////////////////////////////
243 /// Delete any selector created by this object.
244 /// The selector has been created using TSelector::GetSelector(file)
245 
247 {
249  if (fSelectorClass->IsLoaded()) {
250  delete fSelectorFromFile;
251  }
252  }
253  fSelectorFromFile = 0;
254  fSelectorClass = 0;
255 }
256 
257 ////////////////////////////////////////////////////////////////////////////////
258 /// Draw the result of a C++ script.
259 ///
260 /// The macrofilename and optionally cutfilename are assumed to contain
261 /// at least a method with the same name as the file. The method
262 /// should return a value that can be automatically cast to
263 /// respectively a double and a boolean.
264 ///
265 /// Both methods will be executed in a context such that the
266 /// branch names can be used as C++ variables. This is
267 /// accomplished by generating a TTreeProxy (see MakeProxy)
268 /// and including the files in the proper location.
269 ///
270 /// If the branch name can not be used a proper C++ symbol name,
271 /// it will be modified as follow:
272 /// - white spaces are removed
273 /// - if the leading character is not a letter, an underscore is inserted
274 /// - < and > are replace by underscores
275 /// - * is replaced by st
276 /// - & is replaced by rf
277 ///
278 /// If a cutfilename is specified, for each entry, we execute
279 /// ~~~{.cpp}
280 /// if (cutfilename()) htemp->Fill(macrofilename());
281 /// ~~~
282 /// If no cutfilename is specified, for each entry we execute
283 /// ~~~{.cpp}
284 /// htemp(macrofilename());
285 /// ~~~
286 /// The default for the histogram are the same as for
287 /// TTreePlayer::DrawSelect
288 
289 Long64_t TTreePlayer::DrawScript(const char* wrapperPrefix,
290  const char *macrofilename, const char *cutfilename,
291  Option_t *option, Long64_t nentries, Long64_t firstentry)
292 {
293  if (!macrofilename || strlen(macrofilename)==0) return 0;
294 
295  TString aclicMode;
296  TString arguments;
297  TString io;
298  TString realcutname;
299  if (cutfilename && strlen(cutfilename))
300  realcutname = gSystem->SplitAclicMode(cutfilename, aclicMode, arguments, io);
301 
302  // we ignore the aclicMode for the cutfilename!
303  TString realname = gSystem->SplitAclicMode(macrofilename, aclicMode, arguments, io);
304 
305  TString selname = wrapperPrefix;
306 
307  ROOT::Internal::TTreeProxyGenerator gp(fTree,realname,realcutname,selname,option,3);
308 
309  selname = gp.GetFileName();
310  if (aclicMode.Length()==0) {
311  Warning("DrawScript","TTreeProxy does not work in interpreted mode yet. The script will be compiled.");
312  aclicMode = "+";
313  }
314  selname.Append(aclicMode);
315 
316  Info("DrawScript","%s",Form("Will process tree/chain using %s",selname.Data()));
317  Long64_t result = fTree->Process(selname,option,nentries,firstentry);
318  fTree->SetNotify(0);
319 
320  // could delete the file selname+".h"
321  // However this would remove the optimization of avoiding a useless
322  // recompilation if the user ask for the same thing twice!
323 
324  return result;
325 }
326 
327 ////////////////////////////////////////////////////////////////////////////////
328 /// Draw expression varexp for specified entries that matches the selection.
329 /// Returns -1 in case of error or number of selected events in case of succss.
330 ///
331 /// See the documentation of TTree::Draw for the complete details.
332 
333 Long64_t TTreePlayer::DrawSelect(const char *varexp0, const char *selection, Option_t *option,Long64_t nentries, Long64_t firstentry)
334 {
335  if (fTree->GetEntriesFriend() == 0) return 0;
336 
337  // Let's see if we have a filename as arguments instead of
338  // a TTreeFormula expression.
339 
340  TString possibleFilename = varexp0;
341  Ssiz_t dot_pos = possibleFilename.Last('.');
342  if ( dot_pos != kNPOS
343  && possibleFilename.Index("Alt$")<0 && possibleFilename.Index("Entries$")<0
344  && possibleFilename.Index("Length$")<0 && possibleFilename.Index("Entry$")<0
345  && possibleFilename.Index("LocalEntry$")<0
346  && possibleFilename.Index("Min$")<0 && possibleFilename.Index("Max$")<0
347  && possibleFilename.Index("MinIf$")<0 && possibleFilename.Index("MaxIf$")<0
348  && possibleFilename.Index("Iteration$")<0 && possibleFilename.Index("Sum$")<0
349  && possibleFilename.Index(">")<0 && possibleFilename.Index("<")<0
350  && gSystem->IsFileInIncludePath(possibleFilename.Data())) {
351 
352  if (selection && strlen(selection) && !gSystem->IsFileInIncludePath(selection)) {
353  Error("DrawSelect",
354  "Drawing using a C++ file currently requires that both the expression and the selection are files\n\t\"%s\" is not a file",
355  selection);
356  return 0;
357  }
358  return DrawScript("generatedSel",varexp0,selection,option,nentries,firstentry);
359 
360  } else {
361  possibleFilename = selection;
362  if (possibleFilename.Index("Alt$")<0 && possibleFilename.Index("Entries$")<0
363  && possibleFilename.Index("Length$")<0 && possibleFilename.Index("Entry$")<0
364  && possibleFilename.Index("LocalEntry$")<0
365  && possibleFilename.Index("Min$")<0 && possibleFilename.Index("Max$")<0
366  && possibleFilename.Index("MinIf$")<0 && possibleFilename.Index("MaxIf$")<0
367  && possibleFilename.Index("Iteration$")<0 && possibleFilename.Index("Sum$")<0
368  && possibleFilename.Index(">")<0 && possibleFilename.Index("<")<0
369  && gSystem->IsFileInIncludePath(possibleFilename.Data())) {
370 
371  Error("DrawSelect",
372  "Drawing using a C++ file currently requires that both the expression and the selection are files\n\t\"%s\" is not a file",
373  varexp0);
374  return 0;
375  }
376  }
377 
378  Long64_t oldEstimate = fTree->GetEstimate();
379  TEventList *evlist = fTree->GetEventList();
380  TEntryList *elist = fTree->GetEntryList();
381  if (evlist && elist){
382  elist->SetBit(kCanDelete, kTRUE);
383  }
384  TNamed *cvarexp = (TNamed*)fInput->FindObject("varexp");
385  TNamed *cselection = (TNamed*)fInput->FindObject("selection");
386  if (cvarexp) cvarexp->SetTitle(varexp0);
387  if (cselection) cselection->SetTitle(selection);
388 
389  TString opt = option;
390  opt.ToLower();
391  Bool_t optpara = kFALSE;
392  Bool_t optcandle = kFALSE;
393  Bool_t optgl5d = kFALSE;
394  Bool_t optnorm = kFALSE;
395  if (opt.Contains("norm")) {optnorm = kTRUE; opt.ReplaceAll("norm",""); opt.ReplaceAll(" ","");}
396  if (opt.Contains("para")) optpara = kTRUE;
397  if (opt.Contains("candle")) optcandle = kTRUE;
398  if (opt.Contains("gl5d")) optgl5d = kTRUE;
400  if (optgl5d) {
402  if (!gPad) {
403  if (pgl == kFALSE) gStyle->SetCanvasPreferGL(kTRUE);
404  gROOT->ProcessLineFast("new TCanvas();");
405  }
406  }
407 
408 
409  // Do not process more than fMaxEntryLoop entries
410  if (nentries > fTree->GetMaxEntryLoop()) nentries = fTree->GetMaxEntryLoop();
411 
412  // invoke the selector
413  Long64_t nrows = Process(fSelector,option,nentries,firstentry);
414  fSelectedRows = nrows;
416 
417  //*-* an Event List
418  if (fDimension <= 0) {
419  fTree->SetEstimate(oldEstimate);
420  if (fSelector->GetCleanElist()) {
421  // We are in the case where the input list was reset!
422  fTree->SetEntryList(elist);
423  delete fSelector->GetObject();
424  }
425  return nrows;
426  }
427 
428  // Draw generated histogram
429  Long64_t drawflag = fSelector->GetDrawFlag();
430  Int_t action = fSelector->GetAction();
431  Bool_t draw = kFALSE;
432  if (!drawflag && !opt.Contains("goff")) draw = kTRUE;
433  if (!optcandle && !optpara) fHistogram = (TH1*)fSelector->GetObject();
434  if (optnorm) {
436  if (sumh != 0) fHistogram->Scale(1./sumh);
437  }
438 
439  //if (!nrows && draw && drawflag && !opt.Contains("same")) {
440  // if (gPad) gPad->Clear();
441  // return 0;
442  //}
443  if (drawflag) {
444  if (gPad) {
445  gPad->DrawFrame(-1.,-1.,1.,1.);
446  TText *text_empty = new TText(0.,0.,"Empty");
447  text_empty->SetTextAlign(22);
448  text_empty->SetTextFont(42);
449  text_empty->SetTextSize(0.1);
450  text_empty->SetTextColor(1);
451  text_empty->Draw();
452  } else {
453  Warning("DrawSelect", "The selected TTree subset is empty.");
454  }
455  }
456 
457  //*-*- 1-D distribution
458  if (fDimension == 1) {
460  if (draw) fHistogram->Draw(opt.Data());
461 
462  //*-*- 2-D distribution
463  } else if (fDimension == 2 && !(optpara||optcandle)) {
466  if (action == 4) {
467  if (draw) fHistogram->Draw(opt.Data());
468  } else {
469  Bool_t graph = kFALSE;
470  Int_t l = opt.Length();
471  if (l == 0 || opt == "same") graph = kTRUE;
472  if (opt.Contains("p") || opt.Contains("*") || opt.Contains("l")) graph = kTRUE;
473  if (opt.Contains("surf") || opt.Contains("lego") || opt.Contains("cont")) graph = kFALSE;
474  if (opt.Contains("col") || opt.Contains("hist") || opt.Contains("scat")) graph = kFALSE;
475  if (!graph) {
476  if (draw) fHistogram->Draw(opt.Data());
477  } else {
478  if (fSelector->GetOldHistogram() && draw) fHistogram->Draw(opt.Data());
479  }
480  }
481  //*-*- 3-D distribution
482  } else if (fDimension == 3 && !(optpara||optcandle)) {
486  if (action == 23) {
487  if (draw) fHistogram->Draw(opt.Data());
488  } else if (action == 33) {
489  if (draw) {
490  if (opt.Contains("z")) fHistogram->Draw("func z");
491  else fHistogram->Draw("func");
492  }
493  } else {
494  Int_t noscat = opt.Length();
495  if (opt.Contains("same")) noscat -= 4;
496  if (noscat) {
497  if (draw) fHistogram->Draw(opt.Data());
498  } else {
499  if (fSelector->GetOldHistogram() && draw) fHistogram->Draw(opt.Data());
500  }
501  }
502  //*-*- 4-D distribution
503  } else if (fDimension == 4 && !(optpara||optcandle)) {
507  if (draw) fHistogram->Draw(opt.Data());
508  Int_t ncolors = gStyle->GetNumberOfColors();
509  TObjArray *pms = (TObjArray*)fHistogram->GetListOfFunctions()->FindObject("polymarkers");
510  for (Int_t col=0;col<ncolors;col++) {
511  if (!pms) continue;
513  if (draw) pm3d->Draw();
514  }
515  //*-*- Parallel Coordinates or Candle chart.
516  } else if (optpara || optcandle) {
517  if (draw) {
519  fTree->Draw(">>enlist",selection,"entrylist",nentries,firstentry);
520  TObject *enlist = gDirectory->FindObject("enlist");
521  gROOT->ProcessLine(Form("TParallelCoord::SetEntryList((TParallelCoord*)0x%lx,(TEntryList*)0x%lx)",
522  (ULong_t)para, (ULong_t)enlist));
523  }
524  //*-*- 5d with gl
525  } else if (optgl5d) {
526  gROOT->ProcessLineFast(Form("(new TGL5DDataSet((TTree *)0x%lx))->Draw(\"%s\");", (ULong_t)fTree, opt.Data()));
528  }
529 
531  return fSelectedRows;
532 }
533 
534 ////////////////////////////////////////////////////////////////////////////////
535 /// Fit a projected item(s) from a Tree.
536 /// Returns -1 in case of error or number of selected events in case of success.
537 ///
538 /// The formula is a TF1 expression.
539 ///
540 /// See TTree::Draw for explanations of the other parameters.
541 ///
542 /// By default the temporary histogram created is called htemp.
543 /// If varexp contains >>hnew , the new histogram created is called hnew
544 /// and it is kept in the current directory.
545 /// Example:
546 /// ~~~{.cpp}
547 /// tree.Fit("pol4","sqrt(x)>>hsqrt","y>0")
548 /// will fit sqrt(x) and save the histogram as "hsqrt" in the current
549 /// directory.
550 /// ~~~
551 ///
552 /// The function returns the status of the histogram fit (see TH1::Fit)
553 /// If no entries were selected, the function returns -1;
554 /// (i.e. fitResult is null if the fit is OK)
555 
556 Int_t TTreePlayer::Fit(const char *formula ,const char *varexp, const char *selection,Option_t *option ,Option_t *goption,Long64_t nentries, Long64_t firstentry)
557 {
558  Int_t nch = option ? strlen(option) + 10 : 10;
559  char *opt = new char[nch];
560  if (option) strlcpy(opt,option,nch-1);
561  else strlcpy(opt,"goff",5);
562 
563  Long64_t nsel = DrawSelect(varexp,selection,opt,nentries,firstentry);
564 
565  delete [] opt;
566  Int_t fitResult = -1;
567 
568  if (fHistogram && nsel > 0) {
569  fitResult = fHistogram->Fit(formula,option,goption);
570  }
571  return fitResult;
572 }
573 
574 ////////////////////////////////////////////////////////////////////////////////
575 /// Return the number of entries matching the selection.
576 /// Return -1 in case of errors.
577 ///
578 /// If the selection uses any arrays or containers, we return the number
579 /// of entries where at least one element match the selection.
580 /// GetEntries is implemented using the selector class TSelectorEntries,
581 /// which can be used directly (see code in TTreePlayer::GetEntries) for
582 /// additional option.
583 /// If SetEventList was used on the TTree or TChain, only that subset
584 /// of entries will be considered.
585 
586 Long64_t TTreePlayer::GetEntries(const char *selection)
587 {
588  TSelectorEntries s(selection);
589  fTree->Process(&s);
590  fTree->SetNotify(0);
591  return s.GetSelectedRows();
592 }
593 
594 ////////////////////////////////////////////////////////////////////////////////
595 /// return the number of entries to be processed
596 /// this function checks that nentries is not bigger than the number
597 /// of entries in the Tree or in the associated TEventlist
598 
600 {
601  Long64_t lastentry = firstentry + nentries - 1;
602  if (lastentry > fTree->GetEntriesFriend()-1) {
603  lastentry = fTree->GetEntriesFriend() - 1;
604  nentries = lastentry - firstentry + 1;
605  }
606  //TEventList *elist = fTree->GetEventList();
607  //if (elist && elist->GetN() < nentries) nentries = elist->GetN();
608  TEntryList *elist = fTree->GetEntryList();
609  if (elist && elist->GetN() < nentries) nentries = elist->GetN();
610  return nentries;
611 }
612 
613 ////////////////////////////////////////////////////////////////////////////////
614 /// Return name corresponding to colindex in varexp.
615 ///
616 /// - varexp is a string of names separated by :
617 /// - index is an array with pointers to the start of name[i] in varexp
618 
619 const char *TTreePlayer::GetNameByIndex(TString &varexp, Int_t *index,Int_t colindex)
620 {
621  TTHREAD_TLS_DECL(std::string,column);
622  if (colindex<0 ) return "";
623  Int_t i1,n;
624  i1 = index[colindex] + 1;
625  n = index[colindex+1] - i1;
626  column = varexp(i1,n).Data();
627  // return (const char*)Form((const char*)column);
628  return column.c_str();
629 }
630 
631 ////////////////////////////////////////////////////////////////////////////////
632 /// Return the name of the branch pointer needed by MakeClass/MakeSelector
633 
635 {
636  TLeaf *leafcount = leaf->GetLeafCount();
637  TBranch *branch = leaf->GetBranch();
638 
639  TString branchname( branch->GetName() );
640 
641  if ( branch->GetNleaves() <= 1 ) {
642  if (branch->IsA() != TBranchObject::Class()) {
643  if (!leafcount) {
644  TBranch *mother = branch->GetMother();
645  const char* ltitle = leaf->GetTitle();
646  if (mother && mother!=branch) {
647  branchname = mother->GetName();
648  if (branchname[branchname.Length()-1]!='.') {
649  branchname += ".";
650  }
651  if (strncmp(branchname.Data(),ltitle,branchname.Length())==0) {
652  branchname = "";
653  }
654  } else {
655  branchname = "";
656  }
657  branchname += ltitle;
658  }
659  }
660  }
661  if (replace) {
662  char *bname = (char*)branchname.Data();
663  char *twodim = (char*)strstr(bname,"[");
664  if (twodim) *twodim = 0;
665  while (*bname) {
666  if (*bname == '.') *bname='_';
667  if (*bname == ',') *bname='_';
668  if (*bname == ':') *bname='_';
669  if (*bname == '<') *bname='_';
670  if (*bname == '>') *bname='_';
671  bname++;
672  }
673  }
674  return branchname;
675 }
676 
677 ////////////////////////////////////////////////////////////////////////////////
678 /// Generate skeleton analysis class for this Tree.
679 ///
680 /// The following files are produced: classname.h and classname.C
681 /// If classname is 0, classname will be called "nameoftree.
682 ///
683 /// The generated code in classname.h includes the following:
684 /// - Identification of the original Tree and Input file name
685 /// - Definition of analysis class (data and functions)
686 /// - the following class functions:
687 /// - constructor (connecting by default the Tree file)
688 /// - GetEntry(Long64_t entry)
689 /// - Init(TTree *tree) to initialize a new TTree
690 /// - Show(Long64_t entry) to read and Dump entry
691 ///
692 /// The generated code in classname.C includes only the main
693 /// analysis function Loop.
694 ///
695 /// To use this function:
696 /// - connect your Tree file (eg: TFile f("myfile.root");)
697 /// - T->MakeClass("MyClass");
698 ///
699 /// where T is the name of the Tree in file myfile.root
700 /// and MyClass.h, MyClass.C the name of the files created by this function.
701 /// In a ROOT session, you can do:
702 /// ~~~{.cpp}
703 /// root> .L MyClass.C
704 /// root> MyClass t
705 /// root> t.GetEntry(12); // Fill t data members with entry number 12
706 /// root> t.Show(); // Show values of entry 12
707 /// root> t.Show(16); // Read and show values of entry 16
708 /// root> t.Loop(); // Loop on all entries
709 /// ~~~
710 /// NOTE: Do not use the code generated for one Tree in case of a TChain.
711 /// Maximum dimensions calculated on the basis of one TTree only
712 /// might be too small when processing all the TTrees in one TChain.
713 /// Instead of myTree.MakeClass(.., use myChain.MakeClass(..
714 
715 Int_t TTreePlayer::MakeClass(const char *classname, const char *option)
716 {
717  TString opt = option;
718  opt.ToLower();
719 
720  // Connect output files
721  if (!classname) classname = fTree->GetName();
722 
723  TString thead;
724  thead.Form("%s.h", classname);
725  FILE *fp = fopen(thead, "w");
726  if (!fp) {
727  Error("MakeClass","cannot open output file %s", thead.Data());
728  return 3;
729  }
730  TString tcimp;
731  tcimp.Form("%s.C", classname);
732  FILE *fpc = fopen(tcimp, "w");
733  if (!fpc) {
734  Error("MakeClass","cannot open output file %s", tcimp.Data());
735  fclose(fp);
736  return 3;
737  }
738  TString treefile;
739  if (fTree->GetDirectory() && fTree->GetDirectory()->GetFile()) {
740  treefile = fTree->GetDirectory()->GetFile()->GetName();
741  } else {
742  treefile = "Memory Directory";
743  }
744  // In the case of a chain, the GetDirectory information usually does
745  // pertain to the Chain itself but to the currently loaded tree.
746  // So we can not rely on it.
747  Bool_t ischain = fTree->InheritsFrom(TChain::Class());
748  Bool_t isHbook = fTree->InheritsFrom("THbookTree");
749  if (isHbook)
750  treefile = fTree->GetTitle();
751 
752 //======================Generate classname.h=====================
753  // Print header
754  TObjArray *leaves = fTree->GetListOfLeaves();
755  Int_t nleaves = leaves ? leaves->GetEntriesFast() : 0;
756  TDatime td;
757  fprintf(fp,"//////////////////////////////////////////////////////////\n");
758  fprintf(fp,"// This class has been automatically generated on\n");
759  fprintf(fp,"// %s by ROOT version %s\n",td.AsString(),gROOT->GetVersion());
760  if (!ischain) {
761  fprintf(fp,"// from TTree %s/%s\n",fTree->GetName(),fTree->GetTitle());
762  fprintf(fp,"// found on file: %s\n",treefile.Data());
763  } else {
764  fprintf(fp,"// from TChain %s/%s\n",fTree->GetName(),fTree->GetTitle());
765  }
766  fprintf(fp,"//////////////////////////////////////////////////////////\n");
767  fprintf(fp,"\n");
768  fprintf(fp,"#ifndef %s_h\n",classname);
769  fprintf(fp,"#define %s_h\n",classname);
770  fprintf(fp,"\n");
771  fprintf(fp,"#include <TROOT.h>\n");
772  fprintf(fp,"#include <TChain.h>\n");
773  fprintf(fp,"#include <TFile.h>\n");
774  if (isHbook) fprintf(fp,"#include <THbookFile.h>\n");
775  if (opt.Contains("selector")) fprintf(fp,"#include <TSelector.h>\n");
776 
777  // See if we can add any #include about the user data.
778  Int_t l;
779  fprintf(fp,"\n// Header file for the classes stored in the TTree if any.\n");
780  TList listOfHeaders;
781  listOfHeaders.SetOwner();
782  for (l=0;l<nleaves;l++) {
783  TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
784  TBranch *branch = leaf->GetBranch();
785  TClass *cl = TClass::GetClass(branch->GetClassName());
786  if (cl && cl->IsLoaded() && !listOfHeaders.FindObject(cl->GetName())) {
787  const char *declfile = cl->GetDeclFileName();
788  if (declfile && declfile[0]) {
789  static const char *precstl = "prec_stl/";
790  static const unsigned int precstl_len = strlen(precstl);
791  static const char *rootinclude = "include/";
792  static const unsigned int rootinclude_len = strlen(rootinclude);
793  if (strncmp(declfile,precstl,precstl_len) == 0) {
794  fprintf(fp,"#include <%s>\n",declfile+precstl_len);
795  listOfHeaders.Add(new TNamed(cl->GetName(),declfile+precstl_len));
796  } else if (strncmp(declfile,"/usr/include/",13) == 0) {
797  fprintf(fp,"#include <%s>\n",declfile+strlen("/include/c++/"));
798  listOfHeaders.Add(new TNamed(cl->GetName(),declfile+strlen("/include/c++/")));
799  } else if (strstr(declfile,"/include/c++/") != 0) {
800  fprintf(fp,"#include <%s>\n",declfile+strlen("/include/c++/"));
801  listOfHeaders.Add(new TNamed(cl->GetName(),declfile+strlen("/include/c++/")));
802  } else if (strncmp(declfile,rootinclude,rootinclude_len) == 0) {
803  fprintf(fp,"#include <%s>\n",declfile+rootinclude_len);
804  listOfHeaders.Add(new TNamed(cl->GetName(),declfile+rootinclude_len));
805  } else {
806  fprintf(fp,"#include \"%s\"\n",declfile);
807  listOfHeaders.Add(new TNamed(cl->GetName(),declfile));
808  }
809  }
810  }
811  }
812 
813  // First loop on all leaves to generate dimension declarations
814  Int_t len, lenb;
815  char blen[1024];
816  char *bname;
817  Int_t *leaflen = new Int_t[nleaves];
818  TObjArray *leafs = new TObjArray(nleaves);
819  for (l=0;l<nleaves;l++) {
820  TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
821  leafs->AddAt(new TObjString(leaf->GetName()),l);
822  leaflen[l] = leaf->GetMaximum();
823  }
824  if (ischain) {
825  // In case of a chain, one must find the maximum dimension of each leaf
826  // One must be careful and not assume that all Trees in the chain
827  // have the same leaves and in the same order!
828  TChain *chain = (TChain*)fTree;
829  Int_t ntrees = chain->GetNtrees();
830  for (Int_t file=0;file<ntrees;file++) {
831  Long64_t first = chain->GetTreeOffset()[file];
832  chain->LoadTree(first);
833  for (l=0;l<nleaves;l++) {
834  TObjString *obj = (TObjString*)leafs->At(l);
835  TLeaf *leaf = chain->GetLeaf(obj->GetName());
836  if (leaf) {
837  leaflen[l] = TMath::Max(leaflen[l],leaf->GetMaximum());
838  }
839  }
840  }
841  chain->LoadTree(0);
842  }
843 
844  fprintf(fp,"\n");
845  if (opt.Contains("selector")) {
846  fprintf(fp,"class %s : public TSelector {\n",classname);
847  fprintf(fp,"public :\n");
848  fprintf(fp," TTree *fChain; //!pointer to the analyzed TTree or TChain\n");
849  } else {
850  fprintf(fp,"class %s {\n",classname);
851  fprintf(fp,"public :\n");
852  fprintf(fp," TTree *fChain; //!pointer to the analyzed TTree or TChain\n");
853  fprintf(fp," Int_t fCurrent; //!current Tree number in a TChain\n");
854  }
855 
856  fprintf(fp,"\n// Fixed size dimensions of array or collections stored in the TTree if any.\n");
857  leaves = fTree->GetListOfLeaves();
858  for (l=0;l<nleaves;l++) {
859  TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
860  strlcpy(blen,leaf->GetName(),sizeof(blen));
861  bname = &blen[0];
862  while (*bname) {
863  if (*bname == '.') *bname='_';
864  if (*bname == ',') *bname='_';
865  if (*bname == ':') *bname='_';
866  if (*bname == '<') *bname='_';
867  if (*bname == '>') *bname='_';
868  bname++;
869  }
870  lenb = strlen(blen);
871  if (blen[lenb-1] == '_') {
872  blen[lenb-1] = 0;
873  len = leaflen[l];
874  if (len <= 0) len = 1;
875  fprintf(fp," const Int_t kMax%s = %d;\n",blen,len);
876  }
877  }
878  delete [] leaflen;
879  leafs->Delete();
880  delete leafs;
881 
882 // second loop on all leaves to generate type declarations
883  fprintf(fp,"\n // Declaration of leaf types\n");
884  TLeaf *leafcount;
885  TLeafObject *leafobj;
886  TBranchElement *bre=0;
887  const char *headOK = " ";
888  const char *headcom = " //";
889  const char *head;
890  char branchname[1024];
891  char aprefix[1024];
892  TObjArray branches(100);
893  TObjArray mustInit(100);
894  TObjArray mustInitArr(100);
895  mustInitArr.SetOwner(kFALSE);
896  Int_t *leafStatus = new Int_t[nleaves];
897  for (l=0;l<nleaves;l++) {
898  Int_t kmax = 0;
899  head = headOK;
900  leafStatus[l] = 0;
901  TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
902  len = leaf->GetLen(); if (len<=0) len = 1;
903  leafcount =leaf->GetLeafCount();
904  TBranch *branch = leaf->GetBranch();
905  branchname[0] = 0;
906  strlcpy(branchname,branch->GetName(),sizeof(branchname));
907  strlcpy(aprefix,branch->GetName(),sizeof(aprefix));
908  if (!branches.FindObject(branch)) branches.Add(branch);
909  else leafStatus[l] = 1;
910  if ( branch->GetNleaves() > 1) {
911  // More than one leaf for the branch we need to distinguish them
912  strlcat(branchname,".",sizeof(branchname));
913  strlcat(branchname,leaf->GetTitle(),sizeof(branchname));
914  if (leafcount) {
915  // remove any dimension in title
916  char *dim = (char*)strstr(branchname,"["); if (dim) dim[0] = 0;
917  }
918  } else {
919  strlcpy(branchname,branch->GetName(),sizeof(branchname));
920  }
921  char *twodim = (char*)strstr(leaf->GetTitle(),"][");
922  bname = branchname;
923  while (*bname) {
924  if (*bname == '.') *bname='_';
925  if (*bname == ',') *bname='_';
926  if (*bname == ':') *bname='_';
927  if (*bname == '<') *bname='_';
928  if (*bname == '>') *bname='_';
929  bname++;
930  }
931  if (branch->IsA() == TBranchObject::Class()) {
932  if (branch->GetListOfBranches()->GetEntriesFast()) {leafStatus[l] = 1; continue;}
933  leafobj = (TLeafObject*)leaf;
934  if (!leafobj->GetClass()) {leafStatus[l] = 1; head = headcom;}
935  fprintf(fp,"%s%-15s *%s;\n",head,leafobj->GetTypeName(), leafobj->GetName());
936  if (leafStatus[l] == 0) mustInit.Add(leafobj);
937  continue;
938  }
939  if (leafcount) {
940  len = leafcount->GetMaximum();
941  if (len<=0) len = 1;
942  strlcpy(blen,leafcount->GetName(),sizeof(blen));
943  bname = &blen[0];
944  while (*bname) {
945  if (*bname == '.') *bname='_';
946  if (*bname == ',') *bname='_';
947  if (*bname == ':') *bname='_';
948  if (*bname == '<') *bname='_';
949  if (*bname == '>') *bname='_';
950  bname++;
951  }
952  lenb = strlen(blen);
953  if (blen[lenb-1] == '_') {blen[lenb-1] = 0; kmax = 1;}
954  else snprintf(blen,sizeof(blen),"%d",len);
955  }
956  if (branch->IsA() == TBranchElement::Class()) {
957  bre = (TBranchElement*)branch;
958  if (bre->GetType() != 3 && bre->GetType() != 4
959  && bre->GetStreamerType() <= 0 && bre->GetListOfBranches()->GetEntriesFast()) {
960  leafStatus[l] = 0;
961  }
962  if (bre->GetType() == 3 || bre->GetType() == 4) {
963  fprintf(fp," %-15s %s_;\n","Int_t", branchname);
964  continue;
965  }
966  if (bre->IsBranchFolder()) {
967  fprintf(fp," %-15s *%s;\n",bre->GetClassName(), branchname);
968  mustInit.Add(bre);
969  continue;
970  } else {
971  if (branch->GetListOfBranches()->GetEntriesFast()) {leafStatus[l] = 1;}
972  }
973  if (bre->GetStreamerType() < 0) {
974  if (branch->GetListOfBranches()->GetEntriesFast()) {
975  fprintf(fp,"%s%-15s *%s;\n",headcom,bre->GetClassName(), branchname);
976  } else {
977  fprintf(fp,"%s%-15s *%s;\n",head,bre->GetClassName(), branchname);
978  mustInit.Add(bre);
979  }
980  continue;
981  }
982  if (bre->GetStreamerType() == 0) {
983  if (!TClass::GetClass(bre->GetClassName())->HasInterpreterInfo()) {leafStatus[l] = 1; head = headcom;}
984  fprintf(fp,"%s%-15s *%s;\n",head,bre->GetClassName(), branchname);
985  if (leafStatus[l] == 0) mustInit.Add(bre);
986  continue;
987  }
988  if (bre->GetStreamerType() > 60) {
989  TClass *cle = TClass::GetClass(bre->GetClassName());
990  if (!cle) {leafStatus[l] = 1; continue;}
991  if (bre->GetStreamerType() == 66) leafStatus[l] = 0;
992  char brename[256];
993  strlcpy(brename,bre->GetName(),255);
994  char *bren = brename;
995  char *adot = strrchr(bren,'.');
996  if (adot) bren = adot+1;
997  char *brack = strchr(bren,'[');
998  if (brack) *brack = 0;
1000  if (elem) {
1001  if (elem->IsA() == TStreamerBase::Class()) {leafStatus[l] = 1; continue;}
1002  if (!TClass::GetClass(elem->GetTypeName())) {leafStatus[l] = 1; continue;}
1003  if (!TClass::GetClass(elem->GetTypeName())->HasInterpreterInfo()) {leafStatus[l] = 1; head = headcom;}
1004  if (leafcount) fprintf(fp,"%s%-15s %s[kMax%s];\n",head,elem->GetTypeName(), branchname,blen);
1005  else fprintf(fp,"%s%-15s %s;\n",head,elem->GetTypeName(), branchname);
1006  } else {
1007  if (!TClass::GetClass(bre->GetClassName())->HasInterpreterInfo()) {leafStatus[l] = 1; head = headcom;}
1008  fprintf(fp,"%s%-15s %s;\n",head,bre->GetClassName(), branchname);
1009  }
1010  continue;
1011  }
1012  }
1013  if (strlen(leaf->GetTypeName()) == 0) {leafStatus[l] = 1; continue;}
1014  if (leafcount) {
1015  //len = leafcount->GetMaximum();
1016  //strlcpy(blen,leafcount->GetName(),sizeof(blen));
1017  //bname = &blen[0];
1018  //while (*bname) {if (*bname == '.') *bname='_'; bname++;}
1019  //lenb = strlen(blen);
1020  //Int_t kmax = 0;
1021  //if (blen[lenb-1] == '_') {blen[lenb-1] = 0; kmax = 1;}
1022  //else sprintf(blen,"%d",len);
1023 
1024  const char *stars = " ";
1025  if (bre && bre->GetBranchCount2()) {
1026  stars = "*";
1027  }
1028  // Dimensions can be in the branchname for a split Object with a fix length C array.
1029  // Theses dimensions HAVE TO be placed after the dimension explicited by leafcount
1030  TString dimensions;
1031  char *dimInName = (char*) strstr(branchname,"[");
1032  if ( twodim || dimInName ) {
1033  if (dimInName) {
1034  dimensions = dimInName;
1035  dimInName[0] = 0; // terminate branchname before the array dimensions.
1036  }
1037  if (twodim) dimensions += (char*)(twodim+1);
1038  }
1039  const char* leafcountName = leafcount->GetName();
1040  char b2len[1024];
1041  if (bre && bre->GetBranchCount2()) {
1042  TLeaf * l2 = (TLeaf*)bre->GetBranchCount2()->GetListOfLeaves()->At(0);
1043  strlcpy(b2len,l2->GetName(),sizeof(b2len));
1044  bname = &b2len[0];
1045  while (*bname) {
1046  if (*bname == '.') *bname='_';
1047  if (*bname == ',') *bname='_';
1048  if (*bname == ':') *bname='_';
1049  if (*bname == '<') *bname='_';
1050  if (*bname == '>') *bname='_';
1051  bname++;
1052  }
1053  leafcountName = b2len;
1054  }
1055  if (dimensions.Length()) {
1056  if (kmax) fprintf(fp," %-14s %s%s[kMax%s]%s; //[%s]\n",leaf->GetTypeName(), stars,
1057  branchname,blen,dimensions.Data(),leafcountName);
1058  else fprintf(fp," %-14s %s%s[%d]%s; //[%s]\n",leaf->GetTypeName(), stars,
1059  branchname,len,dimensions.Data(),leafcountName);
1060  } else {
1061  if (kmax) fprintf(fp," %-14s %s%s[kMax%s]; //[%s]\n",leaf->GetTypeName(), stars, branchname,blen,leafcountName);
1062  else fprintf(fp," %-14s %s%s[%d]; //[%s]\n",leaf->GetTypeName(), stars, branchname,len,leafcountName);
1063  }
1064  if (stars[0]=='*') {
1065  TNamed *n;
1066  if (kmax) n = new TNamed(branchname, Form("kMax%s",blen));
1067  else n = new TNamed(branchname, Form("%d",len));
1068  mustInitArr.Add(n);
1069  }
1070  } else {
1071  if (strstr(branchname,"[")) len = 1;
1072  if (len < 2) fprintf(fp," %-15s %s;\n",leaf->GetTypeName(), branchname);
1073  else {
1074  if (twodim) fprintf(fp," %-15s %s%s;\n",leaf->GetTypeName(), branchname,(char*)strstr(leaf->GetTitle(),"["));
1075  else fprintf(fp," %-15s %s[%d];\n",leaf->GetTypeName(), branchname,len);
1076  }
1077  }
1078  }
1079 
1080 // generate list of branches
1081  fprintf(fp,"\n");
1082  fprintf(fp," // List of branches\n");
1083  for (l=0;l<nleaves;l++) {
1084  if (leafStatus[l]) continue;
1085  TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
1086  fprintf(fp," TBranch *b_%s; //!\n",R__GetBranchPointerName(leaf).Data());
1087  }
1088 
1089 // generate class member functions prototypes
1090  if (opt.Contains("selector")) {
1091  fprintf(fp,"\n");
1092  fprintf(fp," %s(TTree * /*tree*/ =0) : fChain(0) { }\n",classname) ;
1093  fprintf(fp," virtual ~%s() { }\n",classname);
1094  fprintf(fp," virtual Int_t Version() const { return 2; }\n");
1095  fprintf(fp," virtual void Begin(TTree *tree);\n");
1096  fprintf(fp," virtual void SlaveBegin(TTree *tree);\n");
1097  fprintf(fp," virtual void Init(TTree *tree);\n");
1098  fprintf(fp," virtual Bool_t Notify();\n");
1099  fprintf(fp," virtual Bool_t Process(Long64_t entry);\n");
1100  fprintf(fp," virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }\n");
1101  fprintf(fp," virtual void SetOption(const char *option) { fOption = option; }\n");
1102  fprintf(fp," virtual void SetObject(TObject *obj) { fObject = obj; }\n");
1103  fprintf(fp," virtual void SetInputList(TList *input) { fInput = input; }\n");
1104  fprintf(fp," virtual TList *GetOutputList() const { return fOutput; }\n");
1105  fprintf(fp," virtual void SlaveTerminate();\n");
1106  fprintf(fp," virtual void Terminate();\n\n");
1107  fprintf(fp," ClassDef(%s,0);\n",classname);
1108  fprintf(fp,"};\n");
1109  fprintf(fp,"\n");
1110  fprintf(fp,"#endif\n");
1111  fprintf(fp,"\n");
1112  } else {
1113  fprintf(fp,"\n");
1114  fprintf(fp," %s(TTree *tree=0);\n",classname);
1115  fprintf(fp," virtual ~%s();\n",classname);
1116  fprintf(fp," virtual Int_t Cut(Long64_t entry);\n");
1117  fprintf(fp," virtual Int_t GetEntry(Long64_t entry);\n");
1118  fprintf(fp," virtual Long64_t LoadTree(Long64_t entry);\n");
1119  fprintf(fp," virtual void Init(TTree *tree);\n");
1120  fprintf(fp," virtual void Loop();\n");
1121  fprintf(fp," virtual Bool_t Notify();\n");
1122  fprintf(fp," virtual void Show(Long64_t entry = -1);\n");
1123  fprintf(fp,"};\n");
1124  fprintf(fp,"\n");
1125  fprintf(fp,"#endif\n");
1126  fprintf(fp,"\n");
1127  }
1128 // generate code for class constructor
1129  fprintf(fp,"#ifdef %s_cxx\n",classname);
1130  if (!opt.Contains("selector")) {
1131  fprintf(fp,"%s::%s(TTree *tree) : fChain(0) \n",classname,classname);
1132  fprintf(fp,"{\n");
1133  fprintf(fp,"// if parameter tree is not specified (or zero), connect the file\n");
1134  fprintf(fp,"// used to generate this class and read the Tree.\n");
1135  fprintf(fp," if (tree == 0) {\n");
1136  if (ischain) {
1137  fprintf(fp,"\n#ifdef SINGLE_TREE\n");
1138  fprintf(fp," // The following code should be used if you want this class to access\n");
1139  fprintf(fp," // a single tree instead of a chain\n");
1140  }
1141  if (isHbook) {
1142  fprintf(fp," THbookFile *f = (THbookFile*)gROOT->GetListOfBrowsables()->FindObject(\"%s\");\n",
1143  treefile.Data());
1144  fprintf(fp," if (!f) {\n");
1145  fprintf(fp," f = new THbookFile(\"%s\");\n",treefile.Data());
1146  fprintf(fp," }\n");
1147  Int_t hid;
1148  sscanf(fTree->GetName(),"h%d",&hid);
1149  fprintf(fp," tree = (TTree*)f->Get(%d);\n\n",hid);
1150  } else {
1151  fprintf(fp," TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(\"%s\");\n",treefile.Data());
1152  fprintf(fp," if (!f || !f->IsOpen()) {\n");
1153  fprintf(fp," f = new TFile(\"%s\");\n",treefile.Data());
1154  fprintf(fp," }\n");
1155  if (fTree->GetDirectory() != fTree->GetCurrentFile()) {
1156  fprintf(fp," TDirectory * dir = (TDirectory*)f->Get(\"%s\");\n",fTree->GetDirectory()->GetPath());
1157  fprintf(fp," dir->GetObject(\"%s\",tree);\n\n",fTree->GetName());
1158  } else {
1159  fprintf(fp," f->GetObject(\"%s\",tree);\n\n",fTree->GetName());
1160  }
1161  }
1162  if (ischain) {
1163  fprintf(fp,"#else // SINGLE_TREE\n\n");
1164  fprintf(fp," // The following code should be used if you want this class to access a chain\n");
1165  fprintf(fp," // of trees.\n");
1166  fprintf(fp," TChain * chain = new TChain(\"%s\",\"%s\");\n",
1167  fTree->GetName(),fTree->GetTitle());
1168  {
1170  TIter next(((TChain*)fTree)->GetListOfFiles());
1171  TChainElement *element;
1172  while ((element = (TChainElement*)next())) {
1173  fprintf(fp," chain->Add(\"%s/%s\");\n",element->GetTitle(),element->GetName());
1174  }
1175  }
1176  fprintf(fp," tree = chain;\n");
1177  fprintf(fp,"#endif // SINGLE_TREE\n\n");
1178  }
1179  fprintf(fp," }\n");
1180  fprintf(fp," Init(tree);\n");
1181  fprintf(fp,"}\n");
1182  fprintf(fp,"\n");
1183  }
1184 
1185 // generate code for class destructor()
1186  if (!opt.Contains("selector")) {
1187  fprintf(fp,"%s::~%s()\n",classname,classname);
1188  fprintf(fp,"{\n");
1189  fprintf(fp," if (!fChain) return;\n");
1190  if (isHbook) {
1191  //fprintf(fp," delete fChain->GetCurrentFile();\n");
1192  } else {
1193  fprintf(fp," delete fChain->GetCurrentFile();\n");
1194  }
1195  fprintf(fp,"}\n");
1196  fprintf(fp,"\n");
1197  }
1198 // generate code for class member function GetEntry()
1199  if (!opt.Contains("selector")) {
1200  fprintf(fp,"Int_t %s::GetEntry(Long64_t entry)\n",classname);
1201  fprintf(fp,"{\n");
1202  fprintf(fp,"// Read contents of entry.\n");
1203 
1204  fprintf(fp," if (!fChain) return 0;\n");
1205  fprintf(fp," return fChain->GetEntry(entry);\n");
1206  fprintf(fp,"}\n");
1207  }
1208 // generate code for class member function LoadTree()
1209  if (!opt.Contains("selector")) {
1210  fprintf(fp,"Long64_t %s::LoadTree(Long64_t entry)\n",classname);
1211  fprintf(fp,"{\n");
1212  fprintf(fp,"// Set the environment to read one entry\n");
1213  fprintf(fp," if (!fChain) return -5;\n");
1214  fprintf(fp," Long64_t centry = fChain->LoadTree(entry);\n");
1215  fprintf(fp," if (centry < 0) return centry;\n");
1216  fprintf(fp," if (fChain->GetTreeNumber() != fCurrent) {\n");
1217  fprintf(fp," fCurrent = fChain->GetTreeNumber();\n");
1218  fprintf(fp," Notify();\n");
1219  fprintf(fp," }\n");
1220  fprintf(fp," return centry;\n");
1221  fprintf(fp,"}\n");
1222  fprintf(fp,"\n");
1223  }
1224 
1225 // generate code for class member function Init(), first pass = get branch pointer
1226  fprintf(fp,"void %s::Init(TTree *tree)\n",classname);
1227  fprintf(fp,"{\n");
1228  fprintf(fp," // The Init() function is called when the selector needs to initialize\n"
1229  " // a new tree or chain. Typically here the branch addresses and branch\n"
1230  " // pointers of the tree will be set.\n"
1231  " // It is normally not necessary to make changes to the generated\n"
1232  " // code, but the routine can be extended by the user if needed.\n"
1233  " // Init() will be called many times when running on PROOF\n"
1234  " // (once per file to be processed).\n\n");
1235  if (mustInit.Last()) {
1236  TIter next(&mustInit);
1237  TObject *obj;
1238  fprintf(fp," // Set object pointer\n");
1239  while( (obj = next()) ) {
1240  if (obj->InheritsFrom(TBranch::Class())) {
1241  strlcpy(branchname,((TBranch*)obj)->GetName(),sizeof(branchname));
1242  } else if (obj->InheritsFrom(TLeaf::Class())) {
1243  strlcpy(branchname,((TLeaf*)obj)->GetName(),sizeof(branchname));
1244  }
1245  branchname[1023]=0;
1246  bname = branchname;
1247  while (*bname) {
1248  if (*bname == '.') *bname='_';
1249  if (*bname == ',') *bname='_';
1250  if (*bname == ':') *bname='_';
1251  if (*bname == '<') *bname='_';
1252  if (*bname == '>') *bname='_';
1253  bname++;
1254  }
1255  fprintf(fp," %s = 0;\n",branchname );
1256  }
1257  }
1258  if (mustInitArr.Last()) {
1259  TIter next(&mustInitArr);
1260  TNamed *info;
1261  fprintf(fp," // Set array pointer\n");
1262  while( (info = (TNamed*)next()) ) {
1263  fprintf(fp," for(int i=0; i<%s; ++i) %s[i] = 0;\n",info->GetTitle(),info->GetName());
1264  }
1265  fprintf(fp,"\n");
1266  }
1267  fprintf(fp," // Set branch addresses and branch pointers\n");
1268  fprintf(fp," if (!tree) return;\n");
1269  fprintf(fp," fChain = tree;\n");
1270  if (!opt.Contains("selector")) fprintf(fp," fCurrent = -1;\n");
1271  fprintf(fp," fChain->SetMakeClass(1);\n");
1272  fprintf(fp,"\n");
1273  for (l=0;l<nleaves;l++) {
1274  if (leafStatus[l]) continue;
1275  TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
1276  len = leaf->GetLen();
1277  leafcount =leaf->GetLeafCount();
1278  TBranch *branch = leaf->GetBranch();
1279  strlcpy(aprefix,branch->GetName(),sizeof(aprefix));
1280 
1281  if ( branch->GetNleaves() > 1) {
1282  // More than one leaf for the branch we need to distinguish them
1283  strlcpy(branchname,branch->GetName(),sizeof(branchname));
1284  strlcat(branchname,".",sizeof(branchname));
1285  strlcat(branchname,leaf->GetTitle(),sizeof(branchname));
1286  if (leafcount) {
1287  // remove any dimension in title
1288  char *dim = (char*)strstr(branchname,"["); if (dim) dim[0] = 0;
1289  }
1290  } else {
1291  strlcpy(branchname,branch->GetName(),sizeof(branchname));
1292  if (branch->IsA() == TBranchElement::Class()) {
1293  bre = (TBranchElement*)branch;
1294  if (bre->GetType() == 3 || bre->GetType()==4) strlcat(branchname,"_",sizeof(branchname));
1295  }
1296  }
1297  bname = branchname;
1298  char *brak = strstr(branchname,"["); if (brak) *brak = 0;
1299  char *twodim = (char*)strstr(bname,"["); if (twodim) *twodim = 0;
1300  while (*bname) {
1301  if (*bname == '.') *bname='_';
1302  if (*bname == ',') *bname='_';
1303  if (*bname == ':') *bname='_';
1304  if (*bname == '<') *bname='_';
1305  if (*bname == '>') *bname='_';
1306  bname++;
1307  }
1308  const char *maybedisable = "";
1309  if (branch != fTree->GetBranch(branch->GetName())) {
1310  Error("MakeClass","The branch named %s (full path name: %s) is hidden by another branch of the same name and its data will not be loaded.",branch->GetName(),R__GetBranchPointerName(leaf,kFALSE).Data());
1311  maybedisable = "// ";
1312  }
1313  if (branch->IsA() == TBranchObject::Class()) {
1314  if (branch->GetListOfBranches()->GetEntriesFast()) {
1315  fprintf(fp,"%s fChain->SetBranchAddress(\"%s\",(void*)-1,&b_%s);\n",maybedisable,branch->GetName(),R__GetBranchPointerName(leaf).Data());
1316  continue;
1317  }
1318  strlcpy(branchname,branch->GetName(),sizeof(branchname));
1319  }
1320  if (branch->IsA() == TBranchElement::Class()) {
1321  if (((TBranchElement*)branch)->GetType() == 3) len =1;
1322  if (((TBranchElement*)branch)->GetType() == 4) len =1;
1323  }
1324  if (leafcount) len = leafcount->GetMaximum()+1;
1325  if (len > 1) fprintf(fp,"%s fChain->SetBranchAddress(\"%s\", %s, &b_%s);\n",
1326  maybedisable,branch->GetName(), branchname, R__GetBranchPointerName(leaf).Data());
1327  else fprintf(fp,"%s fChain->SetBranchAddress(\"%s\", &%s, &b_%s);\n",
1328  maybedisable,branch->GetName(), branchname, R__GetBranchPointerName(leaf).Data());
1329  }
1330  //must call Notify in case of MakeClass
1331  if (!opt.Contains("selector")) {
1332  fprintf(fp," Notify();\n");
1333  }
1334 
1335  fprintf(fp,"}\n");
1336  fprintf(fp,"\n");
1337 
1338 // generate code for class member function Notify()
1339  fprintf(fp,"Bool_t %s::Notify()\n",classname);
1340  fprintf(fp,"{\n");
1341  fprintf(fp," // The Notify() function is called when a new file is opened. This\n"
1342  " // can be either for a new TTree in a TChain or when when a new TTree\n"
1343  " // is started when using PROOF. It is normally not necessary to make changes\n"
1344  " // to the generated code, but the routine can be extended by the\n"
1345  " // user if needed. The return value is currently not used.\n\n");
1346  fprintf(fp," return kTRUE;\n");
1347  fprintf(fp,"}\n");
1348  fprintf(fp,"\n");
1349 
1350 // generate code for class member function Show()
1351  if (!opt.Contains("selector")) {
1352  fprintf(fp,"void %s::Show(Long64_t entry)\n",classname);
1353  fprintf(fp,"{\n");
1354  fprintf(fp,"// Print contents of entry.\n");
1355  fprintf(fp,"// If entry is not specified, print current entry\n");
1356 
1357  fprintf(fp," if (!fChain) return;\n");
1358  fprintf(fp," fChain->Show(entry);\n");
1359  fprintf(fp,"}\n");
1360  }
1361 // generate code for class member function Cut()
1362  if (!opt.Contains("selector")) {
1363  fprintf(fp,"Int_t %s::Cut(Long64_t entry)\n",classname);
1364  fprintf(fp,"{\n");
1365  fprintf(fp,"// This function may be called from Loop.\n");
1366  fprintf(fp,"// returns 1 if entry is accepted.\n");
1367  fprintf(fp,"// returns -1 otherwise.\n");
1368 
1369  fprintf(fp," return 1;\n");
1370  fprintf(fp,"}\n");
1371  }
1372  fprintf(fp,"#endif // #ifdef %s_cxx\n",classname);
1373 
1374 //======================Generate classname.C=====================
1375  if (!opt.Contains("selector")) {
1376  // generate code for class member function Loop()
1377  fprintf(fpc,"#define %s_cxx\n",classname);
1378  fprintf(fpc,"#include \"%s\"\n",thead.Data());
1379  fprintf(fpc,"#include <TH2.h>\n");
1380  fprintf(fpc,"#include <TStyle.h>\n");
1381  fprintf(fpc,"#include <TCanvas.h>\n");
1382  fprintf(fpc,"\n");
1383  fprintf(fpc,"void %s::Loop()\n",classname);
1384  fprintf(fpc,"{\n");
1385  fprintf(fpc,"// In a ROOT session, you can do:\n");
1386  fprintf(fpc,"// root> .L %s.C\n",classname);
1387  fprintf(fpc,"// root> %s t\n",classname);
1388  fprintf(fpc,"// root> t.GetEntry(12); // Fill t data members with entry number 12\n");
1389  fprintf(fpc,"// root> t.Show(); // Show values of entry 12\n");
1390  fprintf(fpc,"// root> t.Show(16); // Read and show values of entry 16\n");
1391  fprintf(fpc,"// root> t.Loop(); // Loop on all entries\n");
1392  fprintf(fpc,"//\n");
1393  fprintf(fpc,"\n// This is the loop skeleton where:\n");
1394  fprintf(fpc,"// jentry is the global entry number in the chain\n");
1395  fprintf(fpc,"// ientry is the entry number in the current Tree\n");
1396  fprintf(fpc,"// Note that the argument to GetEntry must be:\n");
1397  fprintf(fpc,"// jentry for TChain::GetEntry\n");
1398  fprintf(fpc,"// ientry for TTree::GetEntry and TBranch::GetEntry\n");
1399  fprintf(fpc,"//\n");
1400  fprintf(fpc,"// To read only selected branches, Insert statements like:\n");
1401  fprintf(fpc,"// METHOD1:\n");
1402  fprintf(fpc,"// fChain->SetBranchStatus(\"*\",0); // disable all branches\n");
1403  fprintf(fpc,"// fChain->SetBranchStatus(\"branchname\",1); // activate branchname\n");
1404  fprintf(fpc,"// METHOD2: replace line\n");
1405  fprintf(fpc,"// fChain->GetEntry(jentry); //read all branches\n");
1406  fprintf(fpc,"//by b_branchname->GetEntry(ientry); //read only this branch\n");
1407  fprintf(fpc," if (fChain == 0) return;\n");
1408  fprintf(fpc,"\n Long64_t nentries = fChain->GetEntriesFast();\n");
1409  fprintf(fpc,"\n Long64_t nbytes = 0, nb = 0;\n");
1410  fprintf(fpc," for (Long64_t jentry=0; jentry<nentries;jentry++) {\n");
1411  fprintf(fpc," Long64_t ientry = LoadTree(jentry);\n");
1412  fprintf(fpc," if (ientry < 0) break;\n");
1413  fprintf(fpc," nb = fChain->GetEntry(jentry); nbytes += nb;\n");
1414  fprintf(fpc," // if (Cut(ientry) < 0) continue;\n");
1415  fprintf(fpc," }\n");
1416  fprintf(fpc,"}\n");
1417  }
1418  if (opt.Contains("selector")) {
1419  // generate usage comments and list of includes
1420  fprintf(fpc,"#define %s_cxx\n",classname);
1421  fprintf(fpc,"// The class definition in %s.h has been generated automatically\n",classname);
1422  fprintf(fpc,"// by the ROOT utility TTree::MakeSelector(). This class is derived\n");
1423  fprintf(fpc,"// from the ROOT class TSelector. For more information on the TSelector\n"
1424  "// framework see $ROOTSYS/README/README.SELECTOR or the ROOT User Manual.\n\n");
1425  fprintf(fpc,"// The following methods are defined in this file:\n");
1426  fprintf(fpc,"// Begin(): called every time a loop on the tree starts,\n");
1427  fprintf(fpc,"// a convenient place to create your histograms.\n");
1428  fprintf(fpc,"// SlaveBegin(): called after Begin(), when on PROOF called only on the\n"
1429  "// slave servers.\n");
1430  fprintf(fpc,"// Process(): called for each event, in this function you decide what\n");
1431  fprintf(fpc,"// to read and fill your histograms.\n");
1432  fprintf(fpc,"// SlaveTerminate: called at the end of the loop on the tree, when on PROOF\n"
1433  "// called only on the slave servers.\n");
1434  fprintf(fpc,"// Terminate(): called at the end of the loop on the tree,\n");
1435  fprintf(fpc,"// a convenient place to draw/fit your histograms.\n");
1436  fprintf(fpc,"//\n");
1437  fprintf(fpc,"// To use this file, try the following session on your Tree T:\n");
1438  fprintf(fpc,"//\n");
1439  fprintf(fpc,"// root> T->Process(\"%s.C\")\n",classname);
1440  fprintf(fpc,"// root> T->Process(\"%s.C\",\"some options\")\n",classname);
1441  fprintf(fpc,"// root> T->Process(\"%s.C+\")\n",classname);
1442  fprintf(fpc,"//\n\n");
1443  fprintf(fpc,"#include \"%s\"\n",thead.Data());
1444  fprintf(fpc,"#include <TH2.h>\n");
1445  fprintf(fpc,"#include <TStyle.h>\n");
1446  fprintf(fpc,"\n");
1447  // generate code for class member function Begin
1448  fprintf(fpc,"\n");
1449  fprintf(fpc,"void %s::Begin(TTree * /*tree*/)\n",classname);
1450  fprintf(fpc,"{\n");
1451  fprintf(fpc," // The Begin() function is called at the start of the query.\n");
1452  fprintf(fpc," // When running with PROOF Begin() is only called on the client.\n");
1453  fprintf(fpc," // The tree argument is deprecated (on PROOF 0 is passed).\n");
1454  fprintf(fpc,"\n");
1455  fprintf(fpc," TString option = GetOption();\n");
1456  fprintf(fpc,"\n");
1457  fprintf(fpc,"}\n");
1458  // generate code for class member function SlaveBegin
1459  fprintf(fpc,"\n");
1460  fprintf(fpc,"void %s::SlaveBegin(TTree * /*tree*/)\n",classname);
1461  fprintf(fpc,"{\n");
1462  fprintf(fpc," // The SlaveBegin() function is called after the Begin() function.\n");
1463  fprintf(fpc," // When running with PROOF SlaveBegin() is called on each slave server.\n");
1464  fprintf(fpc," // The tree argument is deprecated (on PROOF 0 is passed).\n");
1465  fprintf(fpc,"\n");
1466  fprintf(fpc," TString option = GetOption();\n");
1467  fprintf(fpc,"\n");
1468  fprintf(fpc,"}\n");
1469  // generate code for class member function Process
1470  fprintf(fpc,"\n");
1471  fprintf(fpc,"Bool_t %s::Process(Long64_t entry)\n",classname);
1472  fprintf(fpc,"{\n");
1473  fprintf(fpc," // The Process() function is called for each entry in the tree (or possibly\n"
1474  " // keyed object in the case of PROOF) to be processed. The entry argument\n"
1475  " // specifies which entry in the currently loaded tree is to be processed.\n"
1476  " // It can be passed to either %s::GetEntry() or TBranch::GetEntry()\n"
1477  " // to read either all or the required parts of the data. When processing\n"
1478  " // keyed objects with PROOF, the object is already loaded and is available\n"
1479  " // via the fObject pointer.\n"
1480  " //\n"
1481  " // This function should contain the \"body\" of the analysis. It can contain\n"
1482  " // simple or elaborate selection criteria, run algorithms on the data\n"
1483  " // of the event and typically fill histograms.\n"
1484  " //\n"
1485  " // The processing can be stopped by calling Abort().\n"
1486  " //\n"
1487  " // Use fStatus to set the return value of TTree::Process().\n"
1488  " //\n"
1489  " // The return value is currently not used.\n\n", classname);
1490  fprintf(fpc,"\n");
1491  fprintf(fpc," return kTRUE;\n");
1492  fprintf(fpc,"}\n");
1493  // generate code for class member function SlaveTerminate
1494  fprintf(fpc,"\n");
1495  fprintf(fpc,"void %s::SlaveTerminate()\n",classname);
1496  fprintf(fpc,"{\n");
1497  fprintf(fpc," // The SlaveTerminate() function is called after all entries or objects\n"
1498  " // have been processed. When running with PROOF SlaveTerminate() is called\n"
1499  " // on each slave server.");
1500  fprintf(fpc,"\n");
1501  fprintf(fpc,"\n");
1502  fprintf(fpc,"}\n");
1503  // generate code for class member function Terminate
1504  fprintf(fpc,"\n");
1505  fprintf(fpc,"void %s::Terminate()\n",classname);
1506  fprintf(fpc,"{\n");
1507  fprintf(fpc," // The Terminate() function is the last function to be called during\n"
1508  " // a query. It always runs on the client, it can be used to present\n"
1509  " // the results graphically or save the results to file.");
1510  fprintf(fpc,"\n");
1511  fprintf(fpc,"\n");
1512  fprintf(fpc,"}\n");
1513  }
1514  Info("MakeClass","Files: %s and %s generated from TTree: %s",thead.Data(),tcimp.Data(),fTree->GetName());
1515  delete [] leafStatus;
1516  fclose(fp);
1517  fclose(fpc);
1518 
1519  return 0;
1520 }
1521 
1522 
1523 ////////////////////////////////////////////////////////////////////////////////
1524 /// Generate skeleton function for this Tree
1525 ///
1526 /// The function code is written on filename.
1527 /// If filename is 0, filename will be called nameoftree.C
1528 ///
1529 /// The generated code includes the following:
1530 /// - Identification of the original Tree and Input file name
1531 /// - Connection of the Tree file
1532 /// - Declaration of Tree variables
1533 /// - Setting of branches addresses
1534 /// - A skeleton for the entry loop
1535 ///
1536 /// To use this function:
1537 /// - connect your Tree file (eg: TFile f("myfile.root");)
1538 /// - T->MakeCode("anal.C");
1539 /// where T is the name of the Tree in file myfile.root
1540 /// and anal.C the name of the file created by this function.
1541 ///
1542 /// NOTE: Since the implementation of this function, a new and better
1543 /// function TTree::MakeClass() has been developed.
1544 
1546 {
1547 // Connect output file
1548  TString tfile;
1549  if (filename)
1550  tfile = filename;
1551  else
1552  tfile.Form("%s.C", fTree->GetName());
1553  FILE *fp = fopen(tfile, "w");
1554  if (!fp) {
1555  Error("MakeCode","cannot open output file %s", tfile.Data());
1556  return 3;
1557  }
1558  TString treefile;
1559  if (fTree->GetDirectory() && fTree->GetDirectory()->GetFile()) {
1560  treefile = fTree->GetDirectory()->GetFile()->GetName();
1561  } else {
1562  treefile = "Memory Directory";
1563  }
1564  // In the case of a chain, the GetDirectory information usually does
1565  // pertain to the Chain itself but to the currently loaded tree.
1566  // So we can not rely on it.
1567  Bool_t ischain = fTree->InheritsFrom(TChain::Class());
1568 
1569 // Print header
1570  TObjArray *leaves = fTree->GetListOfLeaves();
1571  Int_t nleaves = leaves ? leaves->GetEntriesFast() : 0;
1572  TDatime td;
1573  fprintf(fp,"{\n");
1574  fprintf(fp,"//////////////////////////////////////////////////////////\n");
1575  fprintf(fp,"// This file has been automatically generated \n");
1576  fprintf(fp,"// (%s by ROOT version%s)\n",td.AsString(),gROOT->GetVersion());
1577  if (!ischain) {
1578  fprintf(fp,"// from TTree %s/%s\n",fTree->GetName(),fTree->GetTitle());
1579  fprintf(fp,"// found on file: %s\n",treefile.Data());
1580  } else {
1581  fprintf(fp,"// from TChain %s/%s\n",fTree->GetName(),fTree->GetTitle());
1582  }
1583  fprintf(fp,"//////////////////////////////////////////////////////////\n");
1584  fprintf(fp,"\n");
1585  fprintf(fp,"\n");
1586 
1587 
1588 // Reset and file connect
1589  fprintf(fp,"//Reset ROOT and connect tree file\n");
1590  fprintf(fp," gROOT->Reset();\n");
1591  if (ischain) {
1592  fprintf(fp,"\n#ifdef SINGLE_TREE\n");
1593  fprintf(fp," // The following code should be used if you want this code to access\n");
1594  fprintf(fp," // a single tree instead of a chain\n");
1595  }
1596  fprintf(fp," TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(\"%s\");\n",treefile.Data());
1597  fprintf(fp," if (!f) {\n");
1598  fprintf(fp," f = new TFile(\"%s\");\n",treefile.Data());
1599  fprintf(fp," }\n");
1600  if (fTree->GetDirectory() != fTree->GetCurrentFile()) {
1601  fprintf(fp," TDirectory * dir = (TDirectory*)f->Get(\"%s\");\n",fTree->GetDirectory()->GetPath());
1602  fprintf(fp," dir->GetObject(\"%s\",tree);\n\n",fTree->GetName());
1603  } else {
1604  fprintf(fp," f->GetObject(\"%s\",tree);\n\n",fTree->GetName());
1605  }
1606  if (ischain) {
1607  fprintf(fp,"#else // SINGLE_TREE\n\n");
1608  fprintf(fp," // The following code should be used if you want this code to access a chain\n");
1609  fprintf(fp," // of trees.\n");
1610  fprintf(fp," TChain *%s = new TChain(\"%s\",\"%s\");\n",
1612  {
1614  TIter next(((TChain*)fTree)->GetListOfFiles());
1615  TChainElement *element;
1616  while ((element = (TChainElement*)next())) {
1617  fprintf(fp," %s->Add(\"%s/%s\");\n",fTree->GetName(),element->GetTitle(),element->GetName());
1618  }
1619  }
1620  fprintf(fp,"#endif // SINGLE_TREE\n\n");
1621  }
1622 
1623 // First loop on all leaves to generate type declarations
1624  fprintf(fp,"//Declaration of leaves types\n");
1625  Int_t len, l;
1626  TLeaf *leafcount;
1627  TLeafObject *leafobj;
1628  char *bname;
1629  const char *headOK = " ";
1630  const char *headcom = " //";
1631  const char *head;
1632  char branchname[1024];
1633  for (l=0;l<nleaves;l++) {
1634  TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
1635  len = leaf->GetLen();
1636  leafcount =leaf->GetLeafCount();
1637  TBranch *branch = leaf->GetBranch();
1638  if (branch->GetListOfBranches()->GetEntriesFast() > 0) continue;
1639 
1640  if ( branch->GetNleaves() > 1) {
1641  // More than one leaf for the branch we need to distinguish them
1642  strlcpy(branchname,branch->GetName(),sizeof(branchname));
1643  strlcat(branchname,".",sizeof(branchname));
1644  strlcat(branchname,leaf->GetTitle(),sizeof(branchname));
1645  if (leafcount) {
1646  // remove any dimension in title
1647  char *dim = (char*)strstr(branchname,"[");
1648  if (dim) dim[0] = 0;
1649  }
1650  } else {
1651  if (leafcount) strlcpy(branchname,branch->GetName(),sizeof(branchname));
1652  else strlcpy(branchname,leaf->GetTitle(),sizeof(branchname));
1653  }
1654  char *twodim = (char*)strstr(leaf->GetTitle(),"][");
1655  bname = branchname;
1656  while (*bname) {
1657  if (*bname == '.') *bname='_';
1658  if (*bname == ',') *bname='_';
1659  if (*bname == ':') *bname='_';
1660  if (*bname == '<') *bname='_';
1661  if (*bname == '>') *bname='_';
1662  bname++;
1663  }
1664  if (branch->IsA() == TBranchObject::Class()) {
1665  leafobj = (TLeafObject*)leaf;
1666  if (leafobj->GetClass()) head = headOK;
1667  else head = headcom;
1668  fprintf(fp,"%s%-15s *%s = 0;\n",head,leafobj->GetTypeName(), leafobj->GetName());
1669  continue;
1670  }
1671  if (leafcount) {
1672  len = leafcount->GetMaximum();
1673  // Dimensions can be in the branchname for a split Object with a fix length C array.
1674  // Theses dimensions HAVE TO be placed after the dimension explicited by leafcount
1675  char *dimInName = (char*) strstr(branchname,"[");
1676  TString dimensions;
1677  if ( twodim || dimInName ) {
1678  if (dimInName) {
1679  dimensions = dimInName;
1680  dimInName[0] = 0; // terminate branchname before the array dimensions.
1681  }
1682  if (twodim) dimensions += (char*)(twodim+1);
1683  }
1684  if (dimensions.Length()) {
1685  fprintf(fp," %-15s %s[%d]%s;\n",leaf->GetTypeName(), branchname,len,dimensions.Data());
1686  } else {
1687  fprintf(fp," %-15s %s[%d];\n",leaf->GetTypeName(), branchname,len);
1688  }
1689  } else {
1690  if (strstr(branchname,"[")) len = 1;
1691  if (len < 2) fprintf(fp," %-15s %s;\n",leaf->GetTypeName(), branchname);
1692  else fprintf(fp," %-15s %s[%d];\n",leaf->GetTypeName(), branchname,len);
1693  }
1694  }
1695 
1696 // Second loop on all leaves to set the corresponding branch address
1697  fprintf(fp,"\n // Set branch addresses.\n");
1698  for (l=0;l<nleaves;l++) {
1699  TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
1700  len = leaf->GetLen();
1701  leafcount =leaf->GetLeafCount();
1702  TBranch *branch = leaf->GetBranch();
1703 
1704  if ( branch->GetNleaves() > 1) {
1705  // More than one leaf for the branch we need to distinguish them
1706  strlcpy(branchname,branch->GetName(),sizeof(branchname));
1707  strlcat(branchname,".",sizeof(branchname));
1708  strlcat(branchname,leaf->GetTitle(),sizeof(branchname));
1709  if (leafcount) {
1710  // remove any dimension in title
1711  char *dim = (char*)strstr(branchname,"[");
1712  if (dim) dim[0] = 0;
1713  }
1714  } else {
1715  if (leafcount) strlcpy(branchname,branch->GetName(),sizeof(branchname));
1716  else strlcpy(branchname,leaf->GetTitle(),sizeof(branchname));
1717  }
1718  bname = branchname;
1719  while (*bname) {
1720  if (*bname == '.') *bname='_';
1721  if (*bname == ',') *bname='_';
1722  if (*bname == ':') *bname='_';
1723  if (*bname == '<') *bname='_';
1724  if (*bname == '>') *bname='_';
1725  bname++;
1726  }
1727  char *brak = strstr(branchname,"[");
1728  if (brak) *brak = 0;
1729  head = headOK;
1730  if (branch->IsA() == TBranchObject::Class()) {
1731  strlcpy(branchname,branch->GetName(),sizeof(branchname));
1732  leafobj = (TLeafObject*)leaf;
1733  if (!leafobj->GetClass()) head = headcom;
1734  }
1735  if (leafcount) len = leafcount->GetMaximum()+1;
1736  if (len > 1 || brak) fprintf(fp,"%s%s->SetBranchAddress(\"%s\",%s);\n",head,fTree->GetName(),branch->GetName(),branchname);
1737  else fprintf(fp,"%s%s->SetBranchAddress(\"%s\",&%s);\n",head,fTree->GetName(),branch->GetName(),branchname);
1738  }
1739 
1740 //Generate instructions to make the loop on entries
1741  fprintf(fp,"\n// This is the loop skeleton\n");
1742  fprintf(fp,"// To read only selected branches, Insert statements like:\n");
1743  fprintf(fp,"// %s->SetBranchStatus(\"*\",0); // disable all branches\n",fTree->GetName());
1744  fprintf(fp,"// %s->SetBranchStatus(\"branchname\",1); // activate branchname\n",GetName());
1745  fprintf(fp,"\n Long64_t nentries = %s->GetEntries();\n",fTree->GetName());
1746  fprintf(fp,"\n Long64_t nbytes = 0;\n");
1747  fprintf(fp,"// for (Long64_t i=0; i<nentries;i++) {\n");
1748  fprintf(fp,"// nbytes += %s->GetEntry(i);\n",fTree->GetName());
1749  fprintf(fp,"// }\n");
1750  fprintf(fp,"}\n");
1751 
1752  printf("Macro: %s generated from Tree: %s\n",tfile.Data(), fTree->GetName());
1753  fclose(fp);
1754 
1755  return 0;
1756 }
1757 
1758 ////////////////////////////////////////////////////////////////////////////////
1759 /// Generate a skeleton analysis class for this Tree using TBranchProxy.
1760 /// TBranchProxy is the base of a class hierarchy implementing an
1761 /// indirect access to the content of the branches of a TTree.
1762 ///
1763 /// "proxyClassname" is expected to be of the form:
1764 /// ~~~{.cpp}
1765 /// [path/]fileprefix
1766 /// ~~~
1767 /// The skeleton will then be generated in the file:
1768 /// ~~~{.cpp}
1769 /// fileprefix.h
1770 /// ~~~
1771 /// located in the current directory or in 'path/' if it is specified.
1772 /// The class generated will be named 'fileprefix'.
1773 /// If the fileprefix contains a period, the right side of the period
1774 /// will be used as the extension (instead of 'h') and the left side
1775 /// will be used as the classname.
1776 ///
1777 /// "macrofilename" and optionally "cutfilename" are expected to point
1778 /// to source file which will be included in by the generated skeletong.
1779 /// Method of the same name as the file(minus the extension and path)
1780 /// will be called by the generated skeleton's Process method as follow:
1781 /// ~~~{.cpp}
1782 /// [if (cutfilename())] htemp->Fill(macrofilename());
1783 /// ~~~
1784 /// "option" can be used select some of the optional features during
1785 /// the code generation. The possible options are:
1786 /// - nohist : indicates that the generated ProcessFill should not
1787 /// fill the histogram.
1788 ///
1789 /// 'maxUnrolling' controls how deep in the class hierarchy does the
1790 /// system 'unroll' class that are not split. 'unrolling' a class
1791 /// will allow direct access to its data members a class (this
1792 /// emulates the behavior of TTreeFormula).
1793 ///
1794 /// The main features of this skeleton are:
1795 ///
1796 /// * on-demand loading of branches
1797 /// * ability to use the 'branchname' as if it was a data member
1798 /// * protection against array out-of-bound
1799 /// * ability to use the branch data as object (when the user code is available)
1800 ///
1801 /// For example with Event.root, if
1802 /// ~~~{.cpp}
1803 /// Double_t somepx = fTracks.fPx[2];
1804 /// ~~~
1805 /// is executed by one of the method of the skeleton,
1806 /// somepx will be updated with the current value of fPx of the 3rd track.
1807 ///
1808 /// Both macrofilename and the optional cutfilename are expected to be
1809 /// the name of source files which contain at least a free standing
1810 /// function with the signature:
1811 /// ~~~{.cpp}
1812 /// x_t macrofilename(); // i.e function with the same name as the file
1813 /// ~~~
1814 /// and
1815 /// ~~~{.cpp}
1816 /// y_t cutfilename(); // i.e function with the same name as the file
1817 /// ~~~
1818 /// x_t and y_t needs to be types that can convert respectively to a double
1819 /// and a bool (because the skeleton uses:
1820 /// ~~~{.cpp}
1821 /// if (cutfilename()) htemp->Fill(macrofilename());
1822 /// ~~~
1823 /// This 2 functions are run in a context such that the branch names are
1824 /// available as local variables of the correct (read-only) type.
1825 ///
1826 /// Note that if you use the same 'variable' twice, it is more efficient
1827 /// to 'cache' the value. For example
1828 /// ~~~{.cpp}
1829 /// Int_t n = fEventNumber; // Read fEventNumber
1830 /// if (n<10 || n>10) { ... }
1831 /// ~~~
1832 /// is more efficient than
1833 /// ~~~{.cpp}
1834 /// if (fEventNumber<10 || fEventNumber>10)
1835 /// ~~~
1836 /// Access to TClonesArray.
1837 ///
1838 /// If a branch (or member) is a TClonesArray (let's say fTracks), you
1839 /// can access the TClonesArray itself by using ->:
1840 /// ~~~{.cpp}
1841 /// fTracks->GetLast();
1842 /// ~~~
1843 /// However this will load the full TClonesArray object and its content.
1844 /// To quickly read the size of the TClonesArray use (note the dot):
1845 /// ~~~{.cpp}
1846 /// fTracks.GetEntries();
1847 /// ~~~
1848 /// This will read only the size from disk if the TClonesArray has been
1849 /// split.
1850 /// To access the content of the TClonesArray, use the [] operator:
1851 /// ~~~
1852 /// float px = fTracks[i].fPx; // fPx of the i-th track
1853 /// ~~~
1854 /// Warning:
1855 ///
1856 /// The variable actually use for access are 'wrapper' around the
1857 /// real data type (to add autoload for example) and hence getting to
1858 /// the data involves the implicit call to a C++ conversion operator.
1859 /// This conversion is automatic in most case. However it is not invoked
1860 /// in a few cases, in particular in variadic function (like printf).
1861 /// So when using printf you should either explicitly cast the value or
1862 /// use any intermediary variable:
1863 /// ~~~{.cpp}
1864 /// fprintf(stdout,"trs[%d].a = %d\n",i,(int)trs.a[i]);
1865 /// ~~~
1866 /// Also, optionally, the generated selector will also call methods named
1867 /// macrofilename_methodname in each of 6 main selector methods if the method
1868 /// macrofilename_methodname exist (Where macrofilename is stripped of its
1869 /// extension).
1870 ///
1871 /// Concretely, with the script named h1analysisProxy.C,
1872 ///
1873 /// - The method calls the method (if it exist)
1874 /// - Begin -> void h1analysisProxy_Begin(TTree*);
1875 /// - SlaveBegin -> void h1analysisProxy_SlaveBegin(TTree*);
1876 /// - Notify -> Bool_t h1analysisProxy_Notify();
1877 /// - Process -> Bool_t h1analysisProxy_Process(Long64_t);
1878 /// - SlaveTerminate -> void h1analysisProxy_SlaveTerminate();
1879 /// - Terminate -> void h1analysisProxy_Terminate();
1880 ///
1881 /// If a file name macrofilename.h (or .hh, .hpp, .hxx, .hPP, .hXX) exist
1882 /// it is included before the declaration of the proxy class. This can
1883 /// be used in particular to insure that the include files needed by
1884 /// the macro file are properly loaded.
1885 ///
1886 /// The default histogram is accessible via the variable named 'htemp'.
1887 ///
1888 /// If the library of the classes describing the data in the branch is
1889 /// loaded, the skeleton will add the needed #include statements and
1890 /// give the ability to access the object stored in the branches.
1891 ///
1892 /// To draw px using the file hsimple.root (generated by the
1893 /// hsimple.C tutorial), we need a file named hsimple.cxx:
1894 /// ~~~{.cpp}
1895 /// double hsimple() {
1896 /// return px;
1897 /// }
1898 /// ~~~
1899 /// MakeProxy can then be used indirectly via the TTree::Draw interface
1900 /// as follow:
1901 /// ~~~{.cpp}
1902 /// new TFile("hsimple.root")
1903 /// ntuple->Draw("hsimple.cxx");
1904 /// ~~~
1905 /// A more complete example is available in the tutorials directory:
1906 /// h1analysisProxy.cxx , h1analysProxy.h and h1analysisProxyCut.C
1907 /// which reimplement the selector found in h1analysis.C
1908 
1909 Int_t TTreePlayer::MakeProxy(const char *proxyClassname,
1910  const char *macrofilename, const char *cutfilename,
1911  const char *option, Int_t maxUnrolling)
1912 {
1913  if (macrofilename==0 || strlen(macrofilename)==0 ) {
1914  // We currently require a file name for the script
1915  Error("MakeProxy","A file name for the user script is required");
1916  return 0;
1917  }
1918 
1919  ROOT::Internal::TTreeProxyGenerator gp(fTree,macrofilename,cutfilename,proxyClassname,option,maxUnrolling);
1920 
1921  return 0;
1922 }
1923 
1924 
1925 ////////////////////////////////////////////////////////////////////////////////
1926 /// Generate skeleton selector class for this tree.
1927 ///
1928 /// The following files are produced: classname.h and classname.C.
1929 /// If classname is 0, the selector will be called "nameoftree".
1930 /// The option can be used to specify the branches that will have a data member.
1931 /// - If option is empty, readers will be generated for each leaf.
1932 /// - If option is "@", readers will be generated for the topmost branches.
1933 /// - Individual branches can also be picked by their name:
1934 /// - "X" generates readers for leaves of X.
1935 /// - "@X" generates a reader for X as a whole.
1936 /// - "@X;Y" generates a reader for X as a whole and also readers for the
1937 /// leaves of Y.
1938 /// - For further examples see the figure below.
1939 ///
1940 /// \image html ttree_makeselector_option_examples.png
1941 ///
1942 /// The generated code in classname.h includes the following:
1943 /// - Identification of the original Tree and Input file name
1944 /// - Definition of selector class (data and functions)
1945 /// - The following class functions:
1946 /// - constructor and destructor
1947 /// - void Begin(TTree *tree)
1948 /// - void SlaveBegin(TTree *tree)
1949 /// - void Init(TTree *tree)
1950 /// - Bool_t Notify()
1951 /// - Bool_t Process(Long64_t entry)
1952 /// - void Terminate()
1953 /// - void SlaveTerminate()
1954 ///
1955 /// The selector derives from TSelector.
1956 /// The generated code in classname.C includes empty functions defined above.
1957 ///
1958 /// To use this function:
1959 /// - connect your Tree file (eg: TFile f("myfile.root");)
1960 /// - T->MakeSelector("myselect");
1961 /// where T is the name of the Tree in file myfile.root
1962 /// and myselect.h, myselect.C the name of the files created by this function.
1963 /// In a ROOT session, you can do:
1964 /// root > T->Process("myselect.C")
1965 
1966 Int_t TTreePlayer::MakeReader(const char *classname, Option_t *option)
1967 {
1968  if (!classname) classname = fTree->GetName();
1969 
1970  ROOT::Internal::TTreeReaderGenerator gsr(fTree, classname, option);
1971 
1972  return 0;
1973 }
1974 
1975 
1976 ////////////////////////////////////////////////////////////////////////////////
1977 /// Interface to the Principal Components Analysis class.
1978 ///
1979 /// Create an instance of TPrincipal
1980 /// Fill it with the selected variables
1981 ///
1982 /// - if option "n" is specified, the TPrincipal object is filled with
1983 /// normalized variables.
1984 /// - If option "p" is specified, compute the principal components
1985 /// - If option "p" and "d" print results of analysis
1986 /// - If option "p" and "h" generate standard histograms
1987 /// - If option "p" and "c" generate code of conversion functions
1988 ///
1989 /// return a pointer to the TPrincipal object. It is the user responsibility
1990 /// to delete this object.
1991 ///
1992 /// The option default value is "np"
1993 ///
1994 /// See TTreePlayer::DrawSelect for explanation of the other parameters.
1995 
1996 TPrincipal *TTreePlayer::Principal(const char *varexp, const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)
1997 {
1998  TTreeFormula **var;
1999  std::vector<TString> cnames;
2000  TString opt = option;
2001  opt.ToLower();
2002  TPrincipal *principal = 0;
2003  Long64_t entry,entryNumber;
2004  Int_t i,nch;
2005  Int_t ncols = 8; // by default first 8 columns are printed only
2006  TObjArray *leaves = fTree->GetListOfLeaves();
2007  Int_t nleaves = leaves->GetEntriesFast();
2008  if (nleaves < ncols) ncols = nleaves;
2009  nch = varexp ? strlen(varexp) : 0;
2010 
2011  nentries = GetEntriesToProcess(firstentry, nentries);
2012 
2013 //*-*- Compile selection expression if there is one
2014  TTreeFormula *select = 0;
2015  if (strlen(selection)) {
2016  select = new TTreeFormula("Selection",selection,fTree);
2017  if (!select) return principal;
2018  if (!select->GetNdim()) { delete select; return principal; }
2019  fFormulaList->Add(select);
2020  }
2021 //*-*- if varexp is empty, take first 8 columns by default
2022  int allvar = 0;
2023  if (varexp && !strcmp(varexp, "*")) { ncols = nleaves; allvar = 1; }
2024  if (nch == 0 || allvar) {
2025  for (i=0;i<ncols;i++) {
2026  cnames.push_back( ((TLeaf*)leaves->At(i))->GetName() );
2027  }
2028 //*-*- otherwise select only the specified columns
2029  } else {
2030  ncols = fSelector->SplitNames(varexp,cnames);
2031  }
2032  var = new TTreeFormula* [ncols];
2033  Double_t *xvars = new Double_t[ncols];
2034 
2035 //*-*- Create the TreeFormula objects corresponding to each column
2036  for (i=0;i<ncols;i++) {
2037  var[i] = new TTreeFormula("Var1",cnames[i].Data(),fTree);
2038  fFormulaList->Add(var[i]);
2039  }
2040 
2041 //*-*- Create a TreeFormulaManager to coordinate the formulas
2042  TTreeFormulaManager *manager=0;
2043  if (fFormulaList->LastIndex()>=0) {
2044  manager = new TTreeFormulaManager;
2045  for(i=0;i<=fFormulaList->LastIndex();i++) {
2046  manager->Add((TTreeFormula*)fFormulaList->At(i));
2047  }
2048  manager->Sync();
2049  }
2050 
2051 //*-* Build the TPrincipal object
2052  if (opt.Contains("n")) principal = new TPrincipal(ncols, "n");
2053  else principal = new TPrincipal(ncols);
2054 
2055 //*-*- loop on all selected entries
2056  fSelectedRows = 0;
2057  Int_t tnumber = -1;
2058  for (entry=firstentry;entry<firstentry+nentries;entry++) {
2059  entryNumber = fTree->GetEntryNumber(entry);
2060  if (entryNumber < 0) break;
2061  Long64_t localEntry = fTree->LoadTree(entryNumber);
2062  if (localEntry < 0) break;
2063  if (tnumber != fTree->GetTreeNumber()) {
2064  tnumber = fTree->GetTreeNumber();
2065  if (manager) manager->UpdateFormulaLeaves();
2066  }
2067  int ndata = 1;
2068  if (manager && manager->GetMultiplicity()) {
2069  ndata = manager->GetNdata();
2070  }
2071 
2072  for(int inst=0;inst<ndata;inst++) {
2073  Bool_t loaded = kFALSE;
2074  if (select) {
2075  if (select->EvalInstance(inst) == 0) {
2076  continue;
2077  }
2078  }
2079 
2080  if (inst==0) loaded = kTRUE;
2081  else if (!loaded) {
2082  // EvalInstance(0) always needs to be called so that
2083  // the proper branches are loaded.
2084  for (i=0;i<ncols;i++) {
2085  var[i]->EvalInstance(0);
2086  }
2087  loaded = kTRUE;
2088  }
2089 
2090  for (i=0;i<ncols;i++) {
2091  xvars[i] = var[i]->EvalInstance(inst);
2092  }
2093  principal->AddRow(xvars);
2094  }
2095  }
2096 
2097  //*-* some actions with principal ?
2098  if (opt.Contains("p")) {
2099  principal->MakePrincipals(); // Do the actual analysis
2100  if (opt.Contains("d")) principal->Print();
2101  if (opt.Contains("h")) principal->MakeHistograms();
2102  if (opt.Contains("c")) principal->MakeCode();
2103  }
2104 
2105 //*-*- delete temporary objects
2106  fFormulaList->Clear();
2107  delete [] var;
2108  delete [] xvars;
2109 
2110  return principal;
2111 }
2112 
2113 ////////////////////////////////////////////////////////////////////////////////
2114 /// Process this tree executing the TSelector code in the specified filename.
2115 /// The return value is -1 in case of error and TSelector::GetStatus() in
2116 /// in case of success.
2117 ///
2118 /// The code in filename is loaded (interpreted or compiled, see below),
2119 /// filename must contain a valid class implementation derived from TSelector,
2120 /// where TSelector has the following member functions:
2121 ///
2122 /// - Begin(): called every time a loop on the tree starts,
2123 /// a convenient place to create your histograms.
2124 /// - SlaveBegin(): called after Begin(), when on PROOF called only on the
2125 /// slave servers.
2126 /// - Process(): called for each event, in this function you decide what
2127 /// to read and fill your histograms.
2128 /// - SlaveTerminate: called at the end of the loop on the tree, when on PROOF
2129 /// called only on the slave servers.
2130 /// - Terminate(): called at the end of the loop on the tree,
2131 /// a convenient place to draw/fit your histograms.
2132 ///
2133 /// If filename is of the form file.C, the file will be interpreted.
2134 /// If filename is of the form file.C++, the file file.C will be compiled
2135 /// and dynamically loaded.
2136 ///
2137 /// If filename is of the form file.C+, the file file.C will be compiled
2138 /// and dynamically loaded. At next call, if file.C is older than file.o
2139 /// and file.so, the file.C is not compiled, only file.so is loaded.
2140 ///
2141 /// ### NOTE 1
2142 /// It may be more interesting to invoke directly the other Process function
2143 /// accepting a TSelector* as argument.eg
2144 /// ~~~{.cpp}
2145 /// MySelector *selector = (MySelector*)TSelector::GetSelector(filename);
2146 /// selector->CallSomeFunction(..);
2147 /// mytree.Process(selector,..);
2148 /// ~~~
2149 /// ### NOTE 2
2150 /// One should not call this function twice with the same selector file
2151 /// in the same script. If this is required, proceed as indicated in NOTE1,
2152 /// by getting a pointer to the corresponding TSelector,eg
2153 ///#### workaround 1
2154 /// ~~~{.cpp}
2155 ///void stubs1() {
2156 /// TSelector *selector = TSelector::GetSelector("h1test.C");
2157 /// TFile *f1 = new TFile("stubs_nood_le1.root");
2158 /// TTree *h1 = (TTree*)f1->Get("h1");
2159 /// h1->Process(selector);
2160 /// TFile *f2 = new TFile("stubs_nood_le1_coarse.root");
2161 /// TTree *h2 = (TTree*)f2->Get("h1");
2162 /// h2->Process(selector);
2163 ///}
2164 /// ~~~
2165 /// or use ACLIC to compile the selector
2166 ///#### workaround 2
2167 /// ~~~{.cpp}
2168 ///void stubs2() {
2169 /// TFile *f1 = new TFile("stubs_nood_le1.root");
2170 /// TTree *h1 = (TTree*)f1->Get("h1");
2171 /// h1->Process("h1test.C+");
2172 /// TFile *f2 = new TFile("stubs_nood_le1_coarse.root");
2173 /// TTree *h2 = (TTree*)f2->Get("h1");
2174 /// h2->Process("h1test.C+");
2175 ///}
2176 /// ~~~
2177 
2178 Long64_t TTreePlayer::Process(const char *filename,Option_t *option, Long64_t nentries, Long64_t firstentry)
2179 {
2180  DeleteSelectorFromFile(); //delete previous selector if any
2181 
2182  // This might reloads the script and delete your option
2183  // string! so let copy it first:
2184  TString opt(option);
2185  TString file(filename);
2186  TSelector *selector = TSelector::GetSelector(file);
2187  if (!selector) return -1;
2188 
2189  fSelectorFromFile = selector;
2190  fSelectorClass = selector->IsA();
2191 
2192  Long64_t nsel = Process(selector,opt,nentries,firstentry);
2193  return nsel;
2194 }
2195 
2196 ////////////////////////////////////////////////////////////////////////////////
2197 /// Process this tree executing the code in the specified selector.
2198 /// The return value is -1 in case of error and TSelector::GetStatus() in
2199 /// in case of success.
2200 ///
2201 /// The TSelector class has the following member functions:
2202 ///
2203 /// - Begin(): called every time a loop on the tree starts,
2204 /// a convenient place to create your histograms.
2205 /// - SlaveBegin(): called after Begin(), when on PROOF called only on the
2206 /// slave servers.
2207 /// - Process(): called for each event, in this function you decide what
2208 /// to read and fill your histograms.
2209 /// - SlaveTerminate: called at the end of the loop on the tree, when on PROOF
2210 /// called only on the slave servers.
2211 /// - Terminate(): called at the end of the loop on the tree,
2212 /// a convenient place to draw/fit your histograms.
2213 ///
2214 /// If the Tree (Chain) has an associated EventList, the loop is on the nentries
2215 /// of the EventList, starting at firstentry, otherwise the loop is on the
2216 /// specified Tree entries.
2217 
2218 Long64_t TTreePlayer::Process(TSelector *selector,Option_t *option, Long64_t nentries, Long64_t firstentry)
2219 {
2220  nentries = GetEntriesToProcess(firstentry, nentries);
2221 
2222  TDirectory::TContext ctxt;
2223 
2224  fTree->SetNotify(selector);
2225 
2226  selector->SetOption(option);
2227 
2228  selector->Begin(fTree); //<===call user initialization function
2229  selector->SlaveBegin(fTree); //<===call user initialization function
2230  if (selector->Version() >= 2)
2231  selector->Init(fTree);
2232  selector->Notify();
2233 
2234  if (gMonitoringWriter)
2236 
2237  Bool_t process = (selector->GetAbort() != TSelector::kAbortProcess &&
2238  (selector->Version() != 0 || selector->GetStatus() != -1)) ? kTRUE : kFALSE;
2239  if (process) {
2240 
2241  Long64_t readbytesatstart = 0;
2242  readbytesatstart = TFile::GetFileBytesRead();
2243 
2244  //set the file cache
2245  TTreeCache *tpf = 0;
2246  TFile *curfile = fTree->GetCurrentFile();
2247  if (curfile && fTree->GetCacheSize() > 0) {
2248  tpf = (TTreeCache*)curfile->GetCacheRead(fTree);
2249  if (tpf)
2250  tpf->SetEntryRange(firstentry,firstentry+nentries);
2251  else {
2253  tpf = (TTreeCache*)curfile->GetCacheRead(fTree);
2254  if (tpf) tpf->SetEntryRange(firstentry,firstentry+nentries);
2255  }
2256  }
2257 
2258  //Create a timer to get control in the entry loop(s)
2260  Int_t interval = fTree->GetTimerInterval();
2261  if (!gROOT->IsBatch() && interval)
2262  timer = new TProcessEventTimer(interval);
2263 
2264  //loop on entries (elist or all entries)
2265  Long64_t entry, entryNumber, localEntry;
2266 
2267  Bool_t useCutFill = selector->Version() == 0;
2268 
2269  // force the first monitoring info
2270  if (gMonitoringWriter)
2272 
2273  //trying to set the first tree, because in the Draw function
2274  //the tree corresponding to firstentry has already been loaded,
2275  //so it is not set in the entry list
2276  fSelectorUpdate = selector;
2278 
2279  for (entry=firstentry;entry<firstentry+nentries;entry++) {
2280  entryNumber = fTree->GetEntryNumber(entry);
2281  if (entryNumber < 0) break;
2282  if (timer && timer->ProcessEvents()) break;
2283  if (gROOT->IsInterrupted()) break;
2284  localEntry = fTree->LoadTree(entryNumber);
2285  if (localEntry < 0) break;
2286  if(useCutFill) {
2287  if (selector->ProcessCut(localEntry))
2288  selector->ProcessFill(localEntry); //<==call user analysis function
2289  } else {
2290  selector->Process(localEntry); //<==call user analysis function
2291  }
2292  if (gMonitoringWriter)
2293  gMonitoringWriter->SendProcessingProgress((entry-firstentry),TFile::GetFileBytesRead()-readbytesatstart,kTRUE);
2294  if (selector->GetAbort() == TSelector::kAbortProcess) break;
2295  if (selector->GetAbort() == TSelector::kAbortFile) {
2296  // Skip to the next file.
2297  entry += fTree->GetTree()->GetEntries() - localEntry;
2298  // Reset the abort status.
2299  selector->ResetAbort();
2300  }
2301  }
2302  delete timer;
2303  //we must reset the cache
2304  {
2305  TFile *curfile2 = fTree->GetCurrentFile();
2306  if (curfile2 && fTree->GetCacheSize() > 0) {
2307  tpf = (TTreeCache*)curfile2->GetCacheRead(fTree);
2308  if (tpf) tpf->SetEntryRange(0,0);
2309  }
2310  }
2311  }
2312 
2313  process = (selector->GetAbort() != TSelector::kAbortProcess &&
2314  (selector->Version() != 0 || selector->GetStatus() != -1)) ? kTRUE : kFALSE;
2315  Long64_t res = (process) ? 0 : -1;
2316  if (process) {
2317  selector->SlaveTerminate(); //<==call user termination function
2318  selector->Terminate(); //<==call user termination function
2319  res = selector->GetStatus();
2320  }
2321  fTree->SetNotify(0); // Detach the selector from the tree.
2322  fSelectorUpdate = 0;
2323  if (gMonitoringWriter)
2325 
2326  return res;
2327 }
2328 
2329 ////////////////////////////////////////////////////////////////////////////////
2330 /// cleanup pointers in the player pointing to obj
2331 
2333 {
2334  if (fHistogram == obj) fHistogram = 0;
2335 }
2336 
2337 ////////////////////////////////////////////////////////////////////////////////
2338 /// Loop on Tree and print entries passing selection. If varexp is 0 (or "")
2339 /// then print only first 8 columns. If varexp = "*" print all columns.
2340 /// Otherwise a columns selection can be made using "var1:var2:var3".
2341 /// The function returns the number of entries passing the selection.
2342 ///
2343 /// By default 50 rows are shown and you are asked for <CR>
2344 /// to see the next 50 rows.
2345 ///
2346 /// You can change the default number of rows to be shown before <CR>
2347 /// via mytree->SetScanField(maxrows) where maxrows is 50 by default.
2348 /// if maxrows is set to 0 all rows of the Tree are shown.
2349 ///
2350 /// This option is interesting when dumping the contents of a Tree to
2351 /// an ascii file, eg from the command line
2352 /// ~~~{.cpp}
2353 /// tree->SetScanField(0);
2354 /// tree->Scan("*"); >tree.log
2355 /// ~~~
2356 /// will create a file tree.log
2357 ///
2358 /// Arrays (within an entry) are printed in their linear forms.
2359 /// If several arrays with multiple dimensions are printed together,
2360 /// they will NOT be synchronized. For example print
2361 /// arr1[4][2] and arr2[2][3] will results in a printing similar to:
2362 /// ~~~{.cpp}
2363 /// ***********************************************
2364 /// * Row * Instance * arr1 * arr2 *
2365 /// ***********************************************
2366 /// * x * 0 * arr1[0][0]* arr2[0][0]*
2367 /// * x * 1 * arr1[0][1]* arr2[0][1]*
2368 /// * x * 2 * arr1[1][0]* arr2[0][2]*
2369 /// * x * 3 * arr1[1][1]* arr2[1][0]*
2370 /// * x * 4 * arr1[2][0]* arr2[1][1]*
2371 /// * x * 5 * arr1[2][1]* arr2[1][2]*
2372 /// * x * 6 * arr1[3][0]* *
2373 /// * x * 7 * arr1[3][1]* *
2374 /// ~~~
2375 /// However, if there is a selection criterion which is an array, then
2376 /// all the formulas will be synchronized with the selection criterion
2377 /// (see TTreePlayer::DrawSelect for more information).
2378 ///
2379 /// The options string can contains the following parameters:
2380 ///
2381 /// - lenmax=dd
2382 /// Where 'dd' is the maximum number of elements per array that should
2383 /// be printed. If 'dd' is 0, all elements are printed (this is the
2384 /// default)
2385 /// - colsize=ss
2386 /// Where 'ss' will be used as the default size for all the column
2387 /// If this options is not specified, the default column size is 9
2388 /// - precision=pp
2389 /// Where 'pp' will be used as the default 'precision' for the
2390 /// printing format.
2391 /// - col=xxx
2392 /// Where 'xxx' is colon (:) delimited list of printing format for
2393 /// each column. The format string should follow the printf format
2394 /// specification. The value given will be prefixed by % and, if no
2395 /// conversion specifier is given, will be suffixed by the letter g.
2396 /// before being passed to fprintf. If no format is specified for a
2397 /// column, the default is used (aka ${colsize}.${precision}g )
2398 ///
2399 /// For example:
2400 /// ~~~{.cpp}
2401 /// tree->Scan("a:b:c","","colsize=30 precision=3 col=::20.10:#x:5ld");
2402 /// ~~~
2403 /// Will print 3 columns, the first 2 columns will be 30 characters long,
2404 /// the third columns will be 20 characters long. The printing format used
2405 /// for the columns (assuming they are numbers) will be respectively:
2406 /// `%30.3g %30.3g %20.10g %#x %5ld`
2407 
2408 Long64_t TTreePlayer::Scan(const char *varexp, const char *selection,
2409  Option_t * option,
2410  Long64_t nentries, Long64_t firstentry)
2411 {
2412 
2413  TString opt = option;
2414  opt.ToLower();
2415  UInt_t ui;
2416  UInt_t lenmax = 0;
2417  UInt_t colDefaultSize = 9;
2418  UInt_t colPrecision = 9;
2419  std::vector<TString> colFormats;
2420  std::vector<Int_t> colSizes;
2421 
2422  if (opt.Contains("lenmax=")) {
2423  int start = opt.Index("lenmax=");
2424  int numpos = start + strlen("lenmax=");
2425  int numlen = 0;
2426  int len = opt.Length();
2427  while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
2428  TString num = opt(numpos,numlen);
2429  opt.Remove(start,strlen("lenmax")+numlen);
2430 
2431  lenmax = atoi(num.Data());
2432  }
2433  if (opt.Contains("colsize=")) {
2434  int start = opt.Index("colsize=");
2435  int numpos = start + strlen("colsize=");
2436  int numlen = 0;
2437  int len = opt.Length();
2438  while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
2439  TString num = opt(numpos,numlen);
2440  opt.Remove(start,strlen("size")+numlen);
2441 
2442  colDefaultSize = atoi(num.Data());
2443  colPrecision = colDefaultSize;
2444  if (colPrecision>18) colPrecision = 18;
2445  }
2446  if (opt.Contains("precision=")) {
2447  int start = opt.Index("precision=");
2448  int numpos = start + strlen("precision=");
2449  int numlen = 0;
2450  int len = opt.Length();
2451  while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
2452  TString num = opt(numpos,numlen);
2453  opt.Remove(start,strlen("precision")+numlen);
2454 
2455  colPrecision = atoi(num.Data());
2456  }
2457  TString defFormat = Form("%d.%d",colDefaultSize,colPrecision);
2458  if (opt.Contains("col=")) {
2459  int start = opt.Index("col=");
2460  int numpos = start + strlen("col=");
2461  int numlen = 0;
2462  int len = opt.Length();
2463  while( (numpos+numlen<len) &&
2464  (isdigit(opt[numpos+numlen])
2465  || opt[numpos+numlen] == 'c'
2466  || opt[numpos+numlen] == 'd'
2467  || opt[numpos+numlen] == 'i'
2468  || opt[numpos+numlen] == 'o'
2469  || opt[numpos+numlen] == 'x'
2470  || opt[numpos+numlen] == 'X'
2471  || opt[numpos+numlen] == 'u'
2472  || opt[numpos+numlen] == 'f'
2473  || opt[numpos+numlen] == 'e'
2474  || opt[numpos+numlen] == 'E'
2475  || opt[numpos+numlen] == 'g'
2476  || opt[numpos+numlen] == 'G'
2477  || opt[numpos+numlen] == 'l'
2478  || opt[numpos+numlen] == 'L'
2479  || opt[numpos+numlen] == 'h'
2480  || opt[numpos+numlen] == 's'
2481  || opt[numpos+numlen] == '#'
2482  || opt[numpos+numlen]=='.'
2483  || opt[numpos+numlen]==':')) numlen++;
2484  TString flist = opt(numpos,numlen);
2485  opt.Remove(start,strlen("col")+numlen);
2486 
2487  int i = 0;
2488  while(i<flist.Length() && flist[i]==':') {
2489  colFormats.push_back(defFormat);
2490  colSizes.push_back(colDefaultSize);
2491  ++i;
2492  }
2493  for(; i<flist.Length(); ++i) {
2494  int next = flist.Index(":",i);
2495  if (next==i) {
2496  colFormats.push_back(defFormat);
2497  } else if (next==kNPOS) {
2498  colFormats.push_back(flist(i,flist.Length()-i));
2499  i = flist.Length();
2500  } else {
2501  colFormats.push_back(flist(i,next-i));
2502  i = next;
2503  }
2504  UInt_t siz = atoi(colFormats[colFormats.size()-1].Data());
2505  colSizes.push_back( siz ? siz : colDefaultSize );
2506  }
2507  }
2508 
2509  TTreeFormula **var;
2510  std::vector<TString> cnames;
2511  TString onerow;
2512  Long64_t entry,entryNumber;
2513  Int_t i,nch;
2514  UInt_t ncols = 8; // by default first 8 columns are printed only
2515  std::ofstream out;
2516  Int_t lenfile = 0;
2517  char * fname = 0;
2518  if (fScanRedirect) {
2519  fTree->SetScanField(0); // no page break if Scan is redirected
2520  fname = (char *) fScanFileName;
2521  if (!fname) fname = (char*)"";
2522  lenfile = strlen(fname);
2523  if (!lenfile) {
2524  Int_t nch2 = strlen(fTree->GetName());
2525  fname = new char[nch2+10];
2526  strlcpy(fname, fTree->GetName(),nch2+10);
2527  strlcat(fname, "-scan.dat",nch2+10);
2528  }
2529  out.open(fname, std::ios::out);
2530  if (!out.good ()) {
2531  if (!lenfile) delete [] fname;
2532  Error("Scan","Can not open file for redirection");
2533  return 0;
2534  }
2535  }
2536  TObjArray *leaves = fTree->GetListOfLeaves();
2537  if (leaves==0) return 0;
2538  UInt_t nleaves = leaves->GetEntriesFast();
2539  if (nleaves < ncols) ncols = nleaves;
2540  nch = varexp ? strlen(varexp) : 0;
2541 
2542  nentries = GetEntriesToProcess(firstentry, nentries);
2543 
2544 //*-*- Compile selection expression if there is one
2545  TTreeFormula *select = 0;
2546  if (selection && strlen(selection)) {
2547  select = new TTreeFormula("Selection",selection,fTree);
2548  if (!select) return -1;
2549  if (!select->GetNdim()) { delete select; return -1; }
2550  fFormulaList->Add(select);
2551  }
2552 //*-*- if varexp is empty, take first 8 columns by default
2553  int allvar = 0;
2554  if (varexp && !strcmp(varexp, "*")) { ncols = nleaves; allvar = 1; }
2555  if (nch == 0 || allvar) {
2556  UInt_t ncs = ncols;
2557  ncols = 0;
2558  for (ui=0;ui<ncs;++ui) {
2559  TLeaf *lf = (TLeaf*)leaves->At(ui);
2560  if (lf->GetBranch()->GetListOfBranches()->GetEntries() > 0) continue;
2561  cnames.push_back( lf->GetBranch()->GetMother()->GetName() );
2562  if (cnames[ncols] == lf->GetName() ) {
2563  // Already complete, let move on.
2564  } else if (cnames[ncols][cnames[ncols].Length()-1]=='.') {
2565  cnames[ncols] = lf->GetBranch()->GetName(); // name of branch already include mother's name
2566  } else {
2567  if (lf->GetBranch()->GetMother()->IsA()->InheritsFrom(TBranchElement::Class())) {
2568  TBranchElement *mother = (TBranchElement*)lf->GetBranch()->GetMother();
2569  if (mother->GetType() == 3 || mother->GetType() == 4) {
2570  // The name of the mother branch is embedded in the sub-branch names.
2571  cnames[ncols] = lf->GetBranch()->GetName();
2572  ++ncols;
2573  continue;
2574  }
2575  }
2576  if (!strchr(lf->GetBranch()->GetName() ,'[') ) {
2577  cnames[ncols].Append('.');
2578  cnames[ncols].Append( lf->GetBranch()->GetName() );
2579  }
2580  }
2581  if (strcmp( lf->GetBranch()->GetName(), lf->GetName() ) != 0 ) {
2582  cnames[ncols].Append('.');
2583  cnames[ncols].Append( lf->GetName() );
2584  }
2585  ++ncols;
2586  }
2587 //*-*- otherwise select only the specified columns
2588  } else {
2589 
2590  ncols = fSelector->SplitNames(varexp, cnames);
2591 
2592  }
2593  var = new TTreeFormula* [ncols];
2594 
2595  for(ui=colFormats.size();ui<ncols;++ui) {
2596  colFormats.push_back(defFormat);
2597  colSizes.push_back(colDefaultSize);
2598  }
2599 
2600 //*-*- Create the TreeFormula objects corresponding to each column
2601  for (ui=0;ui<ncols;ui++) {
2602  var[ui] = new TTreeFormula("Var1",cnames[ui].Data(),fTree);
2603  fFormulaList->Add(var[ui]);
2604  }
2605 
2606 //*-*- Create a TreeFormulaManager to coordinate the formulas
2607  TTreeFormulaManager *manager=0;
2608  Bool_t hasArray = kFALSE;
2609  Bool_t forceDim = kFALSE;
2610  if (fFormulaList->LastIndex()>=0) {
2611  if (select) {
2612  if (select->GetManager()->GetMultiplicity() > 0 ) {
2613  manager = new TTreeFormulaManager;
2614  for(i=0;i<=fFormulaList->LastIndex();i++) {
2615  manager->Add((TTreeFormula*)fFormulaList->At(i));
2616  }
2617  manager->Sync();
2618  }
2619  }
2620  for(i=0;i<=fFormulaList->LastIndex();i++) {
2621  TTreeFormula *form = ((TTreeFormula*)fFormulaList->At(i));
2622  switch( form->GetManager()->GetMultiplicity() ) {
2623  case 1:
2624  case 2:
2625  hasArray = kTRUE;
2626  forceDim = kTRUE;
2627  break;
2628  case -1:
2629  forceDim = kTRUE;
2630  break;
2631  case 0:
2632  break;
2633  }
2634 
2635  }
2636  }
2637 
2638 //*-*- Print header
2639  onerow = "***********";
2640  if (hasArray) onerow += "***********";
2641 
2642  for (ui=0;ui<ncols;ui++) {
2643  TString starFormat = Form("*%%%d.%ds",colSizes[ui]+2,colSizes[ui]+2);
2644  onerow += Form(starFormat.Data(),var[ui]->PrintValue(-2));
2645  }
2646  if (fScanRedirect)
2647  out<<onerow.Data()<<"*"<<std::endl;
2648  else
2649  printf("%s*\n",onerow.Data());
2650  onerow = "* Row ";
2651  if (hasArray) onerow += "* Instance ";
2652  for (ui=0;ui<ncols;ui++) {
2653  TString numbFormat = Form("* %%%d.%ds ",colSizes[ui],colSizes[ui]);
2654  onerow += Form(numbFormat.Data(),var[ui]->PrintValue(-1));
2655  }
2656  if (fScanRedirect)
2657  out<<onerow.Data()<<"*"<<std::endl;
2658  else
2659  printf("%s*\n",onerow.Data());
2660  onerow = "***********";
2661  if (hasArray) onerow += "***********";
2662  for (ui=0;ui<ncols;ui++) {
2663  TString starFormat = Form("*%%%d.%ds",colSizes[ui]+2,colSizes[ui]+2);
2664  onerow += Form(starFormat.Data(),var[ui]->PrintValue(-2));
2665  }
2666  if (fScanRedirect)
2667  out<<onerow.Data()<<"*"<<std::endl;
2668  else
2669  printf("%s*\n",onerow.Data());
2670 //*-*- loop on all selected entries
2671  fSelectedRows = 0;
2672  Int_t tnumber = -1;
2673  Bool_t exitloop = kFALSE;
2674  for (entry=firstentry;
2675  entry<(firstentry+nentries) && !exitloop;
2676  entry++) {
2677  entryNumber = fTree->GetEntryNumber(entry);
2678  if (entryNumber < 0) break;
2679  Long64_t localEntry = fTree->LoadTree(entryNumber);
2680  if (localEntry < 0) break;
2681  if (tnumber != fTree->GetTreeNumber()) {
2682  tnumber = fTree->GetTreeNumber();
2683  if (manager) manager->UpdateFormulaLeaves();
2684  else {
2685  for(i=0;i<=fFormulaList->LastIndex();i++) {
2687  }
2688  }
2689  }
2690 
2691  int ndata = 1;
2692  if (forceDim) {
2693 
2694  if (manager) {
2695 
2696  ndata = manager->GetNdata(kTRUE);
2697 
2698  } else {
2699 
2700  // let's print the max number of column
2701  for (ui=0;ui<ncols;ui++) {
2702  if (ndata < var[ui]->GetNdata() ) {
2703  ndata = var[ui]->GetNdata();
2704  }
2705  }
2706  if (select && select->GetNdata()==0) ndata = 0;
2707  }
2708 
2709  }
2710 
2711  if (lenmax && ndata>(int)lenmax) ndata = lenmax;
2712  Bool_t loaded = kFALSE;
2713  for(int inst=0;inst<ndata;inst++) {
2714  if (select) {
2715  if (select->EvalInstance(inst) == 0) {
2716  continue;
2717  }
2718  }
2719  if (inst==0) loaded = kTRUE;
2720  else if (!loaded) {
2721  // EvalInstance(0) always needs to be called so that
2722  // the proper branches are loaded.
2723  for (ui=0;ui<ncols;ui++) {
2724  var[ui]->EvalInstance(0);
2725  }
2726  loaded = kTRUE;
2727  }
2728  onerow = Form("* %8lld ",entryNumber);
2729  if (hasArray) {
2730  onerow += Form("* %8d ",inst);
2731  }
2732  for (ui=0;ui<ncols;++ui) {
2733  TString numbFormat = Form("* %%%d.%ds ",colSizes[ui],colSizes[ui]);
2734  if (var[ui]->GetNdim()) onerow += Form(numbFormat.Data(),var[ui]->PrintValue(0,inst,colFormats[ui].Data()));
2735  else {
2736  TString emptyForm = Form("* %%%dc ",colSizes[ui]);
2737  onerow += Form(emptyForm.Data(),' ');
2738  }
2739  }
2740  fSelectedRows++;
2741  if (fScanRedirect)
2742  out<<onerow.Data()<<"*"<<std::endl;
2743  else
2744  printf("%s*\n",onerow.Data());
2745  if (fTree->GetScanField() > 0 && fSelectedRows > 0) {
2746  if (fSelectedRows%fTree->GetScanField() == 0) {
2747  fprintf(stderr,"Type <CR> to continue or q to quit ==> ");
2748  int answer, readch;
2749  readch = getchar();
2750  answer = readch;
2751  while (readch != '\n' && readch != EOF) readch = getchar();
2752  if (answer == 'q' || answer == 'Q') {
2753  exitloop = kTRUE;
2754  break;
2755  }
2756  }
2757  }
2758  }
2759  }
2760  onerow = "***********";
2761  if (hasArray) onerow += "***********";
2762  for (ui=0;ui<ncols;ui++) {
2763  TString starFormat = Form("*%%%d.%ds",colSizes[ui]+2,colSizes[ui]+2);
2764  onerow += Form(starFormat.Data(),var[ui]->PrintValue(-2));
2765  }
2766  if (fScanRedirect)
2767  out<<onerow.Data()<<"*"<<std::endl;
2768  else
2769  printf("%s*\n",onerow.Data());
2770  if (select) Printf("==> %lld selected %s", fSelectedRows,
2771  fSelectedRows == 1 ? "entry" : "entries");
2772  if (fScanRedirect) printf("File <%s> created\n", fname);
2773 
2774 //*-*- delete temporary objects
2775  fFormulaList->Clear();
2776  // The TTreeFormulaManager is deleted by the last TTreeFormula.
2777  delete [] var;
2778  return fSelectedRows;
2779 }
2780 
2781 ////////////////////////////////////////////////////////////////////////////////
2782 /// Loop on Tree and return TSQLResult object containing entries passing
2783 /// selection. If varexp is 0 (or "") then print only first 8 columns.
2784 /// If varexp = "*" print all columns. Otherwise a columns selection can
2785 /// be made using "var1:var2:var3". In case of error 0 is returned otherwise
2786 /// a TSQLResult object which must be deleted by the user.
2787 
2788 TSQLResult *TTreePlayer::Query(const char *varexp, const char *selection,
2789  Option_t *, Long64_t nentries, Long64_t firstentry)
2790 {
2791  TTreeFormula **var;
2792  std::vector<TString> cnames;
2793  TString onerow;
2794  Long64_t entry,entryNumber;
2795  Int_t i,nch;
2796  Int_t ncols = 8; // by default first 8 columns are printed only
2797  TObjArray *leaves = fTree->GetListOfLeaves();
2798  Int_t nleaves = leaves->GetEntriesFast();
2799  if (nleaves < ncols) ncols = nleaves;
2800  nch = varexp ? strlen(varexp) : 0;
2801 
2802  nentries = GetEntriesToProcess(firstentry, nentries);
2803 
2804  // compile selection expression if there is one
2805  TTreeFormula *select = 0;
2806  if (strlen(selection)) {
2807  select = new TTreeFormula("Selection",selection,fTree);
2808  if (!select) return 0;
2809  if (!select->GetNdim()) { delete select; return 0; }
2810  fFormulaList->Add(select);
2811  }
2812 
2813  // if varexp is empty, take first 8 columns by default
2814  int allvar = 0;
2815  if (varexp && !strcmp(varexp, "*")) { ncols = nleaves; allvar = 1; }
2816  if (nch == 0 || allvar) {
2817  for (i=0;i<ncols;i++) {
2818  cnames.push_back( ((TLeaf*)leaves->At(i))->GetName() );
2819  }
2820  } else {
2821  // otherwise select only the specified columns
2822  ncols = fSelector->SplitNames(varexp,cnames);
2823  }
2824  var = new TTreeFormula* [ncols];
2825 
2826  // create the TreeFormula objects corresponding to each column
2827  for (i=0;i<ncols;i++) {
2828  var[i] = new TTreeFormula("Var1",cnames[i].Data(),fTree);
2829  fFormulaList->Add(var[i]);
2830  }
2831 
2832  // fill header info into result object
2833  TTreeResult *res = new TTreeResult(ncols);
2834  for (i = 0; i < ncols; i++) {
2835  res->AddField(i, var[i]->PrintValue(-1));
2836  }
2837 
2838  //*-*- Create a TreeFormulaManager to coordinate the formulas
2839  TTreeFormulaManager *manager=0;
2840  if (fFormulaList->LastIndex()>=0) {
2841  manager = new TTreeFormulaManager;
2842  for(i=0;i<=fFormulaList->LastIndex();i++) {
2843  manager->Add((TTreeFormula*)fFormulaList->At(i));
2844  }
2845  manager->Sync();
2846  }
2847 
2848  // loop on all selected entries
2849  const char *aresult;
2850  Int_t len;
2851  char *arow = new char[ncols*50];
2852  fSelectedRows = 0;
2853  Int_t tnumber = -1;
2854  Int_t *fields = new Int_t[ncols];
2855  for (entry=firstentry;entry<firstentry+nentries;entry++) {
2856  entryNumber = fTree->GetEntryNumber(entry);
2857  if (entryNumber < 0) break;
2858  Long64_t localEntry = fTree->LoadTree(entryNumber);
2859  if (localEntry < 0) break;
2860  if (tnumber != fTree->GetTreeNumber()) {
2861  tnumber = fTree->GetTreeNumber();
2862  for (i=0;i<ncols;i++) var[i]->UpdateFormulaLeaves();
2863  }
2864 
2865  Int_t ndata = 1;
2866  if (manager && manager->GetMultiplicity()) {
2867  ndata = manager->GetNdata();
2868  }
2869 
2870  if (select) {
2871  select->GetNdata();
2872  if (select->EvalInstance(0) == 0) continue;
2873  }
2874 
2875  Bool_t loaded = kFALSE;
2876  for(int inst=0;inst<ndata;inst++) {
2877  if (select) {
2878  if (select->EvalInstance(inst) == 0) {
2879  continue;
2880  }
2881  }
2882 
2883  if (inst==0) loaded = kTRUE;
2884  else if (!loaded) {
2885  // EvalInstance(0) always needs to be called so that
2886  // the proper branches are loaded.
2887  for (i=0;i<ncols;i++) {
2888  var[i]->EvalInstance(0);
2889  }
2890  loaded = kTRUE;
2891  }
2892  for (i=0;i<ncols;i++) {
2893  aresult = var[i]->PrintValue(0,inst);
2894  len = strlen(aresult)+1;
2895  if (i == 0) {
2896  memcpy(arow,aresult,len);
2897  fields[i] = len;
2898  } else {
2899  memcpy(arow+fields[i-1],aresult,len);
2900  fields[i] = fields[i-1] + len;
2901  }
2902  }
2903  res->AddRow(new TTreeRow(ncols,fields,arow));
2904  fSelectedRows++;
2905  }
2906  }
2907 
2908  // delete temporary objects
2909  fFormulaList->Clear();
2910  // The TTreeFormulaManager is deleted by the last TTreeFormula.
2911  delete [] fields;
2912  delete [] arow;
2913  delete [] var;
2914 
2915  return res;
2916 }
2917 
2918 ////////////////////////////////////////////////////////////////////////////////
2919 /// Set number of entries to estimate variable limits.
2920 
2922 {
2923  fSelector->SetEstimate(n);
2924 }
2925 
2926 ////////////////////////////////////////////////////////////////////////////////
2927 /// Start the TTreeViewer on this TTree.
2928 ///
2929 /// - ww is the width of the canvas in pixels
2930 /// - wh is the height of the canvas in pixels
2931 
2933 {
2934  if (gROOT->IsBatch()) {
2935  Warning("StartViewer", "viewer cannot run in batch mode");
2936  return;
2937  }
2938 
2939  if (ww || wh) { } // use unused variables
2940  TPluginHandler *h;
2941  if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualTreeViewer"))) {
2942  if (h->LoadPlugin() == -1)
2943  return;
2944  h->ExecPlugin(1,fTree);
2945  }
2946 }
2947 
2948 ////////////////////////////////////////////////////////////////////////////////
2949 /// Unbinned fit of one or more variable(s) from a Tree.
2950 ///
2951 /// funcname is a TF1 function.
2952 ///
2953 /// See TTree::Draw for explanations of the other parameters.
2954 ///
2955 /// Fit the variable varexp using the function funcname using the
2956 /// selection cuts given by selection.
2957 ///
2958 /// The list of fit options is given in parameter option.
2959 ///
2960 /// - option = "Q" Quiet mode (minimum printing)
2961 /// - option = "V" Verbose mode (default is between Q and V)
2962 /// - option = "E" Perform better Errors estimation using Minos technique
2963 /// - option = "M" More. Improve fit results
2964 /// - option = "D" Draw the projected histogram with the fitted function
2965 /// normalized to the number of selected rows
2966 /// and multiplied by the bin width
2967 ///
2968 /// You can specify boundary limits for some or all parameters via
2969 /// ~~~{.cpp}
2970 /// func->SetParLimits(p_number, parmin, parmax);
2971 /// ~~~
2972 /// if parmin>=parmax, the parameter is fixed
2973 ///
2974 /// Note that you are not forced to fix the limits for all parameters.
2975 /// For example, if you fit a function with 6 parameters, you can do:
2976 /// ~~~{.cpp}
2977 /// func->SetParameters(0,3.1,1.e-6,0.1,-8,100);
2978 /// func->SetParLimits(4,-10,-4);
2979 /// func->SetParLimits(5, 1,1);
2980 /// ~~~
2981 /// With this setup, parameters 0->3 can vary freely
2982 /// - Parameter 4 has boundaries [-10,-4] with initial value -8
2983 /// - Parameter 5 is fixed to 100.
2984 ///
2985 /// For the fit to be meaningful, the function must be self-normalized.
2986 ///
2987 /// i.e. It must have the same integral regardless of the parameter
2988 /// settings. Otherwise the fit will effectively just maximize the
2989 /// area.
2990 ///
2991 /// It is mandatory to have a normalization variable
2992 /// which is fixed for the fit. e.g.
2993 /// ~~~{.cpp}
2994 /// TF1* f1 = new TF1("f1", "gaus(0)/sqrt(2*3.14159)/[2]", 0, 5);
2995 /// f1->SetParameters(1, 3.1, 0.01);
2996 /// f1->SetParLimits(0, 1, 1); // fix the normalization parameter to 1
2997 /// data->UnbinnedFit("f1", "jpsimass", "jpsipt>3.0");
2998 /// ~~~
2999 ///
3000 /// 1, 2 and 3 Dimensional fits are supported.
3001 /// See also TTree::Fit
3002 ///
3003 /// ### Return status
3004 ///
3005 /// The function return the status of the fit in the following form
3006 /// ~~~{.cpp}
3007 /// fitResult = migradResult + 10*minosResult + 100*hesseResult + 1000*improveResult
3008 /// - The fitResult is 0 is the fit is OK.
3009 /// - The fitResult is negative in case of an error not connected with the fit.
3010 /// - The number of entries used in the fit can be obtained via
3011 /// ~~~{.cpp}
3012 /// mytree.GetSelectedRows();
3013 /// ~~~
3014 /// - If the number of selected entries is null the function returns -1
3015 ///
3016 /// new implementation using new Fitter classes
3017 
3018 Int_t TTreePlayer::UnbinnedFit(const char *funcname ,const char *varexp, const char *selection,Option_t *option ,Long64_t nentries, Long64_t firstentry)
3019 {
3020  // function is given by name, find it in gROOT
3021  TF1* fitfunc = (TF1*)gROOT->GetFunction(funcname);
3022  if (!fitfunc) { Error("UnbinnedFit", "Unknown function: %s",funcname); return 0; }
3023 
3024  Int_t npar = fitfunc->GetNpar();
3025  if (npar <=0) { Error("UnbinnedFit", "Illegal number of parameters = %d",npar); return 0; }
3026 
3027  // Spin through the data to select out the events of interest
3028  // Make sure that the arrays V1,etc are created large enough to accommodate
3029  // all entries
3030  Long64_t oldEstimate = fTree->GetEstimate();
3031  Long64_t nent = fTree->GetEntriesFriend();
3032  fTree->SetEstimate(TMath::Min(nent,nentries));
3033 
3034  // build FitOptions
3035  TString opt = option;
3036  opt.ToUpper();
3037  Foption_t fitOption;
3038  if (opt.Contains("Q")) fitOption.Quiet = 1;
3039  if (opt.Contains("V")){fitOption.Verbose = 1; fitOption.Quiet = 0;}
3040  if (opt.Contains("E")) fitOption.Errors = 1;
3041  if (opt.Contains("M")) fitOption.More = 1;
3042  if (!opt.Contains("D")) fitOption.Nograph = 1; // what about 0
3043  // could add range and automatic normalization of functions and gradient
3044 
3045  TString drawOpt = "goff para";
3046  if (!fitOption.Nograph) drawOpt = "";
3047  Long64_t nsel = DrawSelect(varexp, selection,drawOpt, nentries, firstentry);
3048 
3049  if (!fitOption.Nograph && GetSelectedRows() <= 0 && GetDimension() > 4) {
3050  Info("UnbinnedFit","Ignore option D with more than 4 variables");
3051  nsel = DrawSelect(varexp, selection,"goff para", nentries, firstentry);
3052  }
3053 
3054  //if no selected entries return
3055  Long64_t nrows = GetSelectedRows();
3056 
3057  if (nrows <= 0) {
3058  Error("UnbinnedFit", "Cannot fit: no entries selected");
3059  return -1;
3060  }
3061 
3062  // Check that function has same dimension as number of variables
3063  Int_t ndim = GetDimension();
3064  // do not check with TF1::GetNdim() since it returns 1 for TF1 classes created with
3065  // a C function with larger dimension
3066 
3067 
3068  // use pointer stored in the tree (not copy the data in)
3069  std::vector<double *> vlist(ndim);
3070  for (int i = 0; i < ndim; ++i)
3071  vlist[i] = fSelector->GetVal(i);
3072 
3073  // fill the fit data object
3074  // the object will be then managed by the fitted classes - however it will be invalid when the
3075  // data pointers (given by fSelector->GetVal() ) wil be invalidated
3076  ROOT::Fit::UnBinData * fitdata = new ROOT::Fit::UnBinData(nrows, ndim, vlist.begin());
3077 
3078 
3079 
3080  ROOT::Math::MinimizerOptions minOption;
3081  TFitResultPtr ret = ROOT::Fit::UnBinFit(fitdata,fitfunc, fitOption, minOption);
3082 
3083  //reset estimate
3084  fTree->SetEstimate(oldEstimate);
3085 
3086  //if option "D" is specified, draw the projected histogram
3087  //with the fitted function normalized to the number of selected rows
3088  //and multiplied by the bin width
3089  if (!fitOption.Nograph && fHistogram) {
3090  if (fHistogram->GetDimension() < 2) {
3091  TH1 *hf = (TH1*)fHistogram->Clone("unbinnedFit");
3092  hf->SetLineWidth(3);
3093  hf->Reset();
3094  Int_t nbins = fHistogram->GetXaxis()->GetNbins();
3095  Double_t norm = ((Double_t)nsel)*fHistogram->GetXaxis()->GetBinWidth(1);
3096  for (Int_t bin=1;bin<=nbins;bin++) {
3097  Double_t func = norm*fitfunc->Eval(hf->GetBinCenter(bin));
3098  hf->SetBinContent(bin,func);
3099  }
3100  fHistogram->GetListOfFunctions()->Add(hf,"lsame");
3101  }
3102  fHistogram->Draw();
3103  }
3104 
3105 
3106  return int(ret);
3107 
3108 }
3109 
3110 ////////////////////////////////////////////////////////////////////////////////
3111 /// this function is called by TChain::LoadTree when a new Tree is loaded.
3112 /// Because Trees in a TChain may have a different list of leaves, one
3113 /// must update the leaves numbers in the TTreeFormula used by the TreePlayer.
3114 
3116 {
3117  if (fSelector) fSelector->Notify();
3118  if (fSelectorUpdate){
3119  //If the selector is writing into a TEntryList, the entry list's
3120  //sublists need to be changed according to the loaded tree
3121  if (fSelector==fSelectorUpdate) {
3122  //FIXME: should be more consistent with selector from file
3123  TObject *obj = fSelector->GetObject();
3124  if (obj){
3127  }
3128  }
3129  }
3132  TEntryList *elist=0;
3133  while ((elist=(TEntryList*)next())){
3134  if (elist->InheritsFrom(TEntryList::Class())){
3135  elist->SetTree(fTree->GetTree());
3136  }
3137  }
3138  }
3139  }
3140 
3141  if (fFormulaList->GetSize()) {
3142  TObjLink *lnk = fFormulaList->FirstLink();
3143  while (lnk) {
3144  lnk->GetObject()->Notify();
3145  lnk = lnk->Next();
3146  }
3147  }
3148 }
const char * GetName() const
Returns name of object.
Definition: TObjString.h:42
const int ndata
virtual Int_t GetLen() const
Return the number of effective elements of this leaf.
Definition: TLeaf.cxx:276
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
void DeleteSelectorFromFile()
Delete any selector created by this object.
virtual void SetLineWidth(Width_t lwidth)
Definition: TAttLine.h:57
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
Definition: TLeaf.h:37
static TString R__GetBranchPointerName(TLeaf *leaf, Bool_t replace=kTRUE)
Return the name of the branch pointer needed by MakeClass/MakeSelector.
virtual Int_t GetDimension() const
Definition: TSelectorDraw.h:82
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:851
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition: TH1.cxx:6174
int Errors
Definition: Foption.h:37
virtual int Version() const
Definition: TSelector.h:60
TList * GetListOfFunctions() const
Definition: TH1.h:244
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form: ~~~ {.cpp} [path/]macro.C[+|++[k|f|g|O|c|s|d|v|-]][(args)]...
Definition: TSystem.cxx:3994
An array of TObjects.
Definition: TObjArray.h:39
void para(Int_t iaxis=0, Int_t ndiv=8, Double_t start=0, Double_t step=0)
Definition: geodemo.C:362
Principal Components Analysis (PCA)
Definition: TPrincipal.h:28
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:405
virtual Double_t * GetVal(Int_t i) const
Return the last values corresponding to the i-th component of the formula being processed (where the ...
void AddRow(TSQLRow *row)
Adopt a row to result set.
Bool_t ProcessEvents()
Process events if timer did time out.
Definition: TSystem.cxx:81
virtual Long64_t GetEntriesToProcess(Long64_t firstentry, Long64_t nentries) const
return the number of entries to be processed this function checks that nentries is not bigger than th...
long long Long64_t
Definition: RtypesCore.h:69
TTree * fTree
Definition: TTreePlayer.h:50
Abstract interface for Tree Index.
Definition: TVirtualIndex.h:31
const char * GetTypeName() const
virtual Bool_t Notify()
This method must be overridden to handle object notification.
Definition: TSelector.h:64
virtual TLeaf * GetLeaf(const char *branchname, const char *leafname)
Return a pointer to the leaf name in the current tree.
Definition: TChain.cxx:1013
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:487
virtual Bool_t SendProcessingProgress(Double_t, Double_t, Bool_t=kFALSE)
void AdoptReferenceProxy(TVirtualRefProxy *proxy)
Adopt the Reference proxy pointer to indicate that this class represents a reference.
Definition: TClass.cxx:6126
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
Ssiz_t Length() const
Definition: TString.h:390
virtual TList * GetOutputList() const
Definition: TSelector.h:76
Collectable string class.
Definition: TObjString.h:32
TSelectorDraw * fSelector
Pointer to histogram used for the projection.
Definition: TTreePlayer.h:56
const char * GetNameByIndex(TString &varexp, Int_t *index, Int_t colindex)
Set to the selector address when it's entry list needs to be updated by the UpdateFormulaLeaves funct...
Bool_t GetCanvasPreferGL() const
Definition: TStyle.h:197
const char Option_t
Definition: RtypesCore.h:62
const char * current
Definition: demos.C:12
virtual Bool_t Sync()
Synchronize all the formulae.
TEventList * GetEventList() const
Definition: TTree.h:396
virtual void SetEstimate(Long64_t n)
Set number of entries to estimate variable limits.
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:329
TTreeFormula * GetVar2() const
Definition: TSelectorDraw.h:95
TTreeFormulaManager * GetManager() const
Definition: TTreeFormula.h:184
TBranchElement * GetBranchCount2() const
virtual Bool_t ProcessCut(Long64_t)
Definition: TSelector.cxx:260
A TLeaf for a general object derived from TObject.
Definition: TLeafObject.h:35
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
virtual Long64_t GetSelectedRows() const
Definition: TTreePlayer.h:89
R__EXTERN TStyle * gStyle
Definition: TStyle.h:423
virtual Int_t GetDimension() const
Definition: TH1.h:283
R__EXTERN Foption_t Foption
Definition: TTreePlayer.cxx:88
int Verbose
Definition: Foption.h:30
virtual Int_t Fill()
Fill all branches.
Definition: TTree.cxx:4306
virtual TEntryList * GetEntryList()
Returns the entry list, set to this tree.
Definition: TTree.cxx:5194
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
TH1 * h
Definition: legend2.C:5
A specialized TFileCacheRead object for a TTree.
Definition: TTreeCache.h:34
virtual Long64_t GetEntriesFriend() const
Return pointer to the 1st Leaf named name in any Branch of this Tree or any branch in the list of fri...
Definition: TTree.cxx:5020
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:892
Int_t LastIndex() const
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format...
Definition: TFile.h:45
virtual void Print(Option_t *opt="MSE") const
Print the statistics Options are.
void ToUpper()
Change string to upper case.
Definition: TString.cxx:1088
static const char * filename()
virtual Long64_t GetSelectedRows() const
#define gROOT
Definition: TROOT.h:344
tuple pm3d
Definition: tornado.py:28
virtual Int_t GetEntry(Long64_t entry=0, Int_t getall=0)
Read all branches of entry and return total number of bytes read.
Definition: TTree.cxx:5144
Int_t LoadPlugin()
Load the plugin library for this handler.
Bool_t IsZombie() const
Definition: TObject.h:141
Basic string class.
Definition: TString.h:137
Class describing the unbinned data sets (just x coordinates values) of any dimensions.
Definition: UnBinData.h:47
virtual Long64_t GetDrawFlag() const
Definition: TSelectorDraw.h:83
virtual Int_t GetNdim() const
Definition: TFormula.h:243
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1075
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition: TAxis.cxx:511
virtual void Draw(Option_t *option="")
Default Draw method for all objects.
Definition: TObject.cxx:254
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:497
TBranch * GetBranch() const
Definition: TLeaf.h:70
int nbins[3]
virtual Long64_t GetEntryNumber(Long64_t entry) const
Return entry number corresponding to entry.
Definition: TTree.cxx:5205
virtual Long64_t Scan(const char *varexp, const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)
Loop on Tree and print entries passing selection.
Int_t GetEntriesFast() const
Definition: TObjArray.h:66
virtual void UpdateFormulaLeaves()
This function could be called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree whe...
virtual TTree * CloneTree(Long64_t nentries=-1, Option_t *option="")
Create a clone of this tree and copy nentries.
Definition: TTree.cxx:2960
virtual Long64_t GetEstimate() const
Definition: TTree.h:390
A TChainElement describes a component of a TChain.
Definition: TChainElement.h:30
TFile * GetCurrentFile() const
Return pointer to the current file.
Definition: TTree.cxx:4987
Long_t ExecPlugin(int nargs, const T &...params)
int Nograph
Definition: Foption.h:42
virtual void Add(TTreeFormula *)
Add a new formula to the list of formulas managed The manager of the formula will be changed and the ...
virtual const char * GetPath() const
Returns the full path of the directory.
Definition: TDirectory.cxx:909
A Tree Index with majorname and minorname.
Definition: TTreeIndex.h:32
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:311
virtual void SetTree(const TTree *tree)
If a list for a tree with such name and filename exists, sets it as the current sublist If not...
virtual void SetTree(TTree *t)
Definition: TTreePlayer.h:132
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition: TH1.cxx:6669
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Definition: TH1.cxx:2565
virtual Bool_t GetCleanElist() const
Definition: TSelectorDraw.h:81
virtual Int_t GetMultiplicity() const
TPrincipal * Principal(const char *varexp, const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)
Interface to the Principal Components Analysis class.
TFitResultPtr UnBinFit(ROOT::Fit::UnBinData *data, TF1 *f1, Foption_t &option, const ROOT::Math::MinimizerOptions &moption)
fit an unbin data set (from tree or from histogram buffer) using a TF1 pointer and fit options...
Definition: HFitImpl.cxx:784
TChain chain("h42")
TTree * T
const char * Data() const
Definition: TString.h:349
TFileCacheRead * GetCacheRead(TObject *tree=0) const
Return a pointer to the current read cache.
Definition: TFile.cxx:1196
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:396
virtual Long64_t DrawSelect(const char *varexp, const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)
Draw expression varexp for specified entries that matches the selection.
virtual void SetTextFont(Font_t tfont=62)
Definition: TAttText.h:59
virtual void ProcessFill(Long64_t)
Definition: TSelector.cxx:277
Long64_t * GetTreeOffset() const
Definition: TChain.h:119
virtual TObjArray * GetListOfBranches()
Definition: TTree.h:409
TStopwatch timer
Definition: pirndm.C:37
virtual Long64_t DrawScript(const char *wrapperPrefix, const char *macrofilename, const char *cutfilename, Option_t *option, Long64_t nentries, Long64_t firstentry)
Draw the result of a C++ script.
Used to coordinate one or more TTreeFormula objects.
virtual TTree * CopyTree(const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)
Copy a Tree with selection, make a clone of this Tree header, then copy the selected entries...
Class defining interface to a row of a TTree query result.
Definition: TTreeRow.h:31
virtual Long64_t Process(const char *filename, Option_t *option, Long64_t nentries, Long64_t firstentry)
Process this tree executing the TSelector code in the specified filename.
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:33
void Class()
Definition: Class.C:29
virtual Bool_t Notify()
This method must be overridden to handle object notification.
Definition: TObject.cxx:550
virtual Long64_t LoadTree(Long64_t entry)
Set current entry.
Definition: TTree.cxx:5785
static Long64_t GetFileBytesRead()
Static function returning the total number of bytes read from all files.
Definition: TFile.cxx:4319
TTreeFormula * GetVar3() const
Definition: TSelectorDraw.h:97
R__EXTERN TVirtualMonitoringWriter * gMonitoringWriter
if(pyself &&pyself!=Py_None)
TString & Append(const char *cs)
Definition: TString.h:492
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition: TStyle.cxx:796
virtual Int_t GetAction() const
Definition: TSelectorDraw.h:80
std::vector< std::vector< double > > Data
const char * GetTypeName() const
Returns name of leaf type.
Base class for several text objects.
Definition: TText.h:42
TSelector * fSelectorFromFile
Pointer to current selector.
Definition: TTreePlayer.h:57
virtual void Begin(TTree *)
Definition: TSelector.h:62
TObjArray * GetListOfBranches()
Definition: TBranch.h:177
virtual Long64_t LoadTree(Long64_t entry)
Find the tree which contains entry, and set it as the current tree.
Definition: TChain.cxx:1247
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
TH1 * GetOldHistogram() const
Definition: TSelectorDraw.h:87
virtual void MakeHistograms(const char *name="pca", Option_t *option="epsdx")
Make histograms of the result of the analysis.
Definition: TPrincipal.cxx:569
char * out
Definition: TBase64.cxx:29
Used to pass a selection expression to the Tree drawing routine.
Definition: TTreeFormula.h:64
virtual void SetTextAlign(Short_t align=11)
Definition: TAttText.h:55
virtual ~TTreePlayer()
Tree destructor.
A doubly linked list.
Definition: TList.h:47
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
Definition: TTree.cxx:4803
virtual TFile * GetFile() const
Definition: TDirectory.h:155
virtual void StartViewer(Int_t ww, Int_t wh)
Start the TTreeViewer on this TTree.
virtual Int_t GetMaximum() const
Definition: TLeaf.h:76
virtual Int_t GetDimension() const
Definition: TTreePlayer.h:82
TObject * UncheckedAt(Int_t i) const
Definition: TObjArray.h:91
void SetCanvasPreferGL(Bool_t prefer=kTRUE)
Definition: TStyle.h:337
virtual void SetEstimate(Long64_t n)
Set number of entries to estimate variable limits.
virtual Int_t GetTimerInterval() const
Definition: TTree.h:433
virtual Double_t GetBinCenter(Int_t bin) const
return bin center for 1D historam Better to use h1.GetXaxis().GetBinCenter(bin)
Definition: TH1.cxx:8470
virtual void SetEntryRange(Long64_t emin, Long64_t emax)
Set the minimum and maximum entry number to be processed this information helps to optimize the numbe...
virtual Int_t MakeReader(const char *classname, Option_t *option)
Generate skeleton selector class for this tree.
virtual Long64_t GetMaxEntryLoop() const
Definition: TTree.h:418
virtual Bool_t Notify()
This function is called at the first entry of a new tree in a chain.
virtual const char * GetTypeName() const
Definition: TLeaf.h:81
virtual void SetEstimate(Long64_t nentries=1000000)
Set number of entries to estimate variable limits.
Definition: TTree.cxx:8205
R__EXTERN TSystem * gSystem
Definition: TSystem.h:545
virtual void AddRow(const Double_t *x)
Add a data point and update the covariance matrix.
Definition: TPrincipal.cxx:410
TClass * fSelectorClass
Pointer to a user defined selector created by this TTreePlayer object.
Definition: TTreePlayer.h:58
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2878
virtual Long64_t GetCacheSize() const
Definition: TTree.h:377
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist...
Definition: TClass.cxx:4256
const char * fScanFileName
Definition: TTreePlayer.h:52
Int_t GetNbins() const
Definition: TAxis.h:125
Class defining interface to a TTree query result with the same interface as for SQL databases...
Definition: TTreeResult.h:36
virtual Int_t GetTreeNumber() const
Definition: TTree.h:438
A container proxy, which allows to access references stored in a TRefArray from TTree::Draw.
virtual Int_t MakeProxy(const char *classname, const char *macrofilename=0, const char *cutfilename=0, const char *option=0, Int_t maxUnrolling=3)
Generate a skeleton analysis class for this Tree using TBranchProxy.
TDirectory * GetDirectory() const
Definition: TTree.h:385
Int_t fDimension
Definition: TTreePlayer.h:53
virtual void SlaveBegin(TTree *)
Definition: TSelector.h:63
Provides an indirection to the TFitResult class and with a semantics identical to a TFitResult pointe...
Definition: TFitResultPtr.h:33
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition: TH1.cxx:8543
Int_t GetNtrees() const
Definition: TChain.h:97
TBranch * GetMother() const
Get our top-level parent branch in the tree.
Definition: TBranch.cxx:1533
TList * fInput
Pointer to the actual class of the TSelectorFromFile.
Definition: TTreePlayer.h:59
virtual void SetNotify(TObject *obj)
Definition: TTree.h:547
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2308
virtual void UpdateFormulaLeaves()
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void LabelsDeflate(Option_t *axis="X")
Reduce the number of bins for the axis passed in the option to the number of bins having a label...
Definition: TH1.cxx:4776
virtual Int_t UnbinnedFit(const char *formula, const char *varexp, const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)
char * Form(const char *fmt,...)
virtual void UpdateFormulaLeaves()
This function is called TTreePlayer::UpdateFormulaLeaves, itself called by TChain::LoadTree when a ne...
bool first
Definition: line3Dfit.C:48
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7354
int More
Definition: Foption.h:38
virtual Bool_t SendProcessingStatus(const char *, Bool_t=kFALSE)
TObject * GetObject() const
Definition: TSelectorDraw.h:84
A TEventList object is a list of selected events (entries) in a TTree.
Definition: TEventList.h:33
TLine * l
Definition: textangle.C:4
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:81
virtual Int_t MakeCode(const char *filename)
Generate skeleton function for this Tree.
virtual void MakePrincipals()
Perform the principal components analysis.
Definition: TPrincipal.cxx:862
virtual TObjLink * FirstLink() const
Definition: TList.h:101
Long64_t entry
virtual void Draw(Option_t *option="")
Draws 3-D polymarker with its current attributes.
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
Definition: TObjArray.cxx:239
virtual TLeaf * GetLeafCount() const
Definition: TLeaf.h:71
virtual void Terminate()
Definition: TSelector.h:78
A Branch for the case of an object.
#define Printf
Definition: TGeoToOCC.h:18
A specialized TSelector for TTree::Draw.
Definition: TSelectorDraw.h:33
virtual void SlaveTerminate()
Definition: TSelector.h:77
virtual Long64_t Process(const char *filename, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
Process this tree executing the TSelector code in the specified filename.
Definition: TTree.cxx:6687
static TSelector * GetSelector(const char *filename)
The code in filename is loaded (interpreted or compiled, see below), filename must contain a valid cl...
Definition: TSelector.cxx:140
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition: TClass.cxx:5436
int Ssiz_t
Definition: RtypesCore.h:63
virtual Int_t GetNdata()
Return number of available instances in the formula.
ClassImp(TTreePlayer) TTreePlayer
Default Tree constructor.
Definition: TTreePlayer.cxx:92
tuple tree
Definition: tree.py:24
virtual Int_t GetSize() const
Definition: TCollection.h:95
virtual void ResetAbort()
Definition: TSelector.h:81
tuple file
Definition: fildir.py:20
virtual void SetEntryList(TEntryList *list, Option_t *opt="")
Set an EntryList.
Definition: TTree.cxx:8141
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
double Double_t
Definition: RtypesCore.h:55
void select(Int_t replica=1, Int_t color=kGreen)
Definition: runplugin.C:24
virtual TObjArray * GetElements() const =0
virtual EAbort GetAbort() const
Definition: TSelector.h:80
TClass * GetClass() const
Definition: TLeafObject.h:50
TSelector * fSelectorUpdate
Pointer to a list of coordinated list TTreeFormula (used by Scan and Query)
Definition: TTreePlayer.h:61
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
Bool_t fScanRedirect
Pointer to current Tree.
Definition: TTreePlayer.h:51
TH1 * fHistogram
Definition: TTreePlayer.h:55
unsigned long ULong_t
Definition: RtypesCore.h:51
virtual void Draw(Option_t *opt)
Default Draw method for all objects.
Definition: TTree.h:360
int nentries
Definition: THbookFile.cxx:89
The TH1 histogram class.
Definition: TH1.h:80
virtual TTree * GetTree() const
Definition: TTree.h:436
#define R__LOCKGUARD(mutex)
virtual Bool_t Process(Long64_t)
Definition: TSelector.cxx:290
Int_t GetNleaves() const
Definition: TBranch.h:180
TObjArray * GetListOfLeaves()
Definition: TBranch.h:178
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
T EvalInstance(Int_t i=0, const char *stringStack[]=0)
Evaluate this treeformula.
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:2801
virtual void Clear(Option_t *option="")
Remove all objects from the list.
Definition: TList.cxx:349
virtual Int_t SetCacheSize(Long64_t cachesize=-1)
Set maximum size of the file cache .
Definition: TTree.cxx:7786
virtual void RecursiveRemove(TObject *obj)
cleanup pointers in the player pointing to obj
The class is derived from the ROOT class TSelector.
Bool_t IsBranchFolder() const
virtual void SetOption(const char *option)
Definition: TSelector.h:71
virtual Long64_t GetN() const
Definition: TEntryList.h:77
Abstract Base Class for Fitting.
virtual UInt_t SetCanExtend(UInt_t extendBitMask)
make the histogram axes extendable / not extendable according to the bit mask returns the previous bi...
Definition: TH1.cxx:6211
Mother of all ROOT objects.
Definition: TObject.h:58
virtual Bool_t IsFileInIncludePath(const char *name, char **fullpath=0)
Return true if 'name' is a file that can be found in the ROOT include path or the current directory...
Definition: TSystem.cxx:944
#define R__EXTERN
Definition: DllImport.h:27
const char * GetDeclFileName() const
Definition: TClass.h:385
TObject * Last() const
Return the object in the last filled slot. Returns 0 if no entries.
Definition: TObjArray.cxx:479
Int_t GetType() const
virtual Long64_t GetEntries(const char *selection)
Return the number of entries matching the selection.
A 3D polymarker.
Definition: TPolyMarker3D.h:40
virtual void Add(TObject *obj)
Definition: TList.h:81
const Ssiz_t kNPOS
Definition: Rtypes.h:115
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
1-Dim function class
Definition: TF1.h:149
A chain is a collection of files containg TTree objects.
Definition: TChain.h:35
Long64_t fSelectedRows
Definition: TTreePlayer.h:54
virtual Double_t Eval(Double_t x, Double_t y=0, Double_t z=0, Double_t t=0) const
Evaluate this function.
Definition: TF1.cxx:1162
virtual TVirtualIndex * BuildIndex(const TTree *T, const char *majorname, const char *minorname)
Build the index for the tree (see TTree::BuildIndex)
#define gPad
Definition: TVirtualPad.h:288
virtual void SetTextColor(Color_t tcolor=1)
Definition: TAttText.h:57
virtual void MakeCode(const char *filename="pca", Option_t *option="")
Generates the file <filename>, with .C appended if it does argument doesn't end in .cxx or .C.
Definition: TPrincipal.cxx:544
virtual UInt_t SplitNames(const TString &varexp, std::vector< TString > &names)
Build Index array for names in varexp.
void Add(TObject *obj)
Definition: TObjArray.h:75
virtual Long64_t GetEntries() const
Definition: TTree.h:386
virtual char * PrintValue(Int_t mode=0) const
Return value of variable as a string.
A TTree object has a header with a name and a title.
Definition: TTree.h:98
#define gDirectory
Definition: TDirectory.h:221
double result[121]
virtual Int_t GetNdata(Bool_t forceLoadDim=kFALSE)
Return number of available instances in the formulas.
TList * fFormulaList
input list to the selector
Definition: TTreePlayer.h:60
virtual void SetTextSize(Float_t tsize=1)
Definition: TAttText.h:60
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
Implement some of the functionality of the class TTree requiring access to extra libraries (Histogram...
Definition: TTreePlayer.h:43
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
int Quiet
Definition: Foption.h:29
A TTree is a list of TBranches.
Definition: TBranch.h:58
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
Definition: TBranch.cxx:1166
A TSelector object is used by the TTree::Draw, TTree::Scan, TTree::Process to navigate in a TTree and...
Definition: TSelector.h:39
const char * AsString() const
Return the date & time as a string (ctime() format).
Definition: TDatime.cxx:99
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Definition: TNamed.cxx:152
TObject * obj
virtual Int_t Fit(const char *formula, const char *varexp, const char *selection, Option_t *option, Option_t *goption, Long64_t nentries, Long64_t firstentry)
Fit a projected item(s) from a Tree.
A List of entry numbers in a TTree or TChain.
Definition: TEntryList.h:27
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Double_t xmin=0, Double_t xmax=0)
Fit histogram with function fname.
Definition: TH1.cxx:3607
const Int_t n
Definition: legend1.C:16
virtual Int_t MakeClass(const char *classname, Option_t *option)
Generate skeleton analysis class for this Tree.
virtual void SetScanField(Int_t n=50)
Definition: TTree.h:551
void AddField(Int_t field, const char *fieldname)
Add field name to result set.
virtual Int_t GetNpar() const
Definition: TF1.h:342
Int_t GetStreamerType() const
TTreeFormula * GetVar1() const
Definition: TSelectorDraw.h:93
virtual Long64_t GetStatus() const
Definition: TSelector.h:66
TAxis * GetXaxis()
Definition: TH1.h:319
virtual Int_t GetScanField() const
Definition: TTree.h:430
A Chain Index.
Definition: TChainIndex.h:41
virtual Bool_t IsInteger(Bool_t fast=kTRUE) const
Return TRUE if the formula corresponds to one single Tree leaf and this leaf is short, int or unsigned short, int When a leaf is of type integer or string, the generated histogram is forced to have an integer bin width.
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
Definition: TDatime.h:39
virtual TObjArray * GetListOfLeaves()
Definition: TTree.h:410
virtual void Init(TTree *)
Definition: TSelector.h:61
virtual TSQLResult * Query(const char *varexp, const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)
Loop on Tree and return TSQLResult object containing entries passing selection.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904