KaliVeda  1.13/01
Heavy-Ion Analysis Toolkit
KVTreeAnalyzer.cpp
Go to the documentation of this file.
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 #include "TProof.h"
29 
30 using namespace std;
31 
33 
34 
35 
36 /* colours used for displaying several 1-D spectra on same plot */
37 
38 
40 #define MAX_COLOR_INDEX 5
42  kBlue + 2,
43  kRed + 2,
44  kGreen + 3,
45  kCyan - 2,
46  kOrange + 7,
47  kViolet + 2
48 };
49 
50 
52 
54 
55 
58 
60 {
61  // Default initialization
62 
63  gTreeAnalyzer = this;
64  fgAnalyzerList->Add(this);
65  fDeletedByGUIClose = kFALSE;
66 
68  fMain_histolist = 0;
69  fMain_leaflist = 0;
70  fMain_selectionlist = 0;
71  fMenuFile = 0;
72  SetAnalysisModifiedSinceLastSave(kFALSE);
73  fAnalysisSaveDir = ".";
74  fPROOFEnabled = false;
75 
76  fDrawSame = fApplySelection = fProfileHisto = kFALSE;
77  fDrawLog = gEnv->GetValue("KVTreeAnalyzer.LogScale", kFALSE);
78  fUserBinning = gEnv->GetValue("KVTreeAnalyzer.UserBinning", kFALSE);
79  fUserWeight = gEnv->GetValue("KVTreeAnalyzer.UserWeight", kFALSE);
80  fNewCanvas = gEnv->GetValue("KVTreeAnalyzer.NewCanvas", kFALSE);
81  fNormHisto = gEnv->GetValue("KVTreeAnalyzer.NormalizeIntegral", kFALSE);
82  fNormHistoEvents = gEnv->GetValue("KVTreeAnalyzer.NormalizeEvents", kFALSE);
83  fStatsHisto = gEnv->GetValue("KVTreeAnalyzer.Stats", kFALSE);
84  fAutoSaveHisto = kFALSE;
85  fSameColorIndex = 0;
86  fSelectedSelections = 0;
87  fSelectedLeaves = 0;
88  fSelectedHistos = 0;
89 
90  fNx = fNy = 500;
91  fXmin = fXmax = fYmin = fYmax = -1.;
92  fWeight = "1./(abs(vper))";
93 
94  fNxF = 200;
95  fXminF = fXmaxF = -1.;
96 
97  fNxD = fNyD = 120;
98  fOrderedDalitz = false;
99 }
100 
101 
102 
107 
109  : TNamed("KVTreeAnalyzer", "KVTreeAnalyzer"), fTree(0), fChain(0), fSelections(kTRUE), fHistoNumber(1), fSelectionNumber(1), fAliasNumber(1), fNoGui(nogui)
110 {
111  // Default constructor - used when loading from a file.
112  // The 'nogui' option (default=kTRUE) controls whether or not to
113  // launch the graphical interface
114 
115  init();
116  OpenGUI();
117 }
118 
119 
120 
121 
126 
128  : TNamed("KVTreeAnalyzer", t->GetTitle()), fTree(0), fChain(0), fSelections(kTRUE), fHistoNumber(1), fSelectionNumber(1), fAliasNumber(1), fNoGui(nogui)
129 {
130  // Initialize analyzer for a given TTree.
131  // (in fact we re-open the tree using a TChain)
132  // If 'nogui' option (default=kFALSE) is kTRUE we do not launch the graphical interface.
133 
134  init();
135  OpenGUI();
136  KVList fl;
137  fl.Add(new TNamed(t->GetCurrentFile()->GetName(), t->GetCurrentFile()->GetName()));
138  OpenChain(t->GetName(), t->GetTitle(), &fl);
139 }
140 
141 
142 
145 
147 {
148  // Destructor
152  if (gTreeAnalyzer == this) gTreeAnalyzer = 0x0;
153  fgAnalyzerList->Remove(this);
154 }
155 
156 
157 
158 
166 
168 {
169  // This method copies the current state of 'this' object into 'obj'
170  // You should add here any member variables, for example:
171  // (supposing a member variable KVTreeAnalyzer::fToto)
172  // CastedObj.fToto = fToto;
173  // or
174  // CastedObj.SetToto( GetToto() );
175 
176  TNamed::Copy(obj);
177  KVTreeAnalyzer& CastedObj = (KVTreeAnalyzer&)obj;
178  fSelections.Copy(CastedObj.fSelections);// list of TEntryList user selections
179  fHistolist.Copy(CastedObj.fHistolist);//list of generated histograms
180  CastedObj.fTreeName = fTreeName;//name of analyzed TTree
181  CastedObj.fTreeFileName = fTreeFileName;//name of file containing analyzed TTree
182  CastedObj.fHistoNumber = fHistoNumber; //used for automatic naming of histograms
183  CastedObj.fSelectionNumber = fSelectionNumber; //used for automatic naming of selections
184  CastedObj.fAliasNumber = fAliasNumber; //used for automatic naming of TTree aliases
185  fAliasList.Copy(CastedObj.fAliasList);//list of TTree aliases
187  CastedObj.fChain = fChain;
188  CastedObj.SetTree(fChain);
189 }
190 
191 
192 
210 
211 void KVTreeAnalyzer::GenerateHistoTitle(TString& title, const Char_t* expr, const Char_t* selection, const Char_t* weight)
212 {
213  // PRIVATE utility method
214  // Encodes the histogram title for the desired expression and an optional selection.
215  // The expression and selection should be valid TTreeFormula strings
216  // (i.e. they use TTree leaves and/or alias names)
217  // If there is already an active selection (TEntryList set on TTree)
218  // then the corresponding selection expression will also be included in the title.
219  // The format of the resulting title string is one of the following:
220  //
221  // "expr1[:expr2]"
222  // "expr1[:expr2] {selection}"
223  // "expr1[:expr2] {active selection}"
224  // "expr1[:expr2] {(active selection) && (selection)}"
225  //
226  // If histogram is weighted, the weight is added such as:
227  //
228  // "expr1:expr2 [weight] {active selection}"
229 
230 
231  TString _selection(selection);
232  TString _elist;
233  if (fChain->GetEntryList()) _elist = fChain->GetEntryList()->GetTitle();
234  if (strcmp(weight, "")) {
235  if (_selection != "" && _elist != "")
236  title.Form("%s [%s] {(%s) && (%s)}", expr, weight, _elist.Data(), selection);
237  else if (_selection != "")
238  title.Form("%s [%s] {%s}", expr, weight, selection);
239  else if (_elist != "")
240  title.Form("%s [%s] {%s}", expr, weight, _elist.Data());
241  else
242  title.Form("%s [%s]", expr, weight);
243  }
244  else {
245  if (_selection != "" && _elist != "")
246  title.Form("%s {(%s) && (%s)}", expr, _elist.Data(), selection);
247  else if (_selection != "")
248  title.Form("%s {%s}", expr, selection);
249  else if (_elist != "")
250  title.Form("%s {%s}", expr, _elist.Data());
251  else
252  title.Form("%s", expr);
253  }
254 }
255 
256 
257 
274 
275 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)
276 {
277  // Create and fill a new histogram with the desired expression (expr="expr1[:expr2]" etc.)
278  // with the given selection (selection="" if no selection required).
279  // Any currently active selection (TEntryList set on TTree) will also be applied.
280  // The new histogram is not drawn but added to the internal list of histograms
281  // (see method AddHisto).
282  //
283  // Histograms are automatically named 'h1', 'h2', etc. in order of creation.
284  // Histogram title is generated with method GenerateHistoTitle.
285  // Number of bins on X (and Y for a 2-D spectrum) are given. Axis limits are
286  // automatically adjusted to data unless given.
287  //
288  // For 2-D spectra the initial drawing option is set to "COL"
289  //
290  // If normalisation of spectra is required (fNormHisto = kTRUE) the histogram
291  // bin contents are divided by the integral (sum of weights).
292 
293  TString name;
294  name.Form("h%d", fHistoNumber);
295  TString drawexp(expr), histo, histotitle;
296  if (strcmp(weight, "")) GenerateHistoTitle(histotitle, expr, selection, weight);
297  else GenerateHistoTitle(histotitle, expr, selection);
298  if ((!nY) && (fUserBinning)) {
299  if (!DefineUserBinning1F()) return nullptr;
300  }
301 
302  TString Selection;
303  if (strcmp(weight, "")) {
304  if (strcmp(selection, "")) Selection.Form("(%s)&&(%s)", selection, weight);
305  else Selection = weight;
306  }
307  else
308  Selection = selection;
309  if (nY) histo.Form(">>%s(%d,%f,%f,%d,%f,%f)", name.Data(), nX, xmin, xmax, nY, ymin, ymax);
310  else histo.Form(">>%s(%d,%lf,%lf)", name.Data(), (fUserBinning ? fNxF : nX), (fUserBinning ? fXminF : xmin), (fUserBinning ? fXmaxF : xmax));
311 
312  /*if (!fProfileHisto)*/ drawexp += histo;
313  Long64_t drawResult;
314  if (fProfileHisto) drawResult = fTree->Draw(drawexp, Selection, "prof,goff");// fTree->Draw(Form("%s>>%s", drawexp.Data(), name.Data()), Selection, "prof,goff");
315  else drawResult = fTree->Draw(drawexp, Selection, "goff");
316  if (drawResult < 0) {
317  // Error with Draw: probably a bad expression
318  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
319  return nullptr;
320  }
321  TH1* h;
322  if (IsPROOFEnabled()) h = (TH1*)gProof->GetOutputList()->FindObject(name);
323  else h = (TH1*)gDirectory->Get(name);
324  h->SetTitle(histotitle);
325  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
326  h->SetDirectory(0);
327  AddHisto(h);
328  fHistoNumber++;
329  if (!fProfileHisto) {
330  if (fNormHisto || fNormHistoEvents) {
331  h->Sumw2();
332  if (fNormHisto) {
333  h->Scale(1. / h->Integral("width"));
334  }
335  else {
337  }
338  }
339  }
340  return h;
341 }
342 
343 
344 
351 
352 TH1* KVTreeAnalyzer::MakeIntHisto(const Char_t* expr, const Char_t* selection, Int_t Xmin, Int_t Xmax, const Char_t* weight)
353 {
354  // Like MakeHisto but only used for 1-D spectra of integer variables.
355  // The number of bins is Xmax-Xmin+1 and bins are defined over [x-0.5,x+0.5]
356  // for all values of x.
357  //
358  // Histograms are automatically named 'Ih1', 'Ih2', etc. in order of creation.
359 
360  TString name;
361  name.Form("Ih%d", fHistoNumber);
362  TString drawexp(expr), histo, histotitle;
363  if (strcmp(weight, "")) GenerateHistoTitle(histotitle, expr, selection, weight);
364  else GenerateHistoTitle(histotitle, expr, selection);
365 
366  if (fUserBinning) {
367  if (!DefineUserBinning1F()) return nullptr;
368  }
369 
370  histo.Form(">>%s(%d,%f,%f)", name.Data(), (fUserBinning ? fNxF : (Xmax - Xmin) + 1),
371  (fUserBinning ? fXminF : Xmin - 0.5), (fUserBinning ? fXmaxF : Xmax + 0.5));
372  drawexp += histo;
373  TString Selection;
374  if (strcmp(weight, "")) {
375  if (strcmp(selection, "")) Selection.Form("(%s)&&(%s)", selection, weight);
376  else Selection = weight;
377  }
378  else
379  Selection = selection;
380  Long64_t drawResult = fTree->Draw(drawexp, Selection, "goff");
381  if (drawResult < 0) {
382  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
383  return nullptr;
384  }
385  TH1* h;
386  if (IsPROOFEnabled()) h = (TH1*)gProof->GetOutputList()->FindObject(name);
387  else h = (TH1*)gDirectory->Get(name);
388  h->SetTitle(histotitle);
389  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
390  h->SetDirectory(0);
391 
392  AddHisto(h);
393  fHistoNumber++;
394  if (fNormHisto || fNormHistoEvents) {
395  h->Sumw2();
396  if (fNormHisto) {
397  h->Scale(1. / h->Integral("width"));
398  }
399  else {
401  }
402  }
403  return h;
404 }
405 
406 
407 
410 
412 {
413  // Return histogram with given name
414 
416  if (h->IsType("Histo")) return h->GetHisto();
417  return NULL;
418 }
419 
420 
421 
436 
438 {
439  // Generate a new user-selection (TEntryList) of events in the TTree
440  // according to the given selection expression (valid TTreeFormula expression
441  // using TTree leaf and/or alias names).
442  // The new selection is not applied immediately but added to the internal
443  // list of selections (see method AddSelection).
444  //
445  // If there is already an active selection (TEntryList set on TTree)
446  // this will generate the composite selection, {(active selection) && (selection)}.
447  // The selection's title will then be in the following format:
448  //
449  // "[(active selection) && ](selection)"
450  //
451  // TEntryList objects are automatically named 'el1', 'el2', etc. in order of creation.
452 
453  TObject* tmpObj = gROOT->FindObject(selection);
454  if (tmpObj) {
455  if (tmpObj->InheritsFrom("TCutG")) {
456  TCutG* cut = (TCutG*) tmpObj;
457  cut->SetTitle(cut->GetName());
458  AddCut(cut);
459  }
460  }
461 
462  TString name;
463  name.Form("el%d", fSelectionNumber);
464  TString drawexp(name.Data());
465  drawexp.Prepend(">>");
468  if (fChain->Draw(drawexp, selection, "entrylist") < 0) {
469  new TGMsgBox(gClient->GetRoot(), 0, "Warning", "Mistake in your new selection!", kMBIconExclamation, kMBClose);
470  return kFALSE;
471  }
473  TEntryList* el;
475  el = (TEntryList*)gProof->GetOutputList()->FindObject(name);
476  else
477  el = (TEntryList*)gDirectory->Get(name);
478  el->SetTitle(selection);//needed with PROOF
479  if (fChain->GetEntryList()) {
480  TString _elist = fChain->GetEntryList()->GetTitle();
481  TString title;
482  title.Form("(%s) && (%s)", _elist.Data(), selection);
483  el->SetTitle(title);
484  }
486  AddSelection(el);
488  return kTRUE;
489 }
490 
491 
492 
500 
502 {
503  // Method called when a selection is double-clicked in the GUI list.
504  // The required selection is passed as argument (address of TEntryList object)
505  // and becomes the currently active selection (TEntryList set on TTree).
506  // If the requested selection was already active, it is deactivated
507  // (remove TEntryList from TTree).
508  // The 'CURRENT SELECTION' message in the GUI status bar is updated.
509 
510  if (!obj->InheritsFrom("TEntryList")) return;
511  TEntryList* el = dynamic_cast<TEntryList*>(obj);
512  if (fChain->GetEntryList() == el) {
513  SetEntryList(nullptr);
514  G_selection_status->SetText("CURRENT SELECTION:", 0);
515  return;
516  }
517  SetEntryList(el);
518  G_selection_status->SetText(Form("CURRENT SELECTION: %s (%lld)", el->GetTitle(), el->GetN()), 0);
519 }
520 
521 
522 
525 
527 {
528  // Print the currently active selection (TEntryList set on TTree).
529 
530  TString tmp;
531  if (fChain->GetEntryList()) tmp = fChain->GetEntryList()->GetTitle();
532  else tmp = "";
533  if (tmp != "") cout << "CURRENT SELECTION : " << tmp << endl;
534 }
535 
536 
537 
541 
543 {
544  // Return number of entries (events) in the currently active selection,
545  // or the number of entries in the analysed TTree/TChain if no selection active
546 
547  if (fChain->GetEntryList()) return fChain->GetEntryList()->GetN();
548  return fChain->GetEntries();
549 }
550 
551 
552 
556 
558 {
559  // Fills the GUI list with the names of all leaves in the TTree
560  // and any friend TTrees and all aliases defined by the user
561 
562  TList stuff;
563  if (fTree) {
564  // clone list of leaves
565  fLeafList.Clear();
567  // when using a split object to fill the tree
568  // there is a redundant leaf/branch corresponding to the object itself
569  // more precisely there will be a TLeafElement in the list of leaves
570  // and a TBranchElement in the list of branches with the same name
571  //
572  // however the same applies to a simple unsplit object (such as using a TString to store
573  // strings). as the latter is probably far more common than the former (who creates trees
574  // with split objects in them these days???), I comment out the check which stopped such
575  // leaves appearing in the GUI (they are perfectly usable).
576  TIter next(clones);
577  TObject* o;
578  while ((o = next())) {
579 // if (o->InheritsFrom("TLeafElement")
580 // && fTree->GetListOfBranches()->FindObject(o->GetName())
581 // && fTree->GetListOfBranches()->FindObject(o->GetName())->InheritsFrom("TBranchElement"))
582 // continue;
583  fLeafList.Add(o);
584  }
585  delete clones;
586 
587  stuff.AddAll(&fLeafList);
588  stuff.AddAll(fTree->GetListOfAliases());
589  if (fTree->GetListOfFriends()) {
591  TFriendElement* fel;
592  while ((fel = (TFriendElement*)it())) {
593  stuff.AddAll(fel->GetTree()->GetListOfLeaves());
594  stuff.AddAll(fel->GetTree()->GetListOfAliases());
595  }
596  }
597  }
598  stuff.AddAll(&fAliasList);
599  G_leaflist->Display(&stuff);
600 }
601 
602 
603 
607 
609 {
610  // if analysis has been modified since last save,
611  // open an invite to ask if user wants to save with current default filename
612 
613  if (!fAnalysisModifiedSinceLastSave) return;
614 
615  if (fNoGui) {
616  // text-only interface
617  cout << "Analysis " << GetTitle() << " has been modified. Save before continuing? [y] : " << flush;
618  char reply;
619  cin.get(reply);
620  cout << endl;
621  if (reply == 'n' || reply == 'N') return;
622  cout << "Give name of file [" << fSaveAnalysisFileName << "] : " << flush;
623  char filename[256];
624  cin.get(filename, 256);
625  if (filename[0] != 0) fSaveAnalysisFileName = filename;
626  Save();
627  }
628  else {
629  Int_t ret_code;
631  new TGMsgBox(gClient->GetDefaultRoot(), (fMain_histolist ? fMain_histolist : gClient->GetDefaultRoot()), GetTitle(),
632  "Analysis has been modified. Save before continuing?", kMBIconStop,
633  kMBYes | kMBNo, &ret_code);
634  if (ret_code == kMBNo) return;
636  }
637 }
638 
639 
640 
642 
644 {
646  if (fMenuFile) {
647  if (x) {
650  }
651  else {
654  }
655  }
656 }
657 
658 
659 
668 
670 {
671  // Modify currently active selection (TEntryList)
672  // Instead of calling
673  // fChain->SetEntryList(l);
674  // call this method which works with or without PROOF.
675  // When using PROOF, fChain->SetEntryList(nullptr)
676  // does not work (bug in TProofChain), the last selection
677  // remains active. This problem is corrected here.
678 
680 
681  if (l == nullptr && IsPROOFEnabled()) {
684  }
685 }
686 
687 
688 
691 
693 {
694  // Launch the GUI (unless fNoGui=kTRUE in which case this does nothing)
695 
696  if (fNoGui) return;
697 
698  ULong_t red, cyan, green, yellow, magenta, gura, gurb, gurc, gurd, gure, gurf;
699  gClient->GetColorByName("#ff00ff", magenta);
700  gClient->GetColorByName("#ff0000", red);
701  gClient->GetColorByName("#00ff00", green);
702  gClient->GetColorByName("#00ffff", cyan);
703  gClient->GetColorByName("#ffff00", yellow);
704  gClient->GetColorByName("#cf14b2", gura);
705  gClient->GetColorByName("#cd93e6", gurb);
706  gClient->GetColorByName("#c1e91a", gurc);
707  gClient->GetColorByName("#d1a45b", gurd);
708  gClient->GetColorByName("#b54cfe", gure);
709  gClient->GetColorByName("#a325ef", gurf);
710 
711  /********* MAIN WINDOW **************/
712  //
713  fMain_histolist = new TGMainFrame(gClient->GetRoot(), 10, 10, kMainFrame | kVerticalFrame);
714  fMain_histolist->SetName("fMain_histolist");
715  if (!fTree)
716  fMain_histolist->SetWindowName("Tree Analyzer");
717  else
719  fMain_histolist->SetIconName("TreeAnalyzer");
720  fMain_histolist->SetIconPixmap("root_s.xpm");
721 
723 
724  UInt_t hWidth = 400, hHeight = 400;
725 
726  /* menus */
727  fMenuFile = new TGPopupMenu(gClient->GetRoot());
728  fMenuFile->AddEntry("New analysis", MH_OPEN_CHAIN);
729  fMenuFile->AddEntry("Open analysis", MH_OPEN_FILE);
730  fMenuFile->AddEntry("Add Friend...", MH_ADD_FRIEND);
732  fMenuFile->AddEntry("Save analysis", MH_SAVE);
733  fMenuFile->AddEntry("Save as...", MH_SAVE_FILE);
734  fMenuFile->AddEntry("Close", MH_CLOSE);
736  fMenuFile->AddEntry("Apply analysis...", MH_APPLY_ANALYSIS);
739  fMenuFile->AddEntry("Quit", MH_QUIT);
740  fMenuFile->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleHistoFileMenu(Int_t)");
741  fMenuSelections = new TGPopupMenu(gClient->GetRoot());
742  fSelCombMenu = new TGPopupMenu(gClient->GetRoot());
743  fSelCombMenu->AddEntry("AND (&&)", SEL_COMB_AND);
744  fSelCombMenu->AddEntry("OR (||)", SEL_COMB_OR);
745  fMenuSelections->AddPopup("Combine...", fSelCombMenu);
748  fMenuSelections->AddEntry("Update", SEL_UPDATE);
749  fMenuSelections->AddEntry("Delete", SEL_DELETE);
751  fSelGenerate = new TGPopupMenu(gClient->GetRoot());
752  fSelGenerate->AddEntry("Constant X-sections", SEL_GEN_CONST_XSEC);
753  fMenuSelections->AddPopup("Generate...", fSelGenerate);
754  fMenuSelections->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleSelectionsMenu(Int_t)");
755  fOptionMenu = new TGPopupMenu(gClient->GetRoot());
756  fOptionMenu->AddEntry("PROOF", OPT_PROOF);
757  fOptionMenu->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleOptionsMenu(Int_t)");
766 
767  // Horizontal frame to contain the VARIABLES list (left) and SELECTIONS list (right)
769 
770  /********* VARIABLES **************/
771  // Group frame for TTree variables/aliases
772  fMain_leaflist = new TGGroupFrame(hf, "VARIABLES");
773  UInt_t lWidth = 300, lHeight = 300;
774  /* leaf list */
775 
776  /* make selection */
777  TGHorizontalFrame* fHorizontalFrame = new TGHorizontalFrame(fMain_leaflist, lWidth, 36, kHorizontalFrame);
778  TGLabel* lab = new TGLabel(fHorizontalFrame, "Make alias : ");
779  fHorizontalFrame->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
780  G_alias_text = new TGTextEntry(fHorizontalFrame, new TGTextBuffer(50));
781  G_alias_text->SetMaxLength(4096);
784  G_alias_text->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateAlias()");
785  fHorizontalFrame->AddFrame(G_alias_text, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 2, 5, 2, 2));
786  fMain_leaflist->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
787 
788  G_leaflist = new KVListView(TNamed::Class(), fMain_leaflist, lWidth, lHeight);
790  G_leaflist->SetDataColumn(0, "Title");
793  G_leaflist->SetDoubleClickAction("KVTreeAnalyzer", this, "DrawLeaf(TObject*)");
794  G_leaflist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "LeafChanged()");
795 // G_leaflist->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "ShowVar()");
798  5, 5, 5, 5));
799 
800  //fMain_leaflist->MapSubwindows();
801 
803  //fMain_leaflist->MapWindow();
804  fMain_leaflist->Resize(lWidth, lHeight);
805  FillLeafList();
806  /*********end of VARIABLES **************/
807  hf->AddFrame(fMain_leaflist, new TGLayoutHints(kLHintsLeft, 5, 5, 5, 5));
808 
809  /******* SELECTIONS *********/
810  UInt_t sWidth = 600, sHeight = lHeight;
811  fMain_selectionlist = new TGGroupFrame(hf, "SELECTIONS");
812  /* current selection */
814  G_selection_status->SetText("CURRENT SELECTION:", 0);
816  /* make selection */
817  TGHorizontalFrame* fHorizontalFrame1614 = new TGHorizontalFrame(fMain_selectionlist, sWidth, 36, kHorizontalFrame);
818  lab = new TGLabel(fHorizontalFrame1614, "Make selection : ");
819  fHorizontalFrame1614->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
820  G_selection_text = new TGTextEntry(fHorizontalFrame1614, new TGTextBuffer(50));
824  G_selection_text->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateSelection()");
825  fHorizontalFrame1614->AddFrame(G_selection_text, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 2, 5, 2, 2));
826  fMain_selectionlist->AddFrame(fHorizontalFrame1614, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
827 
828  /* selection list */
829  G_selectionlist = new KVListView(TEntryList::Class(), fMain_selectionlist, sWidth, sHeight);
831  G_selectionlist->SetDataColumn(0, "Selection", "GetTitle");
832  G_selectionlist->SetDataColumn(1, "Reapply", "GetReapplyCut");
834  G_selectionlist->SetDataColumn(2, "Events", "GetN", kTextRight);
836  G_selectionlist->SetDoubleClickAction("KVTreeAnalyzer", this, "SetSelection(TObject*)");
837  G_selectionlist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "SelectionChanged()");
840  5, 5, 5, 5));
841 
842  //fMain_selectionlist->MapSubwindows();
843 
845  //fMain_selectionlist->MapWindow();
846  fMain_selectionlist->Resize(sWidth, sHeight);
848  /******end of SELECTIONS *********/
851 
852  /**** Histo creation group ********/
853  TGGroupFrame* histo_opts = new TGGroupFrame(fMain_histolist, "CREATE HISTO", kHorizontalFrame);
854  fHorizontalFrame = new TGHorizontalFrame(histo_opts, lWidth, 36, kHorizontalFrame);
855  G_leaf_draw = new TGPictureButton(fHorizontalFrame, "draw_t.xpm");
857  G_leaf_draw->Connect("Clicked()", "KVTreeAnalyzer", this, "DrawLeafExpr()");
858  fHorizontalFrame->AddFrame(G_leaf_draw, new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 2, 2, 2));
859  fLeafExpr = " ";
860  G_leaf_expr = new TGLabel(fHorizontalFrame, fLeafExpr.Data());
861  G_leaf_expr->Resize();
862  fHorizontalFrame->AddFrame(G_leaf_expr, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
863  histo_opts->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
864 
865  G_histo_prof = new TGCheckButton(histo_opts, "Profile");
866  G_histo_prof->SetToolTipText("Generate a profile histogram");
868  G_histo_prof->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetProfileHisto(Bool_t)");
869  histo_opts->AddFrame(G_histo_prof, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
870 
871  G_histo_norm = new TGCheckButton(histo_opts, "Normalize (integral)");
872  G_histo_norm->SetToolTipText("Generate normalized histogram with integral=1");
874  G_histo_norm->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNormHisto(Bool_t)");
875  histo_opts->AddFrame(G_histo_norm, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
876  G_histo_norm_events = new TGCheckButton(histo_opts, "Normalize (events)");
877  G_histo_norm_events->SetToolTipText("Generate histogram with integral divided by number of events");
879  G_histo_norm_events->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNormHistoEvents(Bool_t)");
880  histo_opts->AddFrame(G_histo_norm_events, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
881 
882  G_histo_weight = new TGCheckButton(histo_opts, "Weight");
883  G_histo_weight->SetToolTipText("User defined binning of the histogram");
885  G_histo_weight->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetUserWeight(Bool_t)");
886  histo_opts->AddFrame(G_histo_weight, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
887 
888  G_histo_bin = new TGCheckButton(histo_opts, "Bins");
889  G_histo_bin->SetToolTipText("User defined binning of the histogram");
891  G_histo_bin->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetUserBinning(Bool_t)");
892  histo_opts->AddFrame(G_histo_bin, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
893  fMain_histolist->AddFrame(histo_opts, new TGLayoutHints(kLHintsCenterX | kLHintsExpandX, 5, 5, 5, 5));
894 
895  /******** HISTOGRAMS *****************/
896  hWidth = lWidth + sWidth + 20;
897  TGGroupFrame* histo_group = new TGGroupFrame(fMain_histolist, "HISTOGRAMS");
898  /* ip scale */
899 // histo_opts = new TGGroupFrame(histo_group, "Impact parameter", kHorizontalFrame);
900 // G_make_ip_scale = new TGTextButton(histo_opts,"Make scale");
901 // G_make_ip_scale->SetTextJustify(36);
902 // G_make_ip_scale->SetMargins(0,0,0,0);
903 // G_make_ip_scale->SetWrapLength(-1);
904 // G_make_ip_scale->Resize();
905 // G_make_ip_scale->SetEnabled(kFALSE);
906 // G_make_ip_scale->Connect("Clicked()","KVTreeAnalyzer",this,"MakeIPScale()");
907 // G_make_ip_scale->ChangeBackground(green);
908 // histo_opts->AddFrame(G_make_ip_scale, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,10,2));
909 // lab = new TGLabel(histo_opts,"b <");
910 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,5,2,12,2));
911 // G_make_ip_selection = new TGTextEntry(histo_opts, new TGTextBuffer(5));
912 // G_make_ip_selection->SetMaxLength(10);
913 // G_make_ip_selection->SetAlignment(kTextLeft);
914 // G_make_ip_selection->Resize(50,G_make_ip_selection->GetDefaultHeight());
915 // G_make_ip_selection->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateIPSelection()");
916 // G_make_ip_selection->SetEnabled(kFALSE);
917 // histo_opts->AddFrame(G_make_ip_selection, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,10,2));
918 // G_ip_histo = new TGLabel(histo_opts,"-");
919 // histo_opts->AddFrame(G_ip_histo, new TGLayoutHints(kLHintsLeft|kLHintsTop,5,2,12,2));
920 // histo_group->AddFrame(histo_opts, new TGLayoutHints(kLHintsLeft|kLHintsExpandX,5,5,5,5));
921 // /* ip scale */
922 // histo_opts = new TGGroupFrame(histo_group, "Fits", kHorizontalFrame);
923 // lab = new TGLabel(histo_opts,"Gumbel : ");
924 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,5,2));
925 // G_fit1 = new TGTextButton(histo_opts, " 1 ");
926 // G_fit1->SetTextJustify(36);
927 // G_fit1->SetMargins(0,0,0,0);
928 // G_fit1->SetWrapLength(-1);
929 // G_fit1->Resize();
930 // G_fit1->SetEnabled(kFALSE);
931 // G_fit1->ChangeBackground(gura);
932 // G_fit1->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum1()");
933 // histo_opts->AddFrame(G_fit1, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
934 // G_fit2 = new TGTextButton(histo_opts, " 2 ");
935 // G_fit2->SetTextJustify(36);
936 // G_fit2->SetMargins(0,0,0,0);
937 // G_fit2->SetWrapLength(-1);
938 // G_fit2->Resize();
939 // G_fit2->SetEnabled(kFALSE);
940 // G_fit2->ChangeBackground(gurb);
941 // G_fit2->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum2()");
942 // histo_opts->AddFrame(G_fit2, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
943 // G_fit3 = new TGTextButton(histo_opts, " 3 ");
944 // G_fit3->SetTextJustify(36);
945 // G_fit3->SetMargins(0,0,0,0);
946 // G_fit3->SetWrapLength(-1);
947 // G_fit3->Resize();
948 // G_fit3->SetEnabled(kFALSE);
949 // G_fit3->ChangeBackground(gurc);
950 // G_fit3->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum3()");
951 // histo_opts->AddFrame(G_fit3, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
952 // lab = new TGLabel(histo_opts,"Gaus+Gum : ");
953 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,10,2,5,2));
954 // G_fitGG1 = new TGTextButton(histo_opts, " 1 ");
955 // G_fitGG1->SetTextJustify(36);
956 // G_fitGG1->SetMargins(0,0,0,0);
957 // G_fitGG1->SetWrapLength(-1);
958 // G_fitGG1->Resize();
959 // G_fitGG1->SetEnabled(kFALSE);
960 // G_fitGG1->ChangeBackground(gura);
961 // G_fitGG1->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum1()");
962 // histo_opts->AddFrame(G_fitGG1, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
963 // G_fitGG2 = new TGTextButton(histo_opts, " 2 ");
964 // G_fitGG2->SetTextJustify(36);
965 // G_fitGG2->SetMargins(0,0,0,0);
966 // G_fitGG2->SetWrapLength(-1);
967 // G_fitGG2->Resize();
968 // G_fitGG2->SetEnabled(kFALSE);
969 // G_fitGG2->ChangeBackground(gurb);
970 // G_fitGG2->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum2()");
971 // histo_opts->AddFrame(G_fitGG2, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
972 // G_fitGG3 = new TGTextButton(histo_opts, " 3 ");
973 // G_fitGG3->SetTextJustify(36);
974 // G_fitGG3->SetMargins(0,0,0,0);
975 // G_fitGG3->SetWrapLength(-1);
976 // G_fitGG3->Resize();
977 // G_fitGG3->SetEnabled(kFALSE);
978 // G_fitGG3->ChangeBackground(gurc);
979 // G_fitGG3->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum3()");
980 // histo_opts->AddFrame(G_fitGG3, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
981 // histo_group->AddFrame(histo_opts, new TGLayoutHints(kLHintsLeft|kLHintsExpandX,5,5,5,5));
982 
983  /* histo list */
984  //G_histolist = new KVListView(TNamed::Class(), histo_group, hWidth, hHeight);
985  //G_histolist->SetDataColumns(1);
986  //G_histolist->SetDataColumn(0, "Data", "GetTitle", kTextLeft);
987  G_histolist = new KVListView(KVHistogram::Class(), histo_group, hWidth, hHeight);
989  G_histolist->SetDataColumn(0, "Name", "", kTextLeft);
990  G_histolist->SetDataColumn(1, "VarX", "", kTextCenterX);
991  G_histolist->SetDataColumn(2, "VarY", "", kTextCenterX);
992  G_histolist->SetDataColumn(3, "VarZ", "", kTextCenterX);
993  G_histolist->SetDataColumn(4, "Selection", "", kTextCenterX);
994  G_histolist->SetDataColumn(5, "Weight", "", kTextCenterX);
995  G_histolist->SetDataColumn(6, "MeanX (RMS)", "GetMeanRMSX", kTextCenterX);
996  G_histolist->SetDataColumn(7, "MeanY (RMS)", "GetMeanRMSY", kTextCenterX);
999  G_histolist->SetUseObjLabelAsRealClass();//to have icons & context menus of TH* & TCutG classes, not KVHistogram
1000  G_histolist->SetDoubleClickAction("KVTreeAnalyzer", this, "DrawHisto(TObject*)");
1001  G_histolist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "HistoSelectionChanged()");
1004  5, 5, 5, 5));
1005 
1008  /* histo options */
1009  histo_opts = new TGGroupFrame(fMain_histolist, "OPTIONS", kHorizontalFrame);
1010 
1011  //fHorizontalFrame = new TGHorizontalFrame(histo_opts,150,36,kHorizontalFrame);
1012  G_histo_del = new TGPictureButton(histo_opts, "sm_delete.xpm");
1014  G_histo_del->Connect("Clicked()", "KVTreeAnalyzer", this, "DeleteSelectedHisto()");
1015  //fHorizontalFrame->AddFrame(G_histo_del, new TGLayoutHints(kLHintsTop|kLHintsLeft,2,2,2,2));
1016  //lab = new TGLabel(fHorizontalFrame, "DELETE");
1017  //lab->Resize();
1018  //fHorizontalFrame->AddFrame(lab, new TGLayoutHints(kLHintsTop|kLHintsLeft|kLHintsCenterY,2,2,2,2));
1019  histo_opts->AddFrame(G_histo_del, new TGLayoutHints(kLHintsLeft, 5, 2, 8, 2));
1020 
1021  G_histo_add = new TGPictureButton(histo_opts, "bld_plus.png");
1023  G_histo_add->Connect("Clicked()", "KVTreeAnalyzer", this, "AddSelectedHistos()");
1025  histo_opts->AddFrame(G_histo_add, new TGLayoutHints(kLHintsLeft, 15, 25, 8, 2));
1026 
1027  G_histo_draw_option = new TGComboBox(histo_opts);
1028  TString draw_options[] = {
1029  "",
1030  "COL",
1031  "COLZ",
1032  "BOX",
1033  "CONT",
1034  "SURF",
1035  "LEGO",
1036  "ARR",
1037  "TEXT",
1038  "CONT1",
1039  "CONT2",
1040  "CONT3",
1041  "CONT4",
1042  "SURF1",
1043  "SURF2",
1044  "SURF3",
1045  "SURF4",
1046  "LEGO1",
1047  "LEGO2",
1048  "LEGO3",
1049  "LEGO4",
1050  "BOX1",
1051  " "
1052  };
1053  int dop = 0;
1054  while (draw_options[dop] != " ") {
1055  G_histo_draw_option->AddEntry(draw_options[dop], dop);
1056  ++dop;
1057  }
1058  G_histo_draw_option->Resize(100, 20);
1059  histo_opts->AddFrame(G_histo_draw_option, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1060  G_histo_draw_option->Connect("Selected(const char*)", "KVTreeAnalyzer", this, "SetDrawOption(Option_t*)");
1061 
1062  G_histo_new_can = new TGCheckButton(histo_opts, "New canvas");
1063  G_histo_new_can->SetToolTipText("Draw in a new canvas");
1064  G_histo_new_can->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNewCanvas(Bool_t)");
1066  histo_opts->AddFrame(G_histo_new_can, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1067  G_histo_same = new TGCheckButton(histo_opts, "Same");
1068  G_histo_same->SetToolTipText("Draw in same pad");
1069  G_histo_same->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetDrawSame(Bool_t)");
1070  histo_opts->AddFrame(G_histo_same, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1071  G_histo_app_sel = new TGCheckButton(histo_opts, "Apply selection");
1072  G_histo_app_sel->SetToolTipText("Apply current selection to generate new histo");
1073  G_histo_app_sel->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetApplySelection(Bool_t)");
1074  histo_opts->AddFrame(G_histo_app_sel, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1075  G_histo_log = new TGCheckButton(histo_opts, "Log scale");
1076  G_histo_log->SetToolTipText("Use log scale in Y (1D) or Z (2D)");
1078  G_histo_log->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetDrawLog(Bool_t)");
1079  histo_opts->AddFrame(G_histo_log, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1080  G_histo_stats = new TGCheckButton(histo_opts, "Stats");
1081  G_histo_stats->SetToolTipText("Display histogram statistics box");
1083  G_histo_stats->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetStatsHisto(Bool_t)");
1084  histo_opts->AddFrame(G_histo_stats, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1085  G_histo_autosave = new TGCheckButton(histo_opts, "AutoSave");
1086  G_histo_autosave->SetToolTipText("Automatically generate histo image files");
1088  G_histo_autosave->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetAutoSaveHisto(Bool_t)");
1089  histo_opts->AddFrame(G_histo_autosave, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1090  fMain_histolist->AddFrame(histo_opts, new TGLayoutHints(kLHintsCenterX, 5, 5, 5, 5));
1091 
1093 
1096 
1097  hHeight = hHeight + lHeight + 50;
1098 
1099  fMain_histolist->Resize(hWidth, hHeight);
1100  /********* end of HISTOGRAMS *************/
1101 
1102  fMain_histolist->Connect("CloseWindow()", "KVTreeAnalyzer", this, "GUIClosed()");
1103 }
1104 
1105 
1106 
1109 
1111 {
1112  // Called when graphical window is closed
1113 
1116  TTimer::SingleShot(150, "KVTreeAnalyzer", this, "DeleteThis()");
1117 }
1118 
1119 
1120 
1124 
1126 {
1127  // Adds histogram to internal list of user histograms
1128  // and updates GUI display
1129 
1130  SetAnalysisModifiedSinceLastSave(kTRUE);//new histogram needs saving
1131  fHistolist.Add(new KVHistogram(h));
1133 }
1134 
1135 
1136 
1140 
1142 {
1143  // Adds selection to internal list of user histograms
1144  // and updates GUI display
1145 
1146  SetAnalysisModifiedSinceLastSave(kTRUE);//new selection needs saving
1147  fSelections.Add(e);
1149 }
1150 
1151 
1152 
1156 
1158 {
1159  // Adds histogram to internal list of user histograms
1160  // and updates GUI display
1161 
1162  SetAnalysisModifiedSinceLastSave(kTRUE);//new selection needs saving
1163  fHistolist.Add(new KVHistogram(c));
1165 }
1166 
1167 
1168 
1175 
1177 {
1178  // the Tree file name is used as the basis for the default analysis backup filename.
1179  // for a TChain there may be many files with a common root.
1180  // we look for this common root and replace any "wildcard" characters with "X"
1181  // i.e. for files "run_001.root", "run_002.root", ..., "run_999.root" we
1182  // will use "Analysis_run_XXX.root" as default name
1183 
1184  KVString p;
1185  if (t->InheritsFrom("TChain")) {
1186  KVString p;
1187  p.FindCommonTitleCharacters(((TChain*)t)->GetListOfFiles(), 'X');
1188  fTreeFileName = p.Data();
1189  }
1190  else
1194 }
1195 
1196 
1197 
1200 
1202 {
1203  // Connects a TChain for analysis
1204 
1205  fTree = t;
1206  if (IsPROOFEnabled()) fChain->SetProof();
1207  fTreeName = t->GetName();
1208  SetTreeFileName(t);
1210 }
1211 
1212 
1213 
1216 
1218 {
1219  // Backwards compatibility: to read old analysis files
1220 
1221  TFile* f;
1223  // absolute path to TTree file doesn't work, try in working directory
1224  TString tmp;
1226  f = TFile::Open(tmp);
1227  }
1229  // if fRelativePathToAnalysisFile!="." and if fTreeFileName is not an absolute path,
1230  // we guess the Tree file is in the same directory as the analysis file
1231  TString tmp;
1233  f = TFile::Open(tmp);
1234  }
1235  else
1237  if (!f || f->IsZombie()) {
1238  Error("ReconnectTree", "Failed to reconnect Tree file %s", fTreeFileName.Data());
1239  fTree = 0;
1240  fChain = 0;
1241  SafeDelete(f);
1242  return;
1243  }
1244  fTreeFileName = f->GetName();
1245  TTree* t = (TTree*)f->Get(fTreeName);
1246  TString treeTitle = t->GetTitle();
1247  delete f;
1248  fChain = new TChain(fTreeName, treeTitle);
1250  fChain->SetDirectory(0);
1251  SetTree(fChain);
1252 }
1253 
1254 
1255 
1263 
1265 {
1266  // STATIC method to open a previously saved analysis session.
1267  //
1268  // Use:
1269  // root[0] KVTreeAnalyzer* TA = KVTreeAnalyzer::OpenFile("my_analysis.root")
1270  //
1271  // If option nogui=kTRUE the GUI will not be launched
1272 
1273  TFile* f = TFile::Open(filename);
1274  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1275  delete f;
1276  anal->fNoGui = nogui;
1277  anal->SetRelativePathToAnalysisFile(gSystem->DirName(filename));
1278  anal->OpenGUI();
1279  return anal;
1280 }
1281 
1282 
1283 
1286 
1288 {
1289  // open a previously saved analysis session.
1290 
1291  TFile* f = TFile::Open(filename);
1292  ReadFromFile(f);
1293 }
1294 
1295 
1296 
1299 
1301 {
1302  // open a previously saved analysis session.
1303 
1304  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1305  delete f;
1306  anal->Copy(*this);
1307  delete anal;
1308  gTreeAnalyzer = this;
1311  FillLeafList();
1312 }
1313 
1314 
1315 
1317 
1319 {
1320  TString name = Form("%s:%s", cut->GetVarY(), cut->GetVarX());
1321  KVList padList(kFALSE);
1322  Bool_t testHisto = kFALSE;
1323 
1324  if (!gPad) testHisto = kTRUE;
1325 
1326  if (!testHisto) {
1327  testHisto = kTRUE;
1328  padList.AddAll(((TPad*)gPad)->GetListOfPrimitives());
1329  TIter next(&padList);
1330  TObject* o = 0;
1331  while ((o = next())) {
1332  if (o->InheritsFrom("TH1")) {
1333  TH1* hh = (TH1*) o;
1334  TString hName = hh->GetTitle();
1335  if (hName.Contains(name.Data())) {
1336  cut->Draw("PL");
1337  gPad->Update();
1338  testHisto = kFALSE;
1339  }
1340  }
1341  }
1342  }
1343 
1344  if (testHisto) {
1345  TIter next(&fHistolist);
1346  KVHistogram* hhh;
1347  TH1* hh = 0;
1348  while ((hhh = (KVHistogram*)next())) {
1349  if ((hh = hhh->GetHisto())) {
1350  TString hName = hh->GetTitle();
1351  if (hName.Contains(name.Data())) {
1352  DrawHisto(hh, kFALSE);
1353  cut->Draw("PL");
1354  gPad->Update();
1355  break;
1356  }
1357  }
1358  }
1359  }
1360  // else cut->Draw("PAL");
1361 
1362 
1363 // TIter next(fHistoList);
1364 // TH1* tmpHist = 0;
1365 // while((tmpHisto = (TH1*)next()))
1366 // {
1367 //
1368 // }
1369 
1370  return;
1371 }
1372 
1373 
1374 
1376 
1377 void KVTreeAnalyzer::DrawHistogram(TH1* histo, Bool_t same, Bool_t logscale)
1378 {
1379  if (fDrawSame || same) {
1380  // if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1381  // plot with a different colour and add it to the automatically generated
1382  // legend which is also displayed in the plot
1384  histo->SetLineWidth(2);
1386  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1387  if (histo->InheritsFrom("TH2")) {
1388  TString hopt = histo->GetOption();
1389  if (hopt != "") hopt.Form("%s,same", histo->GetOption());
1390  else hopt = "same";
1391  histo->Draw(hopt);
1392  }
1393  else
1394  histo->Draw("same");
1395  TObject* legend = gPad->GetListOfPrimitives()->FindObject("TPave");
1396  if (legend) {
1397  gPad->GetListOfPrimitives()->Remove(legend);
1398  delete legend;
1399  }
1400  ((TPad*) gPad)->BuildLegend();
1401  if (histo->InheritsFrom("TH2")) {
1402  gPad->SetLogy(kFALSE);
1403  gPad->SetLogz(fDrawLog || logscale);
1404  }
1405  else {
1406  gPad->SetLogy(fDrawLog || logscale);
1407  // adjust y-scale to new histogram if needed
1408  // find first histogram
1409  TIter nxt(gPad->GetListOfPrimitives());
1410  TObject* h;
1411  while ((h = nxt())) {
1412  if (h->InheritsFrom("TH1")) {
1413  TH1* hh = (TH1*)h;
1414  if (histo->GetMaximum() > hh->GetMaximum()) hh->SetMaximum(histo->GetMaximum() + 1);
1415  break;
1416  }
1417  }
1418  }
1419  gPad->Modified();
1420  gPad->Update();
1421  if (fAutoSaveHisto) AutoSaveHisto(histo);
1422  }
1423  else {
1424  // if 'new canvas' is active the histogram is displayed in a new KVCanvas
1425  // create a new canvas also if none exists
1426  if (fNewCanvas || !gPad) {
1427  KVCanvas* c = new KVCanvas;
1428  c->SetTitle(histo->GetTitle());
1429  c->SetWindowSize(700, 700);
1430  }
1431  else if (gPad) { // update title of existing canvas
1432  gPad->GetCanvas()->SetTitle(histo->GetTitle());
1433  }
1434  histo->SetLineColor(my_color_array[0]);
1435  histo->SetLineWidth(2);
1436  if (histo->InheritsFrom("TH2")) {
1437  gPad->SetLogy(kFALSE);
1438  gPad->SetLogz(fDrawLog || logscale);
1439  }
1440  else {
1441  histo->SetMaximum(-1111);//in case maximum was changed to accomodate superimposition
1442  gPad->SetLogy(fDrawLog || logscale);
1443  }
1444  histo->SetStats(fStatsHisto);//show/hide stat box according to check-box
1445  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1446  histo->Draw();
1447  gPad->Modified();
1448  gPad->Update();
1449  if (fAutoSaveHisto) AutoSaveHisto(histo);
1450  }
1451 }
1452 
1453 
1454 
1475 
1477 {
1478  // Method called when a user double-clicks a histogram in the GUI list.
1479  //
1480  // * if histogram is already displayed in active pad and if the pad also
1481  // contains a graphical contour (TCutG) object, we use the contour to define
1482  // a new data selection (TEntryList) which is added to the internal list.
1483  //
1484  // * if 'reapply selection' is activated and if the current active selection
1485  // is not the same as that used to generate the histogram, we generate a new
1486  // histogram displaying the same variables but with the current selection.
1487  //
1488  // * if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1489  // plot with a different colour and add it to the automatically generated
1490  // legend which is also displayed in the plot
1491  //
1492  // * if 'new canvas' is active the histogram is displayed in a new KVCanvas
1493  //
1494  // * in all cases when a histogram is displayed the log/linear scale of
1495  // Y (1-D) or Z (2-D) axis is automatically adjusted according to the 'log scale'
1496  // check box
1497 
1498  KVHistogram* kvhisto = 0;
1499  TCutG* cut = 0;
1500  TH1* histo = 0;
1501  if (obj->InheritsFrom("KVHistogram")) {
1502  kvhisto = dynamic_cast<KVHistogram*>(obj);
1503  if (kvhisto->IsType("Cut")) cut = kvhisto->GetCut();
1504  else if (kvhisto->IsType("Histo")) histo = kvhisto->GetHisto();
1505  }
1506  else if (obj->InheritsFrom("TCutG")) {
1507  cut = dynamic_cast<TCutG*>(obj);
1508  }
1509  else if (obj->InheritsFrom("TH1")) {
1510  histo = dynamic_cast<TH1*>(obj);
1511  }
1512 
1513  if (cut) {
1514  DrawCut(cut);
1515  return;
1516  }
1517  if (!histo) return;
1518 
1519  // if histogram is already displayed in active pad and if the pad also
1520  // contains a graphical contour (TCutG) object, we use the contour to define
1521  // a new data selection (TEntryList) which is added to the internal list.
1522  if (gPad && gPad->GetListOfPrimitives()->FindObject(histo) && (gen)) {
1523  TIter next(gPad->GetListOfPrimitives());
1524  TObject* o;
1525  while ((o = next())) {
1526  if ((o->IsA() == TCutG::Class()) && !(fHistolist.FindObjectWithNameAndType(o->GetName(), "Cut"))) {
1527  MakeSelection(o->GetName());
1528  return;
1529  }
1530  }
1531  }
1532 
1533  KVString exp, sel, weight;
1534  if (kvhisto) {
1535  exp = kvhisto->GetExpression();
1536  sel = kvhisto->GetSelection();
1537  weight = kvhisto->GetWeight();
1538  }
1539  else {
1540  KVHistogram::ParseHistoTitle(histo->GetTitle(), exp, sel, weight);
1541  }
1542 
1543  if (weight == "1") weight = "";
1544 
1545  // if 'reapply selection' is activated and if the current active selection
1546  // is not the same as that used to generate the histogram, we generate a new
1547  // histogram displaying the same variables but with the current selection.
1548  if (!IsCurrentSelection(sel) && fApplySelection) {
1549  histo = RemakeHisto(histo, exp, weight);
1550  if (!histo) return;
1551  }
1552 
1553  DrawHistogram(histo);
1554 }
1555 
1556 
1557 
1561 
1563 {
1564  // Returns kTRUE if "sel" corresponds to current active selection
1565  // (i.e. entry list of TTree)
1566 
1567  if (!fTree) return kTRUE;
1568  TString test_sel(sel);
1569  TString tree_sel;
1570  TEntryList* el;
1571  if ((el = fChain->GetEntryList())) tree_sel = el->GetTitle();
1572  return (test_sel == tree_sel);
1573 }
1574 
1575 
1576 
1581 
1582 TH1* KVTreeAnalyzer::RemakeHisto(TH1* h, const Char_t* expr, const Char_t* weight)
1583 {
1584  // Remake an existing histogram of data 'expr' using the current active selection
1585  // If such a histogram already exists, we just return its address.
1586  // We must have the same binning in the new as in the original histogram.
1587 
1588  TString htit;
1589  GenerateHistoTitle(htit, expr, "", weight);
1590  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
1591  TH1* histo = 0;
1592  if (kvhisto) histo = kvhisto->GetHisto();
1593  if (histo && (histo->IsA() == h->IsA())) return histo;
1594  Int_t nx, ny = 0;
1595  TString hname(h->GetName());
1596  if (hname.BeginsWith("I")) {
1597  Int_t xmin = h->GetXaxis()->GetXmin() + 0.5;
1598  Int_t xmax = h->GetXaxis()->GetXmax() - 0.5;
1599  //cout << "Remake histo with xmin = " << xmin << " xmax = " << xmax << endl;
1600  h = MakeIntHisto(expr, "", xmin, xmax, weight);
1601  return h;
1602  }
1603  nx = h->GetNbinsX();
1604  auto xmin = h->GetXaxis()->GetXmin();
1605  auto xmax = h->GetXaxis()->GetXmin();
1606  double ymin(-1), ymax(-1);
1607  if (h->InheritsFrom("TH2")) {
1608  ny = h->GetNbinsY();
1609  ymin = h->GetYaxis()->GetXmin();
1610  ymax = h->GetYaxis()->GetXmin();
1611  }
1612  //cout << "Remake histo with nx = " << nx << " ny = " << ny << endl;
1613  if (h->InheritsFrom("TProfile")) {
1614  // make a new profile histogram
1615  Bool_t oldProfileState = fProfileHisto;
1616  fProfileHisto = kTRUE;
1617  h = MakeHisto(expr, "", nx, ny, weight, xmin, xmax);
1618  fProfileHisto = oldProfileState;
1619  }
1620  else
1621  h = MakeHisto(expr, "", nx, ny, weight, xmin, xmax, ymin, ymax);
1622  return h;
1623 }
1624 
1625 
1626 
1631 
1633 {
1634  // Method called when user hits 'return' in selection GUI text-box
1635  // Takes expression from text-box and generates the corresponding
1636  // selection which is added to the GUI list of selections.
1637 
1638  TString selection = G_selection_text->GetText();
1639  if (selection.IsNull()) return;
1640  if (MakeSelection(selection)) G_selection_text->Clear();
1641 }
1642 
1643 
1644 
1648 
1650 {
1651  // Method called when user hits 'return' in TTree leaf/alias GUI text-box
1652  // Generates a new alias using the expression in the text-box.
1653 
1654  TString alias = G_alias_text->GetText();
1655  TString name;
1656  name.Form("a%d", fAliasNumber++);
1657  SetAlias(name, alias);
1658  FillLeafList();
1659  G_alias_text->Clear();
1660 }
1661 
1662 
1663 
1668 
1670 {
1671  // Method called when user hits 'combine selections' button in selections GUI.
1672  // Generates new selection which is the intersection (logical AND) of
1673  // the currently selected selections.
1674 
1675  if (fSelectedSelections) {
1676  TEntryList* save_elist = fChain->GetEntryList();
1678  TString newselect;
1679  int nsel = fSelectedSelections->GetEntries();
1680  for (int i = 1; i < nsel; i++) {
1681  TString tmp;
1683  tmp.Form("(%s)", el->GetTitle());
1684  if (i > 1) newselect += " && ";
1685  newselect += tmp.Data();
1686  }
1687  MakeSelection(newselect);
1688  SetEntryList(save_elist);
1689  }
1690 }
1691 
1692 
1693 
1698 
1700 {
1701  // Method called when user hits 'combine selections' button in selections GUI.
1702  // Generates new selection which is the intersection (logical AND) of
1703  // the currently selected selections.
1704 
1705  if (fSelectedSelections) {
1706  TEntryList* save_elist = fChain->GetEntryList();
1707  SetEntryList(nullptr);
1708  TString newselect;
1709  int nsel = fSelectedSelections->GetEntries();
1710  for (int i = 0; i < nsel; i++) {
1711  TString tmp;
1713  tmp.Form("(%s)", el->GetTitle());
1714  if (i > 0) newselect += " || ";
1715  newselect += tmp.Data();
1716  }
1717  MakeSelection(newselect);
1718  SetEntryList(save_elist);
1719  }
1720 }
1721 
1722 
1723 
1726 
1728 {
1729  // Delete the currently selected selection(s)
1730 
1731  if (fSelectedSelections) {
1732  int nsel = fSelectedSelections->GetEntries();
1733  if (nsel < 1) return;
1734  for (int i = 0; i < nsel; i++) {
1736  if (!el) continue;
1737  fSelections.Remove(el);
1738  // if current selection, disable
1739  if (fChain->GetEntryList() == el) fChain->SetEntryList(nullptr);
1740  delete el;
1742  }
1744  }
1746 
1747 }
1748 
1749 
1750 
1753 
1755 {
1756  // Method called whenever the selected selection in the GUI list changes
1757 
1760  Bool_t resetSel = kTRUE;
1764 
1766  }
1767  else if (fSelectedSelections->GetEntries() == 1) {
1770  if (tmp->GetSize() != 0 || !strcmp("", G_selection_text->GetText())) {
1771  G_selection_text->SetText(((TNamed*)fSelectedSelections->At(0))->GetTitle());
1772  resetSel = kFALSE;
1773  }
1774  delete tmp;
1775  }
1776  else if (fSelectedSelections->GetEntries() > 1) {
1780  }
1781 
1782  if (resetSel) {
1784  if (tmp->GetSize() != 0) G_selection_text->SetText("");
1785  delete tmp;
1786  }
1787 }
1788 
1789 
1790 
1794 
1796 {
1797  // Method called whenever the leaf/alias selection in the TTree GUI list changes.
1798  // Updates the names of the leaves/aliases displayed next to the 'draw' button.
1799 
1801  fLeafExpr = "-";
1802  fXLeaf = fYLeaf = 0;
1803 // Bool_t resetSel = kTRUE;
1805  Int_t nleaf = fSelectedLeaves->GetEntries();
1806  if (nleaf) {
1807  if (nleaf == 1) {
1809  fLeafExpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1811 
1812  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1813  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1814  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0 || !strcmp("", G_alias_text->GetText())) {
1815  G_alias_text->SetText(fLeafExpr.Data()); //resetSel = kFALSE;
1816  }
1817  else if (strcmp(fLeafExpr.Data(), G_leaf_expr->GetTitle())) {
1818  TString tmps = G_alias_text->GetText();
1819  Int_t pos = G_alias_text->MaxMark();
1820  if (pos >= tmps.Sizeof()) pos = G_alias_text->MinMark();
1821  if (pos >= tmps.Sizeof()) pos = tmps.Sizeof() - 1;
1822  tmps.Insert(pos, fLeafExpr.Data());
1823  G_alias_text->SetText(tmps.Data());
1825  }
1826  delete tmp;
1827  delete tmp1;
1828 
1829  }
1830  else if (nleaf == 2) {
1831  fXLeaf = (TNamed*)fSelectedLeaves->At(1);
1833  TString X, Y;
1834  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1835  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1836  fLeafExpr.Form("%s:%s", Y.Data(), X.Data());
1838  G_alias_text->SetText("");
1839  }
1840  else if (nleaf == 3) {
1841  fXLeaf = (TNamed*)fSelectedLeaves->At(2);
1842  fYLeaf = (TNamed*)fSelectedLeaves->At(1);
1843  fZLeaf = (TNamed*)fSelectedLeaves->At(0);
1844  TString X, Y, Z;
1845  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1846  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1847  Z = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
1848  fLeafExpr.Form("%s:%s:%s", Z.Data(), Y.Data(), X.Data());
1850  G_alias_text->SetText("");
1851  }
1852  else {
1853  fLeafExpr = "-";
1854  G_alias_text->SetText("");
1855  }
1856  }
1857  else {
1858  fLeafExpr = "-";
1859 // G_alias_text->SetText("");
1860  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1861  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1862  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0) {
1863  G_alias_text->SetText(""); //resetSel = kFALSE;
1864  }
1865  delete tmp;
1866  delete tmp1;
1867  }
1868 
1870  G_leaf_expr->Resize();
1871 }
1872 
1873 
1874 
1876 
1878 {
1879  KVNameValueList p{{"Xbins", fNx}, {"Xmin", fXmin}, {"Xmax", fXmax},
1880  {"Ybins", fNy}, {"Ymin", fYmin}, {"Ymax", fYmax}};
1881  bool cancel{false};
1882  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1883  g->DisplayDialog();
1884  if (cancel) return false;
1885  fNx = p.GetIntValue("Xbins");
1886  fXmin = p.GetDoubleValue("Xmin");
1887  fXmax = p.GetDoubleValue("Xmax");
1888  fNy = p.GetIntValue("Ybins");
1889  fYmin = p.GetDoubleValue("Ymin");
1890  fYmax = p.GetDoubleValue("Ymax");
1891  return true;
1892 }
1893 
1894 
1895 
1897 
1899 {
1900  KVNameValueList p{{"bins", fNxF}, {"min", fXminF}, {"max", fXmaxF}};
1901  bool cancel{false};
1902  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1903  g->DisplayDialog();
1904  if (cancel) return false;
1905  fNxF = p.GetIntValue("bins");
1906  fXminF = p.GetDoubleValue("min");
1907  fXmaxF = p.GetDoubleValue("max");
1908  return true;
1909 }
1910 
1911 
1912 
1914 
1916 {
1917  KVNameValueList p{{"Xbins", fNxD}, {"Ybins", fNyD}, {"ordered?", fOrderedDalitz}};
1918  bool cancel{false};
1919  auto g = new KVNameValueListGUI(GetMainWindow(), &p, &cancel);
1920  g->DisplayDialog();
1921  if (cancel) return false;
1922  fNxD = p.GetIntValue("Xbins");
1923  fNyD = p.GetIntValue("Ybins");
1924  fOrderedDalitz = p.GetBoolValue("ordered?");
1925  return true;
1926 }
1927 
1928 
1929 
1931 
1933 {
1934  TLeaf* lf = (TLeaf*)fChain->GetListOfLeaves()->FindObject(l->GetName());
1935  return lf->GetTypeName();
1936 }
1937 
1938 
1939 
1943 
1945 {
1946  // Method called when user hits 'draw' button in TTree GUI.
1947  // If only one leaf/alias is selected, this actually calls DrawLeaf.
1948 
1949  if (fLeafExpr == "-")return;
1950  Bool_t threeDexp = fSelectedLeaves->GetEntries() == 3;
1951  if (threeDexp && !fProfileHisto) {
1952  DrawAsDalitz();
1953  return;
1954  }
1955  if (fSelectedLeaves->GetEntries() == 1) {
1957  return;
1958  }
1959 
1960  if (fUserWeight) {
1961  if (!DefineWeight()) return;
1962  }
1963 
1964  int nx = 500, ny = 500;
1965  double xmin, xmax, ymin, ymax;
1966  xmin = xmax = ymin = ymax = 0;
1967  TString Xexpr, Yexpr, Zexpr;
1968  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1969  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1970  if (threeDexp) Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
1971  if (fXLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fXLeaf), "Char_t")) {
1972  TString tmp = Xexpr;
1973  Xexpr.Form("int(%s)", tmp.Data());
1974  }
1975  if (fYLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fYLeaf), "Char_t")) {
1976  TString tmp = Yexpr;
1977  Yexpr.Form("int(%s)", tmp.Data());
1978  }
1979 
1980  if (threeDexp) fLeafExpr.Form("%s:%s:%s", Zexpr.Data(), Yexpr.Data(), Xexpr.Data());
1981  else fLeafExpr.Form("%s:%s", Yexpr.Data(), Xexpr.Data());
1982  TString name;
1983  name.Form("h%d", fHistoNumber);
1984  TString drawexp(fLeafExpr), histo, histotitle;
1985  if (fUserWeight) GenerateHistoTitle(histotitle, fLeafExpr, "", fWeight);
1986  else GenerateHistoTitle(histotitle, fLeafExpr, "");
1987 
1988  // Check histo doesn't already exist
1989  // Look for list of histograms with given title as we don't distinguish TH2 from TProfile
1990  unique_ptr<KVSeqCollection> same_histo(fHistolist.GetSubListWithMethod(histotitle, "GetHistoTitle"));
1991  TIter nxtSame(same_histo.get());
1992  KVHistogram* kvhisto;
1993  while ((kvhisto = (KVHistogram*)nxtSame())) {
1994  if ((fProfileHisto && kvhisto->IsProfile()) || (!fProfileHisto && kvhisto->IsTH2())) {
1995  DrawHisto(kvhisto->GetHisto());
1996  return;
1997  }
1998  }
1999 
2000  if (fUserBinning) {
2001  if (!DefineUserBinning()) return;
2002  }
2003 
2004  xmin = fTree->GetMinimum(Xexpr);
2005  xmax = fTree->GetMaximum(Xexpr);
2006  if (fXLeaf->InheritsFrom("TLeaf") &&
2007  (!strcmp(get_leaf_type_name(fXLeaf), "Int_t") || !strcmp(get_leaf_type_name(fXLeaf), "Short_t") || !strcmp(get_leaf_type_name(fXLeaf), "Char_t"))
2008  ) {
2009  xmin -= 0.5;
2010  xmax += 0.5;
2011  nx = xmax - xmin;
2012  }
2013  ymin = fTree->GetMinimum(Yexpr);
2014  ymax = fTree->GetMaximum(Yexpr);
2015  if (fYLeaf->InheritsFrom("TLeaf") &&
2016  (!strcmp(get_leaf_type_name(fYLeaf), "Int_t") || !strcmp(get_leaf_type_name(fYLeaf), "Short_t") || !strcmp(get_leaf_type_name(fYLeaf), "Char_t"))
2017  ) {
2018  ymin -= 0.5;
2019  ymax += 0.5;
2020  ny = ymax - ymin;
2021  }
2022  if (fUserBinning) {
2023  nx = fNx;
2024  ny = fNy;
2025  xmin = fXmin;
2026  xmax = fXmax;
2027  ymin = fYmin;
2028  ymax = fYmax;
2029  }
2030 
2031  if (!fProfileHisto) histo.Form(">>%s(%d,%f,%f,%d,%f,%f)", name.Data(), nx, xmin, xmax, ny, ymin, ymax);
2032  else {
2033  if (fUserBinning) histo.Form(">>%s(%d,%f,%f)", name.Data(), nx, xmin, xmax);
2034  else histo.Form(">>%s", name.Data());
2035  }
2036  drawexp += histo;
2037  TString ww = "";
2038  if (fUserWeight) ww += fWeight;
2039  Long64_t drawResult;
2040  if (!fProfileHisto) drawResult = fTree->Draw(drawexp, ww.Data(), "goff");
2041  else drawResult = fTree->Draw(drawexp, ww.Data(), "prof,goff");
2042  if (drawResult < 0) {
2043  // Error: problem with Draw, probably bad expression
2044  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
2045  return;
2046  }
2047  TH1* h(nullptr);
2048  if (IsPROOFEnabled())
2049  h = (TH1*)gProof->GetOutputList()->FindObject(name);
2050  else
2051  h = (TH1*)gDirectory->Get(name);
2052  h->SetTitle(histotitle);
2053  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
2054  h->SetDirectory(0);
2055  if (h->InheritsFrom("TH1")) {
2056  h->GetXaxis()->SetTitle(fXLeaf->GetTitle());
2057  h->SetLineWidth(2);
2058  }
2059  if (h->InheritsFrom("TH2") || h->InheritsFrom("TProfile")) h->GetYaxis()->SetTitle(fYLeaf->GetTitle());
2060 
2061  AddHisto(h);
2062  fHistoNumber++;
2063  DrawHisto(h);
2064 }
2065 
2066 
2067 
2068 
2070 
2072 {
2073  if ((!fXLeaf->InheritsFrom("TLeaf")) || (!fYLeaf->InheritsFrom("TLeaf")) || (!fZLeaf->InheritsFrom("TLeaf"))) {
2074  Warning("DrawAsDalitz", "Cannot be used with aliases !");
2075  return;
2076  }
2077 
2078  TString Xexpr, Yexpr, Zexpr;
2079  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2080  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2081  Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2082  fLeafExpr.Form("%s:%s:%s", Xexpr.Data(), Yexpr.Data(), Zexpr.Data());
2083 
2087 
2088  if ((!xType.Contains(yType.Data())) || (!yType.Contains(zType.Data()))) {
2089  Warning("DrawAsDalitz", "Leaves %s must have the same type !", fLeafExpr.Data());
2090  return;
2091  }
2092 
2093  Double_t x, y, z;
2094  Double_t var1, var2, var3;
2095  Float_t varf1, varf2, varf3;
2096  Int_t vari1, vari2, vari3;
2097  Short_t vars1, vars2, vars3;
2098  Char_t varc1, varc2, varc3;
2099  x = y = z = 0.;
2100 
2101  if (xType.Contains("Int_t")) {
2102  fTree->SetBranchAddress(Xexpr.Data(), &vari1);
2103  fTree->SetBranchAddress(Yexpr.Data(), &vari2);
2104  fTree->SetBranchAddress(Zexpr.Data(), &vari3);
2105  }
2106  else if (xType.Contains("Short_t")) {
2107  fTree->SetBranchAddress(Xexpr.Data(), &vars1);
2108  fTree->SetBranchAddress(Yexpr.Data(), &vars2);
2109  fTree->SetBranchAddress(Zexpr.Data(), &vars3);
2110  }
2111  else if (xType.Contains("Char_t")) {
2112  fTree->SetBranchAddress(Xexpr.Data(), &varc1);
2113  fTree->SetBranchAddress(Yexpr.Data(), &varc2);
2114  fTree->SetBranchAddress(Zexpr.Data(), &varc3);
2115  }
2116  else if (xType.Contains("Double_t")) {
2117  fTree->SetBranchAddress(Xexpr.Data(), &var1);
2118  fTree->SetBranchAddress(Yexpr.Data(), &var2);
2119  fTree->SetBranchAddress(Zexpr.Data(), &var3);
2120  }
2121  else if (xType.Contains("Float_t")) {
2122  fTree->SetBranchAddress(Xexpr.Data(), &varf1);
2123  fTree->SetBranchAddress(Yexpr.Data(), &varf2);
2124  fTree->SetBranchAddress(Zexpr.Data(), &varf3);
2125  }
2126 
2127  if (fUserBinning) {
2128  if (!DefineUserBinningD()) return;
2129  }
2130 
2131  TString histotitle;
2132  GenerateHistoTitle(histotitle, fLeafExpr, "");
2133 
2134  KVDalitzPlot* h = 0;
2135  if (fUserBinning) h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data(), fOrderedDalitz, fNxD, 0., 1.2, fNyD, 0., 1.2);
2136  else h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data());
2137  fHistoNumber++;
2138 
2139  TEntryList* el = fChain->GetEntryList();
2140  if (el) el->GetEntry(0);
2142 
2143  if (el) nentries = el->GetN();
2144  for (int i = 0; i < nentries; i++) {
2145  Int_t j = i;
2146  if (el) j = el->Next();
2147  fTree->GetEntry(j);
2148  if (xType.Contains("Int_t")) {
2149  x = vari1;
2150  y = vari2;
2151  z = vari3;
2152  }
2153  else if (xType.Contains("Short_t")) {
2154  x = vars1;
2155  y = vars2;
2156  z = vars3;
2157  }
2158  else if (xType.Contains("Char_t")) {
2159  x = varc1;
2160  y = varc2;
2161  z = varc3;
2162  }
2163  else if (xType.Contains("Double_t")) {
2164  x = var1;
2165  y = var2;
2166  z = var3;
2167  }
2168  else if (xType.Contains("Float_t")) {
2169  x = varf1;
2170  y = varf2;
2171  z = varf3;
2172  }
2173  h->FillAsDalitz(x, y, z);
2174  }
2175 
2176  h->SetOption("col");
2177  h->SetDirectory(0);
2178  AddHisto((TH2F*)h);
2179  DrawHisto(h);
2181 
2182 }
2183 
2184 
2185 
2190 
2192 {
2193  // Open dialogue box for user to fill required weight for histo
2194  //
2195  // returns false if Cancel button is pressed
2196 
2197  KVNameValueList params{{"Weight", ""}};
2198  Bool_t cancel_pressed{false};
2199  auto s = new KVNameValueListGUI(GetMainWindow(), &params, &cancel_pressed);
2200  s->DisplayDialog();
2201  // cancel was pressed ?
2202  if (cancel_pressed) return false;
2203  fWeight = params.GetStringValue("Weight");
2204  return true;
2205 }
2206 
2207 
2208 
2211 
2213 {
2214  // Method called when user double-clicks a leaf/alias in list
2215 
2216  if (fUserWeight) {
2217  if (!DefineWeight()) return;
2218  }
2219 
2220  TH1* histo = nullptr;
2221  if (obj->InheritsFrom("TLeaf")) {
2222  TLeaf* leaf = (TLeaf*)fChain->GetListOfLeaves()->FindObject(obj->GetName());//dynamic_cast<TLeaf*>(obj);
2223  TString expr = leaf->GetName();
2224  TString type = leaf->GetTypeName();
2225  // check histo not already in list
2226  TString htit;
2227  if (fUserWeight) GenerateHistoTitle(htit, expr, "", fWeight);
2228  else GenerateHistoTitle(htit, expr, "");
2229  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2230  if (kvhisto) histo = kvhisto->GetHisto();
2231  if (!histo) {
2232  if (type == "Int_t" || type == "Char_t" || type == "Short_t") {
2233  Int_t xmin = fTree->GetMinimum(expr);
2234  Int_t xmax = fTree->GetMaximum(expr);
2235  if (type == "Char_t") {
2236  TString tmp;
2237  tmp.Form("int(%s)", expr.Data());
2238  expr = tmp.Data();
2239  }
2240  histo = MakeIntHisto(expr, "", xmin, xmax, (fUserWeight ? fWeight.Data() : ""));
2241  if (!histo) return;
2242  histo->GetXaxis()->SetTitle(leaf->GetName());
2243  }
2244  else {
2245  histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2246  if (!histo) return;
2247  histo->GetXaxis()->SetTitle(leaf->GetName());
2248  }
2249  if (!histo) return;
2250  }
2251  DrawHisto(histo);
2252  }
2253  else {
2254  TString expr = obj->GetTitle();
2255  // check histo not already in list
2256  TString htit;
2257  GenerateHistoTitle(htit, expr, "", (fUserWeight ? fWeight.Data() : ""));
2258  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2259  if (kvhisto) histo = kvhisto->GetHisto();
2260  if (!histo) histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2261  if (!histo) return;
2262  histo->GetXaxis()->SetTitle(obj->GetTitle());
2263  DrawHisto(histo);
2264  }
2265 }
2266 
2267 
2268 
2271 
2273 {
2274  // Method called when user histo selection changes in GUI histogram list
2275 
2280  if (fSelectedHistos) {
2281  if (fSelectedHistos->GetEntries() > 0) {
2283  if (fSelectedHistos->GetEntries() == 1 && fSelectedHistos->First()->IsA() == TH1F::Class()) {
2284  }
2286  }
2287  }
2288 }
2289 
2290 
2291 
2293 
2295 {
2296  SetEntryList(GetSelection(sel));
2297 }
2298 
2299 
2300 
2303 
2305 {
2306  // Look for selection in list of selections
2307  return (TEntryList*)fSelections.FindObjectByTitle(selection);
2308 }
2309 
2310 
2312 
2314 {
2315  fPROOFEnabled = yes;
2316  if (yes) {
2317  // open new PROOF-lite session
2318  if (!gProof) TProof::Open("");
2319  if (fChain) fChain->SetProof(kTRUE);
2320  }
2321  else {
2322  if (fChain) fChain->SetProof(kFALSE);
2323  }
2324 }
2325 
2326 
2327 
2329 
2331 {
2332  Info("Save", "Saving analysis %s in file %s", GetTitle(), fSaveAnalysisFileName.Data());
2335 }
2336 
2337 
2338 
2345 
2346 void KVTreeAnalyzer::SaveAs(const char* filename, Option_t*) const
2347 {
2348  // Override TObject::SaveAs
2349  // We need to:
2350  // - (re)create the file
2351  // - do fChain->SetDirectory before writing to disk
2352 
2353  // save current directory
2354  TDirectory* sav = gDirectory;
2355  TDirectory* chsav = (fChain ? fChain->GetDirectory() : nullptr);
2356 
2357  TFile* f = TFile::Open(filename, "recreate");
2358  Write();
2359  if (fChain) { // make sure TChain doesn't get redirected
2360  fChain->SetDirectory(chsav);
2361  }
2362  delete f;
2363 
2364  // back to original directory
2365  sav->cd();
2366 }
2367 
2368 
2369 // void KVTreeAnalyzer::FitGum1()
2370 // {
2371 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2372 // if(!histo) return;
2373 // GDfirst->SetParameters(histo->GetMean(),histo->GetRMS());
2374 // histo->Fit(GDfirst,"EM");
2375 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2376 // if(!stats){
2377 // histo->SetStats(1);
2378 // histo->Draw();
2379 // gPad->Update();
2380 // stats = (TPaveStats*)histo->FindObject("stats");
2381 // }
2382 // if(stats){
2383 // // if canvas's 'no stats' option has been set by user,
2384 // // there will still be no valid stats object,
2385 // // so this test is to avoid the ensuing seg fault
2386 // stats->SetFitFormat("10.9g");
2387 // stats->SetOptFit(111);
2388 // }
2389 // histo->SetOption("e1");
2390 // histo->SetMarkerStyle(24);
2391 // histo->SetMarkerColor(kBlue+2);
2392 // gPad->Modified();gPad->Update();
2393 // SetAnalysisModifiedSinceLastSave(kTRUE);
2394 // }
2395 // void KVTreeAnalyzer::FitGum2()
2396 // {
2397 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2398 // if(!histo) return;
2399 // GDsecond->SetParameters(histo->GetMean(),histo->GetRMS());
2400 // histo->Fit(GDsecond,"EM");
2401 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2402 // if(!stats){
2403 // histo->SetStats(1);
2404 // histo->Draw();
2405 // gPad->Update();
2406 // stats = (TPaveStats*)histo->FindObject("stats");
2407 // }
2408 // if(stats){
2409 // // if canvas's 'no stats' option has been set by user,
2410 // // there will still be no valid stats object,
2411 // // so this test is to avoid the ensuing seg fault
2412 // stats->SetFitFormat("10.9g");
2413 // stats->SetOptFit(111);
2414 // }
2415 // histo->SetOption("e1");
2416 // histo->SetMarkerStyle(24);
2417 // histo->SetMarkerColor(kBlue+2);
2418 // gPad->Modified();gPad->Update();
2419 // SetAnalysisModifiedSinceLastSave(kTRUE);
2420 // }
2421 // void KVTreeAnalyzer::FitGum3()
2422 // {
2423 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2424 // if(!histo) return;
2425 // GDthird->SetParameters(histo->GetMean(),histo->GetRMS());
2426 // histo->Fit(GDthird,"EM");
2427 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2428 // if(!stats){
2429 // histo->SetStats(1);
2430 // histo->Draw();
2431 // gPad->Update();
2432 // stats = (TPaveStats*)histo->FindObject("stats");
2433 // }
2434 // if(stats){
2435 // // if canvas's 'no stats' option has been set by user,
2436 // // there will still be no valid stats object,
2437 // // so this test is to avoid the ensuing seg fault
2438 // stats->SetFitFormat("10.9g");
2439 // stats->SetOptFit(111);
2440 // }
2441 // histo->SetOption("e1");
2442 // histo->SetMarkerStyle(24);
2443 // histo->SetMarkerColor(kBlue+2);
2444 // gPad->Modified();gPad->Update();
2445 // SetAnalysisModifiedSinceLastSave(kTRUE);
2446 // }
2447 // void KVTreeAnalyzer::FitGausGum1()
2448 // {
2449 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2450 // if(!histo) return;
2451 // GausGum1->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2452 // histo->Fit(GausGum1,"EM");
2453 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2454 // if(!stats){
2455 // histo->SetStats(1);
2456 // histo->Draw();
2457 // gPad->Update();
2458 // stats = (TPaveStats*)histo->FindObject("stats");
2459 // }
2460 // if(stats){
2461 // // if canvas's 'no stats' option has been set by user,
2462 // // there will still be no valid stats object,
2463 // // so this test is to avoid the ensuing seg fault
2464 // stats->SetFitFormat("10.9g");
2465 // stats->SetOptFit(111);
2466 // }
2467 // histo->SetOption("e1");
2468 // histo->SetMarkerStyle(24);
2469 // histo->SetMarkerColor(kBlue+2);
2470 // gPad->Modified();gPad->Update();
2471 // SetAnalysisModifiedSinceLastSave(kTRUE);
2472 // }
2473 //
2474 // void KVTreeAnalyzer::FitGausGum2()
2475 // {
2476 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2477 // if(!histo) return;
2478 // GausGum2->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2479 // histo->Fit(GausGum2,"EM");
2480 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2481 // if(!stats){
2482 // histo->SetStats(1);
2483 // histo->Draw();
2484 // gPad->Update();
2485 // stats = (TPaveStats*)histo->FindObject("stats");
2486 // }
2487 // if(stats){
2488 // // if canvas's 'no stats' option has been set by user,
2489 // // there will still be no valid stats object,
2490 // // so this test is to avoid the ensuing seg fault
2491 // stats->SetFitFormat("10.9g");
2492 // stats->SetOptFit(111);
2493 // }
2494 // histo->SetOption("e1");
2495 // histo->SetMarkerStyle(24);
2496 // histo->SetMarkerColor(kBlue+2);
2497 // gPad->Modified();gPad->Update();
2498 // SetAnalysisModifiedSinceLastSave(kTRUE);
2499 // }
2500 //
2501 // void KVTreeAnalyzer::FitGausGum3()
2502 // {
2503 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2504 // if(!histo) return;
2505 // GausGum3->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2506 // histo->Fit(GausGum3,"EM");
2507 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2508 // if(!stats){
2509 // histo->SetStats(1);
2510 // histo->Draw();
2511 // gPad->Update();
2512 // stats = (TPaveStats*)histo->FindObject("stats");
2513 // }
2514 // if(stats){
2515 // // if canvas's 'no stats' option has been set by user,
2516 // // there will still be no valid stats object,
2517 // // so this test is to avoid the ensuing seg fault
2518 // stats->SetFitFormat("10.9g");
2519 // stats->SetOptFit(111);
2520 // }
2521 // histo->SetOption("e1");
2522 // histo->SetMarkerStyle(24);
2523 // histo->SetMarkerColor(kBlue+2);
2524 // gPad->Modified();gPad->Update();
2525 // SetAnalysisModifiedSinceLastSave(kTRUE);
2526 // }
2527 
2528 
2533 
2535 {
2536  // fill and return TList with histos containing the given data
2537  // which may be 1D ("mult", "zmax", etc.) or 2D ("zmax:mult")
2538  // DELETE LIST AFTER USE
2539  TList* hlist = new TList;
2540  TIter next(&fHistolist);
2541 
2542  KVHistogram* h;
2543  while ((h = (KVHistogram*)next())) {
2544 
2545  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr)) hlist->Add(h->GetHisto());
2546  }
2547  return hlist;
2548 }
2549 
2550 
2551 
2555 
2557 {
2558  // fill and return TList with histos using the given selection criteria
2559  // DELETE LIST AFTER USE
2560  TList* hlist = new TList;
2561  TIter next(&fHistolist);
2562 
2563  KVHistogram* h;
2564  while ((h = (KVHistogram*)next())) {
2565 
2566  if (h->IsType("Histo") && !strcmp(h->GetSelection(), expr)) hlist->Add(h->GetHisto());
2567  }
2568  return hlist;
2569 }
2570 
2571 
2572 
2574 
2575 TH1* KVTreeAnalyzer::GetHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2576 {
2577  TIter next(&fHistolist);
2578 
2579  KVHistogram* h;
2580  while ((h = (KVHistogram*)next())) {
2581 
2582  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection)) {
2583  if (strcmp(weight, "")) {
2584  if (!strcmp(h->GetWeight(), weight)) return h->GetHisto();
2585  }
2586  else return h->GetHisto();
2587  }
2588  }
2589  return 0;
2590 }
2591 
2592 
2593 
2595 
2597 {
2598  return (KVHistogram*)fHistolist.FindObjectWithMethod(title, "GetHistoTitle");
2599 }
2600 
2601 
2602 
2604 
2605 void KVTreeAnalyzer::DeleteHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2606 {
2607  TIter next(&fHistolist);
2608 
2609  KVHistogram* h;
2610  while ((h = (KVHistogram*)next())) {
2611 
2612  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection) && !strcmp(h->GetWeight(), weight)) {
2613  fHistolist.Remove(h);
2614  delete h;
2616  }
2617  }
2619 }
2620 
2621 
2622 
2625 
2627 {
2628  // Delete all currently selected histograms
2629  if (fSelectedHistos) {
2630  Int_t nsel = fSelectedHistos->GetEntries();
2631  if (nsel < 1) return;
2632  for (int i = 0; i < nsel; i++) {
2633  TObject* obj = fSelectedHistos->At(i);
2634  fHistolist.Remove(obj);
2635  delete obj;
2637  }
2639  }
2641 }
2642 
2643 
2644 
2649 
2651 {
2652  // Called when G_histo_add button is pressed
2653  // There should be 2 histograms in fSelectedHistos
2654  // We assume that both are of same type and have same binning etc.
2655 
2656  if (fSelectedHistos->GetEntries() != 2) return;
2657  HistoToAdd1 = dynamic_cast<KVHistogram*>(fSelectedHistos->At(0))->GetHisto();
2658  HistoToAdd2 = dynamic_cast<KVHistogram*>(fSelectedHistos->At(1))->GetHisto();
2659  if (HistoToAdd1 && HistoToAdd2) {
2660  Info("AddSelectedHistos", "Adding %s and %s", HistoToAdd1->GetName(), HistoToAdd2->GetName());
2661  TString name = Form("h%d", fHistoNumber);
2662  TString oldname = HistoToAdd1->GetName();
2663  if (oldname.BeginsWith("I")) name.Prepend("I");
2664  HistoAddResult = (TH1*)HistoToAdd1->Clone(name);
2666  Bool_t ok = KVBase::OpenContextMenu("HistoAddition", this);
2667  if (!ok) {
2668  Info("AddSelectedHistos", "Call to context menu not OK");
2669  delete HistoAddResult;
2670  return;
2671  }
2672  if (MethodNotCalled()) {
2673  Info("AddSelectedHistos", "You pressed cancel");
2674  delete HistoAddResult;
2675  return;
2676  }
2677  ++fHistoNumber;
2679  }
2680  else {
2681  Info("AddSelectedHistos", "Only possible for 2 histograms");
2682  }
2683 }
2684 
2685 
2686 
2688 
2690 {
2691  fMethodCalled = kTRUE;
2693 // TODO: it would be nice to distinguish histograms which are the result of
2694 // adding other histograms together. For the moment they appear identical to
2695 // to the first histogram in terms of variables etc. The following attempt
2696 // doesn't work (can't parse the title correctly)
2697 // TString title;
2698 // title.Form("SUMHIST:{%s,%s}",HistoToAdd1->GetTitle(),HistoToAdd2->GetTitle());
2699 // HistoAddResult->SetTitle(title);
2700 }
2701 
2702 
2703 
2704 
2707 
2709 {
2710  // regenerate entry lists for all selections
2711  TList old_lists;
2712  old_lists.AddAll(&fSelections);
2713  fSelections.Clear();
2715  TIter next(&old_lists);
2716  TEntryList* old_el;
2717  SetEntryList(nullptr);
2718  SelectionChanged();
2719  while ((old_el = (TEntryList*)next())) {
2720  cout << "REGENERATING SELECTION : " << old_el->GetTitle() << endl;
2721  MakeSelection(old_el->GetTitle());
2722  ((TEntryList*)fSelections.Last())->SetReapplyCut(old_el->GetReapplyCut());
2724  }
2725  old_lists.Delete();
2726 }
2727 
2728 
2729 
2731 
2733 {
2734  switch (id) {
2735  case MH_OPEN_CHAIN:
2736  OpenChain();
2737  break;
2738  case MH_OPEN_FILE:
2740  break;
2741  case MH_ADD_FRIEND:
2743  break;
2744  case MH_APPLY_ANALYSIS:
2746  break;
2747  case MH_SAVE_FILE:
2749  break;
2750  case MH_SAVE:
2751  Save();
2752  break;
2753  case MH_CLOSE:
2754  delete fMain_histolist;
2755  GUIClosed();
2756  break;
2757  case MH_QUIT:
2758  // check all analyzers need saving
2759  while (fgAnalyzerList->GetEntries() > 1) {
2760  TIter next(fgAnalyzerList);
2762  do {
2763  tan = (KVTreeAnalyzer*)next();
2764  }
2765  while (tan == this);
2766  tan->AnalysisSaveCheck();
2767  delete tan;
2768  }
2770  gROOT->ProcessLine(".q");
2771  break;
2772 
2773  default:
2774  break;
2775  }
2776 }
2777 
2778 
2780 
2782 {
2783  switch (id) {
2784  case SEL_COMB_AND:
2786  break;
2787 
2788  case SEL_COMB_OR:
2790  break;
2791 
2792  case SEL_DELETE:
2793  DeleteSelections();
2794  break;
2795 
2796  case SEL_UPDATE:
2797  UpdateEntryLists();
2798  break;
2799 
2800  case SEL_GEN_CONST_XSEC:
2801  KVBase::OpenContextMenu("GenerateConstantXSecSelections", this);
2802  break;
2803 
2804  default:
2805  break;
2806  }
2807 }
2808 
2809 
2810 
2812 
2814 {
2815  switch (opt) {
2816  case OPT_PROOF:
2819  EnablePROOF(false);
2820  }
2821  else {
2823  EnablePROOF();
2824  }
2825  }
2826 }
2827 
2828 
2829 
2832 
2834 {
2835  // Open a previous analysis session
2836 
2837  static TString dir(".");
2838  const char* filetypes[] = {
2839  "Analysis files", "Analysis*.root",
2840  0, 0
2841  };
2842  TGFileInfo fi;
2843  fi.fFileTypes = filetypes;
2844  fi.fIniDir = StrDup(dir);
2845  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2846  if (fi.fFilename) {
2847  KVTreeAnalyzer* newAnal = this;
2848  if (fTree) newAnal = new KVTreeAnalyzer(kFALSE);
2849  newAnal->OpenAnyFile(fi.fFilename);
2850  }
2851  dir = fi.fIniDir;
2852 }
2853 
2854 
2855 
2857 
2859 {
2860  static TString dir(".");
2861  const char* filetypes[] = {
2862  "ROOT files", "*.root",
2863  0, 0
2864  };
2865  TGFileInfo fi;
2866  fi.fFileTypes = filetypes;
2867  fi.fIniDir = StrDup(dir);
2868  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2869  if (fi.fFilename) {
2871  }
2872  dir = fi.fIniDir;
2873 }
2874 
2875 
2878 
2880 {
2881  // Open a file or files containing TTrees to analyse
2882 
2883  static TString dir(".");
2884  const char* filetypes[] = {
2885  "ROOT files", "*.root*",
2886  0, 0
2887  };
2888  TGFileInfo fi;
2889  fi.fFileTypes = filetypes;
2890  fi.fIniDir = StrDup(dir);
2892  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2893  if (fi.fFileNamesList && fi.fFileNamesList->GetEntries()) {
2894 
2895  // look in first file to find first TTree and use its name/title
2896  TString theTreeName, theTreeTitle;
2898  KVUnownedList keys;
2899  keys.AddAll(file->GetListOfKeys());
2900  // Get list of trees in file
2901  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
2902  if (trees->GetEntries()) {
2903  theTreeName = trees->First()->GetName();
2904  theTreeTitle = trees->First()->GetTitle();
2905  }
2906  if (theTreeName != "") {
2907  // if analysis already en cours, open new GUI
2908  KVTreeAnalyzer* newAnal = this;
2909  if (fTree) newAnal = new KVTreeAnalyzer(kFALSE);
2910  newAnal->OpenChain(theTreeName, theTreeTitle, fi.fFileNamesList);
2911  if (fi.fFileNamesList->GetEntries() == 1) {
2912  // if a single file is selected, look to see if any histograms are in it
2913  newAnal->GetHistosFromFile(file, keys);
2914  }
2915  }
2916  }
2917  dir = fi.fIniDir;
2918 }
2919 
2920 
2921 
2923 
2925 {
2926  static TString dir(".");
2927  const char* filetypes[] = {
2928  "ROOT files", "*.root",
2929  0, 0
2930  };
2931  TGFileInfo fi;
2932  fi.fFileTypes = filetypes;
2933  fi.fIniDir = StrDup(dir);
2934  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2935  if (fi.fFilename) {
2937  }
2938  dir = fi.fIniDir;
2939 }
2940 
2941 
2942 
2944 
2946 {
2947  const char* filetypes[] = {
2948  "Analysis files", "Analysis*.root",
2949  0, 0
2950  };
2951  TGFileInfo fi;
2952  fi.fFileTypes = filetypes;
2955  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDSave, &fi);
2956  if (fi.fFilename) {
2957  //if no ".xxx" ending given, we add ".root"
2958  TString filenam(fi.fFilename);
2959  if (!filenam.Contains('.'))
2960  filenam += ".root";
2961  // update name of file to autosave analysis in
2962  fSaveAnalysisFileName = filenam;
2963  Save();
2964  }
2966 }
2967 
2968 
2969 
2971 
2973 {
2974  TIter next(&keys);
2975  TKey* akey;
2976  while ((akey = (TKey*)next())) {
2977  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
2978  if (!fHistolist.FindObject(akey->GetName())) {
2979  TH1* h = (TH1*)file->Get(akey->GetName());
2980  h->SetDirectory(0);
2981  fHistolist.Add(new KVHistogram(h));
2982  }
2983  }
2984  }
2986 }
2987 
2988 
2989 
2992 
2993 void KVTreeAnalyzer::OpenSingleFile(TFile* file)
2994 {
2995  // Open TTree in file (as a TChain) and import any histograms found in file
2996 
2997  fHistolist.Clear();
2998  KVUnownedList keys;
2999  keys.AddAll(file->GetListOfKeys());
3000  // Get list of trees in file
3001  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3002  if (trees->GetEntries()) {
3003  // Get name of first tree
3004  TString aTreeName = trees->First()->GetName();
3005  TString aFileName = file->GetName();
3006  TList fileList;
3007  TNamed ff(aFileName.Data(), "File Name");
3008  fileList.Add(&ff);
3009  OpenChain(aTreeName, trees->First()->GetTitle(), &fileList);
3010  }
3011  GetHistosFromFile(file, keys);
3012 }
3013 
3014 
3015 
3019 
3021 {
3022  // assuming filepath is the URL of a ROOT file containing a previously-saved analysis, open it and
3023  // open the KVTreeAnalyzer object stored in it
3024 
3026 
3027  TFile* file = TFile::Open(filepath);
3028  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3029  if (kvta) {
3030  ReadFromFile(file);
3031  }
3032  else {
3033  OpenSingleFile(file);
3034  }
3036 }
3037 
3038 
3039 
3044 
3045 void KVTreeAnalyzer::OpenChain(const TString& treename, const TString& treetitle, const TSeqCollection* files)
3046 {
3047  // Open a TChain for analysis
3048  // treename/title is the name/title of the TTree :)
3049  // files is a list of objects with the names of the files in the chain
3050 
3051  fChain = new TChain(treename, treetitle);
3052  TIter nxt(files);
3053  TObject* o;
3054  while ((o = nxt())) fChain->Add(o->GetName());
3055  fChain->SetDirectory(0);
3056  SetTree(fChain);
3057  fHistolist.Clear();
3058  fSelections.Clear();
3059  fAliasList.Clear();
3060  fHistoNumber = 1;
3061  fSelectionNumber = 1;
3062  fAliasNumber = 1;
3063  fSameColorIndex = 0;
3064  fSelectedSelections = 0;
3065  fSelectedLeaves = 0;
3066  fSelectedHistos = 0;
3070  FillLeafList();
3072 }
3073 
3074 
3075 
3078 
3080 {
3081  // Generate all user aliases in list which are not already defined
3082 
3083  if (list->GetEntries()) {
3084  TIter next(list);
3085  TObject* o;
3086  while ((o = next())) {
3087  if (!GetAlias(o->GetTitle())) {
3088  Info("GenerateAllAliases", "Adding alias %s to leaflist", o->GetTitle());
3090  GenerateAlias();
3091  }
3092  }
3093  }
3094 }
3095 
3096 
3097 
3106 
3108 {
3109  // assuming filepath is the URL of a ROOT file, open it and,
3110  // if no KVTreeAnalyzer object is found, open first TTree in file
3111  // and apply all selections and generate all histograms which
3112  // were made for this analysis.
3113  // Any histograms in the file are added to the list of histograms.
3114  // If filepath contains an existing analysis, we add to it any
3115  // histograms/selections/aliases which are not defined
3116 
3117  TFile* file = TFile::Open(filepath);
3118  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3119  if (kvta) {
3120  // open existing analysis, add any missing histos/selections/aliases
3121  delete file;
3122  KVTreeAnalyzer* applyAnal = OpenFile(filepath);
3123  applyAnal->GenerateAllSelections(&fSelections);
3124  applyAnal->GenerateAllHistograms(&fHistolist);
3125  applyAnal->GenerateAllAliases(&fAliasList);
3126  return;
3127  }
3128  else {
3129  delete file;
3130  KVTreeAnalyzer* applyAnal = new KVTreeAnalyzer(kFALSE);
3131  applyAnal->OpenAnyFile(filepath);
3132  applyAnal->GenerateAllSelections(&fSelections);
3133  applyAnal->GenerateAllHistograms(&fHistolist);
3134  // make sure no selection is left active without being displayed
3135  applyAnal->SetEntryList(nullptr);
3136  applyAnal->G_selection_status->SetText("CURRENT SELECTION:", 0);
3137  applyAnal->GenerateAllAliases(&fAliasList);
3138  }
3139 }
3140 
3141 
3142 
3144 
3145 void KVTreeAnalyzer::SetAlias(const Char_t* name, const Char_t* expr)
3146 {
3147  TString exp = expr;
3148  exp.ReplaceAll("d2r", "TMath::DegToRad()");
3149  exp.ReplaceAll("r2d", "TMath::RadToDeg()");
3150  fAliasList.Add(new TNamed(name, exp.Data()));
3152 }
3153 
3154 
3155 
3157 
3158 static const char* gSaveAsTypes[] = { "PostScript", "*.ps",
3159  "Encapsulated PostScript", "*.eps",
3160  "PDF", "*.pdf",
3161  "SVG", "*.svg",
3162  "TeX", "*.tex",
3163  "GIF", "*.gif",
3164  "ROOT files", "*.root",
3165  "XML", "*.xml",
3166  "PNG", "*.png",
3167  "XPM", "*.xpm",
3168  "JPEG", "*.jpg",
3169  "TIFF", "*.tiff",
3170  "XCF", "*.xcf",
3171  0, 0
3172  };
3173 
3174 
3175 
3180 
3182 {
3183  // Open file dialog box for user to choose directory and
3184  // image file-type for generating picture files of all
3185  // histos as they are drawn
3186 
3187  Info("SetUpHistoAutoSave", "Select image filetype and directory");
3188  TString workdir = gSystem->WorkingDirectory();
3189  static TString dir(".");
3190  static Int_t typeidx = 0;
3191  static Bool_t overwr = kFALSE;
3192  TGFileInfo fi;
3193  fi.fFileTypes = gSaveAsTypes;
3194  fi.fIniDir = StrDup(dir);
3195  fi.fFileTypeIdx = typeidx;
3196  fi.fOverwrite = overwr;
3197  new KVFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kKVFDDirectory, &fi);
3198  gSystem->ChangeDirectory(workdir.Data());
3199  TString ft = fi.fFileTypes[fi.fFileTypeIdx + 1];
3200  dir = fi.fIniDir;
3201  typeidx = fi.fFileTypeIdx;
3202  overwr = fi.fOverwrite;
3203  fAutoSaveDir = dir.Data();
3204  fAutoSaveType = ft(1, ft.Length()).Data();
3205  Info("SetUpHistoAutoSave", "file-type:%s directory:%s", fAutoSaveType.Data(), fAutoSaveDir.Data());
3206 }
3207 
3208 
3209 
3213 
3215 {
3216  // Save currently displayed histo as an image file
3217  // If 'same' checkbox is ticked, we use the same filename as used for the first histogram
3218 
3219  static TString lastFilename = "";
3220 
3221  if (fDrawSame) {
3222  gPad->SaveAs(lastFilename);
3223  return;
3224  }
3225  TString title = h->GetTitle();
3226  title.ReplaceAll(" ", "_");
3227  title.ReplaceAll("/", "#");
3228  title.ReplaceAll("*", "x");
3229  title.ReplaceAll("$", "#");
3230  title.ReplaceAll("(", "[");
3231  title.ReplaceAll(")", "]");
3232  title.Append(fAutoSaveType);
3233  title.Prepend("/");
3234  title.Prepend(fAutoSaveDir);
3235  Info("AutoSaveHisto", "Saved as: %s", title.Data());
3236  gPad->SaveAs(title);
3237  lastFilename = title;
3238 }
3239 
3240 
3241 
3245 
3247 {
3248  // We take the title of every object in 'list' and generate the corresponding selection
3249  // if it does not already exist
3250 
3251  TIter nextSel(list);
3252  TObject* sel;
3253  while ((sel = nextSel())) {
3254  if (!GetSelection(sel->GetTitle())) {
3255  Info("GenerateAllSelections", "Generating selection: %s", sel->GetTitle());
3256  MakeSelection(sel->GetTitle());
3257  }
3258  }
3259 }
3260 
3261 
3262 
3266 
3268 {
3269  // For every histogram in the list, we generate histograms with the same binning for
3270  // the same expression, selection and weight if they don't already exist
3271 
3272  TIter nextHist(list);
3273  KVHistogram* obj;
3274  TH1* hist;
3275  while ((obj = (KVHistogram*)nextHist())) {
3276  if (!obj->IsType("Cut")) {
3277  hist = obj->GetHisto();
3278  if (GetHistoByTitle(hist->GetTitle())) continue;
3279  TString exp = obj->GetExpression();
3280  TString sel = obj->GetSelection();
3281  TString weight = obj->GetWeight();
3282  if (weight == "1") weight = "";
3283  // set selection
3284  Info("GenerateAllHistograms", "Generating histogram: %s", hist->GetTitle());
3285  SetSelection(sel);
3286  RemakeHisto(hist, exp, weight);
3287  }
3288  }
3289 }
3290 
3291 
3292 
3299 
3300 void KVTreeAnalyzer::Streamer(TBuffer& R__b)
3301 {
3302  // Read serialized object from file
3303  // For versions < 4, fHistolist contained TH* or TCutG objects:
3304  // we convert to a list of KVHistogram objects.
3305  // Flag will be set to say analysis needs saving.
3306  // Reparse all histogram expressions and selections in case they were not saved correctly.
3307 
3308  UInt_t R__s, R__c;
3309  if (R__b.IsReading()) {
3310  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3311  R__b.ReadClassBuffer(KVTreeAnalyzer::Class(), this, R__v, R__s, R__c);
3312  if (R__v < 5) {
3313  // no fChain pointer member before v5
3314  ReconnectTree();
3315  }
3316  if (fChain && fTree != fChain) SetTree(fChain);
3317  if (fChain) {
3319  Info("Streamer", "Checking friends");
3320  // check friends are TChains, not TTrees & they have valid pointers
3321  TFriendElement* fe;
3322  TIter nxt(fChain->GetListOfFriends());
3323  KVNumberList toRemove;
3324  KVNameValueList infos;
3325  int idx = 0;
3326  while ((fe = (TFriendElement*)nxt())) {
3327  if (!fe->GetTree() || (fe->GetTree() && !fe->GetTree()->InheritsFrom("TChain"))) {
3328  Info("Streamer", "Found friend to convert to TChain");
3329  toRemove.Add(idx);
3330  infos.SetValue(Form("treeName%d", idx), fe->GetTreeName());
3331  if (!fe->GetFile()) {
3332  Info("Streamer", "Choose file containg friend tree %s", fe->GetTreeName());
3333  static TString dir(".");
3334  const char* filetypes[] = {
3335  "ROOT files", "*.root",
3336  0, 0
3337  };
3338  TGFileInfo fi;
3339  fi.fFileTypes = filetypes;
3340  fi.fIniDir = StrDup(dir);
3341  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3342  if (fi.fFilename) {
3343  infos.SetValue(Form("fileName%d", idx), fi.fFilename);
3344  }
3345  dir = fi.fIniDir;
3346  }
3347  else
3348  infos.SetValue(Form("fileName%d", idx), fe->GetFile()->GetName());
3349  }
3350  ++idx;
3351  }
3352  if (toRemove.GetEntries()) {
3353  Info("Streamer", "Removing TTree friends");
3354  toRemove.Begin();
3355  while (!toRemove.End()) {
3356  fChain->RemoveFriend(fChain->GetFriend(infos.GetStringValue(Form("treeName%d", toRemove.Next()))));
3357  }
3358  toRemove.Begin();
3359  Info("Streamer", "Adding friends as TChains");
3360  while (!toRemove.End()) {
3361  idx = toRemove.Next();
3362  TChain* friendChain = new TChain(infos.GetStringValue(Form("treeName%d", idx)));
3363  friendChain->Add(infos.GetStringValue(Form("fileName%d", idx)));
3364  fChain->AddFriend(friendChain);
3365  }
3366  }
3367  }
3368  }
3369  if (R__v < 4) {
3370  //Info("Streamer","Converting old histo list");
3371  // convert fHistolist
3372  if (fHistolist.GetEntries()) {
3373  TList tmp;
3374  tmp.AddAll(&fHistolist);
3375  //Info("Streamer","List of histos to import:");
3376  //tmp.ls();
3377  fHistolist.SetOwner(kFALSE);
3378  fHistolist.Clear();
3379  fHistolist.SetOwner(kTRUE);
3380  TNamed* obj;
3381  TIter next(&tmp);
3382  while ((obj = (TNamed*)next())) {
3383  if (obj->InheritsFrom("TCutG"))
3384  fHistolist.Add(new KVHistogram(dynamic_cast<TCutG*>(obj)));
3385  else if (obj->InheritsFrom("TH1"))
3386  fHistolist.Add(new KVHistogram(dynamic_cast<TH1*>(obj)));
3387  }
3388  //Info("Streamer","New histolist:");
3389  fHistolist.ls();
3391  }
3392  }
3393  if (fHistolist.GetEntries()) {
3394  TIter next(&fHistolist);
3395  KVHistogram* h;
3396  while ((h = (KVHistogram*)next())) {
3397  if (h->IsType("Histo")) h->ParseExpressionAndSelection();
3398  }
3399  }
3400  }
3401  else {
3402  R__b.WriteClassBuffer(KVTreeAnalyzer::Class(), this);
3403  }
3404 }
3405 
3406 
3407 
3412 
3414 {
3415  // assuming filepath is the URL of a ROOT file, open it and
3416  // add the first TTree found in file as a friend of the current TTree
3417  // Any histograms in the file are added to the list of histograms
3418 
3419  TFile* file = TFile::Open(filepath);
3420  KVList keys(0);
3421  keys.AddAll(file->GetListOfKeys());
3422  // Get list of trees in file
3423  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3424  if (trees->GetEntries()) {
3425  // Get name of first tree
3426  TString aTreeName = trees->First()->GetName();
3427  TChain* t = new TChain(aTreeName);
3428  t->Add(filepath);
3429  fChain->AddFriend(t);
3430  FillLeafList();
3431  }
3432  TIter next(&keys);
3433  TKey* akey;
3434  while ((akey = (TKey*)next())) {
3435  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3436  if (!fHistolist.FindObject(akey->GetName())) {
3437  TH1* h = (TH1*)file->Get(akey->GetName());
3438  h->SetDirectory(0);
3439  fHistolist.Add(new KVHistogram(h));
3440  }
3441  }
3442  }
3444 }
3445 
3446 
3447 
3448 
3449 
3450 
int Int_t
unsigned int UInt_t
unsigned long ULong_t
kVerticalFrame
kHorizontalFrame
kMainFrame
void AssignAndDelete(TString &target, char *tobedeleted)
@ kKVFDDirectory
Definition: KVFileDialog.h:33
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
static const char * gSaveAsTypes[]
Int_t my_color_array[]
#define MAX_COLOR_INDEX
KVTreeAnalyzer * gTreeAnalyzer
#define SafeDelete(p)
#define f(i)
#define c(i)
#define e(i)
short Version_t
char Char_t
const Bool_t kFALSE
bool Bool_t
short Short_t
double Double_t
float Float_t
const Bool_t kTRUE
const char Option_t
kRed
kOrange
kGreen
kCyan
kBlue
kViolet
#define gDirectory
R__EXTERN TEnv * gEnv
EButtonState
#define gClient
kFDOpen
kFDSave
kDeepCleanup
kLHintsExpandY
kLHintsLeft
kLHintsCenterY
kLHintsCenterX
kLHintsTop
kLHintsExpandX
kMBNo
kMBClose
kMBYes
kMBDismiss
kMBIconExclamation
kMBIconStop
kTextCenterX
kTextLeft
kTextRight
int type
float xmin
int nentries
float ymin
float xmax
float ymax
double tan(double)
double exp(double)
R__EXTERN TProof * gProof
#define gROOT
char * Form(const char *fmt,...)
char * StrDup(const char *str)
R__EXTERN TSystem * gSystem
#define gPad
virtual Bool_t IsType(const Char_t *typ) const
Definition: KVBase.h:184
static void InitEnvironment()
Definition: KVBase.cpp:181
static Bool_t OpenContextMenu(const char *method, TObject *obj, const char *alt_method_name="")
Definition: KVBase.cpp:1495
TCanvas with mouse-controlled dynamic zoom and pan & scan.
Definition: KVCanvas.h:53
Fill 3D observables in a dalitz plot ,.
Definition: KVDalitzPlot.h:27
Modified version of TGFileDialog file selection dialog.
Definition: KVFileDialog.h:48
Wrapper for histograms and graphical cuts used by KVTreeAnalyzer.
Definition: KVHistogram.h:19
TCutG * GetCut() const
Definition: KVHistogram.h:40
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:44
const Char_t * GetSelection() const
TH1 * GetHisto() const
Definition: KVHistogram.h:36
const Char_t * GetWeight() const
Return weighting used for filling histogram.
Bool_t IsTH2() const
Definition: KVHistogram.h:48
virtual void SetIsBoolean(Bool_t isit=kTRUE)
Definition: KVLVContainer.h:87
Extension of TGLVContainer for KVListView widget.
Enhanced version of ROOT TGListView widget.
Definition: KVListView.h:145
virtual void ActivateSortButtons()
Definition: KVListView.cpp:72
virtual void SetDataColumns(Int_t ncolumns)
Definition: KVListView.cpp:91
void SetDoubleClickAction(const char *receiver_class, void *receiver, const char *slot)
Definition: KVListView.cpp:210
virtual KVLVColumnData * GetDataColumn(Int_t index) const
Definition: KVListView.h:167
virtual void Display(const TCollection *l)
Definition: KVListView.h:172
virtual void SetMaxColumnSize(UInt_t width)
Definition: KVListView.h:160
KVList * GetPickOrderedSelectedObjects() const
Definition: KVListView.h:250
TList * GetSelectedObjects() const
Definition: KVListView.h:244
virtual void RemoveAll()
Definition: KVListView.h:189
void AllowContextMenu(Bool_t on=kTRUE)
Definition: KVListView.h:282
virtual void SetDataColumn(Int_t index, const Char_t *name, const Char_t *method="", Int_t mode=kTextCenterX)
Definition: KVListView.cpp:106
void SetUseObjLabelAsRealClass(Bool_t yes=kTRUE)
Definition: KVListView.cpp:189
Extended TList class which owns its objects by default.
Definition: KVList.h:27
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:83
Bool_t End(void) const
Definition: KVNumberList.h:197
void Begin(void) const
Int_t GetEntries() const
Definition: KVNumberList.h:169
void Add(Int_t)
Add value 'n' to the list.
Int_t Next(void) const
KaliVeda extensions to ROOT collection classes.
virtual void Copy(TObject &obj) const
KVSeqCollection * GetSubListWithMethod(const Char_t *retvalue, const Char_t *method) const
virtual TObject * Last() const
virtual void SetOwner(Bool_t enable=kTRUE)
virtual void Clear(Option_t *option="")
virtual Int_t GetSize() const
virtual TObject * At(Int_t idx) const
virtual TObject * First() const
virtual TObject * FindObjectWithMethod(const Char_t *retvalue, const Char_t *method) const
virtual TObject * FindObjectByTitle(const Char_t *) const
Will return object with given title (value of TObject::GetTitle() method).
virtual void Add(TObject *obj)
virtual TObject * FindObjectWithNameAndType(const Char_t *name, const Char_t *type) const
virtual TObject * Remove(TObject *obj)
Remove object from list.
virtual TObject * FindObject(const char *name) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:72
KVString & FindCommonTitleCharacters(const TCollection *, const char bug=' *')
Definition: KVString.cpp:1377
GUI for simple intuitive analysis of data in TTree ,.
void DeleteHisto(const Char_t *expr, const Char_t *selection, const Char_t *weight)
Int_t fSelectionNumber
used for automatic naming of selections
Bool_t IsPROOFEnabledForSelections() const
Bool_t fNoGui
=kTRUE if no graphical interface is required
static KVTreeAnalyzer * OpenFile(const Char_t *filename, Bool_t nogui=kFALSE)
TList * GetHistosByData(const Char_t *expr)
KVHistogram * GetHistoByTitle(const Char_t *title)
TChain * fChain
the analyzed TTree or TChain
Bool_t fNormHisto
=kTRUE: generate normalised histograms (normalise to integral of histo)
TGCheckButton * G_histo_norm
void SaveAs(const char *filename="", Option_t *option="") const
Bool_t IsPROOFEnabled() const
void SetTreeFileName(TTree *t)
TGMenuBar * fMenuBar
Int_t fHistoNumber
used for automatic naming of histograms
void SetTree(TTree *t)
Connects a TChain for analysis.
TGGroupFrame * fMain_leaflist
GUI for access to TTree leaves and aliases.
void DeleteSelections()
Delete the currently selected selection(s)
void ReconnectTree()
Backwards compatibility: to read old analysis files.
const TGMainFrame * GetMainWindow() const
void OpenAnyFile(const Char_t *filepath)
KVListView * G_histolist
GUI list of histograms.
Bool_t MakeSelection(const Char_t *selection)
void ReapplyAnyFile(const Char_t *filepath)
void SetAnalysisModifiedSinceLastSave(Bool_t)
TString fAutoSaveDir
directory for autosaving histos
Bool_t fStatsHisto
=kTRUE: display histo stats box
TGCheckButton * G_histo_app_sel
KVList * fSelectedLeaves
const Char_t * get_leaf_type_name(const TNamed *l)
Bool_t fApplySelection
=kTRUE: apply current selection to existing histogram
TString fTreeName
name of analyzed TTree
TString fAnalysisSaveDir
Bool_t fDrawSame
=kTRUE: draw histograms in same plot
void GenerateAllAliases(TCollection *list)
Generate all user aliases in list which are not already defined.
Int_t fAliasNumber
used for automatic naming of TTree aliases
TH1 * RemakeHisto(TH1 *h, const Char_t *expr, const Char_t *weight="")
TH1 * MakeHisto(const Char_t *expr, const Char_t *selection, Int_t nX, Int_t nY=0, const Char_t *weight="", Double_t xmin=-1, Double_t xmax=-1, Double_t ymin=-1, Double_t ymax=-1)
void SetAlias(const Char_t *name, const Char_t *expr)
Bool_t fDeletedByGUIClose
static KVList * fgAnalyzerList
static list of all analyzers in memory
TString fTreeFileName
name of file containing analyzed TTree
void DeleteSelectedHisto()
Delete all currently selected histograms.
void GUIClosed()
Called when graphical window is closed.
TEntryList * GetSelection(const Char_t *)
Look for selection in list of selections.
Bool_t IsCurrentSelection(const Char_t *sel)
void AutoSaveHisto(TH1 *h)
TGTextEntry * G_alias_text
TGPopupMenu * fSelCombMenu
Bool_t fNewCanvas
=kTRUE: draw each histogram in a new canvas
void init()
Default initialization.
TString fRelativePathToAnalysisFile
TGCheckButton * G_histo_log
void AddHisto(TH1 *)
TGComboBox * G_histo_draw_option
KVUniqueNameList fSelections
list of TEntryList user selections
void GenerateAllHistograms(TCollection *)
Bool_t fNormHistoEvents
=kTRUE: generate normalised histograms (normalise to number of events)
void SetSelection(TObject *)
void CurrentSelection()
Print the currently active selection (TEntryList set on TTree).
KVList fLeafList
clones of leaves in TChain
TGCheckButton * G_histo_weight
void UpdateEntryLists()
regenerate entry lists for all selections
TGCheckButton * G_histo_prof
void SetEntryList(TEntryList *)
void DrawCut(TCutG *)
void HistoAddition(Double_t c1=1, Double_t c2=1)
void OpenGUI()
Launch the GUI (unless fNoGui=kTRUE in which case this does nothing)
void HistoFileMenu_OpenFriend()
TGPictureButton * G_histo_add
void SetRelativePathToAnalysisFile(const Char_t *p)
TGPictureButton * G_histo_del
TGCheckButton * G_histo_stats
KVTreeAnalyzer(Bool_t nogui=kTRUE)
TGCheckButton * G_histo_new_can
void HandleHistoFileMenu(Int_t)
TGCheckButton * G_histo_bin
void HandleOptionsMenu(Int_t opt)
TGGroupFrame * fMain_selectionlist
GUI for handling selections.
TList * fSelectedHistos
void GetHistosFromFile(TFile *file, const KVUnownedList &keys)
TString fSaveAnalysisFileName
void AddCut(TCutG *)
TGPopupMenu * fMenuSelections
Bool_t MethodNotCalled()
TGPictureButton * G_leaf_draw
Bool_t fAutoSaveHisto
=kTRUE: on draw, generate image file of current displayed histo
void HandleSelectionsMenu(Int_t)
void DrawHistogram(TH1 *histo, Bool_t same=false, Bool_t logscale=false)
void EnablePROOF(Bool_t yes=kTRUE)
KVList fHistolist
list of generated histograms
TGPopupMenu * fMenuFile
TList * GetHistosBySelection(const Char_t *expr)
void OpenAnyFriendFile(const Char_t *filepath)
TTree * fTree
for backwards compatibility
TGCheckButton * G_histo_norm_events
void GenerateAllSelections(TCollection *)
For applying existing analysis to new data.
TGPopupMenu * fSelGenerate
TString fAutoSaveType
filetype for autosaving histos
TH1 * GetHistogram(const Char_t *name) const
Return histogram with given name.
TGPopupMenu * fOptionMenu
Long64_t GetEntriesInCurrentSelection() const
KVListView * G_selectionlist
GUI list of TEntryList selections.
TGLabel * G_leaf_expr
TGStatusBar * G_selection_status
status bar in selections GUI
void AddSelection(TEntryList *)
TGLayoutHints * fMenuBarItemLayout
TGCheckButton * G_histo_same
TH1 * MakeIntHisto(const Char_t *expr, const Char_t *selection, Int_t Xmin, Int_t Xmax, const Char_t *weight="")
virtual ~KVTreeAnalyzer()
Destructor.
void OpenChain()
Open a file or files containing TTrees to analyse.
void SelectionChanged()
Method called whenever the selected selection in the GUI list changes.
TGMainFrame * fMain_histolist
GUI for handling histograms.
TH1 * GetHisto(const Char_t *expr, const Char_t *selection, const Char_t *weight="")
Bool_t fAnalysisModifiedSinceLastSave
TNamed * GetAlias(const Char_t *expr)
void HistoSelectionChanged()
Method called when user histo selection changes in GUI histogram list.
void GenerateHistoTitle(TString &title, const Char_t *exp, const Char_t *sel, const Char_t *weight="")
void ReadFromFile(const Char_t *filename)
open a previously saved analysis session.
Bool_t fDrawLog
=kTRUE: draw histograms with log-Y (1-D) or log-Z (2-D) scale
void HistoFileMenu_Open()
Open a previous analysis session.
void DrawLeaf(TObject *)
Method called when user double-clicks a leaf/alias in list.
KVList fAliasList
list of TTree aliases
TList * fSelectedSelections
void Copy(TObject &obj) const
void DrawHisto(TObject *o, Bool_t gen=kTRUE)
TGCheckButton * G_histo_autosave
TGTextEntry * G_selection_text
KVListView * G_leaflist
GUI list of TTree leaves and aliases.
Bool_t fMethodCalled
allows to know if context menu methods are called
void ResetMethodCalled()
virtual void Add(TObject *obj)
Extended TList class which does not own its objects by default.
Definition: KVUnownedList.h:16
virtual void SetLineWidth(Width_t lwidth)
virtual void SetLineColor(Color_t lcolor)
Double_t GetXmax() const
Double_t GetXmin() const
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
Bool_t IsReading() const
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual void SetDirectory(TDirectory *dir)
virtual void RemoveFriend(TTree *)
virtual TObjArray * GetListOfLeaves()
virtual void SetEntryList(TEntryList *elist, Option_t *opt="")
virtual Int_t Add(const char *name, Long64_t nentries=TTree::kMaxEntries)
virtual Long64_t GetEntries() const
virtual TFriendElement * AddFriend(const char *chainname, const char *dummy="")
virtual void SetProof(Bool_t on=kTRUE, Bool_t refresh=kFALSE, Bool_t gettreeheader=kFALSE)
virtual Long64_t Draw(const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
static TClass * GetClass(Bool_t load=kTRUE, Bool_t silent=kFALSE)
Bool_t InheritsFrom(const char *cl) const
virtual void ls(Option_t *option="") const
virtual void AddAll(const TCollection *col)
virtual Int_t GetEntries() const
virtual TObject * Clone(const char *newname="") const
const char * GetVarY() const
const char * GetVarX() const
virtual Bool_t cd(const char *path=nullptr)
virtual Bool_t GetReapplyCut() const
virtual Long64_t Next()
virtual Long64_t GetEntry(Int_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 TTree * GetTree()
virtual TFile * GetFile()
virtual const char * GetTreeName() const
virtual void SetToolTipText(const char *text, Long_t delayms=400)
virtual void SetEnabled(Bool_t e=kTRUE)
TGFrame * GetContainer() const
virtual void SetState(EButtonState state, Bool_t emit=kFALSE)
virtual void AddEntry(const char *s, Int_t id)
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=0)
virtual void SetCleanup(Int_t mode=kLocalCleanup)
virtual TGDimension GetDefaultSize() const
virtual void MapSubwindows()
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
virtual void MapWindow()
virtual TGDimension GetDefaultSize() const
void SetText(const char *newText)
virtual const char * GetTitle() const
void SetIconPixmap(char **xpm_array)
void SetIconName(const char *name)
void SetWindowName(const char *name=0)
virtual void AddPopup(const char *s, TGPopupMenu *menu, TGLayoutHints *l, TGPopupMenu *before=0)
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)
virtual void SetCursorPosition(Int_t pos)
const char * GetText() const
virtual void SetAlignment(ETextJustification mode=kTextLeft)
virtual void SetText(const char *text, Bool_t emit=kTRUE)
Int_t MaxMark() const
void Clear(Option_t *option="")
Int_t MinMark() const
virtual void SetName(const char *name)
virtual void RaiseWindow()
virtual void SetTitle(const char *title="")
virtual void Draw(Option_t *chopt="")
virtual void SetDirectory(TDirectory *dir)
virtual void SetTitle(const char *title)
virtual Bool_t Add(const TH1 *h, const TH1 *h2, Double_t c1=1, Double_t c2=1)
virtual Int_t GetNbinsY() const
Option_t * GetOption() const
TAxis * GetXaxis()
TAxis * GetYaxis()
TObject * Clone(const char *newname=0) const
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
virtual Int_t GetNbinsX() const
virtual void SetMaximum(Double_t maximum=-1111)
virtual void Draw(Option_t *option="")
virtual Double_t Integral(Int_t binx1, Int_t binx2, Option_t *option="") const
virtual void SetOption(Option_t *option=" ")
virtual void Scale(Double_t c1=1, Option_t *option="")
virtual void Sumw2(Bool_t flag=kTRUE)
virtual void SetStats(Bool_t stats=kTRUE)
virtual const char * GetClassName() const
virtual const char * GetTypeName() const
virtual void Add(TObject *obj)
virtual TObject * FindObject(const char *name) const
virtual TObject * At(Int_t idx) const
virtual void Delete(Option_t *option="")
virtual TObject * First() const
virtual const char * GetName() const
virtual void Copy(TObject &named) const
virtual void SetTitle(const char *title="")
virtual const char * GetTitle() const
virtual TObject * FindObject(const char *name) const
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
virtual const char * GetName() const
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual Bool_t InheritsFrom(const char *classname) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual const char * GetTitle() 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
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
TString & Append(char c, Ssiz_t rep=1)
const char * Data() const
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 TObjArray * GetListOfLeaves()
virtual Int_t GetEntry(Long64_t entry, Int_t getall=0)
TFile * GetCurrentFile() const
virtual TTree * GetFriend(const char *) const
virtual Double_t GetMaximum(const char *columname)
virtual TEntryList * GetEntryList()
Int_t SetBranchAddress(const char *bname, T **add, TBranch **ptr=0)
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 TList * GetListOfFriends() const
TDirectory * GetDirectory() const
virtual Double_t GetMinimum(const char *columname)
virtual void ResetBranchAddresses()
virtual TList * GetListOfAliases() const
long long Long64_t
return c1
Double_t y[n]
Double_t x[n]
return c2
TH1 * h
const long double s
Definition: KVUnits.h:94
const long double g
masses
Definition: KVUnits.h:72
auto * l