90 R__EXTERN Foption_t Foption;
92 TVirtualFitter *tFitter=0;
94 ClassImp(TTreePlayer);
99 TTreePlayer::TTreePlayer()
103 fScanRedirect = kFALSE;
107 fFormulaList =
new TList();
108 fFormulaList->SetOwner(kTRUE);
109 fSelector =
new TSelectorDraw();
110 fSelectorFromFile = 0;
113 fInput =
new TList();
114 fInput->Add(
new TNamed(
"varexp",
""));
115 fInput->Add(
new TNamed(
"selection",
""));
116 fSelector->SetInputList(fInput);
118 R__LOCKGUARD(gROOTMutex);
119 gROOT->GetListOfCleanups()->Add(
this);
121 TClass::GetClass(
"TRef")->AdoptReferenceProxy(
new TRefProxy());
122 TClass::GetClass(
"TRefArray")->AdoptReferenceProxy(
new TRefArrayProxy());
128 TTreePlayer::~TTreePlayer()
132 DeleteSelectorFromFile();
135 R__LOCKGUARD(gROOTMutex);
136 gROOT->GetListOfCleanups()->Remove(
this);
142 TVirtualIndex *TTreePlayer::BuildIndex(
const TTree *T,
const char *majorname,
const char *minorname)
144 TVirtualIndex *index;
145 if (dynamic_cast<const TChain*>(T)) {
146 index =
new TChainIndex(T, majorname, minorname);
147 if (index->IsZombie()) {
149 Error(
"BuildIndex",
"Creating a TChainIndex unsuccessful - switching to TTreeIndex");
154 return new TTreeIndex(T,majorname,minorname);
187 TTree *TTreePlayer::CopyTree(
const char *selection, Option_t *, Long64_t nentries,
192 TTree *tree = fTree->CloneTree(0);
193 if (tree == 0)
return 0;
196 TObjArray* branches = tree->GetListOfBranches();
197 Int_t nb = branches->GetEntriesFast();
198 for (Int_t i = 0; i < nb; ++i) {
199 TBranch* br = (TBranch*) branches->UncheckedAt(i);
200 if (br->InheritsFrom(TBranchElement::Class())) {
201 ((TBranchElement*) br)->ResetDeleteObject();
205 Long64_t entry,entryNumber;
206 nentries = GetEntriesToProcess(firstentry, nentries);
209 TTreeFormula *select = 0;
212 if (strlen(selection)) {
213 select =
new TTreeFormula(
"Selection",selection,fTree);
214 if (!select || !select->GetNdim()) {
219 fFormulaList->Add(select);
224 for (entry=firstentry;entry<firstentry+nentries;entry++) {
225 entryNumber = fTree->GetEntryNumber(entry);
226 if (entryNumber < 0)
break;
227 Long64_t localEntry = fTree->LoadTree(entryNumber);
228 if (localEntry < 0)
break;
229 if (tnumber != fTree->GetTreeNumber()) {
230 tnumber = fTree->GetTreeNumber();
231 if (select) select->UpdateFormulaLeaves();
234 Int_t ndata = select->GetNdata();
235 Bool_t keep = kFALSE;
236 for(Int_t current = 0; current<ndata && !keep; current++) {
237 keep |= (select->EvalInstance(current) != 0);
241 fTree->GetEntry(entryNumber);
244 fFormulaList->Clear();
252 void TTreePlayer::DeleteSelectorFromFile()
254 if (fSelectorFromFile && fSelectorClass) {
255 if (fSelectorClass->IsLoaded()) {
256 delete fSelectorFromFile;
259 fSelectorFromFile = 0;
295 Long64_t TTreePlayer::DrawScript(
const char* wrapperPrefix,
296 const char *macrofilename,
const char *cutfilename,
297 Option_t *option, Long64_t nentries, Long64_t firstentry)
299 if (!macrofilename || strlen(macrofilename)==0)
return 0;
305 if (cutfilename && strlen(cutfilename))
306 realcutname = gSystem->SplitAclicMode(cutfilename, aclicMode, arguments, io);
309 TString realname = gSystem->SplitAclicMode(macrofilename, aclicMode, arguments, io);
311 TString selname = wrapperPrefix;
313 ROOT::Internal::TTreeProxyGenerator gp(fTree,realname,realcutname,selname,option,3);
315 selname = gp.GetFileName();
316 if (aclicMode.Length()==0) {
317 Warning(
"DrawScript",
"TTreeProxy does not work in interpreted mode yet. The script will be compiled.");
320 selname.Append(aclicMode);
322 Info(
"DrawScript",
"%s",Form(
"Will process tree/chain using %s",selname.Data()));
323 Long64_t result = fTree->Process(selname,option,nentries,firstentry);
339 Long64_t TTreePlayer::DrawSelect(
const char *varexp0,
const char *selection, Option_t *option,Long64_t nentries, Long64_t firstentry)
341 if (fTree->GetEntriesFriend() == 0)
return 0;
346 TString possibleFilename = varexp0;
347 Ssiz_t dot_pos = possibleFilename.Last(
'.');
348 if ( dot_pos != kNPOS
349 && possibleFilename.Index(
"Alt$")<0 && possibleFilename.Index(
"Entries$")<0
350 && possibleFilename.Index(
"LocalEntries$")<0
351 && possibleFilename.Index(
"Length$")<0 && possibleFilename.Index(
"Entry$")<0
352 && possibleFilename.Index(
"LocalEntry$")<0
353 && possibleFilename.Index(
"Min$")<0 && possibleFilename.Index(
"Max$")<0
354 && possibleFilename.Index(
"MinIf$")<0 && possibleFilename.Index(
"MaxIf$")<0
355 && possibleFilename.Index(
"Iteration$")<0 && possibleFilename.Index(
"Sum$")<0
356 && possibleFilename.Index(
">")<0 && possibleFilename.Index(
"<")<0
357 && gSystem->IsFileInIncludePath(possibleFilename.Data())) {
359 if (selection && strlen(selection) && !gSystem->IsFileInIncludePath(selection)) {
361 "Drawing using a C++ file currently requires that both the expression and the selection are files\n\t\"%s\" is not a file",
365 return DrawScript(
"generatedSel",varexp0,selection,option,nentries,firstentry);
368 possibleFilename = selection;
369 if (possibleFilename.Index(
"Alt$")<0 && possibleFilename.Index(
"Entries$")<0
370 && possibleFilename.Index(
"LocalEntries$")<0
371 && possibleFilename.Index(
"Length$")<0 && possibleFilename.Index(
"Entry$")<0
372 && possibleFilename.Index(
"LocalEntry$")<0
373 && possibleFilename.Index(
"Min$")<0 && possibleFilename.Index(
"Max$")<0
374 && possibleFilename.Index(
"MinIf$")<0 && possibleFilename.Index(
"MaxIf$")<0
375 && possibleFilename.Index(
"Iteration$")<0 && possibleFilename.Index(
"Sum$")<0
376 && possibleFilename.Index(
">")<0 && possibleFilename.Index(
"<")<0
377 && gSystem->IsFileInIncludePath(possibleFilename.Data())) {
380 "Drawing using a C++ file currently requires that both the expression and the selection are files\n\t\"%s\" is not a file",
386 Long64_t oldEstimate = fTree->GetEstimate();
387 TEventList *evlist = fTree->GetEventList();
388 TEntryList *elist = fTree->GetEntryList();
389 if (evlist && elist){
390 elist->SetBit(kCanDelete, kTRUE);
392 TNamed *cvarexp = (TNamed*)fInput->FindObject(
"varexp");
393 TNamed *cselection = (TNamed*)fInput->FindObject(
"selection");
394 if (cvarexp) cvarexp->SetTitle(varexp0);
395 if (cselection) cselection->SetTitle(selection);
397 TString opt = option;
399 Bool_t optpara = kFALSE;
400 Bool_t optcandle = kFALSE;
401 Bool_t optgl5d = kFALSE;
402 Bool_t optnorm = kFALSE;
403 if (opt.Contains(
"norm")) {optnorm = kTRUE; opt.ReplaceAll(
"norm",
""); opt.ReplaceAll(
" ",
"");}
404 if (opt.Contains(
"para")) optpara = kTRUE;
405 if (opt.Contains(
"candle")) optcandle = kTRUE;
406 if (opt.Contains(
"gl5d")) optgl5d = kTRUE;
407 Bool_t pgl = gStyle->GetCanvasPreferGL();
409 fTree->SetEstimate(fTree->GetEntries());
411 if (pgl == kFALSE) gStyle->SetCanvasPreferGL(kTRUE);
412 gROOT->ProcessLineFast(
"new TCanvas();");
417 if (nentries > fTree->GetMaxEntryLoop()) nentries = fTree->GetMaxEntryLoop();
420 Long64_t nrows = Process(fSelector,option,nentries,firstentry);
421 fSelectedRows = nrows;
422 fDimension = fSelector->GetDimension();
425 if (fDimension <= 0) {
426 fTree->SetEstimate(oldEstimate);
427 if (fSelector->GetCleanElist()) {
429 fTree->SetEntryList(elist);
430 delete fSelector->GetObject();
436 Long64_t drawflag = fSelector->GetDrawFlag();
437 Int_t action = fSelector->GetAction();
438 Bool_t draw = kFALSE;
439 if (!drawflag && !opt.Contains(
"goff")) draw = kTRUE;
440 if (!optcandle && !optpara) fHistogram = (TH1*)fSelector->GetObject();
442 Double_t sumh= fHistogram->GetSumOfWeights();
443 if (sumh != 0) fHistogram->Scale(1./sumh);
448 if (!opt.Contains(
"same") && !opt.Contains(
"goff")) {
449 gPad->DrawFrame(-1.,-1.,1.,1.);
450 TText *text_empty =
new TText(0.,0.,
"Empty");
451 text_empty->SetTextAlign(22);
452 text_empty->SetTextFont(42);
453 text_empty->SetTextSize(0.1);
454 text_empty->SetTextColor(1);
458 Warning(
"DrawSelect",
"The selected TTree subset is empty.");
463 if (fDimension == 1 && !(optpara||optcandle)) {
464 if (fSelector->GetVar1()->IsInteger()) fHistogram->LabelsDeflate(
"X");
465 if (draw) fHistogram->Draw(opt.Data());
468 }
else if (fDimension == 2 && !(optpara||optcandle)) {
469 if (fSelector->GetVar1()->IsInteger()) fHistogram->LabelsDeflate(
"Y");
470 if (fSelector->GetVar2()->IsInteger()) fHistogram->LabelsDeflate(
"X");
472 if (draw) fHistogram->Draw(opt.Data());
474 Bool_t graph = kFALSE;
475 Int_t l = opt.Length();
476 if (l == 0 || opt ==
"same") graph = kTRUE;
477 if (opt.Contains(
"p") || opt.Contains(
"*") || opt.Contains(
"l")) graph = kTRUE;
478 if (opt.Contains(
"surf") || opt.Contains(
"lego") || opt.Contains(
"cont")) graph = kFALSE;
479 if (opt.Contains(
"col") || opt.Contains(
"hist") || opt.Contains(
"scat")) graph = kFALSE;
481 if (draw) fHistogram->Draw(opt.Data());
483 if (fSelector->GetOldHistogram() && draw) fHistogram->Draw(opt.Data());
487 }
else if (fDimension == 3 && !(optpara||optcandle)) {
488 if (fSelector->GetVar1()->IsInteger()) fHistogram->LabelsDeflate(
"Z");
489 if (fSelector->GetVar2()->IsInteger()) fHistogram->LabelsDeflate(
"Y");
490 if (fSelector->GetVar3()->IsInteger()) fHistogram->LabelsDeflate(
"X");
492 if (draw) fHistogram->Draw(opt.Data());
493 }
else if (action == 33) {
495 if (opt.Contains(
"z")) fHistogram->Draw(
"func z");
496 else fHistogram->Draw(
"func");
499 Int_t noscat = opt.Length();
500 if (opt.Contains(
"same")) noscat -= 4;
502 if (draw) fHistogram->Draw(opt.Data());
504 if (fSelector->GetOldHistogram() && draw) fHistogram->Draw(opt.Data());
508 }
else if (fDimension == 4 && !(optpara||optcandle)) {
509 if (fSelector->GetVar1()->IsInteger()) fHistogram->LabelsDeflate(
"Z");
510 if (fSelector->GetVar2()->IsInteger()) fHistogram->LabelsDeflate(
"Y");
511 if (fSelector->GetVar3()->IsInteger()) fHistogram->LabelsDeflate(
"X");
512 if (draw) fHistogram->Draw(opt.Data());
513 Int_t ncolors = gStyle->GetNumberOfColors();
514 TObjArray *pms = (TObjArray*)fHistogram->GetListOfFunctions()->FindObject(
"polymarkers");
515 for (Int_t col=0;col<ncolors;col++) {
517 TPolyMarker3D *pm3d = (TPolyMarker3D*)pms->UncheckedAt(col);
518 if (draw) pm3d->Draw();
521 }
else if (fDimension > 1 && (optpara || optcandle)) {
523 TObject* para = fSelector->GetObject();
524 fTree->Draw(
">>enlist",selection,
"entrylist",nentries,firstentry);
525 TObject *enlist = gDirectory->FindObject(
"enlist");
526 gROOT->ProcessLine(Form(
"TParallelCoord::SetEntryList((TParallelCoord*)0x%lx,(TEntryList*)0x%lx)",
527 (ULong_t)para, (ULong_t)enlist));
530 }
else if (fDimension == 5 && optgl5d) {
531 gROOT->ProcessLineFast(Form(
"(new TGL5DDataSet((TTree *)0x%lx))->Draw(\"%s\");", (ULong_t)fTree, opt.Data()));
532 gStyle->SetCanvasPreferGL(pgl);
535 if (fHistogram) fHistogram->SetCanExtend(TH1::kNoAxis);
536 return fSelectedRows;
561 Int_t TTreePlayer::Fit(
const char *formula ,
const char *varexp,
const char *selection,Option_t *option ,Option_t *goption,Long64_t nentries, Long64_t firstentry)
563 Int_t nch = option ? strlen(option) + 10 : 10;
564 char *opt =
new char[nch];
565 if (option) strlcpy(opt,option,nch-1);
566 else strlcpy(opt,
"goff",5);
568 Long64_t nsel = DrawSelect(varexp,selection,opt,nentries,firstentry);
571 Int_t fitResult = -1;
573 if (fHistogram && nsel > 0) {
574 fitResult = fHistogram->Fit(formula,option,goption);
591 Long64_t TTreePlayer::GetEntries(
const char *selection)
593 TSelectorEntries s(selection);
596 return s.GetSelectedRows();
604 Long64_t TTreePlayer::GetEntriesToProcess(Long64_t firstentry, Long64_t nentries)
const
606 Long64_t lastentry = firstentry + nentries - 1;
607 if (lastentry > fTree->GetEntriesFriend()-1) {
608 lastentry = fTree->GetEntriesFriend() - 1;
609 nentries = lastentry - firstentry + 1;
613 TEntryList *elist = fTree->GetEntryList();
614 if (elist && elist->GetN() < nentries) nentries = elist->GetN();
624 const char *TTreePlayer::GetNameByIndex(TString &varexp, Int_t *index,Int_t colindex)
626 TTHREAD_TLS_DECL(std::string,column);
627 if (colindex<0 )
return "";
629 i1 = index[colindex] + 1;
630 n = index[colindex+1] - i1;
631 column = varexp(i1,n).Data();
633 return column.c_str();
639 static TString R__GetBranchPointerName(TLeaf *leaf, Bool_t replace = kTRUE)
641 TLeaf *leafcount = leaf->GetLeafCount();
642 TBranch *branch = leaf->GetBranch();
644 TString branchname( branch->GetName() );
646 if ( branch->GetNleaves() <= 1 ) {
647 if (branch->IsA() != TBranchObject::Class()) {
649 TBranch *mother = branch->GetMother();
650 const char* ltitle = leaf->GetTitle();
651 if (mother && mother!=branch) {
652 branchname = mother->GetName();
653 if (branchname[branchname.Length()-1]!=
'.') {
656 if (strncmp(branchname.Data(),ltitle,branchname.Length())==0) {
662 branchname += ltitle;
667 char *bname = (
char*)branchname.Data();
668 char *twodim = (
char*)strstr(bname,
"[");
669 if (twodim) *twodim = 0;
671 if (*bname ==
'.') *bname=
'_';
672 if (*bname ==
',') *bname=
'_';
673 if (*bname ==
':') *bname=
'_';
674 if (*bname ==
'<') *bname=
'_';
675 if (*bname ==
'>') *bname=
'_';
720 Int_t TTreePlayer::MakeClass(
const char *classname,
const char *option)
722 TString opt = option;
726 if (!classname) classname = fTree->GetName();
729 thead.Form(
"%s.h", classname);
730 FILE *fp = fopen(thead,
"w");
732 Error(
"MakeClass",
"cannot open output file %s", thead.Data());
736 tcimp.Form(
"%s.C", classname);
737 FILE *fpc = fopen(tcimp,
"w");
739 Error(
"MakeClass",
"cannot open output file %s", tcimp.Data());
744 if (fTree->GetDirectory() && fTree->GetDirectory()->GetFile()) {
745 treefile = fTree->GetDirectory()->GetFile()->GetName();
747 treefile =
"Memory Directory";
752 Bool_t ischain = fTree->InheritsFrom(TChain::Class());
753 Bool_t isHbook = fTree->InheritsFrom(
"THbookTree");
755 treefile = fTree->GetTitle();
759 TObjArray *leaves = fTree->GetListOfLeaves();
760 Int_t nleaves = leaves ? leaves->GetEntriesFast() : 0;
762 fprintf(fp,
"//////////////////////////////////////////////////////////\n");
763 fprintf(fp,
"// This class has been automatically generated on\n");
764 fprintf(fp,
"// %s by ROOT version %s\n",td.AsString(),gROOT->GetVersion());
766 fprintf(fp,
"// from TTree %s/%s\n",fTree->GetName(),fTree->GetTitle());
767 fprintf(fp,
"// found on file: %s\n",treefile.Data());
769 fprintf(fp,
"// from TChain %s/%s\n",fTree->GetName(),fTree->GetTitle());
771 fprintf(fp,
"//////////////////////////////////////////////////////////\n");
773 fprintf(fp,
"#ifndef %s_h\n",classname);
774 fprintf(fp,
"#define %s_h\n",classname);
776 fprintf(fp,
"#include <TROOT.h>\n");
777 fprintf(fp,
"#include <TChain.h>\n");
778 fprintf(fp,
"#include <TFile.h>\n");
779 if (isHbook) fprintf(fp,
"#include <THbookFile.h>\n");
780 if (opt.Contains(
"selector")) fprintf(fp,
"#include <TSelector.h>\n");
784 fprintf(fp,
"\n// Header file for the classes stored in the TTree if any.\n");
786 listOfHeaders.SetOwner();
787 for (l=0;l<nleaves;l++) {
788 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
789 TBranch *branch = leaf->GetBranch();
790 TClass *cl = TClass::GetClass(branch->GetClassName());
791 if (cl && cl->IsLoaded() && !listOfHeaders.FindObject(cl->GetName())) {
792 const char *declfile = cl->GetDeclFileName();
793 if (declfile && declfile[0]) {
794 static const char *precstl =
"prec_stl/";
795 static const unsigned int precstl_len = strlen(precstl);
796 static const char *rootinclude =
"include/";
797 static const unsigned int rootinclude_len = strlen(rootinclude);
798 if (strncmp(declfile,precstl,precstl_len) == 0) {
799 fprintf(fp,
"#include <%s>\n",declfile+precstl_len);
800 listOfHeaders.Add(
new TNamed(cl->GetName(),declfile+precstl_len));
801 }
else if (strncmp(declfile,
"/usr/include/",13) == 0) {
802 fprintf(fp,
"#include <%s>\n",declfile+strlen(
"/include/c++/"));
803 listOfHeaders.Add(
new TNamed(cl->GetName(),declfile+strlen(
"/include/c++/")));
804 }
else if (strstr(declfile,
"/include/c++/") != 0) {
805 fprintf(fp,
"#include <%s>\n",declfile+strlen(
"/include/c++/"));
806 listOfHeaders.Add(
new TNamed(cl->GetName(),declfile+strlen(
"/include/c++/")));
807 }
else if (strncmp(declfile,rootinclude,rootinclude_len) == 0) {
808 fprintf(fp,
"#include <%s>\n",declfile+rootinclude_len);
809 listOfHeaders.Add(
new TNamed(cl->GetName(),declfile+rootinclude_len));
811 fprintf(fp,
"#include \"%s\"\n",declfile);
812 listOfHeaders.Add(
new TNamed(cl->GetName(),declfile));
822 Int_t *leaflen =
new Int_t[nleaves];
823 TObjArray *leafs =
new TObjArray(nleaves);
824 for (l=0;l<nleaves;l++) {
825 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
826 leafs->AddAt(
new TObjString(leaf->GetName()),l);
827 leaflen[l] = leaf->GetMaximum();
833 TChain *chain = (TChain*)fTree;
834 Int_t ntrees = chain->GetNtrees();
835 for (Int_t file=0;file<ntrees;file++) {
836 Long64_t first = chain->GetTreeOffset()[file];
837 chain->LoadTree(first);
838 for (l=0;l<nleaves;l++) {
839 TObjString *obj = (TObjString*)leafs->At(l);
840 TLeaf *leaf = chain->GetLeaf(obj->GetName());
842 leaflen[l] = TMath::Max(leaflen[l],leaf->GetMaximum());
850 if (opt.Contains(
"selector")) {
851 fprintf(fp,
"class %s : public TSelector {\n",classname);
852 fprintf(fp,
"public :\n");
853 fprintf(fp,
" TTree *fChain; //!pointer to the analyzed TTree or TChain\n");
855 fprintf(fp,
"class %s {\n",classname);
856 fprintf(fp,
"public :\n");
857 fprintf(fp,
" TTree *fChain; //!pointer to the analyzed TTree or TChain\n");
858 fprintf(fp,
" Int_t fCurrent; //!current Tree number in a TChain\n");
861 fprintf(fp,
"\n// Fixed size dimensions of array or collections stored in the TTree if any.\n");
862 leaves = fTree->GetListOfLeaves();
863 for (l=0;l<nleaves;l++) {
864 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
865 strlcpy(blen,leaf->GetName(),
sizeof(blen));
868 if (*bname ==
'.') *bname=
'_';
869 if (*bname ==
',') *bname=
'_';
870 if (*bname ==
':') *bname=
'_';
871 if (*bname ==
'<') *bname=
'_';
872 if (*bname ==
'>') *bname=
'_';
876 if (blen[lenb-1] ==
'_') {
879 if (len <= 0) len = 1;
880 fprintf(fp,
" static constexpr Int_t kMax%s = %d;\n",blen,len);
888 fprintf(fp,
"\n // Declaration of leaf types\n");
890 TLeafObject *leafobj;
891 TBranchElement *bre=0;
892 const char *headOK =
" ";
893 const char *headcom =
" //";
895 char branchname[1024];
897 TObjArray branches(100);
898 TObjArray mustInit(100);
899 TObjArray mustInitArr(100);
900 mustInitArr.SetOwner(kFALSE);
901 Int_t *leafStatus =
new Int_t[nleaves];
902 for (l=0;l<nleaves;l++) {
906 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
907 len = leaf->GetLen();
if (len<=0) len = 1;
908 leafcount =leaf->GetLeafCount();
909 TBranch *branch = leaf->GetBranch();
911 strlcpy(branchname,branch->GetName(),
sizeof(branchname));
912 strlcpy(aprefix,branch->GetName(),
sizeof(aprefix));
913 if (!branches.FindObject(branch)) branches.Add(branch);
914 else leafStatus[l] = 1;
915 if ( branch->GetNleaves() > 1) {
917 strlcat(branchname,
".",
sizeof(branchname));
918 strlcat(branchname,leaf->GetTitle(),
sizeof(branchname));
921 char *dim = (
char*)strstr(branchname,
"[");
if (dim) dim[0] = 0;
924 strlcpy(branchname,branch->GetName(),
sizeof(branchname));
926 char *twodim = (
char*)strstr(leaf->GetTitle(),
"][");
929 if (*bname ==
'.') *bname=
'_';
930 if (*bname ==
',') *bname=
'_';
931 if (*bname ==
':') *bname=
'_';
932 if (*bname ==
'<') *bname=
'_';
933 if (*bname ==
'>') *bname=
'_';
936 if (branch->IsA() == TBranchObject::Class()) {
937 if (branch->GetListOfBranches()->GetEntriesFast()) {leafStatus[l] = 1;
continue;}
938 leafobj = (TLeafObject*)leaf;
939 if (!leafobj->GetClass()) {leafStatus[l] = 1; head = headcom;}
940 fprintf(fp,
"%s%-15s *%s;\n",head,leafobj->GetTypeName(), leafobj->GetName());
941 if (leafStatus[l] == 0) mustInit.Add(leafobj);
945 len = leafcount->GetMaximum();
947 strlcpy(blen,leafcount->GetName(),
sizeof(blen));
950 if (*bname ==
'.') *bname=
'_';
951 if (*bname ==
',') *bname=
'_';
952 if (*bname ==
':') *bname=
'_';
953 if (*bname ==
'<') *bname=
'_';
954 if (*bname ==
'>') *bname=
'_';
958 if (blen[lenb-1] ==
'_') {blen[lenb-1] = 0; kmax = 1;}
959 else snprintf(blen,
sizeof(blen),
"%d",len);
961 if (branch->IsA() == TBranchElement::Class()) {
962 bre = (TBranchElement*)branch;
963 if (bre->GetType() != 3 && bre->GetType() != 4
964 && bre->GetStreamerType() <= 0 && bre->GetListOfBranches()->GetEntriesFast()) {
967 if (bre->GetType() == 3 || bre->GetType() == 4) {
968 fprintf(fp,
" %-15s %s_;\n",
"Int_t", branchname);
971 if (bre->IsBranchFolder()) {
972 fprintf(fp,
" %-15s *%s;\n",bre->GetClassName(), branchname);
976 if (branch->GetListOfBranches()->GetEntriesFast()) {leafStatus[l] = 1;}
978 if (bre->GetStreamerType() < 0) {
979 if (branch->GetListOfBranches()->GetEntriesFast()) {
980 fprintf(fp,
"%s%-15s *%s;\n",headcom,bre->GetClassName(), branchname);
982 fprintf(fp,
"%s%-15s *%s;\n",head,bre->GetClassName(), branchname);
987 if (bre->GetStreamerType() == 0) {
988 if (!TClass::GetClass(bre->GetClassName())->HasInterpreterInfo()) {leafStatus[l] = 1; head = headcom;}
989 fprintf(fp,
"%s%-15s *%s;\n",head,bre->GetClassName(), branchname);
990 if (leafStatus[l] == 0) mustInit.Add(bre);
993 if (bre->GetStreamerType() > 60) {
994 TClass *cle = TClass::GetClass(bre->GetClassName());
995 if (!cle) {leafStatus[l] = 1;
continue;}
996 if (bre->GetStreamerType() == 66) leafStatus[l] = 0;
998 strlcpy(brename,bre->GetName(),255);
999 char *bren = brename;
1000 char *adot = strrchr(bren,
'.');
1001 if (adot) bren = adot+1;
1002 char *brack = strchr(bren,
'[');
1003 if (brack) *brack = 0;
1004 TStreamerElement *elem = (TStreamerElement*)cle->GetStreamerInfo()->GetElements()->FindObject(bren);
1006 if (elem->IsA() == TStreamerBase::Class()) {leafStatus[l] = 1;
continue;}
1007 if (!TClass::GetClass(elem->GetTypeName())) {leafStatus[l] = 1;
continue;}
1008 if (!TClass::GetClass(elem->GetTypeName())->HasInterpreterInfo()) {leafStatus[l] = 1; head = headcom;}
1009 if (leafcount) fprintf(fp,
"%s%-15s %s[kMax%s];\n",head,elem->GetTypeName(), branchname,blen);
1010 else fprintf(fp,
"%s%-15s %s;\n",head,elem->GetTypeName(), branchname);
1012 if (!TClass::GetClass(bre->GetClassName())->HasInterpreterInfo()) {leafStatus[l] = 1; head = headcom;}
1013 fprintf(fp,
"%s%-15s %s;\n",head,bre->GetClassName(), branchname);
1018 if (strlen(leaf->GetTypeName()) == 0) {leafStatus[l] = 1;
continue;}
1029 const char *stars =
" ";
1030 if (bre && bre->GetBranchCount2()) {
1036 char *dimInName = (
char*) strstr(branchname,
"[");
1037 if ( twodim || dimInName ) {
1039 dimensions = dimInName;
1042 if (twodim) dimensions += (
char*)(twodim+1);
1044 const char* leafcountName = leafcount->GetName();
1046 if (bre && bre->GetBranchCount2()) {
1047 TLeaf * l2 = (TLeaf*)bre->GetBranchCount2()->GetListOfLeaves()->At(0);
1048 strlcpy(b2len,l2->GetName(),
sizeof(b2len));
1051 if (*bname ==
'.') *bname=
'_';
1052 if (*bname ==
',') *bname=
'_';
1053 if (*bname ==
':') *bname=
'_';
1054 if (*bname ==
'<') *bname=
'_';
1055 if (*bname ==
'>') *bname=
'_';
1058 leafcountName = b2len;
1060 if (dimensions.Length()) {
1061 if (kmax) fprintf(fp,
" %-14s %s%s[kMax%s]%s; //[%s]\n",leaf->GetTypeName(), stars,
1062 branchname,blen,dimensions.Data(),leafcountName);
1063 else fprintf(fp,
" %-14s %s%s[%d]%s; //[%s]\n",leaf->GetTypeName(), stars,
1064 branchname,len,dimensions.Data(),leafcountName);
1066 if (kmax) fprintf(fp,
" %-14s %s%s[kMax%s]; //[%s]\n",leaf->GetTypeName(), stars, branchname,blen,leafcountName);
1067 else fprintf(fp,
" %-14s %s%s[%d]; //[%s]\n",leaf->GetTypeName(), stars, branchname,len,leafcountName);
1069 if (stars[0]==
'*') {
1071 if (kmax) n =
new TNamed(branchname, Form(
"kMax%s",blen));
1072 else n =
new TNamed(branchname, Form(
"%d",len));
1076 if (strstr(branchname,
"[")) len = 1;
1077 if (len < 2) fprintf(fp,
" %-15s %s;\n",leaf->GetTypeName(), branchname);
1079 if (twodim) fprintf(fp,
" %-15s %s%s;\n",leaf->GetTypeName(), branchname,(
char*)strstr(leaf->GetTitle(),
"["));
1080 else fprintf(fp,
" %-15s %s[%d];\n",leaf->GetTypeName(), branchname,len);
1087 fprintf(fp,
" // List of branches\n");
1088 for (l=0;l<nleaves;l++) {
1089 if (leafStatus[l])
continue;
1090 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
1091 fprintf(fp,
" TBranch *b_%s; //!\n",R__GetBranchPointerName(leaf).Data());
1095 if (opt.Contains(
"selector")) {
1097 fprintf(fp,
" %s(TTree * /*tree*/ =0) : fChain(0) { }\n",classname) ;
1098 fprintf(fp,
" virtual ~%s() { }\n",classname);
1099 fprintf(fp,
" virtual Int_t Version() const { return 2; }\n");
1100 fprintf(fp,
" virtual void Begin(TTree *tree);\n");
1101 fprintf(fp,
" virtual void SlaveBegin(TTree *tree);\n");
1102 fprintf(fp,
" virtual void Init(TTree *tree);\n");
1103 fprintf(fp,
" virtual Bool_t Notify();\n");
1104 fprintf(fp,
" virtual Bool_t Process(Long64_t entry);\n");
1105 fprintf(fp,
" virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }\n");
1106 fprintf(fp,
" virtual void SetOption(const char *option) { fOption = option; }\n");
1107 fprintf(fp,
" virtual void SetObject(TObject *obj) { fObject = obj; }\n");
1108 fprintf(fp,
" virtual void SetInputList(TList *input) { fInput = input; }\n");
1109 fprintf(fp,
" virtual TList *GetOutputList() const { return fOutput; }\n");
1110 fprintf(fp,
" virtual void SlaveTerminate();\n");
1111 fprintf(fp,
" virtual void Terminate();\n\n");
1112 fprintf(fp,
" ClassDef(%s,0);\n",classname);
1115 fprintf(fp,
"#endif\n");
1119 fprintf(fp,
" %s(TTree *tree=0);\n",classname);
1120 fprintf(fp,
" virtual ~%s();\n",classname);
1121 fprintf(fp,
" virtual Int_t Cut(Long64_t entry);\n");
1122 fprintf(fp,
" virtual Int_t GetEntry(Long64_t entry);\n");
1123 fprintf(fp,
" virtual Long64_t LoadTree(Long64_t entry);\n");
1124 fprintf(fp,
" virtual void Init(TTree *tree);\n");
1125 fprintf(fp,
" virtual void Loop();\n");
1126 fprintf(fp,
" virtual Bool_t Notify();\n");
1127 fprintf(fp,
" virtual void Show(Long64_t entry = -1);\n");
1130 fprintf(fp,
"#endif\n");
1134 fprintf(fp,
"#ifdef %s_cxx\n",classname);
1135 if (!opt.Contains(
"selector")) {
1136 fprintf(fp,
"%s::%s(TTree *tree) : fChain(0) \n",classname,classname);
1138 fprintf(fp,
"// if parameter tree is not specified (or zero), connect the file\n");
1139 fprintf(fp,
"// used to generate this class and read the Tree.\n");
1140 fprintf(fp,
" if (tree == 0) {\n");
1142 fprintf(fp,
"\n#ifdef SINGLE_TREE\n");
1143 fprintf(fp,
" // The following code should be used if you want this class to access\n");
1144 fprintf(fp,
" // a single tree instead of a chain\n");
1147 fprintf(fp,
" THbookFile *f = (THbookFile*)gROOT->GetListOfBrowsables()->FindObject(\"%s\");\n",
1149 fprintf(fp,
" if (!f) {\n");
1150 fprintf(fp,
" f = new THbookFile(\"%s\");\n",treefile.Data());
1153 sscanf(fTree->GetName(),
"h%d",&hid);
1154 fprintf(fp,
" tree = (TTree*)f->Get(%d);\n\n",hid);
1156 fprintf(fp,
" TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(\"%s\");\n",treefile.Data());
1157 fprintf(fp,
" if (!f || !f->IsOpen()) {\n");
1158 fprintf(fp,
" f = new TFile(\"%s\");\n",treefile.Data());
1160 if (fTree->GetDirectory() != fTree->GetCurrentFile()) {
1161 fprintf(fp,
" TDirectory * dir = (TDirectory*)f->Get(\"%s\");\n",fTree->GetDirectory()->GetPath());
1162 fprintf(fp,
" dir->GetObject(\"%s\",tree);\n\n",fTree->GetName());
1164 fprintf(fp,
" f->GetObject(\"%s\",tree);\n\n",fTree->GetName());
1168 fprintf(fp,
"#else // SINGLE_TREE\n\n");
1169 fprintf(fp,
" // The following code should be used if you want this class to access a chain\n");
1170 fprintf(fp,
" // of trees.\n");
1171 fprintf(fp,
" TChain * chain = new TChain(\"%s\",\"%s\");\n",
1172 fTree->GetName(),fTree->GetTitle());
1174 R__LOCKGUARD(gROOTMutex);
1175 TIter next(((TChain*)fTree)->GetListOfFiles());
1176 TChainElement *element;
1177 while ((element = (TChainElement*)next())) {
1178 fprintf(fp,
" chain->Add(\"%s/%s\");\n",element->GetTitle(),element->GetName());
1181 fprintf(fp,
" tree = chain;\n");
1182 fprintf(fp,
"#endif // SINGLE_TREE\n\n");
1185 fprintf(fp,
" Init(tree);\n");
1191 if (!opt.Contains(
"selector")) {
1192 fprintf(fp,
"%s::~%s()\n",classname,classname);
1194 fprintf(fp,
" if (!fChain) return;\n");
1198 fprintf(fp,
" delete fChain->GetCurrentFile();\n");
1204 if (!opt.Contains(
"selector")) {
1205 fprintf(fp,
"Int_t %s::GetEntry(Long64_t entry)\n",classname);
1207 fprintf(fp,
"// Read contents of entry.\n");
1209 fprintf(fp,
" if (!fChain) return 0;\n");
1210 fprintf(fp,
" return fChain->GetEntry(entry);\n");
1214 if (!opt.Contains(
"selector")) {
1215 fprintf(fp,
"Long64_t %s::LoadTree(Long64_t entry)\n",classname);
1217 fprintf(fp,
"// Set the environment to read one entry\n");
1218 fprintf(fp,
" if (!fChain) return -5;\n");
1219 fprintf(fp,
" Long64_t centry = fChain->LoadTree(entry);\n");
1220 fprintf(fp,
" if (centry < 0) return centry;\n");
1221 fprintf(fp,
" if (fChain->GetTreeNumber() != fCurrent) {\n");
1222 fprintf(fp,
" fCurrent = fChain->GetTreeNumber();\n");
1223 fprintf(fp,
" Notify();\n");
1225 fprintf(fp,
" return centry;\n");
1231 fprintf(fp,
"void %s::Init(TTree *tree)\n",classname);
1233 fprintf(fp,
" // The Init() function is called when the selector needs to initialize\n"
1234 " // a new tree or chain. Typically here the branch addresses and branch\n"
1235 " // pointers of the tree will be set.\n"
1236 " // It is normally not necessary to make changes to the generated\n"
1237 " // code, but the routine can be extended by the user if needed.\n"
1238 " // Init() will be called many times when running on PROOF\n"
1239 " // (once per file to be processed).\n\n");
1240 if (mustInit.Last()) {
1241 TIter next(&mustInit);
1243 fprintf(fp,
" // Set object pointer\n");
1244 while( (obj = next()) ) {
1245 if (obj->InheritsFrom(TBranch::Class())) {
1246 strlcpy(branchname,((TBranch*)obj)->GetName(),
sizeof(branchname));
1247 }
else if (obj->InheritsFrom(TLeaf::Class())) {
1248 strlcpy(branchname,((TLeaf*)obj)->GetName(),
sizeof(branchname));
1253 if (*bname ==
'.') *bname=
'_';
1254 if (*bname ==
',') *bname=
'_';
1255 if (*bname ==
':') *bname=
'_';
1256 if (*bname ==
'<') *bname=
'_';
1257 if (*bname ==
'>') *bname=
'_';
1260 fprintf(fp,
" %s = 0;\n",branchname );
1263 if (mustInitArr.Last()) {
1264 TIter next(&mustInitArr);
1266 fprintf(fp,
" // Set array pointer\n");
1267 while( (info = (TNamed*)next()) ) {
1268 fprintf(fp,
" for(int i=0; i<%s; ++i) %s[i] = 0;\n",info->GetTitle(),info->GetName());
1272 fprintf(fp,
" // Set branch addresses and branch pointers\n");
1273 fprintf(fp,
" if (!tree) return;\n");
1274 fprintf(fp,
" fChain = tree;\n");
1275 if (!opt.Contains(
"selector")) fprintf(fp,
" fCurrent = -1;\n");
1276 fprintf(fp,
" fChain->SetMakeClass(1);\n");
1278 for (l=0;l<nleaves;l++) {
1279 if (leafStatus[l])
continue;
1280 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
1281 len = leaf->GetLen();
1282 leafcount =leaf->GetLeafCount();
1283 TBranch *branch = leaf->GetBranch();
1284 strlcpy(aprefix,branch->GetName(),
sizeof(aprefix));
1286 if ( branch->GetNleaves() > 1) {
1288 strlcpy(branchname,branch->GetName(),
sizeof(branchname));
1289 strlcat(branchname,
".",
sizeof(branchname));
1290 strlcat(branchname,leaf->GetTitle(),
sizeof(branchname));
1293 char *dim = (
char*)strstr(branchname,
"[");
if (dim) dim[0] = 0;
1296 strlcpy(branchname,branch->GetName(),
sizeof(branchname));
1297 if (branch->IsA() == TBranchElement::Class()) {
1298 bre = (TBranchElement*)branch;
1299 if (bre->GetType() == 3 || bre->GetType()==4) strlcat(branchname,
"_",
sizeof(branchname));
1303 char *brak = strstr(branchname,
"[");
if (brak) *brak = 0;
1304 char *twodim = (
char*)strstr(bname,
"[");
if (twodim) *twodim = 0;
1306 if (*bname ==
'.') *bname=
'_';
1307 if (*bname ==
',') *bname=
'_';
1308 if (*bname ==
':') *bname=
'_';
1309 if (*bname ==
'<') *bname=
'_';
1310 if (*bname ==
'>') *bname=
'_';
1313 const char *maybedisable =
"";
1314 if (branch != fTree->GetBranch(branch->GetName())) {
1315 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());
1316 maybedisable =
"// ";
1318 if (branch->IsA() == TBranchObject::Class()) {
1319 if (branch->GetListOfBranches()->GetEntriesFast()) {
1320 fprintf(fp,
"%s fChain->SetBranchAddress(\"%s\",(void*)-1,&b_%s);\n",maybedisable,branch->GetName(),R__GetBranchPointerName(leaf).Data());
1323 strlcpy(branchname,branch->GetName(),
sizeof(branchname));
1325 if (branch->IsA() == TBranchElement::Class()) {
1326 if (((TBranchElement*)branch)->GetType() == 3) len =1;
1327 if (((TBranchElement*)branch)->GetType() == 4) len =1;
1329 if (leafcount) len = leafcount->GetMaximum()+1;
1330 if (len > 1) fprintf(fp,
"%s fChain->SetBranchAddress(\"%s\", %s, &b_%s);\n",
1331 maybedisable,branch->GetName(), branchname, R__GetBranchPointerName(leaf).Data());
1332 else fprintf(fp,
"%s fChain->SetBranchAddress(\"%s\", &%s, &b_%s);\n",
1333 maybedisable,branch->GetName(), branchname, R__GetBranchPointerName(leaf).Data());
1336 if (!opt.Contains(
"selector")) {
1337 fprintf(fp,
" Notify();\n");
1344 fprintf(fp,
"Bool_t %s::Notify()\n",classname);
1346 fprintf(fp,
" // The Notify() function is called when a new file is opened. This\n"
1347 " // can be either for a new TTree in a TChain or when when a new TTree\n"
1348 " // is started when using PROOF. It is normally not necessary to make changes\n"
1349 " // to the generated code, but the routine can be extended by the\n"
1350 " // user if needed. The return value is currently not used.\n\n");
1351 fprintf(fp,
" return kTRUE;\n");
1356 if (!opt.Contains(
"selector")) {
1357 fprintf(fp,
"void %s::Show(Long64_t entry)\n",classname);
1359 fprintf(fp,
"// Print contents of entry.\n");
1360 fprintf(fp,
"// If entry is not specified, print current entry\n");
1362 fprintf(fp,
" if (!fChain) return;\n");
1363 fprintf(fp,
" fChain->Show(entry);\n");
1367 if (!opt.Contains(
"selector")) {
1368 fprintf(fp,
"Int_t %s::Cut(Long64_t entry)\n",classname);
1370 fprintf(fp,
"// This function may be called from Loop.\n");
1371 fprintf(fp,
"// returns 1 if entry is accepted.\n");
1372 fprintf(fp,
"// returns -1 otherwise.\n");
1374 fprintf(fp,
" return 1;\n");
1377 fprintf(fp,
"#endif // #ifdef %s_cxx\n",classname);
1380 if (!opt.Contains(
"selector")) {
1382 fprintf(fpc,
"#define %s_cxx\n",classname);
1383 fprintf(fpc,
"#include \"%s\"\n",thead.Data());
1384 fprintf(fpc,
"#include <TH2.h>\n");
1385 fprintf(fpc,
"#include <TStyle.h>\n");
1386 fprintf(fpc,
"#include <TCanvas.h>\n");
1388 fprintf(fpc,
"void %s::Loop()\n",classname);
1390 fprintf(fpc,
"// In a ROOT session, you can do:\n");
1391 fprintf(fpc,
"// root> .L %s.C\n",classname);
1392 fprintf(fpc,
"// root> %s t\n",classname);
1393 fprintf(fpc,
"// root> t.GetEntry(12); // Fill t data members with entry number 12\n");
1394 fprintf(fpc,
"// root> t.Show(); // Show values of entry 12\n");
1395 fprintf(fpc,
"// root> t.Show(16); // Read and show values of entry 16\n");
1396 fprintf(fpc,
"// root> t.Loop(); // Loop on all entries\n");
1397 fprintf(fpc,
"//\n");
1398 fprintf(fpc,
"\n// This is the loop skeleton where:\n");
1399 fprintf(fpc,
"// jentry is the global entry number in the chain\n");
1400 fprintf(fpc,
"// ientry is the entry number in the current Tree\n");
1401 fprintf(fpc,
"// Note that the argument to GetEntry must be:\n");
1402 fprintf(fpc,
"// jentry for TChain::GetEntry\n");
1403 fprintf(fpc,
"// ientry for TTree::GetEntry and TBranch::GetEntry\n");
1404 fprintf(fpc,
"//\n");
1405 fprintf(fpc,
"// To read only selected branches, Insert statements like:\n");
1406 fprintf(fpc,
"// METHOD1:\n");
1407 fprintf(fpc,
"// fChain->SetBranchStatus(\"*\",0); // disable all branches\n");
1408 fprintf(fpc,
"// fChain->SetBranchStatus(\"branchname\",1); // activate branchname\n");
1409 fprintf(fpc,
"// METHOD2: replace line\n");
1410 fprintf(fpc,
"// fChain->GetEntry(jentry); //read all branches\n");
1411 fprintf(fpc,
"//by b_branchname->GetEntry(ientry); //read only this branch\n");
1412 fprintf(fpc,
" if (fChain == 0) return;\n");
1413 fprintf(fpc,
"\n Long64_t nentries = fChain->GetEntriesFast();\n");
1414 fprintf(fpc,
"\n Long64_t nbytes = 0, nb = 0;\n");
1415 fprintf(fpc,
" for (Long64_t jentry=0; jentry<nentries;jentry++) {\n");
1416 fprintf(fpc,
" Long64_t ientry = LoadTree(jentry);\n");
1417 fprintf(fpc,
" if (ientry < 0) break;\n");
1418 fprintf(fpc,
" nb = fChain->GetEntry(jentry); nbytes += nb;\n");
1419 fprintf(fpc,
" // if (Cut(ientry) < 0) continue;\n");
1420 fprintf(fpc,
" }\n");
1423 if (opt.Contains(
"selector")) {
1425 fprintf(fpc,
"#define %s_cxx\n",classname);
1426 fprintf(fpc,
"// The class definition in %s.h has been generated automatically\n",classname);
1427 fprintf(fpc,
"// by the ROOT utility TTree::MakeSelector(). This class is derived\n");
1428 fprintf(fpc,
"// from the ROOT class TSelector. For more information on the TSelector\n"
1429 "// framework see $ROOTSYS/README/README.SELECTOR or the ROOT User Manual.\n\n");
1430 fprintf(fpc,
"// The following methods are defined in this file:\n");
1431 fprintf(fpc,
"// Begin(): called every time a loop on the tree starts,\n");
1432 fprintf(fpc,
"// a convenient place to create your histograms.\n");
1433 fprintf(fpc,
"// SlaveBegin(): called after Begin(), when on PROOF called only on the\n"
1434 "// slave servers.\n");
1435 fprintf(fpc,
"// Process(): called for each event, in this function you decide what\n");
1436 fprintf(fpc,
"// to read and fill your histograms.\n");
1437 fprintf(fpc,
"// SlaveTerminate: called at the end of the loop on the tree, when on PROOF\n"
1438 "// called only on the slave servers.\n");
1439 fprintf(fpc,
"// Terminate(): called at the end of the loop on the tree,\n");
1440 fprintf(fpc,
"// a convenient place to draw/fit your histograms.\n");
1441 fprintf(fpc,
"//\n");
1442 fprintf(fpc,
"// To use this file, try the following session on your Tree T:\n");
1443 fprintf(fpc,
"//\n");
1444 fprintf(fpc,
"// root> T->Process(\"%s.C\")\n",classname);
1445 fprintf(fpc,
"// root> T->Process(\"%s.C\",\"some options\")\n",classname);
1446 fprintf(fpc,
"// root> T->Process(\"%s.C+\")\n",classname);
1447 fprintf(fpc,
"//\n\n");
1448 fprintf(fpc,
"#include \"%s\"\n",thead.Data());
1449 fprintf(fpc,
"#include <TH2.h>\n");
1450 fprintf(fpc,
"#include <TStyle.h>\n");
1454 fprintf(fpc,
"void %s::Begin(TTree * /*tree*/)\n",classname);
1456 fprintf(fpc,
" // The Begin() function is called at the start of the query.\n");
1457 fprintf(fpc,
" // When running with PROOF Begin() is only called on the client.\n");
1458 fprintf(fpc,
" // The tree argument is deprecated (on PROOF 0 is passed).\n");
1460 fprintf(fpc,
" TString option = GetOption();\n");
1465 fprintf(fpc,
"void %s::SlaveBegin(TTree * /*tree*/)\n",classname);
1467 fprintf(fpc,
" // The SlaveBegin() function is called after the Begin() function.\n");
1468 fprintf(fpc,
" // When running with PROOF SlaveBegin() is called on each slave server.\n");
1469 fprintf(fpc,
" // The tree argument is deprecated (on PROOF 0 is passed).\n");
1471 fprintf(fpc,
" TString option = GetOption();\n");
1476 fprintf(fpc,
"Bool_t %s::Process(Long64_t entry)\n",classname);
1478 fprintf(fpc,
" // The Process() function is called for each entry in the tree (or possibly\n"
1479 " // keyed object in the case of PROOF) to be processed. The entry argument\n"
1480 " // specifies which entry in the currently loaded tree is to be processed.\n"
1481 " // It can be passed to either %s::GetEntry() or TBranch::GetEntry()\n"
1482 " // to read either all or the required parts of the data. When processing\n"
1483 " // keyed objects with PROOF, the object is already loaded and is available\n"
1484 " // via the fObject pointer.\n"
1486 " // This function should contain the \"body\" of the analysis. It can contain\n"
1487 " // simple or elaborate selection criteria, run algorithms on the data\n"
1488 " // of the event and typically fill histograms.\n"
1490 " // The processing can be stopped by calling Abort().\n"
1492 " // Use fStatus to set the return value of TTree::Process().\n"
1494 " // The return value is currently not used.\n\n", classname);
1496 fprintf(fpc,
" return kTRUE;\n");
1500 fprintf(fpc,
"void %s::SlaveTerminate()\n",classname);
1502 fprintf(fpc,
" // The SlaveTerminate() function is called after all entries or objects\n"
1503 " // have been processed. When running with PROOF SlaveTerminate() is called\n"
1504 " // on each slave server.");
1510 fprintf(fpc,
"void %s::Terminate()\n",classname);
1512 fprintf(fpc,
" // The Terminate() function is the last function to be called during\n"
1513 " // a query. It always runs on the client, it can be used to present\n"
1514 " // the results graphically or save the results to file.");
1519 Info(
"MakeClass",
"Files: %s and %s generated from TTree: %s",thead.Data(),tcimp.Data(),fTree->GetName());
1520 delete [] leafStatus;
1550 Int_t TTreePlayer::MakeCode(
const char *filename)
1557 tfile.Form(
"%s.C", fTree->GetName());
1558 FILE *fp = fopen(tfile,
"w");
1560 Error(
"MakeCode",
"cannot open output file %s", tfile.Data());
1564 if (fTree->GetDirectory() && fTree->GetDirectory()->GetFile()) {
1565 treefile = fTree->GetDirectory()->GetFile()->GetName();
1567 treefile =
"Memory Directory";
1572 Bool_t ischain = fTree->InheritsFrom(TChain::Class());
1575 TObjArray *leaves = fTree->GetListOfLeaves();
1576 Int_t nleaves = leaves ? leaves->GetEntriesFast() : 0;
1579 fprintf(fp,
"//////////////////////////////////////////////////////////\n");
1580 fprintf(fp,
"// This file has been automatically generated \n");
1581 fprintf(fp,
"// (%s by ROOT version%s)\n",td.AsString(),gROOT->GetVersion());
1583 fprintf(fp,
"// from TTree %s/%s\n",fTree->GetName(),fTree->GetTitle());
1584 fprintf(fp,
"// found on file: %s\n",treefile.Data());
1586 fprintf(fp,
"// from TChain %s/%s\n",fTree->GetName(),fTree->GetTitle());
1588 fprintf(fp,
"//////////////////////////////////////////////////////////\n");
1594 fprintf(fp,
"//Reset ROOT and connect tree file\n");
1595 fprintf(fp,
" gROOT->Reset();\n");
1597 fprintf(fp,
"\n#ifdef SINGLE_TREE\n");
1598 fprintf(fp,
" // The following code should be used if you want this code to access\n");
1599 fprintf(fp,
" // a single tree instead of a chain\n");
1601 fprintf(fp,
" TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(\"%s\");\n",treefile.Data());
1602 fprintf(fp,
" if (!f) {\n");
1603 fprintf(fp,
" f = new TFile(\"%s\");\n",treefile.Data());
1605 if (fTree->GetDirectory() != fTree->GetCurrentFile()) {
1606 fprintf(fp,
" TDirectory * dir = (TDirectory*)f->Get(\"%s\");\n",fTree->GetDirectory()->GetPath());
1607 fprintf(fp,
" dir->GetObject(\"%s\",tree);\n\n",fTree->GetName());
1609 fprintf(fp,
" f->GetObject(\"%s\",tree);\n\n",fTree->GetName());
1612 fprintf(fp,
"#else // SINGLE_TREE\n\n");
1613 fprintf(fp,
" // The following code should be used if you want this code to access a chain\n");
1614 fprintf(fp,
" // of trees.\n");
1615 fprintf(fp,
" TChain *%s = new TChain(\"%s\",\"%s\");\n",
1616 fTree->GetName(),fTree->GetName(),fTree->GetTitle());
1618 R__LOCKGUARD(gROOTMutex);
1619 TIter next(((TChain*)fTree)->GetListOfFiles());
1620 TChainElement *element;
1621 while ((element = (TChainElement*)next())) {
1622 fprintf(fp,
" %s->Add(\"%s/%s\");\n",fTree->GetName(),element->GetTitle(),element->GetName());
1625 fprintf(fp,
"#endif // SINGLE_TREE\n\n");
1629 fprintf(fp,
"//Declaration of leaves types\n");
1632 TLeafObject *leafobj;
1634 const char *headOK =
" ";
1635 const char *headcom =
" //";
1637 char branchname[1024];
1638 for (l=0;l<nleaves;l++) {
1639 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
1640 len = leaf->GetLen();
1641 leafcount =leaf->GetLeafCount();
1642 TBranch *branch = leaf->GetBranch();
1643 if (branch->GetListOfBranches()->GetEntriesFast() > 0)
continue;
1645 if ( branch->GetNleaves() > 1) {
1647 strlcpy(branchname,branch->GetName(),
sizeof(branchname));
1648 strlcat(branchname,
".",
sizeof(branchname));
1649 strlcat(branchname,leaf->GetTitle(),
sizeof(branchname));
1652 char *dim = (
char*)strstr(branchname,
"[");
1653 if (dim) dim[0] = 0;
1656 if (leafcount) strlcpy(branchname,branch->GetName(),
sizeof(branchname));
1657 else strlcpy(branchname,leaf->GetTitle(),
sizeof(branchname));
1659 char *twodim = (
char*)strstr(leaf->GetTitle(),
"][");
1662 if (*bname ==
'.') *bname=
'_';
1663 if (*bname ==
',') *bname=
'_';
1664 if (*bname ==
':') *bname=
'_';
1665 if (*bname ==
'<') *bname=
'_';
1666 if (*bname ==
'>') *bname=
'_';
1669 if (branch->IsA() == TBranchObject::Class()) {
1670 leafobj = (TLeafObject*)leaf;
1671 if (leafobj->GetClass()) head = headOK;
1672 else head = headcom;
1673 fprintf(fp,
"%s%-15s *%s = 0;\n",head,leafobj->GetTypeName(), leafobj->GetName());
1677 len = leafcount->GetMaximum();
1680 char *dimInName = (
char*) strstr(branchname,
"[");
1682 if ( twodim || dimInName ) {
1684 dimensions = dimInName;
1687 if (twodim) dimensions += (
char*)(twodim+1);
1689 if (dimensions.Length()) {
1690 fprintf(fp,
" %-15s %s[%d]%s;\n",leaf->GetTypeName(), branchname,len,dimensions.Data());
1692 fprintf(fp,
" %-15s %s[%d];\n",leaf->GetTypeName(), branchname,len);
1695 if (strstr(branchname,
"[")) len = 1;
1696 if (len < 2) fprintf(fp,
" %-15s %s;\n",leaf->GetTypeName(), branchname);
1697 else fprintf(fp,
" %-15s %s[%d];\n",leaf->GetTypeName(), branchname,len);
1702 fprintf(fp,
"\n // Set branch addresses.\n");
1703 for (l=0;l<nleaves;l++) {
1704 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
1705 len = leaf->GetLen();
1706 leafcount =leaf->GetLeafCount();
1707 TBranch *branch = leaf->GetBranch();
1709 if ( branch->GetNleaves() > 1) {
1711 strlcpy(branchname,branch->GetName(),
sizeof(branchname));
1712 strlcat(branchname,
".",
sizeof(branchname));
1713 strlcat(branchname,leaf->GetTitle(),
sizeof(branchname));
1716 char *dim = (
char*)strstr(branchname,
"[");
1717 if (dim) dim[0] = 0;
1720 if (leafcount) strlcpy(branchname,branch->GetName(),
sizeof(branchname));
1721 else strlcpy(branchname,leaf->GetTitle(),
sizeof(branchname));
1725 if (*bname ==
'.') *bname=
'_';
1726 if (*bname ==
',') *bname=
'_';
1727 if (*bname ==
':') *bname=
'_';
1728 if (*bname ==
'<') *bname=
'_';
1729 if (*bname ==
'>') *bname=
'_';
1732 char *brak = strstr(branchname,
"[");
1733 if (brak) *brak = 0;
1735 if (branch->IsA() == TBranchObject::Class()) {
1736 strlcpy(branchname,branch->GetName(),
sizeof(branchname));
1737 leafobj = (TLeafObject*)leaf;
1738 if (!leafobj->GetClass()) head = headcom;
1740 if (leafcount) len = leafcount->GetMaximum()+1;
1741 if (len > 1 || brak) fprintf(fp,
"%s%s->SetBranchAddress(\"%s\",%s);\n",head,fTree->GetName(),branch->GetName(),branchname);
1742 else fprintf(fp,
"%s%s->SetBranchAddress(\"%s\",&%s);\n",head,fTree->GetName(),branch->GetName(),branchname);
1746 fprintf(fp,
"\n// This is the loop skeleton\n");
1747 fprintf(fp,
"// To read only selected branches, Insert statements like:\n");
1748 fprintf(fp,
"// %s->SetBranchStatus(\"*\",0); // disable all branches\n",fTree->GetName());
1749 fprintf(fp,
"// %s->SetBranchStatus(\"branchname\",1); // activate branchname\n",GetName());
1750 fprintf(fp,
"\n Long64_t nentries = %s->GetEntries();\n",fTree->GetName());
1751 fprintf(fp,
"\n Long64_t nbytes = 0;\n");
1752 fprintf(fp,
"// for (Long64_t i=0; i<nentries;i++) {\n");
1753 fprintf(fp,
"// nbytes += %s->GetEntry(i);\n",fTree->GetName());
1754 fprintf(fp,
"// }\n");
1757 printf(
"Macro: %s generated from Tree: %s\n",tfile.Data(), fTree->GetName());
1915 Int_t TTreePlayer::MakeProxy(
const char *proxyClassname,
1916 const char *macrofilename,
const char *cutfilename,
1917 const char *option, Int_t maxUnrolling)
1919 if (macrofilename==0 || strlen(macrofilename)==0 ) {
1921 Error(
"MakeProxy",
"A file name for the user script is required");
1925 ROOT::Internal::TTreeProxyGenerator gp(fTree,macrofilename,cutfilename,proxyClassname,option,maxUnrolling);
1975 Int_t TTreePlayer::MakeReader(
const char *classname, Option_t *option)
1977 if (!classname) classname = fTree->GetName();
1979 ROOT::Internal::TTreeReaderGenerator gsr(fTree, classname, option);
2005 TPrincipal *TTreePlayer::Principal(
const char *varexp,
const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)
2008 std::vector<TString> cnames;
2009 TString opt = option;
2011 TPrincipal *principal = 0;
2012 Long64_t entry,entryNumber;
2015 TObjArray *leaves = fTree->GetListOfLeaves();
2016 Int_t nleaves = leaves->GetEntriesFast();
2017 if (nleaves < ncols) ncols = nleaves;
2018 nch = varexp ? strlen(varexp) : 0;
2020 nentries = GetEntriesToProcess(firstentry, nentries);
2023 TTreeFormula *select = 0;
2024 if (strlen(selection)) {
2025 select =
new TTreeFormula(
"Selection",selection,fTree);
2026 if (!select)
return principal;
2027 if (!select->GetNdim()) {
delete select;
return principal; }
2028 fFormulaList->Add(select);
2032 if (varexp && !strcmp(varexp,
"*")) { ncols = nleaves; allvar = 1; }
2033 if (nch == 0 || allvar) {
2034 for (i=0;i<ncols;i++) {
2035 cnames.push_back( ((TLeaf*)leaves->At(i))->GetName() );
2039 ncols = fSelector->SplitNames(varexp,cnames);
2041 var =
new TTreeFormula* [ncols];
2042 Double_t *xvars =
new Double_t[ncols];
2045 for (i=0;i<ncols;i++) {
2046 var[i] =
new TTreeFormula(
"Var1",cnames[i].Data(),fTree);
2047 fFormulaList->Add(var[i]);
2051 TTreeFormulaManager *manager=0;
2052 if (fFormulaList->LastIndex()>=0) {
2053 manager =
new TTreeFormulaManager;
2054 for(i=0;i<=fFormulaList->LastIndex();i++) {
2055 manager->Add((TTreeFormula*)fFormulaList->At(i));
2061 if (opt.Contains(
"n")) principal =
new TPrincipal(ncols,
"n");
2062 else principal =
new TPrincipal(ncols);
2067 for (entry=firstentry;entry<firstentry+nentries;entry++) {
2068 entryNumber = fTree->GetEntryNumber(entry);
2069 if (entryNumber < 0)
break;
2070 Long64_t localEntry = fTree->LoadTree(entryNumber);
2071 if (localEntry < 0)
break;
2072 if (tnumber != fTree->GetTreeNumber()) {
2073 tnumber = fTree->GetTreeNumber();
2074 if (manager) manager->UpdateFormulaLeaves();
2077 if (manager && manager->GetMultiplicity()) {
2078 ndata = manager->GetNdata();
2081 for(
int inst=0;inst<ndata;inst++) {
2082 Bool_t loaded = kFALSE;
2084 if (select->EvalInstance(inst) == 0) {
2089 if (inst==0) loaded = kTRUE;
2093 for (i=0;i<ncols;i++) {
2094 var[i]->EvalInstance(0);
2099 for (i=0;i<ncols;i++) {
2100 xvars[i] = var[i]->EvalInstance(inst);
2102 principal->AddRow(xvars);
2107 if (opt.Contains(
"p")) {
2108 principal->MakePrincipals();
2109 if (opt.Contains(
"d")) principal->Print();
2110 if (opt.Contains(
"h")) principal->MakeHistograms();
2111 if (opt.Contains(
"c")) principal->MakeCode();
2115 fFormulaList->Clear();
2187 Long64_t TTreePlayer::Process(
const char *filename,Option_t *option, Long64_t nentries, Long64_t firstentry)
2189 DeleteSelectorFromFile();
2193 TString opt(option);
2194 TString file(filename);
2195 TSelector *selector = TSelector::GetSelector(file);
2196 if (!selector)
return -1;
2198 fSelectorFromFile = selector;
2199 fSelectorClass = selector->IsA();
2201 Long64_t nsel = Process(selector,opt,nentries,firstentry);
2227 Long64_t TTreePlayer::Process(TSelector *selector,Option_t *option, Long64_t nentries, Long64_t firstentry)
2229 nentries = GetEntriesToProcess(firstentry, nentries);
2231 TDirectory::TContext ctxt;
2233 fTree->SetNotify(selector);
2235 selector->SetOption(option);
2237 selector->Begin(fTree);
2238 selector->SlaveBegin(fTree);
2239 if (selector->Version() >= 2)
2240 selector->Init(fTree);
2243 if (gMonitoringWriter)
2244 gMonitoringWriter->SendProcessingStatus(
"STARTED",kTRUE);
2246 Bool_t process = (selector->GetAbort() != TSelector::kAbortProcess &&
2247 (selector->Version() != 0 || selector->GetStatus() != -1)) ? kTRUE : kFALSE;
2250 Long64_t readbytesatstart = 0;
2251 readbytesatstart = TFile::GetFileBytesRead();
2254 TTreeCache *tpf = 0;
2255 TFile *curfile = fTree->GetCurrentFile();
2256 if (curfile && fTree->GetCacheSize() > 0) {
2257 tpf = (TTreeCache*)curfile->GetCacheRead(fTree);
2259 tpf->SetEntryRange(firstentry,firstentry+nentries);
2261 fTree->SetCacheSize(fTree->GetCacheSize());
2262 tpf = (TTreeCache*)curfile->GetCacheRead(fTree);
2263 if (tpf) tpf->SetEntryRange(firstentry,firstentry+nentries);
2268 TProcessEventTimer *timer = 0;
2269 Int_t interval = fTree->GetTimerInterval();
2270 if (!gROOT->IsBatch() && interval)
2271 timer =
new TProcessEventTimer(interval);
2274 Long64_t entry, entryNumber, localEntry;
2276 Bool_t useCutFill = selector->Version() == 0;
2279 if (gMonitoringWriter)
2280 gMonitoringWriter->SendProcessingProgress(0,0,kTRUE);
2285 fSelectorUpdate = selector;
2286 UpdateFormulaLeaves();
2288 for (entry=firstentry;entry<firstentry+nentries;entry++) {
2289 entryNumber = fTree->GetEntryNumber(entry);
2290 if (entryNumber < 0)
break;
2291 if (timer && timer->ProcessEvents())
break;
2292 if (gROOT->IsInterrupted())
break;
2293 localEntry = fTree->LoadTree(entryNumber);
2294 if (localEntry < 0)
break;
2296 if (selector->ProcessCut(localEntry))
2297 selector->ProcessFill(localEntry);
2299 selector->Process(localEntry);
2301 if (gMonitoringWriter)
2302 gMonitoringWriter->SendProcessingProgress((entry-firstentry),TFile::GetFileBytesRead()-readbytesatstart,kTRUE);
2303 if (selector->GetAbort() == TSelector::kAbortProcess)
break;
2304 if (selector->GetAbort() == TSelector::kAbortFile) {
2306 entry += fTree->GetTree()->GetEntries() - localEntry;
2308 selector->ResetAbort();
2314 TFile *curfile2 = fTree->GetCurrentFile();
2315 if (curfile2 && fTree->GetCacheSize() > 0) {
2316 tpf = (TTreeCache*)curfile2->GetCacheRead(fTree);
2317 if (tpf) tpf->SetEntryRange(0,0);
2322 process = (selector->GetAbort() != TSelector::kAbortProcess &&
2323 (selector->Version() != 0 || selector->GetStatus() != -1)) ? kTRUE : kFALSE;
2324 Long64_t res = (process) ? 0 : -1;
2326 selector->SlaveTerminate();
2327 selector->Terminate();
2328 res = selector->GetStatus();
2330 fTree->SetNotify(0);
2331 fSelectorUpdate = 0;
2332 if (gMonitoringWriter)
2333 gMonitoringWriter->SendProcessingStatus(
"DONE");
2341 void TTreePlayer::RecursiveRemove(TObject *obj)
2343 if (fHistogram == obj) fHistogram = 0;
2427 Long64_t TTreePlayer::Scan(
const char *varexp,
const char *selection,
2429 Long64_t nentries, Long64_t firstentry)
2432 TString opt = option;
2436 UInt_t colDefaultSize = 9;
2437 UInt_t colPrecision = 9;
2438 std::vector<TString> colFormats;
2439 std::vector<Int_t> colSizes;
2441 if (opt.Contains(
"lenmax=")) {
2442 int start = opt.Index(
"lenmax=");
2443 int numpos = start + strlen(
"lenmax=");
2445 int len = opt.Length();
2446 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
2447 TString num = opt(numpos,numlen);
2448 opt.Remove(start,strlen(
"lenmax")+numlen);
2450 lenmax = atoi(num.Data());
2452 if (opt.Contains(
"colsize=")) {
2453 int start = opt.Index(
"colsize=");
2454 int numpos = start + strlen(
"colsize=");
2456 int len = opt.Length();
2457 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
2458 TString num = opt(numpos,numlen);
2459 opt.Remove(start,strlen(
"size")+numlen);
2461 colDefaultSize = atoi(num.Data());
2462 colPrecision = colDefaultSize;
2463 if (colPrecision>18) colPrecision = 18;
2465 if (opt.Contains(
"precision=")) {
2466 int start = opt.Index(
"precision=");
2467 int numpos = start + strlen(
"precision=");
2469 int len = opt.Length();
2470 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
2471 TString num = opt(numpos,numlen);
2472 opt.Remove(start,strlen(
"precision")+numlen);
2474 colPrecision = atoi(num.Data());
2476 TString defFormat = Form(
"%d.%d",colDefaultSize,colPrecision);
2477 if (opt.Contains(
"col=")) {
2478 int start = opt.Index(
"col=");
2479 int numpos = start + strlen(
"col=");
2481 int len = opt.Length();
2482 while( (numpos+numlen<len) &&
2483 (isdigit(opt[numpos+numlen])
2484 || opt[numpos+numlen] ==
'c'
2485 || opt[numpos+numlen] ==
'd'
2486 || opt[numpos+numlen] ==
'i'
2487 || opt[numpos+numlen] ==
'o'
2488 || opt[numpos+numlen] ==
'x'
2489 || opt[numpos+numlen] ==
'X'
2490 || opt[numpos+numlen] ==
'u'
2491 || opt[numpos+numlen] ==
'f'
2492 || opt[numpos+numlen] ==
'e'
2493 || opt[numpos+numlen] ==
'E'
2494 || opt[numpos+numlen] ==
'g'
2495 || opt[numpos+numlen] ==
'G'
2496 || opt[numpos+numlen] ==
'l'
2497 || opt[numpos+numlen] ==
'L'
2498 || opt[numpos+numlen] ==
'h'
2499 || opt[numpos+numlen] ==
's'
2500 || opt[numpos+numlen] ==
'#'
2501 || opt[numpos+numlen]==
'.'
2502 || opt[numpos+numlen]==
':')) numlen++;
2503 TString flist = opt(numpos,numlen);
2504 opt.Remove(start,strlen(
"col")+numlen);
2507 while(i<flist.Length() && flist[i]==
':') {
2508 colFormats.push_back(defFormat);
2509 colSizes.push_back(colDefaultSize);
2512 for(; i<flist.Length(); ++i) {
2513 int next = flist.Index(
":",i);
2515 colFormats.push_back(defFormat);
2516 }
else if (next==kNPOS) {
2517 colFormats.push_back(flist(i,flist.Length()-i));
2520 colFormats.push_back(flist(i,next-i));
2523 UInt_t siz = atoi(colFormats[colFormats.size()-1].Data());
2524 colSizes.push_back( siz ? siz : colDefaultSize );
2529 std::vector<TString> cnames;
2531 Long64_t entry,entryNumber;
2537 if (fScanRedirect) {
2538 fTree->SetScanField(0);
2539 fname = (
char *) fScanFileName;
2540 if (!fname) fname = (
char*)
"";
2541 lenfile = strlen(fname);
2543 Int_t nch2 = strlen(fTree->GetName());
2544 fname =
new char[nch2+10];
2545 strlcpy(fname, fTree->GetName(),nch2+10);
2546 strlcat(fname,
"-scan.dat",nch2+10);
2548 out.open(fname, std::ios::out);
2550 if (!lenfile)
delete [] fname;
2551 Error(
"Scan",
"Can not open file for redirection");
2555 TObjArray *leaves = fTree->GetListOfLeaves();
2556 if (leaves==0)
return 0;
2557 UInt_t nleaves = leaves->GetEntriesFast();
2558 if (nleaves < ncols) ncols = nleaves;
2559 nch = varexp ? strlen(varexp) : 0;
2561 nentries = GetEntriesToProcess(firstentry, nentries);
2564 TTreeFormula *select = 0;
2565 if (selection && strlen(selection)) {
2566 select =
new TTreeFormula(
"Selection",selection,fTree);
2567 if (!select)
return -1;
2568 if (!select->GetNdim()) {
delete select;
return -1; }
2569 fFormulaList->Add(select);
2573 if (varexp && !strcmp(varexp,
"*")) { ncols = nleaves; allvar = 1; }
2574 if (nch == 0 || allvar) {
2577 for (ui=0;ui<ncs;++ui) {
2578 TLeaf *lf = (TLeaf*)leaves->At(ui);
2579 if (lf->GetBranch()->GetListOfBranches()->GetEntries() > 0)
continue;
2580 cnames.push_back( lf->GetBranch()->GetMother()->GetName() );
2581 if (cnames[ncols] == lf->GetName() ) {
2583 }
else if (cnames[ncols][cnames[ncols].Length()-1]==
'.') {
2584 cnames[ncols] = lf->GetBranch()->GetName();
2586 if (lf->GetBranch()->GetMother()->IsA()->InheritsFrom(TBranchElement::Class())) {
2587 TBranchElement *mother = (TBranchElement*)lf->GetBranch()->GetMother();
2588 if (mother->GetType() == 3 || mother->GetType() == 4) {
2590 cnames[ncols] = lf->GetBranch()->GetName();
2595 if (!strchr(lf->GetBranch()->GetName() ,
'[') ) {
2596 cnames[ncols].Append(
'.');
2597 cnames[ncols].Append( lf->GetBranch()->GetName() );
2600 if (strcmp( lf->GetBranch()->GetName(), lf->GetName() ) != 0 ) {
2601 cnames[ncols].Append(
'.');
2602 cnames[ncols].Append( lf->GetName() );
2609 ncols = fSelector->SplitNames(varexp, cnames);
2612 var =
new TTreeFormula* [ncols];
2614 for(ui=colFormats.size();ui<ncols;++ui) {
2615 colFormats.push_back(defFormat);
2616 colSizes.push_back(colDefaultSize);
2620 for (ui=0;ui<ncols;ui++) {
2621 var[ui] =
new TTreeFormula(
"Var1",cnames[ui].Data(),fTree);
2622 fFormulaList->Add(var[ui]);
2626 TTreeFormulaManager *manager=0;
2627 Bool_t hasArray = kFALSE;
2628 Bool_t forceDim = kFALSE;
2629 if (fFormulaList->LastIndex()>=0) {
2631 if (select->GetManager()->GetMultiplicity() > 0 ) {
2632 manager =
new TTreeFormulaManager;
2633 for(i=0;i<=fFormulaList->LastIndex();i++) {
2634 manager->Add((TTreeFormula*)fFormulaList->At(i));
2639 for(i=0;i<=fFormulaList->LastIndex();i++) {
2640 TTreeFormula *form = ((TTreeFormula*)fFormulaList->At(i));
2641 switch( form->GetManager()->GetMultiplicity() ) {
2658 onerow =
"***********";
2659 if (hasArray) onerow +=
"***********";
2661 for (ui=0;ui<ncols;ui++) {
2662 TString starFormat = Form(
"*%%%d.%ds",colSizes[ui]+2,colSizes[ui]+2);
2663 onerow += Form(starFormat.Data(),var[ui]->PrintValue(-2));
2666 out<<onerow.Data()<<
"*"<<std::endl;
2668 printf(
"%s*\n",onerow.Data());
2670 if (hasArray) onerow +=
"* Instance ";
2671 for (ui=0;ui<ncols;ui++) {
2672 TString numbFormat = Form(
"* %%%d.%ds ",colSizes[ui],colSizes[ui]);
2673 onerow += Form(numbFormat.Data(),var[ui]->PrintValue(-1));
2676 out<<onerow.Data()<<
"*"<<std::endl;
2678 printf(
"%s*\n",onerow.Data());
2679 onerow =
"***********";
2680 if (hasArray) onerow +=
"***********";
2681 for (ui=0;ui<ncols;ui++) {
2682 TString starFormat = Form(
"*%%%d.%ds",colSizes[ui]+2,colSizes[ui]+2);
2683 onerow += Form(starFormat.Data(),var[ui]->PrintValue(-2));
2686 out<<onerow.Data()<<
"*"<<std::endl;
2688 printf(
"%s*\n",onerow.Data());
2692 Bool_t exitloop = kFALSE;
2693 for (entry=firstentry;
2694 entry<(firstentry+nentries) && !exitloop;
2696 entryNumber = fTree->GetEntryNumber(entry);
2697 if (entryNumber < 0)
break;
2698 Long64_t localEntry = fTree->LoadTree(entryNumber);
2699 if (localEntry < 0)
break;
2700 if (tnumber != fTree->GetTreeNumber()) {
2701 tnumber = fTree->GetTreeNumber();
2702 if (manager) manager->UpdateFormulaLeaves();
2704 for(i=0;i<=fFormulaList->LastIndex();i++) {
2705 ((TTreeFormula*)fFormulaList->At(i))->UpdateFormulaLeaves();
2715 ndata = manager->GetNdata(kTRUE);
2720 for (ui=0;ui<ncols;ui++) {
2721 if (ndata < var[ui]->GetNdata() ) {
2722 ndata = var[ui]->GetNdata();
2725 if (select && select->GetNdata()==0) ndata = 0;
2730 if (lenmax && ndata>(
int)lenmax) ndata = lenmax;
2731 Bool_t loaded = kFALSE;
2732 for(
int inst=0;inst<ndata;inst++) {
2734 if (select->EvalInstance(inst) == 0) {
2738 if (inst==0) loaded = kTRUE;
2742 for (ui=0;ui<ncols;ui++) {
2743 var[ui]->EvalInstance(0);
2747 onerow = Form(
"* %8lld ",entryNumber);
2749 onerow += Form(
"* %8d ",inst);
2751 for (ui=0;ui<ncols;++ui) {
2752 TString numbFormat = Form(
"* %%%d.%ds ",colSizes[ui],colSizes[ui]);
2753 if (var[ui]->GetNdim()) onerow += Form(numbFormat.Data(),var[ui]->PrintValue(0,inst,colFormats[ui].Data()));
2755 TString emptyForm = Form(
"* %%%dc ",colSizes[ui]);
2756 onerow += Form(emptyForm.Data(),
' ');
2761 out<<onerow.Data()<<
"*"<<std::endl;
2763 printf(
"%s*\n",onerow.Data());
2764 if (fTree->GetScanField() > 0 && fSelectedRows > 0) {
2765 if (fSelectedRows%fTree->GetScanField() == 0) {
2766 fprintf(stderr,
"Type <CR> to continue or q to quit ==> ");
2770 while (readch !=
'\n' && readch != EOF) readch = getchar();
2771 if (answer ==
'q' || answer ==
'Q') {
2779 onerow =
"***********";
2780 if (hasArray) onerow +=
"***********";
2781 for (ui=0;ui<ncols;ui++) {
2782 TString starFormat = Form(
"*%%%d.%ds",colSizes[ui]+2,colSizes[ui]+2);
2783 onerow += Form(starFormat.Data(),var[ui]->PrintValue(-2));
2786 out<<onerow.Data()<<
"*"<<std::endl;
2788 printf(
"%s*\n",onerow.Data());
2789 if (select) Printf(
"==> %lld selected %s", fSelectedRows,
2790 fSelectedRows == 1 ?
"entry" :
"entries");
2791 if (fScanRedirect) printf(
"File <%s> created\n", fname);
2794 fFormulaList->Clear();
2797 return fSelectedRows;
2807 TSQLResult *TTreePlayer::Query(
const char *varexp,
const char *selection,
2808 Option_t *, Long64_t nentries, Long64_t firstentry)
2811 std::vector<TString> cnames;
2813 Long64_t entry,entryNumber;
2816 TObjArray *leaves = fTree->GetListOfLeaves();
2817 Int_t nleaves = leaves->GetEntriesFast();
2818 if (nleaves < ncols) ncols = nleaves;
2819 nch = varexp ? strlen(varexp) : 0;
2821 nentries = GetEntriesToProcess(firstentry, nentries);
2824 TTreeFormula *select = 0;
2825 if (strlen(selection)) {
2826 select =
new TTreeFormula(
"Selection",selection,fTree);
2827 if (!select)
return 0;
2828 if (!select->GetNdim()) {
delete select;
return 0; }
2829 fFormulaList->Add(select);
2834 if (varexp && !strcmp(varexp,
"*")) { ncols = nleaves; allvar = 1; }
2835 if (nch == 0 || allvar) {
2836 for (i=0;i<ncols;i++) {
2837 cnames.push_back( ((TLeaf*)leaves->At(i))->GetName() );
2841 ncols = fSelector->SplitNames(varexp,cnames);
2843 var =
new TTreeFormula* [ncols];
2846 for (i=0;i<ncols;i++) {
2847 var[i] =
new TTreeFormula(
"Var1",cnames[i].Data(),fTree);
2848 fFormulaList->Add(var[i]);
2852 TTreeResult *res =
new TTreeResult(ncols);
2853 for (i = 0; i < ncols; i++) {
2854 res->AddField(i, var[i]->PrintValue(-1));
2858 TTreeFormulaManager *manager=0;
2859 if (fFormulaList->LastIndex()>=0) {
2860 manager =
new TTreeFormulaManager;
2861 for(i=0;i<=fFormulaList->LastIndex();i++) {
2862 manager->Add((TTreeFormula*)fFormulaList->At(i));
2868 const char *aresult;
2870 char *arow =
new char[ncols*50];
2873 Int_t *fields =
new Int_t[ncols];
2874 for (entry=firstentry;entry<firstentry+nentries;entry++) {
2875 entryNumber = fTree->GetEntryNumber(entry);
2876 if (entryNumber < 0)
break;
2877 Long64_t localEntry = fTree->LoadTree(entryNumber);
2878 if (localEntry < 0)
break;
2879 if (tnumber != fTree->GetTreeNumber()) {
2880 tnumber = fTree->GetTreeNumber();
2881 for (i=0;i<ncols;i++) var[i]->UpdateFormulaLeaves();
2885 if (manager && manager->GetMultiplicity()) {
2886 ndata = manager->GetNdata();
2891 if (select->EvalInstance(0) == 0)
continue;
2894 Bool_t loaded = kFALSE;
2895 for(
int inst=0;inst<ndata;inst++) {
2897 if (select->EvalInstance(inst) == 0) {
2902 if (inst==0) loaded = kTRUE;
2906 for (i=0;i<ncols;i++) {
2907 var[i]->EvalInstance(0);
2911 for (i=0;i<ncols;i++) {
2912 aresult = var[i]->PrintValue(0,inst);
2913 len = strlen(aresult)+1;
2915 memcpy(arow,aresult,len);
2918 memcpy(arow+fields[i-1],aresult,len);
2919 fields[i] = fields[i-1] + len;
2922 res->AddRow(
new TTreeRow(ncols,fields,arow));
2928 fFormulaList->Clear();
2940 void TTreePlayer::SetEstimate(Long64_t n)
2942 fSelector->SetEstimate(n);
2951 void TTreePlayer::StartViewer(Int_t ww, Int_t wh)
2953 if (gROOT->IsBatch()) {
2954 Warning(
"StartViewer",
"viewer cannot run in batch mode");
2960 if ((h = gROOT->GetPluginManager()->FindHandler(
"TVirtualTreeViewer"))) {
2961 if (h->LoadPlugin() == -1)
2963 h->ExecPlugin(1,fTree);
3038 Int_t TTreePlayer::UnbinnedFit(
const char *funcname ,
const char *varexp,
const char *selection,Option_t *option ,Long64_t nentries, Long64_t firstentry)
3041 TF1* fitfunc = (TF1*)gROOT->GetFunction(funcname);
3042 if (!fitfunc) { Error(
"UnbinnedFit",
"Unknown function: %s",funcname);
return 0; }
3044 Int_t npar = fitfunc->GetNpar();
3045 if (npar <=0) { Error(
"UnbinnedFit",
"Illegal number of parameters = %d",npar);
return 0; }
3050 Long64_t oldEstimate = fTree->GetEstimate();
3051 Long64_t nent = fTree->GetEntriesFriend();
3052 fTree->SetEstimate(TMath::Min(nent,nentries));
3055 TString opt = option;
3057 Foption_t fitOption;
3058 if (opt.Contains(
"Q")) fitOption.Quiet = 1;
3059 if (opt.Contains(
"V")){fitOption.Verbose = 1; fitOption.Quiet = 0;}
3060 if (opt.Contains(
"E")) fitOption.Errors = 1;
3061 if (opt.Contains(
"M")) fitOption.More = 1;
3062 if (!opt.Contains(
"D")) fitOption.Nograph = 1;
3065 TString drawOpt =
"goff";
3066 if (!fitOption.Nograph) drawOpt =
"";
3067 Long64_t nsel = DrawSelect(varexp, selection,drawOpt, nentries, firstentry);
3069 if (!fitOption.Nograph && GetSelectedRows() <= 0 && GetDimension() > 4) {
3070 Info(
"UnbinnedFit",
"Ignore option D with more than 4 variables");
3071 nsel = DrawSelect(varexp, selection,
"goff", nentries, firstentry);
3075 Long64_t nrows = GetSelectedRows();
3078 Error(
"UnbinnedFit",
"Cannot fit: no entries selected");
3083 Int_t ndim = GetDimension();
3089 std::vector<double *> vlist(ndim);
3090 for (
int i = 0; i < ndim; ++i)
3091 vlist[i] = fSelector->GetVal(i);
3096 ROOT::Fit::UnBinData * fitdata =
new ROOT::Fit::UnBinData(nrows, ndim, vlist.begin());
3100 ROOT::Math::MinimizerOptions minOption;
3101 TFitResultPtr ret = ROOT::Fit::UnBinFit(fitdata,fitfunc, fitOption, minOption);
3104 fTree->SetEstimate(oldEstimate);
3109 if (!fitOption.Nograph && fHistogram) {
3110 if (fHistogram->GetDimension() < 2) {
3111 TH1 *hf = (TH1*)fHistogram->Clone(
"unbinnedFit");
3112 hf->SetLineWidth(3);
3114 Int_t nbins = fHistogram->GetXaxis()->GetNbins();
3115 Double_t norm = ((Double_t)nsel)*fHistogram->GetXaxis()->GetBinWidth(1);
3116 for (Int_t bin=1;bin<=nbins;bin++) {
3117 Double_t func = norm*fitfunc->Eval(hf->GetBinCenter(bin));
3118 hf->SetBinContent(bin,func);
3120 fHistogram->GetListOfFunctions()->Add(hf,
"lsame");
3135 void TTreePlayer::UpdateFormulaLeaves()
3137 if (fSelector) fSelector->Notify();
3138 if (fSelectorUpdate){
3141 if (fSelector==fSelectorUpdate) {
3143 TObject *obj = fSelector->GetObject();
3145 if (fSelector->GetObject()->InheritsFrom(TEntryList::Class())){
3146 ((TEntryList*)fSelector->GetObject())->SetTree(fTree->GetTree());
3150 if (fSelectorFromFile==fSelectorUpdate) {
3151 TIter next(fSelectorFromFile->GetOutputList());
3152 TEntryList *elist=0;
3153 while ((elist=(TEntryList*)next())){
3154 if (elist->InheritsFrom(TEntryList::Class())){
3155 elist->SetTree(fTree->GetTree());
3161 if (fFormulaList->GetSize()) {
3162 TObjLink *lnk = fFormulaList->FirstLink();
3164 lnk->GetObject()->Notify();