KaliVeda
Toolkit for HIC analysis
KVTreeAnalyzer.cpp
1 //Created by KVClassFactory on Fri Apr 13 12:31:16 2012
2 //Author: John Frankland
3 
4 #include "KVTreeAnalyzer.h"
5 #include "TString.h"
6 #include "TDirectory.h"
7 #include "TSystem.h"
8 #include "TEntryList.h"
9 #include "Riostream.h"
10 #include "KVCanvas.h"
11 #include "TCutG.h"
12 #include "TLeaf.h"
13 #include "TPaveStats.h"
14 #include "TSystem.h"
15 #include "TPad.h"
16 #include "TKey.h"
17 #include "TROOT.h"
18 #include "TGMsgBox.h"
19 #include "KVFileDialog.h"
20 #include "KVDalitzPlot.h"
21 #include "TEnv.h"
22 #include "TColor.h"
23 #include <KVHistogram.h>
24 #include <TChain.h>
25 #include "TFriendElement.h"
26 #include <TTree.h>
27 #include "KVNameValueListGUI.h"
28 #ifdef WITH_PROOF
29 #include "TProof.h"
30 #endif
31 using namespace std;
32 
34 
35 
36 
37 /* colours used for displaying several 1-D spectra on same plot */
38 
39 
41 #define MAX_COLOR_INDEX 5
42 Int_t my_color_array[] = {
43  kBlue + 2,
44  kRed + 2,
45  kGreen + 3,
46  kCyan - 2,
47  kOrange + 7,
48  kViolet + 2
49 };
50 
51 
52 KVTreeAnalyzer* gTreeAnalyzer = 0x0;
53 
55 
56 
59 
61 {
62  // Default initialization
63 
64  gTreeAnalyzer = this;
65  fgAnalyzerList->Add(this);
66  fDeletedByGUIClose = kFALSE;
67 
69  fMain_histolist = 0;
70  fMain_leaflist = 0;
71  fMain_selectionlist = 0;
72  fMenuFile = 0;
73  SetAnalysisModifiedSinceLastSave(kFALSE);
74  fAnalysisSaveDir = ".";
75  fPROOFEnabled = false;
76 
77  fDrawSame = fApplySelection = fProfileHisto = kFALSE;
78  fDrawLog = gEnv->GetValue("KVTreeAnalyzer.LogScale", kFALSE);
79  fUserBinning = gEnv->GetValue("KVTreeAnalyzer.UserBinning", kFALSE);
80  fUserWeight = gEnv->GetValue("KVTreeAnalyzer.UserWeight", kFALSE);
81  fNewCanvas = gEnv->GetValue("KVTreeAnalyzer.NewCanvas", kFALSE);
82  fNormHisto = gEnv->GetValue("KVTreeAnalyzer.NormalizeIntegral", kFALSE);
83  fNormHistoEvents = gEnv->GetValue("KVTreeAnalyzer.NormalizeEvents", kFALSE);
84  fStatsHisto = gEnv->GetValue("KVTreeAnalyzer.Stats", kFALSE);
85  fAutoSaveHisto = kFALSE;
86  fSameColorIndex = 0;
87  fSelectedLeaves = 0;
88 
89  fNx = fNy = 500;
90  fXmin = fXmax = fYmin = fYmax = -1.;
91  fWeight = "1./(abs(vper))";
92 
93  fNxF = 200;
94  fXminF = fXmaxF = -1.;
95 
96  fNxD = fNyD = 120;
97  fOrderedDalitz = false;
98 }
99 
100 
101 
106 
108  : TNamed("KVTreeAnalyzer", "KVTreeAnalyzer"), fTree(0), fChain(0), fSelections(kTRUE), fHistoNumber(1), fSelectionNumber(1), fAliasNumber(1), fNoGui(nogui)
109 {
110  // Default constructor - used when loading from a file.
111  // The 'nogui' option (default=kTRUE) controls whether or not to
112  // launch the graphical interface
113 
114  init();
115  OpenGUI();
116 }
117 
118 
119 
120 
125 
127  : TNamed("KVTreeAnalyzer", t->GetTitle()), fTree(0), fChain(0), fSelections(kTRUE), fHistoNumber(1), fSelectionNumber(1), fAliasNumber(1), fNoGui(nogui)
128 {
129  // Initialize analyzer for a given TTree.
130  // (in fact we re-open the tree using a TChain)
131  // If 'nogui' option (default=kFALSE) is kTRUE we do not launch the graphical interface.
132 
133  init();
134  OpenGUI();
135  KVList fl;
136  fl.Add(new TNamed(t->GetCurrentFile()->GetName(), t->GetCurrentFile()->GetName()));
137  OpenChain(t->GetName(), t->GetTitle(), &fl);
138 }
139 
140 
141 
144 
146 {
147  // Destructor
149  if (gTreeAnalyzer == this) gTreeAnalyzer = 0x0;
150  fgAnalyzerList->Remove(this);
151 }
152 
153 
154 
155 
163 
165 {
166  // This method copies the current state of 'this' object into 'obj'
167  // You should add here any member variables, for example:
168  // (supposing a member variable KVTreeAnalyzer::fToto)
169  // CastedObj.fToto = fToto;
170  // or
171  // CastedObj.SetToto( GetToto() );
172 
173  TNamed::Copy(obj);
174  KVTreeAnalyzer& CastedObj = (KVTreeAnalyzer&)obj;
175  fSelections.Copy(CastedObj.fSelections);// list of TEntryList user selections
176  fHistolist.Copy(CastedObj.fHistolist);//list of generated histograms
177  CastedObj.fTreeName = fTreeName;//name of analyzed TTree
178  CastedObj.fTreeFileName = fTreeFileName;//name of file containing analyzed TTree
179  CastedObj.fHistoNumber = fHistoNumber; //used for automatic naming of histograms
180  CastedObj.fSelectionNumber = fSelectionNumber; //used for automatic naming of selections
181  CastedObj.fAliasNumber = fAliasNumber; //used for automatic naming of TTree aliases
182  fAliasList.Copy(CastedObj.fAliasList);//list of TTree aliases
184  CastedObj.fChain = fChain;
185  CastedObj.SetTree(fChain);
186 }
187 
188 
189 
207 
208 void KVTreeAnalyzer::GenerateHistoTitle(TString& title, const Char_t* expr, const Char_t* selection, const Char_t* weight)
209 {
210  // PRIVATE utility method
211  // Encodes the histogram title for the desired expression and an optional selection.
212  // The expression and selection should be valid TTreeFormula strings
213  // (i.e. they use TTree leaves and/or alias names)
214  // If there is already an active selection (TEntryList set on TTree)
215  // then the corresponding selection expression will also be included in the title.
216  // The format of the resulting title string is one of the following:
217  //
218  // "expr1[:expr2]"
219  // "expr1[:expr2] {selection}"
220  // "expr1[:expr2] {active selection}"
221  // "expr1[:expr2] {(active selection) && (selection)}"
222  //
223  // If histogram is weighted, the weight is added such as:
224  //
225  // "expr1:expr2 [weight] {active selection}"
226 
227 
228  TString _selection(selection);
229  TString _elist;
230  if (fChain->GetEntryList()) _elist = fChain->GetEntryList()->GetTitle();
231  if (strcmp(weight, "")) {
232  if (_selection != "" && _elist != "")
233  title.Form("%s [%s] {(%s) && (%s)}", expr, weight, _elist.Data(), selection);
234  else if (_selection != "")
235  title.Form("%s [%s] {%s}", expr, weight, selection);
236  else if (_elist != "")
237  title.Form("%s [%s] {%s}", expr, weight, _elist.Data());
238  else
239  title.Form("%s [%s]", expr, weight);
240  }
241  else {
242  if (_selection != "" && _elist != "")
243  title.Form("%s {(%s) && (%s)}", expr, _elist.Data(), selection);
244  else if (_selection != "")
245  title.Form("%s {%s}", expr, selection);
246  else if (_elist != "")
247  title.Form("%s {%s}", expr, _elist.Data());
248  else
249  title.Form("%s", expr);
250  }
251 }
252 
253 
254 
271 
272 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)
273 {
274  // Create and fill a new histogram with the desired expression (expr="expr1[:expr2]" etc.)
275  // with the given selection (selection="" if no selection required).
276  // Any currently active selection (TEntryList set on TTree) will also be applied.
277  // The new histogram is not drawn but added to the internal list of histograms
278  // (see method AddHisto).
279  //
280  // Histograms are automatically named 'h1', 'h2', etc. in order of creation.
281  // Histogram title is generated with method GenerateHistoTitle.
282  // Number of bins on X (and Y for a 2-D spectrum) are given. Axis limits are
283  // automatically adjusted to data unless given.
284  //
285  // For 2-D spectra the initial drawing option is set to "COL"
286  //
287  // If normalisation of spectra is required (fNormHisto = kTRUE) the histogram
288  // bin contents are divided by the integral (sum of weights).
289 
290  TString name;
291  name.Form("h%d", fHistoNumber);
292  TString drawexp(expr), histo, histotitle;
293  if (strcmp(weight, "")) GenerateHistoTitle(histotitle, expr, selection, weight);
294  else GenerateHistoTitle(histotitle, expr, selection);
295  if ((!nY) && (fUserBinning)) {
296  if (!DefineUserBinning1F()) return nullptr;
297  }
298 
299  TString Selection;
300  if (strcmp(weight, "")) {
301  if (strcmp(selection, "")) Selection.Form("(%s)&&(%s)", selection, weight);
302  else Selection = weight;
303  }
304  else
305  Selection = selection;
306  if (nY) histo.Form(">>%s(%d,%f,%f,%d,%f,%f)", name.Data(), nX, xmin, xmax, nY, ymin, ymax);
307  else histo.Form(">>%s(%d,%lf,%lf)", name.Data(), (fUserBinning ? fNxF : nX), (fUserBinning ? fXminF : xmin), (fUserBinning ? fXmaxF : xmax));
308 
309  /*if (!fProfileHisto)*/ drawexp += histo;
310  Long64_t drawResult;
311  if (fProfileHisto) drawResult = fTree->Draw(drawexp, Selection, "prof,goff");// fTree->Draw(Form("%s>>%s", drawexp.Data(), name.Data()), Selection, "prof,goff");
312  else drawResult = fTree->Draw(drawexp, Selection, "goff");
313  if (drawResult < 0) {
314  // Error with Draw: probably a bad expression
315  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
316  return nullptr;
317  }
318  TH1* h;
319 #ifdef WITH_PROOF
320  if (IsPROOFEnabled())
322  else
323 #endif
324  h = (TH1*)gDirectory->Get(name);
325  h->SetTitle(histotitle);
326  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
327  h->SetDirectory(0);
328  AddHisto(h);
329  fHistoNumber++;
330  if (!fProfileHisto) {
331  if (fNormHisto || fNormHistoEvents) {
332  h->Sumw2();
333  if (fNormHisto) {
334  h->Scale(1. / h->Integral("width"));
335  }
336  else {
338  }
339  }
340  }
341  return h;
342 }
343 
344 
345 
352 
353 TH1* KVTreeAnalyzer::MakeIntHisto(const Char_t* expr, const Char_t* selection, Int_t Xmin, Int_t Xmax, const Char_t* weight)
354 {
355  // Like MakeHisto but only used for 1-D spectra of integer variables.
356  // The number of bins is Xmax-Xmin+1 and bins are defined over [x-0.5,x+0.5]
357  // for all values of x.
358  //
359  // Histograms are automatically named 'Ih1', 'Ih2', etc. in order of creation.
360 
361  TString name;
362  name.Form("Ih%d", fHistoNumber);
363  TString drawexp(expr), histo, histotitle;
364  if (strcmp(weight, "")) GenerateHistoTitle(histotitle, expr, selection, weight);
365  else GenerateHistoTitle(histotitle, expr, selection);
366 
367  if (fUserBinning) {
368  if (!DefineUserBinning1F()) return nullptr;
369  }
370 
371  histo.Form(">>%s(%d,%f,%f)", name.Data(), (fUserBinning ? fNxF : (Xmax - Xmin) + 1),
372  (fUserBinning ? fXminF : Xmin - 0.5), (fUserBinning ? fXmaxF : Xmax + 0.5));
373  drawexp += histo;
374  TString Selection;
375  if (strcmp(weight, "")) {
376  if (strcmp(selection, "")) Selection.Form("(%s)&&(%s)", selection, weight);
377  else Selection = weight;
378  }
379  else
380  Selection = selection;
381  Long64_t drawResult = fTree->Draw(drawexp, Selection, "goff");
382  if (drawResult < 0) {
383  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
384  return nullptr;
385  }
386  TH1* h;
387 #ifdef WITH_PROOF
388  if (IsPROOFEnabled())
390  else
391 #endif
392  h = (TH1*)gDirectory->Get(name);
393  h->SetTitle(histotitle);
394  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
395  h->SetDirectory(0);
396 
397  AddHisto(h);
398  fHistoNumber++;
399  if (fNormHisto || fNormHistoEvents) {
400  h->Sumw2();
401  if (fNormHisto) {
402  h->Scale(1. / h->Integral("width"));
403  }
404  else {
406  }
407  }
408  return h;
409 }
410 
411 
412 
415 
417 {
418  // Return histogram with given name
419 
421  if (h->IsType("Histo")) return h->GetHisto();
422  return NULL;
423 }
424 
425 
426 
441 
443 {
444  // Generate a new user-selection (TEntryList) of events in the TTree
445  // according to the given selection expression (valid TTreeFormula expression
446  // using TTree leaf and/or alias names).
447  // The new selection is not applied immediately but added to the internal
448  // list of selections (see method AddSelection).
449  //
450  // If there is already an active selection (TEntryList set on TTree)
451  // this will generate the composite selection, {(active selection) && (selection)}.
452  // The selection's title will then be in the following format:
453  //
454  // "[(active selection) && ](selection)"
455  //
456  // TEntryList objects are automatically named 'el1', 'el2', etc. in order of creation.
457 
458  TObject* tmpObj = gROOT->FindObject(selection);
459  if (tmpObj) {
460  if (tmpObj->InheritsFrom("TCutG")) {
461  TCutG* cut = (TCutG*) tmpObj;
462  cut->SetTitle(cut->GetName());
463  AddCut(cut);
464  }
465  }
466 
467  TString name;
468  name.Form("el%d", fSelectionNumber);
469  TString drawexp(name.Data());
470  drawexp.Prepend(">>");
473  if (fChain->Draw(drawexp, selection, "entrylist") < 0) {
474  new TGMsgBox(gClient->GetRoot(), 0, "Warning", "Mistake in your new selection!", kMBIconExclamation, kMBClose);
475  return kFALSE;
476  }
478  TEntryList* el;
479 #ifdef WITH_PROOF
482  else
483 #endif
484  el = (TEntryList*)gDirectory->Get(name);
485  el->SetTitle(selection);//needed with PROOF
486  if (fChain->GetEntryList()) {
487  TString _elist = fChain->GetEntryList()->GetTitle();
488  TString title;
489  title.Form("(%s) && (%s)", _elist.Data(), selection);
490  el->SetTitle(title);
491  }
493  AddSelection(el);
495  return kTRUE;
496 }
497 
498 
499 
507 
509 {
510  // Method called when a selection is double-clicked in the GUI list.
511  // The required selection is passed as argument (address of TEntryList object)
512  // and becomes the currently active selection (TEntryList set on TTree).
513  // If the requested selection was already active, it is deactivated
514  // (remove TEntryList from TTree).
515  // The 'CURRENT SELECTION' message in the GUI status bar is updated.
516 
517  if (!obj->InheritsFrom("TEntryList")) return;
518  TEntryList* el = dynamic_cast<TEntryList*>(obj);
519  if (fChain->GetEntryList() == el) {
520  SetEntryList(nullptr);
521  G_selection_status->SetText("CURRENT SELECTION:", 0);
522  return;
523  }
524  SetEntryList(el);
525  G_selection_status->SetText(Form("CURRENT SELECTION: %s (%lld)", el->GetTitle(), el->GetN()), 0);
526 }
527 
528 
529 
532 
534 {
535  // Print the currently active selection (TEntryList set on TTree).
536 
537  TString tmp;
538  if (fChain->GetEntryList()) tmp = fChain->GetEntryList()->GetTitle();
539  else tmp = "";
540  if (tmp != "") cout << "CURRENT SELECTION : " << tmp << endl;
541 }
542 
543 
544 
548 
550 {
551  // Return number of entries (events) in the currently active selection,
552  // or the number of entries in the analysed TTree/TChain if no selection active
553 
554  if (fChain->GetEntryList()) return fChain->GetEntryList()->GetN();
555  return fChain->GetEntries();
556 }
557 
558 
559 
563 
565 {
566  // Fills the GUI list with the names of all leaves in the TTree
567  // and any friend TTrees and all aliases defined by the user
568 
569  TList stuff;
570  if (fTree) {
571  // clone list of leaves
572  fLeafList.Clear();
574  // when using a split object to fill the tree
575  // there is a redundant leaf/branch corresponding to the object itself
576  // more precisely there will be a TLeafElement in the list of leaves
577  // and a TBranchElement in the list of branches with the same name
578  //
579  // however the same applies to a simple unsplit object (such as using a TString to store
580  // strings). as the latter is probably far more common than the former (who creates trees
581  // with split objects in them these days???), I comment out the check which stopped such
582  // leaves appearing in the GUI (they are perfectly usable).
583  TIter next(clones);
584  TObject* o;
585  while ((o = next())) {
586 // if (o->InheritsFrom("TLeafElement")
587 // && fTree->GetListOfBranches()->FindObject(o->GetName())
588 // && fTree->GetListOfBranches()->FindObject(o->GetName())->InheritsFrom("TBranchElement"))
589 // continue;
590  fLeafList.Add(o);
591  }
592  delete clones;
593 
594  stuff.AddAll(&fLeafList);
595  stuff.AddAll(fTree->GetListOfAliases());
596  if (fTree->GetListOfFriends()) {
598  TFriendElement* fel;
599  while ((fel = (TFriendElement*)it())) {
600  stuff.AddAll(fel->GetTree()->GetListOfLeaves());
601  stuff.AddAll(fel->GetTree()->GetListOfAliases());
602  }
603  }
604  }
605  stuff.AddAll(&fAliasList);
606  G_leaflist->Display(&stuff);
607 }
608 
609 
610 
614 
616 {
617  // if analysis has been modified since last save,
618  // open an invite to ask if user wants to save with current default filename
619 
620  if (!fAnalysisModifiedSinceLastSave) return;
621 
622  if (fNoGui) {
623  // text-only interface
624  cout << "Analysis " << GetTitle() << " has been modified. Save before continuing? [y] : " << flush;
625  char reply;
626  cin.get(reply);
627  cout << endl;
628  if (reply == 'n' || reply == 'N') return;
629  cout << "Give name of file [" << fSaveAnalysisFileName << "] : " << flush;
630  char filename[256];
631  cin.get(filename, 256);
632  if (filename[0] != 0) fSaveAnalysisFileName = filename;
633  Save();
634  }
635  else {
636  Int_t ret_code;
638  new TGMsgBox(gClient->GetDefaultRoot(), (fMain_histolist ? fMain_histolist : gClient->GetDefaultRoot()), GetTitle(),
639  "Analysis has been modified. Save before continuing?", kMBIconStop,
640  kMBYes | kMBNo, &ret_code);
641  if (ret_code == kMBNo) return;
643  }
644 }
645 
646 
647 
649 
651 {
653  if (fMenuFile) {
654  if (x) {
657  }
658  else {
661  }
662  }
663 }
664 
665 
666 
675 
677 {
678  // Modify currently active selection (TEntryList)
679  // Instead of calling
680  // fChain->SetEntryList(l);
681  // call this method which works with or without PROOF.
682  // When using PROOF, fChain->SetEntryList(nullptr)
683  // does not work (bug in TProofChain), the last selection
684  // remains active. This problem is corrected here.
685 
687 
688  if (l == nullptr && IsPROOFEnabled()) {
691  }
692 }
693 
694 
695 
698 
700 {
701  // Launch the GUI (unless fNoGui=kTRUE in which case this does nothing)
702 
703  if (fNoGui) return;
704 
705  ULong_t red, cyan, green, yellow, magenta, gura, gurb, gurc, gurd, gure, gurf;
706  gClient->GetColorByName("#ff00ff", magenta);
707  gClient->GetColorByName("#ff0000", red);
708  gClient->GetColorByName("#00ff00", green);
709  gClient->GetColorByName("#00ffff", cyan);
710  gClient->GetColorByName("#ffff00", yellow);
711  gClient->GetColorByName("#cf14b2", gura);
712  gClient->GetColorByName("#cd93e6", gurb);
713  gClient->GetColorByName("#c1e91a", gurc);
714  gClient->GetColorByName("#d1a45b", gurd);
715  gClient->GetColorByName("#b54cfe", gure);
716  gClient->GetColorByName("#a325ef", gurf);
717 
718  /********* MAIN WINDOW **************/
719  //
720  fMain_histolist = new TGMainFrame(gClient->GetRoot(), 10, 10, kMainFrame | kVerticalFrame);
721  fMain_histolist->SetName("fMain_histolist");
722  if (!fTree)
723  fMain_histolist->SetWindowName("Tree Analyzer");
724  else
726  fMain_histolist->SetIconName("TreeAnalyzer");
727  fMain_histolist->SetIconPixmap("root_s.xpm");
728 
730 
731  UInt_t hWidth = 400, hHeight = 400;
732 
733  /* menus */
734  fMenuFile = new TGPopupMenu(gClient->GetRoot());
735  fMenuFile->AddEntry("New analysis", MH_OPEN_CHAIN);
736  fMenuFile->AddEntry("Open analysis", MH_OPEN_FILE);
737  fMenuFile->AddEntry("Add Friend...", MH_ADD_FRIEND);
739  fMenuFile->AddEntry("Save analysis", MH_SAVE);
740  fMenuFile->AddEntry("Save as...", MH_SAVE_FILE);
741  fMenuFile->AddEntry("Close", MH_CLOSE);
743  fMenuFile->AddEntry("Apply analysis...", MH_APPLY_ANALYSIS);
746  fMenuFile->AddEntry("Quit", MH_QUIT);
747  fMenuFile->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleHistoFileMenu(Int_t)");
748  fMenuSelections = new TGPopupMenu(gClient->GetRoot());
749  fSelCombMenu = new TGPopupMenu(gClient->GetRoot());
750  fSelCombMenu->AddEntry("AND (&&)", SEL_COMB_AND);
751  fSelCombMenu->AddEntry("OR (||)", SEL_COMB_OR);
752  fMenuSelections->AddPopup("Combine...", fSelCombMenu);
755  fMenuSelections->AddEntry("Update", SEL_UPDATE);
756  fMenuSelections->AddEntry("Delete", SEL_DELETE);
758  fSelGenerate = new TGPopupMenu(gClient->GetRoot());
759  fSelGenerate->AddEntry("Constant X-sections", SEL_GEN_CONST_XSEC);
760  fMenuSelections->AddPopup("Generate...", fSelGenerate);
761  fMenuSelections->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleSelectionsMenu(Int_t)");
762  fOptionMenu = new TGPopupMenu(gClient->GetRoot());
763  fOptionMenu->AddEntry("PROOF", OPT_PROOF);
764  fOptionMenu->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleOptionsMenu(Int_t)");
773 
774  // Horizontal frame to contain the VARIABLES list (left) and SELECTIONS list (right)
776 
777  /********* VARIABLES **************/
778  // Group frame for TTree variables/aliases
779  fMain_leaflist = new TGGroupFrame(hf, "VARIABLES");
780  UInt_t lWidth = 300, lHeight = 300;
781  /* leaf list */
782 
783  /* make selection */
784  TGHorizontalFrame* fHorizontalFrame = new TGHorizontalFrame(fMain_leaflist, lWidth, 36, kHorizontalFrame);
785  TGLabel* lab = new TGLabel(fHorizontalFrame, "Make alias : ");
786  fHorizontalFrame->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
787  G_alias_text = new TGTextEntry(fHorizontalFrame, new TGTextBuffer(50));
788  G_alias_text->SetMaxLength(4096);
791  G_alias_text->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateAlias()");
792  fHorizontalFrame->AddFrame(G_alias_text, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 2, 5, 2, 2));
793  fMain_leaflist->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
794 
795  G_leaflist = new KVListView(TNamed::Class(), fMain_leaflist, lWidth, lHeight);
797  G_leaflist->SetDataColumn(0, "Title");
800  G_leaflist->SetDoubleClickAction("KVTreeAnalyzer", this, "DrawLeaf(TObject*)");
801  G_leaflist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "LeafChanged()");
802 // G_leaflist->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "ShowVar()");
805  5, 5, 5, 5));
806 
807  //fMain_leaflist->MapSubwindows();
808 
810  //fMain_leaflist->MapWindow();
811  fMain_leaflist->Resize(lWidth, lHeight);
812  FillLeafList();
813  /*********end of VARIABLES **************/
814  hf->AddFrame(fMain_leaflist, new TGLayoutHints(kLHintsLeft, 5, 5, 5, 5));
815 
816  /******* SELECTIONS *********/
817  UInt_t sWidth = 600, sHeight = lHeight;
818  fMain_selectionlist = new TGGroupFrame(hf, "SELECTIONS");
819  /* current selection */
821  G_selection_status->SetText("CURRENT SELECTION:", 0);
823  /* make selection */
824  TGHorizontalFrame* fHorizontalFrame1614 = new TGHorizontalFrame(fMain_selectionlist, sWidth, 36, kHorizontalFrame);
825  lab = new TGLabel(fHorizontalFrame1614, "Make selection : ");
826  fHorizontalFrame1614->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
827  G_selection_text = new TGTextEntry(fHorizontalFrame1614, new TGTextBuffer(50));
831  G_selection_text->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateSelection()");
832  fHorizontalFrame1614->AddFrame(G_selection_text, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 2, 5, 2, 2));
833  fMain_selectionlist->AddFrame(fHorizontalFrame1614, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
834 
835  /* selection list */
838  G_selectionlist->SetDataColumn(0, "Selection", "GetTitle");
839  G_selectionlist->SetDataColumn(1, "Reapply", "GetReapplyCut");
841  G_selectionlist->SetDataColumn(2, "Events", "GetN", kTextRight);
843  G_selectionlist->SetDoubleClickAction("KVTreeAnalyzer", this, "SetSelection(TObject*)");
844  G_selectionlist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "SelectionChanged()");
847  5, 5, 5, 5));
848 
849  //fMain_selectionlist->MapSubwindows();
850 
852  //fMain_selectionlist->MapWindow();
853  fMain_selectionlist->Resize(sWidth, sHeight);
855  /******end of SELECTIONS *********/
858 
859  /**** Histo creation group ********/
860  TGGroupFrame* histo_opts = new TGGroupFrame(fMain_histolist, "CREATE HISTO", kHorizontalFrame);
861  fHorizontalFrame = new TGHorizontalFrame(histo_opts, lWidth, 36, kHorizontalFrame);
862  G_leaf_draw = new TGPictureButton(fHorizontalFrame, "draw_t.xpm");
864  G_leaf_draw->Connect("Clicked()", "KVTreeAnalyzer", this, "DrawLeafExpr()");
865  fHorizontalFrame->AddFrame(G_leaf_draw, new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 2, 2, 2));
866  fLeafExpr = " ";
867  G_leaf_expr = new TGLabel(fHorizontalFrame, fLeafExpr.Data());
868  G_leaf_expr->Resize();
869  fHorizontalFrame->AddFrame(G_leaf_expr, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
870  histo_opts->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
871 
872  G_histo_prof = new TGCheckButton(histo_opts, "Profile");
873  G_histo_prof->SetToolTipText("Generate a profile histogram");
875  G_histo_prof->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetProfileHisto(Bool_t)");
876  histo_opts->AddFrame(G_histo_prof, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
877 
878  G_histo_norm = new TGCheckButton(histo_opts, "Normalize (integral)");
879  G_histo_norm->SetToolTipText("Generate normalized histogram with integral=1");
881  G_histo_norm->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNormHisto(Bool_t)");
882  histo_opts->AddFrame(G_histo_norm, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
883  G_histo_norm_events = new TGCheckButton(histo_opts, "Normalize (events)");
884  G_histo_norm_events->SetToolTipText("Generate histogram with integral divided by number of events");
886  G_histo_norm_events->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNormHistoEvents(Bool_t)");
887  histo_opts->AddFrame(G_histo_norm_events, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
888 
889  G_histo_weight = new TGCheckButton(histo_opts, "Weight");
890  G_histo_weight->SetToolTipText("User defined binning of the histogram");
892  G_histo_weight->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetUserWeight(Bool_t)");
893  histo_opts->AddFrame(G_histo_weight, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
894 
895  G_histo_bin = new TGCheckButton(histo_opts, "Bins");
896  G_histo_bin->SetToolTipText("User defined binning of the histogram");
898  G_histo_bin->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetUserBinning(Bool_t)");
899  histo_opts->AddFrame(G_histo_bin, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
900  fMain_histolist->AddFrame(histo_opts, new TGLayoutHints(kLHintsCenterX | kLHintsExpandX, 5, 5, 5, 5));
901 
902  /******** HISTOGRAMS *****************/
903  hWidth = lWidth + sWidth + 20;
904  TGGroupFrame* histo_group = new TGGroupFrame(fMain_histolist, "HISTOGRAMS");
905  /* ip scale */
906 // histo_opts = new TGGroupFrame(histo_group, "Impact parameter", kHorizontalFrame);
907 // G_make_ip_scale = new TGTextButton(histo_opts,"Make scale");
908 // G_make_ip_scale->SetTextJustify(36);
909 // G_make_ip_scale->SetMargins(0,0,0,0);
910 // G_make_ip_scale->SetWrapLength(-1);
911 // G_make_ip_scale->Resize();
912 // G_make_ip_scale->SetEnabled(kFALSE);
913 // G_make_ip_scale->Connect("Clicked()","KVTreeAnalyzer",this,"MakeIPScale()");
914 // G_make_ip_scale->ChangeBackground(green);
915 // histo_opts->AddFrame(G_make_ip_scale, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,10,2));
916 // lab = new TGLabel(histo_opts,"b <");
917 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,5,2,12,2));
918 // G_make_ip_selection = new TGTextEntry(histo_opts, new TGTextBuffer(5));
919 // G_make_ip_selection->SetMaxLength(10);
920 // G_make_ip_selection->SetAlignment(kTextLeft);
921 // G_make_ip_selection->Resize(50,G_make_ip_selection->GetDefaultHeight());
922 // G_make_ip_selection->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateIPSelection()");
923 // G_make_ip_selection->SetEnabled(kFALSE);
924 // histo_opts->AddFrame(G_make_ip_selection, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,10,2));
925 // G_ip_histo = new TGLabel(histo_opts,"-");
926 // histo_opts->AddFrame(G_ip_histo, new TGLayoutHints(kLHintsLeft|kLHintsTop,5,2,12,2));
927 // histo_group->AddFrame(histo_opts, new TGLayoutHints(kLHintsLeft|kLHintsExpandX,5,5,5,5));
928 // /* ip scale */
929 // histo_opts = new TGGroupFrame(histo_group, "Fits", kHorizontalFrame);
930 // lab = new TGLabel(histo_opts,"Gumbel : ");
931 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,5,2));
932 // G_fit1 = new TGTextButton(histo_opts, " 1 ");
933 // G_fit1->SetTextJustify(36);
934 // G_fit1->SetMargins(0,0,0,0);
935 // G_fit1->SetWrapLength(-1);
936 // G_fit1->Resize();
937 // G_fit1->SetEnabled(kFALSE);
938 // G_fit1->ChangeBackground(gura);
939 // G_fit1->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum1()");
940 // histo_opts->AddFrame(G_fit1, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
941 // G_fit2 = new TGTextButton(histo_opts, " 2 ");
942 // G_fit2->SetTextJustify(36);
943 // G_fit2->SetMargins(0,0,0,0);
944 // G_fit2->SetWrapLength(-1);
945 // G_fit2->Resize();
946 // G_fit2->SetEnabled(kFALSE);
947 // G_fit2->ChangeBackground(gurb);
948 // G_fit2->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum2()");
949 // histo_opts->AddFrame(G_fit2, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
950 // G_fit3 = new TGTextButton(histo_opts, " 3 ");
951 // G_fit3->SetTextJustify(36);
952 // G_fit3->SetMargins(0,0,0,0);
953 // G_fit3->SetWrapLength(-1);
954 // G_fit3->Resize();
955 // G_fit3->SetEnabled(kFALSE);
956 // G_fit3->ChangeBackground(gurc);
957 // G_fit3->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum3()");
958 // histo_opts->AddFrame(G_fit3, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
959 // lab = new TGLabel(histo_opts,"Gaus+Gum : ");
960 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,10,2,5,2));
961 // G_fitGG1 = new TGTextButton(histo_opts, " 1 ");
962 // G_fitGG1->SetTextJustify(36);
963 // G_fitGG1->SetMargins(0,0,0,0);
964 // G_fitGG1->SetWrapLength(-1);
965 // G_fitGG1->Resize();
966 // G_fitGG1->SetEnabled(kFALSE);
967 // G_fitGG1->ChangeBackground(gura);
968 // G_fitGG1->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum1()");
969 // histo_opts->AddFrame(G_fitGG1, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
970 // G_fitGG2 = new TGTextButton(histo_opts, " 2 ");
971 // G_fitGG2->SetTextJustify(36);
972 // G_fitGG2->SetMargins(0,0,0,0);
973 // G_fitGG2->SetWrapLength(-1);
974 // G_fitGG2->Resize();
975 // G_fitGG2->SetEnabled(kFALSE);
976 // G_fitGG2->ChangeBackground(gurb);
977 // G_fitGG2->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum2()");
978 // histo_opts->AddFrame(G_fitGG2, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
979 // G_fitGG3 = new TGTextButton(histo_opts, " 3 ");
980 // G_fitGG3->SetTextJustify(36);
981 // G_fitGG3->SetMargins(0,0,0,0);
982 // G_fitGG3->SetWrapLength(-1);
983 // G_fitGG3->Resize();
984 // G_fitGG3->SetEnabled(kFALSE);
985 // G_fitGG3->ChangeBackground(gurc);
986 // G_fitGG3->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum3()");
987 // histo_opts->AddFrame(G_fitGG3, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
988 // histo_group->AddFrame(histo_opts, new TGLayoutHints(kLHintsLeft|kLHintsExpandX,5,5,5,5));
989 
990  /* histo list */
991  //G_histolist = new KVListView(TNamed::Class(), histo_group, hWidth, hHeight);
992  //G_histolist->SetDataColumns(1);
993  //G_histolist->SetDataColumn(0, "Data", "GetTitle", kTextLeft);
994  G_histolist = new KVListView(KVHistogram::Class(), histo_group, hWidth, hHeight);
996  G_histolist->SetDataColumn(0, "Name", "", kTextLeft);
997  G_histolist->SetDataColumn(1, "VarX", "", kTextCenterX);
998  G_histolist->SetDataColumn(2, "VarY", "", kTextCenterX);
999  G_histolist->SetDataColumn(3, "VarZ", "", kTextCenterX);
1000  G_histolist->SetDataColumn(4, "Selection", "", kTextCenterX);
1001  G_histolist->SetDataColumn(5, "Weight", "", kTextCenterX);
1002  G_histolist->SetDataColumn(6, "MeanX (RMS)", "GetMeanRMSX", kTextCenterX);
1003  G_histolist->SetDataColumn(7, "MeanY (RMS)", "GetMeanRMSY", kTextCenterX);
1006  G_histolist->SetUseObjLabelAsRealClass();//to have icons & context menus of TH* & TCutG classes, not KVHistogram
1007  G_histolist->SetDoubleClickAction("KVTreeAnalyzer", this, "DrawHisto(TObject*)");
1008  G_histolist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "HistoSelectionChanged()");
1011  5, 5, 5, 5));
1012 
1015  /* histo options */
1016  histo_opts = new TGGroupFrame(fMain_histolist, "OPTIONS", kHorizontalFrame);
1017 
1018  //fHorizontalFrame = new TGHorizontalFrame(histo_opts,150,36,kHorizontalFrame);
1019  G_histo_del = new TGPictureButton(histo_opts, "sm_delete.xpm");
1021  G_histo_del->Connect("Clicked()", "KVTreeAnalyzer", this, "DeleteSelectedHisto()");
1022  //fHorizontalFrame->AddFrame(G_histo_del, new TGLayoutHints(kLHintsTop|kLHintsLeft,2,2,2,2));
1023  //lab = new TGLabel(fHorizontalFrame, "DELETE");
1024  //lab->Resize();
1025  //fHorizontalFrame->AddFrame(lab, new TGLayoutHints(kLHintsTop|kLHintsLeft|kLHintsCenterY,2,2,2,2));
1026  histo_opts->AddFrame(G_histo_del, new TGLayoutHints(kLHintsLeft, 5, 2, 8, 2));
1027 
1028  G_histo_add = new TGPictureButton(histo_opts, "bld_plus.png");
1030  G_histo_add->Connect("Clicked()", "KVTreeAnalyzer", this, "AddSelectedHistos()");
1032  histo_opts->AddFrame(G_histo_add, new TGLayoutHints(kLHintsLeft, 15, 25, 8, 2));
1033 
1034  G_histo_draw_option = new TGComboBox(histo_opts);
1035  TString draw_options[] = {
1036  "",
1037  "COL",
1038  "COLZ",
1039  "BOX",
1040  "CONT",
1041  "SURF",
1042  "LEGO",
1043  "ARR",
1044  "TEXT",
1045  "CONT1",
1046  "CONT2",
1047  "CONT3",
1048  "CONT4",
1049  "SURF1",
1050  "SURF2",
1051  "SURF3",
1052  "SURF4",
1053  "LEGO1",
1054  "LEGO2",
1055  "LEGO3",
1056  "LEGO4",
1057  "BOX1",
1058  " "
1059  };
1060  int dop = 0;
1061  while (draw_options[dop] != " ") {
1062  G_histo_draw_option->AddEntry(draw_options[dop], dop);
1063  ++dop;
1064  }
1065  G_histo_draw_option->Resize(100, 20);
1066  histo_opts->AddFrame(G_histo_draw_option, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1067  G_histo_draw_option->Connect("Selected(const char*)", "KVTreeAnalyzer", this, "SetDrawOption(Option_t*)");
1068 
1069  G_histo_new_can = new TGCheckButton(histo_opts, "New canvas");
1070  G_histo_new_can->SetToolTipText("Draw in a new canvas");
1071  G_histo_new_can->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNewCanvas(Bool_t)");
1073  histo_opts->AddFrame(G_histo_new_can, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1074  G_histo_same = new TGCheckButton(histo_opts, "Same");
1075  G_histo_same->SetToolTipText("Draw in same pad");
1076  G_histo_same->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetDrawSame(Bool_t)");
1077  histo_opts->AddFrame(G_histo_same, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1078  G_histo_app_sel = new TGCheckButton(histo_opts, "Apply selection");
1079  G_histo_app_sel->SetToolTipText("Apply current selection to generate new histo");
1080  G_histo_app_sel->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetApplySelection(Bool_t)");
1081  histo_opts->AddFrame(G_histo_app_sel, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1082  G_histo_log = new TGCheckButton(histo_opts, "Log scale");
1083  G_histo_log->SetToolTipText("Use log scale in Y (1D) or Z (2D)");
1085  G_histo_log->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetDrawLog(Bool_t)");
1086  histo_opts->AddFrame(G_histo_log, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1087  G_histo_stats = new TGCheckButton(histo_opts, "Stats");
1088  G_histo_stats->SetToolTipText("Display histogram statistics box");
1090  G_histo_stats->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetStatsHisto(Bool_t)");
1091  histo_opts->AddFrame(G_histo_stats, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1092  G_histo_autosave = new TGCheckButton(histo_opts, "AutoSave");
1093  G_histo_autosave->SetToolTipText("Automatically generate histo image files");
1095  G_histo_autosave->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetAutoSaveHisto(Bool_t)");
1096  histo_opts->AddFrame(G_histo_autosave, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1097  fMain_histolist->AddFrame(histo_opts, new TGLayoutHints(kLHintsCenterX, 5, 5, 5, 5));
1098 
1100 
1103 
1104  hHeight = hHeight + lHeight + 50;
1105 
1106  fMain_histolist->Resize(hWidth, hHeight);
1107  /********* end of HISTOGRAMS *************/
1108 
1109  fMain_histolist->Connect("CloseWindow()", "KVTreeAnalyzer", this, "GUIClosed()");
1110 }
1111 
1112 
1113 
1116 
1118 {
1119  // Called when graphical window is closed
1120 
1123  TTimer::SingleShot(150, "KVTreeAnalyzer", this, "DeleteThis()");
1124 }
1125 
1126 
1127 
1131 
1133 {
1134  // Adds histogram to internal list of user histograms
1135  // and updates GUI display
1136 
1137  SetAnalysisModifiedSinceLastSave(kTRUE);//new histogram needs saving
1138  fHistolist.Add(new KVHistogram(h));
1140 }
1141 
1142 
1143 
1147 
1149 {
1150  // Adds selection to internal list of user histograms
1151  // and updates GUI display
1152 
1153  SetAnalysisModifiedSinceLastSave(kTRUE);//new selection needs saving
1154  fSelections.Add(e);
1156 }
1157 
1158 
1159 
1163 
1165 {
1166  // Adds histogram to internal list of user histograms
1167  // and updates GUI display
1168 
1169  SetAnalysisModifiedSinceLastSave(kTRUE);//new selection needs saving
1170  fHistolist.Add(new KVHistogram(c));
1172 }
1173 
1174 
1175 
1182 
1184 {
1185  // the Tree file name is used as the basis for the default analysis backup filename.
1186  // for a TChain there may be many files with a common root.
1187  // we look for this common root and replace any "wildcard" characters with "X"
1188  // i.e. for files "run_001.root", "run_002.root", ..., "run_999.root" we
1189  // will use "Analysis_run_XXX.root" as default name
1190 
1191  KVString p;
1192  if (t->InheritsFrom("TChain")) {
1193  KVString p;
1194  p.FindCommonTitleCharacters(((TChain*)t)->GetListOfFiles(), 'X');
1195  fTreeFileName = p.Data();
1196  }
1197  else
1201 }
1202 
1203 
1204 
1207 
1209 {
1210  // Connects a TChain for analysis
1211 
1212  fTree = t;
1214  if (IsPROOFEnabled()) fChain->SetProof();
1215  fTreeName = t->GetName();
1216  SetTreeFileName(t);
1218 }
1219 
1220 
1221 
1224 
1226 {
1227  // Backwards compatibility: to read old analysis files
1228 
1229  TFile* f;
1231  // absolute path to TTree file doesn't work, try in working directory
1232  TString tmp;
1234  f = TFile::Open(tmp);
1235  }
1237  // if fRelativePathToAnalysisFile!="." and if fTreeFileName is not an absolute path,
1238  // we guess the Tree file is in the same directory as the analysis file
1239  TString tmp;
1241  f = TFile::Open(tmp);
1242  }
1243  else
1245  if (!f || f->IsZombie()) {
1246  Error("ReconnectTree", "Failed to reconnect Tree file %s", fTreeFileName.Data());
1247  fTree = 0;
1249  fChain = 0;
1250  SafeDelete(f);
1251  return;
1252  }
1253  fTreeFileName = f->GetName();
1254  TTree* t = (TTree*)f->Get(fTreeName);
1255  TString treeTitle = t->GetTitle();
1256  delete f;
1257  fChain = new TChain(fTreeName, treeTitle);
1259  fChain->SetDirectory(0);
1260  SetTree(fChain);
1261 }
1262 
1263 
1264 
1272 
1274 {
1275  // STATIC method to open a previously saved analysis session.
1276  //
1277  // Use:
1278  // root[0] KVTreeAnalyzer* TA = KVTreeAnalyzer::OpenFile("my_analysis.root")
1279  //
1280  // If option nogui=kTRUE the GUI will not be launched
1281 
1283  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1284  delete f;
1285  anal->fNoGui = nogui;
1287  anal->OpenGUI();
1288  return anal;
1289 }
1290 
1291 
1292 
1295 
1297 {
1298  // open a previously saved analysis session.
1299 
1301  ReadFromFile(f);
1302 }
1303 
1304 
1305 
1308 
1310 {
1311  // open a previously saved analysis session.
1312 
1313  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1314  delete f;
1315  anal->Copy(*this);
1316  delete anal;
1317  gTreeAnalyzer = this;
1320  FillLeafList();
1321 }
1322 
1323 
1324 
1326 
1328 {
1329  TString name = Form("%s:%s", cut->GetVarY(), cut->GetVarX());
1330  KVUnownedList padList;
1331  Bool_t testHisto = kFALSE;
1332 
1333  if (!gPad) testHisto = kTRUE;
1334 
1335  if (!testHisto) {
1336  testHisto = kTRUE;
1337  padList.AddAll(((TPad*)gPad)->GetListOfPrimitives());
1338  TIter next(&padList);
1339  TObject* o = 0;
1340  while ((o = next())) {
1341  if (o->InheritsFrom("TH1")) {
1342  TH1* hh = (TH1*) o;
1343  TString hName = hh->GetTitle();
1344  if (hName.Contains(name.Data())) {
1345  cut->Draw("PL");
1346  gPad->Update();
1347  testHisto = kFALSE;
1348  }
1349  }
1350  }
1351  }
1352 
1353  if (testHisto) {
1354  TIter next(&fHistolist);
1355  KVHistogram* hhh;
1356  TH1* hh = 0;
1357  while ((hhh = (KVHistogram*)next())) {
1358  if ((hh = hhh->GetHisto())) {
1359  TString hName = hh->GetTitle();
1360  if (hName.Contains(name.Data())) {
1361  DrawHisto(hh, kFALSE);
1362  cut->Draw("PL");
1363  gPad->Update();
1364  break;
1365  }
1366  }
1367  }
1368  }
1369  // else cut->Draw("PAL");
1370 
1371 
1372 // TIter next(fHistoList);
1373 // TH1* tmpHist = 0;
1374 // while((tmpHisto = (TH1*)next()))
1375 // {
1376 //
1377 // }
1378 
1379  return;
1380 }
1381 
1382 
1383 
1385 
1386 void KVTreeAnalyzer::DrawHistogram(TH1* histo, Bool_t same, Bool_t logscale)
1387 {
1388  if (fDrawSame || same) {
1389  // if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1390  // plot with a different colour and add it to the automatically generated
1391  // legend which is also displayed in the plot
1392  histo->SetLineColor(my_color_array[++fSameColorIndex]);
1393  histo->SetLineWidth(2);
1394  if (fSameColorIndex == MAX_COLOR_INDEX) fSameColorIndex = -1;
1395  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1396  if (histo->InheritsFrom("TH2")) {
1397  TString hopt = histo->GetOption();
1398  if (hopt != "") hopt.Form("%s,same", histo->GetOption());
1399  else hopt = "same";
1400  histo->Draw(hopt);
1401  }
1402  else
1403  histo->Draw("same");
1404  TObject* legend = gPad->GetListOfPrimitives()->FindObject("TPave");
1405  if (legend) {
1406  gPad->GetListOfPrimitives()->Remove(legend);
1407  delete legend;
1408  }
1409  ((TPad*) gPad)->BuildLegend();
1410  if (histo->InheritsFrom("TH2")) {
1411  gPad->SetLogy(kFALSE);
1412  gPad->SetLogz(fDrawLog || logscale);
1413  }
1414  else {
1415  gPad->SetLogy(fDrawLog || logscale);
1416  // adjust y-scale to new histogram if needed
1417  // find first histogram
1418  TIter nxt(gPad->GetListOfPrimitives());
1419  TObject* h;
1420  while ((h = nxt())) {
1421  if (h->InheritsFrom("TH1")) {
1422  TH1* hh = (TH1*)h;
1423  if (histo->GetMaximum() > hh->GetMaximum()) hh->SetMaximum(histo->GetMaximum() + 1);
1424  break;
1425  }
1426  }
1427  }
1428  gPad->Modified();
1429  gPad->Update();
1430  if (fAutoSaveHisto) AutoSaveHisto(histo);
1431  }
1432  else {
1433  // if 'new canvas' is active the histogram is displayed in a new KVCanvas
1434  // create a new canvas also if none exists
1435  if (fNewCanvas || !gPad) {
1436  KVCanvas* c = new KVCanvas;
1437  c->SetTitle(histo->GetTitle());
1438  c->SetWindowSize(700, 700);
1439  }
1440  else if (gPad) { // update title of existing canvas
1441  gPad->GetCanvas()->SetTitle(histo->GetTitle());
1442  }
1443  histo->SetLineColor(my_color_array[0]);
1444  histo->SetLineWidth(2);
1445  if (histo->InheritsFrom("TH2")) {
1446  gPad->SetLogy(kFALSE);
1447  gPad->SetLogz(fDrawLog || logscale);
1448  }
1449  else {
1450  histo->SetMaximum(-1111);//in case maximum was changed to accomodate superimposition
1451  gPad->SetLogy(fDrawLog || logscale);
1452  }
1453  histo->SetStats(fStatsHisto);//show/hide stat box according to check-box
1454  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1455  histo->Draw();
1456  gPad->Modified();
1457  gPad->Update();
1458  if (fAutoSaveHisto) AutoSaveHisto(histo);
1459  }
1460 }
1461 
1462 
1463 
1484 
1486 {
1487  // Method called when a user double-clicks a histogram in the GUI list.
1488  //
1489  // * if histogram is already displayed in active pad and if the pad also
1490  // contains a graphical contour (TCutG) object, we use the contour to define
1491  // a new data selection (TEntryList) which is added to the internal list.
1492  //
1493  // * if 'reapply selection' is activated and if the current active selection
1494  // is not the same as that used to generate the histogram, we generate a new
1495  // histogram displaying the same variables but with the current selection.
1496  //
1497  // * if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1498  // plot with a different colour and add it to the automatically generated
1499  // legend which is also displayed in the plot
1500  //
1501  // * if 'new canvas' is active the histogram is displayed in a new KVCanvas
1502  //
1503  // * in all cases when a histogram is displayed the log/linear scale of
1504  // Y (1-D) or Z (2-D) axis is automatically adjusted according to the 'log scale'
1505  // check box
1506 
1507  KVHistogram* kvhisto = 0;
1508  TCutG* cut = 0;
1509  TH1* histo = 0;
1510  if (obj->InheritsFrom("KVHistogram")) {
1511  kvhisto = dynamic_cast<KVHistogram*>(obj);
1512  if (kvhisto->IsType("Cut")) cut = kvhisto->GetCut();
1513  else if (kvhisto->IsType("Histo")) histo = kvhisto->GetHisto();
1514  }
1515  else if (obj->InheritsFrom("TCutG")) {
1516  cut = dynamic_cast<TCutG*>(obj);
1517  }
1518  else if (obj->InheritsFrom("TH1")) {
1519  histo = dynamic_cast<TH1*>(obj);
1520  }
1521 
1522  if (cut) {
1523  DrawCut(cut);
1524  return;
1525  }
1526  if (!histo) return;
1527 
1528  // if histogram is already displayed in active pad and if the pad also
1529  // contains a graphical contour (TCutG) object, we use the contour to define
1530  // a new data selection (TEntryList) which is added to the internal list.
1531  if (gPad && gPad->GetListOfPrimitives()->FindObject(histo) && (gen)) {
1532  TIter next(gPad->GetListOfPrimitives());
1533  TObject* o;
1534  while ((o = next())) {
1535  if ((o->IsA() == TCutG::Class()) && !(fHistolist.FindObjectWithNameAndType(o->GetName(), "Cut"))) {
1536  MakeSelection(o->GetName());
1537  return;
1538  }
1539  }
1540  }
1541 
1542  KVString exp, sel, weight;
1543  if (kvhisto) {
1544  exp = kvhisto->GetExpression();
1545  sel = kvhisto->GetSelection();
1546  weight = kvhisto->GetWeight();
1547  }
1548  else {
1549  KVHistogram::ParseHistoTitle(histo->GetTitle(), exp, sel, weight);
1550  }
1551 
1552  if (weight == "1") weight = "";
1553 
1554  // if 'reapply selection' is activated and if the current active selection
1555  // is not the same as that used to generate the histogram, we generate a new
1556  // histogram displaying the same variables but with the current selection.
1558  histo = RemakeHisto(histo, exp, weight);
1559  if (!histo) return;
1560  }
1561 
1562  DrawHistogram(histo);
1563 }
1564 
1565 
1566 
1570 
1572 {
1573  // Returns kTRUE if "sel" corresponds to current active selection
1574  // (i.e. entry list of TTree)
1575 
1576  if (!fTree) return kTRUE;
1577  TString test_sel(sel);
1578  TString tree_sel;
1579  TEntryList* el;
1580  if ((el = fChain->GetEntryList())) tree_sel = el->GetTitle();
1581  return (test_sel == tree_sel);
1582 }
1583 
1584 
1585 
1590 
1591 TH1* KVTreeAnalyzer::RemakeHisto(TH1* h, const Char_t* expr, const Char_t* weight)
1592 {
1593  // Remake an existing histogram of data 'expr' using the current active selection
1594  // If such a histogram already exists, we just return its address.
1595  // We must have the same binning in the new as in the original histogram.
1596 
1597  TString htit;
1598  GenerateHistoTitle(htit, expr, "", weight);
1599  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
1600  TH1* histo = 0;
1601  if (kvhisto) histo = kvhisto->GetHisto();
1602  if (histo && (histo->IsA() == h->IsA())) return histo;
1603  Int_t nx, ny = 0;
1604  TString hname(h->GetName());
1605  if (hname.BeginsWith("I")) {
1606  Int_t xmin = h->GetXaxis()->GetXmin() + 0.5;
1607  Int_t xmax = h->GetXaxis()->GetXmax() - 0.5;
1608  //cout << "Remake histo with xmin = " << xmin << " xmax = " << xmax << endl;
1609  h = MakeIntHisto(expr, "", xmin, xmax, weight);
1610  return h;
1611  }
1612  nx = h->GetNbinsX();
1613  auto xmin = h->GetXaxis()->GetXmin();
1614  auto xmax = h->GetXaxis()->GetXmin();
1615  double ymin(-1), ymax(-1);
1616  if (h->InheritsFrom("TH2")) {
1617  ny = h->GetNbinsY();
1618  ymin = h->GetYaxis()->GetXmin();
1619  ymax = h->GetYaxis()->GetXmin();
1620  }
1621  //cout << "Remake histo with nx = " << nx << " ny = " << ny << endl;
1622  if (h->InheritsFrom("TProfile")) {
1623  // make a new profile histogram
1624  Bool_t oldProfileState = fProfileHisto;
1625  fProfileHisto = kTRUE;
1626  h = MakeHisto(expr, "", nx, ny, weight, xmin, xmax);
1627  fProfileHisto = oldProfileState;
1628  }
1629  else
1630  h = MakeHisto(expr, "", nx, ny, weight, xmin, xmax, ymin, ymax);
1631  return h;
1632 }
1633 
1634 
1635 
1640 
1642 {
1643  // Method called when user hits 'return' in selection GUI text-box
1644  // Takes expression from text-box and generates the corresponding
1645  // selection which is added to the GUI list of selections.
1646 
1647  TString selection = G_selection_text->GetText();
1648  if (selection.IsNull()) return;
1649  if (MakeSelection(selection)) G_selection_text->Clear();
1650 }
1651 
1652 
1653 
1657 
1659 {
1660  // Method called when user hits 'return' in TTree leaf/alias GUI text-box
1661  // Generates a new alias using the expression in the text-box.
1662 
1663  TString alias = G_alias_text->GetText();
1664  TString name;
1665  name.Form("a%d", fAliasNumber++);
1666  SetAlias(name, alias);
1667  FillLeafList();
1668  G_alias_text->Clear();
1669 }
1670 
1671 
1672 
1677 
1679 {
1680  // Method called when user hits 'combine selections' button in selections GUI.
1681  // Generates new selection which is the intersection (logical AND) of
1682  // the currently selected selections.
1683 
1684  if (!fSelectedSelections.IsEmpty()) {
1685  TEntryList* save_elist = fChain->GetEntryList();
1687  TString newselect;
1688  int nsel = fSelectedSelections.GetEntries();
1689  for (int i = 1; i < nsel; i++) {
1690  TString tmp;
1692  tmp.Form("(%s)", el->GetTitle());
1693  if (i > 1) newselect += " && ";
1694  newselect += tmp.Data();
1695  }
1696  MakeSelection(newselect);
1697  SetEntryList(save_elist);
1698  }
1699 }
1700 
1701 
1702 
1707 
1709 {
1710  // Method called when user hits 'combine selections' button in selections GUI.
1711  // Generates new selection which is the intersection (logical AND) of
1712  // the currently selected selections.
1713 
1714  if (!fSelectedSelections.IsEmpty()) {
1715  TEntryList* save_elist = fChain->GetEntryList();
1716  SetEntryList(nullptr);
1717  TString newselect;
1718  int nsel = fSelectedSelections.GetEntries();
1719  for (int i = 0; i < nsel; i++) {
1720  TString tmp;
1722  tmp.Form("(%s)", el->GetTitle());
1723  if (i > 0) newselect += " || ";
1724  newselect += tmp.Data();
1725  }
1726  MakeSelection(newselect);
1727  SetEntryList(save_elist);
1728  }
1729 }
1730 
1731 
1732 
1735 
1737 {
1738  // Delete the currently selected selection(s)
1739 
1740  if (!fSelectedSelections.IsEmpty()) {
1741  int nsel = fSelectedSelections.GetEntries();
1742  if (nsel < 1) return;
1743  for (int i = 0; i < nsel; i++) {
1745  if (!el) continue;
1746  fSelections.Remove(el);
1747  // if current selection, disable
1748  if (fChain->GetEntryList() == el) fChain->SetEntryList(nullptr);
1749  delete el;
1751  }
1753  }
1755 
1756 }
1757 
1758 
1759 
1762 
1764 {
1765  // Method called whenever the selected selection in the GUI list changes
1766 
1768  Bool_t resetSel = kTRUE;
1772 
1773  if (fSelectedSelections.IsEmpty()) {
1774  }
1775  else if (fSelectedSelections.GetEntries() == 1) {
1778  if (tmp->GetSize() != 0 || !strcmp("", G_selection_text->GetText())) {
1779  G_selection_text->SetText(((TNamed*)fSelectedSelections.At(0))->GetTitle());
1780  resetSel = kFALSE;
1781  }
1782  delete tmp;
1783  }
1784  else if (fSelectedSelections.GetEntries() > 1) {
1788  }
1789 
1790  if (resetSel) {
1792  if (tmp->GetSize() != 0) G_selection_text->SetText("");
1793  delete tmp;
1794  }
1795 }
1796 
1797 
1798 
1802 
1804 {
1805  // Method called whenever the leaf/alias selection in the TTree GUI list changes.
1806  // Updates the names of the leaves/aliases displayed next to the 'draw' button.
1807 
1809  fLeafExpr = "-";
1810  fXLeaf = fYLeaf = 0;
1811 // Bool_t resetSel = kTRUE;
1813  Int_t nleaf = fSelectedLeaves->GetEntries();
1814  if (nleaf) {
1815  if (nleaf == 1) {
1817  fLeafExpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1819 
1820  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1821  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1822  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0 || !strcmp("", G_alias_text->GetText())) {
1823  G_alias_text->SetText(fLeafExpr.Data()); //resetSel = kFALSE;
1824  }
1825  else if (strcmp(fLeafExpr.Data(), G_leaf_expr->GetTitle())) {
1826  TString tmps = G_alias_text->GetText();
1827  Int_t pos = G_alias_text->MaxMark();
1828  if (pos >= tmps.Sizeof()) pos = G_alias_text->MinMark();
1829  if (pos >= tmps.Sizeof()) pos = tmps.Sizeof() - 1;
1830  tmps.Insert(pos, fLeafExpr.Data());
1831  G_alias_text->SetText(tmps.Data());
1833  }
1834  delete tmp;
1835  delete tmp1;
1836 
1837  }
1838  else if (nleaf == 2) {
1839  fXLeaf = (TNamed*)fSelectedLeaves->At(1);
1841  TString X, Y;
1842  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1843  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1844  fLeafExpr.Form("%s:%s", Y.Data(), X.Data());
1846  G_alias_text->SetText("");
1847  }
1848  else if (nleaf == 3) {
1849  fXLeaf = (TNamed*)fSelectedLeaves->At(2);
1850  fYLeaf = (TNamed*)fSelectedLeaves->At(1);
1851  fZLeaf = (TNamed*)fSelectedLeaves->At(0);
1852  TString X, Y, Z;
1853  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1854  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1855  Z = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
1856  fLeafExpr.Form("%s:%s:%s", Z.Data(), Y.Data(), X.Data());
1858  G_alias_text->SetText("");
1859  }
1860  else {
1861  fLeafExpr = "-";
1862  G_alias_text->SetText("");
1863  }
1864  }
1865  else {
1866  fLeafExpr = "-";
1867 // G_alias_text->SetText("");
1868  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1869  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1870  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0) {
1871  G_alias_text->SetText(""); //resetSel = kFALSE;
1872  }
1873  delete tmp;
1874  delete tmp1;
1875  }
1876 
1878  G_leaf_expr->Resize();
1879 }
1880 
1881 
1882 
1884 
1886 {
1887  KVNameValueList p{{"Xbins", fNx}, {"Xmin", fXmin}, {"Xmax", fXmax},
1888  {"Ybins", fNy}, {"Ymin", fYmin}, {"Ymax", fYmax}};
1889  bool cancel{false};
1890  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1891  g->DisplayDialog();
1892  if (cancel) return false;
1893  fNx = p.GetIntValue("Xbins");
1894  fXmin = p.GetDoubleValue("Xmin");
1895  fXmax = p.GetDoubleValue("Xmax");
1896  fNy = p.GetIntValue("Ybins");
1897  fYmin = p.GetDoubleValue("Ymin");
1898  fYmax = p.GetDoubleValue("Ymax");
1899  return true;
1900 }
1901 
1902 
1903 
1905 
1907 {
1908  KVNameValueList p{{"bins", fNxF}, {"min", fXminF}, {"max", fXmaxF}};
1909  bool cancel{false};
1910  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1911  g->DisplayDialog();
1912  if (cancel) return false;
1913  fNxF = p.GetIntValue("bins");
1914  fXminF = p.GetDoubleValue("min");
1915  fXmaxF = p.GetDoubleValue("max");
1916  return true;
1917 }
1918 
1919 
1920 
1922 
1924 {
1925  KVNameValueList p{{"Xbins", fNxD}, {"Ybins", fNyD}, {"ordered?", fOrderedDalitz}};
1926  bool cancel{false};
1927  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1928  g->DisplayDialog();
1929  if (cancel) return false;
1930  fNxD = p.GetIntValue("Xbins");
1931  fNyD = p.GetIntValue("Ybins");
1932  fOrderedDalitz = p.GetBoolValue("ordered?");
1933  return true;
1934 }
1935 
1936 
1937 
1943 
1945 {
1946  // \returns maximum value of given TTree variable, taking into account any current selection (TEntryList).
1947  // @param leafname name of TTree variable
1948  //
1949  // \note TTree::GetMaximum() is supposed to do exactly the same, but strangely ignores the selection.
1950 
1951  fTree->GetMaximum(leafname);// this just to use internal TTree cache mechanism
1952 
1953  auto leaf = fTree->GetLeaf(leafname);
1954  if (!leaf) return 0;
1955 
1956  auto branch = leaf->GetBranch();
1957  Double_t cmax = -DBL_MAX;
1958  for (Long64_t i = 0; i < fTree->GetEntries(); ++i) {
1959  auto entryNumber = fTree->GetEntryNumber(i);
1960  if (entryNumber < 0) break;
1961  branch->GetEntry(entryNumber);
1962  for (Int_t j = 0; j < leaf->GetLen(); ++j) {
1963  Double_t val = leaf->GetValue(j);
1964  if (val > cmax) {
1965  cmax = val;
1966  }
1967  }
1968  }
1969  return cmax;
1970 }
1971 
1972 
1973 
1979 
1981 {
1982  // \returns minimum value of given TTree variable, taking into account any current selection (TEntryList).
1983  // @param leafname name of TTree variable
1984  //
1985  // \note TTree::GetMinimum() is supposed to do exactly the same, but strangely ignores the selection.
1986 
1987  fTree->GetMinimum(leafname);// this just to use internal TTree cache mechanism
1988 
1989  auto leaf = fTree->GetLeaf(leafname);
1990  if (!leaf) return 0;
1991 
1992  auto branch = leaf->GetBranch();
1993  Double_t cmin = DBL_MAX;
1994  for (Long64_t i = 0; i < fTree->GetEntries(); ++i) {
1995  auto entryNumber = fTree->GetEntryNumber(i);
1996  if (entryNumber < 0) break;
1997  branch->GetEntry(entryNumber);
1998  for (Int_t j = 0; j < leaf->GetLen(); ++j) {
1999  Double_t val = leaf->GetValue(j);
2000  if (val < cmin) {
2001  cmin = val;
2002  }
2003  }
2004  }
2005  return cmin;
2006 }
2007 
2008 
2009 
2011 
2013 {
2015  return lf->GetTypeName();
2016 }
2017 
2018 
2019 
2023 
2025 {
2026  // Method called when user hits 'draw' button in TTree GUI.
2027  // If only one leaf/alias is selected, this actually calls DrawLeaf.
2028 
2029  if (fLeafExpr == "-")return;
2030  Bool_t threeDexp = fSelectedLeaves->GetEntries() == 3;
2031  if (threeDexp && !fProfileHisto) {
2032  DrawAsDalitz();
2033  return;
2034  }
2035  if (fSelectedLeaves->GetEntries() == 1) {
2037  return;
2038  }
2039 
2040  if (fUserWeight) {
2041  if (!DefineWeight()) return;
2042  }
2043 
2044  int nx = 500, ny = 500;
2045  double xmin, xmax, ymin, ymax;
2046  xmin = xmax = ymin = ymax = 0;
2047  TString Xexpr, Yexpr, Zexpr;
2048  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2049  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2050  if (threeDexp) Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2051  if (fXLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fXLeaf), "Char_t")) {
2052  TString tmp = Xexpr;
2053  Xexpr.Form("int(%s)", tmp.Data());
2054  }
2055  if (fYLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fYLeaf), "Char_t")) {
2056  TString tmp = Yexpr;
2057  Yexpr.Form("int(%s)", tmp.Data());
2058  }
2059 
2060  if (threeDexp) fLeafExpr.Form("%s:%s:%s", Zexpr.Data(), Yexpr.Data(), Xexpr.Data());
2061  else fLeafExpr.Form("%s:%s", Yexpr.Data(), Xexpr.Data());
2062  TString name;
2063  name.Form("h%d", fHistoNumber);
2064  TString drawexp(fLeafExpr), histo, histotitle;
2065  if (fUserWeight) GenerateHistoTitle(histotitle, fLeafExpr, "", fWeight);
2066  else GenerateHistoTitle(histotitle, fLeafExpr, "");
2067 
2068  // Check histo doesn't already exist
2069  // Look for list of histograms with given title as we don't distinguish TH2 from TProfile
2070  unique_ptr<KVSeqCollection> same_histo(fHistolist.GetSubListWithMethod(histotitle, "GetHistoTitle"));
2071  TIter nxtSame(same_histo.get());
2072  KVHistogram* kvhisto;
2073  while ((kvhisto = (KVHistogram*)nxtSame())) {
2074  if ((fProfileHisto && kvhisto->IsProfile()) || (!fProfileHisto && kvhisto->IsTH2())) {
2075  DrawHisto(kvhisto->GetHisto());
2076  return;
2077  }
2078  }
2079 
2080  if (fUserBinning) {
2081  if (!DefineUserBinning()) return;
2082  }
2083 
2084  xmin = GetTreeMinimum(Xexpr);
2085  xmax = GetTreeMaximum(Xexpr);
2086  if (fXLeaf->InheritsFrom("TLeaf") &&
2087  (!strcmp(get_leaf_type_name(fXLeaf), "Int_t") || !strcmp(get_leaf_type_name(fXLeaf), "Short_t") || !strcmp(get_leaf_type_name(fXLeaf), "Char_t"))
2088  ) {
2089  xmin -= 0.5;
2090  xmax += 0.5;
2091  nx = xmax - xmin;
2092  }
2093  ymin = GetTreeMinimum(Yexpr);
2094  ymax = GetTreeMaximum(Yexpr);
2095  if (fYLeaf->InheritsFrom("TLeaf") &&
2096  (!strcmp(get_leaf_type_name(fYLeaf), "Int_t") || !strcmp(get_leaf_type_name(fYLeaf), "Short_t") || !strcmp(get_leaf_type_name(fYLeaf), "Char_t"))
2097  ) {
2098  ymin -= 0.5;
2099  ymax += 0.5;
2100  ny = ymax - ymin;
2101  }
2102  if (fUserBinning) {
2103  nx = fNx;
2104  ny = fNy;
2105  xmin = fXmin;
2106  xmax = fXmax;
2107  ymin = fYmin;
2108  ymax = fYmax;
2109  }
2110 
2111  if (!fProfileHisto) histo.Form(">>%s(%d,%f,%f,%d,%f,%f)", name.Data(), nx, xmin, xmax, ny, ymin, ymax);
2112  else {
2113  if (fUserBinning) histo.Form(">>%s(%d,%f,%f)", name.Data(), nx, xmin, xmax);
2114  else histo.Form(">>%s", name.Data());
2115  }
2116  drawexp += histo;
2117  TString ww = "";
2118  if (fUserWeight) ww += fWeight;
2119  Long64_t drawResult;
2120  if (!fProfileHisto) drawResult = fTree->Draw(drawexp, ww.Data(), "goff");
2121  else drawResult = fTree->Draw(drawexp, ww.Data(), "prof,goff");
2122  if (drawResult < 0) {
2123  // Error: problem with Draw, probably bad expression
2124  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
2125  return;
2126  }
2127  TH1* h(nullptr);
2128 #ifdef WITH_PROOF
2129  if (IsPROOFEnabled())
2131  else
2132 #endif
2133  h = (TH1*)gDirectory->Get(name);
2134  h->SetTitle(histotitle);
2135  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
2136  h->SetDirectory(0);
2137  if (h->InheritsFrom("TH1")) {
2138  h->GetXaxis()->SetTitle(fXLeaf->GetTitle());
2139  h->SetLineWidth(2);
2140  }
2141  if (h->InheritsFrom("TH2") || h->InheritsFrom("TProfile")) h->GetYaxis()->SetTitle(fYLeaf->GetTitle());
2142 
2143  AddHisto(h);
2144  fHistoNumber++;
2145  DrawHisto(h);
2146 }
2147 
2148 
2149 
2150 
2152 
2154 {
2155  if ((!fXLeaf->InheritsFrom("TLeaf")) || (!fYLeaf->InheritsFrom("TLeaf")) || (!fZLeaf->InheritsFrom("TLeaf"))) {
2156  Warning("DrawAsDalitz", "Cannot be used with aliases !");
2157  return;
2158  }
2159 
2160  TString Xexpr, Yexpr, Zexpr;
2161  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2162  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2163  Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2164  fLeafExpr.Form("%s:%s:%s", Xexpr.Data(), Yexpr.Data(), Zexpr.Data());
2165 
2169 
2170  if ((!xType.Contains(yType.Data())) || (!yType.Contains(zType.Data()))) {
2171  Warning("DrawAsDalitz", "Leaves %s must have the same type !", fLeafExpr.Data());
2172  return;
2173  }
2174 
2175  Double_t x, y, z;
2176  Double_t var1, var2, var3;
2177  Float_t varf1, varf2, varf3;
2178  Int_t vari1, vari2, vari3;
2179  Short_t vars1, vars2, vars3;
2180  Char_t varc1, varc2, varc3;
2181  x = y = z = 0.;
2182 
2183  if (xType.Contains("Int_t")) {
2184  fTree->SetBranchAddress(Xexpr.Data(), &vari1);
2185  fTree->SetBranchAddress(Yexpr.Data(), &vari2);
2186  fTree->SetBranchAddress(Zexpr.Data(), &vari3);
2187  }
2188  else if (xType.Contains("Short_t")) {
2189  fTree->SetBranchAddress(Xexpr.Data(), &vars1);
2190  fTree->SetBranchAddress(Yexpr.Data(), &vars2);
2191  fTree->SetBranchAddress(Zexpr.Data(), &vars3);
2192  }
2193  else if (xType.Contains("Char_t")) {
2194  fTree->SetBranchAddress(Xexpr.Data(), &varc1);
2195  fTree->SetBranchAddress(Yexpr.Data(), &varc2);
2196  fTree->SetBranchAddress(Zexpr.Data(), &varc3);
2197  }
2198  else if (xType.Contains("Double_t")) {
2199  fTree->SetBranchAddress(Xexpr.Data(), &var1);
2200  fTree->SetBranchAddress(Yexpr.Data(), &var2);
2201  fTree->SetBranchAddress(Zexpr.Data(), &var3);
2202  }
2203  else if (xType.Contains("Float_t")) {
2204  fTree->SetBranchAddress(Xexpr.Data(), &varf1);
2205  fTree->SetBranchAddress(Yexpr.Data(), &varf2);
2206  fTree->SetBranchAddress(Zexpr.Data(), &varf3);
2207  }
2208 
2209  if (fUserBinning) {
2210  if (!DefineUserBinningD()) return;
2211  }
2212 
2213  TString histotitle;
2214  GenerateHistoTitle(histotitle, fLeafExpr, "");
2215 
2216  KVDalitzPlot* h = 0;
2217  if (fUserBinning) h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data(), fOrderedDalitz, fNxD, 0., 1.2, fNyD, 0., 1.2);
2218  else h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data());
2219  fHistoNumber++;
2220 
2221  TEntryList* el = fChain->GetEntryList();
2222  if (el) el->GetEntry(0);
2224 
2225  if (el) nentries = el->GetN();
2226  for (int i = 0; i < nentries; i++) {
2227  Int_t j = i;
2228  if (el) j = el->Next();
2229  fTree->GetEntry(j);
2230  if (xType.Contains("Int_t")) {
2231  x = vari1;
2232  y = vari2;
2233  z = vari3;
2234  }
2235  else if (xType.Contains("Short_t")) {
2236  x = vars1;
2237  y = vars2;
2238  z = vars3;
2239  }
2240  else if (xType.Contains("Char_t")) {
2241  x = varc1;
2242  y = varc2;
2243  z = varc3;
2244  }
2245  else if (xType.Contains("Double_t")) {
2246  x = var1;
2247  y = var2;
2248  z = var3;
2249  }
2250  else if (xType.Contains("Float_t")) {
2251  x = varf1;
2252  y = varf2;
2253  z = varf3;
2254  }
2255  h->FillAsDalitz(x, y, z);
2256  }
2257 
2258  h->SetOption("col");
2259  h->SetDirectory(0);
2260  AddHisto((TH2F*)h);
2261  DrawHisto(h);
2263 
2264 }
2265 
2266 
2267 
2272 
2274 {
2275  // Open dialogue box for user to fill required weight for histo
2276  //
2277  // returns false if Cancel button is pressed
2278 
2279  KVNameValueList params{{"Weight", ""}};
2280  Bool_t cancel_pressed{false};
2281  auto s = new KVNameValueListGUI(GetMainWindow(), &params, &cancel_pressed);
2282  s->DisplayDialog();
2283  // cancel was pressed ?
2284  if (cancel_pressed) return false;
2285  fWeight = params.GetStringValue("Weight");
2286  return true;
2287 }
2288 
2289 
2290 
2293 
2295 {
2296  // Method called when user double-clicks a leaf/alias in list
2297 
2298  if (fUserWeight) {
2299  if (!DefineWeight()) return;
2300  }
2301 
2302  TH1* histo = nullptr;
2303  if (obj->InheritsFrom("TLeaf")) {
2304  TLeaf* leaf = (TLeaf*)fChain->GetListOfLeaves()->FindObject(obj->GetName());//dynamic_cast<TLeaf*>(obj);
2305  TString expr = leaf->GetName();
2306  TString type = leaf->GetTypeName();
2307  // check histo not already in list
2308  TString htit;
2309  if (fUserWeight) GenerateHistoTitle(htit, expr, "", fWeight);
2310  else GenerateHistoTitle(htit, expr, "");
2311  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2312  if (kvhisto) histo = kvhisto->GetHisto();
2313  if (!histo) {
2314  if (type.Contains("Int_t") || type.Contains("Char_t") || type.Contains("Short_t") || type == "Long_t" || type == "Long64_t") {
2315  Int_t xmin = GetTreeMinimum(expr);
2316  Int_t xmax = GetTreeMaximum(expr);
2317  if (type.Contains("Char_t")) {
2318  TString tmp;
2319  tmp.Form("int(%s)", expr.Data());
2320  expr = tmp.Data();
2321  }
2322  histo = MakeIntHisto(expr, "", xmin, xmax, (fUserWeight ? fWeight.Data() : ""));
2323  if (!histo) return;
2324  histo->GetXaxis()->SetTitle(leaf->GetName());
2325  }
2326  else {
2327  histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2328  if (!histo) return;
2329  histo->GetXaxis()->SetTitle(leaf->GetName());
2330  }
2331  if (!histo) return;
2332  }
2333  DrawHisto(histo);
2334  }
2335  else {
2336  TString expr = obj->GetTitle();
2337  // check histo not already in list
2338  TString htit;
2339  GenerateHistoTitle(htit, expr, "", (fUserWeight ? fWeight.Data() : ""));
2340  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2341  if (kvhisto) histo = kvhisto->GetHisto();
2342  if (!histo) histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2343  if (!histo) return;
2344  histo->GetXaxis()->SetTitle(obj->GetTitle());
2345  DrawHisto(histo);
2346  }
2347 }
2348 
2349 
2350 
2353 
2355 {
2356  // Method called when user histo selection changes in GUI histogram list
2357 
2361  if (fSelectedHistos.GetEntries() > 0) {
2363  if (fSelectedHistos.GetEntries() == 1 && fSelectedHistos.First()->IsA() == TH1F::Class()) {
2364  }
2366  }
2367 }
2368 
2369 
2370 
2372 
2374 {
2376 }
2377 
2378 
2379 
2382 
2384 {
2385  // Look for selection in list of selections
2386  return (TEntryList*)fSelections.FindObjectByTitle(selection);
2387 }
2388 
2389 
2391 
2393 {
2394  fPROOFEnabled = yes;
2395  if (yes) {
2396 #ifdef WITH_PROOF
2397  // open new PROOF-lite session
2398  if (!gProof) TProof::Open("");
2399  if (fChain) fChain->SetProof(kTRUE);
2400 #endif
2401  }
2402  else {
2403  if (fChain) fChain->SetProof(kFALSE);
2404  }
2405 }
2406 
2407 
2408 
2410 
2412 {
2413  Info("Save", "Saving analysis %s in file %s", GetTitle(), fSaveAnalysisFileName.Data());
2416 }
2417 
2418 
2419 
2426 
2427 void KVTreeAnalyzer::SaveAs(const char* filename, Option_t*) const
2428 {
2429  // Override TObject::SaveAs
2430  // We need to:
2431  // - (re)create the file
2432  // - do fChain->SetDirectory before writing to disk
2433 
2434  // save current directory
2435  TDirectory* sav = gDirectory;
2436  TDirectory* chsav = (fChain ? fChain->GetDirectory() : nullptr);
2437 
2438  TFile* f = TFile::Open(filename, "recreate");
2439  Write();
2440  if (fChain) { // make sure TChain doesn't get redirected
2441  fChain->SetDirectory(chsav);
2442  }
2443  delete f;
2444 
2445  // back to original directory
2446  sav->cd();
2447 }
2448 
2449 
2450 // void KVTreeAnalyzer::FitGum1()
2451 // {
2452 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2453 // if(!histo) return;
2454 // GDfirst->SetParameters(histo->GetMean(),histo->GetRMS());
2455 // histo->Fit(GDfirst,"EM");
2456 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2457 // if(!stats){
2458 // histo->SetStats(1);
2459 // histo->Draw();
2460 // gPad->Update();
2461 // stats = (TPaveStats*)histo->FindObject("stats");
2462 // }
2463 // if(stats){
2464 // // if canvas's 'no stats' option has been set by user,
2465 // // there will still be no valid stats object,
2466 // // so this test is to avoid the ensuing seg fault
2467 // stats->SetFitFormat("10.9g");
2468 // stats->SetOptFit(111);
2469 // }
2470 // histo->SetOption("e1");
2471 // histo->SetMarkerStyle(24);
2472 // histo->SetMarkerColor(kBlue+2);
2473 // gPad->Modified();gPad->Update();
2474 // SetAnalysisModifiedSinceLastSave(kTRUE);
2475 // }
2476 // void KVTreeAnalyzer::FitGum2()
2477 // {
2478 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2479 // if(!histo) return;
2480 // GDsecond->SetParameters(histo->GetMean(),histo->GetRMS());
2481 // histo->Fit(GDsecond,"EM");
2482 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2483 // if(!stats){
2484 // histo->SetStats(1);
2485 // histo->Draw();
2486 // gPad->Update();
2487 // stats = (TPaveStats*)histo->FindObject("stats");
2488 // }
2489 // if(stats){
2490 // // if canvas's 'no stats' option has been set by user,
2491 // // there will still be no valid stats object,
2492 // // so this test is to avoid the ensuing seg fault
2493 // stats->SetFitFormat("10.9g");
2494 // stats->SetOptFit(111);
2495 // }
2496 // histo->SetOption("e1");
2497 // histo->SetMarkerStyle(24);
2498 // histo->SetMarkerColor(kBlue+2);
2499 // gPad->Modified();gPad->Update();
2500 // SetAnalysisModifiedSinceLastSave(kTRUE);
2501 // }
2502 // void KVTreeAnalyzer::FitGum3()
2503 // {
2504 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2505 // if(!histo) return;
2506 // GDthird->SetParameters(histo->GetMean(),histo->GetRMS());
2507 // histo->Fit(GDthird,"EM");
2508 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2509 // if(!stats){
2510 // histo->SetStats(1);
2511 // histo->Draw();
2512 // gPad->Update();
2513 // stats = (TPaveStats*)histo->FindObject("stats");
2514 // }
2515 // if(stats){
2516 // // if canvas's 'no stats' option has been set by user,
2517 // // there will still be no valid stats object,
2518 // // so this test is to avoid the ensuing seg fault
2519 // stats->SetFitFormat("10.9g");
2520 // stats->SetOptFit(111);
2521 // }
2522 // histo->SetOption("e1");
2523 // histo->SetMarkerStyle(24);
2524 // histo->SetMarkerColor(kBlue+2);
2525 // gPad->Modified();gPad->Update();
2526 // SetAnalysisModifiedSinceLastSave(kTRUE);
2527 // }
2528 // void KVTreeAnalyzer::FitGausGum1()
2529 // {
2530 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2531 // if(!histo) return;
2532 // GausGum1->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2533 // histo->Fit(GausGum1,"EM");
2534 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2535 // if(!stats){
2536 // histo->SetStats(1);
2537 // histo->Draw();
2538 // gPad->Update();
2539 // stats = (TPaveStats*)histo->FindObject("stats");
2540 // }
2541 // if(stats){
2542 // // if canvas's 'no stats' option has been set by user,
2543 // // there will still be no valid stats object,
2544 // // so this test is to avoid the ensuing seg fault
2545 // stats->SetFitFormat("10.9g");
2546 // stats->SetOptFit(111);
2547 // }
2548 // histo->SetOption("e1");
2549 // histo->SetMarkerStyle(24);
2550 // histo->SetMarkerColor(kBlue+2);
2551 // gPad->Modified();gPad->Update();
2552 // SetAnalysisModifiedSinceLastSave(kTRUE);
2553 // }
2554 //
2555 // void KVTreeAnalyzer::FitGausGum2()
2556 // {
2557 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2558 // if(!histo) return;
2559 // GausGum2->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2560 // histo->Fit(GausGum2,"EM");
2561 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2562 // if(!stats){
2563 // histo->SetStats(1);
2564 // histo->Draw();
2565 // gPad->Update();
2566 // stats = (TPaveStats*)histo->FindObject("stats");
2567 // }
2568 // if(stats){
2569 // // if canvas's 'no stats' option has been set by user,
2570 // // there will still be no valid stats object,
2571 // // so this test is to avoid the ensuing seg fault
2572 // stats->SetFitFormat("10.9g");
2573 // stats->SetOptFit(111);
2574 // }
2575 // histo->SetOption("e1");
2576 // histo->SetMarkerStyle(24);
2577 // histo->SetMarkerColor(kBlue+2);
2578 // gPad->Modified();gPad->Update();
2579 // SetAnalysisModifiedSinceLastSave(kTRUE);
2580 // }
2581 //
2582 // void KVTreeAnalyzer::FitGausGum3()
2583 // {
2584 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2585 // if(!histo) return;
2586 // GausGum3->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2587 // histo->Fit(GausGum3,"EM");
2588 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2589 // if(!stats){
2590 // histo->SetStats(1);
2591 // histo->Draw();
2592 // gPad->Update();
2593 // stats = (TPaveStats*)histo->FindObject("stats");
2594 // }
2595 // if(stats){
2596 // // if canvas's 'no stats' option has been set by user,
2597 // // there will still be no valid stats object,
2598 // // so this test is to avoid the ensuing seg fault
2599 // stats->SetFitFormat("10.9g");
2600 // stats->SetOptFit(111);
2601 // }
2602 // histo->SetOption("e1");
2603 // histo->SetMarkerStyle(24);
2604 // histo->SetMarkerColor(kBlue+2);
2605 // gPad->Modified();gPad->Update();
2606 // SetAnalysisModifiedSinceLastSave(kTRUE);
2607 // }
2608 
2609 
2614 
2616 {
2617  // fill and return TList with histos containing the given data
2618  // which may be 1D ("mult", "zmax", etc.) or 2D ("zmax:mult")
2619  // DELETE LIST AFTER USE
2620  TList* hlist = new TList;
2621  TIter next(&fHistolist);
2622 
2623  KVHistogram* h;
2624  while ((h = (KVHistogram*)next())) {
2625 
2626  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr)) hlist->Add(h->GetHisto());
2627  }
2628  return hlist;
2629 }
2630 
2631 
2632 
2636 
2638 {
2639  // fill and return TList with histos using the given selection criteria
2640  // DELETE LIST AFTER USE
2641  TList* hlist = new TList;
2642  TIter next(&fHistolist);
2643 
2644  KVHistogram* h;
2645  while ((h = (KVHistogram*)next())) {
2646 
2647  if (h->IsType("Histo") && !strcmp(h->GetSelection(), expr)) hlist->Add(h->GetHisto());
2648  }
2649  return hlist;
2650 }
2651 
2652 
2653 
2655 
2656 TH1* KVTreeAnalyzer::GetHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2657 {
2658  TIter next(&fHistolist);
2659 
2660  KVHistogram* h;
2661  while ((h = (KVHistogram*)next())) {
2662 
2663  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection)) {
2664  if (strcmp(weight, "")) {
2665  if (!strcmp(h->GetWeight(), weight)) return h->GetHisto();
2666  }
2667  else return h->GetHisto();
2668  }
2669  }
2670  return 0;
2671 }
2672 
2673 
2674 
2676 
2678 {
2679  return (KVHistogram*)fHistolist.FindObjectWithMethod(title, "GetHistoTitle");
2680 }
2681 
2682 
2683 
2685 
2686 void KVTreeAnalyzer::DeleteHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2687 {
2688  TIter next(&fHistolist);
2689 
2690  KVHistogram* h;
2691  while ((h = (KVHistogram*)next())) {
2692 
2693  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection) && !strcmp(h->GetWeight(), weight)) {
2694  fHistolist.Remove(h);
2695  delete h;
2697  }
2698  }
2700 }
2701 
2702 
2703 
2706 
2708 {
2709  // Delete all currently selected histograms
2710  if (fSelectedHistos.GetEntries()) {
2711  Int_t nsel = fSelectedHistos.GetEntries();
2712  if (nsel < 1) return;
2713  for (int i = 0; i < nsel; i++) {
2714  TObject* obj = fSelectedHistos.At(i);
2715  fHistolist.Remove(obj);
2716  delete obj;
2718  }
2720  }
2722 }
2723 
2724 
2725 
2730 
2732 {
2733  // Called when G_histo_add button is pressed
2734  // There should be 2 histograms in fSelectedHistos
2735  // We assume that both are of same type and have same binning etc.
2736 
2737  if (fSelectedHistos.GetEntries() != 2) return;
2738  HistoToAdd1 = dynamic_cast<KVHistogram*>(fSelectedHistos.At(0))->GetHisto();
2739  HistoToAdd2 = dynamic_cast<KVHistogram*>(fSelectedHistos.At(1))->GetHisto();
2740  if (HistoToAdd1 && HistoToAdd2) {
2741  Info("AddSelectedHistos", "Adding %s and %s", HistoToAdd1->GetName(), HistoToAdd2->GetName());
2742  TString name = Form("h%d", fHistoNumber);
2743  TString oldname = HistoToAdd1->GetName();
2744  if (oldname.BeginsWith("I")) name.Prepend("I");
2747  Bool_t ok = KVBase::OpenContextMenu("HistoAddition", this);
2748  if (!ok) {
2749  Info("AddSelectedHistos", "Call to context menu not OK");
2750  delete HistoAddResult;
2751  return;
2752  }
2753  if (MethodNotCalled()) {
2754  Info("AddSelectedHistos", "You pressed cancel");
2755  delete HistoAddResult;
2756  return;
2757  }
2758  ++fHistoNumber;
2760  }
2761  else {
2762  Info("AddSelectedHistos", "Only possible for 2 histograms");
2763  }
2764 }
2765 
2766 
2767 
2769 
2771 {
2772  fMethodCalled = kTRUE;
2774 // TODO: it would be nice to distinguish histograms which are the result of
2775 // adding other histograms together. For the moment they appear identical to
2776 // to the first histogram in terms of variables etc. The following attempt
2777 // doesn't work (can't parse the title correctly)
2778 // TString title;
2779 // title.Form("SUMHIST:{%s,%s}",HistoToAdd1->GetTitle(),HistoToAdd2->GetTitle());
2780 // HistoAddResult->SetTitle(title);
2781 }
2782 
2783 
2784 
2785 
2788 
2790 {
2791  // regenerate entry lists for all selections
2792  TList old_lists;
2793  old_lists.AddAll(&fSelections);
2794  fSelections.Clear();
2796  TIter next(&old_lists);
2797  TEntryList* old_el;
2798  SetEntryList(nullptr);
2799  SelectionChanged();
2800  while ((old_el = (TEntryList*)next())) {
2801  cout << "REGENERATING SELECTION : " << old_el->GetTitle() << endl;
2802  MakeSelection(old_el->GetTitle());
2803  ((TEntryList*)fSelections.Last())->SetReapplyCut(old_el->GetReapplyCut());
2805  }
2806  old_lists.Delete();
2807 }
2808 
2809 
2810 
2812 
2814 {
2815  switch (id) {
2816  case MH_OPEN_CHAIN:
2817  OpenChain();
2818  break;
2819  case MH_OPEN_FILE:
2821  break;
2822  case MH_ADD_FRIEND:
2824  break;
2825  case MH_APPLY_ANALYSIS:
2827  break;
2828  case MH_SAVE_FILE:
2830  break;
2831  case MH_SAVE:
2832  Save();
2833  break;
2834  case MH_CLOSE:
2835  delete fMain_histolist;
2836  GUIClosed();
2837  break;
2838  case MH_QUIT:
2839  // check all analyzers need saving
2840  while (fgAnalyzerList->GetEntries() > 1) {
2841  TIter next(fgAnalyzerList);
2843  do {
2844  tan = (KVTreeAnalyzer*)next();
2845  }
2846  while (tan == this);
2847  tan->AnalysisSaveCheck();
2848  delete tan;
2849  }
2851  gROOT->ProcessLine(".q");
2852  break;
2853 
2854  default:
2855  break;
2856  }
2857 }
2858 
2859 
2861 
2863 {
2864  switch (id) {
2865  case SEL_COMB_AND:
2867  break;
2868 
2869  case SEL_COMB_OR:
2871  break;
2872 
2873  case SEL_DELETE:
2874  DeleteSelections();
2875  break;
2876 
2877  case SEL_UPDATE:
2878  UpdateEntryLists();
2879  break;
2880 
2881  case SEL_GEN_CONST_XSEC:
2882  KVBase::OpenContextMenu("GenerateConstantXSecSelections", this);
2883  break;
2884 
2885  default:
2886  break;
2887  }
2888 }
2889 
2890 
2891 
2893 
2895 {
2896  switch (opt) {
2897  case OPT_PROOF:
2900  EnablePROOF(false);
2901  }
2902  else {
2904  EnablePROOF();
2905  }
2906  }
2907 }
2908 
2909 
2910 
2913 
2915 {
2916  // Open a previous analysis session
2917 
2918  static TString dir(".");
2919  const char* filetypes[] = {
2920  "Analysis files", "Analysis*.root",
2921  0, 0
2922  };
2923  TGFileInfo fi;
2924  fi.fFileTypes = filetypes;
2925  fi.fIniDir = StrDup(dir);
2926  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2927  if (fi.fFilename) {
2928  KVTreeAnalyzer* newAnal = this;
2929  if (fTree) newAnal = new KVTreeAnalyzer(kFALSE);
2930  newAnal->OpenAnyFile(fi.fFilename);
2931  }
2932  dir = fi.fIniDir;
2933 }
2934 
2935 
2936 
2938 
2940 {
2941  static TString dir(".");
2942  const char* filetypes[] = {
2943  "ROOT files", "*.root",
2944  0, 0
2945  };
2946  TGFileInfo fi;
2947  fi.fFileTypes = filetypes;
2948  fi.fIniDir = StrDup(dir);
2949  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2950  if (fi.fFilename) {
2952  }
2953  dir = fi.fIniDir;
2954 }
2955 
2956 
2959 
2961 {
2962  // Open a file or files containing TTrees to analyse
2963 
2964  static TString dir(".");
2965  const char* filetypes[] = {
2966  "ROOT files", "*.root*",
2967  0, 0
2968  };
2969  TGFileInfo fi;
2970  fi.fFileTypes = filetypes;
2971  fi.fIniDir = StrDup(dir);
2973  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2974  if (fi.fFileNamesList && fi.fFileNamesList->GetEntries()) {
2975 
2976  // look in first file to find first TTree and use its name/title
2977  TString theTreeName, theTreeTitle;
2979  KVUnownedList keys;
2980  keys.AddAll(file->GetListOfKeys());
2981  // Get list of trees in file
2982  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
2983  if (trees->GetEntries()) {
2984  theTreeName = trees->First()->GetName();
2985  theTreeTitle = trees->First()->GetTitle();
2986  }
2987  if (theTreeName != "") {
2988  // if analysis already en cours, open new GUI
2989  KVTreeAnalyzer* newAnal = this;
2991  newAnal->OpenChain(theTreeName, theTreeTitle, fi.fFileNamesList);
2992  if (fi.fFileNamesList->GetEntries() == 1) {
2993  // if a single file is selected, look to see if any histograms are in it
2994  newAnal->GetHistosFromFile(file, keys);
2995  }
2996  }
2997  else { // no TTree in file - look for histograms
2998  if (fi.fFileNamesList->GetEntries() == 1) {
2999  // if analysis already en cours, open new GUI
3000  KVTreeAnalyzer* newAnal = this;
3002  // if a single file is selected, look to see if any histograms are in it
3003  newAnal->GetHistosFromFile(file, keys);
3004  if(newAnal->got_histos_or_tree_from_file) newAnal->SetWindowTitle(file->GetName());
3005  }
3006  }
3007  }
3008  dir = fi.fIniDir;
3009 }
3010 
3011 
3012 
3014 
3016 {
3017  static TString dir(".");
3018  const char* filetypes[] = {
3019  "ROOT files", "*.root",
3020  0, 0
3021  };
3022  TGFileInfo fi;
3023  fi.fFileTypes = filetypes;
3024  fi.fIniDir = StrDup(dir);
3025  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3026  if (fi.fFilename) {
3028  }
3029  dir = fi.fIniDir;
3030 }
3031 
3032 
3033 
3035 
3037 {
3038  const char* filetypes[] = {
3039  "Analysis files", "Analysis*.root",
3040  0, 0
3041  };
3042  TGFileInfo fi;
3043  fi.fFileTypes = filetypes;
3046  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDSave, &fi);
3047  if (fi.fFilename) {
3048  //if no ".xxx" ending given, we add ".root"
3049  TString filenam(fi.fFilename);
3050  if (!filenam.Contains('.'))
3051  filenam += ".root";
3052  // update name of file to autosave analysis in
3053  fSaveAnalysisFileName = filenam;
3054  Save();
3055  }
3057 }
3058 
3059 
3060 
3062 
3064 {
3065  TIter next(&keys);
3066  TKey* akey;
3067  while ((akey = (TKey*)next())) {
3068  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3069  if (!fHistolist.FindObject(akey->GetName())) {
3070  TH1* h = (TH1*)file->Get(akey->GetName());
3071  h->SetDirectory(0);
3072  fHistolist.Add(new KVHistogram(h));
3074  }
3075  }
3076  }
3078 }
3079 
3080 
3081 
3084 
3085 void KVTreeAnalyzer::OpenSingleFile(TFile* file)
3086 {
3087  // Open TTree in file (as a TChain) and import any histograms found in file
3088 
3089  fHistolist.Clear();
3090  KVUnownedList keys;
3091  keys.AddAll(file->GetListOfKeys());
3092  // Get list of trees in file
3093  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3094  if (trees->GetEntries()) {
3095  // Get name of first tree
3096  TString aTreeName = trees->First()->GetName();
3097  TString aFileName = file->GetName();
3098  TList fileList;
3099  TNamed ff(aFileName.Data(), "File Name");
3100  fileList.Add(&ff);
3101  OpenChain(aTreeName, trees->First()->GetTitle(), &fileList);
3102  }
3103  else
3104  SetWindowTitle(file->GetName()); // set GUI window name to file name if no TTree found
3105  GetHistosFromFile(file, keys);
3106 }
3107 
3108 
3109 
3113 
3115 {
3116  // assuming filepath is the URL of a ROOT file containing a previously-saved analysis, open it and
3117  // open the KVTreeAnalyzer object stored in it
3118 
3120 
3121  TFile* file = TFile::Open(filepath);
3122  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3123  if (kvta) {
3124  ReadFromFile(file);
3125  }
3126  else {
3127  OpenSingleFile(file);
3128  }
3130 }
3131 
3132 
3133 
3138 
3139 void KVTreeAnalyzer::OpenChain(const TString& treename, const TString& treetitle, const TSeqCollection* files)
3140 {
3141  // Open a TChain for analysis
3142  // treename/title is the name/title of the TTree :)
3143  // files is a list of objects with the names of the files in the chain
3144 
3145  fChain = new TChain(treename, treetitle);
3146  TIter nxt(files);
3147  TObject* o;
3148  while ((o = nxt())) fChain->Add(o->GetName());
3149  fChain->SetDirectory(0);
3150  SetTree(fChain);
3151  fHistolist.Clear();
3152  fSelections.Clear();
3153  fAliasList.Clear();
3154  fHistoNumber = 1;
3155  fSelectionNumber = 1;
3156  fAliasNumber = 1;
3157  fSameColorIndex = 0;
3158  fSelectedLeaves = 0;
3162  FillLeafList();
3164 }
3165 
3166 
3167 
3170 
3172 {
3173  // Generate all user aliases in list which are not already defined
3174 
3175  if (list->GetEntries()) {
3176  TIter next(list);
3177  TObject* o;
3178  while ((o = next())) {
3179  if (!GetAlias(o->GetTitle())) {
3180  Info("GenerateAllAliases", "Adding alias %s to leaflist", o->GetTitle());
3182  GenerateAlias();
3183  }
3184  }
3185  }
3186 }
3187 
3188 
3189 
3198 
3200 {
3201  // assuming filepath is the URL of a ROOT file, open it and,
3202  // if no KVTreeAnalyzer object is found, open first TTree in file
3203  // and apply all selections and generate all histograms which
3204  // were made for this analysis.
3205  // Any histograms in the file are added to the list of histograms.
3206  // If filepath contains an existing analysis, we add to it any
3207  // histograms/selections/aliases which are not defined
3208 
3209  TFile* file = TFile::Open(filepath);
3210  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3211  if (kvta) {
3212  // open existing analysis, add any missing histos/selections/aliases
3213  delete file;
3214  KVTreeAnalyzer* applyAnal = OpenFile(filepath);
3215  applyAnal->GenerateAllSelections(&fSelections);
3216  applyAnal->GenerateAllHistograms(&fHistolist);
3217  applyAnal->GenerateAllAliases(&fAliasList);
3218  return;
3219  }
3220  else {
3221  delete file;
3222  KVTreeAnalyzer* applyAnal = new KVTreeAnalyzer(kFALSE);
3223  applyAnal->OpenAnyFile(filepath);
3224  applyAnal->GenerateAllSelections(&fSelections);
3225  applyAnal->GenerateAllHistograms(&fHistolist);
3226  // make sure no selection is left active without being displayed
3227  applyAnal->SetEntryList(nullptr);
3228  applyAnal->G_selection_status->SetText("CURRENT SELECTION:", 0);
3229  applyAnal->GenerateAllAliases(&fAliasList);
3230  }
3231 }
3232 
3233 
3234 
3236 
3237 void KVTreeAnalyzer::SetAlias(const Char_t* name, const Char_t* expr)
3238 {
3239  TString exp = expr;
3240  exp.ReplaceAll("d2r", "TMath::DegToRad()");
3241  exp.ReplaceAll("r2d", "TMath::RadToDeg()");
3242  fAliasList.Add(new TNamed(name, exp.Data()));
3244 }
3245 
3246 
3247 
3249 
3250 static const char* gSaveAsTypes[] = { "PostScript", "*.ps",
3251  "Encapsulated PostScript", "*.eps",
3252  "PDF", "*.pdf",
3253  "SVG", "*.svg",
3254  "TeX", "*.tex",
3255  "GIF", "*.gif",
3256  "ROOT files", "*.root",
3257  "XML", "*.xml",
3258  "PNG", "*.png",
3259  "XPM", "*.xpm",
3260  "JPEG", "*.jpg",
3261  "TIFF", "*.tiff",
3262  "XCF", "*.xcf",
3263  0, 0
3264  };
3265 
3266 
3267 
3272 
3274 {
3275  // Open file dialog box for user to choose directory and
3276  // image file-type for generating picture files of all
3277  // histos as they are drawn
3278 
3279  Info("SetUpHistoAutoSave", "Select image filetype and directory");
3280  TString workdir = gSystem->WorkingDirectory();
3281  static TString dir(".");
3282  static Int_t typeidx = 0;
3283  static Bool_t overwr = kFALSE;
3284  TGFileInfo fi;
3285  fi.fFileTypes = gSaveAsTypes;
3286  fi.fIniDir = StrDup(dir);
3287  fi.fFileTypeIdx = typeidx;
3288  fi.fOverwrite = overwr;
3289  new KVFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kKVFDDirectory, &fi);
3290  gSystem->ChangeDirectory(workdir.Data());
3291  TString ft = fi.fFileTypes[fi.fFileTypeIdx + 1];
3292  dir = fi.fIniDir;
3293  typeidx = fi.fFileTypeIdx;
3294  overwr = fi.fOverwrite;
3295  fAutoSaveDir = dir.Data();
3296  fAutoSaveType = ft(1, ft.Length()).Data();
3297  Info("SetUpHistoAutoSave", "file-type:%s directory:%s", fAutoSaveType.Data(), fAutoSaveDir.Data());
3298 }
3299 
3300 
3301 
3305 
3307 {
3308  // Save currently displayed histo as an image file
3309  // If 'same' checkbox is ticked, we use the same filename as used for the first histogram
3310 
3311  static TString lastFilename = "";
3312 
3313  if (fDrawSame) {
3314  gPad->SaveAs(lastFilename);
3315  return;
3316  }
3317  TString title = h->GetTitle();
3318  title.ReplaceAll(" ", "_");
3319  title.ReplaceAll("/", "#");
3320  title.ReplaceAll("*", "x");
3321  title.ReplaceAll("$", "#");
3322  title.ReplaceAll("(", "[");
3323  title.ReplaceAll(")", "]");
3324  title.Append(fAutoSaveType);
3325  title.Prepend("/");
3326  title.Prepend(fAutoSaveDir);
3327  Info("AutoSaveHisto", "Saved as: %s", title.Data());
3328  gPad->SaveAs(title);
3329  lastFilename = title;
3330 }
3331 
3332 
3333 
3337 
3339 {
3340  // We take the title of every object in 'list' and generate the corresponding selection
3341  // if it does not already exist
3342 
3343  TIter nextSel(list);
3344  TObject* sel;
3345  while ((sel = nextSel())) {
3346  if (!GetSelection(sel->GetTitle())) {
3347  Info("GenerateAllSelections", "Generating selection: %s", sel->GetTitle());
3348  MakeSelection(sel->GetTitle());
3349  }
3350  }
3351 }
3352 
3353 
3354 
3358 
3360 {
3361  // For every histogram in the list, we generate histograms with the same binning for
3362  // the same expression, selection and weight if they don't already exist
3363 
3364  TIter nextHist(list);
3365  KVHistogram* obj;
3366  TH1* hist;
3367  while ((obj = (KVHistogram*)nextHist())) {
3368  if (!obj->IsType("Cut")) {
3369  hist = obj->GetHisto();
3370  if (GetHistoByTitle(hist->GetTitle())) continue;
3371  TString exp = obj->GetExpression();
3372  TString sel = obj->GetSelection();
3373  TString weight = obj->GetWeight();
3374  if (weight == "1") weight = "";
3375  // set selection
3376  Info("GenerateAllHistograms", "Generating histogram: %s", hist->GetTitle());
3377  SetSelection(sel);
3378  RemakeHisto(hist, exp, weight);
3379  }
3380  }
3381 }
3382 
3383 
3384 
3394 
3396 {
3397  // Read serialized object from file
3398  //
3399  // For versions < 4, fHistolist contained TH* or TCutG objects:
3400  // we convert to a list of KVHistogram objects.
3401  //
3402  // Flag will be set to say analysis needs saving.
3403  //
3404  // Reparse all histogram expressions and selections in case they were not saved correctly.
3405 
3406  UInt_t R__s, R__c;
3407  if (R__b.IsReading()) {
3408  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3409  R__b.ReadClassBuffer(KVTreeAnalyzer::Class(), this, R__v, R__s, R__c);
3410  if (R__v < 5) {
3411  // no fChain pointer member before v5
3412  ReconnectTree();
3413  }
3414  if (fChain && fTree != fChain) SetTree(fChain);
3415  if (fChain) {
3417  Info("Streamer", "Checking friends");
3418  // check friends are TChains, not TTrees & they have valid pointers
3419  TFriendElement* fe;
3420  TIter nxt(fChain->GetListOfFriends());
3421  KVNumberList toRemove;
3422  KVNameValueList infos;
3423  int idx = 0;
3424  while ((fe = (TFriendElement*)nxt())) {
3425  if (!fe->GetTree() || (fe->GetTree() && !fe->GetTree()->InheritsFrom("TChain"))) {
3426  Info("Streamer", "Found friend to convert to TChain");
3427  toRemove.Add(idx);
3428  infos.SetValue(Form("treeName%d", idx), fe->GetTreeName());
3429  if (!fe->GetFile()) {
3430  Info("Streamer", "Choose file containg friend tree %s", fe->GetTreeName());
3431  static TString dir(".");
3432  const char* filetypes[] = {
3433  "ROOT files", "*.root",
3434  0, 0
3435  };
3436  TGFileInfo fi;
3437  fi.fFileTypes = filetypes;
3438  fi.fIniDir = StrDup(dir);
3439  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3440  if (fi.fFilename) {
3441  infos.SetValue(Form("fileName%d", idx), fi.fFilename);
3442  }
3443  dir = fi.fIniDir;
3444  }
3445  else
3446  infos.SetValue(Form("fileName%d", idx), fe->GetFile()->GetName());
3447  }
3448  ++idx;
3449  }
3450  if (toRemove.GetEntries()) {
3451  Info("Streamer", "Removing TTree friends");
3452  toRemove.Begin();
3453  while (!toRemove.End()) {
3454  fChain->RemoveFriend(fChain->GetFriend(infos.GetStringValue(Form("treeName%d", toRemove.Next()))));
3455  }
3456  toRemove.Begin();
3457  Info("Streamer", "Adding friends as TChains");
3458  while (!toRemove.End()) {
3459  idx = toRemove.Next();
3460  TChain* friendChain = new TChain(infos.GetStringValue(Form("treeName%d", idx)));
3461  friendChain->Add(infos.GetStringValue(Form("fileName%d", idx)));
3462  fChain->AddFriend(friendChain);
3463  }
3464  }
3465  }
3466  }
3467  if (R__v < 4) {
3468  //Info("Streamer","Converting old histo list");
3469  // convert fHistolist
3470  if (fHistolist.GetEntries()) {
3471  TList tmp;
3472  tmp.AddAll(&fHistolist);
3473  fHistolist.Clear("nodelete");
3474  TNamed* obj;
3475  TIter next(&tmp);
3476  while ((obj = (TNamed*)next())) {
3477  if (obj->InheritsFrom("TCutG"))
3478  fHistolist.Add(new KVHistogram(dynamic_cast<TCutG*>(obj)));
3479  else if (obj->InheritsFrom("TH1"))
3480  fHistolist.Add(new KVHistogram(dynamic_cast<TH1*>(obj)));
3481  }
3482  //Info("Streamer","New histolist:");
3483  fHistolist.ls();
3485  }
3486  }
3487  if (fHistolist.GetEntries()) {
3488  TIter next(&fHistolist);
3489  KVHistogram* h;
3490  while ((h = (KVHistogram*)next())) {
3491  if (h->IsType("Histo")) h->ParseExpressionAndSelection();
3492  }
3493  }
3494  }
3495  else {
3497  }
3498 }
3499 
3500 
3501 
3506 
3508 {
3509  // assuming filepath is the URL of a ROOT file, open it and
3510  // add the first TTree found in file as a friend of the current TTree
3511  // Any histograms in the file are added to the list of histograms
3512 
3513  TFile* file = TFile::Open(filepath);
3514  KVUnownedList keys;
3515  keys.AddAll(file->GetListOfKeys());
3516  // Get list of trees in file
3517  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3518  if (trees->GetEntries()) {
3519  // Get name of first tree
3520  TString aTreeName = trees->First()->GetName();
3521  TChain* t = new TChain(aTreeName);
3522  t->Add(filepath);
3523  fChain->AddFriend(t);
3524  FillLeafList();
3525  }
3526  TIter next(&keys);
3527  TKey* akey;
3528  while ((akey = (TKey*)next())) {
3529  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3530  if (!fHistolist.FindObject(akey->GetName())) {
3531  TH1* h = (TH1*)file->Get(akey->GetName());
3532  h->SetDirectory(0);
3533  fHistolist.Add(new KVHistogram(h));
3534  }
3535  }
3536  }
3538 }
3539 
3540 
3541 
3542 
3543 
3544 
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:189
static Bool_t OpenContextMenu(const char *method, TObject *obj, const char *alt_method_name="")
Definition: KVBase.cpp:1479
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:91
Extension of TGLVContainer for KVListView widget.
Enhanced version of ROOT TGListView widget.
Definition: KVListView.h:146
virtual void ActivateSortButtons()
Definition: KVListView.cpp:72
KVSeqCollection * GetPickOrderedSelectedObjects() const
Definition: KVListView.h:258
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
KVUnownedList GetSelectedObjects() const
Definition: KVListView.h:252
virtual void SetMaxColumnSize(UInt_t width)
Definition: KVListView.h:161
virtual void RemoveAll()
Definition: KVListView.h:193
void AllowContextMenu(Bool_t on=kTRUE)
Definition: KVListView.h:291
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:22
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
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.
KVUnownedList fSelectedHistos
static KVUnownedList * fgAnalyzerList
static list of all analyzers in memory
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
const Char_t * get_leaf_type_name(const TNamed *l)
Bool_t fApplySelection
=kTRUE: apply current selection to existing histogram
void SetWindowTitle(const TString &tt)
TString fTreeName
name of analyzed TTree
TString fAnalysisSaveDir
Bool_t fDrawSame
=kTRUE: draw histograms in same plot
void GenerateAllAliases(TCollection *list)
Generate all user aliases in list which are not already defined.
Int_t fAliasNumber
used for automatic naming of TTree aliases
void SaveAs(const char *filename="", Option_t *option="") const override
void Copy(TObject &obj) const override
TH1 * RemakeHisto(TH1 *h, const Char_t *expr, const Char_t *weight="")
KVSeqCollection * fSelectedLeaves
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)
TString fTreeFileName
name of file containing analyzed TTree
void DeleteSelectedHisto()
Delete all currently selected histograms.
void GUIClosed()
Called when graphical window is closed.
TEntryList * GetSelection(const Char_t *)
Look for selection in list of selections.
Bool_t IsCurrentSelection(const Char_t *sel)
void AutoSaveHisto(TH1 *h)
TGTextEntry * G_alias_text
TGPopupMenu * fSelCombMenu
Bool_t fNewCanvas
=kTRUE: draw each histogram in a new canvas
void init()
Default initialization.
TString fRelativePathToAnalysisFile
TGCheckButton * G_histo_log
void AddHisto(TH1 *)
TGComboBox * G_histo_draw_option
KVUniqueNameList fSelections
list of TEntryList user selections
bool got_histos_or_tree_from_file
void GenerateAllHistograms(TCollection *)
Bool_t fNormHistoEvents
=kTRUE: generate normalised histograms (normalise to number of events)
void SetSelection(TObject *)
void CurrentSelection()
Print the currently active selection (TEntryList set on TTree).
KVList fLeafList
clones of leaves in TChain
TGCheckButton * G_histo_weight
void UpdateEntryLists()
regenerate entry lists for all selections
TGCheckButton * G_histo_prof
void SetEntryList(TEntryList *)
void DrawCut(TCutG *)
void HistoAddition(Double_t c1=1, Double_t c2=1)
void OpenGUI()
Launch the GUI (unless fNoGui=kTRUE in which case this does nothing)
void HistoFileMenu_OpenFriend()
TGPictureButton * G_histo_add
void SetRelativePathToAnalysisFile(const Char_t *p)
TGPictureButton * G_histo_del
TGCheckButton * G_histo_stats
KVTreeAnalyzer(Bool_t nogui=kTRUE)
TGCheckButton * G_histo_new_can
void HandleHistoFileMenu(Int_t)
TGCheckButton * G_histo_bin
void HandleOptionsMenu(Int_t opt)
TGGroupFrame * fMain_selectionlist
GUI for handling selections.
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
KVUnownedList fSelectedSelections
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
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:20
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
virtual Bool_t IsEmpty() 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
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)