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