KaliVeda  1.12/06
Heavy-Ion Analysis Toolkit
KVTreeAnalyzer.cpp
Go to the documentation of this file.
1 //Created by KVClassFactory on Fri Apr 13 12:31:16 2012
2 //Author: John Frankland
3 
4 #include "KVTreeAnalyzer.h"
5 #include "TString.h"
6 #include "TDirectory.h"
7 #include "TSystem.h"
8 #include "TEntryList.h"
9 #include "Riostream.h"
10 #include "KVCanvas.h"
11 #include "TCutG.h"
12 #include "TLeaf.h"
13 #include "TPaveStats.h"
14 #include "TSystem.h"
15 #include "TPad.h"
16 #include "TKey.h"
17 #include "TROOT.h"
18 #include "TGMsgBox.h"
19 #include "KVFileDialog.h"
20 #include "KVDalitzPlot.h"
21 #include "TEnv.h"
22 #include "TColor.h"
23 #include <KVHistogram.h>
24 #include <KVList.h>
25 #include <TChain.h>
26 #include "TFriendElement.h"
27 #include <TTree.h>
28 #include "TProof.h"
29 
30 using namespace std;
31 
33 
34 
35 
36 /* colours used for displaying several 1-D spectra on same plot */
37 
38 
40 #define MAX_COLOR_INDEX 5
42  kBlue + 2,
43  kRed + 2,
44  kGreen + 3,
45  kCyan - 2,
46  kOrange + 7,
47  kViolet + 2
48 };
49 
50 
52 
54 
55 
58 
60 {
61  // Default initialization
62 
63  gTreeAnalyzer = this;
64  fgAnalyzerList->Add(this);
65  fDeletedByGUIClose = kFALSE;
66 
68  fMain_histolist = 0;
69  fMain_leaflist = 0;
70  fMain_selectionlist = 0;
71  fMenuFile = 0;
72  SetAnalysisModifiedSinceLastSave(kFALSE);
73  fAnalysisSaveDir = ".";
74  fPROOFEnabled = false;
75 
76  fDrawSame = fApplySelection = fProfileHisto = kFALSE;
77  fDrawLog = gEnv->GetValue("KVTreeAnalyzer.LogScale", kFALSE);
78  fUserBinning = gEnv->GetValue("KVTreeAnalyzer.UserBinning", kFALSE);
79  fUserWeight = gEnv->GetValue("KVTreeAnalyzer.UserWeight", kFALSE);
80  fNewCanvas = gEnv->GetValue("KVTreeAnalyzer.NewCanvas", kFALSE);
81  fNormHisto = gEnv->GetValue("KVTreeAnalyzer.NormalizeIntegral", kFALSE);
82  fNormHistoEvents = gEnv->GetValue("KVTreeAnalyzer.NormalizeEvents", kFALSE);
83  fStatsHisto = gEnv->GetValue("KVTreeAnalyzer.Stats", kFALSE);
84  fAutoSaveHisto = kFALSE;
85  fSameColorIndex = 0;
86  fSelectedSelections = 0;
87  fSelectedLeaves = 0;
88  fSelectedHistos = 0;
89  ipscale = 0;
90 // GDfirst=new KVGumbelDistribution("Gum1",1);
91 // GDsecond=new KVGumbelDistribution("Gum2",2);
92 // GDthird=new KVGumbelDistribution("Gum3",3);
93 // GausGum1=new KVGausGumDistribution("GausGum1",1);
94 // GausGum2=new KVGausGumDistribution("GausGum2",2);
95 // GausGum3=new KVGausGumDistribution("GausGum3",3);
96 
97  fNx = fNy = 500;
98  fXmin = fXmax = fYmin = fYmax = -1.;
99  fWeight = "1./(abs(vper))";
100 
101  fNxF = 200;
102  fXminF = fXmaxF = -1.;
103 
104  fNxD = fNyD = 120;
105  fOrderedDalitz = 0;
106 }
107 
108 
109 
114 
116  : TNamed("KVTreeAnalyzer", "KVTreeAnalyzer"), fTree(0), fChain(0), fSelections(kTRUE), fHistoNumber(1), fSelectionNumber(1), fAliasNumber(1), fNoGui(nogui)
117 {
118  // Default constructor - used when loading from a file.
119  // The 'nogui' option (default=kTRUE) controls whether or not to
120  // launch the graphical interface
121 
122  init();
123  OpenGUI();
124 }
125 
126 
127 
128 
133 
135  : TNamed("KVTreeAnalyzer", t->GetTitle()), fTree(0), fChain(0), fSelections(kTRUE), fHistoNumber(1), fSelectionNumber(1), fAliasNumber(1), fNoGui(nogui)
136 {
137  // Initialize analyzer for a given TTree.
138  // (in fact we re-open the tree using a TChain)
139  // If 'nogui' option (default=kFALSE) is kTRUE we do not launch the graphical interface.
140 
141  init();
142  OpenGUI();
143  KVList fl;
144  fl.Add(new TNamed(t->GetCurrentFile()->GetName(), t->GetCurrentFile()->GetName()));
145  OpenChain(t->GetName(), t->GetTitle(), &fl);
146 }
147 
148 
149 
152 
154 {
155  // Destructor
160  if (gTreeAnalyzer == this) gTreeAnalyzer = 0x0;
161  fgAnalyzerList->Remove(this);
162 }
163 
164 
165 
166 
174 
176 {
177  // This method copies the current state of 'this' object into 'obj'
178  // You should add here any member variables, for example:
179  // (supposing a member variable KVTreeAnalyzer::fToto)
180  // CastedObj.fToto = fToto;
181  // or
182  // CastedObj.SetToto( GetToto() );
183 
184  TNamed::Copy(obj);
185  KVTreeAnalyzer& CastedObj = (KVTreeAnalyzer&)obj;
186  fSelections.Copy(CastedObj.fSelections);// list of TEntryList user selections
187  fHistolist.Copy(CastedObj.fHistolist);//list of generated histograms
188  CastedObj.fTreeName = fTreeName;//name of analyzed TTree
189  CastedObj.fTreeFileName = fTreeFileName;//name of file containing analyzed TTree
190  CastedObj.fHistoNumber = fHistoNumber; //used for automatic naming of histograms
191  CastedObj.fSelectionNumber = fSelectionNumber; //used for automatic naming of selections
192  CastedObj.fAliasNumber = fAliasNumber; //used for automatic naming of TTree aliases
193  fAliasList.Copy(CastedObj.fAliasList);//list of TTree aliases
195  CastedObj.fChain = fChain;
196  CastedObj.SetTree(fChain);
197 }
198 
199 
200 
218 
219 void KVTreeAnalyzer::GenerateHistoTitle(TString& title, const Char_t* expr, const Char_t* selection, const Char_t* weight)
220 {
221  // PRIVATE utility method
222  // Encodes the histogram title for the desired expression and an optional selection.
223  // The expression and selection should be valid TTreeFormula strings
224  // (i.e. they use TTree leaves and/or alias names)
225  // If there is already an active selection (TEntryList set on TTree)
226  // then the corresponding selection expression will also be included in the title.
227  // The format of the resulting title string is one of the following:
228  //
229  // "expr1[:expr2]"
230  // "expr1[:expr2] {selection}"
231  // "expr1[:expr2] {active selection}"
232  // "expr1[:expr2] {(active selection) && (selection)}"
233  //
234  // If histogram is weighted, the weight is added such as:
235  //
236  // "expr1:expr2 [weight] {active selection}"
237 
238 
239  TString _selection(selection);
240  TString _elist;
241  if (fChain->GetEntryList()) _elist = fChain->GetEntryList()->GetTitle();
242  if (strcmp(weight, "")) {
243  if (_selection != "" && _elist != "")
244  title.Form("%s [%s] {(%s) && (%s)}", expr, weight, _elist.Data(), selection);
245  else if (_selection != "")
246  title.Form("%s [%s] {%s}", expr, weight, selection);
247  else if (_elist != "")
248  title.Form("%s [%s] {%s}", expr, weight, _elist.Data());
249  else
250  title.Form("%s [%s]", expr, weight);
251  }
252  else {
253  if (_selection != "" && _elist != "")
254  title.Form("%s {(%s) && (%s)}", expr, _elist.Data(), selection);
255  else if (_selection != "")
256  title.Form("%s {%s}", expr, selection);
257  else if (_elist != "")
258  title.Form("%s {%s}", expr, _elist.Data());
259  else
260  title.Form("%s", expr);
261  }
262 }
263 
264 
265 
282 
283 TH1* KVTreeAnalyzer::MakeHisto(const Char_t* expr, const Char_t* selection, Int_t nX, Int_t nY, const Char_t* weight)
284 {
285  // Create and fill a new histogram with the desired expression (expr="expr1[:expr2]" etc.)
286  // with the given selection (selection="" if no selection required).
287  // Any currently active selection (TEntryList set on TTree) will also be applied.
288  // The new histogram is not drawn but added to the internal list of histograms
289  // (see method AddHisto).
290  //
291  // Histograms are automatically named 'h1', 'h2', etc. in order of creation.
292  // Histogram title is generated with method GenerateHistoTitle.
293  // Number of bins on X (and Y for a 2-D spectrum) are given. Axis limits are
294  // automatically adjusted to data.
295  //
296  // For 2-D spectra the initial drawing option is set to "COL"
297  //
298  // If normalisation of spectra is required (fNormHisto = kTRUE) the histogram
299  // bin contents are divided by the integral (sum of weights).
300 
301  TString name;
302  name.Form("h%d", fHistoNumber);
303  TString drawexp(expr), histo, histotitle;
304  if (strcmp(weight, "")) GenerateHistoTitle(histotitle, expr, selection, weight);
305  else GenerateHistoTitle(histotitle, expr, selection);
306  if ((!nY) && (fUserBinning)) {
308  Bool_t ok = KVBase::OpenContextMenu("DefineUserBinning1F", this, "DefineUserBinning");
309  if (!ok) return 0;
310  // cancel was pressed ?
311  if (MethodNotCalled()) return 0;
312  }
313 
314  TString Selection;
315  if (strcmp(weight, "")) {
316  if (strcmp(selection, "")) Selection.Form("(%s)&&(%s)", selection, weight);
317  else Selection = weight;
318  }
319  else
320  Selection = selection;
321  if (nY) histo.Form(">>%s(%d,0.,0.,%d,0.,0.)", name.Data(), nX, nY);
322  else histo.Form(">>%s(%d,%lf,%lf)", name.Data(), (fUserBinning ? fNxF : nX), (fUserBinning ? fXminF : 0.), (fUserBinning ? fXmaxF : 0));
323 
324  if (!fProfileHisto) drawexp += histo;
325  Long64_t drawResult;
326  if (fProfileHisto) drawResult = fTree->Draw(Form("%s>>%s", drawexp.Data(), name.Data()), Selection, "prof,goff");
327  else drawResult = fTree->Draw(drawexp, Selection, "goff");
328  if (drawResult < 0) {
329  // Error with Draw: probably a bad expression
330  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
331  return nullptr;
332  }
333  TH1* h;
334  if (IsPROOFEnabled()) h = (TH1*)gProof->GetOutputList()->FindObject(name);
335  else h = (TH1*)gDirectory->Get(name);
336  h->SetTitle(histotitle);
337  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
338  h->SetDirectory(0);
339  AddHisto(h);
340  fHistoNumber++;
341  if (!fProfileHisto) {
342  if (fNormHisto || fNormHistoEvents) {
343  h->Sumw2();
344  if (fNormHisto) {
345  h->Scale(1. / h->Integral("width"));
346  }
347  else {
349  }
350  }
351  }
352  return h;
353 }
354 
355 
356 
363 
364 TH1* KVTreeAnalyzer::MakeIntHisto(const Char_t* expr, const Char_t* selection, Int_t Xmin, Int_t Xmax, const Char_t* weight)
365 {
366  // Like MakeHisto but only used for 1-D spectra of integer variables.
367  // The number of bins is Xmax-Xmin+1 and bins are defined over [x-0.5,x+0.5]
368  // for all values of x.
369  //
370  // Histograms are automatically named 'Ih1', 'Ih2', etc. in order of creation.
371 
372  TString name;
373  name.Form("Ih%d", fHistoNumber);
374  TString drawexp(expr), histo, histotitle;
375  if (strcmp(weight, "")) GenerateHistoTitle(histotitle, expr, selection, weight);
376  else GenerateHistoTitle(histotitle, expr, selection);
377 
378  if (fUserBinning) {
380  Bool_t ok = KVBase::OpenContextMenu("DefineUserBinning1F", this, "DefineUserBinning");
381  if (!ok) return 0;
382  // cancel was pressed ?
383  if (MethodNotCalled()) return 0;
384  }
385 
386  histo.Form(">>%s(%d,%f,%f)", name.Data(), (fUserBinning ? fNxF : (Xmax - Xmin) + 1),
387  (fUserBinning ? fXminF : Xmin - 0.5), (fUserBinning ? fXmaxF : Xmax + 0.5));
388  drawexp += histo;
389  TString Selection;
390  if (strcmp(weight, "")) {
391  if (strcmp(selection, "")) Selection.Form("(%s)&&(%s)", selection, weight);
392  else Selection = weight;
393  }
394  else
395  Selection = selection;
396  Long64_t drawResult = fTree->Draw(drawexp, Selection, "goff");
397  if (drawResult < 0) {
398  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
399  return nullptr;
400  }
401  TH1* h;
402  if (IsPROOFEnabled()) h = (TH1*)gProof->GetOutputList()->FindObject(name);
403  else h = (TH1*)gDirectory->Get(name);
404  h->SetTitle(histotitle);
405  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
406  h->SetDirectory(0);
407 
408  AddHisto(h);
409  fHistoNumber++;
410  if (fNormHisto || fNormHistoEvents) {
411  h->Sumw2();
412  if (fNormHisto) {
413  h->Scale(1. / h->Integral("width"));
414  }
415  else {
417  }
418  }
419  return h;
420 }
421 
422 
423 
426 
428 {
429  // Return histogram with given name
430 
432  if (h->IsType("Histo")) return h->GetHisto();
433  return NULL;
434 }
435 
436 
437 
452 
454 {
455  // Generate a new user-selection (TEntryList) of events in the TTree
456  // according to the given selection expression (valid TTreeFormula expression
457  // using TTree leaf and/or alias names).
458  // The new selection is not applied immediately but added to the internal
459  // list of selections (see method AddSelection).
460  //
461  // If there is already an active selection (TEntryList set on TTree)
462  // this will generate the composite selection, {(active selection) && (selection)}.
463  // The selection's title will then be in the following format:
464  //
465  // "[(active selection) && ](selection)"
466  //
467  // TEntryList objects are automatically named 'el1', 'el2', etc. in order of creation.
468 
469  TObject* tmpObj = gROOT->FindObject(selection);
470  if (tmpObj) {
471  if (tmpObj->InheritsFrom("TCutG")) {
472  TCutG* cut = (TCutG*) tmpObj;
473  cut->SetTitle(cut->GetName());
474  AddCut(cut);
475  }
476  }
477 
478  TString name;
479  name.Form("el%d", fSelectionNumber);
480  TString drawexp(name.Data());
481  drawexp.Prepend(">>");
484  if (fChain->Draw(drawexp, selection, "entrylist") < 0) {
485  new TGMsgBox(gClient->GetRoot(), 0, "Warning", "Mistake in your new selection!", kMBIconExclamation, kMBClose);
486  return kFALSE;
487  }
489  TEntryList* el;
491  el = (TEntryList*)gProof->GetOutputList()->FindObject(name);
492  else
493  el = (TEntryList*)gDirectory->Get(name);
494  el->SetTitle(selection);//needed with PROOF
495  if (fChain->GetEntryList()) {
496  TString _elist = fChain->GetEntryList()->GetTitle();
497  TString title;
498  title.Form("(%s) && (%s)", _elist.Data(), selection);
499  el->SetTitle(title);
500  }
502  AddSelection(el);
504  return kTRUE;
505 }
506 
507 
508 
516 
518 {
519  // Method called when a selection is double-clicked in the GUI list.
520  // The required selection is passed as argument (address of TEntryList object)
521  // and becomes the currently active selection (TEntryList set on TTree).
522  // If the requested selection was already active, it is deactivated
523  // (remove TEntryList from TTree).
524  // The 'CURRENT SELECTION' message in the GUI status bar is updated.
525 
526  if (!obj->InheritsFrom("TEntryList")) return;
527  TEntryList* el = dynamic_cast<TEntryList*>(obj);
528  if (fChain->GetEntryList() == el) {
529  SetEntryList(nullptr);
530  G_selection_status->SetText("CURRENT SELECTION:", 0);
531  return;
532  }
533  SetEntryList(el);
534  G_selection_status->SetText(Form("CURRENT SELECTION: %s (%lld)", el->GetTitle(), el->GetN()), 0);
535 }
536 
537 
538 
541 
543 {
544  // Print the currently active selection (TEntryList set on TTree).
545 
546  TString tmp;
547  if (fChain->GetEntryList()) tmp = fChain->GetEntryList()->GetTitle();
548  else tmp = "";
549  if (tmp != "") cout << "CURRENT SELECTION : " << tmp << endl;
550 }
551 
552 
553 
557 
559 {
560  // Return number of entries (events) in the currently active selection,
561  // or the number of entries in the analysed TTree/TChain if no selection active
562 
563  if (fChain->GetEntryList()) return fChain->GetEntryList()->GetN();
564  return fChain->GetEntries();
565 }
566 
567 
568 
572 
574 {
575  // Fills the GUI list with the names of all leaves in the TTree
576  // and any friend TTrees and all aliases defined by the user
577 
578  TList stuff;
579  if (fTree) {
580  // clone list of leaves
581  fLeafList.Clear();
583  // when using a split object to fill the tree
584  // there is a redundant leaf/branch corresponding to the object itself
585  // more precisely there will be a TLeafElement in the list of leaves
586  // and a TBranchElement in the list of branches with the same name
587  //
588  // however the same applies to a simple unsplit object (such as using a TString to store
589  // strings). as the latter is probably far more common than the former (who creates trees
590  // with split objects in them these days???), I comment out the check which stopped such
591  // leaves appearing in the GUI (they are perfectly usable).
592  TIter next(clones);
593  TObject* o;
594  while ((o = next())) {
595 // if (o->InheritsFrom("TLeafElement")
596 // && fTree->GetListOfBranches()->FindObject(o->GetName())
597 // && fTree->GetListOfBranches()->FindObject(o->GetName())->InheritsFrom("TBranchElement"))
598 // continue;
599  fLeafList.Add(o);
600  }
601  delete clones;
602 
603  stuff.AddAll(&fLeafList);
604  stuff.AddAll(fTree->GetListOfAliases());
605  if (fTree->GetListOfFriends()) {
607  TFriendElement* fel;
608  while ((fel = (TFriendElement*)it())) {
609  stuff.AddAll(fel->GetTree()->GetListOfLeaves());
610  stuff.AddAll(fel->GetTree()->GetListOfAliases());
611  }
612  }
613  }
614  stuff.AddAll(&fAliasList);
615  G_leaflist->Display(&stuff);
616 }
617 
618 
619 
623 
625 {
626  // if analysis has been modified since last save,
627  // open an invite to ask if user wants to save with current default filename
628 
629  if (!fAnalysisModifiedSinceLastSave) return;
630 
631  if (fNoGui) {
632  // text-only interface
633  cout << "Analysis " << GetTitle() << " has been modified. Save before continuing? [y] : " << flush;
634  char reply;
635  cin.get(reply);
636  cout << endl;
637  if (reply == 'n' || reply == 'N') return;
638  cout << "Give name of file [" << fSaveAnalysisFileName << "] : " << flush;
639  char filename[256];
640  cin.get(filename, 256);
641  if (filename[0] != 0) fSaveAnalysisFileName = filename;
642  Save();
643  }
644  else {
645  Int_t ret_code;
647  new TGMsgBox(gClient->GetDefaultRoot(), (fMain_histolist ? fMain_histolist : gClient->GetDefaultRoot()), GetTitle(),
648  "Analysis has been modified. Save before continuing?", kMBIconStop,
649  kMBYes | kMBNo, &ret_code);
650  if (ret_code == kMBNo) return;
652  }
653 }
654 
655 
656 
658 
660 {
662  if (fMenuFile) {
663  if (x) {
666  }
667  else {
670  }
671  }
672 }
673 
674 
675 
684 
686 {
687  // Modify currently active selection (TEntryList)
688  // Instead of calling
689  // fChain->SetEntryList(l);
690  // call this method which works with or without PROOF.
691  // When using PROOF, fChain->SetEntryList(nullptr)
692  // does not work (bug in TProofChain), the last selection
693  // remains active. This problem is corrected here.
694 
696 
697  if (l == nullptr && IsPROOFEnabled()) {
700  }
701 }
702 
703 
704 
707 
709 {
710  // Launch the GUI (unless fNoGui=kTRUE in which case this does nothing)
711 
712  if (fNoGui) return;
713 
714  ULong_t red, cyan, green, yellow, magenta, gura, gurb, gurc, gurd, gure, gurf;
715  gClient->GetColorByName("#ff00ff", magenta);
716  gClient->GetColorByName("#ff0000", red);
717  gClient->GetColorByName("#00ff00", green);
718  gClient->GetColorByName("#00ffff", cyan);
719  gClient->GetColorByName("#ffff00", yellow);
720  gClient->GetColorByName("#cf14b2", gura);
721  gClient->GetColorByName("#cd93e6", gurb);
722  gClient->GetColorByName("#c1e91a", gurc);
723  gClient->GetColorByName("#d1a45b", gurd);
724  gClient->GetColorByName("#b54cfe", gure);
725  gClient->GetColorByName("#a325ef", gurf);
726 
727  /********* MAIN WINDOW **************/
728  //
729  fMain_histolist = new TGMainFrame(gClient->GetRoot(), 10, 10, kMainFrame | kVerticalFrame);
730  fMain_histolist->SetName("fMain_histolist");
731  if (!fTree)
732  fMain_histolist->SetWindowName("Tree Analyzer");
733  else
735  fMain_histolist->SetIconName("TreeAnalyzer");
736  fMain_histolist->SetIconPixmap("root_s.xpm");
737 
739 
740  UInt_t hWidth = 400, hHeight = 400;
741 
742  /* menus */
743  fMenuFile = new TGPopupMenu(gClient->GetRoot());
744  fMenuFile->AddEntry("New analysis", MH_OPEN_CHAIN);
745  fMenuFile->AddEntry("Open analysis", MH_OPEN_FILE);
746  fMenuFile->AddEntry("Add Friend...", MH_ADD_FRIEND);
748  fMenuFile->AddEntry("Save analysis", MH_SAVE);
749  fMenuFile->AddEntry("Save as...", MH_SAVE_FILE);
750  fMenuFile->AddEntry("Close", MH_CLOSE);
752  fMenuFile->AddEntry("Apply analysis...", MH_APPLY_ANALYSIS);
755  fMenuFile->AddEntry("Quit", MH_QUIT);
756  fMenuFile->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleHistoFileMenu(Int_t)");
757  fMenuSelections = new TGPopupMenu(gClient->GetRoot());
758  fSelCombMenu = new TGPopupMenu(gClient->GetRoot());
759  fSelCombMenu->AddEntry("AND (&&)", SEL_COMB_AND);
760  fSelCombMenu->AddEntry("OR (||)", SEL_COMB_OR);
761  fMenuSelections->AddPopup("Combine...", fSelCombMenu);
764  fMenuSelections->AddEntry("Update", SEL_UPDATE);
765  fMenuSelections->AddEntry("Delete", SEL_DELETE);
767  fSelGenerate = new TGPopupMenu(gClient->GetRoot());
768  fSelGenerate->AddEntry("Constant X-sections", SEL_GEN_CONST_XSEC);
769  fMenuSelections->AddPopup("Generate...", fSelGenerate);
770  fMenuSelections->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleSelectionsMenu(Int_t)");
771  fOptionMenu = new TGPopupMenu(gClient->GetRoot());
772  fOptionMenu->AddEntry("PROOF", OPT_PROOF);
773  fOptionMenu->Connect("Activated(Int_t)", "KVTreeAnalyzer", this, "HandleOptionsMenu(Int_t)");
782 
783  // Horizontal frame to contain the VARIABLES list (left) and SELECTIONS list (right)
785 
786  /********* VARIABLES **************/
787  // Group frame for TTree variables/aliases
788  fMain_leaflist = new TGGroupFrame(hf, "VARIABLES");
789  UInt_t lWidth = 300, lHeight = 300;
790  /* leaf list */
791 
792  /* make selection */
793  TGHorizontalFrame* fHorizontalFrame = new TGHorizontalFrame(fMain_leaflist, lWidth, 36, kHorizontalFrame);
794  TGLabel* lab = new TGLabel(fHorizontalFrame, "Make alias : ");
795  fHorizontalFrame->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
796  G_alias_text = new TGTextEntry(fHorizontalFrame, new TGTextBuffer(50));
797  G_alias_text->SetMaxLength(4096);
800  G_alias_text->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateAlias()");
801  fHorizontalFrame->AddFrame(G_alias_text, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 2, 5, 2, 2));
802  fMain_leaflist->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
803 
804  G_leaflist = new KVListView(TNamed::Class(), fMain_leaflist, lWidth, lHeight);
806  G_leaflist->SetDataColumn(0, "Title");
809  G_leaflist->SetDoubleClickAction("KVTreeAnalyzer", this, "DrawLeaf(TObject*)");
810  G_leaflist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "LeafChanged()");
811 // G_leaflist->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "ShowVar()");
814  5, 5, 5, 5));
815 
816  //fMain_leaflist->MapSubwindows();
817 
819  //fMain_leaflist->MapWindow();
820  fMain_leaflist->Resize(lWidth, lHeight);
821  FillLeafList();
822  /*********end of VARIABLES **************/
823  hf->AddFrame(fMain_leaflist, new TGLayoutHints(kLHintsLeft, 5, 5, 5, 5));
824 
825  /******* SELECTIONS *********/
826  UInt_t sWidth = 600, sHeight = lHeight;
827  fMain_selectionlist = new TGGroupFrame(hf, "SELECTIONS");
828  /* current selection */
830  G_selection_status->SetText("CURRENT SELECTION:", 0);
832  /* make selection */
833  TGHorizontalFrame* fHorizontalFrame1614 = new TGHorizontalFrame(fMain_selectionlist, sWidth, 36, kHorizontalFrame);
834  lab = new TGLabel(fHorizontalFrame1614, "Make selection : ");
835  fHorizontalFrame1614->AddFrame(lab, new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
836  G_selection_text = new TGTextEntry(fHorizontalFrame1614, new TGTextBuffer(50));
840  G_selection_text->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateSelection()");
841  fHorizontalFrame1614->AddFrame(G_selection_text, new TGLayoutHints(kLHintsLeft | kLHintsTop | kLHintsExpandX, 2, 5, 2, 2));
842  fMain_selectionlist->AddFrame(fHorizontalFrame1614, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
843 
844  /* selection list */
845  G_selectionlist = new KVListView(TEntryList::Class(), fMain_selectionlist, sWidth, sHeight);
847  G_selectionlist->SetDataColumn(0, "Selection", "GetTitle");
848  G_selectionlist->SetDataColumn(1, "Reapply", "GetReapplyCut");
850  G_selectionlist->SetDataColumn(2, "Events", "GetN", kTextRight);
852  G_selectionlist->SetDoubleClickAction("KVTreeAnalyzer", this, "SetSelection(TObject*)");
853  G_selectionlist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "SelectionChanged()");
856  5, 5, 5, 5));
857 
858  //fMain_selectionlist->MapSubwindows();
859 
861  //fMain_selectionlist->MapWindow();
862  fMain_selectionlist->Resize(sWidth, sHeight);
864  /******end of SELECTIONS *********/
867 
868  /**** Histo creation group ********/
869  TGGroupFrame* histo_opts = new TGGroupFrame(fMain_histolist, "CREATE HISTO", kHorizontalFrame);
870  fHorizontalFrame = new TGHorizontalFrame(histo_opts, lWidth, 36, kHorizontalFrame);
871  G_leaf_draw = new TGPictureButton(fHorizontalFrame, "draw_t.xpm");
873  G_leaf_draw->Connect("Clicked()", "KVTreeAnalyzer", this, "DrawLeafExpr()");
874  fHorizontalFrame->AddFrame(G_leaf_draw, new TGLayoutHints(kLHintsTop | kLHintsLeft, 2, 2, 2, 2));
875  fLeafExpr = " ";
876  G_leaf_expr = new TGLabel(fHorizontalFrame, fLeafExpr.Data());
877  G_leaf_expr->Resize();
878  fHorizontalFrame->AddFrame(G_leaf_expr, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsCenterY, 2, 2, 2, 2));
879  histo_opts->AddFrame(fHorizontalFrame, new TGLayoutHints(kLHintsExpandX | kLHintsTop, 1, 1, 1, 1));
880 
881  G_histo_prof = new TGCheckButton(histo_opts, "Profile");
882  G_histo_prof->SetToolTipText("Generate a profile histogram");
884  G_histo_prof->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetProfileHisto(Bool_t)");
885  histo_opts->AddFrame(G_histo_prof, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
886 
887  G_histo_norm = new TGCheckButton(histo_opts, "Normalize (integral)");
888  G_histo_norm->SetToolTipText("Generate normalized histogram with integral=1");
890  G_histo_norm->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNormHisto(Bool_t)");
891  histo_opts->AddFrame(G_histo_norm, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
892  G_histo_norm_events = new TGCheckButton(histo_opts, "Normalize (events)");
893  G_histo_norm_events->SetToolTipText("Generate histogram with integral divided by number of events");
895  G_histo_norm_events->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNormHistoEvents(Bool_t)");
896  histo_opts->AddFrame(G_histo_norm_events, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
897 
898  G_histo_weight = new TGCheckButton(histo_opts, "Weight");
899  G_histo_weight->SetToolTipText("User defined binning of the histogram");
901  G_histo_weight->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetUserWeight(Bool_t)");
902  histo_opts->AddFrame(G_histo_weight, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
903 
904  G_histo_bin = new TGCheckButton(histo_opts, "Bins");
905  G_histo_bin->SetToolTipText("User defined binning of the histogram");
907  G_histo_bin->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetUserBinning(Bool_t)");
908  histo_opts->AddFrame(G_histo_bin, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
909  fMain_histolist->AddFrame(histo_opts, new TGLayoutHints(kLHintsCenterX | kLHintsExpandX, 5, 5, 5, 5));
910 
911  /******** HISTOGRAMS *****************/
912  hWidth = lWidth + sWidth + 20;
913  TGGroupFrame* histo_group = new TGGroupFrame(fMain_histolist, "HISTOGRAMS");
914  /* ip scale */
915 // histo_opts = new TGGroupFrame(histo_group, "Impact parameter", kHorizontalFrame);
916 // G_make_ip_scale = new TGTextButton(histo_opts,"Make scale");
917 // G_make_ip_scale->SetTextJustify(36);
918 // G_make_ip_scale->SetMargins(0,0,0,0);
919 // G_make_ip_scale->SetWrapLength(-1);
920 // G_make_ip_scale->Resize();
921 // G_make_ip_scale->SetEnabled(kFALSE);
922 // G_make_ip_scale->Connect("Clicked()","KVTreeAnalyzer",this,"MakeIPScale()");
923 // G_make_ip_scale->ChangeBackground(green);
924 // histo_opts->AddFrame(G_make_ip_scale, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,10,2));
925 // lab = new TGLabel(histo_opts,"b <");
926 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,5,2,12,2));
927 // G_make_ip_selection = new TGTextEntry(histo_opts, new TGTextBuffer(5));
928 // G_make_ip_selection->SetMaxLength(10);
929 // G_make_ip_selection->SetAlignment(kTextLeft);
930 // G_make_ip_selection->Resize(50,G_make_ip_selection->GetDefaultHeight());
931 // G_make_ip_selection->Connect("ReturnPressed()", "KVTreeAnalyzer", this, "GenerateIPSelection()");
932 // G_make_ip_selection->SetEnabled(kFALSE);
933 // histo_opts->AddFrame(G_make_ip_selection, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,10,2));
934 // G_ip_histo = new TGLabel(histo_opts,"-");
935 // histo_opts->AddFrame(G_ip_histo, new TGLayoutHints(kLHintsLeft|kLHintsTop,5,2,12,2));
936 // histo_group->AddFrame(histo_opts, new TGLayoutHints(kLHintsLeft|kLHintsExpandX,5,5,5,5));
937 // /* ip scale */
938 // histo_opts = new TGGroupFrame(histo_group, "Fits", kHorizontalFrame);
939 // lab = new TGLabel(histo_opts,"Gumbel : ");
940 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,5,2));
941 // G_fit1 = new TGTextButton(histo_opts, " 1 ");
942 // G_fit1->SetTextJustify(36);
943 // G_fit1->SetMargins(0,0,0,0);
944 // G_fit1->SetWrapLength(-1);
945 // G_fit1->Resize();
946 // G_fit1->SetEnabled(kFALSE);
947 // G_fit1->ChangeBackground(gura);
948 // G_fit1->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum1()");
949 // histo_opts->AddFrame(G_fit1, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
950 // G_fit2 = new TGTextButton(histo_opts, " 2 ");
951 // G_fit2->SetTextJustify(36);
952 // G_fit2->SetMargins(0,0,0,0);
953 // G_fit2->SetWrapLength(-1);
954 // G_fit2->Resize();
955 // G_fit2->SetEnabled(kFALSE);
956 // G_fit2->ChangeBackground(gurb);
957 // G_fit2->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum2()");
958 // histo_opts->AddFrame(G_fit2, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
959 // G_fit3 = new TGTextButton(histo_opts, " 3 ");
960 // G_fit3->SetTextJustify(36);
961 // G_fit3->SetMargins(0,0,0,0);
962 // G_fit3->SetWrapLength(-1);
963 // G_fit3->Resize();
964 // G_fit3->SetEnabled(kFALSE);
965 // G_fit3->ChangeBackground(gurc);
966 // G_fit3->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGum3()");
967 // histo_opts->AddFrame(G_fit3, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
968 // lab = new TGLabel(histo_opts,"Gaus+Gum : ");
969 // histo_opts->AddFrame(lab, new TGLayoutHints(kLHintsLeft|kLHintsTop,10,2,5,2));
970 // G_fitGG1 = new TGTextButton(histo_opts, " 1 ");
971 // G_fitGG1->SetTextJustify(36);
972 // G_fitGG1->SetMargins(0,0,0,0);
973 // G_fitGG1->SetWrapLength(-1);
974 // G_fitGG1->Resize();
975 // G_fitGG1->SetEnabled(kFALSE);
976 // G_fitGG1->ChangeBackground(gura);
977 // G_fitGG1->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum1()");
978 // histo_opts->AddFrame(G_fitGG1, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
979 // G_fitGG2 = new TGTextButton(histo_opts, " 2 ");
980 // G_fitGG2->SetTextJustify(36);
981 // G_fitGG2->SetMargins(0,0,0,0);
982 // G_fitGG2->SetWrapLength(-1);
983 // G_fitGG2->Resize();
984 // G_fitGG2->SetEnabled(kFALSE);
985 // G_fitGG2->ChangeBackground(gurb);
986 // G_fitGG2->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum2()");
987 // histo_opts->AddFrame(G_fitGG2, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
988 // G_fitGG3 = new TGTextButton(histo_opts, " 3 ");
989 // G_fitGG3->SetTextJustify(36);
990 // G_fitGG3->SetMargins(0,0,0,0);
991 // G_fitGG3->SetWrapLength(-1);
992 // G_fitGG3->Resize();
993 // G_fitGG3->SetEnabled(kFALSE);
994 // G_fitGG3->ChangeBackground(gurc);
995 // G_fitGG3->Connect("Clicked()", "KVTreeAnalyzer", this, "FitGausGum3()");
996 // histo_opts->AddFrame(G_fitGG3, new TGLayoutHints(kLHintsLeft|kLHintsTop,2,2,2,2));
997 // histo_group->AddFrame(histo_opts, new TGLayoutHints(kLHintsLeft|kLHintsExpandX,5,5,5,5));
998 
999  /* histo list */
1000  //G_histolist = new KVListView(TNamed::Class(), histo_group, hWidth, hHeight);
1001  //G_histolist->SetDataColumns(1);
1002  //G_histolist->SetDataColumn(0, "Data", "GetTitle", kTextLeft);
1003  G_histolist = new KVListView(KVHistogram::Class(), histo_group, hWidth, hHeight);
1005  G_histolist->SetDataColumn(0, "Name", "", kTextLeft);
1006  G_histolist->SetDataColumn(1, "VarX", "", kTextCenterX);
1007  G_histolist->SetDataColumn(2, "VarY", "", kTextCenterX);
1008  G_histolist->SetDataColumn(3, "VarZ", "", kTextCenterX);
1009  G_histolist->SetDataColumn(4, "Selection", "", kTextCenterX);
1010  G_histolist->SetDataColumn(5, "Weight", "", kTextCenterX);
1011  G_histolist->SetDataColumn(6, "MeanX (RMS)", "GetMeanRMSX", kTextCenterX);
1012  G_histolist->SetDataColumn(7, "MeanY (RMS)", "GetMeanRMSY", kTextCenterX);
1015  G_histolist->SetUseObjLabelAsRealClass();//to have icons & context menus of TH* & TCutG classes, not KVHistogram
1016  G_histolist->SetDoubleClickAction("KVTreeAnalyzer", this, "DrawHisto(TObject*)");
1017  G_histolist->Connect("SelectionChanged()", "KVTreeAnalyzer", this, "HistoSelectionChanged()");
1020  5, 5, 5, 5));
1021 
1024  /* histo options */
1025  histo_opts = new TGGroupFrame(fMain_histolist, "OPTIONS", kHorizontalFrame);
1026 
1027  //fHorizontalFrame = new TGHorizontalFrame(histo_opts,150,36,kHorizontalFrame);
1028  G_histo_del = new TGPictureButton(histo_opts, "sm_delete.xpm");
1030  G_histo_del->Connect("Clicked()", "KVTreeAnalyzer", this, "DeleteSelectedHisto()");
1031  //fHorizontalFrame->AddFrame(G_histo_del, new TGLayoutHints(kLHintsTop|kLHintsLeft,2,2,2,2));
1032  //lab = new TGLabel(fHorizontalFrame, "DELETE");
1033  //lab->Resize();
1034  //fHorizontalFrame->AddFrame(lab, new TGLayoutHints(kLHintsTop|kLHintsLeft|kLHintsCenterY,2,2,2,2));
1035  histo_opts->AddFrame(G_histo_del, new TGLayoutHints(kLHintsLeft, 5, 2, 8, 2));
1036 
1037  G_histo_add = new TGPictureButton(histo_opts, "bld_plus.png");
1039  G_histo_add->Connect("Clicked()", "KVTreeAnalyzer", this, "AddSelectedHistos()");
1041  histo_opts->AddFrame(G_histo_add, new TGLayoutHints(kLHintsLeft, 15, 25, 8, 2));
1042 
1043  G_histo_draw_option = new TGComboBox(histo_opts);
1044  TString draw_options[] = {
1045  "",
1046  "COL",
1047  "COLZ",
1048  "BOX",
1049  "CONT",
1050  "SURF",
1051  "LEGO",
1052  "ARR",
1053  "TEXT",
1054  "CONT1",
1055  "CONT2",
1056  "CONT3",
1057  "CONT4",
1058  "SURF1",
1059  "SURF2",
1060  "SURF3",
1061  "SURF4",
1062  "LEGO1",
1063  "LEGO2",
1064  "LEGO3",
1065  "LEGO4",
1066  "BOX1",
1067  " "
1068  };
1069  int dop = 0;
1070  while (draw_options[dop] != " ") {
1071  G_histo_draw_option->AddEntry(draw_options[dop], dop);
1072  ++dop;
1073  }
1074  G_histo_draw_option->Resize(100, 20);
1075  histo_opts->AddFrame(G_histo_draw_option, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1076  G_histo_draw_option->Connect("Selected(const char*)", "KVTreeAnalyzer", this, "SetDrawOption(Option_t*)");
1077 
1078  G_histo_new_can = new TGCheckButton(histo_opts, "New canvas");
1079  G_histo_new_can->SetToolTipText("Draw in a new canvas");
1080  G_histo_new_can->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetNewCanvas(Bool_t)");
1082  histo_opts->AddFrame(G_histo_new_can, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1083  G_histo_same = new TGCheckButton(histo_opts, "Same");
1084  G_histo_same->SetToolTipText("Draw in same pad");
1085  G_histo_same->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetDrawSame(Bool_t)");
1086  histo_opts->AddFrame(G_histo_same, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1087  G_histo_app_sel = new TGCheckButton(histo_opts, "Apply selection");
1088  G_histo_app_sel->SetToolTipText("Apply current selection to generate new histo");
1089  G_histo_app_sel->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetApplySelection(Bool_t)");
1090  histo_opts->AddFrame(G_histo_app_sel, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1091  G_histo_log = new TGCheckButton(histo_opts, "Log scale");
1092  G_histo_log->SetToolTipText("Use log scale in Y (1D) or Z (2D)");
1094  G_histo_log->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetDrawLog(Bool_t)");
1095  histo_opts->AddFrame(G_histo_log, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1096  G_histo_stats = new TGCheckButton(histo_opts, "Stats");
1097  G_histo_stats->SetToolTipText("Display histogram statistics box");
1099  G_histo_stats->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetStatsHisto(Bool_t)");
1100  histo_opts->AddFrame(G_histo_stats, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1101  G_histo_autosave = new TGCheckButton(histo_opts, "AutoSave");
1102  G_histo_autosave->SetToolTipText("Automatically generate histo image files");
1104  G_histo_autosave->Connect("Toggled(Bool_t)", "KVTreeAnalyzer", this, "SetAutoSaveHisto(Bool_t)");
1105  histo_opts->AddFrame(G_histo_autosave, new TGLayoutHints(kLHintsLeft, 15, 2, 8, 2));
1106  fMain_histolist->AddFrame(histo_opts, new TGLayoutHints(kLHintsCenterX, 5, 5, 5, 5));
1107 
1109 
1112 
1113  hHeight = hHeight + lHeight + 50;
1114 
1115  fMain_histolist->Resize(hWidth, hHeight);
1116  /********* end of HISTOGRAMS *************/
1117 
1118  fMain_histolist->Connect("CloseWindow()", "KVTreeAnalyzer", this, "GUIClosed()");
1119 }
1120 
1121 
1122 
1125 
1127 {
1128  // Called when graphical window is closed
1129 
1132  TTimer::SingleShot(150, "KVTreeAnalyzer", this, "DeleteThis()");
1133 }
1134 
1135 
1136 
1140 
1142 {
1143  // Adds histogram to internal list of user histograms
1144  // and updates GUI display
1145 
1146  SetAnalysisModifiedSinceLastSave(kTRUE);//new histogram needs saving
1147  fHistolist.Add(new KVHistogram(h));
1149 }
1150 
1151 
1152 
1156 
1158 {
1159  // Adds selection to internal list of user histograms
1160  // and updates GUI display
1161 
1162  SetAnalysisModifiedSinceLastSave(kTRUE);//new selection needs saving
1163  fSelections.Add(e);
1165 }
1166 
1167 
1168 
1172 
1174 {
1175  // Adds histogram to internal list of user histograms
1176  // and updates GUI display
1177 
1178  SetAnalysisModifiedSinceLastSave(kTRUE);//new selection needs saving
1179  fHistolist.Add(new KVHistogram(c));
1181 }
1182 
1183 
1184 
1191 
1193 {
1194  // the Tree file name is used as the basis for the default analysis backup filename.
1195  // for a TChain there may be many files with a common root.
1196  // we look for this common root and replace any "wildcard" characters with "X"
1197  // i.e. for files "run_001.root", "run_002.root", ..., "run_999.root" we
1198  // will use "Analysis_run_XXX.root" as default name
1199 
1200  KVString p;
1201  if (t->InheritsFrom("TChain")) {
1202  KVString p;
1203  p.FindCommonTitleCharacters(((TChain*)t)->GetListOfFiles(), 'X');
1204  fTreeFileName = p.Data();
1205  }
1206  else
1210 }
1211 
1212 
1213 
1216 
1218 {
1219  // Connects a TChain for analysis
1220 
1221  fTree = t;
1222  if (IsPROOFEnabled()) fChain->SetProof();
1223  fTreeName = t->GetName();
1224  SetTreeFileName(t);
1226 }
1227 
1228 
1229 
1232 
1234 {
1235  // Backwards compatibility: to read old analysis files
1236 
1237  TFile* f;
1239  // absolute path to TTree file doesn't work, try in working directory
1240  TString tmp;
1242  f = TFile::Open(tmp);
1243  }
1245  // if fRelativePathToAnalysisFile!="." and if fTreeFileName is not an absolute path,
1246  // we guess the Tree file is in the same directory as the analysis file
1247  TString tmp;
1249  f = TFile::Open(tmp);
1250  }
1251  else
1253  if (!f || f->IsZombie()) {
1254  Error("ReconnectTree", "Failed to reconnect Tree file %s", fTreeFileName.Data());
1255  fTree = 0;
1256  fChain = 0;
1257  SafeDelete(f);
1258  return;
1259  }
1260  fTreeFileName = f->GetName();
1261  TTree* t = (TTree*)f->Get(fTreeName);
1262  TString treeTitle = t->GetTitle();
1263  delete f;
1264  fChain = new TChain(fTreeName, treeTitle);
1266  fChain->SetDirectory(0);
1267  SetTree(fChain);
1268 }
1269 
1270 
1271 
1279 
1281 {
1282  // STATIC method to open a previously saved analysis session.
1283  //
1284  // Use:
1285  // root[0] KVTreeAnalyzer* TA = KVTreeAnalyzer::OpenFile("my_analysis.root")
1286  //
1287  // If option nogui=kTRUE the GUI will not be launched
1288 
1289  TFile* f = TFile::Open(filename);
1290  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1291  delete f;
1292  anal->fNoGui = nogui;
1293  anal->SetRelativePathToAnalysisFile(gSystem->DirName(filename));
1294  anal->OpenGUI();
1295  return anal;
1296 }
1297 
1298 
1299 
1302 
1304 {
1305  // open a previously saved analysis session.
1306 
1307  TFile* f = TFile::Open(filename);
1308  ReadFromFile(f);
1309 }
1310 
1311 
1312 
1315 
1317 {
1318  // open a previously saved analysis session.
1319 
1320  KVTreeAnalyzer* anal = (KVTreeAnalyzer*)f->Get("KVTreeAnalyzer");
1321  delete f;
1322  anal->Copy(*this);
1323  delete anal;
1324  gTreeAnalyzer = this;
1327  FillLeafList();
1328 }
1329 
1330 
1331 
1333 
1335 {
1336  TString name = Form("%s:%s", cut->GetVarY(), cut->GetVarX());
1337  KVList padList(kFALSE);
1338  Bool_t testHisto = kFALSE;
1339 
1340  if (!gPad) testHisto = kTRUE;
1341 
1342  if (!testHisto) {
1343  testHisto = kTRUE;
1344  padList.AddAll(((TPad*)gPad)->GetListOfPrimitives());
1345  TIter next(&padList);
1346  TObject* o = 0;
1347  while ((o = next())) {
1348  if (o->InheritsFrom("TH1")) {
1349  TH1* hh = (TH1*) o;
1350  TString hName = hh->GetTitle();
1351  if (hName.Contains(name.Data())) {
1352  cut->Draw("PL");
1353  gPad->Update();
1354  testHisto = kFALSE;
1355  }
1356  }
1357  }
1358  }
1359 
1360  if (testHisto) {
1361  TIter next(&fHistolist);
1362  KVHistogram* hhh;
1363  TH1* hh = 0;
1364  while ((hhh = (KVHistogram*)next())) {
1365  if ((hh = hhh->GetHisto())) {
1366  TString hName = hh->GetTitle();
1367  if (hName.Contains(name.Data())) {
1368  DrawHisto(hh, kFALSE);
1369  cut->Draw("PL");
1370  gPad->Update();
1371  break;
1372  }
1373  }
1374  }
1375  }
1376  // else cut->Draw("PAL");
1377 
1378 
1379 // TIter next(fHistoList);
1380 // TH1* tmpHist = 0;
1381 // while((tmpHisto = (TH1*)next()))
1382 // {
1383 //
1384 // }
1385 
1386  return;
1387 }
1388 
1389 
1390 
1411 
1413 {
1414  // Method called when a user double-clicks a histogram in the GUI list.
1415  //
1416  // * if histogram is already displayed in active pad and if the pad also
1417  // contains a graphical contour (TCutG) object, we use the contour to define
1418  // a new data selection (TEntryList) which is added to the internal list.
1419  //
1420  // * if 'reapply selection' is activated and if the current active selection
1421  // is not the same as that used to generate the histogram, we generate a new
1422  // histogram displaying the same variables but with the current selection.
1423  //
1424  // * if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1425  // plot with a different colour and add it to the automatically generated
1426  // legend which is also displayed in the plot
1427  //
1428  // * if 'new canvas' is active the histogram is displayed in a new KVCanvas
1429  //
1430  // * in all cases when a histogram is displayed the log/linear scale of
1431  // Y (1-D) or Z (2-D) axis is automatically adjusted according to the 'log scale'
1432  // check box
1433 
1434  KVHistogram* kvhisto = 0;
1435  TCutG* cut = 0;
1436  TH1* histo = 0;
1437  if (obj->InheritsFrom("KVHistogram")) {
1438  kvhisto = dynamic_cast<KVHistogram*>(obj);
1439  if (kvhisto->IsType("Cut")) cut = kvhisto->GetCut();
1440  else if (kvhisto->IsType("Histo")) histo = kvhisto->GetHisto();
1441  }
1442  else if (obj->InheritsFrom("TCutG")) {
1443  cut = dynamic_cast<TCutG*>(obj);
1444  }
1445  else if (obj->InheritsFrom("TH1")) {
1446  histo = dynamic_cast<TH1*>(obj);
1447  }
1448 
1449  if (cut) {
1450  DrawCut(cut);
1451  return;
1452  }
1453  if (!histo) return;
1454 
1455  // if histogram is already displayed in active pad and if the pad also
1456  // contains a graphical contour (TCutG) object, we use the contour to define
1457  // a new data selection (TEntryList) which is added to the internal list.
1458  if (gPad && gPad->GetListOfPrimitives()->FindObject(histo) && (gen)) {
1459  TIter next(gPad->GetListOfPrimitives());
1460  TObject* o;
1461  while ((o = next())) {
1462  if ((o->IsA() == TCutG::Class()) && !(fHistolist.FindObjectWithNameAndType(o->GetName(), "Cut"))) {
1463  MakeSelection(o->GetName());
1464  return;
1465  }
1466  }
1467  }
1468 
1469  KVString exp, sel, weight;
1470  if (kvhisto) {
1471  exp = kvhisto->GetExpression();
1472  sel = kvhisto->GetSelection();
1473  weight = kvhisto->GetWeight();
1474  }
1475  else {
1476  KVHistogram::ParseHistoTitle(histo->GetTitle(), exp, sel, weight);
1477  }
1478 
1479  if (weight == "1") weight = "";
1480 
1481  // if 'reapply selection' is activated and if the current active selection
1482  // is not the same as that used to generate the histogram, we generate a new
1483  // histogram displaying the same variables but with the current selection.
1484  if (!IsCurrentSelection(sel) && fApplySelection) {
1485  histo = RemakeHisto(histo, exp, weight);
1486  if (!histo) return;
1487  }
1488 
1489  if (fDrawSame) {
1490  // if 'draw same' is active we superimpose the (1-D) spectrum on the existing
1491  // plot with a different colour and add it to the automatically generated
1492  // legend which is also displayed in the plot
1495  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1496  if (histo->InheritsFrom("TH2")) {
1497  TString hopt = histo->GetOption();
1498  if (hopt != "") hopt.Form("%s,same", histo->GetOption());
1499  else hopt = "same";
1500  histo->Draw(hopt);
1501  }
1502  else
1503  histo->Draw("same");
1504  TObject* legend = gPad->GetListOfPrimitives()->FindObject("TPave");
1505  if (legend) {
1506  gPad->GetListOfPrimitives()->Remove(legend);
1507  delete legend;
1508  }
1509  ((TPad*) gPad)->BuildLegend();
1510  if (histo->InheritsFrom("TH2")) {
1511  gPad->SetLogy(kFALSE);
1512  gPad->SetLogz(fDrawLog);
1513  }
1514  else {
1515  gPad->SetLogy(fDrawLog);
1516  // adjust y-scale to new histogram if needed
1517  // find first histogram
1518  TIter nxt(gPad->GetListOfPrimitives());
1519  TObject* h;
1520  while ((h = nxt())) {
1521  if (h->InheritsFrom("TH1")) {
1522  TH1* hh = (TH1*)h;
1523  if (histo->GetMaximum() > hh->GetMaximum()) hh->SetMaximum(histo->GetMaximum() + 1);
1524  break;
1525  }
1526  }
1527  }
1528  gPad->Modified();
1529  gPad->Update();
1530  if (fAutoSaveHisto) AutoSaveHisto(histo);
1531  }
1532  else {
1533  // if 'new canvas' is active the histogram is displayed in a new KVCanvas
1534  // create a new canvas also if none exists
1535  if (fNewCanvas || !gPad) {
1536  KVCanvas* c = new KVCanvas;
1537  c->SetTitle(histo->GetTitle());
1538  c->SetWindowSize(700, 700);
1539  }
1540  else if (gPad) { // update title of existing canvas
1541  gPad->GetCanvas()->SetTitle(histo->GetTitle());
1542  }
1543  histo->SetLineColor(my_color_array[0]);
1544  if (histo->InheritsFrom("TH2")) {
1545  gPad->SetLogy(kFALSE);
1546  gPad->SetLogz(fDrawLog);
1547  }
1548  else {
1549  histo->SetMaximum(-1111);//in case maximum was changed to accomodate superimposition
1550  gPad->SetLogy(fDrawLog);
1551  }
1552  histo->SetStats(fStatsHisto);//show/hide stat box according to check-box
1553  if (fDrawOption != "" && histo->InheritsFrom("TH2")) histo->SetOption(fDrawOption);
1554  histo->Draw();
1555  gPad->Modified();
1556  gPad->Update();
1557  if (fAutoSaveHisto) AutoSaveHisto(histo);
1558  }
1559 }
1560 
1561 
1562 
1566 
1568 {
1569  // Returns kTRUE if "sel" corresponds to current active selection
1570  // (i.e. entry list of TTree)
1571 
1572  if (!fTree) return kTRUE;
1573  TString test_sel(sel);
1574  TString tree_sel;
1575  TEntryList* el;
1576  if ((el = fChain->GetEntryList())) tree_sel = el->GetTitle();
1577  return (test_sel == tree_sel);
1578 }
1579 
1580 
1581 
1586 
1587 TH1* KVTreeAnalyzer::RemakeHisto(TH1* h, const Char_t* expr, const Char_t* weight)
1588 {
1589  // Remake an existing histogram of data 'expr' using the current active selection
1590  // If such a histogram already exists, we just return its address.
1591  // We try to have the same binning in the new as in the original histogram.
1592 
1593  TString htit;
1594  GenerateHistoTitle(htit, expr, "", weight);
1595  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
1596  TH1* histo = 0;
1597  if (kvhisto) histo = kvhisto->GetHisto();
1598  if (histo && (histo->IsA() == h->IsA())) return histo;
1599  Int_t nx, ny = 0;
1600  TString hname(h->GetName());
1601  if (hname.BeginsWith("I")) {
1602  Int_t xmin = h->GetXaxis()->GetXmin() + 0.5;
1603  Int_t xmax = h->GetXaxis()->GetXmax() - 0.5;
1604  //cout << "Remake histo with xmin = " << xmin << " xmax = " << xmax << endl;
1605  h = MakeIntHisto(expr, "", xmin, xmax, weight);
1606  return h;
1607  }
1608  nx = h->GetNbinsX();
1609  if (h->InheritsFrom("TH2")) ny = h->GetNbinsY();
1610  //cout << "Remake histo with nx = " << nx << " ny = " << ny << endl;
1611  if (h->InheritsFrom("TProfile")) {
1612  // make a new profile histogram
1613  Bool_t oldProfileState = fProfileHisto;
1614  fProfileHisto = kTRUE;
1615  h = MakeHisto(expr, "", nx, ny, weight);
1616  fProfileHisto = oldProfileState;
1617  }
1618  else
1619  h = MakeHisto(expr, "", nx, ny, weight);
1620  return h;
1621 }
1622 
1623 
1624 
1629 
1631 {
1632  // Method called when user hits 'return' in selection GUI text-box
1633  // Takes expression from text-box and generates the corresponding
1634  // selection which is added to the GUI list of selections.
1635 
1636  TString selection = G_selection_text->GetText();
1637  if (selection.IsNull()) return;
1638  if (MakeSelection(selection)) G_selection_text->Clear();
1639 }
1640 
1641 
1642 
1646 
1648 {
1649  // Method called when user hits 'return' in TTree leaf/alias GUI text-box
1650  // Generates a new alias using the expression in the text-box.
1651 
1652  TString alias = G_alias_text->GetText();
1653  TString name;
1654  name.Form("a%d", fAliasNumber++);
1655  SetAlias(name, alias);
1656  FillLeafList();
1657  G_alias_text->Clear();
1658 }
1659 
1660 
1661 
1666 
1668 {
1669  // Method called when user hits 'combine selections' button in selections GUI.
1670  // Generates new selection which is the intersection (logical AND) of
1671  // the currently selected selections.
1672 
1673  if (fSelectedSelections) {
1674  TEntryList* save_elist = fChain->GetEntryList();
1676  TString newselect;
1677  int nsel = fSelectedSelections->GetEntries();
1678  for (int i = 1; i < nsel; i++) {
1679  TString tmp;
1681  tmp.Form("(%s)", el->GetTitle());
1682  if (i > 1) newselect += " && ";
1683  newselect += tmp.Data();
1684  }
1685  MakeSelection(newselect);
1686  SetEntryList(save_elist);
1687  }
1688 }
1689 
1690 
1691 
1696 
1698 {
1699  // Method called when user hits 'combine selections' button in selections GUI.
1700  // Generates new selection which is the intersection (logical AND) of
1701  // the currently selected selections.
1702 
1703  if (fSelectedSelections) {
1704  TEntryList* save_elist = fChain->GetEntryList();
1705  SetEntryList(nullptr);
1706  TString newselect;
1707  int nsel = fSelectedSelections->GetEntries();
1708  for (int i = 0; i < nsel; i++) {
1709  TString tmp;
1711  tmp.Form("(%s)", el->GetTitle());
1712  if (i > 0) newselect += " || ";
1713  newselect += tmp.Data();
1714  }
1715  MakeSelection(newselect);
1716  SetEntryList(save_elist);
1717  }
1718 }
1719 
1720 
1721 
1724 
1726 {
1727  // Delete the currently selected selection(s)
1728 
1729  if (fSelectedSelections) {
1730  int nsel = fSelectedSelections->GetEntries();
1731  if (nsel < 1) return;
1732  for (int i = 0; i < nsel; i++) {
1734  if (!el) continue;
1735  fSelections.Remove(el);
1736  // if current selection, disable
1737  if (fChain->GetEntryList() == el) fChain->SetEntryList(nullptr);
1738  delete el;
1740  }
1742  }
1744 
1745 }
1746 
1747 
1748 
1751 
1753 {
1754  // Method called whenever the selected selection in the GUI list changes
1755 
1758  Bool_t resetSel = kTRUE;
1762 
1764  }
1765  else if (fSelectedSelections->GetEntries() == 1) {
1768  if (tmp->GetSize() != 0 || !strcmp("", G_selection_text->GetText())) {
1769  G_selection_text->SetText(((TNamed*)fSelectedSelections->At(0))->GetTitle());
1770  resetSel = kFALSE;
1771  }
1772  delete tmp;
1773  }
1774  else if (fSelectedSelections->GetEntries() > 1) {
1778  }
1779 
1780  if (resetSel) {
1782  if (tmp->GetSize() != 0) G_selection_text->SetText("");
1783  delete tmp;
1784  }
1785 }
1786 
1787 
1788 
1792 
1794 {
1795  // Method called whenever the leaf/alias selection in the TTree GUI list changes.
1796  // Updates the names of the leaves/aliases displayed next to the 'draw' button.
1797 
1799  fLeafExpr = "-";
1800  fXLeaf = fYLeaf = 0;
1801 // Bool_t resetSel = kTRUE;
1803  Int_t nleaf = fSelectedLeaves->GetEntries();
1804  if (nleaf) {
1805  if (nleaf == 1) {
1807  fLeafExpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1809 
1810  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1811  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1812  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0 || !strcmp("", G_alias_text->GetText())) {
1813  G_alias_text->SetText(fLeafExpr.Data()); //resetSel = kFALSE;
1814  }
1815  else if (strcmp(fLeafExpr.Data(), G_leaf_expr->GetTitle())) {
1816  TString tmps = G_alias_text->GetText();
1817  Int_t pos = G_alias_text->MaxMark();
1818  if (pos >= tmps.Sizeof()) pos = G_alias_text->MinMark();
1819  if (pos >= tmps.Sizeof()) pos = tmps.Sizeof() - 1;
1820  tmps.Insert(pos, fLeafExpr.Data());
1821  G_alias_text->SetText(tmps.Data());
1823  }
1824  delete tmp;
1825  delete tmp1;
1826 
1827  }
1828  else if (nleaf == 2) {
1829  fXLeaf = (TNamed*)fSelectedLeaves->At(1);
1831  TString X, Y;
1832  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1833  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1834  fLeafExpr.Form("%s:%s", Y.Data(), X.Data());
1836  G_alias_text->SetText("");
1837  }
1838  else if (nleaf == 3) {
1839  fXLeaf = (TNamed*)fSelectedLeaves->At(2);
1840  fYLeaf = (TNamed*)fSelectedLeaves->At(1);
1841  fZLeaf = (TNamed*)fSelectedLeaves->At(0);
1842  TString X, Y, Z;
1843  X = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1844  Y = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1845  Z = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
1846  fLeafExpr.Form("%s:%s:%s", Z.Data(), Y.Data(), X.Data());
1848  G_alias_text->SetText("");
1849  }
1850  else {
1851  fLeafExpr = "-";
1852  G_alias_text->SetText("");
1853  }
1854  }
1855  else {
1856  fLeafExpr = "-";
1857 // G_alias_text->SetText("");
1858  KVSeqCollection* tmp = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetName");
1859  KVSeqCollection* tmp1 = ((KVList*)((KVLVContainer*)G_leaflist->GetContainer())->GetUserItems())->GetSubListWithMethod(G_alias_text->GetText(), "GetTitle");
1860  if (tmp->GetSize() != 0 || tmp1->GetSize() != 0) {
1861  G_alias_text->SetText(""); //resetSel = kFALSE;
1862  }
1863  delete tmp;
1864  delete tmp1;
1865  }
1866 
1868  G_leaf_expr->Resize();
1869 }
1870 
1871 
1872 
1874 
1876 {
1877  fMethodCalled = kTRUE;
1878  fNx = Nx;
1879  fNy = Ny;
1880  fXmin = Xmin;
1881  fXmax = Xmax;
1882  fYmin = Ymin;
1883  fYmax = Ymax;
1884 }
1885 
1886 
1887 
1889 
1891 {
1892  fMethodCalled = kTRUE;
1893  fNxF = Nx;
1894  fXminF = Xmin;
1895  fXmaxF = Xmax;
1896 }
1897 
1898 
1899 
1901 
1903 {
1904  fMethodCalled = kTRUE;
1905  fNxD = Nx;
1906  fNyD = Ny;
1907  fOrderedDalitz = ordered;
1908 }
1909 
1910 
1911 
1913 
1915 {
1916  fMethodCalled = kTRUE;
1917  fWeight = Weight;
1918 }
1919 
1920 
1921 
1923 
1925 {
1926  TLeaf* lf = (TLeaf*)fChain->GetListOfLeaves()->FindObject(l->GetName());
1927  return lf->GetTypeName();
1928 }
1929 
1930 
1931 
1935 
1937 {
1938  // Method called when user hits 'draw' button in TTree GUI.
1939  // If only one leaf/alias is selected, this actually calls DrawLeaf.
1940 
1941  if (fLeafExpr == "-")return;
1942  Bool_t threeDexp = fSelectedLeaves->GetEntries() == 3;
1943  if (threeDexp && !fProfileHisto) {
1944  DrawAsDalitz();
1945  return;
1946  }
1947  if (fSelectedLeaves->GetEntries() == 1) {
1949  return;
1950  }
1951 
1952  if (fUserWeight) {
1954  Bool_t ok = KVBase::OpenContextMenu("DefineWeight", this);
1955  if (!ok) return;
1956  // cancel was pressed ?
1957  if (MethodNotCalled()) return;
1958  }
1959 
1960  int nx = 500, ny = 500;
1961  double xmin, xmax, ymin, ymax;
1962  xmin = xmax = ymin = ymax = 0;
1963  TString Xexpr, Yexpr, Zexpr;
1964  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
1965  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
1966  if (threeDexp) Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
1967  if (fXLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fXLeaf), "Char_t")) {
1968  TString tmp = Xexpr;
1969  Xexpr.Form("int(%s)", tmp.Data());
1970  }
1971  if (fYLeaf->InheritsFrom("TLeaf") && !strcmp(get_leaf_type_name(fYLeaf), "Char_t")) {
1972  TString tmp = Yexpr;
1973  Yexpr.Form("int(%s)", tmp.Data());
1974  }
1975 
1976  if (threeDexp) fLeafExpr.Form("%s:%s:%s", Zexpr.Data(), Yexpr.Data(), Xexpr.Data());
1977  else fLeafExpr.Form("%s:%s", Yexpr.Data(), Xexpr.Data());
1978  TString name;
1979  name.Form("h%d", fHistoNumber);
1980  TString drawexp(fLeafExpr), histo, histotitle;
1981  if (fUserWeight) GenerateHistoTitle(histotitle, fLeafExpr, "", fWeight);
1982  else GenerateHistoTitle(histotitle, fLeafExpr, "");
1983 
1984  // Check histo doesn't already exist
1985  // Look for list of histograms with given title as we don't distinguish TH2 from TProfile
1986  unique_ptr<KVSeqCollection> same_histo(fHistolist.GetSubListWithMethod(histotitle, "GetHistoTitle"));
1987  TIter nxtSame(same_histo.get());
1988  KVHistogram* kvhisto;
1989  while ((kvhisto = (KVHistogram*)nxtSame())) {
1990  if ((fProfileHisto && kvhisto->IsProfile()) || (!fProfileHisto && kvhisto->IsTH2())) {
1991  DrawHisto(kvhisto->GetHisto());
1992  return;
1993  }
1994  }
1995 
1996  if (fUserBinning) {
1998  Bool_t ok = KVBase::OpenContextMenu("DefineUserBinning", this);
1999  if (!ok) return;
2000  // cancel was pressed ?
2001  if (MethodNotCalled()) return;
2002  }
2003 
2004  xmin = fTree->GetMinimum(Xexpr);
2005  xmax = fTree->GetMaximum(Xexpr);
2006  if (fXLeaf->InheritsFrom("TLeaf") &&
2007  (!strcmp(get_leaf_type_name(fXLeaf), "Int_t") || !strcmp(get_leaf_type_name(fXLeaf), "Short_t") || !strcmp(get_leaf_type_name(fXLeaf), "Char_t"))
2008  ) {
2009  xmin -= 0.5;
2010  xmax += 0.5;
2011  nx = xmax - xmin;
2012  }
2013  ymin = fTree->GetMinimum(Yexpr);
2014  ymax = fTree->GetMaximum(Yexpr);
2015  if (fYLeaf->InheritsFrom("TLeaf") &&
2016  (!strcmp(get_leaf_type_name(fYLeaf), "Int_t") || !strcmp(get_leaf_type_name(fYLeaf), "Short_t") || !strcmp(get_leaf_type_name(fYLeaf), "Char_t"))
2017  ) {
2018  ymin -= 0.5;
2019  ymax += 0.5;
2020  ny = ymax - ymin;
2021  }
2022  if (fUserBinning) {
2023  nx = fNx;
2024  ny = fNy;
2025  xmin = fXmin;
2026  xmax = fXmax;
2027  ymin = fYmin;
2028  ymax = fYmax;
2029  }
2030 
2031  if (!fProfileHisto) histo.Form(">>%s(%d,%f,%f,%d,%f,%f)", name.Data(), nx, xmin, xmax, ny, ymin, ymax);
2032  else {
2033  if (fUserBinning) histo.Form(">>%s(%d,%f,%f)", name.Data(), nx, xmin, xmax);
2034  else histo.Form(">>%s", name.Data());
2035  }
2036  drawexp += histo;
2037  TString ww = "";
2038  if (fUserWeight) ww += fWeight;
2039  Long64_t drawResult;
2040  if (!fProfileHisto) drawResult = fTree->Draw(drawexp, ww.Data(), "goff");
2041  else drawResult = fTree->Draw(drawexp, ww.Data(), "prof,goff");
2042  if (drawResult < 0) {
2043  // Error: problem with Draw, probably bad expression
2044  new TGMsgBox(gClient->GetRoot(), fMain_histolist, "Error", "Problem drawing histogram: check the expressions?", kMBIconExclamation, kMBDismiss);
2045  return;
2046  }
2047  TH1* h(nullptr);
2048  if (IsPROOFEnabled())
2049  h = (TH1*)gProof->GetOutputList()->FindObject(name);
2050  else
2051  h = (TH1*)gDirectory->Get(name);
2052  h->SetTitle(histotitle);
2053  if (h->InheritsFrom("TH2")) h->SetOption(fDrawOption);
2054  h->SetDirectory(0);
2055  if (h->InheritsFrom("TH1")) h->GetXaxis()->SetTitle(fXLeaf->GetTitle());
2056  if (h->InheritsFrom("TH2") || h->InheritsFrom("TProfile")) h->GetYaxis()->SetTitle(fYLeaf->GetTitle());
2057 
2058  AddHisto(h);
2059  fHistoNumber++;
2060  DrawHisto(h);
2061 }
2062 
2063 
2064 
2065 
2067 
2069 {
2070  if ((!fXLeaf->InheritsFrom("TLeaf")) || (!fYLeaf->InheritsFrom("TLeaf")) || (!fZLeaf->InheritsFrom("TLeaf"))) {
2071  Warning("DrawAsDalitz", "Cannot be used with aliases !");
2072  return;
2073  }
2074 
2075  TString Xexpr, Yexpr, Zexpr;
2076  Xexpr = (fXLeaf->InheritsFrom("TLeaf") ? fXLeaf->GetName() : fXLeaf->GetTitle());
2077  Yexpr = (fYLeaf->InheritsFrom("TLeaf") ? fYLeaf->GetName() : fYLeaf->GetTitle());
2078  Zexpr = (fZLeaf->InheritsFrom("TLeaf") ? fZLeaf->GetName() : fZLeaf->GetTitle());
2079  fLeafExpr.Form("%s:%s:%s", Xexpr.Data(), Yexpr.Data(), Zexpr.Data());
2080 
2084 
2085  if ((!xType.Contains(yType.Data())) || (!yType.Contains(zType.Data()))) {
2086  Warning("DrawAsDalitz", "Leaves %s must have the same type !", fLeafExpr.Data());
2087  return;
2088  }
2089 
2090  Double_t x, y, z;
2091  Double_t var1, var2, var3;
2092  Float_t varf1, varf2, varf3;
2093  Int_t vari1, vari2, vari3;
2094  Short_t vars1, vars2, vars3;
2095  Char_t varc1, varc2, varc3;
2096  x = y = z = 0.;
2097 
2098  if (xType.Contains("Int_t")) {
2099  fTree->SetBranchAddress(Xexpr.Data(), &vari1);
2100  fTree->SetBranchAddress(Yexpr.Data(), &vari2);
2101  fTree->SetBranchAddress(Zexpr.Data(), &vari3);
2102  }
2103  else if (xType.Contains("Short_t")) {
2104  fTree->SetBranchAddress(Xexpr.Data(), &vars1);
2105  fTree->SetBranchAddress(Yexpr.Data(), &vars2);
2106  fTree->SetBranchAddress(Zexpr.Data(), &vars3);
2107  }
2108  else if (xType.Contains("Char_t")) {
2109  fTree->SetBranchAddress(Xexpr.Data(), &varc1);
2110  fTree->SetBranchAddress(Yexpr.Data(), &varc2);
2111  fTree->SetBranchAddress(Zexpr.Data(), &varc3);
2112  }
2113  else if (xType.Contains("Double_t")) {
2114  fTree->SetBranchAddress(Xexpr.Data(), &var1);
2115  fTree->SetBranchAddress(Yexpr.Data(), &var2);
2116  fTree->SetBranchAddress(Zexpr.Data(), &var3);
2117  }
2118  else if (xType.Contains("Float_t")) {
2119  fTree->SetBranchAddress(Xexpr.Data(), &varf1);
2120  fTree->SetBranchAddress(Yexpr.Data(), &varf2);
2121  fTree->SetBranchAddress(Zexpr.Data(), &varf3);
2122  }
2123 
2124  if (fUserBinning) {
2126  Bool_t ok = KVBase::OpenContextMenu("DefineUserBinningD", this, "DefineUserBinning");
2127  if (!ok) return;
2128  // cancel was pressed ?
2129  if (MethodNotCalled()) return;
2130  }
2131 
2132  TString histotitle;
2133  GenerateHistoTitle(histotitle, fLeafExpr, "");
2134 
2135  KVDalitzPlot* h = 0;
2136  if (fUserBinning) h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data(), fOrderedDalitz, fNxD, 0., 1.2, fNyD, 0., 1.2);
2137  else h = new KVDalitzPlot(Form("h%d", fHistoNumber), histotitle.Data());
2138  fHistoNumber++;
2139 
2140  TEntryList* el = fChain->GetEntryList();
2141  if (el) el->GetEntry(0);
2143 
2144  if (el) nentries = el->GetN();
2145  for (int i = 0; i < nentries; i++) {
2146  Int_t j = i;
2147  if (el) j = el->Next();
2148  fTree->GetEntry(j);
2149  if (xType.Contains("Int_t")) {
2150  x = vari1;
2151  y = vari2;
2152  z = vari3;
2153  }
2154  else if (xType.Contains("Short_t")) {
2155  x = vars1;
2156  y = vars2;
2157  z = vars3;
2158  }
2159  else if (xType.Contains("Char_t")) {
2160  x = varc1;
2161  y = varc2;
2162  z = varc3;
2163  }
2164  else if (xType.Contains("Double_t")) {
2165  x = var1;
2166  y = var2;
2167  z = var3;
2168  }
2169  else if (xType.Contains("Float_t")) {
2170  x = varf1;
2171  y = varf2;
2172  z = varf3;
2173  }
2174  h->FillAsDalitz(x, y, z);
2175  }
2176 
2177  h->SetOption("col");
2178  h->SetDirectory(0);
2179  AddHisto((TH2F*)h);
2180  DrawHisto(h);
2182 
2183 }
2184 
2185 
2186 
2189 
2191 {
2192  // Method called when user double-clicks a leaf/alias in list
2193 
2194  if (fUserWeight) {
2196  Bool_t ok = KVBase::OpenContextMenu("DefineWeight", this);
2197  if (!ok) return;
2198  // cancel was pressed ?
2199  if (MethodNotCalled()) return;
2200  }
2201 
2202  TH1* histo = nullptr;
2203  if (obj->InheritsFrom("TLeaf")) {
2204  TLeaf* leaf = (TLeaf*)fChain->GetListOfLeaves()->FindObject(obj->GetName());//dynamic_cast<TLeaf*>(obj);
2205  TString expr = leaf->GetName();
2206  TString type = leaf->GetTypeName();
2207  // check histo not already in list
2208  TString htit;
2209  if (fUserWeight) GenerateHistoTitle(htit, expr, "", fWeight);
2210  else GenerateHistoTitle(htit, expr, "");
2211  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2212  if (kvhisto) histo = kvhisto->GetHisto();
2213  if (!histo) {
2214  if (type == "Int_t" || type == "Char_t" || type == "Short_t") {
2215  Int_t xmin = fTree->GetMinimum(expr);
2216  Int_t xmax = fTree->GetMaximum(expr);
2217  if (type == "Char_t") {
2218  TString tmp;
2219  tmp.Form("int(%s)", expr.Data());
2220  expr = tmp.Data();
2221  }
2222  histo = MakeIntHisto(expr, "", xmin, xmax, (fUserWeight ? fWeight.Data() : ""));
2223  if (!histo) return;
2224  histo->GetXaxis()->SetTitle(leaf->GetName());
2225  }
2226  else {
2227  histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2228  if (!histo) return;
2229  histo->GetXaxis()->SetTitle(leaf->GetName());
2230  }
2231  if (!histo) return;
2232  }
2233 // if(fNewCanvas) {KVCanvas*c=new KVCanvas; c->SetTitle(histo->GetTitle()); c->SetWindowSize(600,600);}
2234 // histo->Draw();
2235 // if(histo->InheritsFrom("TH2")) gPad->SetLogz(fDrawLog);
2236 // else gPad->SetLogy(fDrawLog);
2237 // gPad->Modified();gPad->Update();
2238  DrawHisto(histo);
2239  }
2240  else {
2241  TString expr = obj->GetTitle();
2242  // check histo not already in list
2243  TString htit;
2244  GenerateHistoTitle(htit, expr, "", (fUserWeight ? fWeight.Data() : ""));
2245  KVHistogram* kvhisto = (KVHistogram*)fHistolist.FindObjectWithMethod(htit, "GetHistoTitle");
2246  if (kvhisto) histo = kvhisto->GetHisto();
2247  if (!histo) histo = MakeHisto(expr, "", 500, 0, (fUserWeight ? fWeight.Data() : ""));
2248  if (!histo) return;
2249  histo->GetXaxis()->SetTitle(obj->GetTitle());
2250 // if(fNewCanvas) {KVCanvas*c=new KVCanvas; c->SetTitle(histo->GetTitle());}
2251 // histo->Draw();
2252 // if(histo->InheritsFrom("TH2")) gPad->SetLogz(fDrawLog);
2253 // else gPad->SetLogy(fDrawLog);
2254 // gPad->Modified();gPad->Update();
2255  DrawHisto(histo);
2256  }
2257 }
2258 
2259 
2260 
2263 
2265 {
2266  // Method called when user histo selection changes in GUI histogram list
2267 
2271 // G_make_ip_scale->SetEnabled(kFALSE);
2272 // G_fit1->SetEnabled(kFALSE);
2273 // G_fit2->SetEnabled(kFALSE);
2274 // G_fit3->SetEnabled(kFALSE);
2275 // G_fitGG1->SetEnabled(kFALSE);
2276 // G_fitGG2->SetEnabled(kFALSE);
2277 // G_fitGG3->SetEnabled(kFALSE);
2279  if (fSelectedHistos) {
2280  if (fSelectedHistos->GetEntries() > 0) {
2282  if (fSelectedHistos->GetEntries() == 1 && fSelectedHistos->First()->IsA() == TH1F::Class()) {
2283 // G_make_ip_scale->SetEnabled(kTRUE);
2284 // G_fit1->SetEnabled(kTRUE);
2285 // G_fit2->SetEnabled(kTRUE);
2286 // G_fit3->SetEnabled(kTRUE);
2287 // G_fitGG1->SetEnabled(kTRUE);
2288 // G_fitGG2->SetEnabled(kTRUE);
2289 // G_fitGG3->SetEnabled(kTRUE);
2290  }
2292  }
2293  }
2294 }
2295 
2296 
2297 // void KVTreeAnalyzer::GenerateIPSelection()
2298 // {
2299 // // Method called when user hits 'return' in the 'b<...' text-box
2300 // // of the histogram GUI.
2301 // // Create a new selection of events based on the impact parameter
2302 // // scale previously created using MakeIPScale.
2303 //
2304 // TString bmax = G_make_ip_selection->GetText();
2305 // Double_t Bmax = bmax.Atof();
2306 // TGString histotit = G_ip_histo->GetText();
2307 // KVString ipvar,ipsel,ipweight;
2308 // KVHistogram::ParseHistoTitle(histotit.Data(),ipvar,ipsel,ipweight);
2309 // Double_t varCut = ipscale->GetObservable(Bmax);
2310 // TString selection;
2311 // selection.Form("%s>%f", ipvar.Data(), varCut);
2312 // TEntryList* save_elist = fChain->GetEntryList();
2313 // SetSelection(ipsel);
2314 // MakeSelection(selection);
2315 // SetEntryList(save_elist);
2316 // }
2317 //
2318 
2322 
2323 void KVTreeAnalyzer::GenerateConstantXSecSelections(const char* name, Double_t sigmaTot, Double_t sigmaBin)
2324 {
2325  // Generate selections corresponding to constant cross-section
2326  // using histogram with name
2327 
2328  MakeAbsoluteIPScale(name, sigmaTot);
2329  std::vector<Double_t> slices = ipscale->SliceXSec(sigmaTot / sigmaBin, sigmaTot);
2330  TH1* histo = GetHistogram(name);
2331  if (!histo) return;
2332  TString histotit = histo->GetTitle();
2333  KVString ipvar, ipsel, ipweight;
2334  KVHistogram::ParseHistoTitle(histotit.Data(), ipvar, ipsel, ipweight);
2335 
2336  bool integer_values = (name[0] == 'I');
2337 
2338  for (unsigned int i = 0; i < slices.size(); ++i) {
2339  Double_t varCut = slices[i];
2340  if (integer_values) varCut = TMath::Nint(varCut);
2341  Double_t varCutold = (i > 0 ? slices[i - 1] : 0.);
2342  if (integer_values) varCutold = TMath::Nint(varCutold);
2343  TString selection;
2344  if (i > 0) selection.Form("%s>=%f && %s<%f", ipvar.Data(), varCut, ipvar.Data(), varCutold);
2345  else selection.Form("%s>=%f", ipvar.Data(), varCut);
2346  TEntryList* save_elist = fChain->GetEntryList();
2347  SetSelection(ipsel);
2348  MakeSelection(selection);
2349  SetEntryList(save_elist);
2350  }
2351 }
2352 
2353 
2354 
2358 
2359 void KVTreeAnalyzer::MakeAbsoluteIPScale(const char* name, Double_t sigmaTot)
2360 {
2361  // generate absolute IP scale from named histogram
2362  // sigmaTot = total reaction cross-section [mb]
2364  TH1* histo = GetHistogram(name);
2365  if (!histo) return;
2366  ipscale = new KVImpactParameter(histo);
2368 // G_ip_histo->SetText(histo->GetTitle());
2369 // G_ip_histo->Resize();
2370 // G_make_ip_selection->SetEnabled(kTRUE);
2371 }
2372 
2373 
2374 
2376 
2378 {
2379  SetEntryList(GetSelection(sel));
2380 }
2381 
2382 
2383 
2386 
2388 {
2389  // Look for selection in list of selections
2390  return (TEntryList*)fSelections.FindObjectByTitle(selection);
2391 }
2392 
2393 
2395 
2397 {
2398  fPROOFEnabled = yes;
2399  if (yes) {
2400  // open new PROOF-lite session
2401  if (!gProof) TProof::Open("");
2402  if (fChain) fChain->SetProof(kTRUE);
2403  }
2404  else {
2405  if (fChain) fChain->SetProof(kFALSE);
2406  }
2407 }
2408 
2409 
2410 
2412 
2414 {
2415  Info("Save", "Saving analysis %s in file %s", GetTitle(), fSaveAnalysisFileName.Data());
2418 }
2419 
2420 
2421 
2428 
2429 void KVTreeAnalyzer::SaveAs(const char* filename, Option_t*) const
2430 {
2431  // Override TObject::SaveAs
2432  // We need to:
2433  // - (re)create the file
2434  // - do fChain->SetDirectory before writing to disk
2435 
2436  // save current directory
2437  TDirectory* sav = gDirectory;
2438  TDirectory* chsav = (fChain ? fChain->GetDirectory() : nullptr);
2439 
2440  TFile* f = TFile::Open(filename, "recreate");
2441  Write();
2442  if (fChain) { // make sure TChain doesn't get redirected
2443  fChain->SetDirectory(chsav);
2444  }
2445  delete f;
2446 
2447  // back to original directory
2448  sav->cd();
2449 }
2450 
2451 
2452 // void KVTreeAnalyzer::FitGum1()
2453 // {
2454 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2455 // if(!histo) return;
2456 // GDfirst->SetParameters(histo->GetMean(),histo->GetRMS());
2457 // histo->Fit(GDfirst,"EM");
2458 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2459 // if(!stats){
2460 // histo->SetStats(1);
2461 // histo->Draw();
2462 // gPad->Update();
2463 // stats = (TPaveStats*)histo->FindObject("stats");
2464 // }
2465 // if(stats){
2466 // // if canvas's 'no stats' option has been set by user,
2467 // // there will still be no valid stats object,
2468 // // so this test is to avoid the ensuing seg fault
2469 // stats->SetFitFormat("10.9g");
2470 // stats->SetOptFit(111);
2471 // }
2472 // histo->SetOption("e1");
2473 // histo->SetMarkerStyle(24);
2474 // histo->SetMarkerColor(kBlue+2);
2475 // gPad->Modified();gPad->Update();
2476 // SetAnalysisModifiedSinceLastSave(kTRUE);
2477 // }
2478 // void KVTreeAnalyzer::FitGum2()
2479 // {
2480 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2481 // if(!histo) return;
2482 // GDsecond->SetParameters(histo->GetMean(),histo->GetRMS());
2483 // histo->Fit(GDsecond,"EM");
2484 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2485 // if(!stats){
2486 // histo->SetStats(1);
2487 // histo->Draw();
2488 // gPad->Update();
2489 // stats = (TPaveStats*)histo->FindObject("stats");
2490 // }
2491 // if(stats){
2492 // // if canvas's 'no stats' option has been set by user,
2493 // // there will still be no valid stats object,
2494 // // so this test is to avoid the ensuing seg fault
2495 // stats->SetFitFormat("10.9g");
2496 // stats->SetOptFit(111);
2497 // }
2498 // histo->SetOption("e1");
2499 // histo->SetMarkerStyle(24);
2500 // histo->SetMarkerColor(kBlue+2);
2501 // gPad->Modified();gPad->Update();
2502 // SetAnalysisModifiedSinceLastSave(kTRUE);
2503 // }
2504 // void KVTreeAnalyzer::FitGum3()
2505 // {
2506 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2507 // if(!histo) return;
2508 // GDthird->SetParameters(histo->GetMean(),histo->GetRMS());
2509 // histo->Fit(GDthird,"EM");
2510 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2511 // if(!stats){
2512 // histo->SetStats(1);
2513 // histo->Draw();
2514 // gPad->Update();
2515 // stats = (TPaveStats*)histo->FindObject("stats");
2516 // }
2517 // if(stats){
2518 // // if canvas's 'no stats' option has been set by user,
2519 // // there will still be no valid stats object,
2520 // // so this test is to avoid the ensuing seg fault
2521 // stats->SetFitFormat("10.9g");
2522 // stats->SetOptFit(111);
2523 // }
2524 // histo->SetOption("e1");
2525 // histo->SetMarkerStyle(24);
2526 // histo->SetMarkerColor(kBlue+2);
2527 // gPad->Modified();gPad->Update();
2528 // SetAnalysisModifiedSinceLastSave(kTRUE);
2529 // }
2530 // void KVTreeAnalyzer::FitGausGum1()
2531 // {
2532 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2533 // if(!histo) return;
2534 // GausGum1->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2535 // histo->Fit(GausGum1,"EM");
2536 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2537 // if(!stats){
2538 // histo->SetStats(1);
2539 // histo->Draw();
2540 // gPad->Update();
2541 // stats = (TPaveStats*)histo->FindObject("stats");
2542 // }
2543 // if(stats){
2544 // // if canvas's 'no stats' option has been set by user,
2545 // // there will still be no valid stats object,
2546 // // so this test is to avoid the ensuing seg fault
2547 // stats->SetFitFormat("10.9g");
2548 // stats->SetOptFit(111);
2549 // }
2550 // histo->SetOption("e1");
2551 // histo->SetMarkerStyle(24);
2552 // histo->SetMarkerColor(kBlue+2);
2553 // gPad->Modified();gPad->Update();
2554 // SetAnalysisModifiedSinceLastSave(kTRUE);
2555 // }
2556 //
2557 // void KVTreeAnalyzer::FitGausGum2()
2558 // {
2559 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2560 // if(!histo) return;
2561 // GausGum2->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2562 // histo->Fit(GausGum2,"EM");
2563 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2564 // if(!stats){
2565 // histo->SetStats(1);
2566 // histo->Draw();
2567 // gPad->Update();
2568 // stats = (TPaveStats*)histo->FindObject("stats");
2569 // }
2570 // if(stats){
2571 // // if canvas's 'no stats' option has been set by user,
2572 // // there will still be no valid stats object,
2573 // // so this test is to avoid the ensuing seg fault
2574 // stats->SetFitFormat("10.9g");
2575 // stats->SetOptFit(111);
2576 // }
2577 // histo->SetOption("e1");
2578 // histo->SetMarkerStyle(24);
2579 // histo->SetMarkerColor(kBlue+2);
2580 // gPad->Modified();gPad->Update();
2581 // SetAnalysisModifiedSinceLastSave(kTRUE);
2582 // }
2583 //
2584 // void KVTreeAnalyzer::FitGausGum3()
2585 // {
2586 // TH1* histo = dynamic_cast<TH1*>(fSelectedHistos->First());
2587 // if(!histo) return;
2588 // GausGum3->SetParameters(0.5,histo->GetMean()+histo->GetRMS(),1,histo->GetRMS(),1);
2589 // histo->Fit(GausGum3,"EM");
2590 // TPaveStats* stats = (TPaveStats*)histo->FindObject("stats");
2591 // if(!stats){
2592 // histo->SetStats(1);
2593 // histo->Draw();
2594 // gPad->Update();
2595 // stats = (TPaveStats*)histo->FindObject("stats");
2596 // }
2597 // if(stats){
2598 // // if canvas's 'no stats' option has been set by user,
2599 // // there will still be no valid stats object,
2600 // // so this test is to avoid the ensuing seg fault
2601 // stats->SetFitFormat("10.9g");
2602 // stats->SetOptFit(111);
2603 // }
2604 // histo->SetOption("e1");
2605 // histo->SetMarkerStyle(24);
2606 // histo->SetMarkerColor(kBlue+2);
2607 // gPad->Modified();gPad->Update();
2608 // SetAnalysisModifiedSinceLastSave(kTRUE);
2609 // }
2610 
2611 
2616 
2618 {
2619  // fill and return TList with histos containing the given data
2620  // which may be 1D ("mult", "zmax", etc.) or 2D ("zmax:mult")
2621  // DELETE LIST AFTER USE
2622  TList* hlist = new TList;
2623  TIter next(&fHistolist);
2624 
2625  KVHistogram* h;
2626  while ((h = (KVHistogram*)next())) {
2627 
2628  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr)) hlist->Add(h->GetHisto());
2629  }
2630  return hlist;
2631 }
2632 
2633 
2634 
2638 
2640 {
2641  // fill and return TList with histos using the given selection criteria
2642  // DELETE LIST AFTER USE
2643  TList* hlist = new TList;
2644  TIter next(&fHistolist);
2645 
2646  KVHistogram* h;
2647  while ((h = (KVHistogram*)next())) {
2648 
2649  if (h->IsType("Histo") && !strcmp(h->GetSelection(), expr)) hlist->Add(h->GetHisto());
2650  }
2651  return hlist;
2652 }
2653 
2654 
2655 
2657 
2658 TH1* KVTreeAnalyzer::GetHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2659 {
2660  TIter next(&fHistolist);
2661 
2662  KVHistogram* h;
2663  while ((h = (KVHistogram*)next())) {
2664 
2665  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection)) {
2666  if (strcmp(weight, "")) {
2667  if (!strcmp(h->GetWeight(), weight)) return h->GetHisto();
2668  }
2669  else return h->GetHisto();
2670  }
2671  }
2672  return 0;
2673 }
2674 
2675 
2676 
2678 
2680 {
2681  return (KVHistogram*)fHistolist.FindObjectWithMethod(title, "GetHistoTitle");
2682 }
2683 
2684 
2685 
2687 
2688 void KVTreeAnalyzer::DeleteHisto(const Char_t* expr, const Char_t* selection, const Char_t* weight)
2689 {
2690  TIter next(&fHistolist);
2691 
2692  KVHistogram* h;
2693  while ((h = (KVHistogram*)next())) {
2694 
2695  if (h->IsType("Histo") && !strcmp(h->GetExpression(), expr) && !strcmp(h->GetSelection(), selection) && !strcmp(h->GetWeight(), weight)) {
2696  fHistolist.Remove(h);
2697  delete h;
2699  }
2700  }
2702 }
2703 
2704 
2705 
2708 
2710 {
2711  // Delete all currently selected histograms
2712  if (fSelectedHistos) {
2713  Int_t nsel = fSelectedHistos->GetEntries();
2714  if (nsel < 1) return;
2715  for (int i = 0; i < nsel; i++) {
2716  TObject* obj = fSelectedHistos->At(i);
2717  fHistolist.Remove(obj);
2718  delete obj;
2720  }
2722  }
2724 }
2725 
2726 
2727 
2732 
2734 {
2735  // Called when G_histo_add button is pressed
2736  // There should be 2 histograms in fSelectedHistos
2737  // We assume that both are of same type and have same binning etc.
2738 
2739  if (fSelectedHistos->GetEntries() != 2) return;
2740  HistoToAdd1 = dynamic_cast<KVHistogram*>(fSelectedHistos->At(0))->GetHisto();
2741  HistoToAdd2 = dynamic_cast<KVHistogram*>(fSelectedHistos->At(1))->GetHisto();
2742  if (HistoToAdd1 && HistoToAdd2) {
2743  Info("AddSelectedHistos", "Adding %s and %s", HistoToAdd1->GetName(), HistoToAdd2->GetName());
2744  TString name = Form("h%d", fHistoNumber);
2745  TString oldname = HistoToAdd1->GetName();
2746  if (oldname.BeginsWith("I")) name.Prepend("I");
2747  HistoAddResult = (TH1*)HistoToAdd1->Clone(name);
2749  Bool_t ok = KVBase::OpenContextMenu("HistoAddition", this);
2750  if (!ok) {
2751  Info("AddSelectedHistos", "Call to context menu not OK");
2752  delete HistoAddResult;
2753  return;
2754  }
2755  if (MethodNotCalled()) {
2756  Info("AddSelectedHistos", "You pressed cancel");
2757  delete HistoAddResult;
2758  return;
2759  }
2760  ++fHistoNumber;
2762  }
2763  else {
2764  Info("AddSelectedHistos", "Only possible for 2 histograms");
2765  }
2766 }
2767 
2768 
2769 
2771 
2773 {
2774  fMethodCalled = kTRUE;
2776 // TODO: it would be nice to distinguish histograms which are the result of
2777 // adding other histograms together. For the moment they appear identical to
2778 // to the first histogram in terms of variables etc. The following attempt
2779 // doesn't work (can't parse the title correctly)
2780 // TString title;
2781 // title.Form("SUMHIST:{%s,%s}",HistoToAdd1->GetTitle(),HistoToAdd2->GetTitle());
2782 // HistoAddResult->SetTitle(title);
2783 }
2784 
2785 
2786 
2787 
2790 
2792 {
2793  // regenerate entry lists for all selections
2794  TList old_lists;
2795  old_lists.AddAll(&fSelections);
2796  fSelections.Clear();
2798  TIter next(&old_lists);
2799  TEntryList* old_el;
2800  SetEntryList(nullptr);
2801  SelectionChanged();
2802  while ((old_el = (TEntryList*)next())) {
2803  cout << "REGENERATING SELECTION : " << old_el->GetTitle() << endl;
2804  MakeSelection(old_el->GetTitle());
2805  ((TEntryList*)fSelections.Last())->SetReapplyCut(old_el->GetReapplyCut());
2807  }
2808  old_lists.Delete();
2809 }
2810 
2811 
2812 
2814 
2816 {
2817  switch (id) {
2818  case MH_OPEN_CHAIN:
2819  OpenChain();
2820  break;
2821  case MH_OPEN_FILE:
2823  break;
2824  case MH_ADD_FRIEND:
2826  break;
2827  case MH_APPLY_ANALYSIS:
2829  break;
2830  case MH_SAVE_FILE:
2832  break;
2833  case MH_SAVE:
2834  Save();
2835  break;
2836  case MH_CLOSE:
2837  delete fMain_histolist;
2838  GUIClosed();
2839  break;
2840  case MH_QUIT:
2841  // check all analyzers need saving
2842  while (fgAnalyzerList->GetEntries() > 1) {
2843  TIter next(fgAnalyzerList);
2845  do {
2846  tan = (KVTreeAnalyzer*)next();
2847  }
2848  while (tan == this);
2849  tan->AnalysisSaveCheck();
2850  delete tan;
2851  }
2853  gROOT->ProcessLine(".q");
2854  break;
2855 
2856  default:
2857  break;
2858  }
2859 }
2860 
2861 
2863 
2865 {
2866  switch (id) {
2867  case SEL_COMB_AND:
2869  break;
2870 
2871  case SEL_COMB_OR:
2873  break;
2874 
2875  case SEL_DELETE:
2876  DeleteSelections();
2877  break;
2878 
2879  case SEL_UPDATE:
2880  UpdateEntryLists();
2881  break;
2882 
2883  case SEL_GEN_CONST_XSEC:
2884  KVBase::OpenContextMenu("GenerateConstantXSecSelections", this);
2885  break;
2886 
2887  default:
2888  break;
2889  }
2890 }
2891 
2892 
2893 
2895 
2897 {
2898  switch (opt) {
2899  case OPT_PROOF:
2902  EnablePROOF(false);
2903  }
2904  else {
2906  EnablePROOF();
2907  }
2908  }
2909 }
2910 
2911 
2912 
2915 
2917 {
2918  // Open a previous analysis session
2919 
2920  static TString dir(".");
2921  const char* filetypes[] = {
2922  "Analysis files", "Analysis*.root",
2923  0, 0
2924  };
2925  TGFileInfo fi;
2926  fi.fFileTypes = filetypes;
2927  fi.fIniDir = StrDup(dir);
2928  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2929  if (fi.fFilename) {
2930  KVTreeAnalyzer* newAnal = this;
2931  if (fTree) newAnal = new KVTreeAnalyzer(kFALSE);
2932  newAnal->OpenAnyFile(fi.fFilename);
2933  }
2934  dir = fi.fIniDir;
2935 }
2936 
2937 
2938 
2940 
2942 {
2943  static TString dir(".");
2944  const char* filetypes[] = {
2945  "ROOT files", "*.root",
2946  0, 0
2947  };
2948  TGFileInfo fi;
2949  fi.fFileTypes = filetypes;
2950  fi.fIniDir = StrDup(dir);
2951  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2952  if (fi.fFilename) {
2954  }
2955  dir = fi.fIniDir;
2956 }
2957 
2958 
2961 
2963 {
2964  // Open a file or files containing TTrees to analyse
2965 
2966  static TString dir(".");
2967  const char* filetypes[] = {
2968  "ROOT files", "*.root*",
2969  0, 0
2970  };
2971  TGFileInfo fi;
2972  fi.fFileTypes = filetypes;
2973  fi.fIniDir = StrDup(dir);
2975  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
2976  if (fi.fFileNamesList && fi.fFileNamesList->GetEntries()) {
2977 
2978  // look in first file to find first TTree and use its name/title
2979  TString theTreeName, theTreeTitle;
2981  KVList keys(0);
2982  keys.AddAll(file->GetListOfKeys());
2983  // Get list of trees in file
2984  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
2985  if (trees->GetEntries()) {
2986  theTreeName = trees->First()->GetName();
2987  theTreeTitle = trees->First()->GetTitle();
2988  }
2989  if (theTreeName != "") {
2990  // if analysis already en cours, open new GUI
2991  KVTreeAnalyzer* newAnal = this;
2992  if (fTree) newAnal = new KVTreeAnalyzer(kFALSE);
2993  newAnal->OpenChain(theTreeName, theTreeTitle, fi.fFileNamesList);
2994  }
2995  }
2996  dir = fi.fIniDir;
2997 }
2998 
2999 
3000 
3002 
3004 {
3005  static TString dir(".");
3006  const char* filetypes[] = {
3007  "ROOT files", "*.root",
3008  0, 0
3009  };
3010  TGFileInfo fi;
3011  fi.fFileTypes = filetypes;
3012  fi.fIniDir = StrDup(dir);
3013  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3014  if (fi.fFilename) {
3016  }
3017  dir = fi.fIniDir;
3018 }
3019 
3020 
3021 
3023 
3025 {
3026  const char* filetypes[] = {
3027  "Analysis files", "Analysis*.root",
3028  0, 0
3029  };
3030  TGFileInfo fi;
3031  fi.fFileTypes = filetypes;
3034  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDSave, &fi);
3035  if (fi.fFilename) {
3036  //if no ".xxx" ending given, we add ".root"
3037  TString filenam(fi.fFilename);
3038  if (!filenam.Contains('.'))
3039  filenam += ".root";
3040  // update name of file to autosave analysis in
3041  fSaveAnalysisFileName = filenam;
3042  Save();
3043  }
3045 }
3046 
3047 
3048 
3051 
3052 void KVTreeAnalyzer::OpenSingleFile(TFile* file)
3053 {
3054  // Open TTree in file (as a TChain) and import any histograms found in file
3055 
3056  fHistolist.Clear();
3057  KVList keys(0);
3058  keys.AddAll(file->GetListOfKeys());
3059  // Get list of trees in file
3060  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3061  if (trees->GetEntries()) {
3062  // Get name of first tree
3063  TString aTreeName = trees->First()->GetName();
3064  TString aFileName = file->GetName();
3065  TList fileList;
3066  TNamed ff(aFileName.Data(), "File Name");
3067  fileList.Add(&ff);
3068  OpenChain(aTreeName, trees->First()->GetTitle(), &fileList);
3069  }
3070  TIter next(&keys);
3071  TKey* akey;
3072  while ((akey = (TKey*)next())) {
3073  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3074  if (!fHistolist.FindObject(akey->GetName())) {
3075  TH1* h = (TH1*)file->Get(akey->GetName());
3076  h->SetDirectory(0);
3077  fHistolist.Add(new KVHistogram(h));
3078  }
3079  }
3080  }
3082 }
3083 
3084 
3085 
3089 
3091 {
3092  // assuming filepath is the URL of a ROOT file containing a previously-saved analysis, open it and
3093  // open the KVTreeAnalyzer object stored in it
3094 
3096 
3097  TFile* file = TFile::Open(filepath);
3098  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3099  if (kvta) {
3100  ReadFromFile(file);
3101  }
3102  else {
3103  OpenSingleFile(file);
3104  }
3106 }
3107 
3108 
3109 
3114 
3115 void KVTreeAnalyzer::OpenChain(const TString& treename, const TString& treetitle, const TSeqCollection* files)
3116 {
3117  // Open a TChain for analysis
3118  // treename/title is the name/title of the TTree :)
3119  // files is a list of objects with the names of the files in the chain
3120 
3121  fChain = new TChain(treename, treetitle);
3122  TIter nxt(files);
3123  TObject* o;
3124  while ((o = nxt())) fChain->Add(o->GetName());
3125  fChain->SetDirectory(0);
3126  SetTree(fChain);
3127  fHistolist.Clear();
3128  fSelections.Clear();
3129  fAliasList.Clear();
3130  fHistoNumber = 1;
3131  fSelectionNumber = 1;
3132  fAliasNumber = 1;
3133  fSameColorIndex = 0;
3134  fSelectedSelections = 0;
3135  fSelectedLeaves = 0;
3136  fSelectedHistos = 0;
3140  FillLeafList();
3142 }
3143 
3144 
3145 
3148 
3150 {
3151  // Generate all user aliases in list which are not already defined
3152 
3153  if (list->GetEntries()) {
3154  TIter next(list);
3155  TObject* o;
3156  while ((o = next())) {
3157  if (!GetAlias(o->GetTitle())) {
3158  Info("GenerateAllAliases", "Adding alias %s to leaflist", o->GetTitle());
3160  GenerateAlias();
3161  }
3162  }
3163  }
3164 }
3165 
3166 
3167 
3176 
3178 {
3179  // assuming filepath is the URL of a ROOT file, open it and,
3180  // if no KVTreeAnalyzer object is found, open first TTree in file
3181  // and apply all selections and generate all histograms which
3182  // were made for this analysis.
3183  // Any histograms in the file are added to the list of histograms.
3184  // If filepath contains an existing analysis, we add to it any
3185  // histograms/selections/aliases which are not defined
3186 
3187  TFile* file = TFile::Open(filepath);
3188  TObject* kvta = file->GetListOfKeys()->FindObject("KVTreeAnalyzer");
3189  if (kvta) {
3190  // open existing analysis, add any missing histos/selections/aliases
3191  delete file;
3192  KVTreeAnalyzer* applyAnal = OpenFile(filepath);
3193  applyAnal->GenerateAllSelections(&fSelections);
3194  applyAnal->GenerateAllHistograms(&fHistolist);
3195  applyAnal->GenerateAllAliases(&fAliasList);
3196  return;
3197  }
3198  else {
3199  delete file;
3200  KVTreeAnalyzer* applyAnal = new KVTreeAnalyzer(kFALSE);
3201  applyAnal->OpenAnyFile(filepath);
3202  applyAnal->GenerateAllSelections(&fSelections);
3203  applyAnal->GenerateAllHistograms(&fHistolist);
3204  // make sure no selection is left active without being displayed
3205  applyAnal->SetEntryList(nullptr);
3206  applyAnal->G_selection_status->SetText("CURRENT SELECTION:", 0);
3207  applyAnal->GenerateAllAliases(&fAliasList);
3208  }
3209 }
3210 
3211 
3212 
3214 
3215 void KVTreeAnalyzer::SetAlias(const Char_t* name, const Char_t* expr)
3216 {
3217  TString exp = expr;
3218  exp.ReplaceAll("d2r", "TMath::DegToRad()");
3219  exp.ReplaceAll("r2d", "TMath::RadToDeg()");
3220  fAliasList.Add(new TNamed(name, exp.Data()));
3222 }
3223 
3224 
3225 
3227 
3228 static const char* gSaveAsTypes[] = { "PostScript", "*.ps",
3229  "Encapsulated PostScript", "*.eps",
3230  "PDF", "*.pdf",
3231  "SVG", "*.svg",
3232  "TeX", "*.tex",
3233  "GIF", "*.gif",
3234  "ROOT files", "*.root",
3235  "XML", "*.xml",
3236  "PNG", "*.png",
3237  "XPM", "*.xpm",
3238  "JPEG", "*.jpg",
3239  "TIFF", "*.tiff",
3240  "XCF", "*.xcf",
3241  0, 0
3242  };
3243 
3244 
3245 
3250 
3252 {
3253  // Open file dialog box for user to choose directory and
3254  // image file-type for generating picture files of all
3255  // histos as they are drawn
3256 
3257  Info("SetUpHistoAutoSave", "Select image filetype and directory");
3258  TString workdir = gSystem->WorkingDirectory();
3259  static TString dir(".");
3260  static Int_t typeidx = 0;
3261  static Bool_t overwr = kFALSE;
3262  TGFileInfo fi;
3263  fi.fFileTypes = gSaveAsTypes;
3264  fi.fIniDir = StrDup(dir);
3265  fi.fFileTypeIdx = typeidx;
3266  fi.fOverwrite = overwr;
3267  new KVFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kKVFDDirectory, &fi);
3268  gSystem->ChangeDirectory(workdir.Data());
3269  TString ft = fi.fFileTypes[fi.fFileTypeIdx + 1];
3270  dir = fi.fIniDir;
3271  typeidx = fi.fFileTypeIdx;
3272  overwr = fi.fOverwrite;
3273  fAutoSaveDir = dir.Data();
3274  fAutoSaveType = ft(1, ft.Length()).Data();
3275  Info("SetUpHistoAutoSave", "file-type:%s directory:%s", fAutoSaveType.Data(), fAutoSaveDir.Data());
3276 }
3277 
3278 
3279 
3283 
3285 {
3286  // Save currently displayed histo as an image file
3287  // If 'same' checkbox is ticked, we use the same filename as used for the first histogram
3288 
3289  static TString lastFilename = "";
3290 
3291  if (fDrawSame) {
3292  gPad->SaveAs(lastFilename);
3293  return;
3294  }
3295  TString title = h->GetTitle();
3296  title.ReplaceAll(" ", "_");
3297  title.ReplaceAll("/", "#");
3298  title.ReplaceAll("*", "x");
3299  title.ReplaceAll("$", "#");
3300  title.ReplaceAll("(", "[");
3301  title.ReplaceAll(")", "]");
3302  title.Append(fAutoSaveType);
3303  title.Prepend("/");
3304  title.Prepend(fAutoSaveDir);
3305  Info("AutoSaveHisto", "Saved as: %s", title.Data());
3306  gPad->SaveAs(title);
3307  lastFilename = title;
3308 }
3309 
3310 
3311 
3315 
3317 {
3318  // We take the title of every object in 'list' and generate the corresponding selection
3319  // if it does not already exist
3320 
3321  TIter nextSel(list);
3322  TObject* sel;
3323  while ((sel = nextSel())) {
3324  if (!GetSelection(sel->GetTitle())) {
3325  Info("GenerateAllSelections", "Generating selection: %s", sel->GetTitle());
3326  MakeSelection(sel->GetTitle());
3327  }
3328  }
3329 }
3330 
3331 
3332 
3336 
3338 {
3339  // For every histogram in the list, we generate histograms for
3340  // the same expression, selection and weight if they don't already exist
3341 
3342  TIter nextHist(list);
3343  KVHistogram* obj;
3344  TH1* hist;
3345  while ((obj = (KVHistogram*)nextHist())) {
3346  if (!obj->IsType("Cut")) {
3347  hist = obj->GetHisto();
3348  if (GetHistoByTitle(hist->GetTitle())) continue;
3349  TString exp = obj->GetExpression();
3350  TString sel = obj->GetSelection();
3351  TString weight = obj->GetWeight();
3352  if (weight == "1") weight = "";
3353  // set selection
3354  Info("GenerateAllHistograms", "Generating histogram: %s", hist->GetTitle());
3355  SetSelection(sel);
3356  RemakeHisto(hist, exp, weight);
3357  }
3358  }
3359 }
3360 
3361 
3362 
3369 
3370 void KVTreeAnalyzer::Streamer(TBuffer& R__b)
3371 {
3372  // Read serialized object from file
3373  // For versions < 4, fHistolist contained TH* or TCutG objects:
3374  // we convert to a list of KVHistogram objects.
3375  // Flag will be set to say analysis needs saving.
3376  // Reparse all histogram expressions and selections in case they were not saved correctly.
3377 
3378  UInt_t R__s, R__c;
3379  if (R__b.IsReading()) {
3380  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
3381  R__b.ReadClassBuffer(KVTreeAnalyzer::Class(), this, R__v, R__s, R__c);
3382  if (R__v < 5) {
3383  // no fChain pointer member before v5
3384  ReconnectTree();
3385  }
3386  if (fChain && fTree != fChain) SetTree(fChain);
3387  if (fChain) {
3389  Info("Streamer", "Checking friends");
3390  // check friends are TChains, not TTrees & they have valid pointers
3391  TFriendElement* fe;
3392  TIter nxt(fChain->GetListOfFriends());
3393  KVNumberList toRemove;
3394  KVNameValueList infos;
3395  int idx = 0;
3396  while ((fe = (TFriendElement*)nxt())) {
3397  if (!fe->GetTree() || (fe->GetTree() && !fe->GetTree()->InheritsFrom("TChain"))) {
3398  Info("Streamer", "Found friend to convert to TChain");
3399  toRemove.Add(idx);
3400  infos.SetValue(Form("treeName%d", idx), fe->GetTreeName());
3401  if (!fe->GetFile()) {
3402  Info("Streamer", "Choose file containg friend tree %s", fe->GetTreeName());
3403  static TString dir(".");
3404  const char* filetypes[] = {
3405  "ROOT files", "*.root",
3406  0, 0
3407  };
3408  TGFileInfo fi;
3409  fi.fFileTypes = filetypes;
3410  fi.fIniDir = StrDup(dir);
3411  new TGFileDialog(gClient->GetDefaultRoot(), fMain_histolist, kFDOpen, &fi);
3412  if (fi.fFilename) {
3413  infos.SetValue(Form("fileName%d", idx), fi.fFilename);
3414  }
3415  dir = fi.fIniDir;
3416  }
3417  else
3418  infos.SetValue(Form("fileName%d", idx), fe->GetFile()->GetName());
3419  }
3420  ++idx;
3421  }
3422  if (toRemove.GetEntries()) {
3423  Info("Streamer", "Removing TTree friends");
3424  toRemove.Begin();
3425  while (!toRemove.End()) {
3426  fChain->RemoveFriend(fChain->GetFriend(infos.GetStringValue(Form("treeName%d", toRemove.Next()))));
3427  }
3428  toRemove.Begin();
3429  Info("Streamer", "Adding friends as TChains");
3430  while (!toRemove.End()) {
3431  idx = toRemove.Next();
3432  TChain* friendChain = new TChain(infos.GetStringValue(Form("treeName%d", idx)));
3433  friendChain->Add(infos.GetStringValue(Form("fileName%d", idx)));
3434  fChain->AddFriend(friendChain);
3435  }
3436  }
3437  }
3438  }
3439  if (R__v < 4) {
3440  //Info("Streamer","Converting old histo list");
3441  // convert fHistolist
3442  if (fHistolist.GetEntries()) {
3443  TList tmp;
3444  tmp.AddAll(&fHistolist);
3445  //Info("Streamer","List of histos to import:");
3446  //tmp.ls();
3447  fHistolist.SetOwner(kFALSE);
3448  fHistolist.Clear();
3449  fHistolist.SetOwner(kTRUE);
3450  TNamed* obj;
3451  TIter next(&tmp);
3452  while ((obj = (TNamed*)next())) {
3453  if (obj->InheritsFrom("TCutG"))
3454  fHistolist.Add(new KVHistogram(dynamic_cast<TCutG*>(obj)));
3455  else if (obj->InheritsFrom("TH1"))
3456  fHistolist.Add(new KVHistogram(dynamic_cast<TH1*>(obj)));
3457  }
3458  //Info("Streamer","New histolist:");
3459  fHistolist.ls();
3461  }
3462  }
3463  if (fHistolist.GetEntries()) {
3464  TIter next(&fHistolist);
3465  KVHistogram* h;
3466  while ((h = (KVHistogram*)next())) {
3467  if (h->IsType("Histo")) h->ParseExpressionAndSelection();
3468  }
3469  }
3470  }
3471  else {
3472  R__b.WriteClassBuffer(KVTreeAnalyzer::Class(), this);
3473  }
3474 }
3475 
3476 
3477 
3482 
3484 {
3485  // assuming filepath is the URL of a ROOT file, open it and
3486  // add the first TTree found in file as a friend of the current TTree
3487  // Any histograms in the file are added to the list of histograms
3488 
3489  TFile* file = TFile::Open(filepath);
3490  KVList keys(0);
3491  keys.AddAll(file->GetListOfKeys());
3492  // Get list of trees in file
3493  unique_ptr<KVSeqCollection> trees(keys.GetSubListWithMethod("TTree", "GetClassName"));
3494  if (trees->GetEntries()) {
3495  // Get name of first tree
3496  TString aTreeName = trees->First()->GetName();
3497  TChain* t = new TChain(aTreeName);
3498  t->Add(filepath);
3499  fChain->AddFriend(t);
3500  FillLeafList();
3501  }
3502  TIter next(&keys);
3503  TKey* akey;
3504  while ((akey = (TKey*)next())) {
3505  if (TClass::GetClass(akey->GetClassName())->InheritsFrom("TH1")) {
3506  if (!fHistolist.FindObject(akey->GetName())) {
3507  TH1* h = (TH1*)file->Get(akey->GetName());
3508  h->SetDirectory(0);
3509  fHistolist.Add(new KVHistogram(h));
3510  }
3511  }
3512  }
3514 }
3515 
3516 
3517 
3518 
3519 
3520 
int Int_t
unsigned int UInt_t
unsigned long ULong_t
kVerticalFrame
kHorizontalFrame
kMainFrame
void AssignAndDelete(TString &target, char *tobedeleted)
@ kKVFDDirectory
Definition: KVFileDialog.h:33
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
static const char * gSaveAsTypes[]
Int_t my_color_array[]
#define MAX_COLOR_INDEX
KVTreeAnalyzer * gTreeAnalyzer
#define SafeDelete(p)
#define f(i)
#define c(i)
#define e(i)
short Version_t
char Char_t
const Bool_t kFALSE
bool Bool_t
short Short_t
double Double_t
float Float_t
const Bool_t kTRUE
const char Option_t
kRed
kOrange
kGreen
kCyan
kBlue
kViolet
#define gDirectory
R__EXTERN TEnv * gEnv
EButtonState
#define gClient
kFDOpen
kFDSave
kDeepCleanup
kLHintsExpandY
kLHintsLeft
kLHintsCenterY
kLHintsCenterX
kLHintsTop
kLHintsExpandX
kMBNo
kMBClose
kMBYes
kMBDismiss
kMBIconExclamation
kMBIconStop
kTextCenterX
kTextLeft
kTextRight
int type
float xmin
int nentries
float ymin
float xmax
float ymax
double tan(double)
double exp(double)
R__EXTERN TProof * gProof
#define gROOT
char * Form(const char *fmt,...)
char * StrDup(const char *str)
R__EXTERN TSystem * gSystem
#define gPad
virtual Bool_t IsType(const Char_t *typ) const
Definition: KVBase.h:178
static void InitEnvironment()
Definition: KVBase.cpp:181
static Bool_t OpenContextMenu(const char *method, TObject *obj, const char *alt_method_name="")
Definition: KVBase.cpp:1458
TCanvas with mouse-controlled dynamic zoom and pan & scan.
Definition: KVCanvas.h:53
Fill 3D observables in a dalitz plot ,.
Definition: KVDalitzPlot.h:27
Modified version of TGFileDialog file selection dialog.
Definition: KVFileDialog.h:48
Wrapper for histograms and graphical cuts used by KVTreeAnalyzer.
Definition: KVHistogram.h:19
TCutG * GetCut() const
Definition: KVHistogram.h:40
static void ParseHistoTitle(const Char_t *title, KVString &exp, KVString &sel, KVString &weight)
const Char_t * GetExpression() const
Bool_t IsProfile() const
Definition: KVHistogram.h:44
const Char_t * GetSelection() const
TH1 * GetHisto() const
Definition: KVHistogram.h:36
const Char_t * GetWeight() const
Return weighting used for filling histogram.
Bool_t IsTH2() const
Definition: KVHistogram.h:48
Impact parameter analysis tools.
static Double_t GetIPFromXSec(Double_t xsec)
std::vector< Double_t > SliceXSec(Int_t nslices, Double_t totXsec)
void MakeAbsoluteScale(Int_t npoints=100, Double_t bmax=1.0)
virtual void SetIsBoolean(Bool_t isit=kTRUE)
Definition: KVLVContainer.h:87
Extension of TGLVContainer for KVListView widget.
Enhanced version of ROOT TGListView widget.
Definition: KVListView.h:145
virtual void ActivateSortButtons()
Definition: KVListView.cpp:72
virtual void SetDataColumns(Int_t ncolumns)
Definition: KVListView.cpp:91
void SetDoubleClickAction(const char *receiver_class, void *receiver, const char *slot)
Definition: KVListView.cpp:210
virtual KVLVColumnData * GetDataColumn(Int_t index) const
Definition: KVListView.h:167
virtual void Display(const TCollection *l)
Definition: KVListView.h:172
virtual void SetMaxColumnSize(UInt_t width)
Definition: KVListView.h:160
KVList * GetPickOrderedSelectedObjects() const
Definition: KVListView.h:250
TList * GetSelectedObjects() const
Definition: KVListView.h:244
virtual void RemoveAll()
Definition: KVListView.h:189
void AllowContextMenu(Bool_t on=kTRUE)
Definition: KVListView.h:282
virtual void SetDataColumn(Int_t index, const Char_t *name, const Char_t *method="", Int_t mode=kTextCenterX)
Definition: KVListView.cpp:106
void SetUseObjLabelAsRealClass(Bool_t yes=kTRUE)
Definition: KVListView.cpp:189
Extended TList class which owns its objects by default.
Definition: KVList.h:27
Handles lists of named parameters with different types, a list of KVNamedParameter objects.
void SetValue(const Char_t *name, value_type value)
const Char_t * GetStringValue(const Char_t *name) const
Strings used to represent a set of ranges of values.
Definition: KVNumberList.h:83
Bool_t End(void) const
Definition: KVNumberList.h:196
void Begin(void) const
Int_t GetEntries() const
Definition: KVNumberList.h:169
void Add(Int_t)
Add value 'n' to the list.
Int_t Next(void) const
KaliVeda extensions to ROOT collection classes.
virtual void Copy(TObject &obj) const
KVSeqCollection * GetSubListWithMethod(const Char_t *retvalue, const Char_t *method) const
virtual TObject * Last() const
virtual void SetOwner(Bool_t enable=kTRUE)
virtual void Clear(Option_t *option="")
virtual Int_t GetSize() const
virtual TObject * At(Int_t idx) const
virtual TObject * First() const
virtual TObject * FindObjectWithMethod(const Char_t *retvalue, const Char_t *method) const
virtual TObject * FindObjectByTitle(const Char_t *) const
Will return object with given title (value of TObject::GetTitle() method).
virtual void Add(TObject *obj)
virtual TObject * FindObjectWithNameAndType(const Char_t *name, const Char_t *type) const
virtual TObject * Remove(TObject *obj)
Remove object from list.
virtual TObject * FindObject(const char *name) const
Extension of ROOT TString class which allows backwards compatibility with ROOT v3....
Definition: KVString.h:72
KVString & FindCommonTitleCharacters(const TCollection *, const char bug=' *')
Definition: KVString.cpp:1350
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
void DefineUserBinning(Int_t Nx, Int_t Ny, Double_t Xmin, Double_t Xmax, Double_t Ymin, Double_t Ymax)
Bool_t fNormHisto
=kTRUE: generate normalised histograms (normalise to integral of histo)
TGCheckButton * G_histo_norm
void DefineUserBinning1F(Int_t NxF, Double_t XminF, Double_t XmaxF)
void SaveAs(const char *filename="", Option_t *option="") const
Bool_t IsPROOFEnabled() const
void MakeAbsoluteIPScale(const char *name, Double_t sigmaTot)
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.
void OpenAnyFile(const Char_t *filepath)
KVListView * G_histolist
GUI list of histograms.
Bool_t MakeSelection(const Char_t *selection)
void DefineUserBinningD(Int_t NxD, Int_t NyD, Int_t ordered)
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.
void DefineWeight(const Char_t *Weight)
Int_t fAliasNumber
used for automatic naming of TTree aliases
TH1 * RemakeHisto(TH1 *h, const Char_t *expr, const Char_t *weight="")
void SetAlias(const Char_t *name, const Char_t *expr)
Bool_t fDeletedByGUIClose
static KVList * fgAnalyzerList
static list of all analyzers in memory
TString fTreeFileName
name of file containing analyzed TTree
void DeleteSelectedHisto()
Delete all currently selected histograms.
void GUIClosed()
Called when graphical window is closed.
void GenerateConstantXSecSelections(const char *name, Double_t sigmaTot, Double_t sigmaBin)
KVImpactParameter * ipscale
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
TH1 * MakeHisto(const Char_t *expr, const Char_t *selection, Int_t nX, Int_t nY=0, const Char_t *weight="")
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
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 EnablePROOF(Bool_t yes=kTRUE)
KVList fHistolist
list of generated histograms
TGPopupMenu * fMenuFile
TList * GetHistosBySelection(const Char_t *expr)
void OpenAnyFriendFile(const Char_t *filepath)
TTree * fTree
for backwards compatibility
TGCheckButton * G_histo_norm_events
void GenerateAllSelections(TCollection *)
For applying existing analysis to new data.
TGPopupMenu * fSelGenerate
TString fAutoSaveType
filetype for autosaving histos
TH1 * GetHistogram(const Char_t *name) const
Return histogram with given name.
TGPopupMenu * fOptionMenu
Long64_t GetEntriesInCurrentSelection() const
KVListView * G_selectionlist
GUI list of TEntryList selections.
TGLabel * G_leaf_expr
TGStatusBar * G_selection_status
status bar in selections GUI
void AddSelection(TEntryList *)
TGLayoutHints * fMenuBarItemLayout
TGCheckButton * G_histo_same
TH1 * MakeIntHisto(const Char_t *expr, const Char_t *selection, Int_t Xmin, Int_t Xmax, const Char_t *weight="")
virtual ~KVTreeAnalyzer()
Destructor.
void OpenChain()
Open a file or files containing TTrees to analyse.
void SelectionChanged()
Method called whenever the selected selection in the GUI list changes.
TGMainFrame * fMain_histolist
GUI for handling histograms.
TH1 * GetHisto(const Char_t *expr, const Char_t *selection, const Char_t *weight="")
Bool_t fAnalysisModifiedSinceLastSave
TNamed * GetAlias(const Char_t *expr)
void HistoSelectionChanged()
Method called when user histo selection changes in GUI histogram list.
void GenerateHistoTitle(TString &title, const Char_t *exp, const Char_t *sel, const Char_t *weight="")
void ReadFromFile(const Char_t *filename)
open a previously saved analysis session.
Bool_t fDrawLog
=kTRUE: draw histograms with log-Y (1-D) or log-Z (2-D) scale
void HistoFileMenu_Open()
Open a previous analysis session.
void DrawLeaf(TObject *)
Method called when user double-clicks a leaf/alias in list.
KVList fAliasList
list of TTree aliases
TList * fSelectedSelections
void Copy(TObject &obj) const
void DrawHisto(TObject *o, Bool_t gen=kTRUE)
TGCheckButton * G_histo_autosave
TGTextEntry * G_selection_text
KVListView * G_leaflist
GUI list of TTree leaves and aliases.
Bool_t fMethodCalled
allows to know if context menu methods are called
void ResetMethodCalled()
virtual void Add(TObject *obj)
virtual void SetLineColor(Color_t lcolor)
Double_t GetXmax() const
Double_t GetXmin() const
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
Bool_t IsReading() const
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
virtual void SetDirectory(TDirectory *dir)
virtual void RemoveFriend(TTree *)
virtual TObjArray * GetListOfLeaves()
virtual void SetEntryList(TEntryList *elist, Option_t *opt="")
virtual Int_t Add(const char *name, Long64_t nentries=TTree::kMaxEntries)
virtual Long64_t GetEntries() const
virtual TFriendElement * AddFriend(const char *chainname, const char *dummy="")
virtual void SetProof(Bool_t on=kTRUE, Bool_t refresh=kFALSE, Bool_t gettreeheader=kFALSE)
virtual Long64_t Draw(const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
static TClass * GetClass(Bool_t load=kTRUE, Bool_t silent=kFALSE)
Bool_t InheritsFrom(const char *cl) const
virtual void ls(Option_t *option="") const
virtual void AddAll(const TCollection *col)
virtual Int_t GetEntries() const
virtual TObject * Clone(const char *newname="") const
const char * GetVarY() const
const char * GetVarX() const
virtual Bool_t cd(const char *path=nullptr)
virtual Bool_t GetReapplyCut() const
virtual Long64_t Next()
virtual Long64_t GetEntry(Int_t index)
virtual Long64_t GetN() const
virtual const char * GetValue(const char *name, const char *dflt) const
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
virtual TTree * GetTree()
virtual TFile * GetFile()
virtual const char * GetTreeName() const
virtual void SetToolTipText(const char *text, Long_t delayms=400)
virtual void SetEnabled(Bool_t e=kTRUE)
TGFrame * GetContainer() const
virtual void SetState(EButtonState state, Bool_t emit=kFALSE)
virtual void AddEntry(const char *s, Int_t id)
virtual void AddFrame(TGFrame *f, TGLayoutHints *l=0)
virtual void SetCleanup(Int_t mode=kLocalCleanup)
virtual TGDimension GetDefaultSize() const
virtual void MapSubwindows()
TList * fFileNamesList
char * fFilename
void SetMultipleSelection(Bool_t option)
Int_t fFileTypeIdx
const char ** fFileTypes
char * fIniDir
Bool_t fOverwrite
virtual UInt_t GetDefaultHeight() const
virtual void Resize(TGDimension size)
TGDimension GetSize() const
virtual void MapWindow()
virtual TGDimension GetDefaultSize() const
void SetText(const char *newText)
virtual const char * GetTitle() const
void SetIconPixmap(char **xpm_array)
void SetIconName(const char *name)
void SetWindowName(const char *name=0)
virtual void AddPopup(const char *s, TGPopupMenu *menu, TGLayoutHints *l, TGPopupMenu *before=0)
virtual Bool_t IsEntryChecked(Int_t id)
virtual void CheckEntry(Int_t id)
virtual void DisableEntry(Int_t id)
virtual void EnableEntry(Int_t id)
virtual void AddEntry(const char *s, Int_t id, void *ud=nullptr, const TGPicture *p=nullptr, TGMenuEntry *before=nullptr)
virtual void UnCheckEntry(Int_t id)
virtual void AddSeparator(TGMenuEntry *before=nullptr)
virtual void AddPopup(const char *s, TGPopupMenu *popup, TGMenuEntry *before=nullptr, const TGPicture *p=nullptr)
virtual void SetText(const char *text, Int_t partidx=0)
virtual void SetMaxLength(Int_t maxlen)
virtual void SetCursorPosition(Int_t pos)
const char * GetText() const
virtual void SetAlignment(ETextJustification mode=kTextLeft)
virtual void SetText(const char *text, Bool_t emit=kTRUE)
Int_t MaxMark() const
void Clear(Option_t *option="")
Int_t MinMark() const
virtual void SetName(const char *name)
virtual void RaiseWindow()
virtual void SetTitle(const char *title="")
virtual void Draw(Option_t *chopt="")
virtual void SetDirectory(TDirectory *dir)
virtual void SetTitle(const char *title)
virtual Bool_t Add(const TH1 *h, const TH1 *h2, Double_t c1=1, Double_t c2=1)
virtual Int_t GetNbinsY() const
Option_t * GetOption() const
TAxis * GetXaxis()
TAxis * GetYaxis()
TObject * Clone(const char *newname=0) const
virtual Double_t GetMaximum(Double_t maxval=FLT_MAX) const
virtual Int_t GetNbinsX() const
virtual void SetMaximum(Double_t maximum=-1111)
virtual void Draw(Option_t *option="")
virtual Double_t Integral(Int_t binx1, Int_t binx2, Option_t *option="") const
virtual void SetOption(Option_t *option=" ")
virtual void Scale(Double_t c1=1, Option_t *option="")
virtual void Sumw2(Bool_t flag=kTRUE)
virtual void SetStats(Bool_t stats=kTRUE)
virtual const char * GetClassName() const
virtual const char * GetTypeName() const
virtual void Add(TObject *obj)
virtual TObject * FindObject(const char *name) const
virtual TObject * At(Int_t idx) const
virtual void Delete(Option_t *option="")
virtual TObject * First() const
virtual const char * GetName() const
virtual void Copy(TObject &named) const
virtual void SetTitle(const char *title="")
virtual const char * GetTitle() const
virtual TObject * FindObject(const char *name) const
virtual Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
virtual const char * GetName() const
virtual void Warning(const char *method, const char *msgfmt,...) const
virtual Bool_t InheritsFrom(const char *classname) const
virtual void Error(const char *method, const char *msgfmt,...) const
virtual const char * GetTitle() const
virtual void Info(const char *method, const char *msgfmt,...) const
static TProof * Open(const char *url=0, const char *conffile=0, const char *confdir=0, Int_t loglevel=0)
TList * GetOutputList()
Bool_t Connect(const char *signal, const char *receiver_class, void *receiver, const char *slot)
Ssiz_t Length() const
TString & Insert(Ssiz_t pos, const char *s)
Ssiz_t First(char c) const
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
TString & Append(char c, Ssiz_t rep=1)
const char * Data() const
Bool_t IsNull() const
TString & Prepend(char c, Ssiz_t rep=1)
virtual Int_t Sizeof() const
void Form(const char *fmt,...)
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
TString & ReplaceAll(const char *s1, const char *s2)
virtual const char * DirName(const char *pathname)
virtual char * ConcatFileName(const char *dir, const char *name)
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
virtual Bool_t ChangeDirectory(const char *path)
virtual const char * BaseName(const char *pathname)
virtual Bool_t IsAbsoluteFileName(const char *dir)
virtual const char * WorkingDirectory()
static void SingleShot(Int_t milliSec, const char *receiver_class, void *receiver, const char *method)
virtual TObjArray * GetListOfLeaves()
virtual Int_t GetEntry(Long64_t entry, Int_t getall=0)
TFile * GetCurrentFile() const
virtual TTree * GetFriend(const char *) const
virtual Double_t GetMaximum(const char *columname)
virtual TEntryList * GetEntryList()
Int_t SetBranchAddress(const char *bname, T **add, TBranch **ptr=0)
virtual Long64_t GetEntries() const
virtual Long64_t Draw(const char *varexp, const char *selection, Option_t *option="", Long64_t nentries=kMaxEntries, Long64_t firstentry=0)
virtual TList * GetListOfFriends() const
TDirectory * GetDirectory() const
virtual Double_t GetMinimum(const char *columname)
virtual void ResetBranchAddresses()
virtual TList * GetListOfAliases() const
long long Long64_t
RooCmdArg Weight(Double_t wgt)
return c1
Double_t y[n]
Double_t x[n]
return c2
TH1 * h
Int_t Nint(T x)
auto * l