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