Avoid jumping of entries in data-selector window -- restore scrollbar position after...
[u/mrichter/AliRoot.git] / EVE / EveBase / AliEveEventSelectorWindow.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
3  * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
4  * full copyright notice.                                                 *
5  **************************************************************************/
6
7 ///////////////////////////////////////////////////////////////////////////
8 //
9 //  implementation of a GUI for the event/trigger selection
10 //
11 //  origin: Mikolaj Krzewicki, mikolaj.krzewicki@cern.ch
12 //
13 //////////////////////////////////////////////////////////////////////////
14
15 #include "AliEveEventSelectorWindow.h"
16 #include "AliEveEventSelector.h"
17 #include "AliEveEventManager.h"
18 #include <TGTextEntry.h>
19 #include <TGNumberEntry.h>
20 #include <TRootEmbeddedCanvas.h>
21 #include <TCanvas.h>
22 #include <TGButton.h>
23 #include <TGComboBox.h>
24 #include <TGLabel.h>
25 #include <TTree.h>
26 #include <AliESDEvent.h>
27 #include <AliESDRun.h>
28 #include <TH1.h>
29 #include <TDirectory.h>
30 #include <TROOT.h>
31
32 ClassImp(AliEveEventSelectorWindow)
33 //______________________________________________________________________________
34 AliEveEventSelectorWindow::AliEveEventSelectorWindow(const TGWindow *p, UInt_t w, UInt_t h,
35                                                      AliEveEventSelector* sel) :
36   TGMainFrame(p, w, h),
37   fPSelector(sel),
38   fPCanvas(0),
39   fPDrawFormula(0),
40   fPEntryFormula(0),
41   fPEntryLowerBound(0),
42   fPEntryHigherBound(0),
43   fPButtonTextDone(0),
44   fPComboBoxTrigger(0),
45   fPEntryTriggerSelection(0),
46   fPCheckTriggerSimple(0),
47   fPCheckTriggerString(0),
48   fPEntryMultHigh(0),
49   fPEntryMultLow(0)
50 {
51   //ctor
52
53   //the canvas
54   fPCanvas = new TRootEmbeddedCanvas(0,this);
55   Int_t wid = fPCanvas->GetCanvasWindowId();
56   TCanvas *myc = new TCanvas("MyCanvas", 10,10,wid);
57   fPCanvas->AdoptCanvas(myc);
58   AddFrame(fPCanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY));
59
60   //draw box frame
61   TGHorizontalFrame* hframedraw = new TGHorizontalFrame(this);
62   AddFrame(hframedraw, new TGLayoutHints((kLHintsExpandX), 5,5,2,1));
63
64   TGLabel* drawlabel = new TGLabel(hframedraw, "Draw preview");
65   hframedraw->AddFrame(drawlabel, new TGLayoutHints(kLHintsLeft, 2,6,2));
66   fPDrawFormula = new TGTextEntry(hframedraw);
67   hframedraw->AddFrame(fPDrawFormula, new TGLayoutHints(kLHintsExpandX));
68   TGTextButton* buttondraw = new TGTextButton(hframedraw,"Draw");
69   buttondraw->Connect("Clicked()","AliEveEventSelectorWindow",
70                               this, "DoDrawHistogram()");
71   hframedraw->AddFrame(buttondraw, new TGLayoutHints(kLHintsLeft));
72   TGTextButton* buttonview = new TGTextButton(hframedraw,"Browse");
73   buttonview->Connect("Clicked()","TTree",fPSelector->GetESDTree(),"StartViewer()");
74   hframedraw->AddFrame(buttonview, new TGLayoutHints(kLHintsLeft));
75
76
77   //text selection frame
78   TGHorizontalFrame *hframetxtsel = new TGHorizontalFrame(this);
79   AddFrame(hframetxtsel, new TGLayoutHints((kLHintsExpandX), 5,5,1,1));
80
81   TGLabel* exprlabel = new TGLabel(hframetxtsel, "Expression");
82   hframetxtsel->AddFrame(exprlabel, new TGLayoutHints(kLHintsLeft, 6,2,2));
83
84   TGCheckButton* checktextsel = new TGCheckButton(hframetxtsel);
85   checktextsel->Connect("Toggled(Bool_t)", "AliEveEventSelector",
86                         fPSelector, "SetSelectOnString(Bool_t)");
87   checktextsel->SetState(fPSelector->GetSelectOnString() ? kButtonDown : kButtonUp);
88   hframetxtsel->AddFrame(checktextsel, new TGLayoutHints(kLHintsLeft, 0,0,1));
89
90   fPEntryLowerBound = new TGNumberEntry(hframetxtsel);
91   hframetxtsel->AddFrame(fPEntryLowerBound, new TGLayoutHints(kLHintsLeft));
92   fPEntryFormula = new TGTextEntry(hframetxtsel);
93   hframetxtsel->AddFrame(fPEntryFormula, new TGLayoutHints(kLHintsExpandX));
94   fPEntryHigherBound = new TGNumberEntry(hframetxtsel);
95   hframetxtsel->AddFrame(fPEntryHigherBound, new TGLayoutHints(kLHintsLeft));
96   fPButtonTextDone = new TGTextButton(hframetxtsel,"Set");
97   fPButtonTextDone->Connect("Clicked()", "AliEveEventSelectorWindow",
98                             this, "DoSetSelectionString()");
99   hframetxtsel->AddFrame(fPButtonTextDone, new TGLayoutHints(kLHintsLeft));
100
101   //trigger cuts frame
102   TGHorizontalFrame* hframetrigger = new TGHorizontalFrame(this);
103   AddFrame(hframetrigger, new TGLayoutHints((kLHintsLeft|kLHintsExpandX), 5,5,1,1));
104
105   TGLabel* triglabel = new TGLabel(hframetrigger, "Trigger type");
106   hframetrigger->AddFrame(triglabel, new TGLayoutHints(kLHintsLeft, 0,2,2));
107   fPCheckTriggerSimple = new TGCheckButton(hframetrigger);
108   fPCheckTriggerSimple->Connect("Toggled(Bool_t)","AliEveEventSelector",
109                           fPSelector,"SetSelectOnTriggerType(Bool_t)");
110   fPCheckTriggerSimple->SetState(fPSelector->GetSelectOnTriggerType() ? kButtonDown : kButtonUp );
111   hframetrigger->AddFrame(fPCheckTriggerSimple, new TGLayoutHints(kLHintsLeft, 0,0,1));
112   fPComboBoxTrigger = new TGComboBox(hframetrigger);
113   fPComboBoxTrigger->Resize(200,20);
114   fPComboBoxTrigger->Connect("Selected(const char*)","AliEveEventSelectorWindow",
115                              this,"DoHandleTriggerFromComboBox(const char*)");
116   hframetrigger->AddFrame(fPComboBoxTrigger, new TGLayoutHints(kLHintsLeft));
117
118   TGLabel* labelfreetrig = new TGLabel(hframetrigger, "Expression");
119   hframetrigger->AddFrame(labelfreetrig, new TGLayoutHints(kLHintsLeft, 4,2,2));
120   fPCheckTriggerString = new TGCheckButton(hframetrigger);
121   hframetrigger->AddFrame(fPCheckTriggerString, new TGLayoutHints(kLHintsLeft, 0,0,1));
122   fPCheckTriggerString->Connect("Toggled(Bool_t)","AliEveEventSelector",
123                            fPSelector,"SetSelectOnTriggerString(Bool_t)");
124   fPCheckTriggerString->SetState(fPSelector->GetSelectOnTriggerString() ? kButtonDown : kButtonUp );
125   fPEntryTriggerSelection = new TGTextEntry(hframetrigger);
126   hframetrigger->AddFrame(fPEntryTriggerSelection, new TGLayoutHints(kLHintsExpandX));
127   TGTextButton* buttontrigsel = new TGTextButton(hframetrigger,"Set");
128   hframetrigger->AddFrame(buttontrigsel, new TGLayoutHints(kLHintsLeft));
129   buttontrigsel->Connect("Clicked()","AliEveEventSelectorWindow",
130                          this, "DoSetTriggerSelectionString()");
131
132   //multiplicity cuts frame
133   TGHorizontalFrame* hframemult = new TGHorizontalFrame(this);
134   AddFrame(hframemult, new TGLayoutHints((kLHintsLeft), 5,5,1,1));
135
136   TGLabel* multlabel = new TGLabel(hframemult, "Multiplicity");
137   hframemult->AddFrame(multlabel, new TGLayoutHints(kLHintsLeft, 7,2,2));
138   TGCheckButton* checkmult = new TGCheckButton(hframemult);
139   checkmult->Connect("Toggled(Bool_t)", "AliEveEventSelector",
140                       fPSelector,"SetSelectOnMultiplicity(Bool_t)");
141   checkmult->SetState(fPSelector->GetSelectOnMultiplicity() ? kButtonDown : kButtonUp );
142   hframemult->AddFrame(checkmult, new TGLayoutHints(kLHintsLeft, 0,0,1));
143   fPEntryMultLow = new TGNumberEntry(hframemult);
144   hframemult->AddFrame(fPEntryMultLow, new TGLayoutHints(kLHintsLeft));
145   fPEntryMultHigh = new TGNumberEntry(hframemult);
146   hframemult->AddFrame(fPEntryMultHigh, new TGLayoutHints(kLHintsLeft));
147   TGTextButton* buttonmultset = new TGTextButton(hframemult,"Set");
148   hframemult->AddFrame(buttonmultset, new TGLayoutHints(kLHintsLeft));
149   buttonmultset->Connect("Clicked()","AliEveEventSelectorWindow",
150                          this, "DoSetMultiplicityRange()");
151
152   //wrap around
153   TGHorizontalFrame* hframewrap = new TGHorizontalFrame(this);
154   AddFrame(hframewrap, new TGLayoutHints((kLHintsLeft), 5,5,1,2));
155
156   TGLabel* wraplabel = new TGLabel(hframewrap, "Wrap around at the end:");
157   hframewrap->AddFrame(wraplabel, new TGLayoutHints(kLHintsLeft, 0,4,1));
158   TGCheckButton* checkwraparound = new TGCheckButton(hframewrap);
159   hframewrap->AddFrame(checkwraparound, new TGLayoutHints(kLHintsLeft));
160   checkwraparound->Connect("Toggled(Bool_t)","AliEveEventSelector",
161                            fPSelector, "SetWrapAround(Bool_t)");
162   checkwraparound->SetState(fPSelector->GetWrapAround() ? kButtonDown : kButtonUp );
163
164   SetupTriggerSelect();
165   
166   //bookkeeping
167   SetWindowName("Event Selection");
168   MapSubwindows();
169
170   Resize(GetDefaultSize());
171   MapWindow();
172 }
173
174 //______________________________________________________________________________
175 AliEveEventSelectorWindow::~AliEveEventSelectorWindow()
176 {
177   //dtor
178 }
179
180 //______________________________________________________________________________
181 void AliEveEventSelectorWindow::SetupTriggerSelect()
182
183   //Set up the list of available triggers
184
185   // Do nothing if already enabled.
186   if (fPComboBoxTrigger->GetNumberOfEntries() > 0)
187     return;
188   AliEveEventManager* fM = fPSelector->GetEventManager();
189   AliESDEvent* esd = fM->GetESD();
190     
191   if (esd && fM->GetESDFile() != 0)
192   { 
193     TString activetrg = esd->GetESDRun()->GetActiveTriggerClasses();  //Get list of active classes
194     TObjArray* activetrgarr = activetrg.Tokenize(" "); //break up the classes string, space as separator
195     Int_t entries = activetrgarr->GetEntries();  //how many triggerclasses
196     TString entry;  //to hold the triger class name
197     TObjString* entryobj;
198     if (entries == 0)
199     {
200       fPComboBoxTrigger->SetEnabled(kFALSE);  //no trigger classes
201     }
202     else
203     {
204       fPComboBoxTrigger->RemoveAll(); //some initial cleanup
205       fPComboBoxTrigger->SetEnabled(kTRUE);  //no trigger classes
206       //fPComboBoxTrigger->AddEntry("",-1);  //first entry empty - select to not filter by trigger
207       for (Int_t i=0;i<entries;i++)
208       {
209         entryobj = (TObjString*)activetrgarr->At(i);
210         entry = entryobj->GetString();
211         fPComboBoxTrigger->AddEntry(entry.Data(), i);
212       }
213     }
214     fPComboBoxTrigger->Select(0, kTRUE); //set default no filtering and emit
215     fPComboBoxTrigger->SetEnabled(kTRUE);
216   } 
217   else
218   { 
219     fPComboBoxTrigger->SetEnabled(kFALSE);
220   } 
221
222
223 //______________________________________________________________________________
224 void AliEveEventSelectorWindow::DoSetSelectionString()
225 {
226   //process the entered formula and send it to the selector
227
228   TString str = fPEntryFormula->GetText();
229   TString s;
230   if (fPEntryLowerBound->GetNumber()==0&&fPEntryHigherBound->GetNumber()==0)
231   {
232     s = str;
233   }
234   else
235   {
236     s += "(";
237     s += str;
238     s += ")>";
239     s += fPEntryLowerBound->GetNumber();
240     s += "&&";
241     s += "(";
242     s += str;
243     s += ")<";
244     s += fPEntryHigherBound->GetNumber();
245   }
246   fPSelector->SetSelectionString(s);
247 }
248
249 //______________________________________________________________________________
250 void AliEveEventSelectorWindow::DoDrawHistogram()
251 {
252   //Draw histogram with formula in the draw field
253
254   TTree* tree = fPSelector->GetESDTree();
255   TString str = fPDrawFormula->GetText();
256   str += ">>selectionhist";
257
258   TH1 *hist = dynamic_cast<TH1*>(gDirectory->Get("selectionhist"));
259   if (hist) delete hist;
260
261   TEvePadHolder padSwitch(kTRUE, fPCanvas->GetCanvas());
262   tree->Draw(str);
263 }
264
265 //______________________________________________________________________________
266 void AliEveEventSelectorWindow::DoSetTriggerSelectionString()
267 {
268   //Set trigger selection formula
269   
270   TString string = fPEntryTriggerSelection->GetText();
271   fPSelector->SetTriggerSelectionString(string);
272   fPEntryTriggerSelection->SetToolTipText(fPSelector->GetTriggerSelectionString());
273 }
274
275 //______________________________________________________________________________
276 void AliEveEventSelectorWindow::DoHandleTriggerFromComboBox(const char* str)
277 {
278   //Dispatch the trigger selection to proper destination
279   
280   if (fPSelector->GetSelectOnTriggerString() && !fPSelector->GetSelectOnTriggerType())
281   {
282     fPEntryTriggerSelection->Insert(str);
283     fPEntryTriggerSelection->SetFocus();
284   }
285   if (fPSelector->GetSelectOnTriggerType())
286     fPSelector->SetTriggerType(str);
287 }
288
289 //______________________________________________________________________________
290 void AliEveEventSelectorWindow::DoSetMultiplicityRange()
291 {
292   //Set the multiplicity range
293   
294   fPSelector->SetMultiplicityLow(fPEntryMultLow->GetNumber());
295   fPSelector->SetMultiplicityHigh(fPEntryMultHigh->GetNumber());
296 }