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 
54 KVUnownedList* KVTreeAnalyzer::fgAnalyzerList = new KVUnownedList;
55 
56 
59 
60 void KVTreeAnalyzer::init()
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
148  if (!fDeletedByGUIClose) SafeDelete(fMain_histolist);
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
183  CastedObj.SetAnalysisModifiedSinceLastSave(fAnalysisModifiedSinceLastSave);
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 
420  KVHistogram* h = (KVHistogram*)fHistolist.FindObject(name);
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(">>");
471 #ifdef WITH_PROOF
472  fChain->SetProof(kFALSE);
474 #endif
475  if (fChain->Draw(drawexp, selection, "entrylist") < 0) {
476  new TGMsgBox(gClient->GetRoot(), 0, "Warning", "Mistake in your new selection!", kMBIconExclamation, kMBClose);
477  return kFALSE;
478  }
479 #ifdef WITH_PROOF
481 #endif
482  TEntryList* el;
483 #ifdef WITH_PROOF
486  else
487 #endif
488  el = (TEntryList*)gDirectory->Get(name);
489  el->SetTitle(selection);//needed with PROOF
490  if (fChain->GetEntryList()) {
491  TString _elist = fChain->GetEntryList()->GetTitle();
492  TString title;
493  title.Form("(%s) && (%s)", _elist.Data(), selection);
494  el->SetTitle(title);
495  }
496  fSelectionNumber++;
497  AddSelection(el);
499  return kTRUE;
500 }
501 
502 
503 
511 
513 {
514  // Method called when a selection is double-clicked in the GUI list.
515  // The required selection is passed as argument (address of TEntryList object)
516  // and becomes the currently active selection (TEntryList set on TTree).
517  // If the requested selection was already active, it is deactivated
518  // (remove TEntryList from TTree).
519  // The 'CURRENT SELECTION' message in the GUI status bar is updated.
520 
521  if (!obj->InheritsFrom("TEntryList")) return;
522  TEntryList* el = dynamic_cast<TEntryList*>(obj);
523  if (fChain->GetEntryList() == el) {
524  SetEntryList(nullptr);
525  G_selection_status->SetText("CURRENT SELECTION:", 0);
526  return;
527  }
528  SetEntryList(el);
529  G_selection_status->SetText(Form("CURRENT SELECTION: %s (%lld)", el->GetTitle(), el->GetN()), 0);
530 }
531 
532 
533 
536 
538 {
539  // Print the currently active selection (TEntryList set on TTree).
540 
541  TString tmp;
542  if (fChain->GetEntryList()) tmp = fChain->GetEntryList()->GetTitle();
543  else tmp = "";
544  if (tmp != "") cout << "CURRENT SELECTION : " << tmp << endl;
545 }
546 
547 
548 
552 
554 {
555  // Return number of entries (events) in the currently active selection,
556  // or the number of entries in the analysed TTree/TChain if no selection active
557 
558  if (fChain->GetEntryList()) return fChain->GetEntryList()->GetN();
559  return fChain->GetEntries();
560 }
561 
562 
563 
567 
568 void KVTreeAnalyzer::FillLeafList()
569 {
570  // Fills the GUI list with the names of all leaves in the TTree
571  // and any friend TTrees and all aliases defined by the user
572 
573  TList stuff;
574  if (fTree) {
575  // clone list of leaves
576  fLeafList.Clear();
577  TCollection* clones = (TCollection*)fTree->GetListOfLeaves()->Clone();
578  // when using a split object to fill the tree
579  // there is a redundant leaf/branch corresponding to the object itself
580  // more precisely there will be a TLeafElement in the list of leaves
581  // and a TBranchElement in the list of branches with the same name
582  //
583  // however the same applies to a simple unsplit object (such as using a TString to store
584  // strings). as the latter is probably far more common than the former (who creates trees
585  // with split objects in them these days???), I comment out the check which stopped such
586  // leaves appearing in the GUI (they are perfectly usable).
587  TIter next(clones);
588  TObject* o;
589  while ((o = next())) {
590 // if (o->InheritsFrom("TLeafElement")
591 // && fTree->GetListOfBranches()->FindObject(o->GetName())
592 // && fTree->GetListOfBranches()->FindObject(o->GetName())->InheritsFrom("TBranchElement"))
593 // continue;
594  fLeafList.Add(o);
595  }
596  delete clones;
597 
598  stuff.AddAll(&fLeafList);
599  stuff.AddAll(fTree->GetListOfAliases());
600  if (fTree->GetListOfFriends()) {
601  TIter it(fTree->GetListOfFriends());
602  TFriendElement* fel;
603  while ((fel = (TFriendElement*)it())) {
604  stuff.AddAll(fel->GetTree()->GetListOfLeaves());
605  stuff.AddAll(fel->GetTree()->GetListOfAliases());
606  }
607  }
608  }
609  stuff.AddAll(&fAliasList);
610  G_leaflist->Display(&stuff);
611 }
612 
613 
614 
618 
619 void KVTreeAnalyzer::AnalysisSaveCheck()
620 {
621  // if analysis has been modified since last save,
622  // open an invite to ask if user wants to save with current default filename
623 
624  if (!fAnalysisModifiedSinceLastSave) return;
625 
626  if (fNoGui) {
627  // text-only interface
628  cout << "Analysis " << GetTitle() << " has been modified. Save before continuing? [y] : " << flush;
629  char reply;
630  cin.get(reply);
631  cout << endl;
632  if (reply == 'n' || reply == 'N') return;
633  cout << "Give name of file [" << fSaveAnalysisFileName << "] : " << flush;
634  char filename[256];
635  cin.get(filename, 256);
636  if (filename[0] != 0) fSaveAnalysisFileName = filename;
637  Save();
638  }
639  else {
640  Int_t ret_code;
641  if (fMain_histolist) fMain_histolist->RaiseWindow();
642  new TGMsgBox(gClient->GetDefaultRoot(), (fMain_histolist ? fMain_histolist : gClient->GetDefaultRoot()), GetTitle(),
643  "Analysis has been modified. Save before continuing?", kMBIconStop,
644  kMBYes | kMBNo, &ret_code);
645  if (ret_code == kMBNo) return;
646  HistoFileMenu_Save();
647  }
648 }
649 
650 
651 
653 
654 void KVTreeAnalyzer::SetAnalysisModifiedSinceLastSave(Bool_t x)
655 {
656  fAnalysisModifiedSinceLastSave = x;
657  if (fMenuFile) {
658  if (x) {
659  fMenuFile->EnableEntry(MH_SAVE);
660  fMenuFile->EnableEntry(MH_SAVE_FILE);
661  }
662  else {
663  fMenuFile->DisableEntry(MH_SAVE);
664  fMenuFile->DisableEntry(MH_SAVE_FILE);
665  }
666  }
667 }
668 
669 
670 
679 
680 void KVTreeAnalyzer::SetEntryList(TEntryList* l)
681 {
682  // Modify currently active selection (TEntryList)
683  // Instead of calling
684  // fChain->SetEntryList(l);
685  // call this method which works with or without PROOF.
686  // When using PROOF, fChain->SetEntryList(nullptr)
687  // does not work (bug in TProofChain), the last selection
688  // remains active. This problem is corrected here.
689 
690  fChain->SetEntryList(l);
691 
692 #ifdef WITH_PROOF
693  if (l == nullptr && IsPROOFEnabled()) {
694  fChain->SetProof(kFALSE);
695  fChain->SetProof(kTRUE);
696  }
697 #endif
698 }
699 
700 
701 
704 
706 {
707  // Launch the GUI (unless fNoGui=kTRUE in which case this does nothing)
708 
709  if (fNoGui) return;
710 
711  ULong_t red, cyan, green, yellow, magenta, gura, gurb, gurc, gurd, gure, gurf;
712  gClient->GetColorByName("#ff00ff", magenta);
713  gClient->GetColorByName("#ff0000", red);
714  gClient->GetColorByName("#00ff00", green);
715  gClient->GetColorByName("#00ffff", cyan);
716  gClient->GetColorByName("#ffff00", yellow);
717  gClient->GetColorByName("#cf14b2", gura);
718  gClient->GetColorByName("#cd93e6", gurb);
719  gClient->GetColorByName("#c1e91a", gurc);
720  gClient->GetColorByName("#d1a45b", gurd);
721  gClient->GetColorByName("#b54cfe", gure);
722  gClient->GetColorByName("#a325ef", gurf);
723 
724  /********* MAIN WINDOW **************/
725  //
726  fMain_histolist = new TGMainFrame(gClient->GetRoot(), 10, 10, kMainFrame | kVerticalFrame);
727  fMain_histolist->SetName("fMain_histolist");
728  if (!fTree)
729  fMain_histolist->SetWindowName("Tree Analyzer");
730  else
731  fMain_histolist->SetWindowName(Form("%s (%s)", fTree->GetTitle(), fTreeFileName.Data()));
732  fMain_histolist->SetIconName("TreeAnalyzer");
733  fMain_histolist->SetIconPixmap("root_s.xpm");
734 
735  fMain_histolist->SetCleanup(kDeepCleanup);
736 
737  UInt_t hWidth = 400, hHeight = 400;
738 
739  /* menus */
740  fMenuFile = new TGPopupMenu(gClient->GetRoot());
741  fMenuFile->AddEntry("New analysis", MH_OPEN_CHAIN);
742  fMenuFile->AddEntry("Open analysis", MH_OPEN_FILE);
743  fMenuFile->AddEntry("Add Friend...", MH_ADD_FRIEND);
744  fMenuFile->DisableEntry(MH_ADD_FRIEND);
745  fMenuFile->AddEntry("Save analysis", MH_SAVE);
746  fMenuFile->AddEntry("Save as...", MH_SAVE_FILE);
747  fMenuFile->AddEntry("Close", MH_CLOSE);
748  fMenuFile->AddSeparator();
749  fMenuFile->AddEntry("Apply analysis...", MH_APPLY_ANALYSIS);
750  SetAnalysisModifiedSinceLastSave(fAnalysisModifiedSinceLastSave);
751  fMenuFile->AddSeparator();
752  fMenuFile->AddEntry("Quit", MH_QUIT);
753  fMenuFile->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleHistoFileMenu(Int_t)");
754  fMenuSelections = new TGPopupMenu(gClient->GetRoot());
755  fSelCombMenu = new TGPopupMenu(gClient->GetRoot());
756  fSelCombMenu->AddEntry("AND (&&)", SEL_COMB_AND);
757  fSelCombMenu->AddEntry("OR (||)", SEL_COMB_OR);
758  fMenuSelections->AddPopup("Combine...", fSelCombMenu);
759  fSelCombMenu->DisableEntry(SEL_COMB_AND);
760  fSelCombMenu->DisableEntry(SEL_COMB_OR);
761  fMenuSelections->AddEntry("Update", SEL_UPDATE);
762  fMenuSelections->AddEntry("Delete", SEL_DELETE);
763  fMenuSelections->DisableEntry(SEL_DELETE);
764  fSelGenerate = new TGPopupMenu(gClient->GetRoot());
765  fSelGenerate->AddEntry("Constant X-sections", SEL_GEN_CONST_XSEC);
766  fMenuSelections->AddPopup("Generate...", fSelGenerate);
767  fMenuSelections->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleSelectionsMenu(Int_t)");
768  fOptionMenu = new TGPopupMenu(gClient->GetRoot());
769  fOptionMenu->AddEntry("PROOF", OPT_PROOF);
770  fOptionMenu->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleOptionsMenu(Int_t)");
771  fMenuBarItemLayout = new TGLayoutHints(kLHintsTop | kLHintsLeft, 0, 4, 0, 0);
772  fMenuBar = new TGMenuBar(fMain_histolist, 1, 1, kHorizontalFrame);
773  fMenuBar->AddPopup("&File", fMenuFile, fMenuBarItemLayout);
774  fMenuBar->AddPopup("&Options", fOptionMenu, fMenuBarItemLayout);
775  fMenuBar->AddPopup("&Selections", fMenuSelections, fMenuBarItemLayout);
776  fMain_histolist->AddFrame(fMenuBar, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX, 0, 0, 1, 1));
777  TGHorizontal3DLine* lh = new TGHorizontal3DLine(fMain_histolist);
778  fMain_histolist->AddFrame(lh, new TGLayoutHints(kLHintsTop | kLHintsExpandX));
779 
780  // Horizontal frame to contain the VARIABLES list (left) and SELECTIONS list (right)
781  TGHorizontalFrame* hf = new TGHorizontalFrame(fMain_histolist);
782 
783  /********* VARIABLES **************/
784  // Group frame for TTree variables/aliases
785  fMain_leaflist = new TGGroupFrame(hf, "VARIABLES");
786  UInt_t lWidth = 300, lHeight = 300;
787  /* leaf list */
788 
789  /* make selection */
790  TGHorizontalFrame* fHorizontalFrame = new TGHorizontalFrame(fMain_leaflist, lWidth, 36, kHorizontalFrame);
791  TGLabel* lab = new TGLabel(fHorizontalFrame, "Make alias : ");
792  fHorizontalFrame->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
793  G_alias_text = new TGTextEntry(fHorizontalFrame, new TGTextBuffer(50));
794  G_alias_text->SetMaxLength(4096);
795  G_alias_text->SetAlignment(kTextLeft);
796  G_alias_text->Resize(lWidth - 100, G_alias_text->GetDefaultHeight());
797  G_alias_text->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateAlias()");
798  fHorizontalFrame->AddFrame(G_alias_text, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 2, 5, 2, 2));
799  fMain_leaflist->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
800 
801  G_leaflist = new KVListView(TNamed::Class(), fMain_leaflist, lWidth, lHeight);
802  G_leaflist->SetDataColumns(1);
803  G_leaflist->SetDataColumn(0, "Title");
804  G_leaflist->ActivateSortButtons();
805  G_leaflist->AllowContextMenu(kFALSE);
806  G_leaflist->SetDoubleClickAction("KVTreeAnalyzer", this, "DrawLeaf(TObject*)");
807  G_leaflist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "LeafChanged()");
808 // G_leaflist->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "ShowVar()");
809  fMain_leaflist->AddFrame(G_leaflist, new TGLayoutHints(kLHintsLeft | kLHintsTop |
811  5, 5, 5, 5));
812 
813  //fMain_leaflist->MapSubwindows();
814 
815  fMain_leaflist->Resize(fMain_leaflist->GetDefaultSize());
816  //fMain_leaflist->MapWindow();
817  fMain_leaflist->Resize(lWidth, lHeight);
818  FillLeafList();
819  /*********end of VARIABLES **************/
820  hf->AddFrame(fMain_leaflist, new TGLayoutHints(kLHintsLeft, 5, 5, 5, 5));
821 
822  /******* SELECTIONS *********/
823  UInt_t sWidth = 600, sHeight = lHeight;
824  fMain_selectionlist = new TGGroupFrame(hf, "SELECTIONS");
825  /* current selection */
826  G_selection_status = new TGStatusBar(fMain_selectionlist, sWidth, 10);
827  G_selection_status->SetText("CURRENT SELECTION:", 0);
828  fMain_selectionlist->AddFrame(G_selection_status, new TGLayoutHints(kLHintsExpandX, 0, 0, 10, 0));
829  /* make selection */
830  TGHorizontalFrame* fHorizontalFrame1614 = new TGHorizontalFrame(fMain_selectionlist, sWidth, 36, kHorizontalFrame);
831  lab = new TGLabel(fHorizontalFrame1614, "Make selection : ");
832  fHorizontalFrame1614->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
833  G_selection_text = new TGTextEntry(fHorizontalFrame1614, new TGTextBuffer(50));
834  G_selection_text->SetMaxLength(4096);
835  G_selection_text->SetAlignment(kTextLeft);
836  G_selection_text->Resize(sWidth - 100, G_selection_text->GetDefaultHeight());
837  G_selection_text->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateSelection()");
838  fHorizontalFrame1614->AddFrame(G_selection_text, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 2, 5, 2, 2));
839  fMain_selectionlist->AddFrame(fHorizontalFrame1614, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
840 
841  /* selection list */
842  G_selectionlist = new KVListView(TEntryList::Class(), fMain_selectionlist, sWidth, sHeight);
843  G_selectionlist->SetDataColumns(3);
844  G_selectionlist->SetDataColumn(0, "Selection", "GetTitle");
845  G_selectionlist->SetDataColumn(1, "Reapply", "GetReapplyCut");
846  G_selectionlist->GetDataColumn(1)->SetIsBoolean();
847  G_selectionlist->SetDataColumn(2, "Events", "GetN", kTextRight);
848  G_selectionlist->ActivateSortButtons();
849  G_selectionlist->SetDoubleClickAction("KVTreeAnalyzer", this, "SetSelection(TObject*)");
850  G_selectionlist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "SelectionChanged()");
851  fMain_selectionlist->AddFrame(G_selectionlist, new TGLayoutHints(kLHintsLeft | kLHintsTop |
853  5, 5, 5, 5));
854 
855  //fMain_selectionlist->MapSubwindows();
856 
857  fMain_selectionlist->Resize(fMain_selectionlist->GetDefaultSize());
858  //fMain_selectionlist->MapWindow();
859  fMain_selectionlist->Resize(sWidth, sHeight);
860  G_selectionlist->Display(&fSelections);
861  /******end of SELECTIONS *********/
862  hf->AddFrame(fMain_selectionlist, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 5, 5, 5, 5));
863  fMain_histolist->AddFrame(hf, new TGLayoutHints(kLHintsTop | kLHintsCenterX | kLHintsExpandX));
864 
865  /**** Histo creation group ********/
866  TGGroupFrame* histo_opts = new TGGroupFrame(fMain_histolist, "CREATE HISTO", kHorizontalFrame);
867  fHorizontalFrame = new TGHorizontalFrame(histo_opts, lWidth, 36, kHorizontalFrame);
868  G_leaf_draw = new TGPictureButton(fHorizontalFrame, "draw_t.xpm");
869  G_leaf_draw->SetEnabled(kFALSE);
870  G_leaf_draw->Connect("Clicked()", "KVTreeAnalyzer", this, "DrawLeafExpr()");
871  fHorizontalFrame->AddFrame(G_leaf_draw, new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 2, 2, 2));
872  fLeafExpr = " ";
873  G_leaf_expr = new TGLabel(fHorizontalFrame, fLeafExpr.Data());
874  G_leaf_expr->Resize();
875  fHorizontalFrame->AddFrame(G_leaf_expr, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
876  histo_opts->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
877 
878  G_histo_prof = new TGCheckButton(histo_opts, "Profile");
879  G_histo_prof->SetToolTipText("Generate a profile histogram");
880  G_histo_prof->SetState((EButtonState) fProfileHisto);
881  G_histo_prof->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetProfileHisto(Bool_t)");
882  histo_opts->AddFrame(G_histo_prof, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
883 
884  G_histo_norm = new TGCheckButton(histo_opts, "Normalize (integral)");
885  G_histo_norm->SetToolTipText("Generate normalized histogram with integral=1");
886  G_histo_norm->SetState((EButtonState) fNormHisto);
887  G_histo_norm->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNormHisto(Bool_t)");
888  histo_opts->AddFrame(G_histo_norm, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
889  G_histo_norm_events = new TGCheckButton(histo_opts, "Normalize (events)");
890  G_histo_norm_events->SetToolTipText("Generate histogram with integral divided by number of events");
891  G_histo_norm_events->SetState((EButtonState) fNormHistoEvents);
892  G_histo_norm_events->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNormHistoEvents(Bool_t)");
893  histo_opts->AddFrame(G_histo_norm_events, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
894 
895  G_histo_weight = new TGCheckButton(histo_opts, "Weight");
896  G_histo_weight->SetToolTipText("User defined binning of the histogram");
897  G_histo_weight->SetState((EButtonState) fUserWeight);
898  G_histo_weight->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetUserWeight(Bool_t)");
899  histo_opts->AddFrame(G_histo_weight, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
900 
901  G_histo_bin = new TGCheckButton(histo_opts, "Bins");
902  G_histo_bin->SetToolTipText("User defined binning of the histogram");
903  G_histo_bin->SetState((EButtonState) fUserBinning);
904  G_histo_bin->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetUserBinning(Bool_t)");
905  histo_opts->AddFrame(G_histo_bin, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
906  fMain_histolist->AddFrame(histo_opts, new TGLayoutHints(kLHintsCenterX | kLHintsExpandX, 5, 5, 5, 5));
907 
908  /******** HISTOGRAMS *****************/
909  hWidth = lWidth + sWidth + 20;
910  TGGroupFrame* histo_group = new TGGroupFrame(fMain_histolist, "HISTOGRAMS");
911  /* ip scale */
912 // histo_opts = new TGGroupFrame(histo_group, "Impact parameter", kHorizontalFrame);
913 // G_make_ip_scale = new TGTextButton(histo_opts,"Make scale");
914 // G_make_ip_scale->SetTextJustify(36);
915 // G_make_ip_scale->SetMargins(0,0,0,0);
916 // G_make_ip_scale->SetWrapLength(-1);
917 // G_make_ip_scale->Resize();
918 // G_make_ip_scale->SetEnabled(kFALSE);
919 // G_make_ip_scale->Connect("Clicked()","KVTreeAnalyzer",this,"MakeIPScale()");
920 // G_make_ip_scale->ChangeBackground(green);
921 // histo_opts->AddFrame(G_make_ip_scale, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,10,2));
922 // lab = new TGLabel(histo_opts,"b <");
923 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,5,2,12,2));
924 // G_make_ip_selection = new TGTextEntry(histo_opts, new TGTextBuffer(5));
925 // G_make_ip_selection->SetMaxLength(10);
926 // G_make_ip_selection->SetAlignment(kTextLeft);
927 // G_make_ip_selection->Resize(50,G_make_ip_selection->GetDefaultHeight());
928 // G_make_ip_selection->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateIPSelection()");
929 // G_make_ip_selection->SetEnabled(kFALSE);
930 // histo_opts->AddFrame(G_make_ip_selection, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,10,2));
931 // G_ip_histo = new TGLabel(histo_opts,"-");
932 // histo_opts->AddFrame(G_ip_histo, new TGLayoutHints(kLHintsLeft|kLHintsTop,5,2,12,2));
933 // histo_group->AddFrame(histo_opts, new TGLayoutHints(kLHintsLeft|kLHintsExpandX,5,5,5,5));
934 // /* ip scale */
935 // histo_opts = new TGGroupFrame(histo_group, "Fits", kHorizontalFrame);
936 // lab = new TGLabel(histo_opts,"Gumbel : ");
937 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,5,2));
938 // G_fit1 = new TGTextButton(histo_opts, " 1 ");
939 // G_fit1->SetTextJustify(36);
940 // G_fit1->SetMargins(0,0,0,0);
941 // G_fit1->SetWrapLength(-1);
942 // G_fit1->Resize();
943 // G_fit1->SetEnabled(kFALSE);
944 // G_fit1->ChangeBackground(gura);
945 // G_fit1->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum1()");
946 // histo_opts->AddFrame(G_fit1, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
947 // G_fit2 = new TGTextButton(histo_opts, " 2 ");
948 // G_fit2->SetTextJustify(36);
949 // G_fit2->SetMargins(0,0,0,0);
950 // G_fit2->SetWrapLength(-1);
951 // G_fit2->Resize();
952 // G_fit2->SetEnabled(kFALSE);
953 // G_fit2->ChangeBackground(gurb);
954 // G_fit2->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum2()");
955 // histo_opts->AddFrame(G_fit2, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
956 // G_fit3 = new TGTextButton(histo_opts, " 3 ");
957 // G_fit3->SetTextJustify(36);
958 // G_fit3->SetMargins(0,0,0,0);
959 // G_fit3->SetWrapLength(-1);
960 // G_fit3->Resize();
961 // G_fit3->SetEnabled(kFALSE);
962 // G_fit3->ChangeBackground(gurc);
963 // G_fit3->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum3()");
964 // histo_opts->AddFrame(G_fit3, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
965 // lab = new TGLabel(histo_opts,"Gaus+Gum : ");
966 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,10,2,5,2));
967 // G_fitGG1 = new TGTextButton(histo_opts, " 1 ");
968 // G_fitGG1->SetTextJustify(36);
969 // G_fitGG1->SetMargins(0,0,0,0);
970 // G_fitGG1->SetWrapLength(-1);
971 // G_fitGG1->Resize();
972 // G_fitGG1->SetEnabled(kFALSE);
973 // G_fitGG1->ChangeBackground(gura);
974 // G_fitGG1->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum1()");
975 // histo_opts->AddFrame(G_fitGG1, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
976 // G_fitGG2 = new TGTextButton(histo_opts, " 2 ");
977 // G_fitGG2->SetTextJustify(36);
978 // G_fitGG2->SetMargins(0,0,0,0);
979 // G_fitGG2->SetWrapLength(-1);
980 // G_fitGG2->Resize();
981 // G_fitGG2->SetEnabled(kFALSE);
982 // G_fitGG2->ChangeBackground(gurb);
983 // G_fitGG2->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum2()");
984 // histo_opts->AddFrame(G_fitGG2, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
985 // G_fitGG3 = new TGTextButton(histo_opts, " 3 ");
986 // G_fitGG3->SetTextJustify(36);
987 // G_fitGG3->SetMargins(0,0,0,0);
988 // G_fitGG3->SetWrapLength(-1);
989 // G_fitGG3->Resize();
990 // G_fitGG3->SetEnabled(kFALSE);
991 // G_fitGG3->ChangeBackground(gurc);
992 // G_fitGG3->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum3()");
993 // histo_opts->AddFrame(G_fitGG3, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
994 // histo_group->AddFrame(histo_opts, new TGLayoutHints(kLHintsLeft|kLHintsExpandX,5,5,5,5));
995 
996  /* histo list */
997  //G_histolist = new KVListView(TNamed::Class(), histo_group, hWidth, hHeight);
998  //G_histolist->SetDataColumns(1);
999  //G_histolist->SetDataColumn(0, "Data", "GetTitle", kTextLeft);
1000  G_histolist = new KVListView(KVHistogram::Class(), histo_group, hWidth, hHeight);
1001  G_histolist->SetDataColumns(8);
1002  G_histolist->SetDataColumn(0, "Name", "", kTextLeft);
1003  G_histolist->SetDataColumn(1, "VarX", "", kTextCenterX);
1004  G_histolist->SetDataColumn(2, "VarY", "", kTextCenterX);
1005  G_histolist->SetDataColumn(3, "VarZ", "", kTextCenterX);
1006  G_histolist->SetDataColumn(4, "Selection", "", kTextCenterX);
1007  G_histolist->SetDataColumn(5, "Weight", "", kTextCenterX);
1008  G_histolist->SetDataColumn(6, "MeanX (RMS)", "GetMeanRMSX", kTextCenterX);
1009  G_histolist->SetDataColumn(7, "MeanY (RMS)", "GetMeanRMSY", kTextCenterX);
1010  G_histolist->ActivateSortButtons();
1011  G_histolist->SetMaxColumnSize(20);
1012  G_histolist->SetUseObjLabelAsRealClass();//to have icons & context menus of TH* & TCutG classes, not KVHistogram
1013  G_histolist->SetDoubleClickAction("KVTreeAnalyzer", this, "DrawHisto(TObject*)");
1014  G_histolist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "HistoSelectionChanged()");
1015  histo_group->AddFrame(G_histolist, new TGLayoutHints(kLHintsLeft | kLHintsTop |
1017  5, 5, 5, 5));
1018 
1019  fMain_histolist->AddFrame(histo_group, new TGLayoutHints(kLHintsCenterX | kLHintsExpandX | kLHintsExpandY, 5, 5, 5, 5));
1020  G_histolist->Display(&fHistolist);
1021  /* histo options */
1022  histo_opts = new TGGroupFrame(fMain_histolist, "OPTIONS", kHorizontalFrame);
1023 
1024  //fHorizontalFrame = new TGHorizontalFrame(histo_opts,150,36,kHorizontalFrame);
1025  G_histo_del = new TGPictureButton(histo_opts, "sm_delete.xpm");
1026  G_histo_del->SetEnabled(kFALSE);
1027  G_histo_del->Connect("Clicked()", "KVTreeAnalyzer", this, "DeleteSelectedHisto()");
1028  //fHorizontalFrame->AddFrame(G_histo_del, new TGLayoutHints(kLHintsTop|kLHintsLeft,2,2,2,2));
1029  //lab = new TGLabel(fHorizontalFrame, "DELETE");
1030  //lab->Resize();
1031  //fHorizontalFrame->AddFrame(lab, new TGLayoutHints(kLHintsTop|kLHintsLeft|kLHintsCenterY,2,2,2,2));
1032  histo_opts->AddFrame(G_histo_del, new TGLayoutHints(kLHintsLeft, 5, 2, 8, 2));
1033 
1034  G_histo_add = new TGPictureButton(histo_opts, "bld_plus.png");
1035  G_histo_add->SetEnabled(kFALSE);
1036  G_histo_add->Connect("Clicked()", "KVTreeAnalyzer", this, "AddSelectedHistos()");
1037  G_histo_add->Resize(G_histo_del->GetSize());
1038  histo_opts->AddFrame(G_histo_add, new TGLayoutHints(kLHintsLeft, 15, 25, 8, 2));
1039 
1040  G_histo_draw_option = new TGComboBox(histo_opts);
1041  TString draw_options[] = {
1042  "",
1043  "COL",
1044  "COLZ",
1045  "BOX",
1046  "CONT",
1047  "SURF",
1048  "LEGO",
1049  "ARR",
1050  "TEXT",
1051  "CONT1",
1052  "CONT2",
1053  "CONT3",
1054  "CONT4",
1055  "SURF1",
1056  "SURF2",
1057  "SURF3",
1058  "SURF4",
1059  "LEGO1",
1060  "LEGO2",
1061  "LEGO3",
1062  "LEGO4",
1063  "BOX1",
1064  " "
1065  };
1066  int dop = 0;
1067  while (draw_options[dop] != " ") {
1068  G_histo_draw_option->AddEntry(draw_options[dop], dop);
1069  ++dop;
1070  }
1071  G_histo_draw_option->Resize(100, 20);
1072  histo_opts->AddFrame(G_histo_draw_option, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1073  G_histo_draw_option->Connect("Selected(const char*)", "KVTreeAnalyzer", this, "SetDrawOption(Option_t*)");
1074 
1075  G_histo_new_can = new TGCheckButton(histo_opts, "New canvas");
1076  G_histo_new_can->SetToolTipText("Draw in a new canvas");
1077  G_histo_new_can->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNewCanvas(Bool_t)");
1078  G_histo_new_can->SetState((EButtonState)fNewCanvas);
1079  histo_opts->AddFrame(G_histo_new_can, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1080  G_histo_same = new TGCheckButton(histo_opts, "Same");
1081  G_histo_same->SetToolTipText("Draw in same pad");
1082  G_histo_same->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetDrawSame(Bool_t)");
1083  histo_opts->AddFrame(G_histo_same, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1084  G_histo_app_sel = new TGCheckButton(histo_opts, "Apply selection");
1085  G_histo_app_sel->SetToolTipText("Apply current selection to generate new histo");
1086  G_histo_app_sel->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetApplySelection(Bool_t)");
1087  histo_opts->AddFrame(G_histo_app_sel, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1088  G_histo_log = new TGCheckButton(histo_opts, "Log scale");
1089  G_histo_log->SetToolTipText("Use log scale in Y (1D) or Z (2D)");
1090  G_histo_log->SetState((EButtonState)fDrawLog);
1091  G_histo_log->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetDrawLog(Bool_t)");
1092  histo_opts->AddFrame(G_histo_log, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1093  G_histo_stats = new TGCheckButton(histo_opts, "Stats");
1094  G_histo_stats->SetToolTipText("Display histogram statistics box");
1095  G_histo_stats->SetState((EButtonState) fStatsHisto);
1096  G_histo_stats->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetStatsHisto(Bool_t)");
1097  histo_opts->AddFrame(G_histo_stats, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1098  G_histo_autosave = new TGCheckButton(histo_opts, "AutoSave");
1099  G_histo_autosave->SetToolTipText("Automatically generate histo image files");
1100  G_histo_autosave->SetState((EButtonState) fAutoSaveHisto);
1101  G_histo_autosave->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetAutoSaveHisto(Bool_t)");
1102  histo_opts->AddFrame(G_histo_autosave, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1103  fMain_histolist->AddFrame(histo_opts, new TGLayoutHints(kLHintsCenterX, 5, 5, 5, 5));
1104 
1105  fMain_histolist->MapSubwindows();
1106 
1107  fMain_histolist->Resize(fMain_histolist->GetDefaultSize());
1108  fMain_histolist->MapWindow();
1109 
1110  hHeight = hHeight + lHeight + 50;
1111 
1112  fMain_histolist->Resize(hWidth, hHeight);
1113  /********* end of HISTOGRAMS *************/
1114 
1115  fMain_histolist->Connect("CloseWindow()", "KVTreeAnalyzer", this, "GUIClosed()");
1116 }
1117 
1118 
1119 
1122 
1124 {
1125  // Called when graphical window is closed
1126 
1127  AnalysisSaveCheck();
1128  fDeletedByGUIClose = kTRUE;
1129  TTimer::SingleShot(150, "KVTreeAnalyzer", this, "DeleteThis()");
1130 }
1131 
1132 
1133 
1137 
1138 void KVTreeAnalyzer::AddHisto(TH1* h)
1139 {
1140  // Adds histogram to internal list of user histograms
1141  // and updates GUI display
1142 
1143  SetAnalysisModifiedSinceLastSave(kTRUE);//new histogram needs saving
1144  fHistolist.Add(new KVHistogram(h));
1145  G_histolist->Display(&fHistolist);
1146 }
1147 
1148 
1149 
1153 
1154 void KVTreeAnalyzer::AddSelection(TEntryList* e)
1155 {
1156  // Adds selection to internal list of user histograms
1157  // and updates GUI display
1158 
1159  SetAnalysisModifiedSinceLastSave(kTRUE);//new selection needs saving
1160  fSelections.Add(e);
1161  G_selectionlist->Display(&fSelections);
1162 }
1163 
1164 
1165 
1169 
1170 void KVTreeAnalyzer::AddCut(TCutG* c)
1171 {
1172  // Adds histogram to internal list of user histograms
1173  // and updates GUI display
1174 
1175  SetAnalysisModifiedSinceLastSave(kTRUE);//new selection needs saving
1176  fHistolist.Add(new KVHistogram(c));
1177  G_histolist->Display(&fHistolist);
1178 }
1179 
1180 
1181 
1188 
1190 {
1191  // the Tree file name is used as the basis for the default analysis backup filename.
1192  // for a TChain there may be many files with a common root.
1193  // we look for this common root and replace any "wildcard" characters with "X"
1194  // i.e. for files "run_001.root", "run_002.root", ..., "run_999.root" we
1195  // will use "Analysis_run_XXX.root" as default name
1196 
1197  KVString p;
1198  if (t->InheritsFrom("TChain")) {
1199  KVString p;
1200  p.FindCommonTitleCharacters(((TChain*)t)->GetListOfFiles(), 'X');
1201  fTreeFileName = p.Data();
1202  }
1203  else
1204  fTreeFileName = t->GetCurrentFile()->GetName();
1205  fSaveAnalysisFileName.Form("Analysis_%s", gSystem->BaseName(fTreeFileName.Data()));
1206  if (!fSaveAnalysisFileName.Contains(".root")) fSaveAnalysisFileName.Append(".root");
1207 }
1208 
1209 
1210 
1213 
1215 {
1216  // Connects a TChain for analysis
1217 
1218  fTree = t;
1219  got_histos_or_tree_from_file = true;
1220 #ifdef WITH_PROOF
1221  if (IsPROOFEnabled()) fChain->SetProof();
1222 #endif
1223  fTreeName = t->GetName();
1224  SetTreeFileName(t);
1225  if (fMain_histolist) fMain_histolist->SetWindowName(Form("%s (%s)", t->GetTitle(), fTreeFileName.Data()));
1226 }
1227 
1228 
1229 
1232 
1233 void KVTreeAnalyzer::ReconnectTree()
1234 {
1235  // Backwards compatibility: to read old analysis files
1236 
1237  TFile* f;
1238  if (gSystem->IsAbsoluteFileName(fTreeFileName) && gSystem->AccessPathName(fTreeFileName)) {
1239  // absolute path to TTree file doesn't work, try in working directory
1240  TString tmp;
1242  f = TFile::Open(tmp);
1243  }
1244  else if ((fRelativePathToAnalysisFile != "." && fRelativePathToAnalysisFile != "") && !gSystem->IsAbsoluteFileName(fTreeFileName)) {
1245  // if fRelativePathToAnalysisFile!="." and if fTreeFileName is not an absolute path,
1246  // we guess the Tree file is in the same directory as the analysis file
1247  TString tmp;
1248  AssignAndDelete(tmp, gSystem->ConcatFileName(fRelativePathToAnalysisFile, fTreeFileName));
1249  f = TFile::Open(tmp);
1250  }
1251  else
1252  f = TFile::Open(fTreeFileName);
1253  if (!f || f->IsZombie()) {
1254  KVError::Error(this, "ReconnectTree", "Failed to reconnect Tree file %s", fTreeFileName.Data());
1255  fTree = 0;
1256  got_histos_or_tree_from_file = false;
1257  fChain = 0;
1258  SafeDelete(f);
1259  return;
1260  }
1261  fTreeFileName = f->GetName();
1262  TTree* t = (TTree*)f->Get(fTreeName);
1263  TString treeTitle = t->GetTitle();
1264  delete f;
1265  fChain = new TChain(fTreeName, treeTitle);
1266  fChain->Add(fTreeFileName);
1267  fChain->SetDirectory(0);
1268  SetTree(fChain);
1269 }
1270 
1271 
1272 
1280 
1282 {
1283  // STATIC method to open a previously saved analysis session.
1284  //
1285  // Use:
1286  // root[0] KVTreeAnalyzer* TA = KVTreeAnalyzer::OpenFile("my_analysis.root")
1287  //
1288  // If option nogui=kTRUE the GUI will not be launched
1289 
1291  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1292  delete f;
1293  anal->fNoGui = nogui;
1294  anal->SetRelativePathToAnalysisFile(gSystem->DirName(filename));
1295  anal->OpenGUI();
1296  return anal;
1297 }
1298 
1299 
1300 
1303 
1305 {
1306  // open a previously saved analysis session.
1307 
1309  ReadFromFile(f);
1310 }
1311 
1312 
1313 
1316 
1318 {
1319  // open a previously saved analysis session.
1320 
1321  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1322  delete f;
1323  anal->Copy(*this);
1324  delete anal;
1325  gTreeAnalyzer = this;
1326  G_selectionlist->Display(&fSelections);
1327  G_histolist->Display(&fHistolist);
1328  FillLeafList();
1329 }
1330 
1331 
1332 
1334 
1336 {
1337  TString name = Form("%s:%s", cut->GetVarY(), cut->GetVarX());
1338  KVUnownedList padList;
1339  Bool_t testHisto = kFALSE;
1340 
1341  if (!gPad) testHisto = kTRUE;
1342 
1343  if (!testHisto) {
1344  testHisto = kTRUE;
1345  padList.AddAll(((TPad*)gPad)->GetListOfPrimitives());
1346  TIter next(&padList);
1347  TObject* o = 0;
1348  while ((o = next())) {
1349  if (o->InheritsFrom("TH1")) {
1350  TH1* hh = (TH1*) o;
1351  TString hName = hh->GetTitle();
1352  if (hName.Contains(name.Data())) {
1353  cut->Draw("PL");
1354  gPad->Update();
1355  testHisto = kFALSE;
1356  }
1357  }
1358  }
1359  }
1360 
1361  if (testHisto) {
1362  TIter next(&fHistolist);
1363  KVHistogram* hhh;
1364  TH1* hh = 0;
1365  while ((hhh = (KVHistogram*)next())) {
1366  if ((hh = hhh->GetHisto())) {
1367  TString hName = hh->GetTitle();
1368  if (hName.Contains(name.Data())) {
1369  DrawHisto(hh, kFALSE);
1370  cut->Draw("PL");
1371  gPad->Update();
1372  break;
1373  }
1374  }
1375  }
1376  }
1377  // else cut->Draw("PAL");
1378 
1379 
1380 // TIter next(fHistoList);
1381 // TH1* tmpHist = 0;
1382 // while((tmpHisto = (TH1*)next()))
1383 // {
1384 //
1385 // }
1386 
1387  return;
1388 }
1389 
1390 
1391 
1393 
1394 void KVTreeAnalyzer::DrawHistogram(TH1* histo, Bool_t same, Bool_t logscale)
1395 {
1396  if (fDrawSame || same) {
1397  // if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1398  // plot with a different colour and add it to the automatically generated
1399  // legend which is also displayed in the plot
1400  histo->SetLineColor(my_color_array[++fSameColorIndex]);
1401  histo->SetLineWidth(2);
1402  if (fSameColorIndex == MAX_COLOR_INDEX) fSameColorIndex = -1;
1403  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1404  if (histo->InheritsFrom("TH2")) {
1405  TString hopt = histo->GetOption();
1406  if (hopt != "") hopt.Form("%s,same", histo->GetOption());
1407  else hopt = "same";
1408  histo->Draw(hopt);
1409  }
1410  else
1411  histo->Draw("same");
1412  TObject* legend = gPad->GetListOfPrimitives()->FindObject("TPave");
1413  if (legend) {
1414  gPad->GetListOfPrimitives()->Remove(legend);
1415  delete legend;
1416  }
1417  ((TPad*) gPad)->BuildLegend();
1418  if (histo->InheritsFrom("TH2")) {
1419  gPad->SetLogy(kFALSE);
1420  gPad->SetLogz(fDrawLog || logscale);
1421  }
1422  else {
1423  gPad->SetLogy(fDrawLog || logscale);
1424  // adjust y-scale to new histogram if needed
1425  // find first histogram
1426  TIter nxt(gPad->GetListOfPrimitives());
1427  TObject* h;
1428  while ((h = nxt())) {
1429  if (h->InheritsFrom("TH1")) {
1430  TH1* hh = (TH1*)h;
1431  if (histo->GetMaximum() > hh->GetMaximum()) hh->SetMaximum(histo->GetMaximum() + 1);
1432  break;
1433  }
1434  }
1435  }
1436  gPad->Modified();
1437  gPad->Update();
1438  if (fAutoSaveHisto) AutoSaveHisto(histo);
1439  }
1440  else {
1441  // if 'new canvas' is active the histogram is displayed in a new KVCanvas
1442  // create a new canvas also if none exists
1443  if (fNewCanvas || !gPad) {
1444  KVCanvas* c = new KVCanvas;
1445  c->SetTitle(histo->GetTitle());
1446  c->SetWindowSize(700, 700);
1447  }
1448  else if (gPad) { // update title of existing canvas
1449  gPad->GetCanvas()->SetTitle(histo->GetTitle());
1450  }
1451  histo->SetLineColor(my_color_array[0]);
1452  histo->SetLineWidth(2);
1453  if (histo->InheritsFrom("TH2")) {
1454  gPad->SetLogy(kFALSE);
1455  gPad->SetLogz(fDrawLog || logscale);
1456  }
1457  else {
1458  histo->SetMaximum(-1111);//in case maximum was changed to accomodate superimposition
1459  gPad->SetLogy(fDrawLog || logscale);
1460  }
1461  histo->SetStats(fStatsHisto);//show/hide stat box according to check-box
1462  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1463  histo->Draw();
1464  gPad->Modified();
1465  gPad->Update();
1466  if (fAutoSaveHisto) AutoSaveHisto(histo);
1467  }
1468 }
1469 
1470 
1471 
1492 
1494 {
1495  // Method called when a user double-clicks a histogram in the GUI list.
1496  //
1497  // * if histogram is already displayed in active pad and if the pad also
1498  // contains a graphical contour (TCutG) object, we use the contour to define
1499  // a new data selection (TEntryList) which is added to the internal list.
1500  //
1501  // * if 'reapply selection' is activated and if the current active selection
1502  // is not the same as that used to generate the histogram, we generate a new
1503  // histogram displaying the same variables but with the current selection.
1504  //
1505  // * if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1506  // plot with a different colour and add it to the automatically generated
1507  // legend which is also displayed in the plot
1508  //
1509  // * if 'new canvas' is active the histogram is displayed in a new KVCanvas
1510  //
1511  // * in all cases when a histogram is displayed the log/linear scale of
1512  // Y (1-D) or Z (2-D) axis is automatically adjusted according to the 'log scale'
1513  // check box
1514 
1515  KVHistogram* kvhisto = 0;
1516  TCutG* cut = 0;
1517  TH1* histo = 0;
1518  if (obj->InheritsFrom("KVHistogram")) {
1519  kvhisto = dynamic_cast<KVHistogram*>(obj);
1520  if (kvhisto->IsType("Cut")) cut = kvhisto->GetCut();
1521  else if (kvhisto->IsType("Histo")) histo = kvhisto->GetHisto();
1522  }
1523  else if (obj->InheritsFrom("TCutG")) {
1524  cut = dynamic_cast<TCutG*>(obj);
1525  }
1526  else if (obj->InheritsFrom("TH1")) {
1527  histo = dynamic_cast<TH1*>(obj);
1528  }
1529 
1530  if (cut) {
1531  DrawCut(cut);
1532  return;
1533  }
1534  if (!histo) return;
1535 
1536  // if histogram is already displayed in active pad and if the pad also
1537  // contains a graphical contour (TCutG) object, we use the contour to define
1538  // a new data selection (TEntryList) which is added to the internal list.
1539  if (gPad && gPad->GetListOfPrimitives()->FindObject(histo) && (gen)) {
1540  TIter next(gPad->GetListOfPrimitives());
1541  TObject* o;
1542  while ((o = next())) {
1543  if ((o->IsA() == TCutG::Class()) && !(fHistolist.FindObjectWithNameAndType(o->GetName(), "Cut"))) {
1544  MakeSelection(o->GetName());
1545  return;
1546  }
1547  }
1548  }
1549 
1550  KVString exp, sel, weight;
1551  if (kvhisto) {
1552  exp = kvhisto->GetExpression();
1553  sel = kvhisto->GetSelection();
1554  weight = kvhisto->GetWeight();
1555  }
1556  else {
1557  KVHistogram::ParseHistoTitle(histo->GetTitle(), exp, sel, weight);
1558  }
1559 
1560  if (weight == "1") weight = "";
1561 
1562  // if 'reapply selection' is activated and if the current active selection
1563  // is not the same as that used to generate the histogram, we generate a new
1564  // histogram displaying the same variables but with the current selection.
1565  if (!IsCurrentSelection(sel) && fApplySelection) {
1566  histo = RemakeHisto(histo, exp, weight);
1567  if (!histo) return;
1568  }
1569 
1570  DrawHistogram(histo);
1571 }
1572 
1573 
1574 
1578 
1580 {
1581  // Returns kTRUE if "sel" corresponds to current active selection
1582  // (i.e. entry list of TTree)
1583 
1584  if (!fTree) return kTRUE;
1585  TString test_sel(sel);
1586  TString tree_sel;
1587  TEntryList* el;
1588  if ((el = fChain->GetEntryList())) tree_sel = el->GetTitle();
1589  return (test_sel == tree_sel);
1590 }
1591 
1592 
1593 
1598 
1599 TH1* KVTreeAnalyzer::RemakeHisto(TH1* h, const Char_t* expr, const Char_t* weight)
1600 {
1601  // Remake an existing histogram of data 'expr' using the current active selection
1602  // If such a histogram already exists, we just return its address.
1603  // We must have the same binning in the new as in the original histogram.
1604 
1605  TString htit;
1606  GenerateHistoTitle(htit, expr, "", weight);
1607  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
1608  TH1* histo = 0;
1609  if (kvhisto) histo = kvhisto->GetHisto();
1610  if (histo && (histo->IsA() == h->IsA())) return histo;
1611  Int_t nx, ny = 0;
1612  TString hname(h->GetName());
1613  if (hname.BeginsWith("I")) {
1614  Int_t xmin = h->GetXaxis()->GetXmin() + 0.5;
1615  Int_t xmax = h->GetXaxis()->GetXmax() - 0.5;
1616  //cout << "Remake histo with xmin = " << xmin << " xmax = " << xmax << endl;
1617  h = MakeIntHisto(expr, "", xmin, xmax, weight);
1618  return h;
1619  }
1620  nx = h->GetNbinsX();
1621  auto xmin = h->GetXaxis()->GetXmin();
1622  auto xmax = h->GetXaxis()->GetXmin();
1623  double ymin(-1), ymax(-1);
1624  if (h->InheritsFrom("TH2")) {
1625  ny = h->GetNbinsY();
1626  ymin = h->GetYaxis()->GetXmin();
1627  ymax = h->GetYaxis()->GetXmin();
1628  }
1629  //cout << "Remake histo with nx = " << nx << " ny = " << ny << endl;
1630  if (h->InheritsFrom("TProfile")) {
1631  // make a new profile histogram
1632  Bool_t oldProfileState = fProfileHisto;
1633  fProfileHisto = kTRUE;
1634  h = MakeHisto(expr, "", nx, ny, weight, xmin, xmax);
1635  fProfileHisto = oldProfileState;
1636  }
1637  else
1638  h = MakeHisto(expr, "", nx, ny, weight, xmin, xmax, ymin, ymax);
1639  return h;
1640 }
1641 
1642 
1643 
1648 
1650 {
1651  // Method called when user hits 'return' in selection GUI text-box
1652  // Takes expression from text-box and generates the corresponding
1653  // selection which is added to the GUI list of selections.
1654 
1655  TString selection = G_selection_text->GetText();
1656  if (selection.IsNull()) return;
1657  if (MakeSelection(selection)) G_selection_text->Clear();
1658 }
1659 
1660 
1661 
1665 
1667 {
1668  // Method called when user hits 'return' in TTree leaf/alias GUI text-box
1669  // Generates a new alias using the expression in the text-box.
1670 
1671  TString alias = G_alias_text->GetText();
1672  TString name;
1673  name.Form("a%d", fAliasNumber++);
1674  SetAlias(name, alias);
1675  FillLeafList();
1676  G_alias_text->Clear();
1677 }
1678 
1679 
1680 
1685 
1687 {
1688  // Method called when user hits 'combine selections' button in selections GUI.
1689  // Generates new selection which is the intersection (logical AND) of
1690  // the currently selected selections.
1691 
1692  if (!fSelectedSelections.IsEmpty()) {
1693  TEntryList* save_elist = fChain->GetEntryList();
1694  SetEntryList((TEntryList*)fSelectedSelections.First());
1695  TString newselect;
1696  int nsel = fSelectedSelections.GetEntries();
1697  for (int i = 1; i < nsel; i++) {
1698  TString tmp;
1699  TEntryList* el = (TEntryList*)fSelectedSelections.At(i);
1700  tmp.Form("(%s)", el->GetTitle());
1701  if (i > 1) newselect += " && ";
1702  newselect += tmp.Data();
1703  }
1704  MakeSelection(newselect);
1705  SetEntryList(save_elist);
1706  }
1707 }
1708 
1709 
1710 
1715 
1717 {
1718  // Method called when user hits 'combine selections' button in selections GUI.
1719  // Generates new selection which is the intersection (logical AND) of
1720  // the currently selected selections.
1721 
1722  if (!fSelectedSelections.IsEmpty()) {
1723  TEntryList* save_elist = fChain->GetEntryList();
1724  SetEntryList(nullptr);
1725  TString newselect;
1726  int nsel = fSelectedSelections.GetEntries();
1727  for (int i = 0; i < nsel; i++) {
1728  TString tmp;
1729  TEntryList* el = (TEntryList*)fSelectedSelections.At(i);
1730  tmp.Form("(%s)", el->GetTitle());
1731  if (i > 0) newselect += " || ";
1732  newselect += tmp.Data();
1733  }
1734  MakeSelection(newselect);
1735  SetEntryList(save_elist);
1736  }
1737 }
1738 
1739 
1740 
1743 
1745 {
1746  // Delete the currently selected selection(s)
1747 
1748  if (!fSelectedSelections.IsEmpty()) {
1749  int nsel = fSelectedSelections.GetEntries();
1750  if (nsel < 1) return;
1751  for (int i = 0; i < nsel; i++) {
1752  TEntryList* el = (TEntryList*)fSelectedSelections.At(i);
1753  if (!el) continue;
1754  fSelections.Remove(el);
1755  // if current selection, disable
1756  if (fChain->GetEntryList() == el) fChain->SetEntryList(nullptr);
1757  delete el;
1758  SetAnalysisModifiedSinceLastSave(kTRUE);
1759  }
1760  G_selectionlist->Display(&fSelections);
1761  }
1762  fMenuSelections->DisableEntry(SEL_DELETE);
1763 
1764 }
1765 
1766 
1767 
1770 
1772 {
1773  // Method called whenever the selected selection in the GUI list changes
1774 
1775  fSelectedSelections = G_selectionlist->GetSelectedObjects();
1776  Bool_t resetSel = kTRUE;
1777  fSelCombMenu->DisableEntry(SEL_COMB_AND);
1778  fSelCombMenu->DisableEntry(SEL_COMB_OR);
1779  fMenuSelections->DisableEntry(SEL_DELETE);
1780 
1781  if (fSelectedSelections.IsEmpty()) {
1782  }
1783  else if (fSelectedSelections.GetEntries() == 1) {
1784  fMenuSelections->EnableEntry(SEL_DELETE);
1785  KVSeqCollection* tmp = fSelections.GetSubListWithMethod(G_selection_text->GetText(), "GetTitle");
1786  if (tmp->GetSize() != 0 || !strcmp("", G_selection_text->GetText())) {
1787  G_selection_text->SetText(((TNamed*)fSelectedSelections.At(0))->GetTitle());
1788  resetSel = kFALSE;
1789  }
1790  delete tmp;
1791  }
1792  else if (fSelectedSelections.GetEntries() > 1) {
1793  fMenuSelections->EnableEntry(SEL_DELETE);
1794  fSelCombMenu->EnableEntry(SEL_COMB_AND);
1795  fSelCombMenu->EnableEntry(SEL_COMB_OR);
1796  }
1797 
1798  if (resetSel) {
1799  KVSeqCollection* tmp = fSelections.GetSubListWithMethod(G_selection_text->GetText(), "GetTitle");
1800  if (tmp->GetSize() != 0) G_selection_text->SetText("");
1801  delete tmp;
1802  }
1803 }
1804 
1805 
1806 
1810 
1812 {
1813  // Method called whenever the leaf/alias selection in the TTree GUI list changes.
1814  // Updates the names of the leaves/aliases displayed next to the 'draw' button.
1815 
1816  fSelectedLeaves = G_leaflist->GetPickOrderedSelectedObjects();
1817  fLeafExpr = "-";
1818  fXLeaf = fYLeaf = 0;
1819 // Bool_t resetSel = kTRUE;
1820  G_leaf_draw->SetEnabled(kFALSE);
1821  Int_t nleaf = fSelectedLeaves->GetEntries();
1822  if (nleaf) {
1823  if (nleaf == 1) {
1824  fXLeaf = (TNamed*)fSelectedLeaves->First();
1825  fLeafExpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1826  G_leaf_draw->SetEnabled(kTRUE);
1827 
1828  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1829  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1830  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0 || !strcmp("", G_alias_text->GetText())) {
1831  G_alias_text->SetText(fLeafExpr.Data()); //resetSel = kFALSE;
1832  }
1833  else if (strcmp(fLeafExpr.Data(), G_leaf_expr->GetTitle())) {
1834  TString tmps = G_alias_text->GetText();
1835  Int_t pos = G_alias_text->MaxMark();
1836  if (pos >= tmps.Sizeof()) pos = G_alias_text->MinMark();
1837  if (pos >= tmps.Sizeof()) pos = tmps.Sizeof() - 1;
1838  tmps.Insert(pos, fLeafExpr.Data());
1839  G_alias_text->SetText(tmps.Data());
1840  G_alias_text->SetCursorPosition(pos + fLeafExpr.Sizeof());
1841  }
1842  delete tmp;
1843  delete tmp1;
1844 
1845  }
1846  else if (nleaf == 2) {
1847  fXLeaf = (TNamed*)fSelectedLeaves->At(1);
1848  fYLeaf = (TNamed*)fSelectedLeaves->First();
1849  TString X, Y;
1850  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1851  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1852  fLeafExpr.Form("%s:%s", Y.Data(), X.Data());
1853  G_leaf_draw->SetEnabled(kTRUE);
1854  G_alias_text->SetText("");
1855  }
1856  else if (nleaf == 3) {
1857  fXLeaf = (TNamed*)fSelectedLeaves->At(2);
1858  fYLeaf = (TNamed*)fSelectedLeaves->At(1);
1859  fZLeaf = (TNamed*)fSelectedLeaves->At(0);
1860  TString X, Y, Z;
1861  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1862  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1863  Z = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
1864  fLeafExpr.Form("%s:%s:%s", Z.Data(), Y.Data(), X.Data());
1865  G_leaf_draw->SetEnabled(kTRUE);
1866  G_alias_text->SetText("");
1867  }
1868  else {
1869  fLeafExpr = "-";
1870  G_alias_text->SetText("");
1871  }
1872  }
1873  else {
1874  fLeafExpr = "-";
1875 // G_alias_text->SetText("");
1876  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1877  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1878  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0) {
1879  G_alias_text->SetText(""); //resetSel = kFALSE;
1880  }
1881  delete tmp;
1882  delete tmp1;
1883  }
1884 
1885  G_leaf_expr->SetText(fLeafExpr);
1886  G_leaf_expr->Resize();
1887 }
1888 
1889 
1890 
1892 
1893 bool KVTreeAnalyzer::DefineUserBinning()
1894 {
1895  KVNameValueList p{{"Xbins", fNx}, {"Xmin", fXmin}, {"Xmax", fXmax},
1896  {"Ybins", fNy}, {"Ymin", fYmin}, {"Ymax", fYmax}};
1897  bool cancel{false};
1898  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1899  g->DisplayDialog();
1900  if (cancel) return false;
1901  fNx = p.GetIntValue("Xbins");
1902  fXmin = p.GetDoubleValue("Xmin");
1903  fXmax = p.GetDoubleValue("Xmax");
1904  fNy = p.GetIntValue("Ybins");
1905  fYmin = p.GetDoubleValue("Ymin");
1906  fYmax = p.GetDoubleValue("Ymax");
1907  return true;
1908 }
1909 
1910 
1911 
1913 
1914 bool KVTreeAnalyzer::DefineUserBinning1F()
1915 {
1916  KVNameValueList p{{"bins", fNxF}, {"min", fXminF}, {"max", fXmaxF}};
1917  bool cancel{false};
1918  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1919  g->DisplayDialog();
1920  if (cancel) return false;
1921  fNxF = p.GetIntValue("bins");
1922  fXminF = p.GetDoubleValue("min");
1923  fXmaxF = p.GetDoubleValue("max");
1924  return true;
1925 }
1926 
1927 
1928 
1930 
1931 bool KVTreeAnalyzer::DefineUserBinningD()
1932 {
1933  KVNameValueList p{{"Xbins", fNxD}, {"Ybins", fNyD}, {"ordered?", fOrderedDalitz}};
1934  bool cancel{false};
1935  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1936  g->DisplayDialog();
1937  if (cancel) return false;
1938  fNxD = p.GetIntValue("Xbins");
1939  fNyD = p.GetIntValue("Ybins");
1940  fOrderedDalitz = p.GetBoolValue("ordered?");
1941  return true;
1942 }
1943 
1944 
1945 
1951 
1952 double KVTreeAnalyzer::GetTreeMaximum(const TString& leafname)
1953 {
1954  // \returns maximum value of given TTree variable, taking into account any current selection (TEntryList).
1955  // @param leafname name of TTree variable
1956  //
1957  // \note TTree::GetMaximum() is supposed to do exactly the same, but strangely ignores the selection.
1958 
1959  fTree->GetMaximum(leafname);// this just to use internal TTree cache mechanism
1960 
1961  auto leaf = fTree->GetLeaf(leafname);
1962  if (!leaf) return 0;
1963 
1964  auto branch = leaf->GetBranch();
1965  Double_t cmax = -DBL_MAX;
1966  for (Long64_t i = 0; i < fTree->GetEntries(); ++i) {
1967  auto entryNumber = fTree->GetEntryNumber(i);
1968  if (entryNumber < 0) break;
1969  branch->GetEntry(entryNumber);
1970  for (Int_t j = 0; j < leaf->GetLen(); ++j) {
1971  Double_t val = leaf->GetValue(j);
1972  if (val > cmax) {
1973  cmax = val;
1974  }
1975  }
1976  }
1977  return cmax;
1978 }
1979 
1980 
1981 
1987 
1988 double KVTreeAnalyzer::GetTreeMinimum(const TString& leafname)
1989 {
1990  // \returns minimum value of given TTree variable, taking into account any current selection (TEntryList).
1991  // @param leafname name of TTree variable
1992  //
1993  // \note TTree::GetMinimum() is supposed to do exactly the same, but strangely ignores the selection.
1994 
1995  fTree->GetMinimum(leafname);// this just to use internal TTree cache mechanism
1996 
1997  auto leaf = fTree->GetLeaf(leafname);
1998  if (!leaf) return 0;
1999 
2000  auto branch = leaf->GetBranch();
2001  Double_t cmin = DBL_MAX;
2002  for (Long64_t i = 0; i < fTree->GetEntries(); ++i) {
2003  auto entryNumber = fTree->GetEntryNumber(i);
2004  if (entryNumber < 0) break;
2005  branch->GetEntry(entryNumber);
2006  for (Int_t j = 0; j < leaf->GetLen(); ++j) {
2007  Double_t val = leaf->GetValue(j);
2008  if (val < cmin) {
2009  cmin = val;
2010  }
2011  }
2012  }
2013  return cmin;
2014 }
2015 
2016 
2017 
2019 
2020 const Char_t* KVTreeAnalyzer::get_leaf_type_name(const TNamed* l)
2021 {
2022  TLeaf* lf = (TLeaf*)fChain->GetListOfLeaves()->FindObject(l->GetName());
2023  return lf->GetTypeName();
2024 }
2025 
2026 
2027 
2031 
2033 {
2034  // Method called when user hits 'draw' button in TTree GUI.
2035  // If only one leaf/alias is selected, this actually calls DrawLeaf.
2036 
2037  if (fLeafExpr == "-")return;
2038  Bool_t threeDexp = fSelectedLeaves->GetEntries() == 3;
2039  if (threeDexp && !fProfileHisto) {
2040  DrawAsDalitz();
2041  return;
2042  }
2043  if (fSelectedLeaves->GetEntries() == 1) {
2044  DrawLeaf(fSelectedLeaves->First());
2045  return;
2046  }
2047 
2048  if (fUserWeight) {
2049  if (!DefineWeight()) return;
2050  }
2051 
2052  int nx = 500, ny = 500;
2053  double xmin, xmax, ymin, ymax;
2054  xmin = xmax = ymin = ymax = 0;
2055  TString Xexpr, Yexpr, Zexpr;
2056  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2057  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2058  if (threeDexp) Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2059  if (fXLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fXLeaf), "Char_t")) {
2060  TString tmp = Xexpr;
2061  Xexpr.Form("int(%s)", tmp.Data());
2062  }
2063  if (fYLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fYLeaf), "Char_t")) {
2064  TString tmp = Yexpr;
2065  Yexpr.Form("int(%s)", tmp.Data());
2066  }
2067 
2068  if (threeDexp) fLeafExpr.Form("%s:%s:%s", Zexpr.Data(), Yexpr.Data(), Xexpr.Data());
2069  else fLeafExpr.Form("%s:%s", Yexpr.Data(), Xexpr.Data());
2070  TString name;
2071  name.Form("h%d", fHistoNumber);
2072  TString drawexp(fLeafExpr), histo, histotitle;
2073  if (fUserWeight) GenerateHistoTitle(histotitle, fLeafExpr, "", fWeight);
2074  else GenerateHistoTitle(histotitle, fLeafExpr, "");
2075 
2076  // Check histo doesn't already exist
2077  // Look for list of histograms with given title as we don't distinguish TH2 from TProfile
2078  unique_ptr<KVSeqCollection> same_histo(fHistolist.GetSubListWithMethod(histotitle, "GetHistoTitle"));
2079  TIter nxtSame(same_histo.get());
2080  KVHistogram* kvhisto;
2081  while ((kvhisto = (KVHistogram*)nxtSame())) {
2082  if ((fProfileHisto && kvhisto->IsProfile()) || (!fProfileHisto && kvhisto->IsTH2())) {
2083  DrawHisto(kvhisto->GetHisto());
2084  return;
2085  }
2086  }
2087 
2088  if (fUserBinning) {
2089  if (!DefineUserBinning()) return;
2090  }
2091 
2092  xmin = GetTreeMinimum(Xexpr);
2093  xmax = GetTreeMaximum(Xexpr);
2094  if (fXLeaf->InheritsFrom("TLeaf") &&
2095  (!strcmp(get_leaf_type_name(fXLeaf), "Int_t") || !strcmp(get_leaf_type_name(fXLeaf), "Short_t") || !strcmp(get_leaf_type_name(fXLeaf), "Char_t"))
2096  ) {
2097  xmin -= 0.5;
2098  xmax += 0.5;
2099  nx = xmax - xmin;
2100  }
2101  ymin = GetTreeMinimum(Yexpr);
2102  ymax = GetTreeMaximum(Yexpr);
2103  if (fYLeaf->InheritsFrom("TLeaf") &&
2104  (!strcmp(get_leaf_type_name(fYLeaf), "Int_t") || !strcmp(get_leaf_type_name(fYLeaf), "Short_t") || !strcmp(get_leaf_type_name(fYLeaf), "Char_t"))
2105  ) {
2106  ymin -= 0.5;
2107  ymax += 0.5;
2108  ny = ymax - ymin;
2109  }
2110  if (fUserBinning) {
2111  nx = fNx;
2112  ny = fNy;
2113  xmin = fXmin;
2114  xmax = fXmax;
2115  ymin = fYmin;
2116  ymax = fYmax;
2117  }
2118 
2119  if (!fProfileHisto) histo.Form(">>%s(%d,%f,%f,%d,%f,%f)", name.Data(), nx, xmin, xmax, ny, ymin, ymax);
2120  else {
2121  if (fUserBinning) histo.Form(">>%s(%d,%f,%f)", name.Data(), nx, xmin, xmax);
2122  else histo.Form(">>%s", name.Data());
2123  }
2124  drawexp += histo;
2125  TString ww = "";
2126  if (fUserWeight) ww += fWeight;
2127  Long64_t drawResult;
2128  if (!fProfileHisto) drawResult = fTree->Draw(drawexp, ww.Data(), "goff");
2129  else drawResult = fTree->Draw(drawexp, ww.Data(), "prof,goff");
2130  if (drawResult < 0) {
2131  // Error: problem with Draw, probably bad expression
2132  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
2133  return;
2134  }
2135  TH1* h(nullptr);
2136 #ifdef WITH_PROOF
2137  if (IsPROOFEnabled())
2139  else
2140 #endif
2141  h = (TH1*)gDirectory->Get(name);
2142  h->SetTitle(histotitle);
2143  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
2144  h->SetDirectory(0);
2145  if (h->InheritsFrom("TH1")) {
2146  h->GetXaxis()->SetTitle(fXLeaf->GetTitle());
2147  h->SetLineWidth(2);
2148  }
2149  if (h->InheritsFrom("TH2") || h->InheritsFrom("TProfile")) h->GetYaxis()->SetTitle(fYLeaf->GetTitle());
2150 
2151  AddHisto(h);
2152  fHistoNumber++;
2153  DrawHisto(h);
2154 }
2155 
2156 
2157 
2158 
2160 
2162 {
2163  if ((!fXLeaf->InheritsFrom("TLeaf")) || (!fYLeaf->InheritsFrom("TLeaf")) || (!fZLeaf->InheritsFrom("TLeaf"))) {
2164  KVError::Warning(this, "DrawAsDalitz", "Cannot be used with aliases !");
2165  return;
2166  }
2167 
2168  TString Xexpr, Yexpr, Zexpr;
2169  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2170  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2171  Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2172  fLeafExpr.Form("%s:%s:%s", Xexpr.Data(), Yexpr.Data(), Zexpr.Data());
2173 
2174  TString xType(get_leaf_type_name(fXLeaf));
2175  TString yType(get_leaf_type_name(fYLeaf));
2176  TString zType(get_leaf_type_name(fZLeaf));
2177 
2178  if ((!xType.Contains(yType.Data())) || (!yType.Contains(zType.Data()))) {
2179  KVError::Warning(this, "DrawAsDalitz", "Leaves %s must have the same type !", fLeafExpr.Data());
2180  return;
2181  }
2182 
2183  Double_t x, y, z;
2184  Double_t var1, var2, var3;
2185  Float_t varf1, varf2, varf3;
2186  Int_t vari1, vari2, vari3;
2187  Short_t vars1, vars2, vars3;
2188  Char_t varc1, varc2, varc3;
2189  x = y = z = 0.;
2190 
2191  if (xType.Contains("Int_t")) {
2192  fTree->SetBranchAddress(Xexpr.Data(), &vari1);
2193  fTree->SetBranchAddress(Yexpr.Data(), &vari2);
2194  fTree->SetBranchAddress(Zexpr.Data(), &vari3);
2195  }
2196  else if (xType.Contains("Short_t")) {
2197  fTree->SetBranchAddress(Xexpr.Data(), &vars1);
2198  fTree->SetBranchAddress(Yexpr.Data(), &vars2);
2199  fTree->SetBranchAddress(Zexpr.Data(), &vars3);
2200  }
2201  else if (xType.Contains("Char_t")) {
2202  fTree->SetBranchAddress(Xexpr.Data(), &varc1);
2203  fTree->SetBranchAddress(Yexpr.Data(), &varc2);
2204  fTree->SetBranchAddress(Zexpr.Data(), &varc3);
2205  }
2206  else if (xType.Contains("Double_t")) {
2207  fTree->SetBranchAddress(Xexpr.Data(), &var1);
2208  fTree->SetBranchAddress(Yexpr.Data(), &var2);
2209  fTree->SetBranchAddress(Zexpr.Data(), &var3);
2210  }
2211  else if (xType.Contains("Float_t")) {
2212  fTree->SetBranchAddress(Xexpr.Data(), &varf1);
2213  fTree->SetBranchAddress(Yexpr.Data(), &varf2);
2214  fTree->SetBranchAddress(Zexpr.Data(), &varf3);
2215  }
2216 
2217  if (fUserBinning) {
2218  if (!DefineUserBinningD()) return;
2219  }
2220 
2221  TString histotitle;
2222  GenerateHistoTitle(histotitle, fLeafExpr, "");
2223 
2224  KVDalitzPlot* h = 0;
2225  if (fUserBinning) h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data(), fOrderedDalitz, fNxD, 0., 1.2, fNyD, 0., 1.2);
2226  else h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data());
2227  fHistoNumber++;
2228 
2229  TEntryList* el = fChain->GetEntryList();
2230  if (el) el->GetEntry(0);
2231  Int_t nentries = fTree->GetEntries();
2232 
2233  if (el) nentries = el->GetN();
2234  for (int i = 0; i < nentries; i++) {
2235  Int_t j = i;
2236  if (el) j = el->Next();
2237  fTree->GetEntry(j);
2238  if (xType.Contains("Int_t")) {
2239  x = vari1;
2240  y = vari2;
2241  z = vari3;
2242  }
2243  else if (xType.Contains("Short_t")) {
2244  x = vars1;
2245  y = vars2;
2246  z = vars3;
2247  }
2248  else if (xType.Contains("Char_t")) {
2249  x = varc1;
2250  y = varc2;
2251  z = varc3;
2252  }
2253  else if (xType.Contains("Double_t")) {
2254  x = var1;
2255  y = var2;
2256  z = var3;
2257  }
2258  else if (xType.Contains("Float_t")) {
2259  x = varf1;
2260  y = varf2;
2261  z = varf3;
2262  }
2263  h->FillAsDalitz(x, y, z);
2264  }
2265 
2266  h->SetOption("col");
2267  h->SetDirectory(0);
2268  AddHisto((TH2F*)h);
2269  DrawHisto(h);
2270  fTree->ResetBranchAddresses();
2271 
2272 }
2273 
2274 
2275 
2280 
2281 bool KVTreeAnalyzer::DefineWeight()
2282 {
2283  // Open dialogue box for user to fill required weight for histo
2284  //
2285  // returns false if Cancel button is pressed
2286 
2287  KVNameValueList params{{"Weight", ""}};
2288  Bool_t cancel_pressed{false};
2289  auto s = new KVNameValueListGUI(GetMainWindow(), &params, &cancel_pressed);
2290  s->DisplayDialog();
2291  // cancel was pressed ?
2292  if (cancel_pressed) return false;
2293  fWeight = params.GetStringValue("Weight");
2294  return true;
2295 }
2296 
2297 
2298 
2301 
2303 {
2304  // Method called when user double-clicks a leaf/alias in list
2305 
2306  if (fUserWeight) {
2307  if (!DefineWeight()) return;
2308  }
2309 
2310  TH1* histo = nullptr;
2311  if (obj->InheritsFrom("TLeaf")) {
2312  TLeaf* leaf = (TLeaf*)fChain->GetListOfLeaves()->FindObject(obj->GetName());//dynamic_cast<TLeaf*>(obj);
2313  TString expr = leaf->GetName();
2314  TString type = leaf->GetTypeName();
2315  // check histo not already in list
2316  TString htit;
2317  if (fUserWeight) GenerateHistoTitle(htit, expr, "", fWeight);
2318  else GenerateHistoTitle(htit, expr, "");
2319  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2320  if (kvhisto) histo = kvhisto->GetHisto();
2321  if (!histo) {
2322  if (type.Contains("Int_t") || type.Contains("Char_t") || type.Contains("Short_t") || type == "Long_t" || type == "Long64_t") {
2323  Int_t xmin = GetTreeMinimum(expr);
2324  Int_t xmax = GetTreeMaximum(expr);
2325  if (type.Contains("Char_t")) {
2326  TString tmp;
2327  tmp.Form("int(%s)", expr.Data());
2328  expr = tmp.Data();
2329  }
2330  histo = MakeIntHisto(expr, "", xmin, xmax, (fUserWeight ? fWeight.Data() : ""));
2331  if (!histo) return;
2332  histo->GetXaxis()->SetTitle(leaf->GetName());
2333  }
2334  else {
2335  histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2336  if (!histo) return;
2337  histo->GetXaxis()->SetTitle(leaf->GetName());
2338  }
2339  if (!histo) return;
2340  }
2341  DrawHisto(histo);
2342  }
2343  else {
2344  TString expr = obj->GetTitle();
2345  // check histo not already in list
2346  TString htit;
2347  GenerateHistoTitle(htit, expr, "", (fUserWeight ? fWeight.Data() : ""));
2348  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2349  if (kvhisto) histo = kvhisto->GetHisto();
2350  if (!histo) histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2351  if (!histo) return;
2352  histo->GetXaxis()->SetTitle(obj->GetTitle());
2353  DrawHisto(histo);
2354  }
2355 }
2356 
2357 
2358 
2361 
2363 {
2364  // Method called when user histo selection changes in GUI histogram list
2365 
2366  G_histo_del->SetEnabled(kFALSE);
2367  G_histo_add->SetEnabled(kFALSE);
2368  fSelectedHistos = G_histolist->GetSelectedObjects();
2369  if (fSelectedHistos.GetEntries() > 0) {
2370  G_histo_del->SetEnabled(kTRUE);
2371  if (fSelectedHistos.GetEntries() == 1 && fSelectedHistos.First()->IsA() == TH1F::Class()) {
2372  }
2373  if (fSelectedHistos.GetEntries() == 2) G_histo_add->SetEnabled(kTRUE);
2374  }
2375 }
2376 
2377 
2378 
2380 
2382 {
2383  SetEntryList(GetSelection(sel));
2384 }
2385 
2386 
2387 
2390 
2392 {
2393  // Look for selection in list of selections
2394  return (TEntryList*)fSelections.FindObjectByTitle(selection);
2395 }
2396 
2397 
2399 
2401 {
2402 #ifdef WITH_PROOF
2403  fPROOFEnabled = yes;
2404  if (yes) {
2405  // open new PROOF-lite session
2406  if (!gProof) TProof::Open("");
2407  if (fChain) fChain->SetProof(kTRUE);
2408  }
2409  else {
2410  if (fChain) fChain->SetProof(kFALSE);
2411  }
2412 #else
2413  fPROOFEnabled = kFALSE;
2414 #endif
2415 }
2416 
2417 
2418 
2420 
2422 {
2423  Info("Save", "Saving analysis %s in file %s", GetTitle(), fSaveAnalysisFileName.Data());
2424  SaveAs(fSaveAnalysisFileName);
2425  SetAnalysisModifiedSinceLastSave(kFALSE);
2426 }
2427 
2428 
2429 
2436 
2437 void KVTreeAnalyzer::SaveAs(const char* filename, Option_t*) const
2438 {
2439  // Override TObject::SaveAs
2440  // We need to:
2441  // - (re)create the file
2442  // - do fChain->SetDirectory before writing to disk
2443 
2444  // save current directory
2445  TDirectory* sav = gDirectory;
2446  TDirectory* chsav = (fChain ? fChain->GetDirectory() : nullptr);
2447 
2448  TFile* f = TFile::Open(filename, "recreate");
2449  Write();
2450  if (fChain) { // make sure TChain doesn't get redirected
2451  fChain->SetDirectory(chsav);
2452  }
2453  delete f;
2454 
2455  // back to original directory
2456  sav->cd();
2457 }
2458 
2459 
2460 // void KVTreeAnalyzer::FitGum1()
2461 // {
2462 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2463 // if(!histo) return;
2464 // GDfirst->SetParameters(histo->GetMean(),histo->GetRMS());
2465 // histo->Fit(GDfirst,"EM");
2466 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2467 // if(!stats){
2468 // histo->SetStats(1);
2469 // histo->Draw();
2470 // gPad->Update();
2471 // stats = (TPaveStats*)histo->FindObject("stats");
2472 // }
2473 // if(stats){
2474 // // if canvas's 'no stats' option has been set by user,
2475 // // there will still be no valid stats object,
2476 // // so this test is to avoid the ensuing seg fault
2477 // stats->SetFitFormat("10.9g");
2478 // stats->SetOptFit(111);
2479 // }
2480 // histo->SetOption("e1");
2481 // histo->SetMarkerStyle(24);
2482 // histo->SetMarkerColor(kBlue+2);
2483 // gPad->Modified();gPad->Update();
2484 // SetAnalysisModifiedSinceLastSave(kTRUE);
2485 // }
2486 // void KVTreeAnalyzer::FitGum2()
2487 // {
2488 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2489 // if(!histo) return;
2490 // GDsecond->SetParameters(histo->GetMean(),histo->GetRMS());
2491 // histo->Fit(GDsecond,"EM");
2492 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2493 // if(!stats){
2494 // histo->SetStats(1);
2495 // histo->Draw();
2496 // gPad->Update();
2497 // stats = (TPaveStats*)histo->FindObject("stats");
2498 // }
2499 // if(stats){
2500 // // if canvas's 'no stats' option has been set by user,
2501 // // there will still be no valid stats object,
2502 // // so this test is to avoid the ensuing seg fault
2503 // stats->SetFitFormat("10.9g");
2504 // stats->SetOptFit(111);
2505 // }
2506 // histo->SetOption("e1");
2507 // histo->SetMarkerStyle(24);
2508 // histo->SetMarkerColor(kBlue+2);
2509 // gPad->Modified();gPad->Update();
2510 // SetAnalysisModifiedSinceLastSave(kTRUE);
2511 // }
2512 // void KVTreeAnalyzer::FitGum3()
2513 // {
2514 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2515 // if(!histo) return;
2516 // GDthird->SetParameters(histo->GetMean(),histo->GetRMS());
2517 // histo->Fit(GDthird,"EM");
2518 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2519 // if(!stats){
2520 // histo->SetStats(1);
2521 // histo->Draw();
2522 // gPad->Update();
2523 // stats = (TPaveStats*)histo->FindObject("stats");
2524 // }
2525 // if(stats){
2526 // // if canvas's 'no stats' option has been set by user,
2527 // // there will still be no valid stats object,
2528 // // so this test is to avoid the ensuing seg fault
2529 // stats->SetFitFormat("10.9g");
2530 // stats->SetOptFit(111);
2531 // }
2532 // histo->SetOption("e1");
2533 // histo->SetMarkerStyle(24);
2534 // histo->SetMarkerColor(kBlue+2);
2535 // gPad->Modified();gPad->Update();
2536 // SetAnalysisModifiedSinceLastSave(kTRUE);
2537 // }
2538 // void KVTreeAnalyzer::FitGausGum1()
2539 // {
2540 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2541 // if(!histo) return;
2542 // GausGum1->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2543 // histo->Fit(GausGum1,"EM");
2544 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2545 // if(!stats){
2546 // histo->SetStats(1);
2547 // histo->Draw();
2548 // gPad->Update();
2549 // stats = (TPaveStats*)histo->FindObject("stats");
2550 // }
2551 // if(stats){
2552 // // if canvas's 'no stats' option has been set by user,
2553 // // there will still be no valid stats object,
2554 // // so this test is to avoid the ensuing seg fault
2555 // stats->SetFitFormat("10.9g");
2556 // stats->SetOptFit(111);
2557 // }
2558 // histo->SetOption("e1");
2559 // histo->SetMarkerStyle(24);
2560 // histo->SetMarkerColor(kBlue+2);
2561 // gPad->Modified();gPad->Update();
2562 // SetAnalysisModifiedSinceLastSave(kTRUE);
2563 // }
2564 //
2565 // void KVTreeAnalyzer::FitGausGum2()
2566 // {
2567 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2568 // if(!histo) return;
2569 // GausGum2->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2570 // histo->Fit(GausGum2,"EM");
2571 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2572 // if(!stats){
2573 // histo->SetStats(1);
2574 // histo->Draw();
2575 // gPad->Update();
2576 // stats = (TPaveStats*)histo->FindObject("stats");
2577 // }
2578 // if(stats){
2579 // // if canvas's 'no stats' option has been set by user,
2580 // // there will still be no valid stats object,
2581 // // so this test is to avoid the ensuing seg fault
2582 // stats->SetFitFormat("10.9g");
2583 // stats->SetOptFit(111);
2584 // }
2585 // histo->SetOption("e1");
2586 // histo->SetMarkerStyle(24);
2587 // histo->SetMarkerColor(kBlue+2);
2588 // gPad->Modified();gPad->Update();
2589 // SetAnalysisModifiedSinceLastSave(kTRUE);
2590 // }
2591 //
2592 // void KVTreeAnalyzer::FitGausGum3()
2593 // {
2594 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2595 // if(!histo) return;
2596 // GausGum3->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2597 // histo->Fit(GausGum3,"EM");
2598 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2599 // if(!stats){
2600 // histo->SetStats(1);
2601 // histo->Draw();
2602 // gPad->Update();
2603 // stats = (TPaveStats*)histo->FindObject("stats");
2604 // }
2605 // if(stats){
2606 // // if canvas's 'no stats' option has been set by user,
2607 // // there will still be no valid stats object,
2608 // // so this test is to avoid the ensuing seg fault
2609 // stats->SetFitFormat("10.9g");
2610 // stats->SetOptFit(111);
2611 // }
2612 // histo->SetOption("e1");
2613 // histo->SetMarkerStyle(24);
2614 // histo->SetMarkerColor(kBlue+2);
2615 // gPad->Modified();gPad->Update();
2616 // SetAnalysisModifiedSinceLastSave(kTRUE);
2617 // }
2618 
2619 
2624 
2626 {
2627  // fill and return TList with histos containing the given data
2628  // which may be 1D ("mult", "zmax", etc.) or 2D ("zmax:mult")
2629  // DELETE LIST AFTER USE
2630  TList* hlist = new TList;
2631  TIter next(&fHistolist);
2632 
2633  KVHistogram* h;
2634  while ((h = (KVHistogram*)next())) {
2635 
2636  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr)) hlist->Add(h->GetHisto());
2637  }
2638  return hlist;
2639 }
2640 
2641 
2642 
2646 
2648 {
2649  // fill and return TList with histos using the given selection criteria
2650  // DELETE LIST AFTER USE
2651  TList* hlist = new TList;
2652  TIter next(&fHistolist);
2653 
2654  KVHistogram* h;
2655  while ((h = (KVHistogram*)next())) {
2656 
2657  if (h->IsType("Histo") && !strcmp(h->GetSelection(), expr)) hlist->Add(h->GetHisto());
2658  }
2659  return hlist;
2660 }
2661 
2662 
2663 
2665 
2666 TH1* KVTreeAnalyzer::GetHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2667 {
2668  TIter next(&fHistolist);
2669 
2670  KVHistogram* h;
2671  while ((h = (KVHistogram*)next())) {
2672 
2673  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection)) {
2674  if (strcmp(weight, "")) {
2675  if (!strcmp(h->GetWeight(), weight)) return h->GetHisto();
2676  }
2677  else return h->GetHisto();
2678  }
2679  }
2680  return 0;
2681 }
2682 
2683 
2684 
2686 
2688 {
2689  return (KVHistogram*)fHistolist.FindObjectWithMethod(title, "GetHistoTitle");
2690 }
2691 
2692 
2693 
2695 
2696 void KVTreeAnalyzer::DeleteHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2697 {
2698  TIter next(&fHistolist);
2699 
2700  KVHistogram* h;
2701  while ((h = (KVHistogram*)next())) {
2702 
2703  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection) && !strcmp(h->GetWeight(), weight)) {
2704  fHistolist.Remove(h);
2705  delete h;
2706  SetAnalysisModifiedSinceLastSave(kTRUE);
2707  }
2708  }
2709  G_histolist->Display(&fHistolist);
2710 }
2711 
2712 
2713 
2716 
2718 {
2719  // Delete all currently selected histograms
2720  if (fSelectedHistos.GetEntries()) {
2721  Int_t nsel = fSelectedHistos.GetEntries();
2722  if (nsel < 1) return;
2723  for (int i = 0; i < nsel; i++) {
2724  TObject* obj = fSelectedHistos.At(i);
2725  fHistolist.Remove(obj);
2726  delete obj;
2727  SetAnalysisModifiedSinceLastSave(kTRUE);
2728  }
2729  G_histolist->Display(&fHistolist);
2730  }
2732 }
2733 
2734 
2735 
2740 
2742 {
2743  // Called when G_histo_add button is pressed
2744  // There should be 2 histograms in fSelectedHistos
2745  // We assume that both are of same type and have same binning etc.
2746 
2747  if (fSelectedHistos.GetEntries() != 2) return;
2748  HistoToAdd1 = dynamic_cast<KVHistogram*>(fSelectedHistos.At(0))->GetHisto();
2749  HistoToAdd2 = dynamic_cast<KVHistogram*>(fSelectedHistos.At(1))->GetHisto();
2750  if (HistoToAdd1 && HistoToAdd2) {
2751  Info("AddSelectedHistos", "Adding %s and %s", HistoToAdd1->GetName(), HistoToAdd2->GetName());
2752  TString name = Form("h%d", fHistoNumber);
2753  TString oldname = HistoToAdd1->GetName();
2754  if (oldname.BeginsWith("I")) name.Prepend("I");
2755  HistoAddResult = (TH1*)HistoToAdd1->Clone(name);
2756  ResetMethodCalled();
2757  Bool_t ok = KVBase::OpenContextMenu("HistoAddition", this);
2758  if (!ok) {
2759  Info("AddSelectedHistos", "Call to context menu not OK");
2760  delete HistoAddResult;
2761  return;
2762  }
2763  if (MethodNotCalled()) {
2764  Info("AddSelectedHistos", "You pressed cancel");
2765  delete HistoAddResult;
2766  return;
2767  }
2768  ++fHistoNumber;
2769  AddHisto(HistoAddResult);
2770  }
2771  else {
2772  Info("AddSelectedHistos", "Only possible for 2 histograms");
2773  }
2774 }
2775 
2776 
2777 
2779 
2781 {
2782  fMethodCalled = kTRUE;
2783  HistoAddResult->Add(HistoToAdd1, HistoToAdd2, c1, c2);
2784 // TODO: it would be nice to distinguish histograms which are the result of
2785 // adding other histograms together. For the moment they appear identical to
2786 // to the first histogram in terms of variables etc. The following attempt
2787 // doesn't work (can't parse the title correctly)
2788 // TString title;
2789 // title.Form("SUMHIST:{%s,%s}",HistoToAdd1->GetTitle(),HistoToAdd2->GetTitle());
2790 // HistoAddResult->SetTitle(title);
2791 }
2792 
2793 
2794 
2795 
2798 
2800 {
2801  // regenerate entry lists for all selections
2802  TList old_lists;
2803  old_lists.AddAll(&fSelections);
2804  fSelections.Clear();
2805  G_selectionlist->RemoveAll();
2806  TIter next(&old_lists);
2807  TEntryList* old_el;
2808  SetEntryList(nullptr);
2809  SelectionChanged();
2810  while ((old_el = (TEntryList*)next())) {
2811  cout << "REGENERATING SELECTION : " << old_el->GetTitle() << endl;
2812  MakeSelection(old_el->GetTitle());
2813  ((TEntryList*)fSelections.Last())->SetReapplyCut(old_el->GetReapplyCut());
2814  G_selectionlist->Display(&fSelections);
2815  }
2816  old_lists.Delete();
2817 }
2818 
2819 
2820 
2822 
2824 {
2825  switch (id) {
2826  case MH_OPEN_CHAIN:
2827  OpenChain();
2828  break;
2829  case MH_OPEN_FILE:
2830  HistoFileMenu_Open();
2831  break;
2832  case MH_ADD_FRIEND:
2834  break;
2835  case MH_APPLY_ANALYSIS:
2837  break;
2838  case MH_SAVE_FILE:
2839  HistoFileMenu_Save();
2840  break;
2841  case MH_SAVE:
2842  Save();
2843  break;
2844  case MH_CLOSE:
2845  delete fMain_histolist;
2846  GUIClosed();
2847  break;
2848  case MH_QUIT:
2849  // check all analyzers need saving
2850  while (fgAnalyzerList->GetEntries() > 1) {
2851  TIter next(fgAnalyzerList);
2853  do {
2854  tan = (KVTreeAnalyzer*)next();
2855  }
2856  while (tan == this);
2857  tan->AnalysisSaveCheck();
2858  delete tan;
2859  }
2860  AnalysisSaveCheck();
2861  gROOT->ProcessLine(".q");
2862  break;
2863 
2864  default:
2865  break;
2866  }
2867 }
2868 
2869 
2871 
2873 {
2874  switch (id) {
2875  case SEL_COMB_AND:
2877  break;
2878 
2879  case SEL_COMB_OR:
2881  break;
2882 
2883  case SEL_DELETE:
2884  DeleteSelections();
2885  break;
2886 
2887  case SEL_UPDATE:
2888  UpdateEntryLists();
2889  break;
2890 
2891  case SEL_GEN_CONST_XSEC:
2892  KVBase::OpenContextMenu("GenerateConstantXSecSelections", this);
2893  break;
2894 
2895  default:
2896  break;
2897  }
2898 }
2899 
2900 
2901 
2903 
2905 {
2906  switch (opt) {
2907  case OPT_PROOF:
2908  if (fOptionMenu->IsEntryChecked(OPT_PROOF)) {
2909  fOptionMenu->UnCheckEntry(OPT_PROOF);
2910  EnablePROOF(false);
2911  }
2912  else {
2913  fOptionMenu->CheckEntry(OPT_PROOF);
2914  EnablePROOF();
2915  }
2916  }
2917 }
2918 
2919 
2920 
2923 
2924 void KVTreeAnalyzer::HistoFileMenu_Open()
2925 {
2926  // Open a previous analysis session
2927 
2928  static TString dir(".");
2929  const char* filetypes[] = {
2930  "Analysis files", "Analysis*.root",
2931  0, 0
2932  };
2933  TGFileInfo fi;
2934  fi.fFileTypes = filetypes;
2935  fi.fIniDir = StrDup(dir);
2936  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2937  if (fi.fFilename) {
2938  KVTreeAnalyzer* newAnal = this;
2939  if (fTree) newAnal = new KVTreeAnalyzer(kFALSE);
2940  newAnal->OpenAnyFile(fi.fFilename);
2941  }
2942  dir = fi.fIniDir;
2943 }
2944 
2945 
2946 
2948 
2950 {
2951  static TString dir(".");
2952  const char* filetypes[] = {
2953  "ROOT files", "*.root",
2954  0, 0
2955  };
2956  TGFileInfo fi;
2957  fi.fFileTypes = filetypes;
2958  fi.fIniDir = StrDup(dir);
2959  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2960  if (fi.fFilename) {
2962  }
2963  dir = fi.fIniDir;
2964 }
2965 
2966 
2969 
2970 void KVTreeAnalyzer::OpenChain()
2971 {
2972  // Open a file or files containing TTrees to analyse
2973 
2974  static TString dir(".");
2975  const char* filetypes[] = {
2976  "ROOT files", "*.root*",
2977  0, 0
2978  };
2979  TGFileInfo fi;
2980  fi.fFileTypes = filetypes;
2981  fi.fIniDir = StrDup(dir);
2982  fi.SetMultipleSelection(kTRUE);
2983  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2984  if (fi.fFileNamesList && fi.fFileNamesList->GetEntries()) {
2985 
2986  // look in first file to find first TTree and use its name/title
2987  TString theTreeName, theTreeTitle;
2989  KVUnownedList keys;
2990  keys.AddAll(file->GetListOfKeys());
2991  // Get list of trees in file
2992  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
2993  if (trees->GetEntries()) {
2994  theTreeName = trees->First()->GetName();
2995  theTreeTitle = trees->First()->GetTitle();
2996  }
2997  if (theTreeName != "") {
2998  // if analysis already en cours, open new GUI
2999  KVTreeAnalyzer* newAnal = this;
3000  if (got_histos_or_tree_from_file) newAnal = new KVTreeAnalyzer(kFALSE);
3001  newAnal->OpenChain(theTreeName, theTreeTitle, fi.fFileNamesList);
3002  if (fi.fFileNamesList->GetEntries() == 1) {
3003  // if a single file is selected, look to see if any histograms are in it
3004  newAnal->GetHistosFromFile(file, keys);
3005  }
3006  }
3007  else { // no TTree in file - look for histograms
3008  if (fi.fFileNamesList->GetEntries() == 1) {
3009  // if analysis already en cours, open new GUI
3010  KVTreeAnalyzer* newAnal = this;
3011  if (got_histos_or_tree_from_file) newAnal = new KVTreeAnalyzer(kFALSE);
3012  // if a single file is selected, look to see if any histograms are in it
3013  newAnal->GetHistosFromFile(file, keys);
3014  if(newAnal->got_histos_or_tree_from_file) newAnal->SetWindowTitle(file->GetName());
3015  }
3016  }
3017  }
3018  dir = fi.fIniDir;
3019 }
3020 
3021 
3022 
3024 
3026 {
3027  static TString dir(".");
3028  const char* filetypes[] = {
3029  "ROOT files", "*.root",
3030  0, 0
3031  };
3032  TGFileInfo fi;
3033  fi.fFileTypes = filetypes;
3034  fi.fIniDir = StrDup(dir);
3035  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3036  if (fi.fFilename) {
3038  }
3039  dir = fi.fIniDir;
3040 }
3041 
3042 
3043 
3045 
3046 void KVTreeAnalyzer::HistoFileMenu_Save()
3047 {
3048  const char* filetypes[] = {
3049  "Analysis files", "Analysis*.root",
3050  0, 0
3051  };
3052  TGFileInfo fi;
3053  fi.fFileTypes = filetypes;
3054  fi.fIniDir = StrDup(fAnalysisSaveDir);
3055  fi.fFilename = StrDup(fSaveAnalysisFileName);
3056  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDSave, &fi);
3057  if (fi.fFilename) {
3058  //if no ".xxx" ending given, we add ".root"
3059  TString filenam(fi.fFilename);
3060  if (!filenam.Contains('.'))
3061  filenam += ".root";
3062  // update name of file to autosave analysis in
3063  fSaveAnalysisFileName = filenam;
3064  Save();
3065  }
3066  fAnalysisSaveDir = fi.fIniDir;
3067 }
3068 
3069 
3070 
3072 
3074 {
3075  TIter next(&keys);
3076  TKey* akey;
3077  while ((akey = (TKey*)next())) {
3078  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3079  if (!fHistolist.FindObject(akey->GetName())) {
3080  TH1* h = (TH1*)file->Get(akey->GetName());
3081  h->SetDirectory(0);
3082  fHistolist.Add(new KVHistogram(h));
3083  got_histos_or_tree_from_file = true;
3084  }
3085  }
3086  }
3087  G_histolist->Display(&fHistolist);
3088 }
3089 
3090 
3091 
3094 
3095 void KVTreeAnalyzer::OpenSingleFile(TFile* file)
3096 {
3097  // Open TTree in file (as a TChain) and import any histograms found in file
3098 
3099  fHistolist.Clear();
3100  KVUnownedList keys;
3101  keys.AddAll(file->GetListOfKeys());
3102  // Get list of trees in file
3103  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3104  if (trees->GetEntries()) {
3105  // Get name of first tree
3106  TString aTreeName = trees->First()->GetName();
3107  TString aFileName = file->GetName();
3108  TList fileList;
3109  TNamed ff(aFileName.Data(), "File Name");
3110  fileList.Add(&ff);
3111  OpenChain(aTreeName, trees->First()->GetTitle(), &fileList);
3112  }
3113  else
3114  SetWindowTitle(file->GetName()); // set GUI window name to file name if no TTree found
3115  GetHistosFromFile(file, keys);
3116 }
3117 
3118 
3119 
3123 
3125 {
3126  // assuming filepath is the URL of a ROOT file containing a previously-saved analysis, open it and
3127  // open the KVTreeAnalyzer object stored in it
3128 
3129  AnalysisSaveCheck();
3130 
3131  TFile* file = TFile::Open(filepath);
3132  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3133  if (kvta) {
3134  ReadFromFile(file);
3135  }
3136  else {
3137  OpenSingleFile(file);
3138  }
3139  fMenuFile->EnableEntry(MH_ADD_FRIEND);
3140 }
3141 
3142 
3143 
3148 
3149 void KVTreeAnalyzer::OpenChain(const TString& treename, const TString& treetitle, const TSeqCollection* files)
3150 {
3151  // Open a TChain for analysis
3152  // treename/title is the name/title of the TTree :)
3153  // files is a list of objects with the names of the files in the chain
3154 
3155  fChain = new TChain(treename, treetitle);
3156  TIter nxt(files);
3157  TObject* o;
3158  while ((o = nxt())) fChain->Add(o->GetName());
3159  fChain->SetDirectory(0);
3160  SetTree(fChain);
3161  fHistolist.Clear();
3162  fSelections.Clear();
3163  fAliasList.Clear();
3164  fHistoNumber = 1;
3165  fSelectionNumber = 1;
3166  fAliasNumber = 1;
3167  fSameColorIndex = 0;
3168  fSelectedLeaves = 0;
3169  SetAnalysisModifiedSinceLastSave(kFALSE);
3170  G_selectionlist->Display(&fSelections);
3171  G_histolist->Display(&fHistolist);
3172  FillLeafList();
3173  fMenuFile->EnableEntry(MH_ADD_FRIEND);
3174 }
3175 
3176 
3177 
3180 
3182 {
3183  // Generate all user aliases in list which are not already defined
3184 
3185  if (list->GetEntries()) {
3186  TIter next(list);
3187  TObject* o;
3188  while ((o = next())) {
3189  if (!GetAlias(o->GetTitle())) {
3190  Info("GenerateAllAliases", "Adding alias %s to leaflist", o->GetTitle());
3191  G_alias_text->SetText(o->GetTitle(), kFALSE);
3192  GenerateAlias();
3193  }
3194  }
3195  }
3196 }
3197 
3198 
3199 
3208 
3210 {
3211  // assuming filepath is the URL of a ROOT file, open it and,
3212  // if no KVTreeAnalyzer object is found, open first TTree in file
3213  // and apply all selections and generate all histograms which
3214  // were made for this analysis.
3215  // Any histograms in the file are added to the list of histograms.
3216  // If filepath contains an existing analysis, we add to it any
3217  // histograms/selections/aliases which are not defined
3218 
3219  TFile* file = TFile::Open(filepath);
3220  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3221  if (kvta) {
3222  // open existing analysis, add any missing histos/selections/aliases
3223  delete file;
3224  KVTreeAnalyzer* applyAnal = OpenFile(filepath);
3225  applyAnal->GenerateAllSelections(&fSelections);
3226  applyAnal->GenerateAllHistograms(&fHistolist);
3227  applyAnal->GenerateAllAliases(&fAliasList);
3228  return;
3229  }
3230  else {
3231  delete file;
3232  KVTreeAnalyzer* applyAnal = new KVTreeAnalyzer(kFALSE);
3233  applyAnal->OpenAnyFile(filepath);
3234  applyAnal->GenerateAllSelections(&fSelections);
3235  applyAnal->GenerateAllHistograms(&fHistolist);
3236  // make sure no selection is left active without being displayed
3237  applyAnal->SetEntryList(nullptr);
3238  applyAnal->G_selection_status->SetText("CURRENT SELECTION:", 0);
3239  applyAnal->GenerateAllAliases(&fAliasList);
3240  }
3241 }
3242 
3243 
3244 
3246 
3247 void KVTreeAnalyzer::SetAlias(const Char_t* name, const Char_t* expr)
3248 {
3249  TString exp = expr;
3250  exp.ReplaceAll("d2r", "TMath::DegToRad()");
3251  exp.ReplaceAll("r2d", "TMath::RadToDeg()");
3252  fAliasList.Add(new TNamed(name, exp.Data()));
3253  SetAnalysisModifiedSinceLastSave(kTRUE);
3254 }
3255 
3256 
3257 
3259 
3260 static const char* gSaveAsTypes[] = { "PostScript", "*.ps",
3261  "Encapsulated PostScript", "*.eps",
3262  "PDF", "*.pdf",
3263  "SVG", "*.svg",
3264  "TeX", "*.tex",
3265  "GIF", "*.gif",
3266  "ROOT files", "*.root",
3267  "XML", "*.xml",
3268  "PNG", "*.png",
3269  "XPM", "*.xpm",
3270  "JPEG", "*.jpg",
3271  "TIFF", "*.tiff",
3272  "XCF", "*.xcf",
3273  0, 0
3274  };
3275 
3276 
3277 
3282 
3284 {
3285  // Open file dialog box for user to choose directory and
3286  // image file-type for generating picture files of all
3287  // histos as they are drawn
3288 
3289  Info("SetUpHistoAutoSave", "Select image filetype and directory");
3290  TString workdir = gSystem->WorkingDirectory();
3291  static TString dir(".");
3292  static Int_t typeidx = 0;
3293  static Bool_t overwr = kFALSE;
3294  TGFileInfo fi;
3295  fi.fFileTypes = gSaveAsTypes;
3296  fi.fIniDir = StrDup(dir);
3297  fi.fFileTypeIdx = typeidx;
3298  fi.fOverwrite = overwr;
3299  new KVFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kKVFDDirectory, &fi);
3300  gSystem->ChangeDirectory(workdir.Data());
3301  TString ft = fi.fFileTypes[fi.fFileTypeIdx + 1];
3302  dir = fi.fIniDir;
3303  typeidx = fi.fFileTypeIdx;
3304  overwr = fi.fOverwrite;
3305  fAutoSaveDir = dir.Data();
3306  fAutoSaveType = ft(1, ft.Length()).Data();
3307  Info("SetUpHistoAutoSave", "file-type:%s directory:%s", fAutoSaveType.Data(), fAutoSaveDir.Data());
3308 }
3309 
3310 
3311 
3315 
3317 {
3318  // Save currently displayed histo as an image file
3319  // If 'same' checkbox is ticked, we use the same filename as used for the first histogram
3320 
3321  static TString lastFilename = "";
3322 
3323  if (fDrawSame) {
3324  gPad->SaveAs(lastFilename);
3325  return;
3326  }
3327  TString title = h->GetTitle();
3328  title.ReplaceAll(" ", "_");
3329  title.ReplaceAll("/", "#");
3330  title.ReplaceAll("*", "x");
3331  title.ReplaceAll("$", "#");
3332  title.ReplaceAll("(", "[");
3333  title.ReplaceAll(")", "]");
3334  title.Append(fAutoSaveType);
3335  title.Prepend("/");
3336  title.Prepend(fAutoSaveDir);
3337  Info("AutoSaveHisto", "Saved as: %s", title.Data());
3338  gPad->SaveAs(title);
3339  lastFilename = title;
3340 }
3341 
3342 
3343 
3347 
3349 {
3350  // We take the title of every object in 'list' and generate the corresponding selection
3351  // if it does not already exist
3352 
3353  TIter nextSel(list);
3354  TObject* sel;
3355  while ((sel = nextSel())) {
3356  if (!GetSelection(sel->GetTitle())) {
3357  Info("GenerateAllSelections", "Generating selection: %s", sel->GetTitle());
3358  MakeSelection(sel->GetTitle());
3359  }
3360  }
3361 }
3362 
3363 
3364 
3368 
3370 {
3371  // For every histogram in the list, we generate histograms with the same binning for
3372  // the same expression, selection and weight if they don't already exist
3373 
3374  TIter nextHist(list);
3375  KVHistogram* obj;
3376  TH1* hist;
3377  while ((obj = (KVHistogram*)nextHist())) {
3378  if (!obj->IsType("Cut")) {
3379  hist = obj->GetHisto();
3380  if (GetHistoByTitle(hist->GetTitle())) continue;
3381  TString exp = obj->GetExpression();
3382  TString sel = obj->GetSelection();
3383  TString weight = obj->GetWeight();
3384  if (weight == "1") weight = "";
3385  // set selection
3386  Info("GenerateAllHistograms", "Generating histogram: %s", hist->GetTitle());
3387  SetSelection(sel);
3388  RemakeHisto(hist, exp, weight);
3389  }
3390  }
3391 }
3392 
3393 
3394 
3404 
3406 {
3407  // Read serialized object from file
3408  //
3409  // For versions < 4, fHistolist contained TH* or TCutG objects:
3410  // we convert to a list of KVHistogram objects.
3411  //
3412  // Flag will be set to say analysis needs saving.
3413  //
3414  // Reparse all histogram expressions and selections in case they were not saved correctly.
3415 
3416  UInt_t R__s, R__c;
3417  if (R__b.IsReading()) {
3418  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3419  R__b.ReadClassBuffer(KVTreeAnalyzer::Class(), this, R__v, R__s, R__c);
3420  if (R__v < 5) {
3421  // no fChain pointer member before v5
3422  ReconnectTree();
3423  }
3424  if (fChain && fTree != fChain) SetTree(fChain);
3425  if (fChain) {
3426  if (fChain->GetListOfFriends() && fChain->GetListOfFriends()->GetEntries()) {
3427  Info("Streamer", "Checking friends");
3428  // check friends are TChains, not TTrees & they have valid pointers
3429  TFriendElement* fe;
3430  TIter nxt(fChain->GetListOfFriends());
3431  KVNumberList toRemove;
3432  KVNameValueList infos;
3433  int idx = 0;
3434  while ((fe = (TFriendElement*)nxt())) {
3435  if (!fe->GetTree() || (fe->GetTree() && !fe->GetTree()->InheritsFrom("TChain"))) {
3436  Info("Streamer", "Found friend to convert to TChain");
3437  toRemove.Add(idx);
3438  infos.SetValue(Form("treeName%d", idx), fe->GetTreeName());
3439  if (!fe->GetFile()) {
3440  Info("Streamer", "Choose file containg friend tree %s", fe->GetTreeName());
3441  static TString dir(".");
3442  const char* filetypes[] = {
3443  "ROOT files", "*.root",
3444  0, 0
3445  };
3446  TGFileInfo fi;
3447  fi.fFileTypes = filetypes;
3448  fi.fIniDir = StrDup(dir);
3449  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3450  if (fi.fFilename) {
3451  infos.SetValue(Form("fileName%d", idx), fi.fFilename);
3452  }
3453  dir = fi.fIniDir;
3454  }
3455  else
3456  infos.SetValue(Form("fileName%d", idx), fe->GetFile()->GetName());
3457  }
3458  ++idx;
3459  }
3460  if (toRemove.GetEntries()) {
3461  Info("Streamer", "Removing TTree friends");
3462  toRemove.Begin();
3463  while (!toRemove.End()) {
3464  fChain->RemoveFriend(fChain->GetFriend(infos.GetStringValue(Form("treeName%d", toRemove.Next()))));
3465  }
3466  toRemove.Begin();
3467  Info("Streamer", "Adding friends as TChains");
3468  while (!toRemove.End()) {
3469  idx = toRemove.Next();
3470  TChain* friendChain = new TChain(infos.GetStringValue(Form("treeName%d", idx)));
3471  friendChain->Add(infos.GetStringValue(Form("fileName%d", idx)));
3472  fChain->AddFriend(friendChain);
3473  }
3474  }
3475  }
3476  }
3477  if (R__v < 4) {
3478  //Info("Streamer","Converting old histo list");
3479  // convert fHistolist
3480  if (fHistolist.GetEntries()) {
3481  TList tmp;
3482  tmp.AddAll(&fHistolist);
3483  fHistolist.Clear("nodelete");
3484  TNamed* obj;
3485  TIter next(&tmp);
3486  while ((obj = (TNamed*)next())) {
3487  if (obj->InheritsFrom("TCutG"))
3488  fHistolist.Add(new KVHistogram(dynamic_cast<TCutG*>(obj)));
3489  else if (obj->InheritsFrom("TH1"))
3490  fHistolist.Add(new KVHistogram(dynamic_cast<TH1*>(obj)));
3491  }
3492  //Info("Streamer","New histolist:");
3493  fHistolist.ls();
3494  SetAnalysisModifiedSinceLastSave(kTRUE);
3495  }
3496  }
3497  if (fHistolist.GetEntries()) {
3498  TIter next(&fHistolist);
3499  KVHistogram* h;
3500  while ((h = (KVHistogram*)next())) {
3501  if (h->IsType("Histo")) h->ParseExpressionAndSelection();
3502  }
3503  }
3504  }
3505  else {
3507  }
3508 }
3509 
3510 
3511 
3516 
3518 {
3519  // assuming filepath is the URL of a ROOT file, open it and
3520  // add the first TTree found in file as a friend of the current TTree
3521  // Any histograms in the file are added to the list of histograms
3522 
3523  TFile* file = TFile::Open(filepath);
3524  KVUnownedList keys;
3525  keys.AddAll(file->GetListOfKeys());
3526  // Get list of trees in file
3527  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3528  if (trees->GetEntries()) {
3529  // Get name of first tree
3530  TString aTreeName = trees->First()->GetName();
3531  TChain* t = new TChain(aTreeName);
3532  t->Add(filepath);
3533  fChain->AddFriend(t);
3534  FillLeafList();
3535  }
3536  TIter next(&keys);
3537  TKey* akey;
3538  while ((akey = (TKey*)next())) {
3539  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3540  if (!fHistolist.FindObject(akey->GetName())) {
3541  TH1* h = (TH1*)file->Get(akey->GetName());
3542  h->SetDirectory(0);
3543  fHistolist.Add(new KVHistogram(h));
3544  }
3545  }
3546  }
3547  G_histolist->Display(&fHistolist);
3548 }
3549 
3550 
3551 
3552 
3553 
int Int_t
unsigned int UInt_t
unsigned long ULong_t
kVerticalFrame
kHorizontalFrame
kMainFrame
#define SafeDelete(p)
#define f(i)
#define c(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
kDeepCleanup
kLHintsExpandY
kLHintsLeft
kLHintsCenterY
kLHintsCenterX
kLHintsTop
kLHintsExpandX
kMBClose
kMBDismiss
kMBIconExclamation
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
Bool_t IsType(const Char_t *typ, bool case_insensitive=false) const
Definition: KVBase.h:185
static void InitEnvironment()
Definition: KVBase.cpp:196
static Bool_t OpenContextMenu(const char *method, TObject *obj, const char *alt_method_name="")
Definition: KVBase.cpp:1486
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:147
virtual void ActivateSortButtons()
Definition: KVListView.cpp:73
KVSeqCollection * GetPickOrderedSelectedObjects() const
Definition: KVListView.h:259
virtual void SetDataColumns(Int_t ncolumns)
Definition: KVListView.cpp:92
void SetDoubleClickAction(const char *receiver_class, void *receiver, const char *slot)
Definition: KVListView.cpp:211
virtual KVLVColumnData * GetDataColumn(Int_t index) const
Definition: KVListView.h:169
virtual void Display(const TCollection *l)
Definition: KVListView.h:174
KVUnownedList GetSelectedObjects() const
Definition: KVListView.h:253
virtual void SetMaxColumnSize(UInt_t width)
Definition: KVListView.h:162
virtual void RemoveAll()
Definition: KVListView.h:194
void AllowContextMenu(Bool_t on=kTRUE)
Definition: KVListView.h:292
virtual void SetDataColumn(Int_t index, const Char_t *name, const Char_t *method="", Int_t mode=kTextCenterX)
Definition: KVListView.cpp:107
void SetUseObjLabelAsRealClass(Bool_t yes=kTRUE)
Definition: KVListView.cpp:190
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:86
Bool_t End(void) const
Definition: KVNumberList.h:200
void Begin(void) const
Int_t GetEntries() const
Definition: KVNumberList.h:172
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)
Bool_t IsPROOFEnabledForSelections() const
static KVTreeAnalyzer * OpenFile(const Char_t *filename, Bool_t nogui=kFALSE)
TList * GetHistosByData(const Char_t *expr)
KVHistogram * GetHistoByTitle(const Char_t *title)
Bool_t IsPROOFEnabled() const
void SetTreeFileName(TTree *t)
void SetTree(TTree *t)
Connects a TChain for analysis.
void DeleteSelections()
Delete the currently selected selection(s)
void OpenAnyFile(const Char_t *filepath)
Bool_t MakeSelection(const Char_t *selection)
void ReapplyAnyFile(const Char_t *filepath)
void GenerateAllAliases(TCollection *list)
Generate all user aliases in list which are not already defined.
void SaveAs(const char *filename="", Option_t *option="") const override
void Copy(TObject &obj) const override
TH1 * RemakeHisto(TH1 *h, const Char_t *expr, const Char_t *weight="")
TH1 * MakeHisto(const Char_t *expr, const Char_t *selection, Int_t nX, Int_t nY=0, const Char_t *weight="", Double_t xmin=-1, Double_t xmax=-1, Double_t ymin=-1, Double_t ymax=-1)
void SetAlias(const Char_t *name, const Char_t *expr)
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)
void GenerateAllHistograms(TCollection *)
void SetSelection(TObject *)
void CurrentSelection()
Print the currently active selection (TEntryList set on TTree).
void UpdateEntryLists()
regenerate entry lists for all selections
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()
KVTreeAnalyzer(Bool_t nogui=kTRUE)
void HandleHistoFileMenu(Int_t)
void HandleOptionsMenu(Int_t opt)
void GetHistosFromFile(TFile *file, const KVUnownedList &keys)
void HandleSelectionsMenu(Int_t)
void DrawHistogram(TH1 *histo, Bool_t same=false, Bool_t logscale=false)
void EnablePROOF(Bool_t yes=kTRUE)
TList * GetHistosBySelection(const Char_t *expr)
void OpenAnyFriendFile(const Char_t *filepath)
void GenerateAllSelections(TCollection *)
For applying existing analysis to new data.
TH1 * GetHistogram(const Char_t *name) const
Return histogram with given name.
Long64_t GetEntriesInCurrentSelection() const
TH1 * MakeIntHisto(const Char_t *expr, const Char_t *selection, Int_t Xmin, Int_t Xmax, const Char_t *weight="")
virtual ~KVTreeAnalyzer()
Destructor.
void SelectionChanged()
Method called whenever the selected selection in the GUI list changes.
TH1 * GetHisto(const Char_t *expr, const Char_t *selection, const Char_t *weight="")
TNamed * GetAlias(const Char_t *expr)
void HistoSelectionChanged()
Method called when user histo selection changes in GUI histogram list.
void ReadFromFile(const Char_t *filename)
open a previously saved analysis session.
void DrawLeaf(TObject *)
Method called when user double-clicks a leaf/alias in list.
void DrawHisto(TObject *o, Bool_t gen=kTRUE)
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 Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
virtual Bool_t InheritsFrom(const char *classname) 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
void Error(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:116
void Warning(UserClass p, const char *location, const char *va_(fmt),...)
Definition: KVError.h:125
const long double s
Definition: KVUnits.h:98
TLine l
ClassImp(TPyArg)