KaliVeda
Toolkit for HIC analysis
KVTreeAnalyzer.cpp
1 //Created by KVClassFactory on Fri Apr 13 12:31:16 2012
2 //Author: John Frankland
3 
4 #include "KVTreeAnalyzer.h"
5 #include "TString.h"
6 #include "TDirectory.h"
7 #include "TSystem.h"
8 #include "TEntryList.h"
9 #include "Riostream.h"
10 #include "KVCanvas.h"
11 #include "TCutG.h"
12 #include "TLeaf.h"
13 #include "TPaveStats.h"
14 #include "TSystem.h"
15 #include "TPad.h"
16 #include "TKey.h"
17 #include "TROOT.h"
18 #include "TGMsgBox.h"
19 #include "KVFileDialog.h"
20 #include "KVDalitzPlot.h"
21 #include "TEnv.h"
22 #include "TColor.h"
23 #include <KVHistogram.h>
24 #include <TChain.h>
25 #include "TFriendElement.h"
26 #include <TTree.h>
27 #include "KVNameValueListGUI.h"
28 #ifdef WITH_PROOF
29 #include "TProof.h"
30 #endif
31 using namespace std;
32 
34 
35 
36 
37 /* colours used for displaying several 1-D spectra on same plot */
38 
39 
41 #define MAX_COLOR_INDEX 5
42 Int_t my_color_array[] = {
43  kBlue + 2,
44  kRed + 2,
45  kGreen + 3,
46  kCyan - 2,
47  kOrange + 7,
48  kViolet + 2
49 };
50 
51 
52 KVTreeAnalyzer* gTreeAnalyzer = 0x0;
53 
55 
56 
59 
61 {
62  // Default initialization
63 
64  gTreeAnalyzer = this;
65  fgAnalyzerList->Add(this);
66  fDeletedByGUIClose = kFALSE;
67 
69  fMain_histolist = 0;
70  fMain_leaflist = 0;
71  fMain_selectionlist = 0;
72  fMenuFile = 0;
73  SetAnalysisModifiedSinceLastSave(kFALSE);
74  fAnalysisSaveDir = ".";
75  fPROOFEnabled = false;
76 
77  fDrawSame = fApplySelection = fProfileHisto = kFALSE;
78  fDrawLog = gEnv->GetValue("KVTreeAnalyzer.LogScale", kFALSE);
79  fUserBinning = gEnv->GetValue("KVTreeAnalyzer.UserBinning", kFALSE);
80  fUserWeight = gEnv->GetValue("KVTreeAnalyzer.UserWeight", kFALSE);
81  fNewCanvas = gEnv->GetValue("KVTreeAnalyzer.NewCanvas", kFALSE);
82  fNormHisto = gEnv->GetValue("KVTreeAnalyzer.NormalizeIntegral", kFALSE);
83  fNormHistoEvents = gEnv->GetValue("KVTreeAnalyzer.NormalizeEvents", kFALSE);
84  fStatsHisto = gEnv->GetValue("KVTreeAnalyzer.Stats", kFALSE);
85  fAutoSaveHisto = kFALSE;
86  fSameColorIndex = 0;
87  fSelectedSelections = 0;
88  fSelectedLeaves = 0;
89  fSelectedHistos = 0;
90 
91  fNx = fNy = 500;
92  fXmin = fXmax = fYmin = fYmax = -1.;
93  fWeight = "1./(abs(vper))";
94 
95  fNxF = 200;
96  fXminF = fXmaxF = -1.;
97 
98  fNxD = fNyD = 120;
99  fOrderedDalitz = false;
100 }
101 
102 
103 
108 
110  : TNamed("KVTreeAnalyzer", "KVTreeAnalyzer"), fTree(0), fChain(0), fSelections(kTRUE), fHistoNumber(1), fSelectionNumber(1), fAliasNumber(1), fNoGui(nogui)
111 {
112  // Default constructor - used when loading from a file.
113  // The 'nogui' option (default=kTRUE) controls whether or not to
114  // launch the graphical interface
115 
116  init();
117  OpenGUI();
118 }
119 
120 
121 
122 
127 
129  : TNamed("KVTreeAnalyzer", t->GetTitle()), fTree(0), fChain(0), fSelections(kTRUE), fHistoNumber(1), fSelectionNumber(1), fAliasNumber(1), fNoGui(nogui)
130 {
131  // Initialize analyzer for a given TTree.
132  // (in fact we re-open the tree using a TChain)
133  // If 'nogui' option (default=kFALSE) is kTRUE we do not launch the graphical interface.
134 
135  init();
136  OpenGUI();
137  KVList fl;
138  fl.Add(new TNamed(t->GetCurrentFile()->GetName(), t->GetCurrentFile()->GetName()));
139  OpenChain(t->GetName(), t->GetTitle(), &fl);
140 }
141 
142 
143 
146 
148 {
149  // Destructor
153  if (gTreeAnalyzer == this) gTreeAnalyzer = 0x0;
154  fgAnalyzerList->Remove(this);
155 }
156 
157 
158 
159 
167 
169 {
170  // This method copies the current state of 'this' object into 'obj'
171  // You should add here any member variables, for example:
172  // (supposing a member variable KVTreeAnalyzer::fToto)
173  // CastedObj.fToto = fToto;
174  // or
175  // CastedObj.SetToto( GetToto() );
176 
177  TNamed::Copy(obj);
178  KVTreeAnalyzer& CastedObj = (KVTreeAnalyzer&)obj;
179  fSelections.Copy(CastedObj.fSelections);// list of TEntryList user selections
180  fHistolist.Copy(CastedObj.fHistolist);//list of generated histograms
181  CastedObj.fTreeName = fTreeName;//name of analyzed TTree
182  CastedObj.fTreeFileName = fTreeFileName;//name of file containing analyzed TTree
183  CastedObj.fHistoNumber = fHistoNumber; //used for automatic naming of histograms
184  CastedObj.fSelectionNumber = fSelectionNumber; //used for automatic naming of selections
185  CastedObj.fAliasNumber = fAliasNumber; //used for automatic naming of TTree aliases
186  fAliasList.Copy(CastedObj.fAliasList);//list of TTree aliases
188  CastedObj.fChain = fChain;
189  CastedObj.SetTree(fChain);
190 }
191 
192 
193 
211 
212 void KVTreeAnalyzer::GenerateHistoTitle(TString& title, const Char_t* expr, const Char_t* selection, const Char_t* weight)
213 {
214  // PRIVATE utility method
215  // Encodes the histogram title for the desired expression and an optional selection.
216  // The expression and selection should be valid TTreeFormula strings
217  // (i.e. they use TTree leaves and/or alias names)
218  // If there is already an active selection (TEntryList set on TTree)
219  // then the corresponding selection expression will also be included in the title.
220  // The format of the resulting title string is one of the following:
221  //
222  // "expr1[:expr2]"
223  // "expr1[:expr2] {selection}"
224  // "expr1[:expr2] {active selection}"
225  // "expr1[:expr2] {(active selection) && (selection)}"
226  //
227  // If histogram is weighted, the weight is added such as:
228  //
229  // "expr1:expr2 [weight] {active selection}"
230 
231 
232  TString _selection(selection);
233  TString _elist;
234  if (fChain->GetEntryList()) _elist = fChain->GetEntryList()->GetTitle();
235  if (strcmp(weight, "")) {
236  if (_selection != "" && _elist != "")
237  title.Form("%s [%s] {(%s) && (%s)}", expr, weight, _elist.Data(), selection);
238  else if (_selection != "")
239  title.Form("%s [%s] {%s}", expr, weight, selection);
240  else if (_elist != "")
241  title.Form("%s [%s] {%s}", expr, weight, _elist.Data());
242  else
243  title.Form("%s [%s]", expr, weight);
244  }
245  else {
246  if (_selection != "" && _elist != "")
247  title.Form("%s {(%s) && (%s)}", expr, _elist.Data(), selection);
248  else if (_selection != "")
249  title.Form("%s {%s}", expr, selection);
250  else if (_elist != "")
251  title.Form("%s {%s}", expr, _elist.Data());
252  else
253  title.Form("%s", expr);
254  }
255 }
256 
257 
258 
275 
276 TH1* KVTreeAnalyzer::MakeHisto(const Char_t* expr, const Char_t* selection, Int_t nX, Int_t nY, const Char_t* weight, Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax)
277 {
278  // Create and fill a new histogram with the desired expression (expr="expr1[:expr2]" etc.)
279  // with the given selection (selection="" if no selection required).
280  // Any currently active selection (TEntryList set on TTree) will also be applied.
281  // The new histogram is not drawn but added to the internal list of histograms
282  // (see method AddHisto).
283  //
284  // Histograms are automatically named 'h1', 'h2', etc. in order of creation.
285  // Histogram title is generated with method GenerateHistoTitle.
286  // Number of bins on X (and Y for a 2-D spectrum) are given. Axis limits are
287  // automatically adjusted to data unless given.
288  //
289  // For 2-D spectra the initial drawing option is set to "COL"
290  //
291  // If normalisation of spectra is required (fNormHisto = kTRUE) the histogram
292  // bin contents are divided by the integral (sum of weights).
293 
294  TString name;
295  name.Form("h%d", fHistoNumber);
296  TString drawexp(expr), histo, histotitle;
297  if (strcmp(weight, "")) GenerateHistoTitle(histotitle, expr, selection, weight);
298  else GenerateHistoTitle(histotitle, expr, selection);
299  if ((!nY) && (fUserBinning)) {
300  if (!DefineUserBinning1F()) return nullptr;
301  }
302 
303  TString Selection;
304  if (strcmp(weight, "")) {
305  if (strcmp(selection, "")) Selection.Form("(%s)&&(%s)", selection, weight);
306  else Selection = weight;
307  }
308  else
309  Selection = selection;
310  if (nY) histo.Form(">>%s(%d,%f,%f,%d,%f,%f)", name.Data(), nX, xmin, xmax, nY, ymin, ymax);
311  else histo.Form(">>%s(%d,%lf,%lf)", name.Data(), (fUserBinning ? fNxF : nX), (fUserBinning ? fXminF : xmin), (fUserBinning ? fXmaxF : xmax));
312 
313  /*if (!fProfileHisto)*/ drawexp += histo;
314  Long64_t drawResult;
315  if (fProfileHisto) drawResult = fTree->Draw(drawexp, Selection, "prof,goff");// fTree->Draw(Form("%s>>%s", drawexp.Data(), name.Data()), Selection, "prof,goff");
316  else drawResult = fTree->Draw(drawexp, Selection, "goff");
317  if (drawResult < 0) {
318  // Error with Draw: probably a bad expression
319  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
320  return nullptr;
321  }
322  TH1* h;
323 #ifdef WITH_PROOF
324  if (IsPROOFEnabled())
326  else
327 #endif
328  h = (TH1*)gDirectory->Get(name);
329  h->SetTitle(histotitle);
330  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
331  h->SetDirectory(0);
332  AddHisto(h);
333  fHistoNumber++;
334  if (!fProfileHisto) {
335  if (fNormHisto || fNormHistoEvents) {
336  h->Sumw2();
337  if (fNormHisto) {
338  h->Scale(1. / h->Integral("width"));
339  }
340  else {
342  }
343  }
344  }
345  return h;
346 }
347 
348 
349 
356 
357 TH1* KVTreeAnalyzer::MakeIntHisto(const Char_t* expr, const Char_t* selection, Int_t Xmin, Int_t Xmax, const Char_t* weight)
358 {
359  // Like MakeHisto but only used for 1-D spectra of integer variables.
360  // The number of bins is Xmax-Xmin+1 and bins are defined over [x-0.5,x+0.5]
361  // for all values of x.
362  //
363  // Histograms are automatically named 'Ih1', 'Ih2', etc. in order of creation.
364 
365  TString name;
366  name.Form("Ih%d", fHistoNumber);
367  TString drawexp(expr), histo, histotitle;
368  if (strcmp(weight, "")) GenerateHistoTitle(histotitle, expr, selection, weight);
369  else GenerateHistoTitle(histotitle, expr, selection);
370 
371  if (fUserBinning) {
372  if (!DefineUserBinning1F()) return nullptr;
373  }
374 
375  histo.Form(">>%s(%d,%f,%f)", name.Data(), (fUserBinning ? fNxF : (Xmax - Xmin) + 1),
376  (fUserBinning ? fXminF : Xmin - 0.5), (fUserBinning ? fXmaxF : Xmax + 0.5));
377  drawexp += histo;
378  TString Selection;
379  if (strcmp(weight, "")) {
380  if (strcmp(selection, "")) Selection.Form("(%s)&&(%s)", selection, weight);
381  else Selection = weight;
382  }
383  else
384  Selection = selection;
385  Long64_t drawResult = fTree->Draw(drawexp, Selection, "goff");
386  if (drawResult < 0) {
387  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
388  return nullptr;
389  }
390  TH1* h;
391 #ifdef WITH_PROOF
392  if (IsPROOFEnabled())
394  else
395 #endif
396  h = (TH1*)gDirectory->Get(name);
397  h->SetTitle(histotitle);
398  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
399  h->SetDirectory(0);
400 
401  AddHisto(h);
402  fHistoNumber++;
403  if (fNormHisto || fNormHistoEvents) {
404  h->Sumw2();
405  if (fNormHisto) {
406  h->Scale(1. / h->Integral("width"));
407  }
408  else {
410  }
411  }
412  return h;
413 }
414 
415 
416 
419 
421 {
422  // Return histogram with given name
423 
425  if (h->IsType("Histo")) return h->GetHisto();
426  return NULL;
427 }
428 
429 
430 
445 
447 {
448  // Generate a new user-selection (TEntryList) of events in the TTree
449  // according to the given selection expression (valid TTreeFormula expression
450  // using TTree leaf and/or alias names).
451  // The new selection is not applied immediately but added to the internal
452  // list of selections (see method AddSelection).
453  //
454  // If there is already an active selection (TEntryList set on TTree)
455  // this will generate the composite selection, {(active selection) && (selection)}.
456  // The selection's title will then be in the following format:
457  //
458  // "[(active selection) && ](selection)"
459  //
460  // TEntryList objects are automatically named 'el1', 'el2', etc. in order of creation.
461 
462  TObject* tmpObj = gROOT->FindObject(selection);
463  if (tmpObj) {
464  if (tmpObj->InheritsFrom("TCutG")) {
465  TCutG* cut = (TCutG*) tmpObj;
466  cut->SetTitle(cut->GetName());
467  AddCut(cut);
468  }
469  }
470 
471  TString name;
472  name.Form("el%d", fSelectionNumber);
473  TString drawexp(name.Data());
474  drawexp.Prepend(">>");
477  if (fChain->Draw(drawexp, selection, "entrylist") < 0) {
478  new TGMsgBox(gClient->GetRoot(), 0, "Warning", "Mistake in your new selection!", kMBIconExclamation, kMBClose);
479  return kFALSE;
480  }
482  TEntryList* el;
483 #ifdef WITH_PROOF
486  else
487 #endif
488  el = (TEntryList*)gDirectory->Get(name);
489  el->SetTitle(selection);//needed with PROOF
490  if (fChain->GetEntryList()) {
491  TString _elist = fChain->GetEntryList()->GetTitle();
492  TString title;
493  title.Form("(%s) && (%s)", _elist.Data(), selection);
494  el->SetTitle(title);
495  }
497  AddSelection(el);
499  return kTRUE;
500 }
501 
502 
503 
511 
513 {
514  // Method called when a selection is double-clicked in the GUI list.
515  // The required selection is passed as argument (address of TEntryList object)
516  // and becomes the currently active selection (TEntryList set on TTree).
517  // If the requested selection was already active, it is deactivated
518  // (remove TEntryList from TTree).
519  // The 'CURRENT SELECTION' message in the GUI status bar is updated.
520 
521  if (!obj->InheritsFrom("TEntryList")) return;
522  TEntryList* el = dynamic_cast<TEntryList*>(obj);
523  if (fChain->GetEntryList() == el) {
524  SetEntryList(nullptr);
525  G_selection_status->SetText("CURRENT SELECTION:", 0);
526  return;
527  }
528  SetEntryList(el);
529  G_selection_status->SetText(Form("CURRENT SELECTION: %s (%lld)", el->GetTitle(), el->GetN()), 0);
530 }
531 
532 
533 
536 
538 {
539  // Print the currently active selection (TEntryList set on TTree).
540 
541  TString tmp;
542  if (fChain->GetEntryList()) tmp = fChain->GetEntryList()->GetTitle();
543  else tmp = "";
544  if (tmp != "") cout << "CURRENT SELECTION : " << tmp << endl;
545 }
546 
547 
548 
552 
554 {
555  // Return number of entries (events) in the currently active selection,
556  // or the number of entries in the analysed TTree/TChain if no selection active
557 
558  if (fChain->GetEntryList()) return fChain->GetEntryList()->GetN();
559  return fChain->GetEntries();
560 }
561 
562 
563 
567 
569 {
570  // Fills the GUI list with the names of all leaves in the TTree
571  // and any friend TTrees and all aliases defined by the user
572 
573  TList stuff;
574  if (fTree) {
575  // clone list of leaves
576  fLeafList.Clear();
578  // when using a split object to fill the tree
579  // there is a redundant leaf/branch corresponding to the object itself
580  // more precisely there will be a TLeafElement in the list of leaves
581  // and a TBranchElement in the list of branches with the same name
582  //
583  // however the same applies to a simple unsplit object (such as using a TString to store
584  // strings). as the latter is probably far more common than the former (who creates trees
585  // with split objects in them these days???), I comment out the check which stopped such
586  // leaves appearing in the GUI (they are perfectly usable).
587  TIter next(clones);
588  TObject* o;
589  while ((o = next())) {
590 // if (o->InheritsFrom("TLeafElement")
591 // && fTree->GetListOfBranches()->FindObject(o->GetName())
592 // && fTree->GetListOfBranches()->FindObject(o->GetName())->InheritsFrom("TBranchElement"))
593 // continue;
594  fLeafList.Add(o);
595  }
596  delete clones;
597 
598  stuff.AddAll(&fLeafList);
599  stuff.AddAll(fTree->GetListOfAliases());
600  if (fTree->GetListOfFriends()) {
602  TFriendElement* fel;
603  while ((fel = (TFriendElement*)it())) {
604  stuff.AddAll(fel->GetTree()->GetListOfLeaves());
605  stuff.AddAll(fel->GetTree()->GetListOfAliases());
606  }
607  }
608  }
609  stuff.AddAll(&fAliasList);
610  G_leaflist->Display(&stuff);
611 }
612 
613 
614 
618 
620 {
621  // if analysis has been modified since last save,
622  // open an invite to ask if user wants to save with current default filename
623 
624  if (!fAnalysisModifiedSinceLastSave) return;
625 
626  if (fNoGui) {
627  // text-only interface
628  cout << "Analysis " << GetTitle() << " has been modified. Save before continuing? [y] : " << flush;
629  char reply;
630  cin.get(reply);
631  cout << endl;
632  if (reply == 'n' || reply == 'N') return;
633  cout << "Give name of file [" << fSaveAnalysisFileName << "] : " << flush;
634  char filename[256];
635  cin.get(filename, 256);
636  if (filename[0] != 0) fSaveAnalysisFileName = filename;
637  Save();
638  }
639  else {
640  Int_t ret_code;
642  new TGMsgBox(gClient->GetDefaultRoot(), (fMain_histolist ? fMain_histolist : gClient->GetDefaultRoot()), GetTitle(),
643  "Analysis has been modified. Save before continuing?", kMBIconStop,
644  kMBYes | kMBNo, &ret_code);
645  if (ret_code == kMBNo) return;
647  }
648 }
649 
650 
651 
653 
655 {
657  if (fMenuFile) {
658  if (x) {
661  }
662  else {
665  }
666  }
667 }
668 
669 
670 
679 
681 {
682  // Modify currently active selection (TEntryList)
683  // Instead of calling
684  // fChain->SetEntryList(l);
685  // call this method which works with or without PROOF.
686  // When using PROOF, fChain->SetEntryList(nullptr)
687  // does not work (bug in TProofChain), the last selection
688  // remains active. This problem is corrected here.
689 
691 
692  if (l == nullptr && IsPROOFEnabled()) {
695  }
696 }
697 
698 
699 
702 
704 {
705  // Launch the GUI (unless fNoGui=kTRUE in which case this does nothing)
706 
707  if (fNoGui) return;
708 
709  ULong_t red, cyan, green, yellow, magenta, gura, gurb, gurc, gurd, gure, gurf;
710  gClient->GetColorByName("#ff00ff", magenta);
711  gClient->GetColorByName("#ff0000", red);
712  gClient->GetColorByName("#00ff00", green);
713  gClient->GetColorByName("#00ffff", cyan);
714  gClient->GetColorByName("#ffff00", yellow);
715  gClient->GetColorByName("#cf14b2", gura);
716  gClient->GetColorByName("#cd93e6", gurb);
717  gClient->GetColorByName("#c1e91a", gurc);
718  gClient->GetColorByName("#d1a45b", gurd);
719  gClient->GetColorByName("#b54cfe", gure);
720  gClient->GetColorByName("#a325ef", gurf);
721 
722  /********* MAIN WINDOW **************/
723  //
724  fMain_histolist = new TGMainFrame(gClient->GetRoot(), 10, 10, kMainFrame | kVerticalFrame);
725  fMain_histolist->SetName("fMain_histolist");
726  if (!fTree)
727  fMain_histolist->SetWindowName("Tree Analyzer");
728  else
730  fMain_histolist->SetIconName("TreeAnalyzer");
731  fMain_histolist->SetIconPixmap("root_s.xpm");
732 
734 
735  UInt_t hWidth = 400, hHeight = 400;
736 
737  /* menus */
738  fMenuFile = new TGPopupMenu(gClient->GetRoot());
739  fMenuFile->AddEntry("New analysis", MH_OPEN_CHAIN);
740  fMenuFile->AddEntry("Open analysis", MH_OPEN_FILE);
741  fMenuFile->AddEntry("Add Friend...", MH_ADD_FRIEND);
743  fMenuFile->AddEntry("Save analysis", MH_SAVE);
744  fMenuFile->AddEntry("Save as...", MH_SAVE_FILE);
745  fMenuFile->AddEntry("Close", MH_CLOSE);
747  fMenuFile->AddEntry("Apply analysis...", MH_APPLY_ANALYSIS);
750  fMenuFile->AddEntry("Quit", MH_QUIT);
751  fMenuFile->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleHistoFileMenu(Int_t)");
752  fMenuSelections = new TGPopupMenu(gClient->GetRoot());
753  fSelCombMenu = new TGPopupMenu(gClient->GetRoot());
754  fSelCombMenu->AddEntry("AND (&&)", SEL_COMB_AND);
755  fSelCombMenu->AddEntry("OR (||)", SEL_COMB_OR);
756  fMenuSelections->AddPopup("Combine...", fSelCombMenu);
759  fMenuSelections->AddEntry("Update", SEL_UPDATE);
760  fMenuSelections->AddEntry("Delete", SEL_DELETE);
762  fSelGenerate = new TGPopupMenu(gClient->GetRoot());
763  fSelGenerate->AddEntry("Constant X-sections", SEL_GEN_CONST_XSEC);
764  fMenuSelections->AddPopup("Generate...", fSelGenerate);
765  fMenuSelections->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleSelectionsMenu(Int_t)");
766  fOptionMenu = new TGPopupMenu(gClient->GetRoot());
767  fOptionMenu->AddEntry("PROOF", OPT_PROOF);
768  fOptionMenu->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleOptionsMenu(Int_t)");
777 
778  // Horizontal frame to contain the VARIABLES list (left) and SELECTIONS list (right)
780 
781  /********* VARIABLES **************/
782  // Group frame for TTree variables/aliases
783  fMain_leaflist = new TGGroupFrame(hf, "VARIABLES");
784  UInt_t lWidth = 300, lHeight = 300;
785  /* leaf list */
786 
787  /* make selection */
788  TGHorizontalFrame* fHorizontalFrame = new TGHorizontalFrame(fMain_leaflist, lWidth, 36, kHorizontalFrame);
789  TGLabel* lab = new TGLabel(fHorizontalFrame, "Make alias : ");
790  fHorizontalFrame->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
791  G_alias_text = new TGTextEntry(fHorizontalFrame, new TGTextBuffer(50));
792  G_alias_text->SetMaxLength(4096);
795  G_alias_text->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateAlias()");
796  fHorizontalFrame->AddFrame(G_alias_text, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 2, 5, 2, 2));
797  fMain_leaflist->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
798 
799  G_leaflist = new KVListView(TNamed::Class(), fMain_leaflist, lWidth, lHeight);
801  G_leaflist->SetDataColumn(0, "Title");
804  G_leaflist->SetDoubleClickAction("KVTreeAnalyzer", this, "DrawLeaf(TObject*)");
805  G_leaflist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "LeafChanged()");
806 // G_leaflist->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "ShowVar()");
809  5, 5, 5, 5));
810 
811  //fMain_leaflist->MapSubwindows();
812 
814  //fMain_leaflist->MapWindow();
815  fMain_leaflist->Resize(lWidth, lHeight);
816  FillLeafList();
817  /*********end of VARIABLES **************/
818  hf->AddFrame(fMain_leaflist, new TGLayoutHints(kLHintsLeft, 5, 5, 5, 5));
819 
820  /******* SELECTIONS *********/
821  UInt_t sWidth = 600, sHeight = lHeight;
822  fMain_selectionlist = new TGGroupFrame(hf, "SELECTIONS");
823  /* current selection */
825  G_selection_status->SetText("CURRENT SELECTION:", 0);
827  /* make selection */
828  TGHorizontalFrame* fHorizontalFrame1614 = new TGHorizontalFrame(fMain_selectionlist, sWidth, 36, kHorizontalFrame);
829  lab = new TGLabel(fHorizontalFrame1614, "Make selection : ");
830  fHorizontalFrame1614->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
831  G_selection_text = new TGTextEntry(fHorizontalFrame1614, new TGTextBuffer(50));
835  G_selection_text->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateSelection()");
836  fHorizontalFrame1614->AddFrame(G_selection_text, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 2, 5, 2, 2));
837  fMain_selectionlist->AddFrame(fHorizontalFrame1614, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
838 
839  /* selection list */
842  G_selectionlist->SetDataColumn(0, "Selection", "GetTitle");
843  G_selectionlist->SetDataColumn(1, "Reapply", "GetReapplyCut");
845  G_selectionlist->SetDataColumn(2, "Events", "GetN", kTextRight);
847  G_selectionlist->SetDoubleClickAction("KVTreeAnalyzer", this, "SetSelection(TObject*)");
848  G_selectionlist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "SelectionChanged()");
851  5, 5, 5, 5));
852 
853  //fMain_selectionlist->MapSubwindows();
854 
856  //fMain_selectionlist->MapWindow();
857  fMain_selectionlist->Resize(sWidth, sHeight);
859  /******end of SELECTIONS *********/
862 
863  /**** Histo creation group ********/
864  TGGroupFrame* histo_opts = new TGGroupFrame(fMain_histolist, "CREATE HISTO", kHorizontalFrame);
865  fHorizontalFrame = new TGHorizontalFrame(histo_opts, lWidth, 36, kHorizontalFrame);
866  G_leaf_draw = new TGPictureButton(fHorizontalFrame, "draw_t.xpm");
868  G_leaf_draw->Connect("Clicked()", "KVTreeAnalyzer", this, "DrawLeafExpr()");
869  fHorizontalFrame->AddFrame(G_leaf_draw, new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 2, 2, 2));
870  fLeafExpr = " ";
871  G_leaf_expr = new TGLabel(fHorizontalFrame, fLeafExpr.Data());
872  G_leaf_expr->Resize();
873  fHorizontalFrame->AddFrame(G_leaf_expr, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
874  histo_opts->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
875 
876  G_histo_prof = new TGCheckButton(histo_opts, "Profile");
877  G_histo_prof->SetToolTipText("Generate a profile histogram");
879  G_histo_prof->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetProfileHisto(Bool_t)");
880  histo_opts->AddFrame(G_histo_prof, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
881 
882  G_histo_norm = new TGCheckButton(histo_opts, "Normalize (integral)");
883  G_histo_norm->SetToolTipText("Generate normalized histogram with integral=1");
885  G_histo_norm->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNormHisto(Bool_t)");
886  histo_opts->AddFrame(G_histo_norm, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
887  G_histo_norm_events = new TGCheckButton(histo_opts, "Normalize (events)");
888  G_histo_norm_events->SetToolTipText("Generate histogram with integral divided by number of events");
890  G_histo_norm_events->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNormHistoEvents(Bool_t)");
891  histo_opts->AddFrame(G_histo_norm_events, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
892 
893  G_histo_weight = new TGCheckButton(histo_opts, "Weight");
894  G_histo_weight->SetToolTipText("User defined binning of the histogram");
896  G_histo_weight->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetUserWeight(Bool_t)");
897  histo_opts->AddFrame(G_histo_weight, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
898 
899  G_histo_bin = new TGCheckButton(histo_opts, "Bins");
900  G_histo_bin->SetToolTipText("User defined binning of the histogram");
902  G_histo_bin->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetUserBinning(Bool_t)");
903  histo_opts->AddFrame(G_histo_bin, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
904  fMain_histolist->AddFrame(histo_opts, new TGLayoutHints(kLHintsCenterX | kLHintsExpandX, 5, 5, 5, 5));
905 
906  /******** HISTOGRAMS *****************/
907  hWidth = lWidth + sWidth + 20;
908  TGGroupFrame* histo_group = new TGGroupFrame(fMain_histolist, "HISTOGRAMS");
909  /* ip scale */
910 // histo_opts = new TGGroupFrame(histo_group, "Impact parameter", kHorizontalFrame);
911 // G_make_ip_scale = new TGTextButton(histo_opts,"Make scale");
912 // G_make_ip_scale->SetTextJustify(36);
913 // G_make_ip_scale->SetMargins(0,0,0,0);
914 // G_make_ip_scale->SetWrapLength(-1);
915 // G_make_ip_scale->Resize();
916 // G_make_ip_scale->SetEnabled(kFALSE);
917 // G_make_ip_scale->Connect("Clicked()","KVTreeAnalyzer",this,"MakeIPScale()");
918 // G_make_ip_scale->ChangeBackground(green);
919 // histo_opts->AddFrame(G_make_ip_scale, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,10,2));
920 // lab = new TGLabel(histo_opts,"b <");
921 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,5,2,12,2));
922 // G_make_ip_selection = new TGTextEntry(histo_opts, new TGTextBuffer(5));
923 // G_make_ip_selection->SetMaxLength(10);
924 // G_make_ip_selection->SetAlignment(kTextLeft);
925 // G_make_ip_selection->Resize(50,G_make_ip_selection->GetDefaultHeight());
926 // G_make_ip_selection->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateIPSelection()");
927 // G_make_ip_selection->SetEnabled(kFALSE);
928 // histo_opts->AddFrame(G_make_ip_selection, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,10,2));
929 // G_ip_histo = new TGLabel(histo_opts,"-");
930 // histo_opts->AddFrame(G_ip_histo, new TGLayoutHints(kLHintsLeft|kLHintsTop,5,2,12,2));
931 // histo_group->AddFrame(histo_opts, new TGLayoutHints(kLHintsLeft|kLHintsExpandX,5,5,5,5));
932 // /* ip scale */
933 // histo_opts = new TGGroupFrame(histo_group, "Fits", kHorizontalFrame);
934 // lab = new TGLabel(histo_opts,"Gumbel : ");
935 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,5,2));
936 // G_fit1 = new TGTextButton(histo_opts, " 1 ");
937 // G_fit1->SetTextJustify(36);
938 // G_fit1->SetMargins(0,0,0,0);
939 // G_fit1->SetWrapLength(-1);
940 // G_fit1->Resize();
941 // G_fit1->SetEnabled(kFALSE);
942 // G_fit1->ChangeBackground(gura);
943 // G_fit1->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum1()");
944 // histo_opts->AddFrame(G_fit1, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
945 // G_fit2 = new TGTextButton(histo_opts, " 2 ");
946 // G_fit2->SetTextJustify(36);
947 // G_fit2->SetMargins(0,0,0,0);
948 // G_fit2->SetWrapLength(-1);
949 // G_fit2->Resize();
950 // G_fit2->SetEnabled(kFALSE);
951 // G_fit2->ChangeBackground(gurb);
952 // G_fit2->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum2()");
953 // histo_opts->AddFrame(G_fit2, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
954 // G_fit3 = new TGTextButton(histo_opts, " 3 ");
955 // G_fit3->SetTextJustify(36);
956 // G_fit3->SetMargins(0,0,0,0);
957 // G_fit3->SetWrapLength(-1);
958 // G_fit3->Resize();
959 // G_fit3->SetEnabled(kFALSE);
960 // G_fit3->ChangeBackground(gurc);
961 // G_fit3->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum3()");
962 // histo_opts->AddFrame(G_fit3, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
963 // lab = new TGLabel(histo_opts,"Gaus+Gum : ");
964 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,10,2,5,2));
965 // G_fitGG1 = new TGTextButton(histo_opts, " 1 ");
966 // G_fitGG1->SetTextJustify(36);
967 // G_fitGG1->SetMargins(0,0,0,0);
968 // G_fitGG1->SetWrapLength(-1);
969 // G_fitGG1->Resize();
970 // G_fitGG1->SetEnabled(kFALSE);
971 // G_fitGG1->ChangeBackground(gura);
972 // G_fitGG1->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum1()");
973 // histo_opts->AddFrame(G_fitGG1, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
974 // G_fitGG2 = new TGTextButton(histo_opts, " 2 ");
975 // G_fitGG2->SetTextJustify(36);
976 // G_fitGG2->SetMargins(0,0,0,0);
977 // G_fitGG2->SetWrapLength(-1);
978 // G_fitGG2->Resize();
979 // G_fitGG2->SetEnabled(kFALSE);
980 // G_fitGG2->ChangeBackground(gurb);
981 // G_fitGG2->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum2()");
982 // histo_opts->AddFrame(G_fitGG2, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
983 // G_fitGG3 = new TGTextButton(histo_opts, " 3 ");
984 // G_fitGG3->SetTextJustify(36);
985 // G_fitGG3->SetMargins(0,0,0,0);
986 // G_fitGG3->SetWrapLength(-1);
987 // G_fitGG3->Resize();
988 // G_fitGG3->SetEnabled(kFALSE);
989 // G_fitGG3->ChangeBackground(gurc);
990 // G_fitGG3->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum3()");
991 // histo_opts->AddFrame(G_fitGG3, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
992 // histo_group->AddFrame(histo_opts, new TGLayoutHints(kLHintsLeft|kLHintsExpandX,5,5,5,5));
993 
994  /* histo list */
995  //G_histolist = new KVListView(TNamed::Class(), histo_group, hWidth, hHeight);
996  //G_histolist->SetDataColumns(1);
997  //G_histolist->SetDataColumn(0, "Data", "GetTitle", kTextLeft);
998  G_histolist = new KVListView(KVHistogram::Class(), histo_group, hWidth, hHeight);
1000  G_histolist->SetDataColumn(0, "Name", "", kTextLeft);
1001  G_histolist->SetDataColumn(1, "VarX", "", kTextCenterX);
1002  G_histolist->SetDataColumn(2, "VarY", "", kTextCenterX);
1003  G_histolist->SetDataColumn(3, "VarZ", "", kTextCenterX);
1004  G_histolist->SetDataColumn(4, "Selection", "", kTextCenterX);
1005  G_histolist->SetDataColumn(5, "Weight", "", kTextCenterX);
1006  G_histolist->SetDataColumn(6, "MeanX (RMS)", "GetMeanRMSX", kTextCenterX);
1007  G_histolist->SetDataColumn(7, "MeanY (RMS)", "GetMeanRMSY", kTextCenterX);
1010  G_histolist->SetUseObjLabelAsRealClass();//to have icons & context menus of TH* & TCutG classes, not KVHistogram
1011  G_histolist->SetDoubleClickAction("KVTreeAnalyzer", this, "DrawHisto(TObject*)");
1012  G_histolist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "HistoSelectionChanged()");
1015  5, 5, 5, 5));
1016 
1019  /* histo options */
1020  histo_opts = new TGGroupFrame(fMain_histolist, "OPTIONS", kHorizontalFrame);
1021 
1022  //fHorizontalFrame = new TGHorizontalFrame(histo_opts,150,36,kHorizontalFrame);
1023  G_histo_del = new TGPictureButton(histo_opts, "sm_delete.xpm");
1025  G_histo_del->Connect("Clicked()", "KVTreeAnalyzer", this, "DeleteSelectedHisto()");
1026  //fHorizontalFrame->AddFrame(G_histo_del, new TGLayoutHints(kLHintsTop|kLHintsLeft,2,2,2,2));
1027  //lab = new TGLabel(fHorizontalFrame, "DELETE");
1028  //lab->Resize();
1029  //fHorizontalFrame->AddFrame(lab, new TGLayoutHints(kLHintsTop|kLHintsLeft|kLHintsCenterY,2,2,2,2));
1030  histo_opts->AddFrame(G_histo_del, new TGLayoutHints(kLHintsLeft, 5, 2, 8, 2));
1031 
1032  G_histo_add = new TGPictureButton(histo_opts, "bld_plus.png");
1034  G_histo_add->Connect("Clicked()", "KVTreeAnalyzer", this, "AddSelectedHistos()");
1036  histo_opts->AddFrame(G_histo_add, new TGLayoutHints(kLHintsLeft, 15, 25, 8, 2));
1037 
1038  G_histo_draw_option = new TGComboBox(histo_opts);
1039  TString draw_options[] = {
1040  "",
1041  "COL",
1042  "COLZ",
1043  "BOX",
1044  "CONT",
1045  "SURF",
1046  "LEGO",
1047  "ARR",
1048  "TEXT",
1049  "CONT1",
1050  "CONT2",
1051  "CONT3",
1052  "CONT4",
1053  "SURF1",
1054  "SURF2",
1055  "SURF3",
1056  "SURF4",
1057  "LEGO1",
1058  "LEGO2",
1059  "LEGO3",
1060  "LEGO4",
1061  "BOX1",
1062  " "
1063  };
1064  int dop = 0;
1065  while (draw_options[dop] != " ") {
1066  G_histo_draw_option->AddEntry(draw_options[dop], dop);
1067  ++dop;
1068  }
1069  G_histo_draw_option->Resize(100, 20);
1070  histo_opts->AddFrame(G_histo_draw_option, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1071  G_histo_draw_option->Connect("Selected(const char*)", "KVTreeAnalyzer", this, "SetDrawOption(Option_t*)");
1072 
1073  G_histo_new_can = new TGCheckButton(histo_opts, "New canvas");
1074  G_histo_new_can->SetToolTipText("Draw in a new canvas");
1075  G_histo_new_can->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNewCanvas(Bool_t)");
1077  histo_opts->AddFrame(G_histo_new_can, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1078  G_histo_same = new TGCheckButton(histo_opts, "Same");
1079  G_histo_same->SetToolTipText("Draw in same pad");
1080  G_histo_same->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetDrawSame(Bool_t)");
1081  histo_opts->AddFrame(G_histo_same, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1082  G_histo_app_sel = new TGCheckButton(histo_opts, "Apply selection");
1083  G_histo_app_sel->SetToolTipText("Apply current selection to generate new histo");
1084  G_histo_app_sel->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetApplySelection(Bool_t)");
1085  histo_opts->AddFrame(G_histo_app_sel, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1086  G_histo_log = new TGCheckButton(histo_opts, "Log scale");
1087  G_histo_log->SetToolTipText("Use log scale in Y (1D) or Z (2D)");
1089  G_histo_log->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetDrawLog(Bool_t)");
1090  histo_opts->AddFrame(G_histo_log, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1091  G_histo_stats = new TGCheckButton(histo_opts, "Stats");
1092  G_histo_stats->SetToolTipText("Display histogram statistics box");
1094  G_histo_stats->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetStatsHisto(Bool_t)");
1095  histo_opts->AddFrame(G_histo_stats, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1096  G_histo_autosave = new TGCheckButton(histo_opts, "AutoSave");
1097  G_histo_autosave->SetToolTipText("Automatically generate histo image files");
1099  G_histo_autosave->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetAutoSaveHisto(Bool_t)");
1100  histo_opts->AddFrame(G_histo_autosave, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1101  fMain_histolist->AddFrame(histo_opts, new TGLayoutHints(kLHintsCenterX, 5, 5, 5, 5));
1102 
1104 
1107 
1108  hHeight = hHeight + lHeight + 50;
1109 
1110  fMain_histolist->Resize(hWidth, hHeight);
1111  /********* end of HISTOGRAMS *************/
1112 
1113  fMain_histolist->Connect("CloseWindow()", "KVTreeAnalyzer", this, "GUIClosed()");
1114 }
1115 
1116 
1117 
1120 
1122 {
1123  // Called when graphical window is closed
1124 
1127  TTimer::SingleShot(150, "KVTreeAnalyzer", this, "DeleteThis()");
1128 }
1129 
1130 
1131 
1135 
1137 {
1138  // Adds histogram to internal list of user histograms
1139  // and updates GUI display
1140 
1141  SetAnalysisModifiedSinceLastSave(kTRUE);//new histogram needs saving
1142  fHistolist.Add(new KVHistogram(h));
1144 }
1145 
1146 
1147 
1151 
1153 {
1154  // Adds selection to internal list of user histograms
1155  // and updates GUI display
1156 
1157  SetAnalysisModifiedSinceLastSave(kTRUE);//new selection needs saving
1158  fSelections.Add(e);
1160 }
1161 
1162 
1163 
1167 
1169 {
1170  // Adds histogram to internal list of user histograms
1171  // and updates GUI display
1172 
1173  SetAnalysisModifiedSinceLastSave(kTRUE);//new selection needs saving
1174  fHistolist.Add(new KVHistogram(c));
1176 }
1177 
1178 
1179 
1186 
1188 {
1189  // the Tree file name is used as the basis for the default analysis backup filename.
1190  // for a TChain there may be many files with a common root.
1191  // we look for this common root and replace any "wildcard" characters with "X"
1192  // i.e. for files "run_001.root", "run_002.root", ..., "run_999.root" we
1193  // will use "Analysis_run_XXX.root" as default name
1194 
1195  KVString p;
1196  if (t->InheritsFrom("TChain")) {
1197  KVString p;
1198  p.FindCommonTitleCharacters(((TChain*)t)->GetListOfFiles(), 'X');
1199  fTreeFileName = p.Data();
1200  }
1201  else
1205 }
1206 
1207 
1208 
1211 
1213 {
1214  // Connects a TChain for analysis
1215 
1216  fTree = t;
1218  if (IsPROOFEnabled()) fChain->SetProof();
1219  fTreeName = t->GetName();
1220  SetTreeFileName(t);
1222 }
1223 
1224 
1225 
1228 
1230 {
1231  // Backwards compatibility: to read old analysis files
1232 
1233  TFile* f;
1235  // absolute path to TTree file doesn't work, try in working directory
1236  TString tmp;
1238  f = TFile::Open(tmp);
1239  }
1241  // if fRelativePathToAnalysisFile!="." and if fTreeFileName is not an absolute path,
1242  // we guess the Tree file is in the same directory as the analysis file
1243  TString tmp;
1245  f = TFile::Open(tmp);
1246  }
1247  else
1249  if (!f || f->IsZombie()) {
1250  Error("ReconnectTree", "Failed to reconnect Tree file %s", fTreeFileName.Data());
1251  fTree = 0;
1253  fChain = 0;
1254  SafeDelete(f);
1255  return;
1256  }
1257  fTreeFileName = f->GetName();
1258  TTree* t = (TTree*)f->Get(fTreeName);
1259  TString treeTitle = t->GetTitle();
1260  delete f;
1261  fChain = new TChain(fTreeName, treeTitle);
1263  fChain->SetDirectory(0);
1264  SetTree(fChain);
1265 }
1266 
1267 
1268 
1276 
1278 {
1279  // STATIC method to open a previously saved analysis session.
1280  //
1281  // Use:
1282  // root[0] KVTreeAnalyzer* TA = KVTreeAnalyzer::OpenFile("my_analysis.root")
1283  //
1284  // If option nogui=kTRUE the GUI will not be launched
1285 
1287  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1288  delete f;
1289  anal->fNoGui = nogui;
1291  anal->OpenGUI();
1292  return anal;
1293 }
1294 
1295 
1296 
1299 
1301 {
1302  // open a previously saved analysis session.
1303 
1305  ReadFromFile(f);
1306 }
1307 
1308 
1309 
1312 
1314 {
1315  // open a previously saved analysis session.
1316 
1317  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1318  delete f;
1319  anal->Copy(*this);
1320  delete anal;
1321  gTreeAnalyzer = this;
1324  FillLeafList();
1325 }
1326 
1327 
1328 
1330 
1332 {
1333  TString name = Form("%s:%s", cut->GetVarY(), cut->GetVarX());
1334  KVList padList(kFALSE);
1335  Bool_t testHisto = kFALSE;
1336 
1337  if (!gPad) testHisto = kTRUE;
1338 
1339  if (!testHisto) {
1340  testHisto = kTRUE;
1341  padList.AddAll(((TPad*)gPad)->GetListOfPrimitives());
1342  TIter next(&padList);
1343  TObject* o = 0;
1344  while ((o = next())) {
1345  if (o->InheritsFrom("TH1")) {
1346  TH1* hh = (TH1*) o;
1347  TString hName = hh->GetTitle();
1348  if (hName.Contains(name.Data())) {
1349  cut->Draw("PL");
1350  gPad->Update();
1351  testHisto = kFALSE;
1352  }
1353  }
1354  }
1355  }
1356 
1357  if (testHisto) {
1358  TIter next(&fHistolist);
1359  KVHistogram* hhh;
1360  TH1* hh = 0;
1361  while ((hhh = (KVHistogram*)next())) {
1362  if ((hh = hhh->GetHisto())) {
1363  TString hName = hh->GetTitle();
1364  if (hName.Contains(name.Data())) {
1365  DrawHisto(hh, kFALSE);
1366  cut->Draw("PL");
1367  gPad->Update();
1368  break;
1369  }
1370  }
1371  }
1372  }
1373  // else cut->Draw("PAL");
1374 
1375 
1376 // TIter next(fHistoList);
1377 // TH1* tmpHist = 0;
1378 // while((tmpHisto = (TH1*)next()))
1379 // {
1380 //
1381 // }
1382 
1383  return;
1384 }
1385 
1386 
1387 
1389 
1390 void KVTreeAnalyzer::DrawHistogram(TH1* histo, Bool_t same, Bool_t logscale)
1391 {
1392  if (fDrawSame || same) {
1393  // if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1394  // plot with a different colour and add it to the automatically generated
1395  // legend which is also displayed in the plot
1396  histo->SetLineColor(my_color_array[++fSameColorIndex]);
1397  histo->SetLineWidth(2);
1398  if (fSameColorIndex == MAX_COLOR_INDEX) fSameColorIndex = -1;
1399  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1400  if (histo->InheritsFrom("TH2")) {
1401  TString hopt = histo->GetOption();
1402  if (hopt != "") hopt.Form("%s,same", histo->GetOption());
1403  else hopt = "same";
1404  histo->Draw(hopt);
1405  }
1406  else
1407  histo->Draw("same");
1408  TObject* legend = gPad->GetListOfPrimitives()->FindObject("TPave");
1409  if (legend) {
1410  gPad->GetListOfPrimitives()->Remove(legend);
1411  delete legend;
1412  }
1413  ((TPad*) gPad)->BuildLegend();
1414  if (histo->InheritsFrom("TH2")) {
1415  gPad->SetLogy(kFALSE);
1416  gPad->SetLogz(fDrawLog || logscale);
1417  }
1418  else {
1419  gPad->SetLogy(fDrawLog || logscale);
1420  // adjust y-scale to new histogram if needed
1421  // find first histogram
1422  TIter nxt(gPad->GetListOfPrimitives());
1423  TObject* h;
1424  while ((h = nxt())) {
1425  if (h->InheritsFrom("TH1")) {
1426  TH1* hh = (TH1*)h;
1427  if (histo->GetMaximum() > hh->GetMaximum()) hh->SetMaximum(histo->GetMaximum() + 1);
1428  break;
1429  }
1430  }
1431  }
1432  gPad->Modified();
1433  gPad->Update();
1434  if (fAutoSaveHisto) AutoSaveHisto(histo);
1435  }
1436  else {
1437  // if 'new canvas' is active the histogram is displayed in a new KVCanvas
1438  // create a new canvas also if none exists
1439  if (fNewCanvas || !gPad) {
1440  KVCanvas* c = new KVCanvas;
1441  c->SetTitle(histo->GetTitle());
1442  c->SetWindowSize(700, 700);
1443  }
1444  else if (gPad) { // update title of existing canvas
1445  gPad->GetCanvas()->SetTitle(histo->GetTitle());
1446  }
1447  histo->SetLineColor(my_color_array[0]);
1448  histo->SetLineWidth(2);
1449  if (histo->InheritsFrom("TH2")) {
1450  gPad->SetLogy(kFALSE);
1451  gPad->SetLogz(fDrawLog || logscale);
1452  }
1453  else {
1454  histo->SetMaximum(-1111);//in case maximum was changed to accomodate superimposition
1455  gPad->SetLogy(fDrawLog || logscale);
1456  }
1457  histo->SetStats(fStatsHisto);//show/hide stat box according to check-box
1458  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1459  histo->Draw();
1460  gPad->Modified();
1461  gPad->Update();
1462  if (fAutoSaveHisto) AutoSaveHisto(histo);
1463  }
1464 }
1465 
1466 
1467 
1488 
1490 {
1491  // Method called when a user double-clicks a histogram in the GUI list.
1492  //
1493  // * if histogram is already displayed in active pad and if the pad also
1494  // contains a graphical contour (TCutG) object, we use the contour to define
1495  // a new data selection (TEntryList) which is added to the internal list.
1496  //
1497  // * if 'reapply selection' is activated and if the current active selection
1498  // is not the same as that used to generate the histogram, we generate a new
1499  // histogram displaying the same variables but with the current selection.
1500  //
1501  // * if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1502  // plot with a different colour and add it to the automatically generated
1503  // legend which is also displayed in the plot
1504  //
1505  // * if 'new canvas' is active the histogram is displayed in a new KVCanvas
1506  //
1507  // * in all cases when a histogram is displayed the log/linear scale of
1508  // Y (1-D) or Z (2-D) axis is automatically adjusted according to the 'log scale'
1509  // check box
1510 
1511  KVHistogram* kvhisto = 0;
1512  TCutG* cut = 0;
1513  TH1* histo = 0;
1514  if (obj->InheritsFrom("KVHistogram")) {
1515  kvhisto = dynamic_cast<KVHistogram*>(obj);
1516  if (kvhisto->IsType("Cut")) cut = kvhisto->GetCut();
1517  else if (kvhisto->IsType("Histo")) histo = kvhisto->GetHisto();
1518  }
1519  else if (obj->InheritsFrom("TCutG")) {
1520  cut = dynamic_cast<TCutG*>(obj);
1521  }
1522  else if (obj->InheritsFrom("TH1")) {
1523  histo = dynamic_cast<TH1*>(obj);
1524  }
1525 
1526  if (cut) {
1527  DrawCut(cut);
1528  return;
1529  }
1530  if (!histo) return;
1531 
1532  // if histogram is already displayed in active pad and if the pad also
1533  // contains a graphical contour (TCutG) object, we use the contour to define
1534  // a new data selection (TEntryList) which is added to the internal list.
1535  if (gPad && gPad->GetListOfPrimitives()->FindObject(histo) && (gen)) {
1536  TIter next(gPad->GetListOfPrimitives());
1537  TObject* o;
1538  while ((o = next())) {
1539  if ((o->IsA() == TCutG::Class()) && !(fHistolist.FindObjectWithNameAndType(o->GetName(), "Cut"))) {
1540  MakeSelection(o->GetName());
1541  return;
1542  }
1543  }
1544  }
1545 
1546  KVString exp, sel, weight;
1547  if (kvhisto) {
1548  exp = kvhisto->GetExpression();
1549  sel = kvhisto->GetSelection();
1550  weight = kvhisto->GetWeight();
1551  }
1552  else {
1553  KVHistogram::ParseHistoTitle(histo->GetTitle(), exp, sel, weight);
1554  }
1555 
1556  if (weight == "1") weight = "";
1557 
1558  // if 'reapply selection' is activated and if the current active selection
1559  // is not the same as that used to generate the histogram, we generate a new
1560  // histogram displaying the same variables but with the current selection.
1562  histo = RemakeHisto(histo, exp, weight);
1563  if (!histo) return;
1564  }
1565 
1566  DrawHistogram(histo);
1567 }
1568 
1569 
1570 
1574 
1576 {
1577  // Returns kTRUE if "sel" corresponds to current active selection
1578  // (i.e. entry list of TTree)
1579 
1580  if (!fTree) return kTRUE;
1581  TString test_sel(sel);
1582  TString tree_sel;
1583  TEntryList* el;
1584  if ((el = fChain->GetEntryList())) tree_sel = el->GetTitle();
1585  return (test_sel == tree_sel);
1586 }
1587 
1588 
1589 
1594 
1595 TH1* KVTreeAnalyzer::RemakeHisto(TH1* h, const Char_t* expr, const Char_t* weight)
1596 {
1597  // Remake an existing histogram of data 'expr' using the current active selection
1598  // If such a histogram already exists, we just return its address.
1599  // We must have the same binning in the new as in the original histogram.
1600 
1601  TString htit;
1602  GenerateHistoTitle(htit, expr, "", weight);
1603  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
1604  TH1* histo = 0;
1605  if (kvhisto) histo = kvhisto->GetHisto();
1606  if (histo && (histo->IsA() == h->IsA())) return histo;
1607  Int_t nx, ny = 0;
1608  TString hname(h->GetName());
1609  if (hname.BeginsWith("I")) {
1610  Int_t xmin = h->GetXaxis()->GetXmin() + 0.5;
1611  Int_t xmax = h->GetXaxis()->GetXmax() - 0.5;
1612  //cout << "Remake histo with xmin = " << xmin << " xmax = " << xmax << endl;
1613  h = MakeIntHisto(expr, "", xmin, xmax, weight);
1614  return h;
1615  }
1616  nx = h->GetNbinsX();
1617  auto xmin = h->GetXaxis()->GetXmin();
1618  auto xmax = h->GetXaxis()->GetXmin();
1619  double ymin(-1), ymax(-1);
1620  if (h->InheritsFrom("TH2")) {
1621  ny = h->GetNbinsY();
1622  ymin = h->GetYaxis()->GetXmin();
1623  ymax = h->GetYaxis()->GetXmin();
1624  }
1625  //cout << "Remake histo with nx = " << nx << " ny = " << ny << endl;
1626  if (h->InheritsFrom("TProfile")) {
1627  // make a new profile histogram
1628  Bool_t oldProfileState = fProfileHisto;
1629  fProfileHisto = kTRUE;
1630  h = MakeHisto(expr, "", nx, ny, weight, xmin, xmax);
1631  fProfileHisto = oldProfileState;
1632  }
1633  else
1634  h = MakeHisto(expr, "", nx, ny, weight, xmin, xmax, ymin, ymax);
1635  return h;
1636 }
1637 
1638 
1639 
1644 
1646 {
1647  // Method called when user hits 'return' in selection GUI text-box
1648  // Takes expression from text-box and generates the corresponding
1649  // selection which is added to the GUI list of selections.
1650 
1651  TString selection = G_selection_text->GetText();
1652  if (selection.IsNull()) return;
1653  if (MakeSelection(selection)) G_selection_text->Clear();
1654 }
1655 
1656 
1657 
1661 
1663 {
1664  // Method called when user hits 'return' in TTree leaf/alias GUI text-box
1665  // Generates a new alias using the expression in the text-box.
1666 
1667  TString alias = G_alias_text->GetText();
1668  TString name;
1669  name.Form("a%d", fAliasNumber++);
1670  SetAlias(name, alias);
1671  FillLeafList();
1672  G_alias_text->Clear();
1673 }
1674 
1675 
1676 
1681 
1683 {
1684  // Method called when user hits 'combine selections' button in selections GUI.
1685  // Generates new selection which is the intersection (logical AND) of
1686  // the currently selected selections.
1687 
1688  if (fSelectedSelections) {
1689  TEntryList* save_elist = fChain->GetEntryList();
1691  TString newselect;
1692  int nsel = fSelectedSelections->GetEntries();
1693  for (int i = 1; i < nsel; i++) {
1694  TString tmp;
1696  tmp.Form("(%s)", el->GetTitle());
1697  if (i > 1) newselect += " && ";
1698  newselect += tmp.Data();
1699  }
1700  MakeSelection(newselect);
1701  SetEntryList(save_elist);
1702  }
1703 }
1704 
1705 
1706 
1711 
1713 {
1714  // Method called when user hits 'combine selections' button in selections GUI.
1715  // Generates new selection which is the intersection (logical AND) of
1716  // the currently selected selections.
1717 
1718  if (fSelectedSelections) {
1719  TEntryList* save_elist = fChain->GetEntryList();
1720  SetEntryList(nullptr);
1721  TString newselect;
1722  int nsel = fSelectedSelections->GetEntries();
1723  for (int i = 0; i < nsel; i++) {
1724  TString tmp;
1726  tmp.Form("(%s)", el->GetTitle());
1727  if (i > 0) newselect += " || ";
1728  newselect += tmp.Data();
1729  }
1730  MakeSelection(newselect);
1731  SetEntryList(save_elist);
1732  }
1733 }
1734 
1735 
1736 
1739 
1741 {
1742  // Delete the currently selected selection(s)
1743 
1744  if (fSelectedSelections) {
1745  int nsel = fSelectedSelections->GetEntries();
1746  if (nsel < 1) return;
1747  for (int i = 0; i < nsel; i++) {
1749  if (!el) continue;
1750  fSelections.Remove(el);
1751  // if current selection, disable
1752  if (fChain->GetEntryList() == el) fChain->SetEntryList(nullptr);
1753  delete el;
1755  }
1757  }
1759 
1760 }
1761 
1762 
1763 
1766 
1768 {
1769  // Method called whenever the selected selection in the GUI list changes
1770 
1773  Bool_t resetSel = kTRUE;
1777 
1779  }
1780  else if (fSelectedSelections->GetEntries() == 1) {
1783  if (tmp->GetSize() != 0 || !strcmp("", G_selection_text->GetText())) {
1784  G_selection_text->SetText(((TNamed*)fSelectedSelections->At(0))->GetTitle());
1785  resetSel = kFALSE;
1786  }
1787  delete tmp;
1788  }
1789  else if (fSelectedSelections->GetEntries() > 1) {
1793  }
1794 
1795  if (resetSel) {
1797  if (tmp->GetSize() != 0) G_selection_text->SetText("");
1798  delete tmp;
1799  }
1800 }
1801 
1802 
1803 
1807 
1809 {
1810  // Method called whenever the leaf/alias selection in the TTree GUI list changes.
1811  // Updates the names of the leaves/aliases displayed next to the 'draw' button.
1812 
1814  fLeafExpr = "-";
1815  fXLeaf = fYLeaf = 0;
1816 // Bool_t resetSel = kTRUE;
1818  Int_t nleaf = fSelectedLeaves->GetEntries();
1819  if (nleaf) {
1820  if (nleaf == 1) {
1822  fLeafExpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1824 
1825  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1826  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1827  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0 || !strcmp("", G_alias_text->GetText())) {
1828  G_alias_text->SetText(fLeafExpr.Data()); //resetSel = kFALSE;
1829  }
1830  else if (strcmp(fLeafExpr.Data(), G_leaf_expr->GetTitle())) {
1831  TString tmps = G_alias_text->GetText();
1832  Int_t pos = G_alias_text->MaxMark();
1833  if (pos >= tmps.Sizeof()) pos = G_alias_text->MinMark();
1834  if (pos >= tmps.Sizeof()) pos = tmps.Sizeof() - 1;
1835  tmps.Insert(pos, fLeafExpr.Data());
1836  G_alias_text->SetText(tmps.Data());
1838  }
1839  delete tmp;
1840  delete tmp1;
1841 
1842  }
1843  else if (nleaf == 2) {
1844  fXLeaf = (TNamed*)fSelectedLeaves->At(1);
1846  TString X, Y;
1847  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1848  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1849  fLeafExpr.Form("%s:%s", Y.Data(), X.Data());
1851  G_alias_text->SetText("");
1852  }
1853  else if (nleaf == 3) {
1854  fXLeaf = (TNamed*)fSelectedLeaves->At(2);
1855  fYLeaf = (TNamed*)fSelectedLeaves->At(1);
1856  fZLeaf = (TNamed*)fSelectedLeaves->At(0);
1857  TString X, Y, Z;
1858  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1859  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1860  Z = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
1861  fLeafExpr.Form("%s:%s:%s", Z.Data(), Y.Data(), X.Data());
1863  G_alias_text->SetText("");
1864  }
1865  else {
1866  fLeafExpr = "-";
1867  G_alias_text->SetText("");
1868  }
1869  }
1870  else {
1871  fLeafExpr = "-";
1872 // G_alias_text->SetText("");
1873  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1874  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1875  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0) {
1876  G_alias_text->SetText(""); //resetSel = kFALSE;
1877  }
1878  delete tmp;
1879  delete tmp1;
1880  }
1881 
1883  G_leaf_expr->Resize();
1884 }
1885 
1886 
1887 
1889 
1891 {
1892  KVNameValueList p{{"Xbins", fNx}, {"Xmin", fXmin}, {"Xmax", fXmax},
1893  {"Ybins", fNy}, {"Ymin", fYmin}, {"Ymax", fYmax}};
1894  bool cancel{false};
1895  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1896  g->DisplayDialog();
1897  if (cancel) return false;
1898  fNx = p.GetIntValue("Xbins");
1899  fXmin = p.GetDoubleValue("Xmin");
1900  fXmax = p.GetDoubleValue("Xmax");
1901  fNy = p.GetIntValue("Ybins");
1902  fYmin = p.GetDoubleValue("Ymin");
1903  fYmax = p.GetDoubleValue("Ymax");
1904  return true;
1905 }
1906 
1907 
1908 
1910 
1912 {
1913  KVNameValueList p{{"bins", fNxF}, {"min", fXminF}, {"max", fXmaxF}};
1914  bool cancel{false};
1915  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1916  g->DisplayDialog();
1917  if (cancel) return false;
1918  fNxF = p.GetIntValue("bins");
1919  fXminF = p.GetDoubleValue("min");
1920  fXmaxF = p.GetDoubleValue("max");
1921  return true;
1922 }
1923 
1924 
1925 
1927 
1929 {
1930  KVNameValueList p{{"Xbins", fNxD}, {"Ybins", fNyD}, {"ordered?", fOrderedDalitz}};
1931  bool cancel{false};
1932  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1933  g->DisplayDialog();
1934  if (cancel) return false;
1935  fNxD = p.GetIntValue("Xbins");
1936  fNyD = p.GetIntValue("Ybins");
1937  fOrderedDalitz = p.GetBoolValue("ordered?");
1938  return true;
1939 }
1940 
1941 
1942 
1948 
1950 {
1951  // \returns maximum value of given TTree variable, taking into account any current selection (TEntryList).
1952  // @param leafname name of TTree variable
1953  //
1954  // \note TTree::GetMaximum() is supposed to do exactly the same, but strangely ignores the selection.
1955 
1956  fTree->GetMaximum(leafname);// this just to use internal TTree cache mechanism
1957 
1958  auto leaf = fTree->GetLeaf(leafname);
1959  if (!leaf) return 0;
1960 
1961  auto branch = leaf->GetBranch();
1962  Double_t cmax = -DBL_MAX;
1963  for (Long64_t i = 0; i < fTree->GetEntries(); ++i) {
1964  auto entryNumber = fTree->GetEntryNumber(i);
1965  if (entryNumber < 0) break;
1966  branch->GetEntry(entryNumber);
1967  for (Int_t j = 0; j < leaf->GetLen(); ++j) {
1968  Double_t val = leaf->GetValue(j);
1969  if (val > cmax) {
1970  cmax = val;
1971  }
1972  }
1973  }
1974  return cmax;
1975 }
1976 
1977 
1978 
1984 
1986 {
1987  // \returns minimum value of given TTree variable, taking into account any current selection (TEntryList).
1988  // @param leafname name of TTree variable
1989  //
1990  // \note TTree::GetMinimum() is supposed to do exactly the same, but strangely ignores the selection.
1991 
1992  fTree->GetMinimum(leafname);// this just to use internal TTree cache mechanism
1993 
1994  auto leaf = fTree->GetLeaf(leafname);
1995  if (!leaf) return 0;
1996 
1997  auto branch = leaf->GetBranch();
1998  Double_t cmin = DBL_MAX;
1999  for (Long64_t i = 0; i < fTree->GetEntries(); ++i) {
2000  auto entryNumber = fTree->GetEntryNumber(i);
2001  if (entryNumber < 0) break;
2002  branch->GetEntry(entryNumber);
2003  for (Int_t j = 0; j < leaf->GetLen(); ++j) {
2004  Double_t val = leaf->GetValue(j);
2005  if (val < cmin) {
2006  cmin = val;
2007  }
2008  }
2009  }
2010  return cmin;
2011 }
2012 
2013 
2014 
2016 
2018 {
2020  return lf->GetTypeName();
2021 }
2022 
2023 
2024 
2028 
2030 {
2031  // Method called when user hits 'draw' button in TTree GUI.
2032  // If only one leaf/alias is selected, this actually calls DrawLeaf.
2033 
2034  if (fLeafExpr == "-")return;
2035  Bool_t threeDexp = fSelectedLeaves->GetEntries() == 3;
2036  if (threeDexp && !fProfileHisto) {
2037  DrawAsDalitz();
2038  return;
2039  }
2040  if (fSelectedLeaves->GetEntries() == 1) {
2042  return;
2043  }
2044 
2045  if (fUserWeight) {
2046  if (!DefineWeight()) return;
2047  }
2048 
2049  int nx = 500, ny = 500;
2050  double xmin, xmax, ymin, ymax;
2051  xmin = xmax = ymin = ymax = 0;
2052  TString Xexpr, Yexpr, Zexpr;
2053  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2054  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2055  if (threeDexp) Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2056  if (fXLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fXLeaf), "Char_t")) {
2057  TString tmp = Xexpr;
2058  Xexpr.Form("int(%s)", tmp.Data());
2059  }
2060  if (fYLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fYLeaf), "Char_t")) {
2061  TString tmp = Yexpr;
2062  Yexpr.Form("int(%s)", tmp.Data());
2063  }
2064 
2065  if (threeDexp) fLeafExpr.Form("%s:%s:%s", Zexpr.Data(), Yexpr.Data(), Xexpr.Data());
2066  else fLeafExpr.Form("%s:%s", Yexpr.Data(), Xexpr.Data());
2067  TString name;
2068  name.Form("h%d", fHistoNumber);
2069  TString drawexp(fLeafExpr), histo, histotitle;
2070  if (fUserWeight) GenerateHistoTitle(histotitle, fLeafExpr, "", fWeight);
2071  else GenerateHistoTitle(histotitle, fLeafExpr, "");
2072 
2073  // Check histo doesn't already exist
2074  // Look for list of histograms with given title as we don't distinguish TH2 from TProfile
2075  unique_ptr<KVSeqCollection> same_histo(fHistolist.GetSubListWithMethod(histotitle, "GetHistoTitle"));
2076  TIter nxtSame(same_histo.get());
2077  KVHistogram* kvhisto;
2078  while ((kvhisto = (KVHistogram*)nxtSame())) {
2079  if ((fProfileHisto && kvhisto->IsProfile()) || (!fProfileHisto && kvhisto->IsTH2())) {
2080  DrawHisto(kvhisto->GetHisto());
2081  return;
2082  }
2083  }
2084 
2085  if (fUserBinning) {
2086  if (!DefineUserBinning()) return;
2087  }
2088 
2089  xmin = GetTreeMinimum(Xexpr);
2090  xmax = GetTreeMaximum(Xexpr);
2091  if (fXLeaf->InheritsFrom("TLeaf") &&
2092  (!strcmp(get_leaf_type_name(fXLeaf), "Int_t") || !strcmp(get_leaf_type_name(fXLeaf), "Short_t") || !strcmp(get_leaf_type_name(fXLeaf), "Char_t"))
2093  ) {
2094  xmin -= 0.5;
2095  xmax += 0.5;
2096  nx = xmax - xmin;
2097  }
2098  ymin = GetTreeMinimum(Yexpr);
2099  ymax = GetTreeMaximum(Yexpr);
2100  if (fYLeaf->InheritsFrom("TLeaf") &&
2101  (!strcmp(get_leaf_type_name(fYLeaf), "Int_t") || !strcmp(get_leaf_type_name(fYLeaf), "Short_t") || !strcmp(get_leaf_type_name(fYLeaf), "Char_t"))
2102  ) {
2103  ymin -= 0.5;
2104  ymax += 0.5;
2105  ny = ymax - ymin;
2106  }
2107  if (fUserBinning) {
2108  nx = fNx;
2109  ny = fNy;
2110  xmin = fXmin;
2111  xmax = fXmax;
2112  ymin = fYmin;
2113  ymax = fYmax;
2114  }
2115 
2116  if (!fProfileHisto) histo.Form(">>%s(%d,%f,%f,%d,%f,%f)", name.Data(), nx, xmin, xmax, ny, ymin, ymax);
2117  else {
2118  if (fUserBinning) histo.Form(">>%s(%d,%f,%f)", name.Data(), nx, xmin, xmax);
2119  else histo.Form(">>%s", name.Data());
2120  }
2121  drawexp += histo;
2122  TString ww = "";
2123  if (fUserWeight) ww += fWeight;
2124  Long64_t drawResult;
2125  if (!fProfileHisto) drawResult = fTree->Draw(drawexp, ww.Data(), "goff");
2126  else drawResult = fTree->Draw(drawexp, ww.Data(), "prof,goff");
2127  if (drawResult < 0) {
2128  // Error: problem with Draw, probably bad expression
2129  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
2130  return;
2131  }
2132  TH1* h(nullptr);
2133 #ifdef WITH_PROOF
2134  if (IsPROOFEnabled())
2136  else
2137 #endif
2138  h = (TH1*)gDirectory->Get(name);
2139  h->SetTitle(histotitle);
2140  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
2141  h->SetDirectory(0);
2142  if (h->InheritsFrom("TH1")) {
2143  h->GetXaxis()->SetTitle(fXLeaf->GetTitle());
2144  h->SetLineWidth(2);
2145  }
2146  if (h->InheritsFrom("TH2") || h->InheritsFrom("TProfile")) h->GetYaxis()->SetTitle(fYLeaf->GetTitle());
2147 
2148  AddHisto(h);
2149  fHistoNumber++;
2150  DrawHisto(h);
2151 }
2152 
2153 
2154 
2155 
2157 
2159 {
2160  if ((!fXLeaf->InheritsFrom("TLeaf")) || (!fYLeaf->InheritsFrom("TLeaf")) || (!fZLeaf->InheritsFrom("TLeaf"))) {
2161  Warning("DrawAsDalitz", "Cannot be used with aliases !");
2162  return;
2163  }
2164 
2165  TString Xexpr, Yexpr, Zexpr;
2166  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2167  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2168  Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2169  fLeafExpr.Form("%s:%s:%s", Xexpr.Data(), Yexpr.Data(), Zexpr.Data());
2170 
2174 
2175  if ((!xType.Contains(yType.Data())) || (!yType.Contains(zType.Data()))) {
2176  Warning("DrawAsDalitz", "Leaves %s must have the same type !", fLeafExpr.Data());
2177  return;
2178  }
2179 
2180  Double_t x, y, z;
2181  Double_t var1, var2, var3;
2182  Float_t varf1, varf2, varf3;
2183  Int_t vari1, vari2, vari3;
2184  Short_t vars1, vars2, vars3;
2185  Char_t varc1, varc2, varc3;
2186  x = y = z = 0.;
2187 
2188  if (xType.Contains("Int_t")) {
2189  fTree->SetBranchAddress(Xexpr.Data(), &vari1);
2190  fTree->SetBranchAddress(Yexpr.Data(), &vari2);
2191  fTree->SetBranchAddress(Zexpr.Data(), &vari3);
2192  }
2193  else if (xType.Contains("Short_t")) {
2194  fTree->SetBranchAddress(Xexpr.Data(), &vars1);
2195  fTree->SetBranchAddress(Yexpr.Data(), &vars2);
2196  fTree->SetBranchAddress(Zexpr.Data(), &vars3);
2197  }
2198  else if (xType.Contains("Char_t")) {
2199  fTree->SetBranchAddress(Xexpr.Data(), &varc1);
2200  fTree->SetBranchAddress(Yexpr.Data(), &varc2);
2201  fTree->SetBranchAddress(Zexpr.Data(), &varc3);
2202  }
2203  else if (xType.Contains("Double_t")) {
2204  fTree->SetBranchAddress(Xexpr.Data(), &var1);
2205  fTree->SetBranchAddress(Yexpr.Data(), &var2);
2206  fTree->SetBranchAddress(Zexpr.Data(), &var3);
2207  }
2208  else if (xType.Contains("Float_t")) {
2209  fTree->SetBranchAddress(Xexpr.Data(), &varf1);
2210  fTree->SetBranchAddress(Yexpr.Data(), &varf2);
2211  fTree->SetBranchAddress(Zexpr.Data(), &varf3);
2212  }
2213 
2214  if (fUserBinning) {
2215  if (!DefineUserBinningD()) return;
2216  }
2217 
2218  TString histotitle;
2219  GenerateHistoTitle(histotitle, fLeafExpr, "");
2220 
2221  KVDalitzPlot* h = 0;
2222  if (fUserBinning) h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data(), fOrderedDalitz, fNxD, 0., 1.2, fNyD, 0., 1.2);
2223  else h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data());
2224  fHistoNumber++;
2225 
2226  TEntryList* el = fChain->GetEntryList();
2227  if (el) el->GetEntry(0);
2229 
2230  if (el) nentries = el->GetN();
2231  for (int i = 0; i < nentries; i++) {
2232  Int_t j = i;
2233  if (el) j = el->Next();
2234  fTree->GetEntry(j);
2235  if (xType.Contains("Int_t")) {
2236  x = vari1;
2237  y = vari2;
2238  z = vari3;
2239  }
2240  else if (xType.Contains("Short_t")) {
2241  x = vars1;
2242  y = vars2;
2243  z = vars3;
2244  }
2245  else if (xType.Contains("Char_t")) {
2246  x = varc1;
2247  y = varc2;
2248  z = varc3;
2249  }
2250  else if (xType.Contains("Double_t")) {
2251  x = var1;
2252  y = var2;
2253  z = var3;
2254  }
2255  else if (xType.Contains("Float_t")) {
2256  x = varf1;
2257  y = varf2;
2258  z = varf3;
2259  }
2260  h->FillAsDalitz(x, y, z);
2261  }
2262 
2263  h->SetOption("col");
2264  h->SetDirectory(0);
2265  AddHisto((TH2F*)h);
2266  DrawHisto(h);
2268 
2269 }
2270 
2271 
2272 
2277 
2279 {
2280  // Open dialogue box for user to fill required weight for histo
2281  //
2282  // returns false if Cancel button is pressed
2283 
2284  KVNameValueList params{{"Weight", ""}};
2285  Bool_t cancel_pressed{false};
2286  auto s = new KVNameValueListGUI(GetMainWindow(), &params, &cancel_pressed);
2287  s->DisplayDialog();
2288  // cancel was pressed ?
2289  if (cancel_pressed) return false;
2290  fWeight = params.GetStringValue("Weight");
2291  return true;
2292 }
2293 
2294 
2295 
2298 
2300 {
2301  // Method called when user double-clicks a leaf/alias in list
2302 
2303  if (fUserWeight) {
2304  if (!DefineWeight()) return;
2305  }
2306 
2307  TH1* histo = nullptr;
2308  if (obj->InheritsFrom("TLeaf")) {
2309  TLeaf* leaf = (TLeaf*)fChain->GetListOfLeaves()->FindObject(obj->GetName());//dynamic_cast<TLeaf*>(obj);
2310  TString expr = leaf->GetName();
2311  TString type = leaf->GetTypeName();
2312  // check histo not already in list
2313  TString htit;
2314  if (fUserWeight) GenerateHistoTitle(htit, expr, "", fWeight);
2315  else GenerateHistoTitle(htit, expr, "");
2316  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2317  if (kvhisto) histo = kvhisto->GetHisto();
2318  if (!histo) {
2319  if (type.Contains("Int_t") || type.Contains("Char_t") || type.Contains("Short_t") || type == "Long_t" || type == "Long64_t") {
2320  Int_t xmin = GetTreeMinimum(expr);
2321  Int_t xmax = GetTreeMaximum(expr);
2322  if (type.Contains("Char_t")) {
2323  TString tmp;
2324  tmp.Form("int(%s)", expr.Data());
2325  expr = tmp.Data();
2326  }
2327  histo = MakeIntHisto(expr, "", xmin, xmax, (fUserWeight ? fWeight.Data() : ""));
2328  if (!histo) return;
2329  histo->GetXaxis()->SetTitle(leaf->GetName());
2330  }
2331  else {
2332  histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2333  if (!histo) return;
2334  histo->GetXaxis()->SetTitle(leaf->GetName());
2335  }
2336  if (!histo) return;
2337  }
2338  DrawHisto(histo);
2339  }
2340  else {
2341  TString expr = obj->GetTitle();
2342  // check histo not already in list
2343  TString htit;
2344  GenerateHistoTitle(htit, expr, "", (fUserWeight ? fWeight.Data() : ""));
2345  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2346  if (kvhisto) histo = kvhisto->GetHisto();
2347  if (!histo) histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2348  if (!histo) return;
2349  histo->GetXaxis()->SetTitle(obj->GetTitle());
2350  DrawHisto(histo);
2351  }
2352 }
2353 
2354 
2355 
2358 
2360 {
2361  // Method called when user histo selection changes in GUI histogram list
2362 
2367  if (fSelectedHistos) {
2368  if (fSelectedHistos->GetEntries() > 0) {
2370  if (fSelectedHistos->GetEntries() == 1 && fSelectedHistos->First()->IsA() == TH1F::Class()) {
2371  }
2373  }
2374  }
2375 }
2376 
2377 
2378 
2380 
2382 {
2384 }
2385 
2386 
2387 
2390 
2392 {
2393  // Look for selection in list of selections
2394  return (TEntryList*)fSelections.FindObjectByTitle(selection);
2395 }
2396 
2397 
2399 
2401 {
2402  fPROOFEnabled = yes;
2403  if (yes) {
2404 #ifdef WITH_PROOF
2405  // open new PROOF-lite session
2406  if (!gProof) TProof::Open("");
2407  if (fChain) fChain->SetProof(kTRUE);
2408 #endif
2409  }
2410  else {
2411  if (fChain) fChain->SetProof(kFALSE);
2412  }
2413 }
2414 
2415 
2416 
2418 
2420 {
2421  Info("Save", "Saving analysis %s in file %s", GetTitle(), fSaveAnalysisFileName.Data());
2424 }
2425 
2426 
2427 
2434 
2435 void KVTreeAnalyzer::SaveAs(const char* filename, Option_t*) const
2436 {
2437  // Override TObject::SaveAs
2438  // We need to:
2439  // - (re)create the file
2440  // - do fChain->SetDirectory before writing to disk
2441 
2442  // save current directory
2443  TDirectory* sav = gDirectory;
2444  TDirectory* chsav = (fChain ? fChain->GetDirectory() : nullptr);
2445 
2446  TFile* f = TFile::Open(filename, "recreate");
2447  Write();
2448  if (fChain) { // make sure TChain doesn't get redirected
2449  fChain->SetDirectory(chsav);
2450  }
2451  delete f;
2452 
2453  // back to original directory
2454  sav->cd();
2455 }
2456 
2457 
2458 // void KVTreeAnalyzer::FitGum1()
2459 // {
2460 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2461 // if(!histo) return;
2462 // GDfirst->SetParameters(histo->GetMean(),histo->GetRMS());
2463 // histo->Fit(GDfirst,"EM");
2464 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2465 // if(!stats){
2466 // histo->SetStats(1);
2467 // histo->Draw();
2468 // gPad->Update();
2469 // stats = (TPaveStats*)histo->FindObject("stats");
2470 // }
2471 // if(stats){
2472 // // if canvas's 'no stats' option has been set by user,
2473 // // there will still be no valid stats object,
2474 // // so this test is to avoid the ensuing seg fault
2475 // stats->SetFitFormat("10.9g");
2476 // stats->SetOptFit(111);
2477 // }
2478 // histo->SetOption("e1");
2479 // histo->SetMarkerStyle(24);
2480 // histo->SetMarkerColor(kBlue+2);
2481 // gPad->Modified();gPad->Update();
2482 // SetAnalysisModifiedSinceLastSave(kTRUE);
2483 // }
2484 // void KVTreeAnalyzer::FitGum2()
2485 // {
2486 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2487 // if(!histo) return;
2488 // GDsecond->SetParameters(histo->GetMean(),histo->GetRMS());
2489 // histo->Fit(GDsecond,"EM");
2490 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2491 // if(!stats){
2492 // histo->SetStats(1);
2493 // histo->Draw();
2494 // gPad->Update();
2495 // stats = (TPaveStats*)histo->FindObject("stats");
2496 // }
2497 // if(stats){
2498 // // if canvas's 'no stats' option has been set by user,
2499 // // there will still be no valid stats object,
2500 // // so this test is to avoid the ensuing seg fault
2501 // stats->SetFitFormat("10.9g");
2502 // stats->SetOptFit(111);
2503 // }
2504 // histo->SetOption("e1");
2505 // histo->SetMarkerStyle(24);
2506 // histo->SetMarkerColor(kBlue+2);
2507 // gPad->Modified();gPad->Update();
2508 // SetAnalysisModifiedSinceLastSave(kTRUE);
2509 // }
2510 // void KVTreeAnalyzer::FitGum3()
2511 // {
2512 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2513 // if(!histo) return;
2514 // GDthird->SetParameters(histo->GetMean(),histo->GetRMS());
2515 // histo->Fit(GDthird,"EM");
2516 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2517 // if(!stats){
2518 // histo->SetStats(1);
2519 // histo->Draw();
2520 // gPad->Update();
2521 // stats = (TPaveStats*)histo->FindObject("stats");
2522 // }
2523 // if(stats){
2524 // // if canvas's 'no stats' option has been set by user,
2525 // // there will still be no valid stats object,
2526 // // so this test is to avoid the ensuing seg fault
2527 // stats->SetFitFormat("10.9g");
2528 // stats->SetOptFit(111);
2529 // }
2530 // histo->SetOption("e1");
2531 // histo->SetMarkerStyle(24);
2532 // histo->SetMarkerColor(kBlue+2);
2533 // gPad->Modified();gPad->Update();
2534 // SetAnalysisModifiedSinceLastSave(kTRUE);
2535 // }
2536 // void KVTreeAnalyzer::FitGausGum1()
2537 // {
2538 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2539 // if(!histo) return;
2540 // GausGum1->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2541 // histo->Fit(GausGum1,"EM");
2542 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2543 // if(!stats){
2544 // histo->SetStats(1);
2545 // histo->Draw();
2546 // gPad->Update();
2547 // stats = (TPaveStats*)histo->FindObject("stats");
2548 // }
2549 // if(stats){
2550 // // if canvas's 'no stats' option has been set by user,
2551 // // there will still be no valid stats object,
2552 // // so this test is to avoid the ensuing seg fault
2553 // stats->SetFitFormat("10.9g");
2554 // stats->SetOptFit(111);
2555 // }
2556 // histo->SetOption("e1");
2557 // histo->SetMarkerStyle(24);
2558 // histo->SetMarkerColor(kBlue+2);
2559 // gPad->Modified();gPad->Update();
2560 // SetAnalysisModifiedSinceLastSave(kTRUE);
2561 // }
2562 //
2563 // void KVTreeAnalyzer::FitGausGum2()
2564 // {
2565 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2566 // if(!histo) return;
2567 // GausGum2->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2568 // histo->Fit(GausGum2,"EM");
2569 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2570 // if(!stats){
2571 // histo->SetStats(1);
2572 // histo->Draw();
2573 // gPad->Update();
2574 // stats = (TPaveStats*)histo->FindObject("stats");
2575 // }
2576 // if(stats){
2577 // // if canvas's 'no stats' option has been set by user,
2578 // // there will still be no valid stats object,
2579 // // so this test is to avoid the ensuing seg fault
2580 // stats->SetFitFormat("10.9g");
2581 // stats->SetOptFit(111);
2582 // }
2583 // histo->SetOption("e1");
2584 // histo->SetMarkerStyle(24);
2585 // histo->SetMarkerColor(kBlue+2);
2586 // gPad->Modified();gPad->Update();
2587 // SetAnalysisModifiedSinceLastSave(kTRUE);
2588 // }
2589 //
2590 // void KVTreeAnalyzer::FitGausGum3()
2591 // {
2592 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2593 // if(!histo) return;
2594 // GausGum3->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2595 // histo->Fit(GausGum3,"EM");
2596 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2597 // if(!stats){
2598 // histo->SetStats(1);
2599 // histo->Draw();
2600 // gPad->Update();
2601 // stats = (TPaveStats*)histo->FindObject("stats");
2602 // }
2603 // if(stats){
2604 // // if canvas's 'no stats' option has been set by user,
2605 // // there will still be no valid stats object,
2606 // // so this test is to avoid the ensuing seg fault
2607 // stats->SetFitFormat("10.9g");
2608 // stats->SetOptFit(111);
2609 // }
2610 // histo->SetOption("e1");
2611 // histo->SetMarkerStyle(24);
2612 // histo->SetMarkerColor(kBlue+2);
2613 // gPad->Modified();gPad->Update();
2614 // SetAnalysisModifiedSinceLastSave(kTRUE);
2615 // }
2616 
2617 
2622 
2624 {
2625  // fill and return TList with histos containing the given data
2626  // which may be 1D ("mult", "zmax", etc.) or 2D ("zmax:mult")
2627  // DELETE LIST AFTER USE
2628  TList* hlist = new TList;
2629  TIter next(&fHistolist);
2630 
2631  KVHistogram* h;
2632  while ((h = (KVHistogram*)next())) {
2633 
2634  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr)) hlist->Add(h->GetHisto());
2635  }
2636  return hlist;
2637 }
2638 
2639 
2640 
2644 
2646 {
2647  // fill and return TList with histos using the given selection criteria
2648  // DELETE LIST AFTER USE
2649  TList* hlist = new TList;
2650  TIter next(&fHistolist);
2651 
2652  KVHistogram* h;
2653  while ((h = (KVHistogram*)next())) {
2654 
2655  if (h->IsType("Histo") && !strcmp(h->GetSelection(), expr)) hlist->Add(h->GetHisto());
2656  }
2657  return hlist;
2658 }
2659 
2660 
2661 
2663 
2664 TH1* KVTreeAnalyzer::GetHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2665 {
2666  TIter next(&fHistolist);
2667 
2668  KVHistogram* h;
2669  while ((h = (KVHistogram*)next())) {
2670 
2671  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection)) {
2672  if (strcmp(weight, "")) {
2673  if (!strcmp(h->GetWeight(), weight)) return h->GetHisto();
2674  }
2675  else return h->GetHisto();
2676  }
2677  }
2678  return 0;
2679 }
2680 
2681 
2682 
2684 
2686 {
2687  return (KVHistogram*)fHistolist.FindObjectWithMethod(title, "GetHistoTitle");
2688 }
2689 
2690 
2691 
2693 
2694 void KVTreeAnalyzer::DeleteHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2695 {
2696  TIter next(&fHistolist);
2697 
2698  KVHistogram* h;
2699  while ((h = (KVHistogram*)next())) {
2700 
2701  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection) && !strcmp(h->GetWeight(), weight)) {
2702  fHistolist.Remove(h);
2703  delete h;
2705  }
2706  }
2708 }
2709 
2710 
2711 
2714 
2716 {
2717  // Delete all currently selected histograms
2718  if (fSelectedHistos) {
2719  Int_t nsel = fSelectedHistos->GetEntries();
2720  if (nsel < 1) return;
2721  for (int i = 0; i < nsel; i++) {
2722  TObject* obj = fSelectedHistos->At(i);
2723  fHistolist.Remove(obj);
2724  delete obj;
2726  }
2728  }
2730 }
2731 
2732 
2733 
2738 
2740 {
2741  // Called when G_histo_add button is pressed
2742  // There should be 2 histograms in fSelectedHistos
2743  // We assume that both are of same type and have same binning etc.
2744 
2745  if (fSelectedHistos->GetEntries() != 2) return;
2746  HistoToAdd1 = dynamic_cast<KVHistogram*>(fSelectedHistos->At(0))->GetHisto();
2747  HistoToAdd2 = dynamic_cast<KVHistogram*>(fSelectedHistos->At(1))->GetHisto();
2748  if (HistoToAdd1 && HistoToAdd2) {
2749  Info("AddSelectedHistos", "Adding %s and %s", HistoToAdd1->GetName(), HistoToAdd2->GetName());
2750  TString name = Form("h%d", fHistoNumber);
2751  TString oldname = HistoToAdd1->GetName();
2752  if (oldname.BeginsWith("I")) name.Prepend("I");
2755  Bool_t ok = KVBase::OpenContextMenu("HistoAddition", this);
2756  if (!ok) {
2757  Info("AddSelectedHistos", "Call to context menu not OK");
2758  delete HistoAddResult;
2759  return;
2760  }
2761  if (MethodNotCalled()) {
2762  Info("AddSelectedHistos", "You pressed cancel");
2763  delete HistoAddResult;
2764  return;
2765  }
2766  ++fHistoNumber;
2768  }
2769  else {
2770  Info("AddSelectedHistos", "Only possible for 2 histograms");
2771  }
2772 }
2773 
2774 
2775 
2777 
2779 {
2780  fMethodCalled = kTRUE;
2782 // TODO: it would be nice to distinguish histograms which are the result of
2783 // adding other histograms together. For the moment they appear identical to
2784 // to the first histogram in terms of variables etc. The following attempt
2785 // doesn't work (can't parse the title correctly)
2786 // TString title;
2787 // title.Form("SUMHIST:{%s,%s}",HistoToAdd1->GetTitle(),HistoToAdd2->GetTitle());
2788 // HistoAddResult->SetTitle(title);
2789 }
2790 
2791 
2792 
2793 
2796 
2798 {
2799  // regenerate entry lists for all selections
2800  TList old_lists;
2801  old_lists.AddAll(&fSelections);
2802  fSelections.Clear();
2804  TIter next(&old_lists);
2805  TEntryList* old_el;
2806  SetEntryList(nullptr);
2807  SelectionChanged();
2808  while ((old_el = (TEntryList*)next())) {
2809  cout << "REGENERATING SELECTION : " << old_el->GetTitle() << endl;
2810  MakeSelection(old_el->GetTitle());
2811  ((TEntryList*)fSelections.Last())->SetReapplyCut(old_el->GetReapplyCut());
2813  }
2814  old_lists.Delete();
2815 }
2816 
2817 
2818 
2820 
2822 {
2823  switch (id) {
2824  case MH_OPEN_CHAIN:
2825  OpenChain();
2826  break;
2827  case MH_OPEN_FILE:
2829  break;
2830  case MH_ADD_FRIEND:
2832  break;
2833  case MH_APPLY_ANALYSIS:
2835  break;
2836  case MH_SAVE_FILE:
2838  break;
2839  case MH_SAVE:
2840  Save();
2841  break;
2842  case MH_CLOSE:
2843  delete fMain_histolist;
2844  GUIClosed();
2845  break;
2846  case MH_QUIT:
2847  // check all analyzers need saving
2848  while (fgAnalyzerList->GetEntries() > 1) {
2849  TIter next(fgAnalyzerList);
2851  do {
2852  tan = (KVTreeAnalyzer*)next();
2853  }
2854  while (tan == this);
2855  tan->AnalysisSaveCheck();
2856  delete tan;
2857  }
2859  gROOT->ProcessLine(".q");
2860  break;
2861 
2862  default:
2863  break;
2864  }
2865 }
2866 
2867 
2869 
2871 {
2872  switch (id) {
2873  case SEL_COMB_AND:
2875  break;
2876 
2877  case SEL_COMB_OR:
2879  break;
2880 
2881  case SEL_DELETE:
2882  DeleteSelections();
2883  break;
2884 
2885  case SEL_UPDATE:
2886  UpdateEntryLists();
2887  break;
2888 
2889  case SEL_GEN_CONST_XSEC:
2890  KVBase::OpenContextMenu("GenerateConstantXSecSelections", this);
2891  break;
2892 
2893  default:
2894  break;
2895  }
2896 }
2897 
2898 
2899 
2901 
2903 {
2904  switch (opt) {
2905  case OPT_PROOF:
2908  EnablePROOF(false);
2909  }
2910  else {
2912  EnablePROOF();
2913  }
2914  }
2915 }
2916 
2917 
2918 
2921 
2923 {
2924  // Open a previous analysis session
2925 
2926  static TString dir(".");
2927  const char* filetypes[] = {
2928  "Analysis files", "Analysis*.root",
2929  0, 0
2930  };
2931  TGFileInfo fi;
2932  fi.fFileTypes = filetypes;
2933  fi.fIniDir = StrDup(dir);
2934  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2935  if (fi.fFilename) {
2936  KVTreeAnalyzer* newAnal = this;
2937  if (fTree) newAnal = new KVTreeAnalyzer(kFALSE);
2938  newAnal->OpenAnyFile(fi.fFilename);
2939  }
2940  dir = fi.fIniDir;
2941 }
2942 
2943 
2944 
2946 
2948 {
2949  static TString dir(".");
2950  const char* filetypes[] = {
2951  "ROOT files", "*.root",
2952  0, 0
2953  };
2954  TGFileInfo fi;
2955  fi.fFileTypes = filetypes;
2956  fi.fIniDir = StrDup(dir);
2957  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2958  if (fi.fFilename) {
2960  }
2961  dir = fi.fIniDir;
2962 }
2963 
2964 
2967 
2969 {
2970  // Open a file or files containing TTrees to analyse
2971 
2972  static TString dir(".");
2973  const char* filetypes[] = {
2974  "ROOT files", "*.root*",
2975  0, 0
2976  };
2977  TGFileInfo fi;
2978  fi.fFileTypes = filetypes;
2979  fi.fIniDir = StrDup(dir);
2981  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2982  if (fi.fFileNamesList && fi.fFileNamesList->GetEntries()) {
2983 
2984  // look in first file to find first TTree and use its name/title
2985  TString theTreeName, theTreeTitle;
2987  KVUnownedList keys;
2988  keys.AddAll(file->GetListOfKeys());
2989  // Get list of trees in file
2990  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
2991  if (trees->GetEntries()) {
2992  theTreeName = trees->First()->GetName();
2993  theTreeTitle = trees->First()->GetTitle();
2994  }
2995  if (theTreeName != "") {
2996  // if analysis already en cours, open new GUI
2997  KVTreeAnalyzer* newAnal = this;
2999  newAnal->OpenChain(theTreeName, theTreeTitle, fi.fFileNamesList);
3000  if (fi.fFileNamesList->GetEntries() == 1) {
3001  // if a single file is selected, look to see if any histograms are in it
3002  newAnal->GetHistosFromFile(file, keys);
3003  }
3004  }
3005  else { // no TTree in file - look for histograms
3006  if (fi.fFileNamesList->GetEntries() == 1) {
3007  // if analysis already en cours, open new GUI
3008  KVTreeAnalyzer* newAnal = this;
3010  // if a single file is selected, look to see if any histograms are in it
3011  newAnal->GetHistosFromFile(file, keys);
3012  if(newAnal->got_histos_or_tree_from_file) newAnal->SetWindowTitle(file->GetName());
3013  }
3014  }
3015  }
3016  dir = fi.fIniDir;
3017 }
3018 
3019 
3020 
3022 
3024 {
3025  static TString dir(".");
3026  const char* filetypes[] = {
3027  "ROOT files", "*.root",
3028  0, 0
3029  };
3030  TGFileInfo fi;
3031  fi.fFileTypes = filetypes;
3032  fi.fIniDir = StrDup(dir);
3033  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3034  if (fi.fFilename) {
3036  }
3037  dir = fi.fIniDir;
3038 }
3039 
3040 
3041 
3043 
3045 {
3046  const char* filetypes[] = {
3047  "Analysis files", "Analysis*.root",
3048  0, 0
3049  };
3050  TGFileInfo fi;
3051  fi.fFileTypes = filetypes;
3054  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDSave, &fi);
3055  if (fi.fFilename) {
3056  //if no ".xxx" ending given, we add ".root"
3057  TString filenam(fi.fFilename);
3058  if (!filenam.Contains('.'))
3059  filenam += ".root";
3060  // update name of file to autosave analysis in
3061  fSaveAnalysisFileName = filenam;
3062  Save();
3063  }
3065 }
3066 
3067 
3068 
3070 
3072 {
3073  TIter next(&keys);
3074  TKey* akey;
3075  while ((akey = (TKey*)next())) {
3076  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3077  if (!fHistolist.FindObject(akey->GetName())) {
3078  TH1* h = (TH1*)file->Get(akey->GetName());
3079  h->SetDirectory(0);
3080  fHistolist.Add(new KVHistogram(h));
3082  }
3083  }
3084  }
3086 }
3087 
3088 
3089 
3092 
3093 void KVTreeAnalyzer::OpenSingleFile(TFile* file)
3094 {
3095  // Open TTree in file (as a TChain) and import any histograms found in file
3096 
3097  fHistolist.Clear();
3098  KVUnownedList keys;
3099  keys.AddAll(file->GetListOfKeys());
3100  // Get list of trees in file
3101  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3102  if (trees->GetEntries()) {
3103  // Get name of first tree
3104  TString aTreeName = trees->First()->GetName();
3105  TString aFileName = file->GetName();
3106  TList fileList;
3107  TNamed ff(aFileName.Data(), "File Name");
3108  fileList.Add(&ff);
3109  OpenChain(aTreeName, trees->First()->GetTitle(), &fileList);
3110  }
3111  else
3112  SetWindowTitle(file->GetName()); // set GUI window name to file name if no TTree found
3113  GetHistosFromFile(file, keys);
3114 }
3115 
3116 
3117 
3121 
3123 {
3124  // assuming filepath is the URL of a ROOT file containing a previously-saved analysis, open it and
3125  // open the KVTreeAnalyzer object stored in it
3126 
3128 
3129  TFile* file = TFile::Open(filepath);
3130  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3131  if (kvta) {
3132  ReadFromFile(file);
3133  }
3134  else {
3135  OpenSingleFile(file);
3136  }
3138 }
3139 
3140 
3141 
3146 
3147 void KVTreeAnalyzer::OpenChain(const TString& treename, const TString& treetitle, const TSeqCollection* files)
3148 {
3149  // Open a TChain for analysis
3150  // treename/title is the name/title of the TTree :)
3151  // files is a list of objects with the names of the files in the chain
3152 
3153  fChain = new TChain(treename, treetitle);
3154  TIter nxt(files);
3155  TObject* o;
3156  while ((o = nxt())) fChain->Add(o->GetName());
3157  fChain->SetDirectory(0);
3158  SetTree(fChain);
3159  fHistolist.Clear();
3160  fSelections.Clear();
3161  fAliasList.Clear();
3162  fHistoNumber = 1;
3163  fSelectionNumber = 1;
3164  fAliasNumber = 1;
3165  fSameColorIndex = 0;
3166  fSelectedSelections = 0;
3167  fSelectedLeaves = 0;
3168  fSelectedHistos = 0;
3172  FillLeafList();
3174 }
3175 
3176 
3177 
3180 
3182 {
3183  // Generate all user aliases in list which are not already defined
3184 
3185  if (list->GetEntries()) {
3186  TIter next(list);
3187  TObject* o;
3188  while ((o = next())) {
3189  if (!GetAlias(o->GetTitle())) {
3190  Info("GenerateAllAliases", "Adding alias %s to leaflist", o->GetTitle());
3192  GenerateAlias();
3193  }
3194  }
3195  }
3196 }
3197 
3198 
3199 
3208 
3210 {
3211  // assuming filepath is the URL of a ROOT file, open it and,
3212  // if no KVTreeAnalyzer object is found, open first TTree in file
3213  // and apply all selections and generate all histograms which
3214  // were made for this analysis.
3215  // Any histograms in the file are added to the list of histograms.
3216  // If filepath contains an existing analysis, we add to it any
3217  // histograms/selections/aliases which are not defined
3218 
3219  TFile* file = TFile::Open(filepath);
3220  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3221  if (kvta) {
3222  // open existing analysis, add any missing histos/selections/aliases
3223  delete file;
3224  KVTreeAnalyzer* applyAnal = OpenFile(filepath);
3225  applyAnal->GenerateAllSelections(&fSelections);
3226  applyAnal->GenerateAllHistograms(&fHistolist);
3227  applyAnal->GenerateAllAliases(&fAliasList);
3228  return;
3229  }
3230  else {
3231  delete file;
3232  KVTreeAnalyzer* applyAnal = new KVTreeAnalyzer(kFALSE);
3233  applyAnal->OpenAnyFile(filepath);
3234  applyAnal->GenerateAllSelections(&fSelections);
3235  applyAnal->GenerateAllHistograms(&fHistolist);
3236  // make sure no selection is left active without being displayed
3237  applyAnal->SetEntryList(nullptr);
3238  applyAnal->G_selection_status->SetText("CURRENT SELECTION:", 0);
3239  applyAnal->GenerateAllAliases(&fAliasList);
3240  }
3241 }
3242 
3243 
3244 
3246 
3247 void KVTreeAnalyzer::SetAlias(const Char_t* name, const Char_t* expr)
3248 {
3249  TString exp = expr;
3250  exp.ReplaceAll("d2r", "TMath::DegToRad()");
3251  exp.ReplaceAll("r2d", "TMath::RadToDeg()");
3252  fAliasList.Add(new TNamed(name, exp.Data()));
3254 }
3255 
3256 
3257 
3259 
3260 static const char* gSaveAsTypes[] = { "PostScript", "*.ps",
3261  "Encapsulated PostScript", "*.eps",
3262  "PDF", "*.pdf",
3263  "SVG", "*.svg",
3264  "TeX", "*.tex",
3265  "GIF", "*.gif",
3266  "ROOT files", "*.root",
3267  "XML", "*.xml",
3268  "PNG", "*.png",
3269  "XPM", "*.xpm",
3270  "JPEG", "*.jpg",
3271  "TIFF", "*.tiff",
3272  "XCF", "*.xcf",
3273  0, 0
3274  };
3275 
3276 
3277 
3282 
3284 {
3285  // Open file dialog box for user to choose directory and
3286  // image file-type for generating picture files of all
3287  // histos as they are drawn
3288 
3289  Info("SetUpHistoAutoSave", "Select image filetype and directory");
3290  TString workdir = gSystem->WorkingDirectory();
3291  static TString dir(".");
3292  static Int_t typeidx = 0;
3293  static Bool_t overwr = kFALSE;
3294  TGFileInfo fi;
3295  fi.fFileTypes = gSaveAsTypes;
3296  fi.fIniDir = StrDup(dir);
3297  fi.fFileTypeIdx = typeidx;
3298  fi.fOverwrite = overwr;
3299  new KVFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kKVFDDirectory, &fi);
3300  gSystem->ChangeDirectory(workdir.Data());
3301  TString ft = fi.fFileTypes[fi.fFileTypeIdx + 1];
3302  dir = fi.fIniDir;
3303  typeidx = fi.fFileTypeIdx;
3304  overwr = fi.fOverwrite;
3305  fAutoSaveDir = dir.Data();
3306  fAutoSaveType = ft(1, ft.Length()).Data();
3307  Info("SetUpHistoAutoSave", "file-type:%s directory:%s", fAutoSaveType.Data(), fAutoSaveDir.Data());
3308 }
3309 
3310 
3311 
3315 
3317 {
3318  // Save currently displayed histo as an image file
3319  // If 'same' checkbox is ticked, we use the same filename as used for the first histogram
3320 
3321  static TString lastFilename = "";
3322 
3323  if (fDrawSame) {
3324  gPad->SaveAs(lastFilename);
3325  return;
3326  }
3327  TString title = h->GetTitle();
3328  title.ReplaceAll(" ", "_");
3329  title.ReplaceAll("/", "#");
3330  title.ReplaceAll("*", "x");
3331  title.ReplaceAll("$", "#");
3332  title.ReplaceAll("(", "[");
3333  title.ReplaceAll(")", "]");
3334  title.Append(fAutoSaveType);
3335  title.Prepend("/");
3336  title.Prepend(fAutoSaveDir);
3337  Info("AutoSaveHisto", "Saved as: %s", title.Data());
3338  gPad->SaveAs(title);
3339  lastFilename = title;
3340 }
3341 
3342 
3343 
3347 
3349 {
3350  // We take the title of every object in 'list' and generate the corresponding selection
3351  // if it does not already exist
3352 
3353  TIter nextSel(list);
3354  TObject* sel;
3355  while ((sel = nextSel())) {
3356  if (!GetSelection(sel->GetTitle())) {
3357  Info("GenerateAllSelections", "Generating selection: %s", sel->GetTitle());
3358  MakeSelection(sel->GetTitle());
3359  }
3360  }
3361 }
3362 
3363 
3364 
3368 
3370 {
3371  // For every histogram in the list, we generate histograms with the same binning for
3372  // the same expression, selection and weight if they don't already exist
3373 
3374  TIter nextHist(list);
3375  KVHistogram* obj;
3376  TH1* hist;
3377  while ((obj = (KVHistogram*)nextHist())) {
3378  if (!obj->IsType("Cut")) {
3379  hist = obj->GetHisto();
3380  if (GetHistoByTitle(hist->GetTitle())) continue;
3381  TString exp = obj->GetExpression();
3382  TString sel = obj->GetSelection();
3383  TString weight = obj->GetWeight();
3384  if (weight == "1") weight = "";
3385  // set selection
3386  Info("GenerateAllHistograms", "Generating histogram: %s", hist->GetTitle());
3387  SetSelection(sel);
3388  RemakeHisto(hist, exp, weight);
3389  }
3390  }
3391 }
3392 
3393 
3394 
3401 
3403 {
3404  // Read serialized object from file
3405  // For versions < 4, fHistolist contained TH* or TCutG objects:
3406  // we convert to a list of KVHistogram objects.
3407  // Flag will be set to say analysis needs saving.
3408  // Reparse all histogram expressions and selections in case they were not saved correctly.
3409 
3410  UInt_t R__s, R__c;
3411  if (R__b.IsReading()) {
3412  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3413  R__b.ReadClassBuffer(KVTreeAnalyzer::Class(), this, R__v, R__s, R__c);
3414  if (R__v < 5) {
3415  // no fChain pointer member before v5
3416  ReconnectTree();
3417  }
3418  if (fChain && fTree != fChain) SetTree(fChain);
3419  if (fChain) {
3421  Info("Streamer", "Checking friends");
3422  // check friends are TChains, not TTrees & they have valid pointers
3423  TFriendElement* fe;
3424  TIter nxt(fChain->GetListOfFriends());
3425  KVNumberList toRemove;
3426  KVNameValueList infos;
3427  int idx = 0;
3428  while ((fe = (TFriendElement*)nxt())) {
3429  if (!fe->GetTree() || (fe->GetTree() && !fe->GetTree()->InheritsFrom("TChain"))) {
3430  Info("Streamer", "Found friend to convert to TChain");
3431  toRemove.Add(idx);
3432  infos.SetValue(Form("treeName%d", idx), fe->GetTreeName());
3433  if (!fe->GetFile()) {
3434  Info("Streamer", "Choose file containg friend tree %s", fe->GetTreeName());
3435  static TString dir(".");
3436  const char* filetypes[] = {
3437  "ROOT files", "*.root",
3438  0, 0
3439  };
3440  TGFileInfo fi;
3441  fi.fFileTypes = filetypes;
3442  fi.fIniDir = StrDup(dir);
3443  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3444  if (fi.fFilename) {
3445  infos.SetValue(Form("fileName%d", idx), fi.fFilename);
3446  }
3447  dir = fi.fIniDir;
3448  }
3449  else
3450  infos.SetValue(Form("fileName%d", idx), fe->GetFile()->GetName());
3451  }
3452  ++idx;
3453  }
3454  if (toRemove.GetEntries()) {
3455  Info("Streamer", "Removing TTree friends");
3456  toRemove.Begin();
3457  while (!toRemove.End()) {
3458  fChain->RemoveFriend(fChain->GetFriend(infos.GetStringValue(Form("treeName%d", toRemove.Next()))));
3459  }
3460  toRemove.Begin();
3461  Info("Streamer", "Adding friends as TChains");
3462  while (!toRemove.End()) {
3463  idx = toRemove.Next();
3464  TChain* friendChain = new TChain(infos.GetStringValue(Form("treeName%d", idx)));
3465  friendChain->Add(infos.GetStringValue(Form("fileName%d", idx)));
3466  fChain->AddFriend(friendChain);
3467  }
3468  }
3469  }
3470  }
3471  if (R__v < 4) {
3472  //Info("Streamer","Converting old histo list");
3473  // convert fHistolist
3474  if (fHistolist.GetEntries()) {
3475  TList tmp;
3476  tmp.AddAll(&fHistolist);
3477  //Info("Streamer","List of histos to import:");
3478  //tmp.ls();
3479  fHistolist.SetOwner(kFALSE);
3480  fHistolist.Clear();
3481  fHistolist.SetOwner(kTRUE);
3482  TNamed* obj;
3483  TIter next(&tmp);
3484  while ((obj = (TNamed*)next())) {
3485  if (obj->InheritsFrom("TCutG"))
3486  fHistolist.Add(new KVHistogram(dynamic_cast<TCutG*>(obj)));
3487  else if (obj->InheritsFrom("TH1"))
3488  fHistolist.Add(new KVHistogram(dynamic_cast<TH1*>(obj)));
3489  }
3490  //Info("Streamer","New histolist:");
3491  fHistolist.ls();
3493  }
3494  }
3495  if (fHistolist.GetEntries()) {
3496  TIter next(&fHistolist);
3497  KVHistogram* h;
3498  while ((h = (KVHistogram*)next())) {
3499  if (h->IsType("Histo")) h->ParseExpressionAndSelection();
3500  }
3501  }
3502  }
3503  else {
3505  }
3506 }
3507 
3508 
3509 
3514 
3516 {
3517  // assuming filepath is the URL of a ROOT file, open it and
3518  // add the first TTree found in file as a friend of the current TTree
3519  // Any histograms in the file are added to the list of histograms
3520 
3521  TFile* file = TFile::Open(filepath);
3522  KVList keys(0);
3523  keys.AddAll(file->GetListOfKeys());
3524  // Get list of trees in file
3525  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3526  if (trees->GetEntries()) {
3527  // Get name of first tree
3528  TString aTreeName = trees->First()->GetName();
3529  TChain* t = new TChain(aTreeName);
3530  t->Add(filepath);
3531  fChain->AddFriend(t);
3532  FillLeafList();
3533  }
3534  TIter next(&keys);
3535  TKey* akey;
3536  while ((akey = (TKey*)next())) {
3537  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3538  if (!fHistolist.FindObject(akey->GetName())) {
3539  TH1* h = (TH1*)file->Get(akey->GetName());
3540  h->SetDirectory(0);
3541  fHistolist.Add(new KVHistogram(h));
3542  }
3543  }
3544  }
3546 }
3547 
3548 
3549 
3550 
3551 
3552 
int Int_t
unsigned int UInt_t
unsigned long ULong_t
kVerticalFrame
kHorizontalFrame
kMainFrame
#define SafeDelete(p)
#define f(i)
#define c(i)
#define e(i)
bool Bool_t
short Version_t
char Char_t
float Float_t
short Short_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
kRed
kOrange
kGreen
kCyan
kBlue
kViolet
#define X(type, name)
#define gDirectory
R__EXTERN TEnv * gEnv
EButtonState
#define gClient
kFDOpen
kFDSave
kDeepCleanup
kLHintsExpandY
kLHintsLeft
kLHintsCenterY
kLHintsCenterX
kLHintsTop
kLHintsExpandX
kMBNo
kMBClose
kMBYes
kMBDismiss
kMBIconExclamation
kMBIconStop
kTextCenterX
kTextLeft
kTextRight
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t sel
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t g
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
float xmin
int nentries
float ymin
float xmax
float ymax
R__EXTERN TProof * gProof
#define gROOT
char * Form(const char *fmt,...)
char * StrDup(const char *str)
void AssignAndDelete(TString &target, char *tobedeleted)
R__EXTERN TSystem * gSystem
#define gPad
virtual Bool_t IsType(const Char_t *typ) const
Definition: KVBase.h:184
static void InitEnvironment()
Definition: KVBase.cpp:175
static Bool_t OpenContextMenu(const char *method, TObject *obj, const char *alt_method_name="")
Definition: KVBase.cpp:1463
TCanvas with mouse-controlled dynamic zoom and pan & scan.
Definition: KVCanvas.h:54
Fill 3D observables in a dalitz plot ,.
Definition: KVDalitzPlot.h:28
Modified version of TGFileDialog file selection dialog.
Definition: KVFileDialog.h:49
Wrapper for histograms and graphical cuts used by KVTreeAnalyzer.
Definition: KVHistogram.h:20
TCutG * GetCut() const
Definition: KVHistogram.h:41
static void ParseHistoTitle(const Char_t *title, KVString &exp, KVString &sel, KVString &weight)
const Char_t * GetExpression() const
Bool_t IsProfile() const
Definition: KVHistogram.h:45
const Char_t * GetSelection() const
TH1 * GetHisto() const
Definition: KVHistogram.h:37
const Char_t * GetWeight() const
Return weighting used for filling histogram.
Bool_t IsTH2() const
Definition: KVHistogram.h:49
virtual void SetIsBoolean(Bool_t isit=kTRUE)
Definition: KVLVContainer.h:89
Extension of TGLVContainer for KVListView widget.
Enhanced version of ROOT TGListView widget.
Definition: KVListView.h:146
virtual void ActivateSortButtons()
Definition: KVListView.cpp:72
virtual void SetDataColumns(Int_t ncolumns)
Definition: KVListView.cpp:91
void SetDoubleClickAction(const char *receiver_class, void *receiver, const char *slot)
Definition: KVListView.cpp:210
virtual KVLVColumnData * GetDataColumn(Int_t index) const
Definition: KVListView.h:168
virtual void Display(const TCollection *l)
Definition: KVListView.h:173
virtual void SetMaxColumnSize(UInt_t width)
Definition: KVListView.h:161
KVList * GetPickOrderedSelectedObjects() const
Definition: KVListView.h:255
TList * GetSelectedObjects() const
Definition: KVListView.h:249
virtual void RemoveAll()
Definition: KVListView.h:190
void AllowContextMenu(Bool_t on=kTRUE)
Definition: KVListView.h:287
virtual void SetDataColumn(Int_t index, const Char_t *name, const Char_t *method="", Int_t mode=kTextCenterX)
Definition: KVListView.cpp:106
void SetUseObjLabelAsRealClass(Bool_t yes=kTRUE)
Definition: KVListView.cpp:189
Extended TList class which owns its objects by default.
Definition: KVList.h:28
GUI for setting KVNameValueList parameters.
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
void SetValue(const Char_t *name, value_type value)
const Char_t * GetStringValue(const Char_t *name) const
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:85
Bool_t End(void) const
Definition: KVNumberList.h:199
void Begin(void) const
Int_t GetEntries() const
Definition: KVNumberList.h:171
void Add(Int_t)
Add value 'n' to the list.
Int_t Next(void) const
KaliVeda extensions to ROOT collection classes.
void Copy(TObject &obj) const override
TObject * First() const override
KVSeqCollection * GetSubListWithMethod(const Char_t *retvalue, const Char_t *method) const
TObject * Remove(TObject *obj) override
Remove object from list.
void Add(TObject *obj) override
TObject * FindObject(const char *name) const override
TObject * Last() const override
Int_t GetSize() const override
void Clear(Option_t *option="") override
void SetOwner(Bool_t enable=kTRUE) override
virtual TObject * FindObjectWithMethod(const Char_t *retvalue, const Char_t *method) const
TObject * At(Int_t idx) const override
virtual TObject * FindObjectByTitle(const Char_t *) const
Will return object with given title (value of TObject::GetTitle() method).
virtual TObject * FindObjectWithNameAndType(const Char_t *name, const Char_t *type) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:73
GUI for simple intuitive analysis of data in TTree ,.
void DeleteHisto(const Char_t *expr, const Char_t *selection, const Char_t *weight)
Int_t fSelectionNumber
used for automatic naming of selections
Bool_t IsPROOFEnabledForSelections() const
Bool_t fNoGui
=kTRUE if no graphical interface is required
static KVTreeAnalyzer * OpenFile(const Char_t *filename, Bool_t nogui=kFALSE)
TList * GetHistosByData(const Char_t *expr)
KVHistogram * GetHistoByTitle(const Char_t *title)
TChain * fChain
the analyzed TTree or TChain
Bool_t fNormHisto
=kTRUE: generate normalised histograms (normalise to integral of histo)
TGCheckButton * G_histo_norm
Bool_t IsPROOFEnabled() const
void SetTreeFileName(TTree *t)
TGMenuBar * fMenuBar
Int_t fHistoNumber
used for automatic naming of histograms
void SetTree(TTree *t)
Connects a TChain for analysis.
TGGroupFrame * fMain_leaflist
GUI for access to TTree leaves and aliases.
void DeleteSelections()
Delete the currently selected selection(s)
void ReconnectTree()
Backwards compatibility: to read old analysis files.
const TGMainFrame * GetMainWindow() const
void OpenAnyFile(const Char_t *filepath)
KVListView * G_histolist
GUI list of histograms.
Bool_t MakeSelection(const Char_t *selection)
void ReapplyAnyFile(const Char_t *filepath)
void SetAnalysisModifiedSinceLastSave(Bool_t)
TString fAutoSaveDir
directory for autosaving histos
Bool_t fStatsHisto
=kTRUE: display histo stats box
TGCheckButton * G_histo_app_sel
KVList * fSelectedLeaves
const Char_t * get_leaf_type_name(const TNamed *l)
Bool_t fApplySelection
=kTRUE: apply current selection to existing histogram
void SetWindowTitle(const TString &tt)
TString fTreeName
name of analyzed TTree
TString fAnalysisSaveDir
Bool_t fDrawSame
=kTRUE: draw histograms in same plot
void GenerateAllAliases(TCollection *list)
Generate all user aliases in list which are not already defined.
Int_t fAliasNumber
used for automatic naming of TTree aliases
void SaveAs(const char *filename="", Option_t *option="") const override
void Copy(TObject &obj) const override
TH1 * RemakeHisto(TH1 *h, const Char_t *expr, const Char_t *weight="")
TH1 * MakeHisto(const Char_t *expr, const Char_t *selection, Int_t nX, Int_t nY=0, const Char_t *weight="", Double_t xmin=-1, Double_t xmax=-1, Double_t ymin=-1, Double_t ymax=-1)
void SetAlias(const Char_t *name, const Char_t *expr)
Bool_t fDeletedByGUIClose
double GetTreeMinimum(const TString &leafname)
static KVList * fgAnalyzerList
static list of all analyzers in memory
TString fTreeFileName
name of file containing analyzed TTree
void DeleteSelectedHisto()
Delete all currently selected histograms.
void GUIClosed()
Called when graphical window is closed.
TEntryList * GetSelection(const Char_t *)
Look for selection in list of selections.
Bool_t IsCurrentSelection(const Char_t *sel)
void AutoSaveHisto(TH1 *h)
TGTextEntry * G_alias_text
TGPopupMenu * fSelCombMenu
Bool_t fNewCanvas
=kTRUE: draw each histogram in a new canvas
void init()
Default initialization.
TString fRelativePathToAnalysisFile
TGCheckButton * G_histo_log
void AddHisto(TH1 *)
TGComboBox * G_histo_draw_option
KVUniqueNameList fSelections
list of TEntryList user selections
bool got_histos_or_tree_from_file
void GenerateAllHistograms(TCollection *)
Bool_t fNormHistoEvents
=kTRUE: generate normalised histograms (normalise to number of events)
void SetSelection(TObject *)
void CurrentSelection()
Print the currently active selection (TEntryList set on TTree).
KVList fLeafList
clones of leaves in TChain
TGCheckButton * G_histo_weight
void UpdateEntryLists()
regenerate entry lists for all selections
TGCheckButton * G_histo_prof
void SetEntryList(TEntryList *)
void DrawCut(TCutG *)
void HistoAddition(Double_t c1=1, Double_t c2=1)
void OpenGUI()
Launch the GUI (unless fNoGui=kTRUE in which case this does nothing)
void HistoFileMenu_OpenFriend()
TGPictureButton * G_histo_add
void SetRelativePathToAnalysisFile(const Char_t *p)
TGPictureButton * G_histo_del
TGCheckButton * G_histo_stats
KVTreeAnalyzer(Bool_t nogui=kTRUE)
TGCheckButton * G_histo_new_can
void HandleHistoFileMenu(Int_t)
TGCheckButton * G_histo_bin
void HandleOptionsMenu(Int_t opt)
TGGroupFrame * fMain_selectionlist
GUI for handling selections.
TList * fSelectedHistos
void GetHistosFromFile(TFile *file, const KVUnownedList &keys)
TString fSaveAnalysisFileName
void AddCut(TCutG *)
TGPopupMenu * fMenuSelections
Bool_t MethodNotCalled()
TGPictureButton * G_leaf_draw
Bool_t fAutoSaveHisto
=kTRUE: on draw, generate image file of current displayed histo
void HandleSelectionsMenu(Int_t)
void DrawHistogram(TH1 *histo, Bool_t same=false, Bool_t logscale=false)
void EnablePROOF(Bool_t yes=kTRUE)
KVList fHistolist
list of generated histograms
TGPopupMenu * fMenuFile
TList * GetHistosBySelection(const Char_t *expr)
void OpenAnyFriendFile(const Char_t *filepath)
TTree * fTree
for backwards compatibility
TGCheckButton * G_histo_norm_events
void GenerateAllSelections(TCollection *)
For applying existing analysis to new data.
TGPopupMenu * fSelGenerate
TString fAutoSaveType
filetype for autosaving histos
TH1 * GetHistogram(const Char_t *name) const
Return histogram with given name.
TGPopupMenu * fOptionMenu
Long64_t GetEntriesInCurrentSelection() const
KVListView * G_selectionlist
GUI list of TEntryList selections.
double GetTreeMaximum(const TString &leafname)
TGLabel * G_leaf_expr
TGStatusBar * G_selection_status
status bar in selections GUI
void AddSelection(TEntryList *)
TGLayoutHints * fMenuBarItemLayout
TGCheckButton * G_histo_same
TH1 * MakeIntHisto(const Char_t *expr, const Char_t *selection, Int_t Xmin, Int_t Xmax, const Char_t *weight="")
virtual ~KVTreeAnalyzer()
Destructor.
void OpenChain()
Open a file or files containing TTrees to analyse.
void SelectionChanged()
Method called whenever the selected selection in the GUI list changes.
TGMainFrame * fMain_histolist
GUI for handling histograms.
TH1 * GetHisto(const Char_t *expr, const Char_t *selection, const Char_t *weight="")
Bool_t fAnalysisModifiedSinceLastSave
TNamed * GetAlias(const Char_t *expr)
void HistoSelectionChanged()
Method called when user histo selection changes in GUI histogram list.
void GenerateHistoTitle(TString &title, const Char_t *exp, const Char_t *sel, const Char_t *weight="")
void ReadFromFile(const Char_t *filename)
open a previously saved analysis session.
Bool_t fDrawLog
=kTRUE: draw histograms with log-Y (1-D) or log-Z (2-D) scale
void HistoFileMenu_Open()
Open a previous analysis session.
void DrawLeaf(TObject *)
Method called when user double-clicks a leaf/alias in list.
KVList fAliasList
list of TTree aliases
TList * fSelectedSelections
void DrawHisto(TObject *o, Bool_t gen=kTRUE)
TGCheckButton * G_histo_autosave
TGTextEntry * G_selection_text
KVListView * G_leaflist
GUI list of TTree leaves and aliases.
Bool_t fMethodCalled
allows to know if context menu methods are called
void ResetMethodCalled()
void Add(TObject *obj) override
Extended TList class which does not own its objects by default.
Definition: KVUnownedList.h:17
virtual void SetLineWidth(Width_t lwidth)
virtual void SetLineColor(Color_t lcolor)
Double_t GetXmax() const
Double_t GetXmin() const
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=nullptr)=0
Bool_t IsReading() const
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
void SetEntryList(TEntryList *elist, Option_t *opt="") override
TFriendElement * AddFriend(const char *chainname, const char *dummy="") override
TObjArray * GetListOfLeaves() override
virtual Int_t Add(const char *name, Long64_t nentries=TTree::kMaxEntries)
void RemoveFriend(TTree *) override
void SetDirectory(TDirectory *dir) override
Long64_t Draw(const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0) override
virtual void SetProof(Bool_t on=kTRUE, Bool_t refresh=kFALSE, Bool_t gettreeheader=kFALSE)
Long64_t GetEntries() const override
static TClass * GetClass(Bool_t load=kTRUE, Bool_t silent=kFALSE)
Bool_t InheritsFrom(const char *cl) const override
void ls(Option_t *option="") const override
virtual void AddAll(const TCollection *col)
virtual Int_t GetEntries() const
TObject * Clone(const char *newname="") const override
const char * GetVarX() const
static TClass * Class()
const char * GetVarY() const
virtual Bool_t cd()
static TClass * Class()
virtual Bool_t GetReapplyCut() const
virtual Long64_t Next()
virtual Long64_t GetEntry(Long64_t index)
virtual Long64_t GetN() const
virtual const char * GetValue(const char *name, const char *dflt) const
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
virtual const char * GetTreeName() const
virtual TTree * GetTree()
virtual TFile * GetFile()
virtual void SetToolTipText(const char *text, Long_t delayms=400)
virtual void SetEnabled(Bool_t e=kTRUE)
TGFrame * GetContainer() const
void SetState(EButtonState state, Bool_t emit=kFALSE) override
virtual void AddEntry(const char *s, Int_t id)
TGDimension GetDefaultSize() const override
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=nullptr)
void MapSubwindows() override
void SetCleanup(Int_t mode=kLocalCleanup) override
TList * fFileNamesList
char * fFilename
void SetMultipleSelection(Bool_t option)
Int_t fFileTypeIdx
const char ** fFileTypes
char * fIniDir
Bool_t fOverwrite
virtual UInt_t GetDefaultHeight() const
virtual void Resize(TGDimension size)
TGDimension GetSize() const
void MapWindow() override
TGDimension GetDefaultSize() const override
void SetText(const char *newText)
const char * GetTitle() const override
void SetIconPixmap(char **xpm_array)
void SetIconName(const char *name)
void SetWindowName(const char *name=nullptr) override
virtual void AddPopup(const char *s, TGPopupMenu *menu, TGLayoutHints *l, TGPopupMenu *before=nullptr)
virtual Bool_t IsEntryChecked(Int_t id)
virtual void CheckEntry(Int_t id)
virtual void DisableEntry(Int_t id)
virtual void EnableEntry(Int_t id)
virtual void AddEntry(const char *s, Int_t id, void *ud=nullptr, const TGPicture *p=nullptr, TGMenuEntry *before=nullptr)
virtual void UnCheckEntry(Int_t id)
virtual void AddSeparator(TGMenuEntry *before=nullptr)
virtual void AddPopup(const char *s, TGPopupMenu *popup, TGMenuEntry *before=nullptr, const TGPicture *p=nullptr)
virtual void SetText(const char *text, Int_t partidx=0)
virtual void SetMaxLength(Int_t maxlen)
void Clear(Option_t *option="") override
const char * GetText() const
virtual void SetCursorPosition(Int_t pos)
virtual void SetAlignment(ETextJustification mode=kTextLeft)
virtual void SetText(const char *text, Bool_t emit=kTRUE)
Int_t MaxMark() const
Int_t MinMark() const
virtual void SetName(const char *name)
virtual void RaiseWindow()
void Draw(Option_t *chopt="") override
void SetTitle(const char *title="") override
static TClass * Class()
virtual void SetDirectory(TDirectory *dir)
virtual Bool_t Add(const TH1 *h, const TH1 *h2, Double_t c1=1, Double_t c2=1)
void SetTitle(const char *title) override
virtual Int_t GetNbinsY() const
Option_t * GetOption() const override
TAxis * GetXaxis()
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
virtual Int_t GetNbinsX() const
virtual void SetMaximum(Double_t maximum=-1111)
TAxis * GetYaxis()
void Draw(Option_t *option="") override
virtual Double_t Integral(Int_t binx1, Int_t binx2, Option_t *option="") const
TClass * IsA() const override
virtual void SetOption(Option_t *option=" ")
virtual void Scale(Double_t c1=1, Option_t *option="")
TObject * Clone(const char *newname="") const override
virtual void Sumw2(Bool_t flag=kTRUE)
virtual void SetStats(Bool_t stats=kTRUE)
virtual const char * GetClassName() const
virtual const char * GetTypeName() const
TBranch * GetBranch() const
TObject * FindObject(const char *name) const override
void Add(TObject *obj) override
TObject * First() const override
void Delete(Option_t *option="") override
TObject * At(Int_t idx) const override
void Copy(TObject &named) const override
virtual void SetTitle(const char *title="")
const char * GetName() const override
void Streamer(TBuffer &) override
const char * GetTitle() const override
static TClass * Class()
TObject * FindObject(const char *name) const override
virtual const char * GetName() const
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
virtual Bool_t InheritsFrom(const char *classname) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual const char * GetTitle() const
virtual TClass * IsA() const
virtual void Info(const char *method, const char *msgfmt,...) const
static TProof * Open(const char *url=0, const char *conffile=0, const char *confdir=0, Int_t loglevel=0)
TList * GetOutputList()
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Ssiz_t Length() const
TString & Insert(Ssiz_t pos, const char *s)
Ssiz_t First(char c) const
const char * Data() const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
TString & Append(char c, Ssiz_t rep=1)
Bool_t IsNull() const
TString & Prepend(char c, Ssiz_t rep=1)
virtual Int_t Sizeof() const
void Form(const char *fmt,...)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
virtual const char * DirName(const char *pathname)
virtual char * ConcatFileName(const char *dir, const char *name)
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
virtual Bool_t ChangeDirectory(const char *path)
virtual const char * BaseName(const char *pathname)
virtual Bool_t IsAbsoluteFileName(const char *dir)
virtual const char * WorkingDirectory()
static void SingleShot(Int_t milliSec, const char *receiver_class, void *receiver, const char *method)
virtual Int_t GetEntry(Long64_t entry, Int_t getall=0)
virtual TObjArray * GetListOfLeaves()
TFile * GetCurrentFile() const
virtual TList * GetListOfAliases() const
virtual TTree * GetFriend(const char *) const
virtual Double_t GetMaximum(const char *columname)
TDirectory * GetDirectory() const
virtual TEntryList * GetEntryList()
virtual Long64_t GetEntries() const
virtual Long64_t Draw(const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
virtual Long64_t GetEntryNumber(Long64_t entry) const
virtual TLeaf * GetLeaf(const char *branchname, const char *leafname)
virtual Double_t GetMinimum(const char *columname)
Int_t SetBranchAddress(const char *bname, T **add, TBranch **ptr=nullptr)
virtual TList * GetListOfFriends() const
virtual void ResetBranchAddresses()
long long Long64_t
RVec< PromoteType< T > > tan(const RVec< T > &v)
RVec< PromoteType< T > > exp(const RVec< T > &v)
Double_t y[n]
return c1
Double_t x[n]
TH1 * h
return c2
TLine l
ClassImp(TPyArg)