KaliVeda
Toolkit for HIC analysis
KVTreeAnalyzer.cpp
1 //Created by KVClassFactory on Fri Apr 13 12:31:16 2012
2 //Author: John Frankland
3 
4 #include "KVTreeAnalyzer.h"
5 #include "TString.h"
6 #include "TDirectory.h"
7 #include "TSystem.h"
8 #include "TEntryList.h"
9 #include "Riostream.h"
10 #include "KVCanvas.h"
11 #include "TCutG.h"
12 #include "TLeaf.h"
13 #include "TPaveStats.h"
14 #include "TSystem.h"
15 #include "TPad.h"
16 #include "TKey.h"
17 #include "TROOT.h"
18 #include "TGMsgBox.h"
19 #include "KVFileDialog.h"
20 #include "KVDalitzPlot.h"
21 #include "TEnv.h"
22 #include "TColor.h"
23 #include <KVHistogram.h>
24 #include <TChain.h>
25 #include "TFriendElement.h"
26 #include <TTree.h>
27 #include "KVNameValueListGUI.h"
28 #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
41 Int_t my_color_array[] = {
42  kBlue + 2,
43  kRed + 2,
44  kGreen + 3,
45  kCyan - 2,
46  kOrange + 7,
47  kViolet + 2
48 };
49 
50 
51 KVTreeAnalyzer* gTreeAnalyzer = 0x0;
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;
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;
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;
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 */
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 
1274  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1275  delete f;
1276  anal->fNoGui = nogui;
1278  anal->OpenGUI();
1279  return anal;
1280 }
1281 
1282 
1283 
1286 
1288 {
1289  // open a previously saved analysis session.
1290 
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
1383  histo->SetLineColor(my_color_array[++fSameColorIndex]);
1384  histo->SetLineWidth(2);
1385  if (fSameColorIndex == MAX_COLOR_INDEX) fSameColorIndex = -1;
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.
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 
1935 
1937 {
1938  // \returns maximum value of given TTree variable, taking into account any current selection (TEntryList).
1939  // @param leafname name of TTree variable
1940  //
1941  // \note TTree::GetMaximum() is supposed to do exactly the same, but strangely ignores the selection.
1942 
1943  fTree->GetMaximum(leafname);// this just to use internal TTree cache mechanism
1944 
1945  auto leaf = fTree->GetLeaf(leafname);
1946  if (!leaf) return 0;
1947 
1948  auto branch = leaf->GetBranch();
1949  Double_t cmax = -DBL_MAX;
1950  for (Long64_t i = 0; i < fTree->GetEntries(); ++i) {
1951  auto entryNumber = fTree->GetEntryNumber(i);
1952  if (entryNumber < 0) break;
1953  branch->GetEntry(entryNumber);
1954  for (Int_t j = 0; j < leaf->GetLen(); ++j) {
1955  Double_t val = leaf->GetValue(j);
1956  if (val > cmax) {
1957  cmax = val;
1958  }
1959  }
1960  }
1961  return cmax;
1962 }
1963 
1964 
1965 
1971 
1973 {
1974  // \returns minimum value of given TTree variable, taking into account any current selection (TEntryList).
1975  // @param leafname name of TTree variable
1976  //
1977  // \note TTree::GetMinimum() is supposed to do exactly the same, but strangely ignores the selection.
1978 
1979  fTree->GetMinimum(leafname);// this just to use internal TTree cache mechanism
1980 
1981  auto leaf = fTree->GetLeaf(leafname);
1982  if (!leaf) return 0;
1983 
1984  auto branch = leaf->GetBranch();
1985  Double_t cmin = DBL_MAX;
1986  for (Long64_t i = 0; i < fTree->GetEntries(); ++i) {
1987  auto entryNumber = fTree->GetEntryNumber(i);
1988  if (entryNumber < 0) break;
1989  branch->GetEntry(entryNumber);
1990  for (Int_t j = 0; j < leaf->GetLen(); ++j) {
1991  Double_t val = leaf->GetValue(j);
1992  if (val < cmin) {
1993  cmin = val;
1994  }
1995  }
1996  }
1997  return cmin;
1998 }
1999 
2000 
2001 
2003 
2005 {
2007  return lf->GetTypeName();
2008 }
2009 
2010 
2011 
2015 
2017 {
2018  // Method called when user hits 'draw' button in TTree GUI.
2019  // If only one leaf/alias is selected, this actually calls DrawLeaf.
2020 
2021  if (fLeafExpr == "-")return;
2022  Bool_t threeDexp = fSelectedLeaves->GetEntries() == 3;
2023  if (threeDexp && !fProfileHisto) {
2024  DrawAsDalitz();
2025  return;
2026  }
2027  if (fSelectedLeaves->GetEntries() == 1) {
2029  return;
2030  }
2031 
2032  if (fUserWeight) {
2033  if (!DefineWeight()) return;
2034  }
2035 
2036  int nx = 500, ny = 500;
2037  double xmin, xmax, ymin, ymax;
2038  xmin = xmax = ymin = ymax = 0;
2039  TString Xexpr, Yexpr, Zexpr;
2040  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2041  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2042  if (threeDexp) Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2043  if (fXLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fXLeaf), "Char_t")) {
2044  TString tmp = Xexpr;
2045  Xexpr.Form("int(%s)", tmp.Data());
2046  }
2047  if (fYLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fYLeaf), "Char_t")) {
2048  TString tmp = Yexpr;
2049  Yexpr.Form("int(%s)", tmp.Data());
2050  }
2051 
2052  if (threeDexp) fLeafExpr.Form("%s:%s:%s", Zexpr.Data(), Yexpr.Data(), Xexpr.Data());
2053  else fLeafExpr.Form("%s:%s", Yexpr.Data(), Xexpr.Data());
2054  TString name;
2055  name.Form("h%d", fHistoNumber);
2056  TString drawexp(fLeafExpr), histo, histotitle;
2057  if (fUserWeight) GenerateHistoTitle(histotitle, fLeafExpr, "", fWeight);
2058  else GenerateHistoTitle(histotitle, fLeafExpr, "");
2059 
2060  // Check histo doesn't already exist
2061  // Look for list of histograms with given title as we don't distinguish TH2 from TProfile
2062  unique_ptr<KVSeqCollection> same_histo(fHistolist.GetSubListWithMethod(histotitle, "GetHistoTitle"));
2063  TIter nxtSame(same_histo.get());
2064  KVHistogram* kvhisto;
2065  while ((kvhisto = (KVHistogram*)nxtSame())) {
2066  if ((fProfileHisto && kvhisto->IsProfile()) || (!fProfileHisto && kvhisto->IsTH2())) {
2067  DrawHisto(kvhisto->GetHisto());
2068  return;
2069  }
2070  }
2071 
2072  if (fUserBinning) {
2073  if (!DefineUserBinning()) return;
2074  }
2075 
2076  xmin = GetTreeMinimum(Xexpr);
2077  xmax = GetTreeMaximum(Xexpr);
2078  if (fXLeaf->InheritsFrom("TLeaf") &&
2079  (!strcmp(get_leaf_type_name(fXLeaf), "Int_t") || !strcmp(get_leaf_type_name(fXLeaf), "Short_t") || !strcmp(get_leaf_type_name(fXLeaf), "Char_t"))
2080  ) {
2081  xmin -= 0.5;
2082  xmax += 0.5;
2083  nx = xmax - xmin;
2084  }
2085  ymin = GetTreeMinimum(Yexpr);
2086  ymax = GetTreeMaximum(Yexpr);
2087  if (fYLeaf->InheritsFrom("TLeaf") &&
2088  (!strcmp(get_leaf_type_name(fYLeaf), "Int_t") || !strcmp(get_leaf_type_name(fYLeaf), "Short_t") || !strcmp(get_leaf_type_name(fYLeaf), "Char_t"))
2089  ) {
2090  ymin -= 0.5;
2091  ymax += 0.5;
2092  ny = ymax - ymin;
2093  }
2094  if (fUserBinning) {
2095  nx = fNx;
2096  ny = fNy;
2097  xmin = fXmin;
2098  xmax = fXmax;
2099  ymin = fYmin;
2100  ymax = fYmax;
2101  }
2102 
2103  if (!fProfileHisto) histo.Form(">>%s(%d,%f,%f,%d,%f,%f)", name.Data(), nx, xmin, xmax, ny, ymin, ymax);
2104  else {
2105  if (fUserBinning) histo.Form(">>%s(%d,%f,%f)", name.Data(), nx, xmin, xmax);
2106  else histo.Form(">>%s", name.Data());
2107  }
2108  drawexp += histo;
2109  TString ww = "";
2110  if (fUserWeight) ww += fWeight;
2111  Long64_t drawResult;
2112  if (!fProfileHisto) drawResult = fTree->Draw(drawexp, ww.Data(), "goff");
2113  else drawResult = fTree->Draw(drawexp, ww.Data(), "prof,goff");
2114  if (drawResult < 0) {
2115  // Error: problem with Draw, probably bad expression
2116  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
2117  return;
2118  }
2119  TH1* h(nullptr);
2120  if (IsPROOFEnabled())
2122  else
2123  h = (TH1*)gDirectory->Get(name);
2124  h->SetTitle(histotitle);
2125  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
2126  h->SetDirectory(0);
2127  if (h->InheritsFrom("TH1")) {
2128  h->GetXaxis()->SetTitle(fXLeaf->GetTitle());
2129  h->SetLineWidth(2);
2130  }
2131  if (h->InheritsFrom("TH2") || h->InheritsFrom("TProfile")) h->GetYaxis()->SetTitle(fYLeaf->GetTitle());
2132 
2133  AddHisto(h);
2134  fHistoNumber++;
2135  DrawHisto(h);
2136 }
2137 
2138 
2139 
2140 
2142 
2144 {
2145  if ((!fXLeaf->InheritsFrom("TLeaf")) || (!fYLeaf->InheritsFrom("TLeaf")) || (!fZLeaf->InheritsFrom("TLeaf"))) {
2146  Warning("DrawAsDalitz", "Cannot be used with aliases !");
2147  return;
2148  }
2149 
2150  TString Xexpr, Yexpr, Zexpr;
2151  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2152  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2153  Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2154  fLeafExpr.Form("%s:%s:%s", Xexpr.Data(), Yexpr.Data(), Zexpr.Data());
2155 
2159 
2160  if ((!xType.Contains(yType.Data())) || (!yType.Contains(zType.Data()))) {
2161  Warning("DrawAsDalitz", "Leaves %s must have the same type !", fLeafExpr.Data());
2162  return;
2163  }
2164 
2165  Double_t x, y, z;
2166  Double_t var1, var2, var3;
2167  Float_t varf1, varf2, varf3;
2168  Int_t vari1, vari2, vari3;
2169  Short_t vars1, vars2, vars3;
2170  Char_t varc1, varc2, varc3;
2171  x = y = z = 0.;
2172 
2173  if (xType.Contains("Int_t")) {
2174  fTree->SetBranchAddress(Xexpr.Data(), &vari1);
2175  fTree->SetBranchAddress(Yexpr.Data(), &vari2);
2176  fTree->SetBranchAddress(Zexpr.Data(), &vari3);
2177  }
2178  else if (xType.Contains("Short_t")) {
2179  fTree->SetBranchAddress(Xexpr.Data(), &vars1);
2180  fTree->SetBranchAddress(Yexpr.Data(), &vars2);
2181  fTree->SetBranchAddress(Zexpr.Data(), &vars3);
2182  }
2183  else if (xType.Contains("Char_t")) {
2184  fTree->SetBranchAddress(Xexpr.Data(), &varc1);
2185  fTree->SetBranchAddress(Yexpr.Data(), &varc2);
2186  fTree->SetBranchAddress(Zexpr.Data(), &varc3);
2187  }
2188  else if (xType.Contains("Double_t")) {
2189  fTree->SetBranchAddress(Xexpr.Data(), &var1);
2190  fTree->SetBranchAddress(Yexpr.Data(), &var2);
2191  fTree->SetBranchAddress(Zexpr.Data(), &var3);
2192  }
2193  else if (xType.Contains("Float_t")) {
2194  fTree->SetBranchAddress(Xexpr.Data(), &varf1);
2195  fTree->SetBranchAddress(Yexpr.Data(), &varf2);
2196  fTree->SetBranchAddress(Zexpr.Data(), &varf3);
2197  }
2198 
2199  if (fUserBinning) {
2200  if (!DefineUserBinningD()) return;
2201  }
2202 
2203  TString histotitle;
2204  GenerateHistoTitle(histotitle, fLeafExpr, "");
2205 
2206  KVDalitzPlot* h = 0;
2207  if (fUserBinning) h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data(), fOrderedDalitz, fNxD, 0., 1.2, fNyD, 0., 1.2);
2208  else h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data());
2209  fHistoNumber++;
2210 
2211  TEntryList* el = fChain->GetEntryList();
2212  if (el) el->GetEntry(0);
2214 
2215  if (el) nentries = el->GetN();
2216  for (int i = 0; i < nentries; i++) {
2217  Int_t j = i;
2218  if (el) j = el->Next();
2219  fTree->GetEntry(j);
2220  if (xType.Contains("Int_t")) {
2221  x = vari1;
2222  y = vari2;
2223  z = vari3;
2224  }
2225  else if (xType.Contains("Short_t")) {
2226  x = vars1;
2227  y = vars2;
2228  z = vars3;
2229  }
2230  else if (xType.Contains("Char_t")) {
2231  x = varc1;
2232  y = varc2;
2233  z = varc3;
2234  }
2235  else if (xType.Contains("Double_t")) {
2236  x = var1;
2237  y = var2;
2238  z = var3;
2239  }
2240  else if (xType.Contains("Float_t")) {
2241  x = varf1;
2242  y = varf2;
2243  z = varf3;
2244  }
2245  h->FillAsDalitz(x, y, z);
2246  }
2247 
2248  h->SetOption("col");
2249  h->SetDirectory(0);
2250  AddHisto((TH2F*)h);
2251  DrawHisto(h);
2253 
2254 }
2255 
2256 
2257 
2262 
2264 {
2265  // Open dialogue box for user to fill required weight for histo
2266  //
2267  // returns false if Cancel button is pressed
2268 
2269  KVNameValueList params{{"Weight", ""}};
2270  Bool_t cancel_pressed{false};
2271  auto s = new KVNameValueListGUI(GetMainWindow(), &params, &cancel_pressed);
2272  s->DisplayDialog();
2273  // cancel was pressed ?
2274  if (cancel_pressed) return false;
2275  fWeight = params.GetStringValue("Weight");
2276  return true;
2277 }
2278 
2279 
2280 
2283 
2285 {
2286  // Method called when user double-clicks a leaf/alias in list
2287 
2288  if (fUserWeight) {
2289  if (!DefineWeight()) return;
2290  }
2291 
2292  TH1* histo = nullptr;
2293  if (obj->InheritsFrom("TLeaf")) {
2294  TLeaf* leaf = (TLeaf*)fChain->GetListOfLeaves()->FindObject(obj->GetName());//dynamic_cast<TLeaf*>(obj);
2295  TString expr = leaf->GetName();
2296  TString type = leaf->GetTypeName();
2297  // check histo not already in list
2298  TString htit;
2299  if (fUserWeight) GenerateHistoTitle(htit, expr, "", fWeight);
2300  else GenerateHistoTitle(htit, expr, "");
2301  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2302  if (kvhisto) histo = kvhisto->GetHisto();
2303  if (!histo) {
2304  if (type.Contains("Int_t") || type.Contains("Char_t") || type.Contains("Short_t") || type == "Long_t" || type == "Long64_t") {
2305  Int_t xmin = GetTreeMinimum(expr);
2306  Int_t xmax = GetTreeMaximum(expr);
2307  if (type.Contains("Char_t")) {
2308  TString tmp;
2309  tmp.Form("int(%s)", expr.Data());
2310  expr = tmp.Data();
2311  }
2312  histo = MakeIntHisto(expr, "", xmin, xmax, (fUserWeight ? fWeight.Data() : ""));
2313  if (!histo) return;
2314  histo->GetXaxis()->SetTitle(leaf->GetName());
2315  }
2316  else {
2317  histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2318  if (!histo) return;
2319  histo->GetXaxis()->SetTitle(leaf->GetName());
2320  }
2321  if (!histo) return;
2322  }
2323  DrawHisto(histo);
2324  }
2325  else {
2326  TString expr = obj->GetTitle();
2327  // check histo not already in list
2328  TString htit;
2329  GenerateHistoTitle(htit, expr, "", (fUserWeight ? fWeight.Data() : ""));
2330  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2331  if (kvhisto) histo = kvhisto->GetHisto();
2332  if (!histo) histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2333  if (!histo) return;
2334  histo->GetXaxis()->SetTitle(obj->GetTitle());
2335  DrawHisto(histo);
2336  }
2337 }
2338 
2339 
2340 
2343 
2345 {
2346  // Method called when user histo selection changes in GUI histogram list
2347 
2352  if (fSelectedHistos) {
2353  if (fSelectedHistos->GetEntries() > 0) {
2355  if (fSelectedHistos->GetEntries() == 1 && fSelectedHistos->First()->IsA() == TH1F::Class()) {
2356  }
2358  }
2359  }
2360 }
2361 
2362 
2363 
2365 
2367 {
2369 }
2370 
2371 
2372 
2375 
2377 {
2378  // Look for selection in list of selections
2379  return (TEntryList*)fSelections.FindObjectByTitle(selection);
2380 }
2381 
2382 
2384 
2386 {
2387  fPROOFEnabled = yes;
2388  if (yes) {
2389  // open new PROOF-lite session
2390  if (!gProof) TProof::Open("");
2391  if (fChain) fChain->SetProof(kTRUE);
2392  }
2393  else {
2394  if (fChain) fChain->SetProof(kFALSE);
2395  }
2396 }
2397 
2398 
2399 
2401 
2403 {
2404  Info("Save", "Saving analysis %s in file %s", GetTitle(), fSaveAnalysisFileName.Data());
2407 }
2408 
2409 
2410 
2417 
2418 void KVTreeAnalyzer::SaveAs(const char* filename, Option_t*) const
2419 {
2420  // Override TObject::SaveAs
2421  // We need to:
2422  // - (re)create the file
2423  // - do fChain->SetDirectory before writing to disk
2424 
2425  // save current directory
2426  TDirectory* sav = gDirectory;
2427  TDirectory* chsav = (fChain ? fChain->GetDirectory() : nullptr);
2428 
2429  TFile* f = TFile::Open(filename, "recreate");
2430  Write();
2431  if (fChain) { // make sure TChain doesn't get redirected
2432  fChain->SetDirectory(chsav);
2433  }
2434  delete f;
2435 
2436  // back to original directory
2437  sav->cd();
2438 }
2439 
2440 
2441 // void KVTreeAnalyzer::FitGum1()
2442 // {
2443 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2444 // if(!histo) return;
2445 // GDfirst->SetParameters(histo->GetMean(),histo->GetRMS());
2446 // histo->Fit(GDfirst,"EM");
2447 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2448 // if(!stats){
2449 // histo->SetStats(1);
2450 // histo->Draw();
2451 // gPad->Update();
2452 // stats = (TPaveStats*)histo->FindObject("stats");
2453 // }
2454 // if(stats){
2455 // // if canvas's 'no stats' option has been set by user,
2456 // // there will still be no valid stats object,
2457 // // so this test is to avoid the ensuing seg fault
2458 // stats->SetFitFormat("10.9g");
2459 // stats->SetOptFit(111);
2460 // }
2461 // histo->SetOption("e1");
2462 // histo->SetMarkerStyle(24);
2463 // histo->SetMarkerColor(kBlue+2);
2464 // gPad->Modified();gPad->Update();
2465 // SetAnalysisModifiedSinceLastSave(kTRUE);
2466 // }
2467 // void KVTreeAnalyzer::FitGum2()
2468 // {
2469 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2470 // if(!histo) return;
2471 // GDsecond->SetParameters(histo->GetMean(),histo->GetRMS());
2472 // histo->Fit(GDsecond,"EM");
2473 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2474 // if(!stats){
2475 // histo->SetStats(1);
2476 // histo->Draw();
2477 // gPad->Update();
2478 // stats = (TPaveStats*)histo->FindObject("stats");
2479 // }
2480 // if(stats){
2481 // // if canvas's 'no stats' option has been set by user,
2482 // // there will still be no valid stats object,
2483 // // so this test is to avoid the ensuing seg fault
2484 // stats->SetFitFormat("10.9g");
2485 // stats->SetOptFit(111);
2486 // }
2487 // histo->SetOption("e1");
2488 // histo->SetMarkerStyle(24);
2489 // histo->SetMarkerColor(kBlue+2);
2490 // gPad->Modified();gPad->Update();
2491 // SetAnalysisModifiedSinceLastSave(kTRUE);
2492 // }
2493 // void KVTreeAnalyzer::FitGum3()
2494 // {
2495 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2496 // if(!histo) return;
2497 // GDthird->SetParameters(histo->GetMean(),histo->GetRMS());
2498 // histo->Fit(GDthird,"EM");
2499 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2500 // if(!stats){
2501 // histo->SetStats(1);
2502 // histo->Draw();
2503 // gPad->Update();
2504 // stats = (TPaveStats*)histo->FindObject("stats");
2505 // }
2506 // if(stats){
2507 // // if canvas's 'no stats' option has been set by user,
2508 // // there will still be no valid stats object,
2509 // // so this test is to avoid the ensuing seg fault
2510 // stats->SetFitFormat("10.9g");
2511 // stats->SetOptFit(111);
2512 // }
2513 // histo->SetOption("e1");
2514 // histo->SetMarkerStyle(24);
2515 // histo->SetMarkerColor(kBlue+2);
2516 // gPad->Modified();gPad->Update();
2517 // SetAnalysisModifiedSinceLastSave(kTRUE);
2518 // }
2519 // void KVTreeAnalyzer::FitGausGum1()
2520 // {
2521 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2522 // if(!histo) return;
2523 // GausGum1->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2524 // histo->Fit(GausGum1,"EM");
2525 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2526 // if(!stats){
2527 // histo->SetStats(1);
2528 // histo->Draw();
2529 // gPad->Update();
2530 // stats = (TPaveStats*)histo->FindObject("stats");
2531 // }
2532 // if(stats){
2533 // // if canvas's 'no stats' option has been set by user,
2534 // // there will still be no valid stats object,
2535 // // so this test is to avoid the ensuing seg fault
2536 // stats->SetFitFormat("10.9g");
2537 // stats->SetOptFit(111);
2538 // }
2539 // histo->SetOption("e1");
2540 // histo->SetMarkerStyle(24);
2541 // histo->SetMarkerColor(kBlue+2);
2542 // gPad->Modified();gPad->Update();
2543 // SetAnalysisModifiedSinceLastSave(kTRUE);
2544 // }
2545 //
2546 // void KVTreeAnalyzer::FitGausGum2()
2547 // {
2548 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2549 // if(!histo) return;
2550 // GausGum2->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2551 // histo->Fit(GausGum2,"EM");
2552 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2553 // if(!stats){
2554 // histo->SetStats(1);
2555 // histo->Draw();
2556 // gPad->Update();
2557 // stats = (TPaveStats*)histo->FindObject("stats");
2558 // }
2559 // if(stats){
2560 // // if canvas's 'no stats' option has been set by user,
2561 // // there will still be no valid stats object,
2562 // // so this test is to avoid the ensuing seg fault
2563 // stats->SetFitFormat("10.9g");
2564 // stats->SetOptFit(111);
2565 // }
2566 // histo->SetOption("e1");
2567 // histo->SetMarkerStyle(24);
2568 // histo->SetMarkerColor(kBlue+2);
2569 // gPad->Modified();gPad->Update();
2570 // SetAnalysisModifiedSinceLastSave(kTRUE);
2571 // }
2572 //
2573 // void KVTreeAnalyzer::FitGausGum3()
2574 // {
2575 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2576 // if(!histo) return;
2577 // GausGum3->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2578 // histo->Fit(GausGum3,"EM");
2579 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2580 // if(!stats){
2581 // histo->SetStats(1);
2582 // histo->Draw();
2583 // gPad->Update();
2584 // stats = (TPaveStats*)histo->FindObject("stats");
2585 // }
2586 // if(stats){
2587 // // if canvas's 'no stats' option has been set by user,
2588 // // there will still be no valid stats object,
2589 // // so this test is to avoid the ensuing seg fault
2590 // stats->SetFitFormat("10.9g");
2591 // stats->SetOptFit(111);
2592 // }
2593 // histo->SetOption("e1");
2594 // histo->SetMarkerStyle(24);
2595 // histo->SetMarkerColor(kBlue+2);
2596 // gPad->Modified();gPad->Update();
2597 // SetAnalysisModifiedSinceLastSave(kTRUE);
2598 // }
2599 
2600 
2605 
2607 {
2608  // fill and return TList with histos containing the given data
2609  // which may be 1D ("mult", "zmax", etc.) or 2D ("zmax:mult")
2610  // DELETE LIST AFTER USE
2611  TList* hlist = new TList;
2612  TIter next(&fHistolist);
2613 
2614  KVHistogram* h;
2615  while ((h = (KVHistogram*)next())) {
2616 
2617  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr)) hlist->Add(h->GetHisto());
2618  }
2619  return hlist;
2620 }
2621 
2622 
2623 
2627 
2629 {
2630  // fill and return TList with histos using the given selection criteria
2631  // DELETE LIST AFTER USE
2632  TList* hlist = new TList;
2633  TIter next(&fHistolist);
2634 
2635  KVHistogram* h;
2636  while ((h = (KVHistogram*)next())) {
2637 
2638  if (h->IsType("Histo") && !strcmp(h->GetSelection(), expr)) hlist->Add(h->GetHisto());
2639  }
2640  return hlist;
2641 }
2642 
2643 
2644 
2646 
2647 TH1* KVTreeAnalyzer::GetHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2648 {
2649  TIter next(&fHistolist);
2650 
2651  KVHistogram* h;
2652  while ((h = (KVHistogram*)next())) {
2653 
2654  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection)) {
2655  if (strcmp(weight, "")) {
2656  if (!strcmp(h->GetWeight(), weight)) return h->GetHisto();
2657  }
2658  else return h->GetHisto();
2659  }
2660  }
2661  return 0;
2662 }
2663 
2664 
2665 
2667 
2669 {
2670  return (KVHistogram*)fHistolist.FindObjectWithMethod(title, "GetHistoTitle");
2671 }
2672 
2673 
2674 
2676 
2677 void KVTreeAnalyzer::DeleteHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2678 {
2679  TIter next(&fHistolist);
2680 
2681  KVHistogram* h;
2682  while ((h = (KVHistogram*)next())) {
2683 
2684  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection) && !strcmp(h->GetWeight(), weight)) {
2685  fHistolist.Remove(h);
2686  delete h;
2688  }
2689  }
2691 }
2692 
2693 
2694 
2697 
2699 {
2700  // Delete all currently selected histograms
2701  if (fSelectedHistos) {
2702  Int_t nsel = fSelectedHistos->GetEntries();
2703  if (nsel < 1) return;
2704  for (int i = 0; i < nsel; i++) {
2705  TObject* obj = fSelectedHistos->At(i);
2706  fHistolist.Remove(obj);
2707  delete obj;
2709  }
2711  }
2713 }
2714 
2715 
2716 
2721 
2723 {
2724  // Called when G_histo_add button is pressed
2725  // There should be 2 histograms in fSelectedHistos
2726  // We assume that both are of same type and have same binning etc.
2727 
2728  if (fSelectedHistos->GetEntries() != 2) return;
2729  HistoToAdd1 = dynamic_cast<KVHistogram*>(fSelectedHistos->At(0))->GetHisto();
2730  HistoToAdd2 = dynamic_cast<KVHistogram*>(fSelectedHistos->At(1))->GetHisto();
2731  if (HistoToAdd1 && HistoToAdd2) {
2732  Info("AddSelectedHistos", "Adding %s and %s", HistoToAdd1->GetName(), HistoToAdd2->GetName());
2733  TString name = Form("h%d", fHistoNumber);
2734  TString oldname = HistoToAdd1->GetName();
2735  if (oldname.BeginsWith("I")) name.Prepend("I");
2738  Bool_t ok = KVBase::OpenContextMenu("HistoAddition", this);
2739  if (!ok) {
2740  Info("AddSelectedHistos", "Call to context menu not OK");
2741  delete HistoAddResult;
2742  return;
2743  }
2744  if (MethodNotCalled()) {
2745  Info("AddSelectedHistos", "You pressed cancel");
2746  delete HistoAddResult;
2747  return;
2748  }
2749  ++fHistoNumber;
2751  }
2752  else {
2753  Info("AddSelectedHistos", "Only possible for 2 histograms");
2754  }
2755 }
2756 
2757 
2758 
2760 
2762 {
2763  fMethodCalled = kTRUE;
2765 // TODO: it would be nice to distinguish histograms which are the result of
2766 // adding other histograms together. For the moment they appear identical to
2767 // to the first histogram in terms of variables etc. The following attempt
2768 // doesn't work (can't parse the title correctly)
2769 // TString title;
2770 // title.Form("SUMHIST:{%s,%s}",HistoToAdd1->GetTitle(),HistoToAdd2->GetTitle());
2771 // HistoAddResult->SetTitle(title);
2772 }
2773 
2774 
2775 
2776 
2779 
2781 {
2782  // regenerate entry lists for all selections
2783  TList old_lists;
2784  old_lists.AddAll(&fSelections);
2785  fSelections.Clear();
2787  TIter next(&old_lists);
2788  TEntryList* old_el;
2789  SetEntryList(nullptr);
2790  SelectionChanged();
2791  while ((old_el = (TEntryList*)next())) {
2792  cout << "REGENERATING SELECTION : " << old_el->GetTitle() << endl;
2793  MakeSelection(old_el->GetTitle());
2794  ((TEntryList*)fSelections.Last())->SetReapplyCut(old_el->GetReapplyCut());
2796  }
2797  old_lists.Delete();
2798 }
2799 
2800 
2801 
2803 
2805 {
2806  switch (id) {
2807  case MH_OPEN_CHAIN:
2808  OpenChain();
2809  break;
2810  case MH_OPEN_FILE:
2812  break;
2813  case MH_ADD_FRIEND:
2815  break;
2816  case MH_APPLY_ANALYSIS:
2818  break;
2819  case MH_SAVE_FILE:
2821  break;
2822  case MH_SAVE:
2823  Save();
2824  break;
2825  case MH_CLOSE:
2826  delete fMain_histolist;
2827  GUIClosed();
2828  break;
2829  case MH_QUIT:
2830  // check all analyzers need saving
2831  while (fgAnalyzerList->GetEntries() > 1) {
2832  TIter next(fgAnalyzerList);
2834  do {
2835  tan = (KVTreeAnalyzer*)next();
2836  }
2837  while (tan == this);
2838  tan->AnalysisSaveCheck();
2839  delete tan;
2840  }
2842  gROOT->ProcessLine(".q");
2843  break;
2844 
2845  default:
2846  break;
2847  }
2848 }
2849 
2850 
2852 
2854 {
2855  switch (id) {
2856  case SEL_COMB_AND:
2858  break;
2859 
2860  case SEL_COMB_OR:
2862  break;
2863 
2864  case SEL_DELETE:
2865  DeleteSelections();
2866  break;
2867 
2868  case SEL_UPDATE:
2869  UpdateEntryLists();
2870  break;
2871 
2872  case SEL_GEN_CONST_XSEC:
2873  KVBase::OpenContextMenu("GenerateConstantXSecSelections", this);
2874  break;
2875 
2876  default:
2877  break;
2878  }
2879 }
2880 
2881 
2882 
2884 
2886 {
2887  switch (opt) {
2888  case OPT_PROOF:
2891  EnablePROOF(false);
2892  }
2893  else {
2895  EnablePROOF();
2896  }
2897  }
2898 }
2899 
2900 
2901 
2904 
2906 {
2907  // Open a previous analysis session
2908 
2909  static TString dir(".");
2910  const char* filetypes[] = {
2911  "Analysis files", "Analysis*.root",
2912  0, 0
2913  };
2914  TGFileInfo fi;
2915  fi.fFileTypes = filetypes;
2916  fi.fIniDir = StrDup(dir);
2917  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2918  if (fi.fFilename) {
2919  KVTreeAnalyzer* newAnal = this;
2920  if (fTree) newAnal = new KVTreeAnalyzer(kFALSE);
2921  newAnal->OpenAnyFile(fi.fFilename);
2922  }
2923  dir = fi.fIniDir;
2924 }
2925 
2926 
2927 
2929 
2931 {
2932  static TString dir(".");
2933  const char* filetypes[] = {
2934  "ROOT files", "*.root",
2935  0, 0
2936  };
2937  TGFileInfo fi;
2938  fi.fFileTypes = filetypes;
2939  fi.fIniDir = StrDup(dir);
2940  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2941  if (fi.fFilename) {
2943  }
2944  dir = fi.fIniDir;
2945 }
2946 
2947 
2950 
2952 {
2953  // Open a file or files containing TTrees to analyse
2954 
2955  static TString dir(".");
2956  const char* filetypes[] = {
2957  "ROOT files", "*.root*",
2958  0, 0
2959  };
2960  TGFileInfo fi;
2961  fi.fFileTypes = filetypes;
2962  fi.fIniDir = StrDup(dir);
2964  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2965  if (fi.fFileNamesList && fi.fFileNamesList->GetEntries()) {
2966 
2967  // look in first file to find first TTree and use its name/title
2968  TString theTreeName, theTreeTitle;
2970  KVUnownedList keys;
2971  keys.AddAll(file->GetListOfKeys());
2972  // Get list of trees in file
2973  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
2974  if (trees->GetEntries()) {
2975  theTreeName = trees->First()->GetName();
2976  theTreeTitle = trees->First()->GetTitle();
2977  }
2978  if (theTreeName != "") {
2979  // if analysis already en cours, open new GUI
2980  KVTreeAnalyzer* newAnal = this;
2981  if (fTree) newAnal = new KVTreeAnalyzer(kFALSE);
2982  newAnal->OpenChain(theTreeName, theTreeTitle, fi.fFileNamesList);
2983  if (fi.fFileNamesList->GetEntries() == 1) {
2984  // if a single file is selected, look to see if any histograms are in it
2985  newAnal->GetHistosFromFile(file, keys);
2986  }
2987  }
2988  }
2989  dir = fi.fIniDir;
2990 }
2991 
2992 
2993 
2995 
2997 {
2998  static TString dir(".");
2999  const char* filetypes[] = {
3000  "ROOT files", "*.root",
3001  0, 0
3002  };
3003  TGFileInfo fi;
3004  fi.fFileTypes = filetypes;
3005  fi.fIniDir = StrDup(dir);
3006  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3007  if (fi.fFilename) {
3009  }
3010  dir = fi.fIniDir;
3011 }
3012 
3013 
3014 
3016 
3018 {
3019  const char* filetypes[] = {
3020  "Analysis files", "Analysis*.root",
3021  0, 0
3022  };
3023  TGFileInfo fi;
3024  fi.fFileTypes = filetypes;
3027  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDSave, &fi);
3028  if (fi.fFilename) {
3029  //if no ".xxx" ending given, we add ".root"
3030  TString filenam(fi.fFilename);
3031  if (!filenam.Contains('.'))
3032  filenam += ".root";
3033  // update name of file to autosave analysis in
3034  fSaveAnalysisFileName = filenam;
3035  Save();
3036  }
3038 }
3039 
3040 
3041 
3043 
3045 {
3046  TIter next(&keys);
3047  TKey* akey;
3048  while ((akey = (TKey*)next())) {
3049  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3050  if (!fHistolist.FindObject(akey->GetName())) {
3051  TH1* h = (TH1*)file->Get(akey->GetName());
3052  h->SetDirectory(0);
3053  fHistolist.Add(new KVHistogram(h));
3054  }
3055  }
3056  }
3058 }
3059 
3060 
3061 
3064 
3065 void KVTreeAnalyzer::OpenSingleFile(TFile* file)
3066 {
3067  // Open TTree in file (as a TChain) and import any histograms found in file
3068 
3069  fHistolist.Clear();
3070  KVUnownedList keys;
3071  keys.AddAll(file->GetListOfKeys());
3072  // Get list of trees in file
3073  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3074  if (trees->GetEntries()) {
3075  // Get name of first tree
3076  TString aTreeName = trees->First()->GetName();
3077  TString aFileName = file->GetName();
3078  TList fileList;
3079  TNamed ff(aFileName.Data(), "File Name");
3080  fileList.Add(&ff);
3081  OpenChain(aTreeName, trees->First()->GetTitle(), &fileList);
3082  }
3083  GetHistosFromFile(file, keys);
3084 }
3085 
3086 
3087 
3091 
3093 {
3094  // assuming filepath is the URL of a ROOT file containing a previously-saved analysis, open it and
3095  // open the KVTreeAnalyzer object stored in it
3096 
3098 
3099  TFile* file = TFile::Open(filepath);
3100  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3101  if (kvta) {
3102  ReadFromFile(file);
3103  }
3104  else {
3105  OpenSingleFile(file);
3106  }
3108 }
3109 
3110 
3111 
3116 
3117 void KVTreeAnalyzer::OpenChain(const TString& treename, const TString& treetitle, const TSeqCollection* files)
3118 {
3119  // Open a TChain for analysis
3120  // treename/title is the name/title of the TTree :)
3121  // files is a list of objects with the names of the files in the chain
3122 
3123  fChain = new TChain(treename, treetitle);
3124  TIter nxt(files);
3125  TObject* o;
3126  while ((o = nxt())) fChain->Add(o->GetName());
3127  fChain->SetDirectory(0);
3128  SetTree(fChain);
3129  fHistolist.Clear();
3130  fSelections.Clear();
3131  fAliasList.Clear();
3132  fHistoNumber = 1;
3133  fSelectionNumber = 1;
3134  fAliasNumber = 1;
3135  fSameColorIndex = 0;
3136  fSelectedSelections = 0;
3137  fSelectedLeaves = 0;
3138  fSelectedHistos = 0;
3142  FillLeafList();
3144 }
3145 
3146 
3147 
3150 
3152 {
3153  // Generate all user aliases in list which are not already defined
3154 
3155  if (list->GetEntries()) {
3156  TIter next(list);
3157  TObject* o;
3158  while ((o = next())) {
3159  if (!GetAlias(o->GetTitle())) {
3160  Info("GenerateAllAliases", "Adding alias %s to leaflist", o->GetTitle());
3162  GenerateAlias();
3163  }
3164  }
3165  }
3166 }
3167 
3168 
3169 
3178 
3180 {
3181  // assuming filepath is the URL of a ROOT file, open it and,
3182  // if no KVTreeAnalyzer object is found, open first TTree in file
3183  // and apply all selections and generate all histograms which
3184  // were made for this analysis.
3185  // Any histograms in the file are added to the list of histograms.
3186  // If filepath contains an existing analysis, we add to it any
3187  // histograms/selections/aliases which are not defined
3188 
3189  TFile* file = TFile::Open(filepath);
3190  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3191  if (kvta) {
3192  // open existing analysis, add any missing histos/selections/aliases
3193  delete file;
3194  KVTreeAnalyzer* applyAnal = OpenFile(filepath);
3195  applyAnal->GenerateAllSelections(&fSelections);
3196  applyAnal->GenerateAllHistograms(&fHistolist);
3197  applyAnal->GenerateAllAliases(&fAliasList);
3198  return;
3199  }
3200  else {
3201  delete file;
3202  KVTreeAnalyzer* applyAnal = new KVTreeAnalyzer(kFALSE);
3203  applyAnal->OpenAnyFile(filepath);
3204  applyAnal->GenerateAllSelections(&fSelections);
3205  applyAnal->GenerateAllHistograms(&fHistolist);
3206  // make sure no selection is left active without being displayed
3207  applyAnal->SetEntryList(nullptr);
3208  applyAnal->G_selection_status->SetText("CURRENT SELECTION:", 0);
3209  applyAnal->GenerateAllAliases(&fAliasList);
3210  }
3211 }
3212 
3213 
3214 
3216 
3217 void KVTreeAnalyzer::SetAlias(const Char_t* name, const Char_t* expr)
3218 {
3219  TString exp = expr;
3220  exp.ReplaceAll("d2r", "TMath::DegToRad()");
3221  exp.ReplaceAll("r2d", "TMath::RadToDeg()");
3222  fAliasList.Add(new TNamed(name, exp.Data()));
3224 }
3225 
3226 
3227 
3229 
3230 static const char* gSaveAsTypes[] = { "PostScript", "*.ps",
3231  "Encapsulated PostScript", "*.eps",
3232  "PDF", "*.pdf",
3233  "SVG", "*.svg",
3234  "TeX", "*.tex",
3235  "GIF", "*.gif",
3236  "ROOT files", "*.root",
3237  "XML", "*.xml",
3238  "PNG", "*.png",
3239  "XPM", "*.xpm",
3240  "JPEG", "*.jpg",
3241  "TIFF", "*.tiff",
3242  "XCF", "*.xcf",
3243  0, 0
3244  };
3245 
3246 
3247 
3252 
3254 {
3255  // Open file dialog box for user to choose directory and
3256  // image file-type for generating picture files of all
3257  // histos as they are drawn
3258 
3259  Info("SetUpHistoAutoSave", "Select image filetype and directory");
3260  TString workdir = gSystem->WorkingDirectory();
3261  static TString dir(".");
3262  static Int_t typeidx = 0;
3263  static Bool_t overwr = kFALSE;
3264  TGFileInfo fi;
3265  fi.fFileTypes = gSaveAsTypes;
3266  fi.fIniDir = StrDup(dir);
3267  fi.fFileTypeIdx = typeidx;
3268  fi.fOverwrite = overwr;
3269  new KVFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kKVFDDirectory, &fi);
3270  gSystem->ChangeDirectory(workdir.Data());
3271  TString ft = fi.fFileTypes[fi.fFileTypeIdx + 1];
3272  dir = fi.fIniDir;
3273  typeidx = fi.fFileTypeIdx;
3274  overwr = fi.fOverwrite;
3275  fAutoSaveDir = dir.Data();
3276  fAutoSaveType = ft(1, ft.Length()).Data();
3277  Info("SetUpHistoAutoSave", "file-type:%s directory:%s", fAutoSaveType.Data(), fAutoSaveDir.Data());
3278 }
3279 
3280 
3281 
3285 
3287 {
3288  // Save currently displayed histo as an image file
3289  // If 'same' checkbox is ticked, we use the same filename as used for the first histogram
3290 
3291  static TString lastFilename = "";
3292 
3293  if (fDrawSame) {
3294  gPad->SaveAs(lastFilename);
3295  return;
3296  }
3297  TString title = h->GetTitle();
3298  title.ReplaceAll(" ", "_");
3299  title.ReplaceAll("/", "#");
3300  title.ReplaceAll("*", "x");
3301  title.ReplaceAll("$", "#");
3302  title.ReplaceAll("(", "[");
3303  title.ReplaceAll(")", "]");
3304  title.Append(fAutoSaveType);
3305  title.Prepend("/");
3306  title.Prepend(fAutoSaveDir);
3307  Info("AutoSaveHisto", "Saved as: %s", title.Data());
3308  gPad->SaveAs(title);
3309  lastFilename = title;
3310 }
3311 
3312 
3313 
3317 
3319 {
3320  // We take the title of every object in 'list' and generate the corresponding selection
3321  // if it does not already exist
3322 
3323  TIter nextSel(list);
3324  TObject* sel;
3325  while ((sel = nextSel())) {
3326  if (!GetSelection(sel->GetTitle())) {
3327  Info("GenerateAllSelections", "Generating selection: %s", sel->GetTitle());
3328  MakeSelection(sel->GetTitle());
3329  }
3330  }
3331 }
3332 
3333 
3334 
3338 
3340 {
3341  // For every histogram in the list, we generate histograms with the same binning for
3342  // the same expression, selection and weight if they don't already exist
3343 
3344  TIter nextHist(list);
3345  KVHistogram* obj;
3346  TH1* hist;
3347  while ((obj = (KVHistogram*)nextHist())) {
3348  if (!obj->IsType("Cut")) {
3349  hist = obj->GetHisto();
3350  if (GetHistoByTitle(hist->GetTitle())) continue;
3351  TString exp = obj->GetExpression();
3352  TString sel = obj->GetSelection();
3353  TString weight = obj->GetWeight();
3354  if (weight == "1") weight = "";
3355  // set selection
3356  Info("GenerateAllHistograms", "Generating histogram: %s", hist->GetTitle());
3357  SetSelection(sel);
3358  RemakeHisto(hist, exp, weight);
3359  }
3360  }
3361 }
3362 
3363 
3364 
3371 
3373 {
3374  // Read serialized object from file
3375  // For versions < 4, fHistolist contained TH* or TCutG objects:
3376  // we convert to a list of KVHistogram objects.
3377  // Flag will be set to say analysis needs saving.
3378  // Reparse all histogram expressions and selections in case they were not saved correctly.
3379 
3380  UInt_t R__s, R__c;
3381  if (R__b.IsReading()) {
3382  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3383  R__b.ReadClassBuffer(KVTreeAnalyzer::Class(), this, R__v, R__s, R__c);
3384  if (R__v < 5) {
3385  // no fChain pointer member before v5
3386  ReconnectTree();
3387  }
3388  if (fChain && fTree != fChain) SetTree(fChain);
3389  if (fChain) {
3391  Info("Streamer", "Checking friends");
3392  // check friends are TChains, not TTrees & they have valid pointers
3393  TFriendElement* fe;
3394  TIter nxt(fChain->GetListOfFriends());
3395  KVNumberList toRemove;
3396  KVNameValueList infos;
3397  int idx = 0;
3398  while ((fe = (TFriendElement*)nxt())) {
3399  if (!fe->GetTree() || (fe->GetTree() && !fe->GetTree()->InheritsFrom("TChain"))) {
3400  Info("Streamer", "Found friend to convert to TChain");
3401  toRemove.Add(idx);
3402  infos.SetValue(Form("treeName%d", idx), fe->GetTreeName());
3403  if (!fe->GetFile()) {
3404  Info("Streamer", "Choose file containg friend tree %s", fe->GetTreeName());
3405  static TString dir(".");
3406  const char* filetypes[] = {
3407  "ROOT files", "*.root",
3408  0, 0
3409  };
3410  TGFileInfo fi;
3411  fi.fFileTypes = filetypes;
3412  fi.fIniDir = StrDup(dir);
3413  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3414  if (fi.fFilename) {
3415  infos.SetValue(Form("fileName%d", idx), fi.fFilename);
3416  }
3417  dir = fi.fIniDir;
3418  }
3419  else
3420  infos.SetValue(Form("fileName%d", idx), fe->GetFile()->GetName());
3421  }
3422  ++idx;
3423  }
3424  if (toRemove.GetEntries()) {
3425  Info("Streamer", "Removing TTree friends");
3426  toRemove.Begin();
3427  while (!toRemove.End()) {
3428  fChain->RemoveFriend(fChain->GetFriend(infos.GetStringValue(Form("treeName%d", toRemove.Next()))));
3429  }
3430  toRemove.Begin();
3431  Info("Streamer", "Adding friends as TChains");
3432  while (!toRemove.End()) {
3433  idx = toRemove.Next();
3434  TChain* friendChain = new TChain(infos.GetStringValue(Form("treeName%d", idx)));
3435  friendChain->Add(infos.GetStringValue(Form("fileName%d", idx)));
3436  fChain->AddFriend(friendChain);
3437  }
3438  }
3439  }
3440  }
3441  if (R__v < 4) {
3442  //Info("Streamer","Converting old histo list");
3443  // convert fHistolist
3444  if (fHistolist.GetEntries()) {
3445  TList tmp;
3446  tmp.AddAll(&fHistolist);
3447  //Info("Streamer","List of histos to import:");
3448  //tmp.ls();
3449  fHistolist.SetOwner(kFALSE);
3450  fHistolist.Clear();
3451  fHistolist.SetOwner(kTRUE);
3452  TNamed* obj;
3453  TIter next(&tmp);
3454  while ((obj = (TNamed*)next())) {
3455  if (obj->InheritsFrom("TCutG"))
3456  fHistolist.Add(new KVHistogram(dynamic_cast<TCutG*>(obj)));
3457  else if (obj->InheritsFrom("TH1"))
3458  fHistolist.Add(new KVHistogram(dynamic_cast<TH1*>(obj)));
3459  }
3460  //Info("Streamer","New histolist:");
3461  fHistolist.ls();
3463  }
3464  }
3465  if (fHistolist.GetEntries()) {
3466  TIter next(&fHistolist);
3467  KVHistogram* h;
3468  while ((h = (KVHistogram*)next())) {
3469  if (h->IsType("Histo")) h->ParseExpressionAndSelection();
3470  }
3471  }
3472  }
3473  else {
3475  }
3476 }
3477 
3478 
3479 
3484 
3486 {
3487  // assuming filepath is the URL of a ROOT file, open it and
3488  // add the first TTree found in file as a friend of the current TTree
3489  // Any histograms in the file are added to the list of histograms
3490 
3491  TFile* file = TFile::Open(filepath);
3492  KVList keys(0);
3493  keys.AddAll(file->GetListOfKeys());
3494  // Get list of trees in file
3495  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3496  if (trees->GetEntries()) {
3497  // Get name of first tree
3498  TString aTreeName = trees->First()->GetName();
3499  TChain* t = new TChain(aTreeName);
3500  t->Add(filepath);
3501  fChain->AddFriend(t);
3502  FillLeafList();
3503  }
3504  TIter next(&keys);
3505  TKey* akey;
3506  while ((akey = (TKey*)next())) {
3507  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3508  if (!fHistolist.FindObject(akey->GetName())) {
3509  TH1* h = (TH1*)file->Get(akey->GetName());
3510  h->SetDirectory(0);
3511  fHistolist.Add(new KVHistogram(h));
3512  }
3513  }
3514  }
3516 }
3517 
3518 
3519 
3520 
3521 
3522 
int Int_t
unsigned int UInt_t
unsigned long ULong_t
kVerticalFrame
kHorizontalFrame
kMainFrame
#define SafeDelete(p)
#define f(i)
#define c(i)
#define e(i)
bool Bool_t
short Version_t
char Char_t
float Float_t
short Short_t
constexpr Bool_t kFALSE
double Double_t
constexpr Bool_t kTRUE
const char Option_t
kRed
kOrange
kGreen
kCyan
kBlue
kViolet
#define X(type, name)
#define gDirectory
R__EXTERN TEnv * gEnv
EButtonState
#define gClient
kFDOpen
kFDSave
kDeepCleanup
kLHintsExpandY
kLHintsLeft
kLHintsCenterY
kLHintsCenterX
kLHintsTop
kLHintsExpandX
kMBNo
kMBClose
kMBYes
kMBDismiss
kMBIconExclamation
kMBIconStop
kTextCenterX
kTextLeft
kTextRight
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t sel
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t g
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
float xmin
int nentries
float ymin
float xmax
float ymax
R__EXTERN TProof * gProof
#define gROOT
char * Form(const char *fmt,...)
char * StrDup(const char *str)
void AssignAndDelete(TString &target, char *tobedeleted)
R__EXTERN TSystem * gSystem
#define gPad
virtual Bool_t IsType(const Char_t *typ) const
Definition: KVBase.h:185
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:54
Fill 3D observables in a dalitz plot ,.
Definition: KVDalitzPlot.h:28
Modified version of TGFileDialog file selection dialog.
Definition: KVFileDialog.h:49
Wrapper for histograms and graphical cuts used by KVTreeAnalyzer.
Definition: KVHistogram.h:20
TCutG * GetCut() const
Definition: KVHistogram.h:41
static void ParseHistoTitle(const Char_t *title, KVString &exp, KVString &sel, KVString &weight)
const Char_t * GetExpression() const
Bool_t IsProfile() const
Definition: KVHistogram.h:45
const Char_t * GetSelection() const
TH1 * GetHisto() const
Definition: KVHistogram.h:37
const Char_t * GetWeight() const
Return weighting used for filling histogram.
Bool_t IsTH2() const
Definition: KVHistogram.h:49
virtual void SetIsBoolean(Bool_t isit=kTRUE)
Definition: KVLVContainer.h:88
Extension of TGLVContainer for KVListView widget.
Enhanced version of ROOT TGListView widget.
Definition: KVListView.h:146
virtual void ActivateSortButtons()
Definition: KVListView.cpp:72
virtual void SetDataColumns(Int_t ncolumns)
Definition: KVListView.cpp:91
void SetDoubleClickAction(const char *receiver_class, void *receiver, const char *slot)
Definition: KVListView.cpp:210
virtual KVLVColumnData * GetDataColumn(Int_t index) const
Definition: KVListView.h:168
virtual void Display(const TCollection *l)
Definition: KVListView.h:173
virtual void SetMaxColumnSize(UInt_t width)
Definition: KVListView.h:161
KVList * GetPickOrderedSelectedObjects() const
Definition: KVListView.h:251
TList * GetSelectedObjects() const
Definition: KVListView.h:245
virtual void RemoveAll()
Definition: KVListView.h:190
void AllowContextMenu(Bool_t on=kTRUE)
Definition: KVListView.h:283
virtual void SetDataColumn(Int_t index, const Char_t *name, const Char_t *method="", Int_t mode=kTextCenterX)
Definition: KVListView.cpp:106
void SetUseObjLabelAsRealClass(Bool_t yes=kTRUE)
Definition: KVListView.cpp:189
Extended TList class which owns its objects by default.
Definition: KVList.h:28
GUI for setting KVNameValueList parameters.
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
void SetValue(const Char_t *name, value_type value)
const Char_t * GetStringValue(const Char_t *name) const
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:85
Bool_t End(void) const
Definition: KVNumberList.h:199
void Begin(void) const
Int_t GetEntries() const
Definition: KVNumberList.h:171
void Add(Int_t)
Add value 'n' to the list.
Int_t Next(void) const
KaliVeda extensions to ROOT collection classes.
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:73
GUI for simple intuitive analysis of data in TTree ,.
void DeleteHisto(const Char_t *expr, const Char_t *selection, const Char_t *weight)
Int_t fSelectionNumber
used for automatic naming of selections
Bool_t IsPROOFEnabledForSelections() const
Bool_t fNoGui
=kTRUE if no graphical interface is required
static KVTreeAnalyzer * OpenFile(const Char_t *filename, Bool_t nogui=kFALSE)
TList * GetHistosByData(const Char_t *expr)
KVHistogram * GetHistoByTitle(const Char_t *title)
TChain * fChain
the analyzed TTree or TChain
Bool_t fNormHisto
=kTRUE: generate normalised histograms (normalise to integral of histo)
TGCheckButton * G_histo_norm
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
double GetTreeMinimum(const TString &leafname)
static KVList * fgAnalyzerList
static list of all analyzers in memory
TString fTreeFileName
name of file containing analyzed TTree
void DeleteSelectedHisto()
Delete all currently selected histograms.
void GUIClosed()
Called when graphical window is closed.
TEntryList * GetSelection(const Char_t *)
Look for selection in list of selections.
Bool_t IsCurrentSelection(const Char_t *sel)
void AutoSaveHisto(TH1 *h)
TGTextEntry * G_alias_text
TGPopupMenu * fSelCombMenu
Bool_t fNewCanvas
=kTRUE: draw each histogram in a new canvas
void init()
Default initialization.
TString fRelativePathToAnalysisFile
TGCheckButton * G_histo_log
void AddHisto(TH1 *)
TGComboBox * G_histo_draw_option
KVUniqueNameList fSelections
list of TEntryList user selections
void GenerateAllHistograms(TCollection *)
Bool_t fNormHistoEvents
=kTRUE: generate normalised histograms (normalise to number of events)
void SetSelection(TObject *)
void CurrentSelection()
Print the currently active selection (TEntryList set on TTree).
KVList fLeafList
clones of leaves in TChain
TGCheckButton * G_histo_weight
void UpdateEntryLists()
regenerate entry lists for all selections
TGCheckButton * G_histo_prof
void SetEntryList(TEntryList *)
void DrawCut(TCutG *)
void HistoAddition(Double_t c1=1, Double_t c2=1)
void OpenGUI()
Launch the GUI (unless fNoGui=kTRUE in which case this does nothing)
void HistoFileMenu_OpenFriend()
TGPictureButton * G_histo_add
void SetRelativePathToAnalysisFile(const Char_t *p)
TGPictureButton * G_histo_del
TGCheckButton * G_histo_stats
KVTreeAnalyzer(Bool_t nogui=kTRUE)
TGCheckButton * G_histo_new_can
void HandleHistoFileMenu(Int_t)
TGCheckButton * G_histo_bin
void HandleOptionsMenu(Int_t opt)
TGGroupFrame * fMain_selectionlist
GUI for handling selections.
TList * fSelectedHistos
void GetHistosFromFile(TFile *file, const KVUnownedList &keys)
TString fSaveAnalysisFileName
void AddCut(TCutG *)
TGPopupMenu * fMenuSelections
Bool_t MethodNotCalled()
TGPictureButton * G_leaf_draw
Bool_t fAutoSaveHisto
=kTRUE: on draw, generate image file of current displayed histo
void HandleSelectionsMenu(Int_t)
void DrawHistogram(TH1 *histo, Bool_t same=false, Bool_t logscale=false)
void EnablePROOF(Bool_t yes=kTRUE)
KVList fHistolist
list of generated histograms
TGPopupMenu * fMenuFile
TList * GetHistosBySelection(const Char_t *expr)
void OpenAnyFriendFile(const Char_t *filepath)
TTree * fTree
for backwards compatibility
TGCheckButton * G_histo_norm_events
void GenerateAllSelections(TCollection *)
For applying existing analysis to new data.
TGPopupMenu * fSelGenerate
TString fAutoSaveType
filetype for autosaving histos
TH1 * GetHistogram(const Char_t *name) const
Return histogram with given name.
TGPopupMenu * fOptionMenu
Long64_t GetEntriesInCurrentSelection() const
KVListView * G_selectionlist
GUI list of TEntryList selections.
double GetTreeMaximum(const TString &leafname)
TGLabel * G_leaf_expr
TGStatusBar * G_selection_status
status bar in selections GUI
void AddSelection(TEntryList *)
TGLayoutHints * fMenuBarItemLayout
TGCheckButton * G_histo_same
TH1 * MakeIntHisto(const Char_t *expr, const Char_t *selection, Int_t Xmin, Int_t Xmax, const Char_t *weight="")
virtual ~KVTreeAnalyzer()
Destructor.
void OpenChain()
Open a file or files containing TTrees to analyse.
void SelectionChanged()
Method called whenever the selected selection in the GUI list changes.
TGMainFrame * fMain_histolist
GUI for handling histograms.
TH1 * GetHisto(const Char_t *expr, const Char_t *selection, const Char_t *weight="")
Bool_t fAnalysisModifiedSinceLastSave
TNamed * GetAlias(const Char_t *expr)
void HistoSelectionChanged()
Method called when user histo selection changes in GUI histogram list.
void GenerateHistoTitle(TString &title, const Char_t *exp, const Char_t *sel, const Char_t *weight="")
void ReadFromFile(const Char_t *filename)
open a previously saved analysis session.
Bool_t fDrawLog
=kTRUE: draw histograms with log-Y (1-D) or log-Z (2-D) scale
void HistoFileMenu_Open()
Open a previous analysis session.
void DrawLeaf(TObject *)
Method called when user double-clicks a leaf/alias in list.
KVList fAliasList
list of TTree aliases
TList * fSelectedSelections
void 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:17
virtual void SetLineWidth(Width_t lwidth)
virtual void SetLineColor(Color_t lcolor)
Double_t GetXmax() const
Double_t GetXmin() const
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=nullptr)=0
Bool_t IsReading() const
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
void SetEntryList(TEntryList *elist, Option_t *opt="") override
TFriendElement * AddFriend(const char *chainname, const char *dummy="") override
TObjArray * GetListOfLeaves() override
virtual Int_t Add(const char *name, Long64_t nentries=TTree::kMaxEntries)
void RemoveFriend(TTree *) override
void SetDirectory(TDirectory *dir) override
Long64_t Draw(const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0) override
virtual void SetProof(Bool_t on=kTRUE, Bool_t refresh=kFALSE, Bool_t gettreeheader=kFALSE)
Long64_t GetEntries() const override
static TClass * GetClass(Bool_t load=kTRUE, Bool_t silent=kFALSE)
Bool_t InheritsFrom(const char *cl) const override
void ls(Option_t *option="") const override
virtual void AddAll(const TCollection *col)
virtual Int_t GetEntries() const
TObject * Clone(const char *newname="") const override
const char * GetVarX() const
static TClass * Class()
const char * GetVarY() const
virtual Bool_t cd()
static TClass * Class()
virtual Bool_t GetReapplyCut() const
virtual Long64_t Next()
virtual Long64_t GetEntry(Long64_t index)
virtual Long64_t GetN() const
virtual const char * GetValue(const char *name, const char *dflt) const
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
virtual const char * GetTreeName() const
virtual TTree * GetTree()
virtual TFile * GetFile()
virtual void SetToolTipText(const char *text, Long_t delayms=400)
virtual void SetEnabled(Bool_t e=kTRUE)
TGFrame * GetContainer() const
void SetState(EButtonState state, Bool_t emit=kFALSE) override
virtual void AddEntry(const char *s, Int_t id)
TGDimension GetDefaultSize() const override
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=nullptr)
void MapSubwindows() override
void SetCleanup(Int_t mode=kLocalCleanup) override
TList * fFileNamesList
char * fFilename
void SetMultipleSelection(Bool_t option)
Int_t fFileTypeIdx
const char ** fFileTypes
char * fIniDir
Bool_t fOverwrite
virtual UInt_t GetDefaultHeight() const
virtual void Resize(TGDimension size)
TGDimension GetSize() const
void MapWindow() override
TGDimension GetDefaultSize() const override
void SetText(const char *newText)
const char * GetTitle() const override
void SetIconPixmap(char **xpm_array)
void SetIconName(const char *name)
void SetWindowName(const char *name=nullptr) override
virtual void AddPopup(const char *s, TGPopupMenu *menu, TGLayoutHints *l, TGPopupMenu *before=nullptr)
virtual Bool_t IsEntryChecked(Int_t id)
virtual void CheckEntry(Int_t id)
virtual void DisableEntry(Int_t id)
virtual void EnableEntry(Int_t id)
virtual void AddEntry(const char *s, Int_t id, void *ud=nullptr, const TGPicture *p=nullptr, TGMenuEntry *before=nullptr)
virtual void UnCheckEntry(Int_t id)
virtual void AddSeparator(TGMenuEntry *before=nullptr)
virtual void AddPopup(const char *s, TGPopupMenu *popup, TGMenuEntry *before=nullptr, const TGPicture *p=nullptr)
virtual void SetText(const char *text, Int_t partidx=0)
virtual void SetMaxLength(Int_t maxlen)
void Clear(Option_t *option="") override
const char * GetText() const
virtual void SetCursorPosition(Int_t pos)
virtual void SetAlignment(ETextJustification mode=kTextLeft)
virtual void SetText(const char *text, Bool_t emit=kTRUE)
Int_t MaxMark() const
Int_t MinMark() const
virtual void SetName(const char *name)
virtual void RaiseWindow()
void Draw(Option_t *chopt="") override
void SetTitle(const char *title="") override
static TClass * Class()
virtual void SetDirectory(TDirectory *dir)
virtual Bool_t Add(const TH1 *h, const TH1 *h2, Double_t c1=1, Double_t c2=1)
void SetTitle(const char *title) override
virtual Int_t GetNbinsY() const
Option_t * GetOption() const override
TAxis * GetXaxis()
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
virtual Int_t GetNbinsX() const
virtual void SetMaximum(Double_t maximum=-1111)
TAxis * GetYaxis()
void Draw(Option_t *option="") override
virtual Double_t Integral(Int_t binx1, Int_t binx2, Option_t *option="") const
TClass * IsA() const override
virtual void SetOption(Option_t *option=" ")
virtual void Scale(Double_t c1=1, Option_t *option="")
TObject * Clone(const char *newname="") const override
virtual void Sumw2(Bool_t flag=kTRUE)
virtual void SetStats(Bool_t stats=kTRUE)
virtual const char * GetClassName() const
virtual const char * GetTypeName() const
TBranch * GetBranch() const
TObject * FindObject(const char *name) const override
void Add(TObject *obj) override
TObject * First() const override
void Delete(Option_t *option="") override
TObject * At(Int_t idx) const override
void Copy(TObject &named) const override
virtual void SetTitle(const char *title="")
const char * GetName() const override
void Streamer(TBuffer &) override
const char * GetTitle() const override
static TClass * Class()
TObject * FindObject(const char *name) const override
virtual const char * GetName() const
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
virtual Bool_t InheritsFrom(const char *classname) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual const char * GetTitle() const
virtual TClass * IsA() const
virtual void Info(const char *method, const char *msgfmt,...) const
static TProof * Open(const char *url=0, const char *conffile=0, const char *confdir=0, Int_t loglevel=0)
TList * GetOutputList()
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Ssiz_t Length() const
TString & Insert(Ssiz_t pos, const char *s)
Ssiz_t First(char c) const
const char * Data() const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
TString & Append(char c, Ssiz_t rep=1)
Bool_t IsNull() const
TString & Prepend(char c, Ssiz_t rep=1)
virtual Int_t Sizeof() const
void Form(const char *fmt,...)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
virtual const char * DirName(const char *pathname)
virtual char * ConcatFileName(const char *dir, const char *name)
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
virtual Bool_t ChangeDirectory(const char *path)
virtual const char * BaseName(const char *pathname)
virtual Bool_t IsAbsoluteFileName(const char *dir)
virtual const char * WorkingDirectory()
static void SingleShot(Int_t milliSec, const char *receiver_class, void *receiver, const char *method)
virtual Int_t GetEntry(Long64_t entry, Int_t getall=0)
virtual TObjArray * GetListOfLeaves()
TFile * GetCurrentFile() const
virtual TList * GetListOfAliases() const
virtual TTree * GetFriend(const char *) const
virtual Double_t GetMaximum(const char *columname)
TDirectory * GetDirectory() const
virtual TEntryList * GetEntryList()
virtual Long64_t GetEntries() const
virtual Long64_t Draw(const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
virtual Long64_t GetEntryNumber(Long64_t entry) const
virtual TLeaf * GetLeaf(const char *branchname, const char *leafname)
virtual Double_t GetMinimum(const char *columname)
Int_t SetBranchAddress(const char *bname, T **add, TBranch **ptr=nullptr)
virtual TList * GetListOfFriends() const
virtual void ResetBranchAddresses()
long long Long64_t
RVec< PromoteType< T > > tan(const RVec< T > &v)
RVec< PromoteType< T > > exp(const RVec< T > &v)
Double_t y[n]
return c1
Double_t x[n]
TH1 * h
return c2
TLine l
ClassImp(TPyArg)