00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 #include <string.h>
00211 #include <stdio.h>
00212
00213 #include "Riostream.h"
00214 #include "TTreePlayer.h"
00215 #include "TROOT.h"
00216 #include "TSystem.h"
00217 #include "TFile.h"
00218 #include "TEventList.h"
00219 #include "TEntryList.h"
00220 #include "TBranchObject.h"
00221 #include "TBranchElement.h"
00222 #include "TStreamerInfo.h"
00223 #include "TStreamerElement.h"
00224 #include "TLeafObject.h"
00225 #include "TLeafF.h"
00226 #include "TLeafD.h"
00227 #include "TLeafC.h"
00228 #include "TLeafB.h"
00229 #include "TLeafI.h"
00230 #include "TLeafS.h"
00231 #include "TMath.h"
00232 #include "TH2.h"
00233 #include "TH3.h"
00234 #include "TPolyMarker.h"
00235 #include "TPolyMarker3D.h"
00236 #include "TDirectory.h"
00237 #include "TClonesArray.h"
00238 #include "TClass.h"
00239 #include "TVirtualPad.h"
00240 #include "TProfile.h"
00241 #include "TProfile2D.h"
00242 #include "TTreeFormula.h"
00243 #include "TTreeFormulaManager.h"
00244 #include "TStyle.h"
00245 #include "Foption.h"
00246 #include "TTreeResult.h"
00247 #include "TTreeRow.h"
00248 #include "TPrincipal.h"
00249 #include "TChain.h"
00250 #include "TChainElement.h"
00251 #include "TF1.h"
00252 #include "TH1.h"
00253 #include "TVirtualFitter.h"
00254 #include "TEnv.h"
00255 #include "THLimitsFinder.h"
00256 #include "TSelectorDraw.h"
00257 #include "TSelectorEntries.h"
00258 #include "TPluginManager.h"
00259 #include "TObjString.h"
00260 #include "TTreeProxyGenerator.h"
00261 #include "TTreeIndex.h"
00262 #include "TChainIndex.h"
00263 #include "TRefProxy.h"
00264 #include "TRefArrayProxy.h"
00265 #include "TVirtualMonitoring.h"
00266 #include "TTreeCache.h"
00267 #include "TStyle.h"
00268
00269 #include "HFitInterface.h"
00270 #include "Foption.h"
00271 #include "Fit/UnBinData.h"
00272 #include "Math/MinimizerOptions.h"
00273
00274 R__EXTERN Foption_t Foption;
00275 R__EXTERN TTree *gTree;
00276
00277 TVirtualFitter *tFitter=0;
00278
00279 extern void TreeUnbinnedFitLikelihood(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag);
00280
00281 ClassImp(TTreePlayer)
00282
00283
00284 TTreePlayer::TTreePlayer()
00285 {
00286
00287
00288 fTree = 0;
00289 fScanFileName = 0;
00290 fScanRedirect = kFALSE;
00291 fSelectedRows = 0;
00292 fDimension = 0;
00293 fHistogram = 0;
00294 fFormulaList = new TList();
00295 fFormulaList->SetOwner(kTRUE);
00296 fSelector = new TSelectorDraw();
00297 fSelectorFromFile = 0;
00298 fSelectorClass = 0;
00299 fSelectorUpdate = 0;
00300 fInput = new TList();
00301 fInput->Add(new TNamed("varexp",""));
00302 fInput->Add(new TNamed("selection",""));
00303 fSelector->SetInputList(fInput);
00304 gROOT->GetListOfCleanups()->Add(this);
00305 TClass::GetClass("TRef")->AdoptReferenceProxy(new TRefProxy());
00306 TClass::GetClass("TRefArray")->AdoptReferenceProxy(new TRefArrayProxy());
00307 }
00308
00309
00310 TTreePlayer::~TTreePlayer()
00311 {
00312
00313
00314
00315 delete fFormulaList;
00316 delete fSelector;
00317 DeleteSelectorFromFile();
00318 fInput->Delete();
00319 delete fInput;
00320 gROOT->GetListOfCleanups()->Remove(this);
00321 }
00322
00323
00324 TVirtualIndex *TTreePlayer::BuildIndex(const TTree *T, const char *majorname, const char *minorname)
00325 {
00326
00327
00328 TVirtualIndex *index;
00329 if (dynamic_cast<const TChain*>(T)) {
00330 index = new TChainIndex(T, majorname, minorname);
00331 if (index->IsZombie()) {
00332 delete index;
00333 Error("BuildIndex", "Creating a TChainIndex unsuccessfull - switching to TTreeIndex");
00334 }
00335 else
00336 return index;
00337 }
00338 return new TTreeIndex(T,majorname,minorname);
00339 }
00340
00341
00342 TTree *TTreePlayer::CopyTree(const char *selection, Option_t *, Long64_t nentries,
00343 Long64_t firstentry)
00344 {
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 TTree *tree = fTree->CloneTree(0);
00377 if (tree == 0) return 0;
00378
00379
00380 TObjArray* branches = tree->GetListOfBranches();
00381 Int_t nb = branches->GetEntriesFast();
00382 for (Int_t i = 0; i < nb; ++i) {
00383 TBranch* br = (TBranch*) branches->UncheckedAt(i);
00384 if (br->InheritsFrom(TBranchElement::Class())) {
00385 ((TBranchElement*) br)->ResetDeleteObject();
00386 }
00387 }
00388
00389 Long64_t entry,entryNumber;
00390 nentries = GetEntriesToProcess(firstentry, nentries);
00391
00392
00393 TTreeFormula *select = 0;
00394
00395
00396 if (strlen(selection)) {
00397 select = new TTreeFormula("Selection",selection,fTree);
00398 if (!select || !select->GetNdim()) {
00399 delete select;
00400 delete tree;
00401 return 0;
00402 }
00403 fFormulaList->Add(select);
00404 }
00405
00406
00407 Int_t tnumber = -1;
00408 for (entry=firstentry;entry<firstentry+nentries;entry++) {
00409 entryNumber = fTree->GetEntryNumber(entry);
00410 if (entryNumber < 0) break;
00411 Long64_t localEntry = fTree->LoadTree(entryNumber);
00412 if (localEntry < 0) break;
00413 if (tnumber != fTree->GetTreeNumber()) {
00414 tnumber = fTree->GetTreeNumber();
00415 if (select) select->UpdateFormulaLeaves();
00416 }
00417 if (select) {
00418 Int_t ndata = select->GetNdata();
00419 Bool_t keep = kFALSE;
00420 for(Int_t current = 0; current<ndata && !keep; current++) {
00421 keep |= (select->EvalInstance(current) != 0);
00422 }
00423 if (!keep) continue;
00424 }
00425 fTree->GetEntry(entryNumber);
00426 tree->Fill();
00427 }
00428 fFormulaList->Clear();
00429 return tree;
00430 }
00431
00432
00433 void TTreePlayer::DeleteSelectorFromFile()
00434 {
00435
00436
00437
00438 if (fSelectorFromFile && fSelectorClass) {
00439 if (fSelectorClass->IsLoaded()) {
00440 delete fSelectorFromFile;
00441 }
00442 }
00443 fSelectorFromFile = 0;
00444 fSelectorClass = 0;
00445 }
00446
00447
00448 Long64_t TTreePlayer::DrawScript(const char* wrapperPrefix,
00449 const char *macrofilename, const char *cutfilename,
00450 Option_t *option, Long64_t nentries, Long64_t firstentry)
00451 {
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480 if (!macrofilename || strlen(macrofilename)==0) return 0;
00481
00482 TString aclicMode;
00483 TString arguments;
00484 TString io;
00485 TString realcutname;
00486 if (cutfilename && strlen(cutfilename))
00487 realcutname = gSystem->SplitAclicMode(cutfilename, aclicMode, arguments, io);
00488
00489
00490 TString realname = gSystem->SplitAclicMode(macrofilename, aclicMode, arguments, io);
00491
00492 TString selname = wrapperPrefix;
00493
00494 TTreeProxyGenerator gp(fTree,realname,realcutname,selname,option,3);
00495
00496 selname = gp.GetFileName();
00497 if (aclicMode.Length()==0) {
00498 Warning("DrawScript","TTreeProxy does not work in interpreted mode yet. The script will be compiled.");
00499 aclicMode = "+";
00500 }
00501 selname.Append(aclicMode);
00502
00503 Info("DrawScript","%s",Form("Will process tree/chain using %s",selname.Data()));
00504 Long64_t result = fTree->Process(selname,option,nentries,firstentry);
00505 fTree->SetNotify(0);
00506
00507
00508
00509
00510
00511 return result;
00512 }
00513
00514
00515 Long64_t TTreePlayer::DrawSelect(const char *varexp0, const char *selection, Option_t *option,Long64_t nentries, Long64_t firstentry)
00516 {
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003 if (fTree->GetEntriesFriend() == 0) return 0;
01004
01005
01006
01007
01008 TString possibleFilename = varexp0;
01009 Ssiz_t dot_pos = possibleFilename.Last('.');
01010 if ( dot_pos != kNPOS
01011 && possibleFilename.Index("Alt$")<0 && possibleFilename.Index("Entries$")<0
01012 && possibleFilename.Index("Length$")<0 && possibleFilename.Index("Entry$")<0
01013 && possibleFilename.Index("LocalEntry$")<0
01014 && possibleFilename.Index("Min$")<0 && possibleFilename.Index("Max$")<0
01015 && possibleFilename.Index("MinIf$")<0 && possibleFilename.Index("MaxIf$")<0
01016 && possibleFilename.Index("Iteration$")<0 && possibleFilename.Index("Sum$")<0
01017 && possibleFilename.Index(">")<0 && possibleFilename.Index("<")<0
01018 && gSystem->IsFileInIncludePath(possibleFilename.Data())) {
01019
01020 if (selection && strlen(selection) && !gSystem->IsFileInIncludePath(selection)) {
01021 Error("DrawSelect",
01022 "Drawing using a C++ file currently requires that both the expression and the selection are files\n\t\"%s\" is not a file",
01023 selection);
01024 return 0;
01025 }
01026 return DrawScript("generatedSel",varexp0,selection,option,nentries,firstentry);
01027
01028 } else {
01029 possibleFilename = selection;
01030 if (possibleFilename.Index("Alt$")<0 && possibleFilename.Index("Entries$")<0
01031 && possibleFilename.Index("Length$")<0 && possibleFilename.Index("Entry$")<0
01032 && possibleFilename.Index("LocalEntry$")<0
01033 && possibleFilename.Index("Min$")<0 && possibleFilename.Index("Max$")<0
01034 && possibleFilename.Index("MinIf$")<0 && possibleFilename.Index("MaxIf$")<0
01035 && possibleFilename.Index("Iteration$")<0 && possibleFilename.Index("Sum$")<0
01036 && possibleFilename.Index(">")<0 && possibleFilename.Index("<")<0
01037 && gSystem->IsFileInIncludePath(possibleFilename.Data())) {
01038
01039 Error("DrawSelect",
01040 "Drawing using a C++ file currently requires that both the expression and the selection are files\n\t\"%s\" is not a file",
01041 varexp0);
01042 return 0;
01043 }
01044 }
01045
01046 Long64_t oldEstimate = fTree->GetEstimate();
01047 TEventList *evlist = fTree->GetEventList();
01048 TEntryList *elist = fTree->GetEntryList();
01049 if (evlist && elist){
01050 elist->SetBit(kCanDelete, kTRUE);
01051 }
01052 TNamed *cvarexp = (TNamed*)fInput->FindObject("varexp");
01053 TNamed *cselection = (TNamed*)fInput->FindObject("selection");
01054 if (cvarexp) cvarexp->SetTitle(varexp0);
01055 if (cselection) cselection->SetTitle(selection);
01056
01057 TString opt = option;
01058 opt.ToLower();
01059 Bool_t optpara = kFALSE;
01060 Bool_t optcandle = kFALSE;
01061 Bool_t optgl5d = kFALSE;
01062 Bool_t optnorm = kFALSE;
01063 if (opt.Contains("norm")) {optnorm = kTRUE; opt.ReplaceAll("norm",""); opt.ReplaceAll(" ","");}
01064 if (opt.Contains("para")) optpara = kTRUE;
01065 if (opt.Contains("candle")) optcandle = kTRUE;
01066 if (opt.Contains("gl5d")) optgl5d = kTRUE;
01067 Bool_t pgl = gStyle->GetCanvasPreferGL();
01068 if (optgl5d) {
01069 fTree->SetEstimate(fTree->GetEntries());
01070 if (!gPad) {
01071 if (pgl == kFALSE) gStyle->SetCanvasPreferGL(kTRUE);
01072 gROOT->ProcessLineFast("new TCanvas();");
01073 }
01074 }
01075
01076
01077
01078 if (nentries > fTree->GetMaxEntryLoop()) nentries = fTree->GetMaxEntryLoop();
01079
01080
01081 Long64_t nrows = Process(fSelector,option,nentries,firstentry);
01082 fSelectedRows = nrows;
01083 fDimension = fSelector->GetDimension();
01084
01085
01086 if (fDimension <= 0) {
01087 fTree->SetEstimate(oldEstimate);
01088 if (fSelector->GetCleanElist()) {
01089
01090 fTree->SetEntryList(elist);
01091 delete fSelector->GetObject();
01092 }
01093 return nrows;
01094 }
01095
01096
01097 Long64_t drawflag = fSelector->GetDrawFlag();
01098 Int_t action = fSelector->GetAction();
01099 Bool_t draw = kFALSE;
01100 if (!drawflag && !opt.Contains("goff")) draw = kTRUE;
01101 if (!optcandle && !optpara) fHistogram = (TH1*)fSelector->GetObject();
01102 if (optnorm) {
01103 Double_t sumh= fHistogram->GetSumOfWeights();
01104 if (sumh != 0) fHistogram->Scale(1./sumh);
01105 }
01106
01107
01108
01109
01110
01111
01112
01113 if (fDimension == 1) {
01114 if (fSelector->GetVar1()->IsInteger()) fHistogram->LabelsDeflate("X");
01115 if (draw) fHistogram->Draw(opt.Data());
01116
01117
01118 } else if (fDimension == 2 && !(optpara||optcandle)) {
01119 if (fSelector->GetVar1()->IsInteger()) fHistogram->LabelsDeflate("Y");
01120 if (fSelector->GetVar2()->IsInteger()) fHistogram->LabelsDeflate("X");
01121 if (action == 4) {
01122 if (draw) fHistogram->Draw(opt.Data());
01123 } else {
01124 Bool_t graph = kFALSE;
01125 Int_t l = opt.Length();
01126 if (l == 0 || opt == "same") graph = kTRUE;
01127 if (opt.Contains("p") || opt.Contains("*") || opt.Contains("l")) graph = kTRUE;
01128 if (opt.Contains("surf") || opt.Contains("lego") || opt.Contains("cont")) graph = kFALSE;
01129 if (opt.Contains("col") || opt.Contains("hist") || opt.Contains("scat")) graph = kFALSE;
01130 if (!graph) {
01131 if (draw) fHistogram->Draw(opt.Data());
01132 } else {
01133 if (fSelector->GetOldHistogram() && draw) fHistogram->Draw(opt.Data());
01134 }
01135 }
01136
01137 } else if (fDimension == 3 && !(optpara||optcandle)) {
01138 if (fSelector->GetVar1()->IsInteger()) fHistogram->LabelsDeflate("Z");
01139 if (fSelector->GetVar2()->IsInteger()) fHistogram->LabelsDeflate("Y");
01140 if (fSelector->GetVar3()->IsInteger()) fHistogram->LabelsDeflate("X");
01141 if (action == 23) {
01142 if (draw) fHistogram->Draw(opt.Data());
01143 } else {
01144 Int_t noscat = opt.Length();
01145 if (opt.Contains("same")) noscat -= 4;
01146 if (noscat) {
01147 if (draw) fHistogram->Draw(opt.Data());
01148 } else {
01149 if (fSelector->GetOldHistogram() && draw) fHistogram->Draw(opt.Data());
01150 }
01151 }
01152
01153 } else if (fDimension == 4 && !(optpara||optcandle)) {
01154 if (fSelector->GetVar1()->IsInteger()) fHistogram->LabelsDeflate("Z");
01155 if (fSelector->GetVar2()->IsInteger()) fHistogram->LabelsDeflate("Y");
01156 if (fSelector->GetVar3()->IsInteger()) fHistogram->LabelsDeflate("X");
01157 if (draw) fHistogram->Draw(opt.Data());
01158 Int_t ncolors = gStyle->GetNumberOfColors();
01159 TObjArray *pms = (TObjArray*)fHistogram->GetListOfFunctions()->FindObject("polymarkers");
01160 for (Int_t col=0;col<ncolors;col++) {
01161 if (!pms) continue;
01162 TPolyMarker3D *pm3d = (TPolyMarker3D*)pms->UncheckedAt(col);
01163 if (draw) pm3d->Draw();
01164 }
01165
01166 } else if (optpara || optcandle) {
01167 if (draw) {
01168 TObject* para = fSelector->GetObject();
01169 TObject *enlist = gDirectory->FindObject("enlist");
01170 fTree->Draw(">>enlist",selection,"entrylist",nentries,firstentry);
01171 gROOT->ProcessLineFast(Form("TParallelCoord::SetEntryList((TParallelCoord*)0x%lx,(TEntryList*)0x%lx)",
01172 (ULong_t)para, (ULong_t)enlist));
01173 }
01174
01175 } else if (optgl5d) {
01176 gROOT->ProcessLineFast(Form("(new TGL5DDataSet((TTree *)0x%lx))->Draw(\"%s\");", (ULong_t)fTree, opt.Data()));
01177 gStyle->SetCanvasPreferGL(pgl);
01178 }
01179
01180 if (fHistogram) fHistogram->ResetBit(TH1::kCanRebin);
01181 return fSelectedRows;
01182 }
01183
01184
01185 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)
01186 {
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 Int_t nch = option ? strlen(option) + 10 : 10;
01209 char *opt = new char[nch];
01210 if (option) strlcpy(opt,option,nch-1);
01211 else strlcpy(opt,"goff",5);
01212
01213 Long64_t nsel = DrawSelect(varexp,selection,opt,nentries,firstentry);
01214
01215 delete [] opt;
01216 Int_t fitResult = -1;
01217
01218 if (fHistogram && nsel > 0) {
01219 fitResult = fHistogram->Fit(formula,option,goption);
01220 }
01221 return fitResult;
01222 }
01223
01224
01225 Long64_t TTreePlayer::GetEntries(const char *selection)
01226 {
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238 TSelectorEntries s(selection);
01239 fTree->Process(&s);
01240 fTree->SetNotify(0);
01241 return s.GetSelectedRows();
01242 }
01243
01244
01245 Long64_t TTreePlayer::GetEntriesToProcess(Long64_t firstentry, Long64_t nentries) const
01246 {
01247
01248
01249
01250
01251 Long64_t lastentry = firstentry + nentries - 1;
01252 if (lastentry > fTree->GetEntriesFriend()-1) {
01253 lastentry = fTree->GetEntriesFriend() - 1;
01254 nentries = lastentry - firstentry + 1;
01255 }
01256
01257
01258 TEntryList *elist = fTree->GetEntryList();
01259 if (elist && elist->GetN() < nentries) nentries = elist->GetN();
01260 return nentries;
01261 }
01262
01263
01264 const char *TTreePlayer::GetNameByIndex(TString &varexp, Int_t *index,Int_t colindex)
01265 {
01266
01267
01268
01269
01270
01271
01272
01273 Int_t i1,n;
01274 static TString column;
01275 if (colindex<0 ) return "";
01276 i1 = index[colindex] + 1;
01277 n = index[colindex+1] - i1;
01278 column = varexp(i1,n);
01279
01280 return column.Data();
01281 }
01282
01283
01284 static TString R__GetBranchPointerName(TLeaf *leaf)
01285 {
01286
01287
01288 TLeaf *leafcount = leaf->GetLeafCount();
01289 TBranch *branch = leaf->GetBranch();
01290
01291 TString branchname( branch->GetName() );
01292
01293 if ( branch->GetNleaves() <= 1 ) {
01294 if (branch->IsA() != TBranchObject::Class()) {
01295 if (!leafcount) {
01296 TBranch *mother = branch->GetMother();
01297 const char* ltitle = leaf->GetTitle();
01298 if (mother && mother!=branch) {
01299 branchname = mother->GetName();
01300 if (branchname[branchname.Length()-1]!='.') {
01301 branchname += ".";
01302 }
01303 if (strncmp(branchname.Data(),ltitle,branchname.Length())==0) {
01304 branchname = "";
01305 }
01306 } else {
01307 branchname = "";
01308 }
01309 branchname += ltitle;
01310 }
01311 }
01312 }
01313 char *bname = (char*)branchname.Data();
01314 char *twodim = (char*)strstr(bname,"[");
01315 if (twodim) *twodim = 0;
01316 while (*bname) {
01317 if (*bname == '.') *bname='_';
01318 if (*bname == ',') *bname='_';
01319 if (*bname == ':') *bname='_';
01320 if (*bname == '<') *bname='_';
01321 if (*bname == '>') *bname='_';
01322 bname++;
01323 }
01324 return branchname;
01325 }
01326
01327
01328 Int_t TTreePlayer::MakeClass(const char *classname, const char *option)
01329 {
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365 TString opt = option;
01366 opt.ToLower();
01367
01368
01369 if (!classname) classname = fTree->GetName();
01370
01371 TString thead;
01372 thead.Form("%s.h", classname);
01373 FILE *fp = fopen(thead, "w");
01374 if (!fp) {
01375 Error("MakeClass","cannot open output file %s", thead.Data());
01376 return 3;
01377 }
01378 TString tcimp;
01379 tcimp.Form("%s.C", classname);
01380 FILE *fpc = fopen(tcimp, "w");
01381 if (!fpc) {
01382 Error("MakeClass","cannot open output file %s", tcimp.Data());
01383 fclose(fp);
01384 return 3;
01385 }
01386 TString treefile;
01387 if (fTree->GetDirectory() && fTree->GetDirectory()->GetFile()) {
01388 treefile = fTree->GetDirectory()->GetFile()->GetName();
01389 } else {
01390 treefile = "Memory Directory";
01391 }
01392
01393
01394
01395 Bool_t ischain = fTree->InheritsFrom(TChain::Class());
01396 Bool_t isHbook = fTree->InheritsFrom("THbookTree");
01397 if (isHbook)
01398 treefile = fTree->GetTitle();
01399
01400
01401
01402 TObjArray *leaves = fTree->GetListOfLeaves();
01403 Int_t nleaves = leaves ? leaves->GetEntriesFast() : 0;
01404 TDatime td;
01405 fprintf(fp,"//////////////////////////////////////////////////////////\n");
01406 fprintf(fp,"// This class has been automatically generated on\n");
01407 fprintf(fp,"// %s by ROOT version %s\n",td.AsString(),gROOT->GetVersion());
01408 if (!ischain) {
01409 fprintf(fp,"// from TTree %s/%s\n",fTree->GetName(),fTree->GetTitle());
01410 fprintf(fp,"// found on file: %s\n",treefile.Data());
01411 } else {
01412 fprintf(fp,"// from TChain %s/%s\n",fTree->GetName(),fTree->GetTitle());
01413 }
01414 fprintf(fp,"//////////////////////////////////////////////////////////\n");
01415 fprintf(fp,"\n");
01416 fprintf(fp,"#ifndef %s_h\n",classname);
01417 fprintf(fp,"#define %s_h\n",classname);
01418 fprintf(fp,"\n");
01419 fprintf(fp,"#include <TROOT.h>\n");
01420 fprintf(fp,"#include <TChain.h>\n");
01421 fprintf(fp,"#include <TFile.h>\n");
01422 if (isHbook) fprintf(fp,"#include <THbookFile.h>\n");
01423 if (opt.Contains("selector")) fprintf(fp,"#include <TSelector.h>\n");
01424
01425
01426 Int_t len, lenb,l;
01427 char blen[1024];
01428 char *bname;
01429 Int_t *leaflen = new Int_t[nleaves];
01430 TObjArray *leafs = new TObjArray(nleaves);
01431 for (l=0;l<nleaves;l++) {
01432 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
01433 leafs->AddAt(new TObjString(leaf->GetName()),l);
01434 leaflen[l] = leaf->GetMaximum();
01435 }
01436 if (ischain) {
01437
01438
01439
01440 TChain *chain = (TChain*)fTree;
01441 Int_t ntrees = chain->GetNtrees();
01442 for (Int_t file=0;file<ntrees;file++) {
01443 Long64_t first = chain->GetTreeOffset()[file];
01444 chain->LoadTree(first);
01445 for (l=0;l<nleaves;l++) {
01446 TObjString *obj = (TObjString*)leafs->At(l);
01447 TLeaf *leaf = chain->GetLeaf(obj->GetName());
01448 if (leaf) {
01449 leaflen[l] = TMath::Max(leaflen[l],leaf->GetMaximum());
01450 }
01451 }
01452 }
01453 chain->LoadTree(0);
01454 }
01455
01456 leaves = fTree->GetListOfLeaves();
01457 for (l=0;l<nleaves;l++) {
01458 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
01459 strlcpy(blen,leaf->GetName(),sizeof(blen));
01460 bname = &blen[0];
01461 while (*bname) {
01462 if (*bname == '.') *bname='_';
01463 if (*bname == ',') *bname='_';
01464 if (*bname == ':') *bname='_';
01465 if (*bname == '<') *bname='_';
01466 if (*bname == '>') *bname='_';
01467 bname++;
01468 }
01469 lenb = strlen(blen);
01470 if (blen[lenb-1] == '_') {
01471 blen[lenb-1] = 0;
01472 len = leaflen[l];
01473 if (len <= 0) len = 1;
01474 fprintf(fp," const Int_t kMax%s = %d;\n",blen,len);
01475 }
01476 }
01477 delete [] leaflen;
01478 leafs->Delete();
01479 delete leafs;
01480
01481
01482 fprintf(fp,"\n");
01483 if (opt.Contains("selector")) {
01484 fprintf(fp,"class %s : public TSelector {\n",classname);
01485 fprintf(fp,"public :\n");
01486 fprintf(fp," TTree *fChain; //!pointer to the analyzed TTree or TChain\n");
01487 } else {
01488 fprintf(fp,"class %s {\n",classname);
01489 fprintf(fp,"public :\n");
01490 fprintf(fp," TTree *fChain; //!pointer to the analyzed TTree or TChain\n");
01491 fprintf(fp," Int_t fCurrent; //!current Tree number in a TChain\n");
01492 }
01493 fprintf(fp,"\n // Declaration of leaf types\n");
01494 TLeaf *leafcount;
01495 TLeafObject *leafobj;
01496 TBranchElement *bre=0;
01497 const char *headOK = " ";
01498 const char *headcom = " //";
01499 const char *head;
01500 char branchname[1024];
01501 char aprefix[1024];
01502 TObjArray branches(100);
01503 TObjArray mustInit(100);
01504 TObjArray mustInitArr(100);
01505 mustInitArr.SetOwner(kFALSE);
01506 Int_t *leafStatus = new Int_t[nleaves];
01507 for (l=0;l<nleaves;l++) {
01508 Int_t kmax = 0;
01509 head = headOK;
01510 leafStatus[l] = 0;
01511 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
01512 len = leaf->GetLen(); if (len<=0) len = 1;
01513 leafcount =leaf->GetLeafCount();
01514 TBranch *branch = leaf->GetBranch();
01515 branchname[0] = 0;
01516 strlcpy(branchname,branch->GetName(),sizeof(branchname));
01517 strlcpy(aprefix,branch->GetName(),sizeof(aprefix));
01518 if (!branches.FindObject(branch)) branches.Add(branch);
01519 else leafStatus[l] = 1;
01520 if ( branch->GetNleaves() > 1) {
01521
01522 strlcat(branchname,".",sizeof(branchname));
01523 strlcat(branchname,leaf->GetTitle(),sizeof(branchname));
01524 if (leafcount) {
01525
01526 char *dim = (char*)strstr(branchname,"["); if (dim) dim[0] = 0;
01527 }
01528 } else {
01529 strlcpy(branchname,branch->GetName(),sizeof(branchname));
01530 }
01531 char *twodim = (char*)strstr(leaf->GetTitle(),"][");
01532 bname = branchname;
01533 while (*bname) {
01534 if (*bname == '.') *bname='_';
01535 if (*bname == ',') *bname='_';
01536 if (*bname == ':') *bname='_';
01537 if (*bname == '<') *bname='_';
01538 if (*bname == '>') *bname='_';
01539 bname++;
01540 }
01541 if (branch->IsA() == TBranchObject::Class()) {
01542 if (branch->GetListOfBranches()->GetEntriesFast()) {leafStatus[l] = 1; continue;}
01543 leafobj = (TLeafObject*)leaf;
01544 if (!leafobj->GetClass()) {leafStatus[l] = 1; head = headcom;}
01545 fprintf(fp,"%s%-15s *%s;\n",head,leafobj->GetTypeName(), leafobj->GetName());
01546 if (leafStatus[l] == 0) mustInit.Add(leafobj);
01547 continue;
01548 }
01549 if (leafcount) {
01550 len = leafcount->GetMaximum();
01551 if (len<=0) len = 1;
01552 strlcpy(blen,leafcount->GetName(),sizeof(blen));
01553 bname = &blen[0];
01554 while (*bname) {
01555 if (*bname == '.') *bname='_';
01556 if (*bname == ',') *bname='_';
01557 if (*bname == ':') *bname='_';
01558 if (*bname == '<') *bname='_';
01559 if (*bname == '>') *bname='_';
01560 bname++;
01561 }
01562 lenb = strlen(blen);
01563 if (blen[lenb-1] == '_') {blen[lenb-1] = 0; kmax = 1;}
01564 else snprintf(blen,sizeof(blen),"%d",len);
01565 }
01566 if (branch->IsA() == TBranchElement::Class()) {
01567 bre = (TBranchElement*)branch;
01568 if (bre->GetType() != 3 && bre->GetType() != 4
01569 && bre->GetStreamerType() <= 0 && bre->GetListOfBranches()->GetEntriesFast()) {
01570 leafStatus[l] = 0;
01571 }
01572 if (bre->GetType() == 3 || bre->GetType() == 4) {
01573 fprintf(fp," %-15s %s_;\n","Int_t", branchname);
01574 continue;
01575 }
01576 if (bre->IsBranchFolder()) {
01577 fprintf(fp," %-15s *%s;\n",bre->GetClassName(), branchname);
01578 mustInit.Add(bre);
01579 continue;
01580 } else {
01581 if (branch->GetListOfBranches()->GetEntriesFast()) {leafStatus[l] = 1;}
01582 }
01583 if (bre->GetStreamerType() < 0) {
01584 if (branch->GetListOfBranches()->GetEntriesFast()) {
01585 fprintf(fp,"%s%-15s *%s;\n",headcom,bre->GetClassName(), branchname);
01586 } else {
01587 fprintf(fp,"%s%-15s *%s;\n",head,bre->GetClassName(), branchname);
01588 mustInit.Add(bre);
01589 }
01590 continue;
01591 }
01592 if (bre->GetStreamerType() == 0) {
01593 if (!TClass::GetClass(bre->GetClassName())->GetClassInfo()) {leafStatus[l] = 1; head = headcom;}
01594 fprintf(fp,"%s%-15s *%s;\n",head,bre->GetClassName(), branchname);
01595 if (leafStatus[l] == 0) mustInit.Add(bre);
01596 continue;
01597 }
01598 if (bre->GetStreamerType() > 60) {
01599 TClass *cle = TClass::GetClass(bre->GetClassName());
01600 if (!cle) {leafStatus[l] = 1; continue;}
01601 if (bre->GetStreamerType() == 66) leafStatus[l] = 0;
01602 char brename[256];
01603 strlcpy(brename,bre->GetName(),255);
01604 char *bren = brename;
01605 char *adot = strrchr(bren,'.');
01606 if (adot) bren = adot+1;
01607 char *brack = strchr(bren,'[');
01608 if (brack) *brack = 0;
01609 TStreamerElement *elem = (TStreamerElement*)cle->GetStreamerInfo()->GetElements()->FindObject(bren);
01610 if (elem) {
01611 if (elem->IsA() == TStreamerBase::Class()) {leafStatus[l] = 1; continue;}
01612 if (!TClass::GetClass(elem->GetTypeName())) {leafStatus[l] = 1; continue;}
01613 if (!TClass::GetClass(elem->GetTypeName())->GetClassInfo()) {leafStatus[l] = 1; head = headcom;}
01614 if (leafcount) fprintf(fp,"%s%-15s %s[kMax%s];\n",head,elem->GetTypeName(), branchname,blen);
01615 else fprintf(fp,"%s%-15s %s;\n",head,elem->GetTypeName(), branchname);
01616 } else {
01617 if (!TClass::GetClass(bre->GetClassName())->GetClassInfo()) {leafStatus[l] = 1; head = headcom;}
01618 fprintf(fp,"%s%-15s %s;\n",head,bre->GetClassName(), branchname);
01619 }
01620 continue;
01621 }
01622 }
01623 if (strlen(leaf->GetTypeName()) == 0) {leafStatus[l] = 1; continue;}
01624 if (leafcount) {
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634 const char *stars = " ";
01635 if (bre && bre->GetBranchCount2()) {
01636 stars = "*";
01637 }
01638
01639
01640 TString dimensions;
01641 char *dimInName = (char*) strstr(branchname,"[");
01642 if ( twodim || dimInName ) {
01643 if (dimInName) {
01644 dimensions = dimInName;
01645 dimInName[0] = 0;
01646 }
01647 if (twodim) dimensions += (char*)(twodim+1);
01648 }
01649 const char* leafcountName = leafcount->GetName();
01650 char b2len[1024];
01651 if (bre && bre->GetBranchCount2()) {
01652 TLeaf * l2 = (TLeaf*)bre->GetBranchCount2()->GetListOfLeaves()->At(0);
01653 strlcpy(b2len,l2->GetName(),sizeof(b2len));
01654 bname = &b2len[0];
01655 while (*bname) {
01656 if (*bname == '.') *bname='_';
01657 if (*bname == ',') *bname='_';
01658 if (*bname == ':') *bname='_';
01659 if (*bname == '<') *bname='_';
01660 if (*bname == '>') *bname='_';
01661 bname++;
01662 }
01663 leafcountName = b2len;
01664 }
01665 if (dimensions.Length()) {
01666 if (kmax) fprintf(fp," %-14s %s%s[kMax%s]%s; //[%s]\n",leaf->GetTypeName(), stars,
01667 branchname,blen,dimensions.Data(),leafcountName);
01668 else fprintf(fp," %-14s %s%s[%d]%s; //[%s]\n",leaf->GetTypeName(), stars,
01669 branchname,len,dimensions.Data(),leafcountName);
01670 } else {
01671 if (kmax) fprintf(fp," %-14s %s%s[kMax%s]; //[%s]\n",leaf->GetTypeName(), stars, branchname,blen,leafcountName);
01672 else fprintf(fp," %-14s %s%s[%d]; //[%s]\n",leaf->GetTypeName(), stars, branchname,len,leafcountName);
01673 }
01674 if (stars[0]=='*') {
01675 TNamed *n;
01676 if (kmax) n = new TNamed(branchname, Form("kMax%s",blen));
01677 else n = new TNamed(branchname, Form("%d",len));
01678 mustInitArr.Add(n);
01679 }
01680 } else {
01681 if (strstr(branchname,"[")) len = 1;
01682 if (len < 2) fprintf(fp," %-15s %s;\n",leaf->GetTypeName(), branchname);
01683 else {
01684 if (twodim) fprintf(fp," %-15s %s%s;\n",leaf->GetTypeName(), branchname,(char*)strstr(leaf->GetTitle(),"["));
01685 else fprintf(fp," %-15s %s[%d];\n",leaf->GetTypeName(), branchname,len);
01686 }
01687 }
01688 }
01689
01690
01691 fprintf(fp,"\n");
01692 fprintf(fp," // List of branches\n");
01693 for (l=0;l<nleaves;l++) {
01694 if (leafStatus[l]) continue;
01695 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
01696 fprintf(fp," TBranch *b_%s; //!\n",R__GetBranchPointerName(leaf).Data());
01697 }
01698
01699
01700 if (opt.Contains("selector")) {
01701 fprintf(fp,"\n");
01702 fprintf(fp," %s(TTree * /*tree*/ =0) { }\n",classname) ;
01703 fprintf(fp," virtual ~%s() { }\n",classname);
01704 fprintf(fp," virtual Int_t Version() const { return 2; }\n");
01705 fprintf(fp," virtual void Begin(TTree *tree);\n");
01706 fprintf(fp," virtual void SlaveBegin(TTree *tree);\n");
01707 fprintf(fp," virtual void Init(TTree *tree);\n");
01708 fprintf(fp," virtual Bool_t Notify();\n");
01709 fprintf(fp," virtual Bool_t Process(Long64_t entry);\n");
01710 fprintf(fp," virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }\n");
01711 fprintf(fp," virtual void SetOption(const char *option) { fOption = option; }\n");
01712 fprintf(fp," virtual void SetObject(TObject *obj) { fObject = obj; }\n");
01713 fprintf(fp," virtual void SetInputList(TList *input) { fInput = input; }\n");
01714 fprintf(fp," virtual TList *GetOutputList() const { return fOutput; }\n");
01715 fprintf(fp," virtual void SlaveTerminate();\n");
01716 fprintf(fp," virtual void Terminate();\n\n");
01717 fprintf(fp," ClassDef(%s,0);\n",classname);
01718 fprintf(fp,"};\n");
01719 fprintf(fp,"\n");
01720 fprintf(fp,"#endif\n");
01721 fprintf(fp,"\n");
01722 } else {
01723 fprintf(fp,"\n");
01724 fprintf(fp," %s(TTree *tree=0);\n",classname);
01725 fprintf(fp," virtual ~%s();\n",classname);
01726 fprintf(fp," virtual Int_t Cut(Long64_t entry);\n");
01727 fprintf(fp," virtual Int_t GetEntry(Long64_t entry);\n");
01728 fprintf(fp," virtual Long64_t LoadTree(Long64_t entry);\n");
01729 fprintf(fp," virtual void Init(TTree *tree);\n");
01730 fprintf(fp," virtual void Loop();\n");
01731 fprintf(fp," virtual Bool_t Notify();\n");
01732 fprintf(fp," virtual void Show(Long64_t entry = -1);\n");
01733 fprintf(fp,"};\n");
01734 fprintf(fp,"\n");
01735 fprintf(fp,"#endif\n");
01736 fprintf(fp,"\n");
01737 }
01738
01739 fprintf(fp,"#ifdef %s_cxx\n",classname);
01740 if (!opt.Contains("selector")) {
01741 fprintf(fp,"%s::%s(TTree *tree)\n",classname,classname);
01742 fprintf(fp,"{\n");
01743 fprintf(fp,"// if parameter tree is not specified (or zero), connect the file\n");
01744 fprintf(fp,"// used to generate this class and read the Tree.\n");
01745 fprintf(fp," if (tree == 0) {\n");
01746 if (ischain) {
01747 fprintf(fp,"\n#ifdef SINGLE_TREE\n");
01748 fprintf(fp," // The following code should be used if you want this class to access\n");
01749 fprintf(fp," // a single tree instead of a chain\n");
01750 }
01751 if (isHbook) {
01752 fprintf(fp," THbookFile *f = (THbookFile*)gROOT->GetListOfBrowsables()->FindObject(\"%s\");\n",
01753 treefile.Data());
01754 fprintf(fp," if (!f) {\n");
01755 fprintf(fp," f = new THbookFile(\"%s\");\n",treefile.Data());
01756 fprintf(fp," }\n");
01757 Int_t hid;
01758 sscanf(fTree->GetName(),"h%d",&hid);
01759 fprintf(fp," tree = (TTree*)f->Get(%d);\n\n",hid);
01760 } else {
01761 fprintf(fp," TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(\"%s\");\n",treefile.Data());
01762 fprintf(fp," if (!f) {\n");
01763 fprintf(fp," f = new TFile(\"%s\");\n",treefile.Data());
01764 if (gDirectory != gFile) {
01765 fprintf(fp," f->cd(\"%s\");\n",gDirectory->GetPath());
01766 }
01767 fprintf(fp," }\n");
01768 fprintf(fp," tree = (TTree*)gDirectory->Get(\"%s\");\n\n",fTree->GetName());
01769 }
01770 if (ischain) {
01771 fprintf(fp,"#else // SINGLE_TREE\n\n");
01772 fprintf(fp," // The following code should be used if you want this class to access a chain\n");
01773 fprintf(fp," // of trees.\n");
01774 fprintf(fp," TChain * chain = new TChain(\"%s\",\"%s\");\n",
01775 fTree->GetName(),fTree->GetTitle());
01776 TIter next(((TChain*)fTree)->GetListOfFiles());
01777 TChainElement *element;
01778 while ((element = (TChainElement*)next())) {
01779 fprintf(fp," chain->Add(\"%s/%s\");\n",element->GetTitle(),element->GetName());
01780 }
01781 fprintf(fp," tree = chain;\n");
01782 fprintf(fp,"#endif // SINGLE_TREE\n\n");
01783 }
01784 fprintf(fp," }\n");
01785 fprintf(fp," Init(tree);\n");
01786 fprintf(fp,"}\n");
01787 fprintf(fp,"\n");
01788 }
01789
01790
01791 if (!opt.Contains("selector")) {
01792 fprintf(fp,"%s::~%s()\n",classname,classname);
01793 fprintf(fp,"{\n");
01794 fprintf(fp," if (!fChain) return;\n");
01795 if (isHbook) {
01796
01797 } else {
01798 fprintf(fp," delete fChain->GetCurrentFile();\n");
01799 }
01800 fprintf(fp,"}\n");
01801 fprintf(fp,"\n");
01802 }
01803
01804 if (!opt.Contains("selector")) {
01805 fprintf(fp,"Int_t %s::GetEntry(Long64_t entry)\n",classname);
01806 fprintf(fp,"{\n");
01807 fprintf(fp,"// Read contents of entry.\n");
01808
01809 fprintf(fp," if (!fChain) return 0;\n");
01810 fprintf(fp," return fChain->GetEntry(entry);\n");
01811 fprintf(fp,"}\n");
01812 }
01813
01814 if (!opt.Contains("selector")) {
01815 fprintf(fp,"Long64_t %s::LoadTree(Long64_t entry)\n",classname);
01816 fprintf(fp,"{\n");
01817 fprintf(fp,"// Set the environment to read one entry\n");
01818 fprintf(fp," if (!fChain) return -5;\n");
01819 fprintf(fp," Long64_t centry = fChain->LoadTree(entry);\n");
01820 fprintf(fp," if (centry < 0) return centry;\n");
01821 fprintf(fp," if (!fChain->InheritsFrom(TChain::Class())) return centry;\n");
01822 fprintf(fp," TChain *chain = (TChain*)fChain;\n");
01823 fprintf(fp," if (chain->GetTreeNumber() != fCurrent) {\n");
01824 fprintf(fp," fCurrent = chain->GetTreeNumber();\n");
01825 fprintf(fp," Notify();\n");
01826 fprintf(fp," }\n");
01827 fprintf(fp," return centry;\n");
01828 fprintf(fp,"}\n");
01829 fprintf(fp,"\n");
01830 }
01831
01832
01833 fprintf(fp,"void %s::Init(TTree *tree)\n",classname);
01834 fprintf(fp,"{\n");
01835 fprintf(fp," // The Init() function is called when the selector needs to initialize\n"
01836 " // a new tree or chain. Typically here the branch addresses and branch\n"
01837 " // pointers of the tree will be set.\n"
01838 " // It is normally not necessary to make changes to the generated\n"
01839 " // code, but the routine can be extended by the user if needed.\n"
01840 " // Init() will be called many times when running on PROOF\n"
01841 " // (once per file to be processed).\n\n");
01842 if (mustInit.Last()) {
01843 TIter next(&mustInit);
01844 TObject *obj;
01845 fprintf(fp," // Set object pointer\n");
01846 while( (obj = next()) ) {
01847 if (obj->InheritsFrom(TBranch::Class())) {
01848 strlcpy(branchname,((TBranch*)obj)->GetName(),sizeof(branchname));
01849 } else if (obj->InheritsFrom(TLeaf::Class())) {
01850 strlcpy(branchname,((TLeaf*)obj)->GetName(),sizeof(branchname));
01851 }
01852 branchname[1023]=0;
01853 bname = branchname;
01854 while (*bname) {
01855 if (*bname == '.') *bname='_';
01856 if (*bname == ',') *bname='_';
01857 if (*bname == ':') *bname='_';
01858 if (*bname == '<') *bname='_';
01859 if (*bname == '>') *bname='_';
01860 bname++;
01861 }
01862 fprintf(fp," %s = 0;\n",branchname );
01863 }
01864 }
01865 if (mustInitArr.Last()) {
01866 TIter next(&mustInitArr);
01867 TNamed *info;
01868 fprintf(fp," // Set array pointer\n");
01869 while( (info = (TNamed*)next()) ) {
01870 fprintf(fp," for(int i=0; i<%s; ++i) %s[i] = 0;\n",info->GetTitle(),info->GetName());
01871 }
01872 fprintf(fp,"\n");
01873 }
01874 fprintf(fp," // Set branch addresses and branch pointers\n");
01875 fprintf(fp," if (!tree) return;\n");
01876 fprintf(fp," fChain = tree;\n");
01877 if (!opt.Contains("selector")) fprintf(fp," fCurrent = -1;\n");
01878 fprintf(fp," fChain->SetMakeClass(1);\n");
01879 fprintf(fp,"\n");
01880 for (l=0;l<nleaves;l++) {
01881 if (leafStatus[l]) continue;
01882 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
01883 len = leaf->GetLen();
01884 leafcount =leaf->GetLeafCount();
01885 TBranch *branch = leaf->GetBranch();
01886 strlcpy(aprefix,branch->GetName(),sizeof(aprefix));
01887
01888 if ( branch->GetNleaves() > 1) {
01889
01890 strlcpy(branchname,branch->GetName(),sizeof(branchname));
01891 strlcat(branchname,".",sizeof(branchname));
01892 strlcat(branchname,leaf->GetTitle(),sizeof(branchname));
01893 if (leafcount) {
01894
01895 char *dim = (char*)strstr(branchname,"["); if (dim) dim[0] = 0;
01896 }
01897 } else {
01898 strlcpy(branchname,branch->GetName(),sizeof(branchname));
01899 if (branch->IsA() == TBranchElement::Class()) {
01900 bre = (TBranchElement*)branch;
01901 if (bre->GetType() == 3 || bre->GetType()==4) strlcat(branchname,"_",sizeof(branchname));
01902 }
01903 }
01904 bname = branchname;
01905 char *brak = strstr(branchname,"["); if (brak) *brak = 0;
01906 char *twodim = (char*)strstr(bname,"["); if (twodim) *twodim = 0;
01907 while (*bname) {
01908 if (*bname == '.') *bname='_';
01909 if (*bname == ',') *bname='_';
01910 if (*bname == ':') *bname='_';
01911 if (*bname == '<') *bname='_';
01912 if (*bname == '>') *bname='_';
01913 bname++;
01914 }
01915 if (branch->IsA() == TBranchObject::Class()) {
01916 if (branch->GetListOfBranches()->GetEntriesFast()) {
01917 fprintf(fp," fChain->SetBranchAddress(\"%s\",(void*)-1,&b_%s);\n",branch->GetName(),R__GetBranchPointerName(leaf).Data());
01918 continue;
01919 }
01920 strlcpy(branchname,branch->GetName(),sizeof(branchname));
01921 }
01922 if (branch->IsA() == TBranchElement::Class()) {
01923 if (((TBranchElement*)branch)->GetType() == 3) len =1;
01924 if (((TBranchElement*)branch)->GetType() == 4) len =1;
01925 }
01926 if (leafcount) len = leafcount->GetMaximum()+1;
01927 if (len > 1) fprintf(fp," fChain->SetBranchAddress(\"%s\", %s, &b_%s);\n",
01928 branch->GetName(), branchname, R__GetBranchPointerName(leaf).Data());
01929 else fprintf(fp," fChain->SetBranchAddress(\"%s\", &%s, &b_%s);\n",
01930 branch->GetName(), branchname, R__GetBranchPointerName(leaf).Data());
01931 }
01932
01933 if (!opt.Contains("selector")) {
01934 fprintf(fp," Notify();\n");
01935 }
01936
01937 fprintf(fp,"}\n");
01938 fprintf(fp,"\n");
01939
01940
01941 fprintf(fp,"Bool_t %s::Notify()\n",classname);
01942 fprintf(fp,"{\n");
01943 fprintf(fp," // The Notify() function is called when a new file is opened. This\n"
01944 " // can be either for a new TTree in a TChain or when when a new TTree\n"
01945 " // is started when using PROOF. It is normally not necessary to make changes\n"
01946 " // to the generated code, but the routine can be extended by the\n"
01947 " // user if needed. The return value is currently not used.\n\n");
01948 fprintf(fp," return kTRUE;\n");
01949 fprintf(fp,"}\n");
01950 fprintf(fp,"\n");
01951
01952
01953 if (!opt.Contains("selector")) {
01954 fprintf(fp,"void %s::Show(Long64_t entry)\n",classname);
01955 fprintf(fp,"{\n");
01956 fprintf(fp,"// Print contents of entry.\n");
01957 fprintf(fp,"// If entry is not specified, print current entry\n");
01958
01959 fprintf(fp," if (!fChain) return;\n");
01960 fprintf(fp," fChain->Show(entry);\n");
01961 fprintf(fp,"}\n");
01962 }
01963
01964 if (!opt.Contains("selector")) {
01965 fprintf(fp,"Int_t %s::Cut(Long64_t entry)\n",classname);
01966 fprintf(fp,"{\n");
01967 fprintf(fp,"// This function may be called from Loop.\n");
01968 fprintf(fp,"// returns 1 if entry is accepted.\n");
01969 fprintf(fp,"// returns -1 otherwise.\n");
01970
01971 fprintf(fp," return 1;\n");
01972 fprintf(fp,"}\n");
01973 }
01974 fprintf(fp,"#endif // #ifdef %s_cxx\n",classname);
01975
01976
01977 if (!opt.Contains("selector")) {
01978
01979 fprintf(fpc,"#define %s_cxx\n",classname);
01980 fprintf(fpc,"#include \"%s\"\n",thead.Data());
01981 fprintf(fpc,"#include <TH2.h>\n");
01982 fprintf(fpc,"#include <TStyle.h>\n");
01983 fprintf(fpc,"#include <TCanvas.h>\n");
01984 fprintf(fpc,"\n");
01985 fprintf(fpc,"void %s::Loop()\n",classname);
01986 fprintf(fpc,"{\n");
01987 fprintf(fpc,"// In a ROOT session, you can do:\n");
01988 fprintf(fpc,"// Root > .L %s.C\n",classname);
01989 fprintf(fpc,"// Root > %s t\n",classname);
01990 fprintf(fpc,"// Root > t.GetEntry(12); // Fill t data members with entry number 12\n");
01991 fprintf(fpc,"// Root > t.Show(); // Show values of entry 12\n");
01992 fprintf(fpc,"// Root > t.Show(16); // Read and show values of entry 16\n");
01993 fprintf(fpc,"// Root > t.Loop(); // Loop on all entries\n");
01994 fprintf(fpc,"//\n");
01995 fprintf(fpc,"\n// This is the loop skeleton where:\n");
01996 fprintf(fpc,"// jentry is the global entry number in the chain\n");
01997 fprintf(fpc,"// ientry is the entry number in the current Tree\n");
01998 fprintf(fpc,"// Note that the argument to GetEntry must be:\n");
01999 fprintf(fpc,"// jentry for TChain::GetEntry\n");
02000 fprintf(fpc,"// ientry for TTree::GetEntry and TBranch::GetEntry\n");
02001 fprintf(fpc,"//\n");
02002 fprintf(fpc,"// To read only selected branches, Insert statements like:\n");
02003 fprintf(fpc,"// METHOD1:\n");
02004 fprintf(fpc,"// fChain->SetBranchStatus(\"*\",0); // disable all branches\n");
02005 fprintf(fpc,"// fChain->SetBranchStatus(\"branchname\",1); // activate branchname\n");
02006 fprintf(fpc,"// METHOD2: replace line\n");
02007 fprintf(fpc,"// fChain->GetEntry(jentry); //read all branches\n");
02008 fprintf(fpc,"//by b_branchname->GetEntry(ientry); //read only this branch\n");
02009 fprintf(fpc," if (fChain == 0) return;\n");
02010 fprintf(fpc,"\n Long64_t nentries = fChain->GetEntriesFast();\n");
02011 fprintf(fpc,"\n Long64_t nbytes = 0, nb = 0;\n");
02012 fprintf(fpc," for (Long64_t jentry=0; jentry<nentries;jentry++) {\n");
02013 fprintf(fpc," Long64_t ientry = LoadTree(jentry);\n");
02014 fprintf(fpc," if (ientry < 0) break;\n");
02015 fprintf(fpc," nb = fChain->GetEntry(jentry); nbytes += nb;\n");
02016 fprintf(fpc," // if (Cut(ientry) < 0) continue;\n");
02017 fprintf(fpc," }\n");
02018 fprintf(fpc,"}\n");
02019 }
02020 if (opt.Contains("selector")) {
02021
02022 fprintf(fpc,"#define %s_cxx\n",classname);
02023 fprintf(fpc,"// The class definition in %s.h has been generated automatically\n",classname);
02024 fprintf(fpc,"// by the ROOT utility TTree::MakeSelector(). This class is derived\n");
02025 fprintf(fpc,"// from the ROOT class TSelector. For more information on the TSelector\n"
02026 "// framework see $ROOTSYS/README/README.SELECTOR or the ROOT User Manual.\n\n");
02027 fprintf(fpc,"// The following methods are defined in this file:\n");
02028 fprintf(fpc,"// Begin(): called every time a loop on the tree starts,\n");
02029 fprintf(fpc,"// a convenient place to create your histograms.\n");
02030 fprintf(fpc,"// SlaveBegin(): called after Begin(), when on PROOF called only on the\n"
02031 "// slave servers.\n");
02032 fprintf(fpc,"// Process(): called for each event, in this function you decide what\n");
02033 fprintf(fpc,"// to read and fill your histograms.\n");
02034 fprintf(fpc,"// SlaveTerminate: called at the end of the loop on the tree, when on PROOF\n"
02035 "// called only on the slave servers.\n");
02036 fprintf(fpc,"// Terminate(): called at the end of the loop on the tree,\n");
02037 fprintf(fpc,"// a convenient place to draw/fit your histograms.\n");
02038 fprintf(fpc,"//\n");
02039 fprintf(fpc,"// To use this file, try the following session on your Tree T:\n");
02040 fprintf(fpc,"//\n");
02041 fprintf(fpc,"// Root > T->Process(\"%s.C\")\n",classname);
02042 fprintf(fpc,"// Root > T->Process(\"%s.C\",\"some options\")\n",classname);
02043 fprintf(fpc,"// Root > T->Process(\"%s.C+\")\n",classname);
02044 fprintf(fpc,"//\n\n");
02045 fprintf(fpc,"#include \"%s\"\n",thead.Data());
02046 fprintf(fpc,"#include <TH2.h>\n");
02047 fprintf(fpc,"#include <TStyle.h>\n");
02048 fprintf(fpc,"\n");
02049
02050 fprintf(fpc,"\n");
02051 fprintf(fpc,"void %s::Begin(TTree * /*tree*/)\n",classname);
02052 fprintf(fpc,"{\n");
02053 fprintf(fpc," // The Begin() function is called at the start of the query.\n");
02054 fprintf(fpc," // When running with PROOF Begin() is only called on the client.\n");
02055 fprintf(fpc," // The tree argument is deprecated (on PROOF 0 is passed).\n");
02056 fprintf(fpc,"\n");
02057 fprintf(fpc," TString option = GetOption();\n");
02058 fprintf(fpc,"\n");
02059 fprintf(fpc,"}\n");
02060
02061 fprintf(fpc,"\n");
02062 fprintf(fpc,"void %s::SlaveBegin(TTree * /*tree*/)\n",classname);
02063 fprintf(fpc,"{\n");
02064 fprintf(fpc," // The SlaveBegin() function is called after the Begin() function.\n");
02065 fprintf(fpc," // When running with PROOF SlaveBegin() is called on each slave server.\n");
02066 fprintf(fpc," // The tree argument is deprecated (on PROOF 0 is passed).\n");
02067 fprintf(fpc,"\n");
02068 fprintf(fpc," TString option = GetOption();\n");
02069 fprintf(fpc,"\n");
02070 fprintf(fpc,"}\n");
02071
02072 fprintf(fpc,"\n");
02073 fprintf(fpc,"Bool_t %s::Process(Long64_t entry)\n",classname);
02074 fprintf(fpc,"{\n");
02075 fprintf(fpc," // The Process() function is called for each entry in the tree (or possibly\n"
02076 " // keyed object in the case of PROOF) to be processed. The entry argument\n"
02077 " // specifies which entry in the currently loaded tree is to be processed.\n"
02078 " // It can be passed to either %s::GetEntry() or TBranch::GetEntry()\n"
02079 " // to read either all or the required parts of the data. When processing\n"
02080 " // keyed objects with PROOF, the object is already loaded and is available\n"
02081 " // via the fObject pointer.\n"
02082 " //\n"
02083 " // This function should contain the \"body\" of the analysis. It can contain\n"
02084 " // simple or elaborate selection criteria, run algorithms on the data\n"
02085 " // of the event and typically fill histograms.\n"
02086 " //\n"
02087 " // The processing can be stopped by calling Abort().\n"
02088 " //\n"
02089 " // Use fStatus to set the return value of TTree::Process().\n"
02090 " //\n"
02091 " // The return value is currently not used.\n\n", classname);
02092 fprintf(fpc,"\n");
02093 fprintf(fpc," return kTRUE;\n");
02094 fprintf(fpc,"}\n");
02095
02096 fprintf(fpc,"\n");
02097 fprintf(fpc,"void %s::SlaveTerminate()\n",classname);
02098 fprintf(fpc,"{\n");
02099 fprintf(fpc," // The SlaveTerminate() function is called after all entries or objects\n"
02100 " // have been processed. When running with PROOF SlaveTerminate() is called\n"
02101 " // on each slave server.");
02102 fprintf(fpc,"\n");
02103 fprintf(fpc,"\n");
02104 fprintf(fpc,"}\n");
02105
02106 fprintf(fpc,"\n");
02107 fprintf(fpc,"void %s::Terminate()\n",classname);
02108 fprintf(fpc,"{\n");
02109 fprintf(fpc," // The Terminate() function is the last function to be called during\n"
02110 " // a query. It always runs on the client, it can be used to present\n"
02111 " // the results graphically or save the results to file.");
02112 fprintf(fpc,"\n");
02113 fprintf(fpc,"\n");
02114 fprintf(fpc,"}\n");
02115 }
02116 Info("MakeClass","Files: %s and %s generated from TTree: %s",thead.Data(),tcimp.Data(),fTree->GetName());
02117 delete [] leafStatus;
02118 fclose(fp);
02119 fclose(fpc);
02120
02121 return 0;
02122 }
02123
02124
02125
02126 Int_t TTreePlayer::MakeCode(const char *filename)
02127 {
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150 TString tfile;
02151 if (filename)
02152 tfile = filename;
02153 else
02154 tfile.Form("%s.C", fTree->GetName());
02155 FILE *fp = fopen(tfile, "w");
02156 if (!fp) {
02157 Error("MakeCode","cannot open output file %s", tfile.Data());
02158 return 3;
02159 }
02160 TString treefile;
02161 if (fTree->GetDirectory() && fTree->GetDirectory()->GetFile()) {
02162 treefile = fTree->GetDirectory()->GetFile()->GetName();
02163 } else {
02164 treefile = "Memory Directory";
02165 }
02166
02167
02168
02169 Bool_t ischain = fTree->InheritsFrom(TChain::Class());
02170
02171
02172 TObjArray *leaves = fTree->GetListOfLeaves();
02173 Int_t nleaves = leaves ? leaves->GetEntriesFast() : 0;
02174 TDatime td;
02175 fprintf(fp,"{\n");
02176 fprintf(fp,"//////////////////////////////////////////////////////////\n");
02177 fprintf(fp,"// This file has been automatically generated \n");
02178 fprintf(fp,"// (%s by ROOT version%s)\n",td.AsString(),gROOT->GetVersion());
02179 if (!ischain) {
02180 fprintf(fp,"// from TTree %s/%s\n",fTree->GetName(),fTree->GetTitle());
02181 fprintf(fp,"// found on file: %s\n",treefile.Data());
02182 } else {
02183 fprintf(fp,"// from TChain %s/%s\n",fTree->GetName(),fTree->GetTitle());
02184 }
02185 fprintf(fp,"//////////////////////////////////////////////////////////\n");
02186 fprintf(fp,"\n");
02187 fprintf(fp,"\n");
02188
02189
02190
02191 fprintf(fp,"//Reset ROOT and connect tree file\n");
02192 fprintf(fp," gROOT->Reset();\n");
02193 if (ischain) {
02194 fprintf(fp,"\n#ifdef SINGLE_TREE\n");
02195 fprintf(fp," // The following code should be used if you want this code to access\n");
02196 fprintf(fp," // a single tree instead of a chain\n");
02197 }
02198 fprintf(fp," TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject(\"%s\");\n",treefile.Data());
02199 fprintf(fp," if (!f) {\n");
02200 fprintf(fp," f = new TFile(\"%s\");\n",treefile.Data());
02201 if (gDirectory != gFile) {
02202 fprintf(fp," f->cd(\"%s\");\n",gDirectory->GetPath());
02203 }
02204 fprintf(fp," }\n");
02205 fprintf(fp," TTree *%s = (TTree*)gDirectory->Get(\"%s\");\n\n",fTree->GetName(),fTree->GetName());
02206 if (ischain) {
02207 fprintf(fp,"#else // SINGLE_TREE\n\n");
02208 fprintf(fp," // The following code should be used if you want this code to access a chain\n");
02209 fprintf(fp," // of trees.\n");
02210 fprintf(fp," TChain *%s = new TChain(\"%s\",\"%s\");\n",
02211 fTree->GetName(),fTree->GetName(),fTree->GetTitle());
02212 TIter next(((TChain*)fTree)->GetListOfFiles());
02213 TChainElement *element;
02214 while ((element = (TChainElement*)next())) {
02215 fprintf(fp," %s->Add(\"%s/%s\");\n",fTree->GetName(),element->GetTitle(),element->GetName());
02216 }
02217 fprintf(fp,"#endif // SINGLE_TREE\n\n");
02218 }
02219
02220
02221 fprintf(fp,"//Declaration of leaves types\n");
02222 Int_t len, l;
02223 TLeaf *leafcount;
02224 TLeafObject *leafobj;
02225 char *bname;
02226 const char *headOK = " ";
02227 const char *headcom = " //";
02228 const char *head;
02229 char branchname[1024];
02230 for (l=0;l<nleaves;l++) {
02231 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
02232 len = leaf->GetLen();
02233 leafcount =leaf->GetLeafCount();
02234 TBranch *branch = leaf->GetBranch();
02235 if (branch->GetListOfBranches()->GetEntriesFast() > 0) continue;
02236
02237 if ( branch->GetNleaves() > 1) {
02238
02239 strlcpy(branchname,branch->GetName(),sizeof(branchname));
02240 strlcat(branchname,".",sizeof(branchname));
02241 strlcat(branchname,leaf->GetTitle(),sizeof(branchname));
02242 if (leafcount) {
02243
02244 char *dim = (char*)strstr(branchname,"[");
02245 dim[0] = 0;
02246 }
02247 } else {
02248 if (leafcount) strlcpy(branchname,branch->GetName(),sizeof(branchname));
02249 else strlcpy(branchname,leaf->GetTitle(),sizeof(branchname));
02250 }
02251 char *twodim = (char*)strstr(leaf->GetTitle(),"][");
02252 bname = branchname;
02253 while (*bname) {
02254 if (*bname == '.') *bname='_';
02255 if (*bname == ',') *bname='_';
02256 if (*bname == ':') *bname='_';
02257 if (*bname == '<') *bname='_';
02258 if (*bname == '>') *bname='_';
02259 bname++;
02260 }
02261 if (branch->IsA() == TBranchObject::Class()) {
02262 leafobj = (TLeafObject*)leaf;
02263 if (leafobj->GetClass()) head = headOK;
02264 else head = headcom;
02265 fprintf(fp,"%s%-15s *%s = 0;\n",head,leafobj->GetTypeName(), leafobj->GetName());
02266 continue;
02267 }
02268 if (leafcount) {
02269 len = leafcount->GetMaximum();
02270
02271
02272 char *dimInName = (char*) strstr(branchname,"[");
02273 TString dimensions;
02274 if ( twodim || dimInName ) {
02275 if (dimInName) {
02276 dimensions = dimInName;
02277 dimInName[0] = 0;
02278 }
02279 if (twodim) dimensions += (char*)(twodim+1);
02280 }
02281 if (dimensions.Length()) {
02282 fprintf(fp," %-15s %s[%d]%s;\n",leaf->GetTypeName(), branchname,len,dimensions.Data());
02283 } else {
02284 fprintf(fp," %-15s %s[%d];\n",leaf->GetTypeName(), branchname,len);
02285 }
02286 } else {
02287 if (strstr(branchname,"[")) len = 1;
02288 if (len < 2) fprintf(fp," %-15s %s;\n",leaf->GetTypeName(), branchname);
02289 else fprintf(fp," %-15s %s[%d];\n",leaf->GetTypeName(), branchname,len);
02290 }
02291 }
02292
02293
02294 fprintf(fp,"\n // Set branch addresses.\n");
02295 for (l=0;l<nleaves;l++) {
02296 TLeaf *leaf = (TLeaf*)leaves->UncheckedAt(l);
02297 len = leaf->GetLen();
02298 leafcount =leaf->GetLeafCount();
02299 TBranch *branch = leaf->GetBranch();
02300
02301 if ( branch->GetNleaves() > 1) {
02302
02303 strlcpy(branchname,branch->GetName(),sizeof(branchname));
02304 strlcat(branchname,".",sizeof(branchname));
02305 strlcat(branchname,leaf->GetTitle(),sizeof(branchname));
02306 if (leafcount) {
02307
02308 char *dim = (char*)strstr(branchname,"[");
02309 dim[0] = 0;
02310 }
02311 } else {
02312 if (leafcount) strlcpy(branchname,branch->GetName(),sizeof(branchname));
02313 else strlcpy(branchname,leaf->GetTitle(),sizeof(branchname));
02314 }
02315 bname = branchname;
02316 while (*bname) {
02317 if (*bname == '.') *bname='_';
02318 if (*bname == ',') *bname='_';
02319 if (*bname == ':') *bname='_';
02320 if (*bname == '<') *bname='_';
02321 if (*bname == '>') *bname='_';
02322 bname++;
02323 }
02324 char *brak = strstr(branchname,"[");
02325 if (brak) *brak = 0;
02326 head = headOK;
02327 if (branch->IsA() == TBranchObject::Class()) {
02328 strlcpy(branchname,branch->GetName(),sizeof(branchname));
02329 leafobj = (TLeafObject*)leaf;
02330 if (!leafobj->GetClass()) head = headcom;
02331 }
02332 if (leafcount) len = leafcount->GetMaximum()+1;
02333 if (len > 1 || brak) fprintf(fp,"%s%s->SetBranchAddress(\"%s\",%s);\n",head,fTree->GetName(),branch->GetName(),branchname);
02334 else fprintf(fp,"%s%s->SetBranchAddress(\"%s\",&%s);\n",head,fTree->GetName(),branch->GetName(),branchname);
02335 }
02336
02337
02338 fprintf(fp,"\n// This is the loop skeleton\n");
02339 fprintf(fp,"// To read only selected branches, Insert statements like:\n");
02340 fprintf(fp,"// %s->SetBranchStatus(\"*\",0); // disable all branches\n",fTree->GetName());
02341 fprintf(fp,"// %s->SetBranchStatus(\"branchname\",1); // activate branchname\n",GetName());
02342 fprintf(fp,"\n Long64_t nentries = %s->GetEntries();\n",fTree->GetName());
02343 fprintf(fp,"\n Long64_t nbytes = 0;\n");
02344 fprintf(fp,"// for (Long64_t i=0; i<nentries;i++) {\n");
02345 fprintf(fp,"// nbytes += %s->GetEntry(i);\n",fTree->GetName());
02346 fprintf(fp,"// }\n");
02347 fprintf(fp,"}\n");
02348
02349 printf("Macro: %s generated from Tree: %s\n",tfile.Data(), fTree->GetName());
02350 fclose(fp);
02351
02352 return 0;
02353 }
02354
02355
02356 Int_t TTreePlayer::MakeProxy(const char *proxyClassname,
02357 const char *macrofilename, const char *cutfilename,
02358 const char *option, Int_t maxUnrolling)
02359 {
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476
02477
02478
02479
02480
02481
02482
02483
02484
02485 if (macrofilename==0 || strlen(macrofilename)==0 ) {
02486
02487 Error("MakeProxy","A file name for the user script is required");
02488 return 0;
02489 }
02490
02491 TTreeProxyGenerator gp(fTree,macrofilename,cutfilename,proxyClassname,option,maxUnrolling);
02492
02493 return 0;
02494 }
02495
02496
02497 TPrincipal *TTreePlayer::Principal(const char *varexp, const char *selection, Option_t *option, Long64_t nentries, Long64_t firstentry)
02498 {
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515 TTreeFormula **var;
02516 std::vector<TString> cnames;
02517 TString opt = option;
02518 opt.ToLower();
02519 TPrincipal *principal = 0;
02520 Long64_t entry,entryNumber;
02521 Int_t i,nch;
02522 Int_t ncols = 8;
02523 TObjArray *leaves = fTree->GetListOfLeaves();
02524 Int_t nleaves = leaves->GetEntriesFast();
02525 if (nleaves < ncols) ncols = nleaves;
02526 nch = varexp ? strlen(varexp) : 0;
02527
02528 nentries = GetEntriesToProcess(firstentry, nentries);
02529
02530
02531 TTreeFormula *select = 0;
02532 if (strlen(selection)) {
02533 select = new TTreeFormula("Selection",selection,fTree);
02534 if (!select) return principal;
02535 if (!select->GetNdim()) { delete select; return principal; }
02536 fFormulaList->Add(select);
02537 }
02538
02539 int allvar = 0;
02540 if (varexp && !strcmp(varexp, "*")) { ncols = nleaves; allvar = 1; }
02541 if (nch == 0 || allvar) {
02542 for (i=0;i<ncols;i++) {
02543 cnames.push_back( ((TLeaf*)leaves->At(i))->GetName() );
02544 }
02545
02546 } else {
02547 ncols = fSelector->SplitNames(varexp,cnames);
02548 }
02549 var = new TTreeFormula* [ncols];
02550 Double_t *xvars = new Double_t[ncols];
02551
02552
02553 for (i=0;i<ncols;i++) {
02554 var[i] = new TTreeFormula("Var1",cnames[i].Data(),fTree);
02555 fFormulaList->Add(var[i]);
02556 }
02557
02558
02559 TTreeFormulaManager *manager=0;
02560 if (fFormulaList->LastIndex()>=0) {
02561 manager = new TTreeFormulaManager;
02562 for(i=0;i<=fFormulaList->LastIndex();i++) {
02563 manager->Add((TTreeFormula*)fFormulaList->At(i));
02564 }
02565 manager->Sync();
02566 }
02567
02568
02569 if (opt.Contains("n")) principal = new TPrincipal(ncols, "n");
02570 else principal = new TPrincipal(ncols);
02571
02572
02573 fSelectedRows = 0;
02574 Int_t tnumber = -1;
02575 for (entry=firstentry;entry<firstentry+nentries;entry++) {
02576 entryNumber = fTree->GetEntryNumber(entry);
02577 if (entryNumber < 0) break;
02578 Long64_t localEntry = fTree->LoadTree(entryNumber);
02579 if (localEntry < 0) break;
02580 if (tnumber != fTree->GetTreeNumber()) {
02581 tnumber = fTree->GetTreeNumber();
02582 if (manager) manager->UpdateFormulaLeaves();
02583 }
02584 int ndata = 1;
02585 if (manager && manager->GetMultiplicity()) {
02586 ndata = manager->GetNdata();
02587 }
02588
02589 for(int inst=0;inst<ndata;inst++) {
02590 Bool_t loaded = kFALSE;
02591 if (select) {
02592 if (select->EvalInstance(inst) == 0) {
02593 continue;
02594 }
02595 }
02596
02597 if (inst==0) loaded = kTRUE;
02598 else if (!loaded) {
02599
02600
02601 for (i=0;i<ncols;i++) {
02602 var[i]->EvalInstance(0);
02603 }
02604 loaded = kTRUE;
02605 }
02606
02607 for (i=0;i<ncols;i++) {
02608 xvars[i] = var[i]->EvalInstance(inst);
02609 }
02610 principal->AddRow(xvars);
02611 }
02612 }
02613
02614
02615 if (opt.Contains("p")) {
02616 principal->MakePrincipals();
02617 if (opt.Contains("d")) principal->Print();
02618 if (opt.Contains("h")) principal->MakeHistograms();
02619 if (opt.Contains("c")) principal->MakeCode();
02620 }
02621
02622
02623 fFormulaList->Clear();
02624 delete [] var;
02625 delete [] xvars;
02626
02627 return principal;
02628 }
02629
02630
02631 Long64_t TTreePlayer::Process(const char *filename,Option_t *option, Long64_t nentries, Long64_t firstentry)
02632 {
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647
02648
02649
02650
02651
02652
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693 DeleteSelectorFromFile();
02694
02695
02696
02697 TString opt(option);
02698 TString file(filename);
02699 TSelector *selector = TSelector::GetSelector(file);
02700 if (!selector) return -1;
02701
02702 fSelectorFromFile = selector;
02703 fSelectorClass = selector->IsA();
02704
02705 Long64_t nsel = Process(selector,opt,nentries,firstentry);
02706 return nsel;
02707 }
02708
02709
02710 Long64_t TTreePlayer::Process(TSelector *selector,Option_t *option, Long64_t nentries, Long64_t firstentry)
02711 {
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731
02732
02733 nentries = GetEntriesToProcess(firstentry, nentries);
02734
02735 TDirectory::TContext ctxt(0);
02736
02737 fTree->SetNotify(selector);
02738
02739 selector->SetOption(option);
02740
02741 selector->Begin(fTree);
02742 selector->SlaveBegin(fTree);
02743 if (selector->Version() >= 2)
02744 selector->Init(fTree);
02745 selector->Notify();
02746
02747 if (gMonitoringWriter)
02748 gMonitoringWriter->SendProcessingStatus("STARTED",kTRUE);
02749
02750 if (selector->GetAbort() != TSelector::kAbortProcess
02751 && (selector->Version() != 0 || selector->GetStatus() != -1)) {
02752
02753 Long64_t readbytesatstart = 0;
02754 readbytesatstart = TFile::GetFileBytesRead();
02755
02756
02757 TTreeCache *tpf = 0;
02758 TFile *curfile = fTree->GetCurrentFile();
02759 if (curfile && fTree->GetCacheSize() > 0) {
02760 tpf = (TTreeCache*)curfile->GetCacheRead();
02761 if (tpf)
02762 tpf->SetEntryRange(firstentry,firstentry+nentries);
02763 else {
02764 fTree->SetCacheSize(fTree->GetCacheSize());
02765 tpf = (TTreeCache*)curfile->GetCacheRead();
02766 if (tpf) tpf->SetEntryRange(firstentry,firstentry+nentries);
02767 }
02768 }
02769
02770
02771 TProcessEventTimer *timer = 0;
02772 Int_t interval = fTree->GetTimerInterval();
02773 if (!gROOT->IsBatch() && interval)
02774 timer = new TProcessEventTimer(interval);
02775
02776
02777 Long64_t entry, entryNumber, localEntry;
02778
02779 Bool_t useCutFill = selector->Version() == 0;
02780
02781
02782 if (gMonitoringWriter)
02783 gMonitoringWriter->SendProcessingProgress(0,0,kTRUE);
02784
02785
02786
02787
02788 fSelectorUpdate = selector;
02789 UpdateFormulaLeaves();
02790
02791 for (entry=firstentry;entry<firstentry+nentries;entry++) {
02792 entryNumber = fTree->GetEntryNumber(entry);
02793 if (entryNumber < 0) break;
02794 if (timer && timer->ProcessEvents()) break;
02795 if (gROOT->IsInterrupted()) break;
02796 localEntry = fTree->LoadTree(entryNumber);
02797 if (localEntry < 0) break;
02798 if(useCutFill) {
02799 if (selector->ProcessCut(localEntry))
02800 selector->ProcessFill(localEntry);
02801 } else {
02802 selector->Process(localEntry);
02803 }
02804 if (gMonitoringWriter)
02805 gMonitoringWriter->SendProcessingProgress((entry-firstentry),TFile::GetFileBytesRead()-readbytesatstart,kTRUE);
02806 if (selector->GetAbort() == TSelector::kAbortProcess) break;
02807 }
02808 delete timer;
02809
02810 {
02811 TFile *curfile2 = fTree->GetCurrentFile();
02812 if (curfile2 && fTree->GetCacheSize() > 0) {
02813 tpf = (TTreeCache*)curfile2->GetCacheRead();
02814 if (tpf) tpf->SetEntryRange(0,0);
02815 }
02816 }
02817 }
02818
02819 if (selector->Version() != 0 || selector->GetStatus() != -1) {
02820 selector->SlaveTerminate();
02821 selector->Terminate();
02822 }
02823 fSelectorUpdate = 0;
02824 if (gMonitoringWriter)
02825 gMonitoringWriter->SendProcessingStatus("DONE");
02826
02827 return selector->GetStatus();
02828 }
02829
02830
02831 void TTreePlayer::RecursiveRemove(TObject *obj)
02832 {
02833
02834
02835 if (fHistogram == obj) fHistogram = 0;
02836 }
02837
02838
02839 Long64_t TTreePlayer::Scan(const char *varexp, const char *selection,
02840 Option_t * option,
02841 Long64_t nentries, Long64_t firstentry)
02842 {
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905 TString opt = option;
02906 opt.ToLower();
02907 UInt_t ui;
02908 UInt_t lenmax = 0;
02909 UInt_t colDefaultSize = 9;
02910 UInt_t colPrecision = 9;
02911 vector<TString> colFormats;
02912 vector<Int_t> colSizes;
02913
02914 if (opt.Contains("lenmax=")) {
02915 int start = opt.Index("lenmax=");
02916 int numpos = start + strlen("lenmax=");
02917 int numlen = 0;
02918 int len = opt.Length();
02919 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
02920 TString num = opt(numpos,numlen);
02921 opt.Remove(start,strlen("lenmax")+numlen);
02922
02923 lenmax = atoi(num.Data());
02924 }
02925 if (opt.Contains("colsize=")) {
02926 int start = opt.Index("colsize=");
02927 int numpos = start + strlen("colsize=");
02928 int numlen = 0;
02929 int len = opt.Length();
02930 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
02931 TString num = opt(numpos,numlen);
02932 opt.Remove(start,strlen("size")+numlen);
02933
02934 colDefaultSize = atoi(num.Data());
02935 colPrecision = colDefaultSize;
02936 if (colPrecision>18) colPrecision = 18;
02937 }
02938 if (opt.Contains("precision=")) {
02939 int start = opt.Index("precision=");
02940 int numpos = start + strlen("precision=");
02941 int numlen = 0;
02942 int len = opt.Length();
02943 while( (numpos+numlen<len) && isdigit(opt[numpos+numlen]) ) numlen++;
02944 TString num = opt(numpos,numlen);
02945 opt.Remove(start,strlen("precision")+numlen);
02946
02947 colPrecision = atoi(num.Data());
02948 }
02949 TString defFormat = Form("%d.%d",colDefaultSize,colPrecision);
02950 if (opt.Contains("col=")) {
02951 int start = opt.Index("col=");
02952 int numpos = start + strlen("col=");
02953 int numlen = 0;
02954 int len = opt.Length();
02955 while( (numpos+numlen<len) &&
02956 (isdigit(opt[numpos+numlen])
02957 || opt[numpos+numlen] == 'c'
02958 || opt[numpos+numlen] == 'd'
02959 || opt[numpos+numlen] == 'i'
02960 || opt[numpos+numlen] == 'o'
02961 || opt[numpos+numlen] == 'x'
02962 || opt[numpos+numlen] == 'X'
02963 || opt[numpos+numlen] == 'u'
02964 || opt[numpos+numlen] == 'f'
02965 || opt[numpos+numlen] == 'e'
02966 || opt[numpos+numlen] == 'E'
02967 || opt[numpos+numlen] == 'g'
02968 || opt[numpos+numlen] == 'G'
02969 || opt[numpos+numlen] == 'l'
02970 || opt[numpos+numlen] == 'L'
02971 || opt[numpos+numlen] == 'h'
02972 || opt[numpos+numlen] == '#'
02973 || opt[numpos+numlen]=='.'
02974 || opt[numpos+numlen]==':')) numlen++;
02975 TString flist = opt(numpos,numlen);
02976 opt.Remove(start,strlen("col")+numlen);
02977
02978 int i = 0;
02979 while(i<flist.Length() && flist[i]==':') {
02980 colFormats.push_back(defFormat);
02981 colSizes.push_back(colDefaultSize);
02982 ++i;
02983 }
02984 for(; i<flist.Length(); ++i) {
02985 int next = flist.Index(":",i);
02986 if (next==i) {
02987 colFormats.push_back(defFormat);
02988 } else if (next==kNPOS) {
02989 colFormats.push_back(flist(i,flist.Length()-i));
02990 i = flist.Length();
02991 } else {
02992 colFormats.push_back(flist(i,next-i));
02993 i = next;
02994 }
02995 UInt_t siz = atoi(colFormats[colFormats.size()-1].Data());
02996 colSizes.push_back( siz ? siz : colDefaultSize );
02997 }
02998 }
02999
03000 TTreeFormula **var;
03001 std::vector<TString> cnames;
03002 TString onerow;
03003 Long64_t entry,entryNumber;
03004 Int_t i,nch;
03005 UInt_t ncols = 8;
03006 ofstream out;
03007 Int_t lenfile = 0;
03008 char * fname = 0;
03009 if (fScanRedirect) {
03010 fTree->SetScanField(0);
03011 fname = (char *) fScanFileName;
03012 if (!fname) fname = (char*)"";
03013 lenfile = strlen(fname);
03014 if (!lenfile) {
03015 Int_t nch2 = strlen(fTree->GetName());
03016 fname = new char[nch2+10];
03017 strlcpy(fname, fTree->GetName(),nch2+10);
03018 strlcat(fname, "-scan.dat",nch2+10);
03019 }
03020 out.open(fname, ios::out);
03021 if (!out.good ()) {
03022 if (!lenfile) delete [] fname;
03023 Error("Scan","Can not open file for redirection");
03024 return 0;
03025 }
03026 }
03027 TObjArray *leaves = fTree->GetListOfLeaves();
03028 if (leaves==0) return 0;
03029 UInt_t nleaves = leaves->GetEntriesFast();
03030 if (nleaves < ncols) ncols = nleaves;
03031 nch = varexp ? strlen(varexp) : 0;
03032
03033 nentries = GetEntriesToProcess(firstentry, nentries);
03034
03035
03036 TTreeFormula *select = 0;
03037 if (selection && strlen(selection)) {
03038 select = new TTreeFormula("Selection",selection,fTree);
03039 if (!select) return -1;
03040 if (!select->GetNdim()) { delete select; return -1; }
03041 fFormulaList->Add(select);
03042 }
03043
03044 int allvar = 0;
03045 if (varexp && !strcmp(varexp, "*")) { ncols = nleaves; allvar = 1; }
03046 if (nch == 0 || allvar) {
03047 UInt_t ncs = ncols;
03048 ncols = 0;
03049 for (ui=0;ui<ncs;++ui) {
03050 TLeaf *lf = (TLeaf*)leaves->At(ui);
03051 if (lf->GetBranch()->GetListOfBranches()->GetEntries() > 0) continue;
03052 cnames.push_back( lf->GetBranch()->GetMother()->GetName() );
03053 if (cnames[ncols] == lf->GetName() ) {
03054
03055 } else if (cnames[ncols][cnames[ncols].Length()-1]=='.') {
03056 cnames[ncols] = lf->GetBranch()->GetName();
03057 } else {
03058 if (lf->GetBranch()->GetMother()->IsA()->InheritsFrom(TBranchElement::Class())) {
03059 TBranchElement *mother = (TBranchElement*)lf->GetBranch()->GetMother();
03060 if (mother->GetType() == 3 || mother->GetType() == 4) {
03061
03062 cnames[ncols] = lf->GetBranch()->GetName();
03063 ++ncols;
03064 continue;
03065 }
03066 }
03067 if (!strchr(lf->GetBranch()->GetName() ,'[') ) {
03068 cnames[ncols].Append('.');
03069 cnames[ncols].Append( lf->GetBranch()->GetName() );
03070 }
03071 }
03072 if (strcmp( lf->GetBranch()->GetName(), lf->GetName() ) != 0 ) {
03073 cnames[ncols].Append('.');
03074 cnames[ncols].Append( lf->GetName() );
03075 }
03076 ++ncols;
03077 }
03078
03079 } else {
03080
03081 ncols = fSelector->SplitNames(varexp, cnames);
03082
03083 }
03084 var = new TTreeFormula* [ncols];
03085
03086 for(ui=colFormats.size();ui<ncols;++ui) {
03087 colFormats.push_back(defFormat);
03088 colSizes.push_back(colDefaultSize);
03089 }
03090
03091
03092 for (ui=0;ui<ncols;ui++) {
03093 var[ui] = new TTreeFormula("Var1",cnames[ui].Data(),fTree);
03094 fFormulaList->Add(var[ui]);
03095 }
03096
03097
03098 TTreeFormulaManager *manager=0;
03099 Bool_t hasArray = kFALSE;
03100 Bool_t forceDim = kFALSE;
03101 if (fFormulaList->LastIndex()>=0) {
03102 if (select) {
03103 if (select->GetManager()->GetMultiplicity() > 0 ) {
03104 manager = new TTreeFormulaManager;
03105 for(i=0;i<=fFormulaList->LastIndex();i++) {
03106 manager->Add((TTreeFormula*)fFormulaList->At(i));
03107 }
03108 manager->Sync();
03109 }
03110 }
03111 for(i=0;i<=fFormulaList->LastIndex();i++) {
03112 TTreeFormula *form = ((TTreeFormula*)fFormulaList->At(i));
03113 switch( form->GetManager()->GetMultiplicity() ) {
03114 case 1:
03115 case 2:
03116 hasArray = kTRUE;
03117 forceDim = kTRUE;
03118 break;
03119 case -1:
03120 forceDim = kTRUE;
03121 break;
03122 case 0:
03123 break;
03124 }
03125
03126 }
03127 }
03128
03129
03130 onerow = "***********";
03131 if (hasArray) onerow += "***********";
03132
03133 for (ui=0;ui<ncols;ui++) {
03134 TString starFormat = Form("*%%%d.%ds",colSizes[ui]+2,colSizes[ui]+2);
03135 onerow += Form(starFormat.Data(),var[ui]->PrintValue(-2));
03136 }
03137 if (fScanRedirect)
03138 out<<onerow.Data()<<"*"<<endl;
03139 else
03140 printf("%s*\n",onerow.Data());
03141 onerow = "* Row ";
03142 if (hasArray) onerow += "* Instance ";
03143 for (ui=0;ui<ncols;ui++) {
03144 TString numbFormat = Form("* %%%d.%ds ",colSizes[ui],colSizes[ui]);
03145 onerow += Form(numbFormat.Data(),var[ui]->PrintValue(-1));
03146 }
03147 if (fScanRedirect)
03148 out<<onerow.Data()<<"*"<<endl;
03149 else
03150 printf("%s*\n",onerow.Data());
03151 onerow = "***********";
03152 if (hasArray) onerow += "***********";
03153 for (ui=0;ui<ncols;ui++) {
03154 TString starFormat = Form("*%%%d.%ds",colSizes[ui]+2,colSizes[ui]+2);
03155 onerow += Form(starFormat.Data(),var[ui]->PrintValue(-2));
03156 }
03157 if (fScanRedirect)
03158 out<<onerow.Data()<<"*"<<endl;
03159 else
03160 printf("%s*\n",onerow.Data());
03161
03162 fSelectedRows = 0;
03163 Int_t tnumber = -1;
03164 Bool_t exitloop = kFALSE;
03165 for (entry=firstentry;
03166 entry<(firstentry+nentries) && !exitloop;
03167 entry++) {
03168 entryNumber = fTree->GetEntryNumber(entry);
03169 if (entryNumber < 0) break;
03170 Long64_t localEntry = fTree->LoadTree(entryNumber);
03171 if (localEntry < 0) break;
03172 if (tnumber != fTree->GetTreeNumber()) {
03173 tnumber = fTree->GetTreeNumber();
03174 if (manager) manager->UpdateFormulaLeaves();
03175 else {
03176 for(i=0;i<=fFormulaList->LastIndex();i++) {
03177 ((TTreeFormula*)fFormulaList->At(i))->UpdateFormulaLeaves();
03178 }
03179 }
03180 }
03181
03182 int ndata = 1;
03183 if (forceDim) {
03184
03185 if (manager) {
03186
03187 ndata = manager->GetNdata(kTRUE);
03188
03189 } else {
03190
03191
03192 for (ui=0;ui<ncols;ui++) {
03193 if (ndata < var[ui]->GetNdata() ) {
03194 ndata = var[ui]->GetNdata();
03195 }
03196 }
03197 if (select && select->GetNdata()==0) ndata = 0;
03198 }
03199
03200 }
03201
03202 if (lenmax && ndata>(int)lenmax) ndata = lenmax;
03203 Bool_t loaded = kFALSE;
03204 for(int inst=0;inst<ndata;inst++) {
03205 if (select) {
03206 if (select->EvalInstance(inst) == 0) {
03207 continue;
03208 }
03209 }
03210 if (inst==0) loaded = kTRUE;
03211 else if (!loaded) {
03212
03213
03214 for (ui=0;ui<ncols;ui++) {
03215 var[ui]->EvalInstance(0);
03216 }
03217 loaded = kTRUE;
03218 }
03219 onerow = Form("* %8lld ",entryNumber);
03220 if (hasArray) {
03221 onerow += Form("* %8d ",inst);
03222 }
03223 for (ui=0;ui<ncols;++ui) {
03224 TString numbFormat = Form("* %%%d.%ds ",colSizes[ui],colSizes[ui]);
03225 if (var[ui]->GetNdim()) onerow += Form(numbFormat.Data(),var[ui]->PrintValue(0,inst,colFormats[ui].Data()));
03226 else {
03227 TString emptyForm = Form("* %%%dc ",colSizes[ui]);
03228 onerow += Form(emptyForm.Data(),' ');
03229 }
03230 }
03231 fSelectedRows++;
03232 if (fScanRedirect)
03233 out<<onerow.Data()<<"*"<<endl;
03234 else
03235 printf("%s*\n",onerow.Data());
03236 if (fTree->GetScanField() > 0 && fSelectedRows > 0) {
03237 if (fSelectedRows%fTree->GetScanField() == 0) {
03238 fprintf(stderr,"Type <CR> to continue or q to quit ==> ");
03239 int answer, readch;
03240 readch = getchar();
03241 answer = readch;
03242 while (readch != '\n' && readch != EOF) readch = getchar();
03243 if (answer == 'q' || answer == 'Q') {
03244 exitloop = kTRUE;
03245 break;
03246 }
03247 }
03248 }
03249 }
03250 }
03251 onerow = "***********";
03252 if (hasArray) onerow += "***********";
03253 for (ui=0;ui<ncols;ui++) {
03254 TString starFormat = Form("*%%%d.%ds",colSizes[ui]+2,colSizes[ui]+2);
03255 onerow += Form(starFormat.Data(),var[ui]->PrintValue(-2));
03256 }
03257 if (fScanRedirect)
03258 out<<onerow.Data()<<"*"<<endl;
03259 else
03260 printf("%s*\n",onerow.Data());
03261 if (select) Printf("==> %lld selected %s", fSelectedRows,
03262 fSelectedRows == 1 ? "entry" : "entries");
03263 if (fScanRedirect) printf("File <%s> created\n", fname);
03264
03265
03266 fFormulaList->Clear();
03267
03268 delete [] var;
03269 return fSelectedRows;
03270 }
03271
03272
03273 TSQLResult *TTreePlayer::Query(const char *varexp, const char *selection,
03274 Option_t *, Long64_t nentries, Long64_t firstentry)
03275 {
03276
03277
03278
03279
03280
03281
03282 TTreeFormula **var;
03283 std::vector<TString> cnames;
03284 TString onerow;
03285 Long64_t entry,entryNumber;
03286 Int_t i,nch;
03287 Int_t ncols = 8;
03288 TObjArray *leaves = fTree->GetListOfLeaves();
03289 Int_t nleaves = leaves->GetEntriesFast();
03290 if (nleaves < ncols) ncols = nleaves;
03291 nch = varexp ? strlen(varexp) : 0;
03292
03293 nentries = GetEntriesToProcess(firstentry, nentries);
03294
03295
03296 TTreeFormula *select = 0;
03297 if (strlen(selection)) {
03298 select = new TTreeFormula("Selection",selection,fTree);
03299 if (!select) return 0;
03300 if (!select->GetNdim()) { delete select; return 0; }
03301 fFormulaList->Add(select);
03302 }
03303
03304
03305 int allvar = 0;
03306 if (varexp && !strcmp(varexp, "*")) { ncols = nleaves; allvar = 1; }
03307 if (nch == 0 || allvar) {
03308 for (i=0;i<ncols;i++) {
03309 cnames.push_back( ((TLeaf*)leaves->At(i))->GetName() );
03310 }
03311 } else {
03312
03313 ncols = fSelector->SplitNames(varexp,cnames);
03314 }
03315 var = new TTreeFormula* [ncols];
03316
03317
03318 for (i=0;i<ncols;i++) {
03319 var[i] = new TTreeFormula("Var1",cnames[i].Data(),fTree);
03320 fFormulaList->Add(var[i]);
03321 }
03322
03323
03324 TTreeResult *res = new TTreeResult(ncols);
03325 for (i = 0; i < ncols; i++) {
03326 res->AddField(i, var[i]->PrintValue(-1));
03327 }
03328
03329
03330 TTreeFormulaManager *manager=0;
03331 if (fFormulaList->LastIndex()>=0) {
03332 manager = new TTreeFormulaManager;
03333 for(i=0;i<=fFormulaList->LastIndex();i++) {
03334 manager->Add((TTreeFormula*)fFormulaList->At(i));
03335 }
03336 manager->Sync();
03337 }
03338
03339
03340 const char *aresult;
03341 Int_t len;
03342 char *arow = new char[ncols*50];
03343 fSelectedRows = 0;
03344 Int_t tnumber = -1;
03345 Int_t *fields = new Int_t[ncols];
03346 for (entry=firstentry;entry<firstentry+nentries;entry++) {
03347 entryNumber = fTree->GetEntryNumber(entry);
03348 if (entryNumber < 0) break;
03349 Long64_t localEntry = fTree->LoadTree(entryNumber);
03350 if (localEntry < 0) break;
03351 if (tnumber != fTree->GetTreeNumber()) {
03352 tnumber = fTree->GetTreeNumber();
03353 for (i=0;i<ncols;i++) var[i]->UpdateFormulaLeaves();
03354 }
03355
03356 Int_t ndata = 1;
03357 if (manager && manager->GetMultiplicity()) {
03358 ndata = manager->GetNdata();
03359 }
03360
03361 if (select) {
03362 select->GetNdata();
03363 if (select->EvalInstance(0) == 0) continue;
03364 }
03365
03366 Bool_t loaded = kFALSE;
03367 for(int inst=0;inst<ndata;inst++) {
03368 if (select) {
03369 if (select->EvalInstance(inst) == 0) {
03370 continue;
03371 }
03372 }
03373
03374 if (inst==0) loaded = kTRUE;
03375 else if (!loaded) {
03376
03377
03378 for (i=0;i<ncols;i++) {
03379 var[i]->EvalInstance(0);
03380 }
03381 loaded = kTRUE;
03382 }
03383 for (i=0;i<ncols;i++) {
03384 aresult = var[i]->PrintValue(0,inst);
03385 len = strlen(aresult)+1;
03386 if (i == 0) {
03387 memcpy(arow,aresult,len);
03388 fields[i] = len;
03389 } else {
03390 memcpy(arow+fields[i-1],aresult,len);
03391 fields[i] = fields[i-1] + len;
03392 }
03393 }
03394 res->AddRow(new TTreeRow(ncols,fields,arow));
03395 fSelectedRows++;
03396 }
03397 }
03398
03399
03400 fFormulaList->Clear();
03401
03402 delete [] fields;
03403 delete [] arow;
03404 delete [] var;
03405
03406 return res;
03407 }
03408
03409
03410 void TTreePlayer::SetEstimate(Long64_t n)
03411 {
03412
03413
03414
03415 fSelector->SetEstimate(n);
03416 }
03417
03418
03419 void TTreePlayer::StartViewer(Int_t ww, Int_t wh)
03420 {
03421
03422
03423
03424
03425
03426
03427 if (gROOT->IsBatch()) {
03428 Warning("StartViewer", "viewer cannot run in batch mode");
03429 return;
03430 }
03431
03432 if (ww || wh) { }
03433 TPluginHandler *h;
03434 if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualTreeViewer"))) {
03435 if (h->LoadPlugin() == -1)
03436 return;
03437 h->ExecPlugin(1,fTree);
03438 }
03439 }
03440
03441
03442 void TreeUnbinnedFitLikelihood(Int_t & , Double_t * ,
03443 Double_t &r, Double_t *par, Int_t )
03444 {
03445
03446
03447 Double_t x[3];
03448 TF1 *fitfunc = (TF1*)tFitter->GetObjectFit();
03449 fitfunc->InitArgs(x,par);
03450
03451 Long64_t n = gTree->GetSelectedRows();
03452 Double_t *data1 = gTree->GetV1();
03453 Double_t *data2 = gTree->GetV2();
03454 Double_t *data3 = gTree->GetV3();
03455 Double_t *weight = gTree->GetW();
03456 Double_t logEpsilon = -230;
03457 Double_t logL = 0.0, prob;
03458
03459
03460 for(Long64_t i = 0; i < n; i++) {
03461 if (weight[i] <= 0) continue;
03462 x[0] = data1[i];
03463 if (data2) x[1] = data2[i];
03464 if (data3) x[2] = data3[i];
03465 prob = fitfunc->EvalPar(x,par);
03466
03467 if(prob > 0) logL += TMath::Log(prob) * weight[i];
03468 else logL += logEpsilon * weight[i];
03469 }
03470
03471 r = -2*logL;
03472 }
03473
03474
03475
03476 Int_t TTreePlayer::UnbinnedFit(const char *funcname ,const char *varexp, const char *selection,Option_t *option ,Long64_t nentries, Long64_t firstentry)
03477 {
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511
03512
03513
03514
03515
03516
03517
03518
03519
03520
03521
03522
03523
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540 gTree = fTree;
03541
03542
03543 TF1* fitfunc = (TF1*)gROOT->GetFunction(funcname);
03544 if (!fitfunc) { Error("UnbinnedFit", "Unknown function: %s",funcname); return 0; }
03545
03546 Int_t npar = fitfunc->GetNpar();
03547 if (npar <=0) { Error("UnbinnedFit", "Illegal number of parameters = %d",npar); return 0; }
03548
03549
03550
03551
03552 Long64_t oldEstimate = fTree->GetEstimate();
03553 Long64_t nent = fTree->GetEntriesFriend();
03554 fTree->SetEstimate(TMath::Min(nent,nentries));
03555
03556
03557 TString opt = option;
03558 opt.ToUpper();
03559 Foption_t fitOption;
03560 if (opt.Contains("Q")) fitOption.Quiet = 1;
03561 if (opt.Contains("V")){fitOption.Verbose = 1; fitOption.Quiet = 0;}
03562 if (opt.Contains("E")) fitOption.Errors = 1;
03563 if (opt.Contains("M")) fitOption.More = 1;
03564 if (!opt.Contains("D")) fitOption.Nograph = 1;
03565
03566
03567 TString drawOpt = "goff para";
03568 if (!fitOption.Nograph) drawOpt = "";
03569 Long64_t nsel = DrawSelect(varexp, selection,drawOpt, nentries, firstentry);
03570
03571 if (!fitOption.Nograph && GetSelectedRows() <= 0 && GetDimension() > 4) {
03572 Info("UnbinnedFit","Ignore option D with more than 4 variables");
03573 nsel = DrawSelect(varexp, selection,"goff para", nentries, firstentry);
03574 }
03575
03576
03577 Long64_t nrows = GetSelectedRows();
03578
03579 if (nrows <= 0) {
03580 Error("UnbinnedFit", "Cannot fit: no entries selected");
03581 return -1;
03582 }
03583
03584
03585 Int_t ndim = GetDimension();
03586
03587
03588
03589
03590
03591 std::vector<double *> vlist(ndim);
03592 for (int i = 0; i < ndim; ++i)
03593 vlist[i] = fSelector->GetVal(i);
03594
03595
03596 ROOT::Fit::UnBinData * fitdata = new ROOT::Fit::UnBinData(nrows, ndim, vlist.begin());
03597
03598
03599
03600 ROOT::Math::MinimizerOptions minOption;
03601 TFitResultPtr ret = ROOT::Fit::UnBinFit(fitdata,fitfunc, fitOption, minOption);
03602
03603
03604 fTree->SetEstimate(oldEstimate);
03605
03606
03607
03608
03609 if (!fitOption.Nograph && fHistogram) {
03610 if (fHistogram->GetDimension() < 2) {
03611 TH1 *hf = (TH1*)fHistogram->Clone("unbinnedFit");
03612 hf->SetLineWidth(3);
03613 hf->Reset();
03614 Int_t nbins = fHistogram->GetXaxis()->GetNbins();
03615 Double_t norm = ((Double_t)nsel)*fHistogram->GetXaxis()->GetBinWidth(1);
03616 for (Int_t bin=1;bin<=nbins;bin++) {
03617 Double_t func = norm*fitfunc->Eval(hf->GetBinCenter(bin));
03618 hf->SetBinContent(bin,func);
03619 }
03620 fHistogram->GetListOfFunctions()->Add(hf,"lsame");
03621 }
03622 fHistogram->Draw();
03623 }
03624
03625
03626 return int(ret);
03627
03628 }
03629
03630
03631 void TTreePlayer::UpdateFormulaLeaves()
03632 {
03633
03634
03635
03636
03637 if (fSelector) fSelector->Notify();
03638 if (fSelectorUpdate){
03639
03640
03641 if (fSelector==fSelectorUpdate) {
03642
03643 TObject *obj = fSelector->GetObject();
03644 if (obj){
03645 if (fSelector->GetObject()->InheritsFrom(TEntryList::Class())){
03646 ((TEntryList*)fSelector->GetObject())->SetTree(fTree->GetTree());
03647 }
03648 }
03649 }
03650 if (fSelectorFromFile==fSelectorUpdate) {
03651 TIter next(fSelectorFromFile->GetOutputList());
03652 TEntryList *elist=0;
03653 while ((elist=(TEntryList*)next())){
03654 if (elist->InheritsFrom(TEntryList::Class())){
03655 elist->SetTree(fTree->GetTree());
03656 }
03657 }
03658 }
03659 }
03660
03661 if (fFormulaList->GetSize()) {
03662 TObjLink *lnk = fFormulaList->FirstLink();
03663 while (lnk) {
03664 lnk->GetObject()->Notify();
03665 lnk = lnk->Next();
03666 }
03667 }
03668 }