Loading [MathJax]/jax/input/TeX/config.js
KaliVeda
Toolkit for HIC analysis
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Modules Pages
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;
1217  if (IsPROOFEnabled()) fChain->SetProof();
1218  fTreeName = t->GetName();
1219  SetTreeFileName(t);
1221 }
1222 
1223 
1224 
1227 
1229 {
1230  // Backwards compatibility: to read old analysis files
1231 
1232  TFile* f;
1234  // absolute path to TTree file doesn't work, try in working directory
1235  TString tmp;
1237  f = TFile::Open(tmp);
1238  }
1240  // if fRelativePathToAnalysisFile!="." and if fTreeFileName is not an absolute path,
1241  // we guess the Tree file is in the same directory as the analysis file
1242  TString tmp;
1244  f = TFile::Open(tmp);
1245  }
1246  else
1248  if (!f || f->IsZombie()) {
1249  Error("ReconnectTree", "Failed to reconnect Tree file %s", fTreeFileName.Data());
1250  fTree = 0;
1251  fChain = 0;
1252  SafeDelete(f);
1253  return;
1254  }
1255  fTreeFileName = f->GetName();
1256  TTree* t = (TTree*)f->Get(fTreeName);
1257  TString treeTitle = t->GetTitle();
1258  delete f;
1259  fChain = new TChain(fTreeName, treeTitle);
1261  fChain->SetDirectory(0);
1262  SetTree(fChain);
1263 }
1264 
1265 
1266 
1274 
1276 {
1277  // STATIC method to open a previously saved analysis session.
1278  //
1279  // Use:
1280  // root[0] KVTreeAnalyzer* TA = KVTreeAnalyzer::OpenFile("my_analysis.root")
1281  //
1282  // If option nogui=kTRUE the GUI will not be launched
1283 
1285  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1286  delete f;
1287  anal->fNoGui = nogui;
1289  anal->OpenGUI();
1290  return anal;
1291 }
1292 
1293 
1294 
1297 
1299 {
1300  // open a previously saved analysis session.
1301 
1303  ReadFromFile(f);
1304 }
1305 
1306 
1307 
1310 
1312 {
1313  // open a previously saved analysis session.
1314 
1315  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1316  delete f;
1317  anal->Copy(*this);
1318  delete anal;
1319  gTreeAnalyzer = this;
1322  FillLeafList();
1323 }
1324 
1325 
1326 
1328 
1330 {
1331  TString name = Form("%s:%s", cut->GetVarY(), cut->GetVarX());
1332  KVList padList(kFALSE);
1333  Bool_t testHisto = kFALSE;
1334 
1335  if (!gPad) testHisto = kTRUE;
1336 
1337  if (!testHisto) {
1338  testHisto = kTRUE;
1339  padList.AddAll(((TPad*)gPad)->GetListOfPrimitives());
1340  TIter next(&padList);
1341  TObject* o = 0;
1342  while ((o = next())) {
1343  if (o->InheritsFrom("TH1")) {
1344  TH1* hh = (TH1*) o;
1345  TString hName = hh->GetTitle();
1346  if (hName.Contains(name.Data())) {
1347  cut->Draw("PL");
1348  gPad->Update();
1349  testHisto = kFALSE;
1350  }
1351  }
1352  }
1353  }
1354 
1355  if (testHisto) {
1356  TIter next(&fHistolist);
1357  KVHistogram* hhh;
1358  TH1* hh = 0;
1359  while ((hhh = (KVHistogram*)next())) {
1360  if ((hh = hhh->GetHisto())) {
1361  TString hName = hh->GetTitle();
1362  if (hName.Contains(name.Data())) {
1363  DrawHisto(hh, kFALSE);
1364  cut->Draw("PL");
1365  gPad->Update();
1366  break;
1367  }
1368  }
1369  }
1370  }
1371  // else cut->Draw("PAL");
1372 
1373 
1374 // TIter next(fHistoList);
1375 // TH1* tmpHist = 0;
1376 // while((tmpHisto = (TH1*)next()))
1377 // {
1378 //
1379 // }
1380 
1381  return;
1382 }
1383 
1384 
1385 
1387 
1388 void KVTreeAnalyzer::DrawHistogram(TH1* histo, Bool_t same, Bool_t logscale)
1389 {
1390  if (fDrawSame || same) {
1391  // if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1392  // plot with a different colour and add it to the automatically generated
1393  // legend which is also displayed in the plot
1394  histo->SetLineColor(my_color_array[++fSameColorIndex]);
1395  histo->SetLineWidth(2);
1396  if (fSameColorIndex == MAX_COLOR_INDEX) fSameColorIndex = -1;
1397  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1398  if (histo->InheritsFrom("TH2")) {
1399  TString hopt = histo->GetOption();
1400  if (hopt != "") hopt.Form("%s,same", histo->GetOption());
1401  else hopt = "same";
1402  histo->Draw(hopt);
1403  }
1404  else
1405  histo->Draw("same");
1406  TObject* legend = gPad->GetListOfPrimitives()->FindObject("TPave");
1407  if (legend) {
1408  gPad->GetListOfPrimitives()->Remove(legend);
1409  delete legend;
1410  }
1411  ((TPad*) gPad)->BuildLegend();
1412  if (histo->InheritsFrom("TH2")) {
1413  gPad->SetLogy(kFALSE);
1414  gPad->SetLogz(fDrawLog || logscale);
1415  }
1416  else {
1417  gPad->SetLogy(fDrawLog || logscale);
1418  // adjust y-scale to new histogram if needed
1419  // find first histogram
1420  TIter nxt(gPad->GetListOfPrimitives());
1421  TObject* h;
1422  while ((h = nxt())) {
1423  if (h->InheritsFrom("TH1")) {
1424  TH1* hh = (TH1*)h;
1425  if (histo->GetMaximum() > hh->GetMaximum()) hh->SetMaximum(histo->GetMaximum() + 1);
1426  break;
1427  }
1428  }
1429  }
1430  gPad->Modified();
1431  gPad->Update();
1432  if (fAutoSaveHisto) AutoSaveHisto(histo);
1433  }
1434  else {
1435  // if 'new canvas' is active the histogram is displayed in a new KVCanvas
1436  // create a new canvas also if none exists
1437  if (fNewCanvas || !gPad) {
1438  KVCanvas* c = new KVCanvas;
1439  c->SetTitle(histo->GetTitle());
1440  c->SetWindowSize(700, 700);
1441  }
1442  else if (gPad) { // update title of existing canvas
1443  gPad->GetCanvas()->SetTitle(histo->GetTitle());
1444  }
1445  histo->SetLineColor(my_color_array[0]);
1446  histo->SetLineWidth(2);
1447  if (histo->InheritsFrom("TH2")) {
1448  gPad->SetLogy(kFALSE);
1449  gPad->SetLogz(fDrawLog || logscale);
1450  }
1451  else {
1452  histo->SetMaximum(-1111);//in case maximum was changed to accomodate superimposition
1453  gPad->SetLogy(fDrawLog || logscale);
1454  }
1455  histo->SetStats(fStatsHisto);//show/hide stat box according to check-box
1456  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1457  histo->Draw();
1458  gPad->Modified();
1459  gPad->Update();
1460  if (fAutoSaveHisto) AutoSaveHisto(histo);
1461  }
1462 }
1463 
1464 
1465 
1486 
1488 {
1489  // Method called when a user double-clicks a histogram in the GUI list.
1490  //
1491  // * if histogram is already displayed in active pad and if the pad also
1492  // contains a graphical contour (TCutG) object, we use the contour to define
1493  // a new data selection (TEntryList) which is added to the internal list.
1494  //
1495  // * if 'reapply selection' is activated and if the current active selection
1496  // is not the same as that used to generate the histogram, we generate a new
1497  // histogram displaying the same variables but with the current selection.
1498  //
1499  // * if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1500  // plot with a different colour and add it to the automatically generated
1501  // legend which is also displayed in the plot
1502  //
1503  // * if 'new canvas' is active the histogram is displayed in a new KVCanvas
1504  //
1505  // * in all cases when a histogram is displayed the log/linear scale of
1506  // Y (1-D) or Z (2-D) axis is automatically adjusted according to the 'log scale'
1507  // check box
1508 
1509  KVHistogram* kvhisto = 0;
1510  TCutG* cut = 0;
1511  TH1* histo = 0;
1512  if (obj->InheritsFrom("KVHistogram")) {
1513  kvhisto = dynamic_cast<KVHistogram*>(obj);
1514  if (kvhisto->IsType("Cut")) cut = kvhisto->GetCut();
1515  else if (kvhisto->IsType("Histo")) histo = kvhisto->GetHisto();
1516  }
1517  else if (obj->InheritsFrom("TCutG")) {
1518  cut = dynamic_cast<TCutG*>(obj);
1519  }
1520  else if (obj->InheritsFrom("TH1")) {
1521  histo = dynamic_cast<TH1*>(obj);
1522  }
1523 
1524  if (cut) {
1525  DrawCut(cut);
1526  return;
1527  }
1528  if (!histo) return;
1529 
1530  // if histogram is already displayed in active pad and if the pad also
1531  // contains a graphical contour (TCutG) object, we use the contour to define
1532  // a new data selection (TEntryList) which is added to the internal list.
1533  if (gPad && gPad->GetListOfPrimitives()->FindObject(histo) && (gen)) {
1534  TIter next(gPad->GetListOfPrimitives());
1535  TObject* o;
1536  while ((o = next())) {
1537  if ((o->IsA() == TCutG::Class()) && !(fHistolist.FindObjectWithNameAndType(o->GetName(), "Cut"))) {
1538  MakeSelection(o->GetName());
1539  return;
1540  }
1541  }
1542  }
1543 
1544  KVString exp, sel, weight;
1545  if (kvhisto) {
1546  exp = kvhisto->GetExpression();
1547  sel = kvhisto->GetSelection();
1548  weight = kvhisto->GetWeight();
1549  }
1550  else {
1551  KVHistogram::ParseHistoTitle(histo->GetTitle(), exp, sel, weight);
1552  }
1553 
1554  if (weight == "1") weight = "";
1555 
1556  // if 'reapply selection' is activated and if the current active selection
1557  // is not the same as that used to generate the histogram, we generate a new
1558  // histogram displaying the same variables but with the current selection.
1560  histo = RemakeHisto(histo, exp, weight);
1561  if (!histo) return;
1562  }
1563 
1564  DrawHistogram(histo);
1565 }
1566 
1567 
1568 
1572 
1574 {
1575  // Returns kTRUE if "sel" corresponds to current active selection
1576  // (i.e. entry list of TTree)
1577 
1578  if (!fTree) return kTRUE;
1579  TString test_sel(sel);
1580  TString tree_sel;
1581  TEntryList* el;
1582  if ((el = fChain->GetEntryList())) tree_sel = el->GetTitle();
1583  return (test_sel == tree_sel);
1584 }
1585 
1586 
1587 
1592 
1593 TH1* KVTreeAnalyzer::RemakeHisto(TH1* h, const Char_t* expr, const Char_t* weight)
1594 {
1595  // Remake an existing histogram of data 'expr' using the current active selection
1596  // If such a histogram already exists, we just return its address.
1597  // We must have the same binning in the new as in the original histogram.
1598 
1599  TString htit;
1600  GenerateHistoTitle(htit, expr, "", weight);
1601  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
1602  TH1* histo = 0;
1603  if (kvhisto) histo = kvhisto->GetHisto();
1604  if (histo && (histo->IsA() == h->IsA())) return histo;
1605  Int_t nx, ny = 0;
1606  TString hname(h->GetName());
1607  if (hname.BeginsWith("I")) {
1608  Int_t xmin = h->GetXaxis()->GetXmin() + 0.5;
1609  Int_t xmax = h->GetXaxis()->GetXmax() - 0.5;
1610  //cout << "Remake histo with xmin = " << xmin << " xmax = " << xmax << endl;
1611  h = MakeIntHisto(expr, "", xmin, xmax, weight);
1612  return h;
1613  }
1614  nx = h->GetNbinsX();
1615  auto xmin = h->GetXaxis()->GetXmin();
1616  auto xmax = h->GetXaxis()->GetXmin();
1617  double ymin(-1), ymax(-1);
1618  if (h->InheritsFrom("TH2")) {
1619  ny = h->GetNbinsY();
1620  ymin = h->GetYaxis()->GetXmin();
1621  ymax = h->GetYaxis()->GetXmin();
1622  }
1623  //cout << "Remake histo with nx = " << nx << " ny = " << ny << endl;
1624  if (h->InheritsFrom("TProfile")) {
1625  // make a new profile histogram
1626  Bool_t oldProfileState = fProfileHisto;
1627  fProfileHisto = kTRUE;
1628  h = MakeHisto(expr, "", nx, ny, weight, xmin, xmax);
1629  fProfileHisto = oldProfileState;
1630  }
1631  else
1632  h = MakeHisto(expr, "", nx, ny, weight, xmin, xmax, ymin, ymax);
1633  return h;
1634 }
1635 
1636 
1637 
1642 
1644 {
1645  // Method called when user hits 'return' in selection GUI text-box
1646  // Takes expression from text-box and generates the corresponding
1647  // selection which is added to the GUI list of selections.
1648 
1649  TString selection = G_selection_text->GetText();
1650  if (selection.IsNull()) return;
1651  if (MakeSelection(selection)) G_selection_text->Clear();
1652 }
1653 
1654 
1655 
1659 
1661 {
1662  // Method called when user hits 'return' in TTree leaf/alias GUI text-box
1663  // Generates a new alias using the expression in the text-box.
1664 
1665  TString alias = G_alias_text->GetText();
1666  TString name;
1667  name.Form("a%d", fAliasNumber++);
1668  SetAlias(name, alias);
1669  FillLeafList();
1670  G_alias_text->Clear();
1671 }
1672 
1673 
1674 
1679 
1681 {
1682  // Method called when user hits 'combine selections' button in selections GUI.
1683  // Generates new selection which is the intersection (logical AND) of
1684  // the currently selected selections.
1685 
1686  if (fSelectedSelections) {
1687  TEntryList* save_elist = fChain->GetEntryList();
1689  TString newselect;
1690  int nsel = fSelectedSelections->GetEntries();
1691  for (int i = 1; i < nsel; i++) {
1692  TString tmp;
1694  tmp.Form("(%s)", el->GetTitle());
1695  if (i > 1) newselect += " && ";
1696  newselect += tmp.Data();
1697  }
1698  MakeSelection(newselect);
1699  SetEntryList(save_elist);
1700  }
1701 }
1702 
1703 
1704 
1709 
1711 {
1712  // Method called when user hits 'combine selections' button in selections GUI.
1713  // Generates new selection which is the intersection (logical AND) of
1714  // the currently selected selections.
1715 
1716  if (fSelectedSelections) {
1717  TEntryList* save_elist = fChain->GetEntryList();
1718  SetEntryList(nullptr);
1719  TString newselect;
1720  int nsel = fSelectedSelections->GetEntries();
1721  for (int i = 0; i < nsel; i++) {
1722  TString tmp;
1724  tmp.Form("(%s)", el->GetTitle());
1725  if (i > 0) newselect += " || ";
1726  newselect += tmp.Data();
1727  }
1728  MakeSelection(newselect);
1729  SetEntryList(save_elist);
1730  }
1731 }
1732 
1733 
1734 
1737 
1739 {
1740  // Delete the currently selected selection(s)
1741 
1742  if (fSelectedSelections) {
1743  int nsel = fSelectedSelections->GetEntries();
1744  if (nsel < 1) return;
1745  for (int i = 0; i < nsel; i++) {
1747  if (!el) continue;
1748  fSelections.Remove(el);
1749  // if current selection, disable
1750  if (fChain->GetEntryList() == el) fChain->SetEntryList(nullptr);
1751  delete el;
1753  }
1755  }
1757 
1758 }
1759 
1760 
1761 
1764 
1766 {
1767  // Method called whenever the selected selection in the GUI list changes
1768 
1771  Bool_t resetSel = kTRUE;
1775 
1777  }
1778  else if (fSelectedSelections->GetEntries() == 1) {
1781  if (tmp->GetSize() != 0 || !strcmp("", G_selection_text->GetText())) {
1782  G_selection_text->SetText(((TNamed*)fSelectedSelections->At(0))->GetTitle());
1783  resetSel = kFALSE;
1784  }
1785  delete tmp;
1786  }
1787  else if (fSelectedSelections->GetEntries() > 1) {
1791  }
1792 
1793  if (resetSel) {
1795  if (tmp->GetSize() != 0) G_selection_text->SetText("");
1796  delete tmp;
1797  }
1798 }
1799 
1800 
1801 
1805 
1807 {
1808  // Method called whenever the leaf/alias selection in the TTree GUI list changes.
1809  // Updates the names of the leaves/aliases displayed next to the 'draw' button.
1810 
1812  fLeafExpr = "-";
1813  fXLeaf = fYLeaf = 0;
1814 // Bool_t resetSel = kTRUE;
1816  Int_t nleaf = fSelectedLeaves->GetEntries();
1817  if (nleaf) {
1818  if (nleaf == 1) {
1820  fLeafExpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1822 
1823  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1824  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1825  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0 || !strcmp("", G_alias_text->GetText())) {
1826  G_alias_text->SetText(fLeafExpr.Data()); //resetSel = kFALSE;
1827  }
1828  else if (strcmp(fLeafExpr.Data(), G_leaf_expr->GetTitle())) {
1829  TString tmps = G_alias_text->GetText();
1830  Int_t pos = G_alias_text->MaxMark();
1831  if (pos >= tmps.Sizeof()) pos = G_alias_text->MinMark();
1832  if (pos >= tmps.Sizeof()) pos = tmps.Sizeof() - 1;
1833  tmps.Insert(pos, fLeafExpr.Data());
1834  G_alias_text->SetText(tmps.Data());
1836  }
1837  delete tmp;
1838  delete tmp1;
1839 
1840  }
1841  else if (nleaf == 2) {
1842  fXLeaf = (TNamed*)fSelectedLeaves->At(1);
1844  TString X, Y;
1845  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1846  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1847  fLeafExpr.Form("%s:%s", Y.Data(), X.Data());
1849  G_alias_text->SetText("");
1850  }
1851  else if (nleaf == 3) {
1852  fXLeaf = (TNamed*)fSelectedLeaves->At(2);
1853  fYLeaf = (TNamed*)fSelectedLeaves->At(1);
1854  fZLeaf = (TNamed*)fSelectedLeaves->At(0);
1855  TString X, Y, Z;
1856  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1857  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1858  Z = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
1859  fLeafExpr.Form("%s:%s:%s", Z.Data(), Y.Data(), X.Data());
1861  G_alias_text->SetText("");
1862  }
1863  else {
1864  fLeafExpr = "-";
1865  G_alias_text->SetText("");
1866  }
1867  }
1868  else {
1869  fLeafExpr = "-";
1870 // G_alias_text->SetText("");
1871  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1872  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1873  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0) {
1874  G_alias_text->SetText(""); //resetSel = kFALSE;
1875  }
1876  delete tmp;
1877  delete tmp1;
1878  }
1879 
1881  G_leaf_expr->Resize();
1882 }
1883 
1884 
1885 
1887 
1889 {
1890  KVNameValueList p{{"Xbins", fNx}, {"Xmin", fXmin}, {"Xmax", fXmax},
1891  {"Ybins", fNy}, {"Ymin", fYmin}, {"Ymax", fYmax}};
1892  bool cancel{false};
1893  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1894  g->DisplayDialog();
1895  if (cancel) return false;
1896  fNx = p.GetIntValue("Xbins");
1897  fXmin = p.GetDoubleValue("Xmin");
1898  fXmax = p.GetDoubleValue("Xmax");
1899  fNy = p.GetIntValue("Ybins");
1900  fYmin = p.GetDoubleValue("Ymin");
1901  fYmax = p.GetDoubleValue("Ymax");
1902  return true;
1903 }
1904 
1905 
1906 
1908 
1910 {
1911  KVNameValueList p{{"bins", fNxF}, {"min", fXminF}, {"max", fXmaxF}};
1912  bool cancel{false};
1913  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1914  g->DisplayDialog();
1915  if (cancel) return false;
1916  fNxF = p.GetIntValue("bins");
1917  fXminF = p.GetDoubleValue("min");
1918  fXmaxF = p.GetDoubleValue("max");
1919  return true;
1920 }
1921 
1922 
1923 
1925 
1927 {
1928  KVNameValueList p{{"Xbins", fNxD}, {"Ybins", fNyD}, {"ordered?", fOrderedDalitz}};
1929  bool cancel{false};
1930  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1931  g->DisplayDialog();
1932  if (cancel) return false;
1933  fNxD = p.GetIntValue("Xbins");
1934  fNyD = p.GetIntValue("Ybins");
1935  fOrderedDalitz = p.GetBoolValue("ordered?");
1936  return true;
1937 }
1938 
1939 
1940 
1946 
1948 {
1949  // \returns maximum value of given TTree variable, taking into account any current selection (TEntryList).
1950  // @param leafname name of TTree variable
1951  //
1952  // \note TTree::GetMaximum() is supposed to do exactly the same, but strangely ignores the selection.
1953 
1954  fTree->GetMaximum(leafname);// this just to use internal TTree cache mechanism
1955 
1956  auto leaf = fTree->GetLeaf(leafname);
1957  if (!leaf) return 0;
1958 
1959  auto branch = leaf->GetBranch();
1960  Double_t cmax = -DBL_MAX;
1961  for (Long64_t i = 0; i < fTree->GetEntries(); ++i) {
1962  auto entryNumber = fTree->GetEntryNumber(i);
1963  if (entryNumber < 0) break;
1964  branch->GetEntry(entryNumber);
1965  for (Int_t j = 0; j < leaf->GetLen(); ++j) {
1966  Double_t val = leaf->GetValue(j);
1967  if (val > cmax) {
1968  cmax = val;
1969  }
1970  }
1971  }
1972  return cmax;
1973 }
1974 
1975 
1976 
1982 
1984 {
1985  // \returns minimum value of given TTree variable, taking into account any current selection (TEntryList).
1986  // @param leafname name of TTree variable
1987  //
1988  // \note TTree::GetMinimum() is supposed to do exactly the same, but strangely ignores the selection.
1989 
1990  fTree->GetMinimum(leafname);// this just to use internal TTree cache mechanism
1991 
1992  auto leaf = fTree->GetLeaf(leafname);
1993  if (!leaf) return 0;
1994 
1995  auto branch = leaf->GetBranch();
1996  Double_t cmin = DBL_MAX;
1997  for (Long64_t i = 0; i < fTree->GetEntries(); ++i) {
1998  auto entryNumber = fTree->GetEntryNumber(i);
1999  if (entryNumber < 0) break;
2000  branch->GetEntry(entryNumber);
2001  for (Int_t j = 0; j < leaf->GetLen(); ++j) {
2002  Double_t val = leaf->GetValue(j);
2003  if (val < cmin) {
2004  cmin = val;
2005  }
2006  }
2007  }
2008  return cmin;
2009 }
2010 
2011 
2012 
2014 
2016 {
2018  return lf->GetTypeName();
2019 }
2020 
2021 
2022 
2026 
2028 {
2029  // Method called when user hits 'draw' button in TTree GUI.
2030  // If only one leaf/alias is selected, this actually calls DrawLeaf.
2031 
2032  if (fLeafExpr == "-")return;
2033  Bool_t threeDexp = fSelectedLeaves->GetEntries() == 3;
2034  if (threeDexp && !fProfileHisto) {
2035  DrawAsDalitz();
2036  return;
2037  }
2038  if (fSelectedLeaves->GetEntries() == 1) {
2040  return;
2041  }
2042 
2043  if (fUserWeight) {
2044  if (!DefineWeight()) return;
2045  }
2046 
2047  int nx = 500, ny = 500;
2048  double xmin, xmax, ymin, ymax;
2049  xmin = xmax = ymin = ymax = 0;
2050  TString Xexpr, Yexpr, Zexpr;
2051  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2052  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2053  if (threeDexp) Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2054  if (fXLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fXLeaf), "Char_t")) {
2055  TString tmp = Xexpr;
2056  Xexpr.Form("int(%s)", tmp.Data());
2057  }
2058  if (fYLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fYLeaf), "Char_t")) {
2059  TString tmp = Yexpr;
2060  Yexpr.Form("int(%s)", tmp.Data());
2061  }
2062 
2063  if (threeDexp) fLeafExpr.Form("%s:%s:%s", Zexpr.Data(), Yexpr.Data(), Xexpr.Data());
2064  else fLeafExpr.Form("%s:%s", Yexpr.Data(), Xexpr.Data());
2065  TString name;
2066  name.Form("h%d", fHistoNumber);
2067  TString drawexp(fLeafExpr), histo, histotitle;
2068  if (fUserWeight) GenerateHistoTitle(histotitle, fLeafExpr, "", fWeight);
2069  else GenerateHistoTitle(histotitle, fLeafExpr, "");
2070 
2071  // Check histo doesn't already exist
2072  // Look for list of histograms with given title as we don't distinguish TH2 from TProfile
2073  unique_ptr<KVSeqCollection> same_histo(fHistolist.GetSubListWithMethod(histotitle, "GetHistoTitle"));
2074  TIter nxtSame(same_histo.get());
2075  KVHistogram* kvhisto;
2076  while ((kvhisto = (KVHistogram*)nxtSame())) {
2077  if ((fProfileHisto && kvhisto->IsProfile()) || (!fProfileHisto && kvhisto->IsTH2())) {
2078  DrawHisto(kvhisto->GetHisto());
2079  return;
2080  }
2081  }
2082 
2083  if (fUserBinning) {
2084  if (!DefineUserBinning()) return;
2085  }
2086 
2087  xmin = GetTreeMinimum(Xexpr);
2088  xmax = GetTreeMaximum(Xexpr);
2089  if (fXLeaf->InheritsFrom("TLeaf") &&
2090  (!strcmp(get_leaf_type_name(fXLeaf), "Int_t") || !strcmp(get_leaf_type_name(fXLeaf), "Short_t") || !strcmp(get_leaf_type_name(fXLeaf), "Char_t"))
2091  ) {
2092  xmin -= 0.5;
2093  xmax += 0.5;
2094  nx = xmax - xmin;
2095  }
2096  ymin = GetTreeMinimum(Yexpr);
2097  ymax = GetTreeMaximum(Yexpr);
2098  if (fYLeaf->InheritsFrom("TLeaf") &&
2099  (!strcmp(get_leaf_type_name(fYLeaf), "Int_t") || !strcmp(get_leaf_type_name(fYLeaf), "Short_t") || !strcmp(get_leaf_type_name(fYLeaf), "Char_t"))
2100  ) {
2101  ymin -= 0.5;
2102  ymax += 0.5;
2103  ny = ymax - ymin;
2104  }
2105  if (fUserBinning) {
2106  nx = fNx;
2107  ny = fNy;
2108  xmin = fXmin;
2109  xmax = fXmax;
2110  ymin = fYmin;
2111  ymax = fYmax;
2112  }
2113 
2114  if (!fProfileHisto) histo.Form(">>%s(%d,%f,%f,%d,%f,%f)", name.Data(), nx, xmin, xmax, ny, ymin, ymax);
2115  else {
2116  if (fUserBinning) histo.Form(">>%s(%d,%f,%f)", name.Data(), nx, xmin, xmax);
2117  else histo.Form(">>%s", name.Data());
2118  }
2119  drawexp += histo;
2120  TString ww = "";
2121  if (fUserWeight) ww += fWeight;
2122  Long64_t drawResult;
2123  if (!fProfileHisto) drawResult = fTree->Draw(drawexp, ww.Data(), "goff");
2124  else drawResult = fTree->Draw(drawexp, ww.Data(), "prof,goff");
2125  if (drawResult < 0) {
2126  // Error: problem with Draw, probably bad expression
2127  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
2128  return;
2129  }
2130  TH1* h(nullptr);
2131 #ifdef WITH_PROOF
2132  if (IsPROOFEnabled())
2134  else
2135 #endif
2136  h = (TH1*)gDirectory->Get(name);
2137  h->SetTitle(histotitle);
2138  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
2139  h->SetDirectory(0);
2140  if (h->InheritsFrom("TH1")) {
2141  h->GetXaxis()->SetTitle(fXLeaf->GetTitle());
2142  h->SetLineWidth(2);
2143  }
2144  if (h->InheritsFrom("TH2") || h->InheritsFrom("TProfile")) h->GetYaxis()->SetTitle(fYLeaf->GetTitle());
2145 
2146  AddHisto(h);
2147  fHistoNumber++;
2148  DrawHisto(h);
2149 }
2150 
2151 
2152 
2153 
2155 
2157 {
2158  if ((!fXLeaf->InheritsFrom("TLeaf")) || (!fYLeaf->InheritsFrom("TLeaf")) || (!fZLeaf->InheritsFrom("TLeaf"))) {
2159  Warning("DrawAsDalitz", "Cannot be used with aliases !");
2160  return;
2161  }
2162 
2163  TString Xexpr, Yexpr, Zexpr;
2164  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2165  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2166  Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2167  fLeafExpr.Form("%s:%s:%s", Xexpr.Data(), Yexpr.Data(), Zexpr.Data());
2168 
2172 
2173  if ((!xType.Contains(yType.Data())) || (!yType.Contains(zType.Data()))) {
2174  Warning("DrawAsDalitz", "Leaves %s must have the same type !", fLeafExpr.Data());
2175  return;
2176  }
2177 
2178  Double_t x, y, z;
2179  Double_t var1, var2, var3;
2180  Float_t varf1, varf2, varf3;
2181  Int_t vari1, vari2, vari3;
2182  Short_t vars1, vars2, vars3;
2183  Char_t varc1, varc2, varc3;
2184  x = y = z = 0.;
2185 
2186  if (xType.Contains("Int_t")) {
2187  fTree->SetBranchAddress(Xexpr.Data(), &vari1);
2188  fTree->SetBranchAddress(Yexpr.Data(), &vari2);
2189  fTree->SetBranchAddress(Zexpr.Data(), &vari3);
2190  }
2191  else if (xType.Contains("Short_t")) {
2192  fTree->SetBranchAddress(Xexpr.Data(), &vars1);
2193  fTree->SetBranchAddress(Yexpr.Data(), &vars2);
2194  fTree->SetBranchAddress(Zexpr.Data(), &vars3);
2195  }
2196  else if (xType.Contains("Char_t")) {
2197  fTree->SetBranchAddress(Xexpr.Data(), &varc1);
2198  fTree->SetBranchAddress(Yexpr.Data(), &varc2);
2199  fTree->SetBranchAddress(Zexpr.Data(), &varc3);
2200  }
2201  else if (xType.Contains("Double_t")) {
2202  fTree->SetBranchAddress(Xexpr.Data(), &var1);
2203  fTree->SetBranchAddress(Yexpr.Data(), &var2);
2204  fTree->SetBranchAddress(Zexpr.Data(), &var3);
2205  }
2206  else if (xType.Contains("Float_t")) {
2207  fTree->SetBranchAddress(Xexpr.Data(), &varf1);
2208  fTree->SetBranchAddress(Yexpr.Data(), &varf2);
2209  fTree->SetBranchAddress(Zexpr.Data(), &varf3);
2210  }
2211 
2212  if (fUserBinning) {
2213  if (!DefineUserBinningD()) return;
2214  }
2215 
2216  TString histotitle;
2217  GenerateHistoTitle(histotitle, fLeafExpr, "");
2218 
2219  KVDalitzPlot* h = 0;
2220  if (fUserBinning) h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data(), fOrderedDalitz, fNxD, 0., 1.2, fNyD, 0., 1.2);
2221  else h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data());
2222  fHistoNumber++;
2223 
2224  TEntryList* el = fChain->GetEntryList();
2225  if (el) el->GetEntry(0);
2227 
2228  if (el) nentries = el->GetN();
2229  for (int i = 0; i < nentries; i++) {
2230  Int_t j = i;
2231  if (el) j = el->Next();
2232  fTree->GetEntry(j);
2233  if (xType.Contains("Int_t")) {
2234  x = vari1;
2235  y = vari2;
2236  z = vari3;
2237  }
2238  else if (xType.Contains("Short_t")) {
2239  x = vars1;
2240  y = vars2;
2241  z = vars3;
2242  }
2243  else if (xType.Contains("Char_t")) {
2244  x = varc1;
2245  y = varc2;
2246  z = varc3;
2247  }
2248  else if (xType.Contains("Double_t")) {
2249  x = var1;
2250  y = var2;
2251  z = var3;
2252  }
2253  else if (xType.Contains("Float_t")) {
2254  x = varf1;
2255  y = varf2;
2256  z = varf3;
2257  }
2258  h->FillAsDalitz(x, y, z);
2259  }
2260 
2261  h->SetOption("col");
2262  h->SetDirectory(0);
2263  AddHisto((TH2F*)h);
2264  DrawHisto(h);
2266 
2267 }
2268 
2269 
2270 
2275 
2277 {
2278  // Open dialogue box for user to fill required weight for histo
2279  //
2280  // returns false if Cancel button is pressed
2281 
2282  KVNameValueList params{{"Weight", ""}};
2283  Bool_t cancel_pressed{false};
2284  auto s = new KVNameValueListGUI(GetMainWindow(), &params, &cancel_pressed);
2285  s->DisplayDialog();
2286  // cancel was pressed ?
2287  if (cancel_pressed) return false;
2288  fWeight = params.GetStringValue("Weight");
2289  return true;
2290 }
2291 
2292 
2293 
2296 
2298 {
2299  // Method called when user double-clicks a leaf/alias in list
2300 
2301  if (fUserWeight) {
2302  if (!DefineWeight()) return;
2303  }
2304 
2305  TH1* histo = nullptr;
2306  if (obj->InheritsFrom("TLeaf")) {
2307  TLeaf* leaf = (TLeaf*)fChain->GetListOfLeaves()->FindObject(obj->GetName());//dynamic_cast<TLeaf*>(obj);
2308  TString expr = leaf->GetName();
2309  TString type = leaf->GetTypeName();
2310  // check histo not already in list
2311  TString htit;
2312  if (fUserWeight) GenerateHistoTitle(htit, expr, "", fWeight);
2313  else GenerateHistoTitle(htit, expr, "");
2314  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2315  if (kvhisto) histo = kvhisto->GetHisto();
2316  if (!histo) {
2317  if (type.Contains("Int_t") || type.Contains("Char_t") || type.Contains("Short_t") || type == "Long_t" || type == "Long64_t") {
2318  Int_t xmin = GetTreeMinimum(expr);
2319  Int_t xmax = GetTreeMaximum(expr);
2320  if (type.Contains("Char_t")) {
2321  TString tmp;
2322  tmp.Form("int(%s)", expr.Data());
2323  expr = tmp.Data();
2324  }
2325  histo = MakeIntHisto(expr, "", xmin, xmax, (fUserWeight ? fWeight.Data() : ""));
2326  if (!histo) return;
2327  histo->GetXaxis()->SetTitle(leaf->GetName());
2328  }
2329  else {
2330  histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2331  if (!histo) return;
2332  histo->GetXaxis()->SetTitle(leaf->GetName());
2333  }
2334  if (!histo) return;
2335  }
2336  DrawHisto(histo);
2337  }
2338  else {
2339  TString expr = obj->GetTitle();
2340  // check histo not already in list
2341  TString htit;
2342  GenerateHistoTitle(htit, expr, "", (fUserWeight ? fWeight.Data() : ""));
2343  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2344  if (kvhisto) histo = kvhisto->GetHisto();
2345  if (!histo) histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2346  if (!histo) return;
2347  histo->GetXaxis()->SetTitle(obj->GetTitle());
2348  DrawHisto(histo);
2349  }
2350 }
2351 
2352 
2353 
2356 
2358 {
2359  // Method called when user histo selection changes in GUI histogram list
2360 
2365  if (fSelectedHistos) {
2366  if (fSelectedHistos->GetEntries() > 0) {
2368  if (fSelectedHistos->GetEntries() == 1 && fSelectedHistos->First()->IsA() == TH1F::Class()) {
2369  }
2371  }
2372  }
2373 }
2374 
2375 
2376 
2378 
2380 {
2382 }
2383 
2384 
2385 
2388 
2390 {
2391  // Look for selection in list of selections
2392  return (TEntryList*)fSelections.FindObjectByTitle(selection);
2393 }
2394 
2395 
2397 
2399 {
2400  fPROOFEnabled = yes;
2401  if (yes) {
2402 #ifdef WITH_PROOF
2403  // open new PROOF-lite session
2404  if (!gProof) TProof::Open("");
2405  if (fChain) fChain->SetProof(kTRUE);
2406 #endif
2407  }
2408  else {
2409  if (fChain) fChain->SetProof(kFALSE);
2410  }
2411 }
2412 
2413 
2414 
2416 
2418 {
2419  Info("Save", "Saving analysis %s in file %s", GetTitle(), fSaveAnalysisFileName.Data());
2422 }
2423 
2424 
2425 
2432 
2433 void KVTreeAnalyzer::SaveAs(const char* filename, Option_t*) const
2434 {
2435  // Override TObject::SaveAs
2436  // We need to:
2437  // - (re)create the file
2438  // - do fChain->SetDirectory before writing to disk
2439 
2440  // save current directory
2441  TDirectory* sav = gDirectory;
2442  TDirectory* chsav = (fChain ? fChain->GetDirectory() : nullptr);
2443 
2444  TFile* f = TFile::Open(filename, "recreate");
2445  Write();
2446  if (fChain) { // make sure TChain doesn't get redirected
2447  fChain->SetDirectory(chsav);
2448  }
2449  delete f;
2450 
2451  // back to original directory
2452  sav->cd();
2453 }
2454 
2455 
2456 // void KVTreeAnalyzer::FitGum1()
2457 // {
2458 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2459 // if(!histo) return;
2460 // GDfirst->SetParameters(histo->GetMean(),histo->GetRMS());
2461 // histo->Fit(GDfirst,"EM");
2462 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2463 // if(!stats){
2464 // histo->SetStats(1);
2465 // histo->Draw();
2466 // gPad->Update();
2467 // stats = (TPaveStats*)histo->FindObject("stats");
2468 // }
2469 // if(stats){
2470 // // if canvas's 'no stats' option has been set by user,
2471 // // there will still be no valid stats object,
2472 // // so this test is to avoid the ensuing seg fault
2473 // stats->SetFitFormat("10.9g");
2474 // stats->SetOptFit(111);
2475 // }
2476 // histo->SetOption("e1");
2477 // histo->SetMarkerStyle(24);
2478 // histo->SetMarkerColor(kBlue+2);
2479 // gPad->Modified();gPad->Update();
2480 // SetAnalysisModifiedSinceLastSave(kTRUE);
2481 // }
2482 // void KVTreeAnalyzer::FitGum2()
2483 // {
2484 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2485 // if(!histo) return;
2486 // GDsecond->SetParameters(histo->GetMean(),histo->GetRMS());
2487 // histo->Fit(GDsecond,"EM");
2488 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2489 // if(!stats){
2490 // histo->SetStats(1);
2491 // histo->Draw();
2492 // gPad->Update();
2493 // stats = (TPaveStats*)histo->FindObject("stats");
2494 // }
2495 // if(stats){
2496 // // if canvas's 'no stats' option has been set by user,
2497 // // there will still be no valid stats object,
2498 // // so this test is to avoid the ensuing seg fault
2499 // stats->SetFitFormat("10.9g");
2500 // stats->SetOptFit(111);
2501 // }
2502 // histo->SetOption("e1");
2503 // histo->SetMarkerStyle(24);
2504 // histo->SetMarkerColor(kBlue+2);
2505 // gPad->Modified();gPad->Update();
2506 // SetAnalysisModifiedSinceLastSave(kTRUE);
2507 // }
2508 // void KVTreeAnalyzer::FitGum3()
2509 // {
2510 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2511 // if(!histo) return;
2512 // GDthird->SetParameters(histo->GetMean(),histo->GetRMS());
2513 // histo->Fit(GDthird,"EM");
2514 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2515 // if(!stats){
2516 // histo->SetStats(1);
2517 // histo->Draw();
2518 // gPad->Update();
2519 // stats = (TPaveStats*)histo->FindObject("stats");
2520 // }
2521 // if(stats){
2522 // // if canvas's 'no stats' option has been set by user,
2523 // // there will still be no valid stats object,
2524 // // so this test is to avoid the ensuing seg fault
2525 // stats->SetFitFormat("10.9g");
2526 // stats->SetOptFit(111);
2527 // }
2528 // histo->SetOption("e1");
2529 // histo->SetMarkerStyle(24);
2530 // histo->SetMarkerColor(kBlue+2);
2531 // gPad->Modified();gPad->Update();
2532 // SetAnalysisModifiedSinceLastSave(kTRUE);
2533 // }
2534 // void KVTreeAnalyzer::FitGausGum1()
2535 // {
2536 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2537 // if(!histo) return;
2538 // GausGum1->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2539 // histo->Fit(GausGum1,"EM");
2540 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2541 // if(!stats){
2542 // histo->SetStats(1);
2543 // histo->Draw();
2544 // gPad->Update();
2545 // stats = (TPaveStats*)histo->FindObject("stats");
2546 // }
2547 // if(stats){
2548 // // if canvas's 'no stats' option has been set by user,
2549 // // there will still be no valid stats object,
2550 // // so this test is to avoid the ensuing seg fault
2551 // stats->SetFitFormat("10.9g");
2552 // stats->SetOptFit(111);
2553 // }
2554 // histo->SetOption("e1");
2555 // histo->SetMarkerStyle(24);
2556 // histo->SetMarkerColor(kBlue+2);
2557 // gPad->Modified();gPad->Update();
2558 // SetAnalysisModifiedSinceLastSave(kTRUE);
2559 // }
2560 //
2561 // void KVTreeAnalyzer::FitGausGum2()
2562 // {
2563 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2564 // if(!histo) return;
2565 // GausGum2->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2566 // histo->Fit(GausGum2,"EM");
2567 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2568 // if(!stats){
2569 // histo->SetStats(1);
2570 // histo->Draw();
2571 // gPad->Update();
2572 // stats = (TPaveStats*)histo->FindObject("stats");
2573 // }
2574 // if(stats){
2575 // // if canvas's 'no stats' option has been set by user,
2576 // // there will still be no valid stats object,
2577 // // so this test is to avoid the ensuing seg fault
2578 // stats->SetFitFormat("10.9g");
2579 // stats->SetOptFit(111);
2580 // }
2581 // histo->SetOption("e1");
2582 // histo->SetMarkerStyle(24);
2583 // histo->SetMarkerColor(kBlue+2);
2584 // gPad->Modified();gPad->Update();
2585 // SetAnalysisModifiedSinceLastSave(kTRUE);
2586 // }
2587 //
2588 // void KVTreeAnalyzer::FitGausGum3()
2589 // {
2590 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2591 // if(!histo) return;
2592 // GausGum3->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2593 // histo->Fit(GausGum3,"EM");
2594 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2595 // if(!stats){
2596 // histo->SetStats(1);
2597 // histo->Draw();
2598 // gPad->Update();
2599 // stats = (TPaveStats*)histo->FindObject("stats");
2600 // }
2601 // if(stats){
2602 // // if canvas's 'no stats' option has been set by user,
2603 // // there will still be no valid stats object,
2604 // // so this test is to avoid the ensuing seg fault
2605 // stats->SetFitFormat("10.9g");
2606 // stats->SetOptFit(111);
2607 // }
2608 // histo->SetOption("e1");
2609 // histo->SetMarkerStyle(24);
2610 // histo->SetMarkerColor(kBlue+2);
2611 // gPad->Modified();gPad->Update();
2612 // SetAnalysisModifiedSinceLastSave(kTRUE);
2613 // }
2614 
2615 
2620 
2622 {
2623  // fill and return TList with histos containing the given data
2624  // which may be 1D ("mult", "zmax", etc.) or 2D ("zmax:mult")
2625  // DELETE LIST AFTER USE
2626  TList* hlist = new TList;
2627  TIter next(&fHistolist);
2628 
2629  KVHistogram* h;
2630  while ((h = (KVHistogram*)next())) {
2631 
2632  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr)) hlist->Add(h->GetHisto());
2633  }
2634  return hlist;
2635 }
2636 
2637 
2638 
2642 
2644 {
2645  // fill and return TList with histos using the given selection criteria
2646  // DELETE LIST AFTER USE
2647  TList* hlist = new TList;
2648  TIter next(&fHistolist);
2649 
2650  KVHistogram* h;
2651  while ((h = (KVHistogram*)next())) {
2652 
2653  if (h->IsType("Histo") && !strcmp(h->GetSelection(), expr)) hlist->Add(h->GetHisto());
2654  }
2655  return hlist;
2656 }
2657 
2658 
2659 
2661 
2662 TH1* KVTreeAnalyzer::GetHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2663 {
2664  TIter next(&fHistolist);
2665 
2666  KVHistogram* h;
2667  while ((h = (KVHistogram*)next())) {
2668 
2669  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection)) {
2670  if (strcmp(weight, "")) {
2671  if (!strcmp(h->GetWeight(), weight)) return h->GetHisto();
2672  }
2673  else return h->GetHisto();
2674  }
2675  }
2676  return 0;
2677 }
2678 
2679 
2680 
2682 
2684 {
2685  return (KVHistogram*)fHistolist.FindObjectWithMethod(title, "GetHistoTitle");
2686 }
2687 
2688 
2689 
2691 
2692 void KVTreeAnalyzer::DeleteHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2693 {
2694  TIter next(&fHistolist);
2695 
2696  KVHistogram* h;
2697  while ((h = (KVHistogram*)next())) {
2698 
2699  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection) && !strcmp(h->GetWeight(), weight)) {
2700  fHistolist.Remove(h);
2701  delete h;
2703  }
2704  }
2706 }
2707 
2708 
2709 
2712 
2714 {
2715  // Delete all currently selected histograms
2716  if (fSelectedHistos) {
2717  Int_t nsel = fSelectedHistos->GetEntries();
2718  if (nsel < 1) return;
2719  for (int i = 0; i < nsel; i++) {
2720  TObject* obj = fSelectedHistos->At(i);
2721  fHistolist.Remove(obj);
2722  delete obj;
2724  }
2726  }
2728 }
2729 
2730 
2731 
2736 
2738 {
2739  // Called when G_histo_add button is pressed
2740  // There should be 2 histograms in fSelectedHistos
2741  // We assume that both are of same type and have same binning etc.
2742 
2743  if (fSelectedHistos->GetEntries() != 2) return;
2744  HistoToAdd1 = dynamic_cast<KVHistogram*>(fSelectedHistos->At(0))->GetHisto();
2745  HistoToAdd2 = dynamic_cast<KVHistogram*>(fSelectedHistos->At(1))->GetHisto();
2746  if (HistoToAdd1 && HistoToAdd2) {
2747  Info("AddSelectedHistos", "Adding %s and %s", HistoToAdd1->GetName(), HistoToAdd2->GetName());
2748  TString name = Form("h%d", fHistoNumber);
2749  TString oldname = HistoToAdd1->GetName();
2750  if (oldname.BeginsWith("I")) name.Prepend("I");
2753  Bool_t ok = KVBase::OpenContextMenu("HistoAddition", this);
2754  if (!ok) {
2755  Info("AddSelectedHistos", "Call to context menu not OK");
2756  delete HistoAddResult;
2757  return;
2758  }
2759  if (MethodNotCalled()) {
2760  Info("AddSelectedHistos", "You pressed cancel");
2761  delete HistoAddResult;
2762  return;
2763  }
2764  ++fHistoNumber;
2766  }
2767  else {
2768  Info("AddSelectedHistos", "Only possible for 2 histograms");
2769  }
2770 }
2771 
2772 
2773 
2775 
2777 {
2778  fMethodCalled = kTRUE;
2780 // TODO: it would be nice to distinguish histograms which are the result of
2781 // adding other histograms together. For the moment they appear identical to
2782 // to the first histogram in terms of variables etc. The following attempt
2783 // doesn't work (can't parse the title correctly)
2784 // TString title;
2785 // title.Form("SUMHIST:{%s,%s}",HistoToAdd1->GetTitle(),HistoToAdd2->GetTitle());
2786 // HistoAddResult->SetTitle(title);
2787 }
2788 
2789 
2790 
2791 
2794 
2796 {
2797  // regenerate entry lists for all selections
2798  TList old_lists;
2799  old_lists.AddAll(&fSelections);
2800  fSelections.Clear();
2802  TIter next(&old_lists);
2803  TEntryList* old_el;
2804  SetEntryList(nullptr);
2805  SelectionChanged();
2806  while ((old_el = (TEntryList*)next())) {
2807  cout << "REGENERATING SELECTION : " << old_el->GetTitle() << endl;
2808  MakeSelection(old_el->GetTitle());
2809  ((TEntryList*)fSelections.Last())->SetReapplyCut(old_el->GetReapplyCut());
2811  }
2812  old_lists.Delete();
2813 }
2814 
2815 
2816 
2818 
2820 {
2821  switch (id) {
2822  case MH_OPEN_CHAIN:
2823  OpenChain();
2824  break;
2825  case MH_OPEN_FILE:
2827  break;
2828  case MH_ADD_FRIEND:
2830  break;
2831  case MH_APPLY_ANALYSIS:
2833  break;
2834  case MH_SAVE_FILE:
2836  break;
2837  case MH_SAVE:
2838  Save();
2839  break;
2840  case MH_CLOSE:
2841  delete fMain_histolist;
2842  GUIClosed();
2843  break;
2844  case MH_QUIT:
2845  // check all analyzers need saving
2846  while (fgAnalyzerList->GetEntries() > 1) {
2847  TIter next(fgAnalyzerList);
2849  do {
2850  tan = (KVTreeAnalyzer*)next();
2851  }
2852  while (tan == this);
2853  tan->AnalysisSaveCheck();
2854  delete tan;
2855  }
2857  gROOT->ProcessLine(".q");
2858  break;
2859 
2860  default:
2861  break;
2862  }
2863 }
2864 
2865 
2867 
2869 {
2870  switch (id) {
2871  case SEL_COMB_AND:
2873  break;
2874 
2875  case SEL_COMB_OR:
2877  break;
2878 
2879  case SEL_DELETE:
2880  DeleteSelections();
2881  break;
2882 
2883  case SEL_UPDATE:
2884  UpdateEntryLists();
2885  break;
2886 
2887  case SEL_GEN_CONST_XSEC:
2888  KVBase::OpenContextMenu("GenerateConstantXSecSelections", this);
2889  break;
2890 
2891  default:
2892  break;
2893  }
2894 }
2895 
2896 
2897 
2899 
2901 {
2902  switch (opt) {
2903  case OPT_PROOF:
2906  EnablePROOF(false);
2907  }
2908  else {
2910  EnablePROOF();
2911  }
2912  }
2913 }
2914 
2915 
2916 
2919 
2921 {
2922  // Open a previous analysis session
2923 
2924  static TString dir(".");
2925  const char* filetypes[] = {
2926  "Analysis files", "Analysis*.root",
2927  0, 0
2928  };
2929  TGFileInfo fi;
2930  fi.fFileTypes = filetypes;
2931  fi.fIniDir = StrDup(dir);
2932  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2933  if (fi.fFilename) {
2934  KVTreeAnalyzer* newAnal = this;
2935  if (fTree) newAnal = new KVTreeAnalyzer(kFALSE);
2936  newAnal->OpenAnyFile(fi.fFilename);
2937  }
2938  dir = fi.fIniDir;
2939 }
2940 
2941 
2942 
2944 
2946 {
2947  static TString dir(".");
2948  const char* filetypes[] = {
2949  "ROOT files", "*.root",
2950  0, 0
2951  };
2952  TGFileInfo fi;
2953  fi.fFileTypes = filetypes;
2954  fi.fIniDir = StrDup(dir);
2955  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2956  if (fi.fFilename) {
2958  }
2959  dir = fi.fIniDir;
2960 }
2961 
2962 
2965 
2967 {
2968  // Open a file or files containing TTrees to analyse
2969 
2970  static TString dir(".");
2971  const char* filetypes[] = {
2972  "ROOT files", "*.root*",
2973  0, 0
2974  };
2975  TGFileInfo fi;
2976  fi.fFileTypes = filetypes;
2977  fi.fIniDir = StrDup(dir);
2979  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2980  if (fi.fFileNamesList && fi.fFileNamesList->GetEntries()) {
2981 
2982  // look in first file to find first TTree and use its name/title
2983  TString theTreeName, theTreeTitle;
2985  KVUnownedList keys;
2986  keys.AddAll(file->GetListOfKeys());
2987  // Get list of trees in file
2988  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
2989  if (trees->GetEntries()) {
2990  theTreeName = trees->First()->GetName();
2991  theTreeTitle = trees->First()->GetTitle();
2992  }
2993  if (theTreeName != "") {
2994  // if analysis already en cours, open new GUI
2995  KVTreeAnalyzer* newAnal = this;
2996  if (fTree) newAnal = new KVTreeAnalyzer(kFALSE);
2997  newAnal->OpenChain(theTreeName, theTreeTitle, fi.fFileNamesList);
2998  if (fi.fFileNamesList->GetEntries() == 1) {
2999  // if a single file is selected, look to see if any histograms are in it
3000  newAnal->GetHistosFromFile(file, keys);
3001  }
3002  }
3003  }
3004  dir = fi.fIniDir;
3005 }
3006 
3007 
3008 
3010 
3012 {
3013  static TString dir(".");
3014  const char* filetypes[] = {
3015  "ROOT files", "*.root",
3016  0, 0
3017  };
3018  TGFileInfo fi;
3019  fi.fFileTypes = filetypes;
3020  fi.fIniDir = StrDup(dir);
3021  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3022  if (fi.fFilename) {
3024  }
3025  dir = fi.fIniDir;
3026 }
3027 
3028 
3029 
3031 
3033 {
3034  const char* filetypes[] = {
3035  "Analysis files", "Analysis*.root",
3036  0, 0
3037  };
3038  TGFileInfo fi;
3039  fi.fFileTypes = filetypes;
3042  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDSave, &fi);
3043  if (fi.fFilename) {
3044  //if no ".xxx" ending given, we add ".root"
3045  TString filenam(fi.fFilename);
3046  if (!filenam.Contains('.'))
3047  filenam += ".root";
3048  // update name of file to autosave analysis in
3049  fSaveAnalysisFileName = filenam;
3050  Save();
3051  }
3053 }
3054 
3055 
3056 
3058 
3060 {
3061  TIter next(&keys);
3062  TKey* akey;
3063  while ((akey = (TKey*)next())) {
3064  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3065  if (!fHistolist.FindObject(akey->GetName())) {
3066  TH1* h = (TH1*)file->Get(akey->GetName());
3067  h->SetDirectory(0);
3068  fHistolist.Add(new KVHistogram(h));
3069  }
3070  }
3071  }
3073 }
3074 
3075 
3076 
3079 
3080 void KVTreeAnalyzer::OpenSingleFile(TFile* file)
3081 {
3082  // Open TTree in file (as a TChain) and import any histograms found in file
3083 
3084  fHistolist.Clear();
3085  KVUnownedList keys;
3086  keys.AddAll(file->GetListOfKeys());
3087  // Get list of trees in file
3088  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3089  if (trees->GetEntries()) {
3090  // Get name of first tree
3091  TString aTreeName = trees->First()->GetName();
3092  TString aFileName = file->GetName();
3093  TList fileList;
3094  TNamed ff(aFileName.Data(), "File Name");
3095  fileList.Add(&ff);
3096  OpenChain(aTreeName, trees->First()->GetTitle(), &fileList);
3097  }
3098  GetHistosFromFile(file, keys);
3099 }
3100 
3101 
3102 
3106 
3108 {
3109  // assuming filepath is the URL of a ROOT file containing a previously-saved analysis, open it and
3110  // open the KVTreeAnalyzer object stored in it
3111 
3113 
3114  TFile* file = TFile::Open(filepath);
3115  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3116  if (kvta) {
3117  ReadFromFile(file);
3118  }
3119  else {
3120  OpenSingleFile(file);
3121  }
3123 }
3124 
3125 
3126 
3131 
3132 void KVTreeAnalyzer::OpenChain(const TString& treename, const TString& treetitle, const TSeqCollection* files)
3133 {
3134  // Open a TChain for analysis
3135  // treename/title is the name/title of the TTree :)
3136  // files is a list of objects with the names of the files in the chain
3137 
3138  fChain = new TChain(treename, treetitle);
3139  TIter nxt(files);
3140  TObject* o;
3141  while ((o = nxt())) fChain->Add(o->GetName());
3142  fChain->SetDirectory(0);
3143  SetTree(fChain);
3144  fHistolist.Clear();
3145  fSelections.Clear();
3146  fAliasList.Clear();
3147  fHistoNumber = 1;
3148  fSelectionNumber = 1;
3149  fAliasNumber = 1;
3150  fSameColorIndex = 0;
3151  fSelectedSelections = 0;
3152  fSelectedLeaves = 0;
3153  fSelectedHistos = 0;
3157  FillLeafList();
3159 }
3160 
3161 
3162 
3165 
3167 {
3168  // Generate all user aliases in list which are not already defined
3169 
3170  if (list->GetEntries()) {
3171  TIter next(list);
3172  TObject* o;
3173  while ((o = next())) {
3174  if (!GetAlias(o->GetTitle())) {
3175  Info("GenerateAllAliases", "Adding alias %s to leaflist", o->GetTitle());
3177  GenerateAlias();
3178  }
3179  }
3180  }
3181 }
3182 
3183 
3184 
3193 
3195 {
3196  // assuming filepath is the URL of a ROOT file, open it and,
3197  // if no KVTreeAnalyzer object is found, open first TTree in file
3198  // and apply all selections and generate all histograms which
3199  // were made for this analysis.
3200  // Any histograms in the file are added to the list of histograms.
3201  // If filepath contains an existing analysis, we add to it any
3202  // histograms/selections/aliases which are not defined
3203 
3204  TFile* file = TFile::Open(filepath);
3205  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3206  if (kvta) {
3207  // open existing analysis, add any missing histos/selections/aliases
3208  delete file;
3209  KVTreeAnalyzer* applyAnal = OpenFile(filepath);
3210  applyAnal->GenerateAllSelections(&fSelections);
3211  applyAnal->GenerateAllHistograms(&fHistolist);
3212  applyAnal->GenerateAllAliases(&fAliasList);
3213  return;
3214  }
3215  else {
3216  delete file;
3217  KVTreeAnalyzer* applyAnal = new KVTreeAnalyzer(kFALSE);
3218  applyAnal->OpenAnyFile(filepath);
3219  applyAnal->GenerateAllSelections(&fSelections);
3220  applyAnal->GenerateAllHistograms(&fHistolist);
3221  // make sure no selection is left active without being displayed
3222  applyAnal->SetEntryList(nullptr);
3223  applyAnal->G_selection_status->SetText("CURRENT SELECTION:", 0);
3224  applyAnal->GenerateAllAliases(&fAliasList);
3225  }
3226 }
3227 
3228 
3229 
3231 
3232 void KVTreeAnalyzer::SetAlias(const Char_t* name, const Char_t* expr)
3233 {
3234  TString exp = expr;
3235  exp.ReplaceAll("d2r", "TMath::DegToRad()");
3236  exp.ReplaceAll("r2d", "TMath::RadToDeg()");
3237  fAliasList.Add(new TNamed(name, exp.Data()));
3239 }
3240 
3241 
3242 
3244 
3245 static const char* gSaveAsTypes[] = { "PostScript", "*.ps",
3246  "Encapsulated PostScript", "*.eps",
3247  "PDF", "*.pdf",
3248  "SVG", "*.svg",
3249  "TeX", "*.tex",
3250  "GIF", "*.gif",
3251  "ROOT files", "*.root",
3252  "XML", "*.xml",
3253  "PNG", "*.png",
3254  "XPM", "*.xpm",
3255  "JPEG", "*.jpg",
3256  "TIFF", "*.tiff",
3257  "XCF", "*.xcf",
3258  0, 0
3259  };
3260 
3261 
3262 
3267 
3269 {
3270  // Open file dialog box for user to choose directory and
3271  // image file-type for generating picture files of all
3272  // histos as they are drawn
3273 
3274  Info("SetUpHistoAutoSave", "Select image filetype and directory");
3275  TString workdir = gSystem->WorkingDirectory();
3276  static TString dir(".");
3277  static Int_t typeidx = 0;
3278  static Bool_t overwr = kFALSE;
3279  TGFileInfo fi;
3280  fi.fFileTypes = gSaveAsTypes;
3281  fi.fIniDir = StrDup(dir);
3282  fi.fFileTypeIdx = typeidx;
3283  fi.fOverwrite = overwr;
3284  new KVFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kKVFDDirectory, &fi);
3285  gSystem->ChangeDirectory(workdir.Data());
3286  TString ft = fi.fFileTypes[fi.fFileTypeIdx + 1];
3287  dir = fi.fIniDir;
3288  typeidx = fi.fFileTypeIdx;
3289  overwr = fi.fOverwrite;
3290  fAutoSaveDir = dir.Data();
3291  fAutoSaveType = ft(1, ft.Length()).Data();
3292  Info("SetUpHistoAutoSave", "file-type:%s directory:%s", fAutoSaveType.Data(), fAutoSaveDir.Data());
3293 }
3294 
3295 
3296 
3300 
3302 {
3303  // Save currently displayed histo as an image file
3304  // If 'same' checkbox is ticked, we use the same filename as used for the first histogram
3305 
3306  static TString lastFilename = "";
3307 
3308  if (fDrawSame) {
3309  gPad->SaveAs(lastFilename);
3310  return;
3311  }
3312  TString title = h->GetTitle();
3313  title.ReplaceAll(" ", "_");
3314  title.ReplaceAll("/", "#");
3315  title.ReplaceAll("*", "x");
3316  title.ReplaceAll("$", "#");
3317  title.ReplaceAll("(", "[");
3318  title.ReplaceAll(")", "]");
3319  title.Append(fAutoSaveType);
3320  title.Prepend("/");
3321  title.Prepend(fAutoSaveDir);
3322  Info("AutoSaveHisto", "Saved as: %s", title.Data());
3323  gPad->SaveAs(title);
3324  lastFilename = title;
3325 }
3326 
3327 
3328 
3332 
3334 {
3335  // We take the title of every object in 'list' and generate the corresponding selection
3336  // if it does not already exist
3337 
3338  TIter nextSel(list);
3339  TObject* sel;
3340  while ((sel = nextSel())) {
3341  if (!GetSelection(sel->GetTitle())) {
3342  Info("GenerateAllSelections", "Generating selection: %s", sel->GetTitle());
3343  MakeSelection(sel->GetTitle());
3344  }
3345  }
3346 }
3347 
3348 
3349 
3353 
3355 {
3356  // For every histogram in the list, we generate histograms with the same binning for
3357  // the same expression, selection and weight if they don't already exist
3358 
3359  TIter nextHist(list);
3360  KVHistogram* obj;
3361  TH1* hist;
3362  while ((obj = (KVHistogram*)nextHist())) {
3363  if (!obj->IsType("Cut")) {
3364  hist = obj->GetHisto();
3365  if (GetHistoByTitle(hist->GetTitle())) continue;
3366  TString exp = obj->GetExpression();
3367  TString sel = obj->GetSelection();
3368  TString weight = obj->GetWeight();
3369  if (weight == "1") weight = "";
3370  // set selection
3371  Info("GenerateAllHistograms", "Generating histogram: %s", hist->GetTitle());
3372  SetSelection(sel);
3373  RemakeHisto(hist, exp, weight);
3374  }
3375  }
3376 }
3377 
3378 
3379 
3386 
3388 {
3389  // Read serialized object from file
3390  // For versions < 4, fHistolist contained TH* or TCutG objects:
3391  // we convert to a list of KVHistogram objects.
3392  // Flag will be set to say analysis needs saving.
3393  // Reparse all histogram expressions and selections in case they were not saved correctly.
3394 
3395  UInt_t R__s, R__c;
3396  if (R__b.IsReading()) {
3397  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3398  R__b.ReadClassBuffer(KVTreeAnalyzer::Class(), this, R__v, R__s, R__c);
3399  if (R__v < 5) {
3400  // no fChain pointer member before v5
3401  ReconnectTree();
3402  }
3403  if (fChain && fTree != fChain) SetTree(fChain);
3404  if (fChain) {
3406  Info("Streamer", "Checking friends");
3407  // check friends are TChains, not TTrees & they have valid pointers
3408  TFriendElement* fe;
3409  TIter nxt(fChain->GetListOfFriends());
3410  KVNumberList toRemove;
3411  KVNameValueList infos;
3412  int idx = 0;
3413  while ((fe = (TFriendElement*)nxt())) {
3414  if (!fe->GetTree() || (fe->GetTree() && !fe->GetTree()->InheritsFrom("TChain"))) {
3415  Info("Streamer", "Found friend to convert to TChain");
3416  toRemove.Add(idx);
3417  infos.SetValue(Form("treeName%d", idx), fe->GetTreeName());
3418  if (!fe->GetFile()) {
3419  Info("Streamer", "Choose file containg friend tree %s", fe->GetTreeName());
3420  static TString dir(".");
3421  const char* filetypes[] = {
3422  "ROOT files", "*.root",
3423  0, 0
3424  };
3425  TGFileInfo fi;
3426  fi.fFileTypes = filetypes;
3427  fi.fIniDir = StrDup(dir);
3428  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3429  if (fi.fFilename) {
3430  infos.SetValue(Form("fileName%d", idx), fi.fFilename);
3431  }
3432  dir = fi.fIniDir;
3433  }
3434  else
3435  infos.SetValue(Form("fileName%d", idx), fe->GetFile()->GetName());
3436  }
3437  ++idx;
3438  }
3439  if (toRemove.GetEntries()) {
3440  Info("Streamer", "Removing TTree friends");
3441  toRemove.Begin();
3442  while (!toRemove.End()) {
3443  fChain->RemoveFriend(fChain->GetFriend(infos.GetStringValue(Form("treeName%d", toRemove.Next()))));
3444  }
3445  toRemove.Begin();
3446  Info("Streamer", "Adding friends as TChains");
3447  while (!toRemove.End()) {
3448  idx = toRemove.Next();
3449  TChain* friendChain = new TChain(infos.GetStringValue(Form("treeName%d", idx)));
3450  friendChain->Add(infos.GetStringValue(Form("fileName%d", idx)));
3451  fChain->AddFriend(friendChain);
3452  }
3453  }
3454  }
3455  }
3456  if (R__v < 4) {
3457  //Info("Streamer","Converting old histo list");
3458  // convert fHistolist
3459  if (fHistolist.GetEntries()) {
3460  TList tmp;
3461  tmp.AddAll(&fHistolist);
3462  //Info("Streamer","List of histos to import:");
3463  //tmp.ls();
3464  fHistolist.SetOwner(kFALSE);
3465  fHistolist.Clear();
3466  fHistolist.SetOwner(kTRUE);
3467  TNamed* obj;
3468  TIter next(&tmp);
3469  while ((obj = (TNamed*)next())) {
3470  if (obj->InheritsFrom("TCutG"))
3471  fHistolist.Add(new KVHistogram(dynamic_cast<TCutG*>(obj)));
3472  else if (obj->InheritsFrom("TH1"))
3473  fHistolist.Add(new KVHistogram(dynamic_cast<TH1*>(obj)));
3474  }
3475  //Info("Streamer","New histolist:");
3476  fHistolist.ls();
3478  }
3479  }
3480  if (fHistolist.GetEntries()) {
3481  TIter next(&fHistolist);
3482  KVHistogram* h;
3483  while ((h = (KVHistogram*)next())) {
3484  if (h->IsType("Histo")) h->ParseExpressionAndSelection();
3485  }
3486  }
3487  }
3488  else {
3490  }
3491 }
3492 
3493 
3494 
3499 
3501 {
3502  // assuming filepath is the URL of a ROOT file, open it and
3503  // add the first TTree found in file as a friend of the current TTree
3504  // Any histograms in the file are added to the list of histograms
3505 
3506  TFile* file = TFile::Open(filepath);
3507  KVList keys(0);
3508  keys.AddAll(file->GetListOfKeys());
3509  // Get list of trees in file
3510  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3511  if (trees->GetEntries()) {
3512  // Get name of first tree
3513  TString aTreeName = trees->First()->GetName();
3514  TChain* t = new TChain(aTreeName);
3515  t->Add(filepath);
3516  fChain->AddFriend(t);
3517  FillLeafList();
3518  }
3519  TIter next(&keys);
3520  TKey* akey;
3521  while ((akey = (TKey*)next())) {
3522  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3523  if (!fHistolist.FindObject(akey->GetName())) {
3524  TH1* h = (TH1*)file->Get(akey->GetName());
3525  h->SetDirectory(0);
3526  fHistolist.Add(new KVHistogram(h));
3527  }
3528  }
3529  }
3531 }
3532 
3533 
3534 
3535 
3536 
3537 
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
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
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)