Improved quitting Event Display with close button.
[u/mrichter/AliRoot.git] / EVE / EveBase / AliEveEventManagerEditor.cxx
1 // @(#)root/eve:$Id$
2 // Author: Matevz Tadel 2007
3
4 /**************************************************************************
5  * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6  * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
7  * full copyright notice.                                                 *
8  **************************************************************************/
9
10 #include "AliEveEventManagerEditor.h"
11 #include "AliEveEventManager.h"
12 #include "AliEveConfigManager.h"
13
14 #include <AliESDEvent.h>
15
16 #include <TVirtualPad.h>
17 #include "TColor.h"
18
19 #include <TEveGValuators.h>
20 #include <TGButton.h>
21 #include <TGTextView.h>
22 #include <TGLabel.h>
23
24 #include "Riostream.h"
25
26 #ifdef ZMQ
27 #include "AliStorageAdministratorPanelListEvents.h"
28 #include "AliStorageAdministratorPanelMarkEvent.h"
29 #endif
30
31 //______________________________________________________________________________
32 // GUI editor for AliEveEventManager.
33 //
34
35 using std::ofstream;
36 using std::ios;
37 using std::cout;
38 using std::endl;
39
40 ClassImp(AliEveEventManagerEditor)
41
42 //______________________________________________________________________________
43 AliEveEventManagerEditor::AliEveEventManagerEditor(const TGWindow *p, Int_t width, Int_t height,
44                                                    UInt_t options, Pixel_t back) :
45   TGedFrame(p, width, height, options | kVerticalFrame, back),
46   fM(0),
47   fDumpEventInfo(0),
48   fEventInfo(0)
49 {
50   // Constructor.
51
52   MakeTitle("AliEveEventManager");
53
54   {
55     TGHorizontalFrame* f = new TGHorizontalFrame(this);
56     fDumpEventInfo = new TGTextButton(f, "Dump Event Info");
57     fDumpEventInfo->SetToolTipText("Append information about current event to event_info.txt file.");
58     fDumpEventInfo->SetWidth(120);
59     fDumpEventInfo->ChangeOptions(fDumpEventInfo->GetOptions() | kFixedWidth);
60     f->AddFrame(fDumpEventInfo, new TGLayoutHints(kLHintsNormal, 4,0,0,0));
61     fDumpEventInfo->Connect("Clicked()",
62                         "AliEveEventManagerEditor", this, "DumpEventInfo()");
63     AddFrame(f, new TGLayoutHints(kLHintsExpandX, 8,8,8,0));
64   }
65   {
66     TGVerticalFrame* f = new TGVerticalFrame(this);
67
68     TGLabel *eventInfoLabel = new TGLabel(f, "Event Information:");
69     f->AddFrame(eventInfoLabel, new TGLayoutHints(kLHintsNormal, 0,0,6,2));
70
71     fEventInfo = new TGTextView(f, 200, 300);
72     f->AddFrame(fEventInfo, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
73
74     AddFrame(f, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
75   }
76 }
77
78 /******************************************************************************/
79
80 //______________________________________________________________________________
81 void AliEveEventManagerEditor::SetModel(TObject* obj)
82 {
83   // Set model object.
84
85   fM = static_cast<AliEveEventManager*>(obj);
86
87   fEventInfo->LoadBuffer(fM->GetEventInfoVertical());
88 }
89
90 /******************************************************************************/
91
92 //______________________________________________________________________________
93 void AliEveEventManagerEditor::DumpEventInfo()
94 {
95   // Dump event-info into event_info.txt.
96   // The info is appended into the file.
97
98   ofstream f("event_info.txt", ios::out | ios::app);
99
100   f << "================================================================================\n\n";
101   f << fM->GetEventInfoHorizontal() << std::endl << std::endl;
102
103   f.close();
104 }
105
106
107 //==============================================================================
108 // AliEveEventManagerWindow
109 //==============================================================================
110
111 //______________________________________________________________________________
112 //
113 // Horizontal GUI for AliEveEventManager, to be placed in the
114 // bottom part of ROOT browser.
115
116 ClassImp(AliEveEventManagerWindow)
117
118 AliEveEventManagerWindow::AliEveEventManagerWindow(AliEveEventManager* mgr) :
119   TGMainFrame(gClient->GetRoot(), 400, 100, kVerticalFrame),
120   fM            (mgr),
121   fFirstEvent   (0),
122   fPrevEvent    (0),
123   fNextEvent    (0),
124   fLastEvent    (0),
125   fRefresh      (0),
126   fEventId      (0),
127   fInfoLabel    (0),
128   fAutoLoad     (0),
129   fLoopMarked   (0),
130   fAutoLoadTime (0),
131   fTrigSel      (0),
132   fEventInfo    (0)
133 {
134   // Constructor.
135
136   const TString cls("AliEveEventManagerWindow");
137   TGTextButton *b = 0;
138   {
139     Int_t width = 50;
140
141     TGHorizontalFrame* f = new TGHorizontalFrame(this);
142     AddFrame(f, new TGLayoutHints(kLHintsExpandX, 0,0,2,2));
143
144     fFirstEvent = b = MkTxtButton(f, "First", width);
145     b->Connect("Clicked()", cls, this, "DoFirstEvent()");
146     fPrevEvent = b = MkTxtButton(f, "Prev", width);
147     b->Connect("Clicked()", cls, this, "DoPrevEvent()");
148
149     fEventId = new TGNumberEntry(f, 0, 5, -1,TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative,
150                                  TGNumberFormat::kNELLimitMinMax, 0, 10000);
151     f->AddFrame(fEventId, new TGLayoutHints(kLHintsNormal, 10, 5, 0, 0));
152     fEventId->Connect("ValueSet(Long_t)", cls, this, "DoSetEvent()");
153     fInfoLabel = new TGLabel(f);
154     f->AddFrame(fInfoLabel, new TGLayoutHints(kLHintsNormal, 5, 10, 4, 0));
155
156     fNextEvent = b = MkTxtButton(f, "Next", width);
157     b->Connect("Clicked()", cls, this, "DoNextEvent()");
158     fLastEvent = b = MkTxtButton(f, "Last", width);
159     b->Connect("Clicked()", cls, this, "DoLastEvent()");
160     fMarkEvent = b = MkTxtButton(f, "Mark", width);
161     b->Connect("Clicked()", cls, this, "DoMarkEvent()");
162       fRestartReco = b = MkTxtButton(f, "Restart reco", 2*width);
163       b->Connect("Clicked()", cls, this, "DoRestartReco()");
164       fRestartManager = b = MkTxtButton(f, "Restart manager", 2*width);
165       b->Connect("Clicked()", cls, this, "DoRestartManager()");
166       
167       
168     MkLabel(f, "||", 0, 8, 8);
169
170     fRefresh = b = MkTxtButton(f, "Refresh", width + 8);
171     b->Connect("Clicked()",cls, this, "DoRefresh()");
172
173     MkLabel(f, "||", 0, 8, 8);
174
175     fAutoLoad = new TGCheckButton(f, "Autoload");
176     f->AddFrame(fAutoLoad, new TGLayoutHints(kLHintsLeft, 0, 4, 3, 0));
177     fAutoLoad->SetToolTipText("Automatic event loading.");
178     fAutoLoad->Connect("Toggled(Bool_t)", cls, this, "DoSetAutoLoad()");
179
180     fLoopMarked = new TGCheckButton(f, "Loop Marked");
181     f->AddFrame(fLoopMarked, new TGLayoutHints(kLHintsLeft, 0, 4, 3, 0));
182     fLoopMarked->SetToolTipText("Automatic marked events loading.");
183     fLoopMarked->Connect("Toggled(Bool_t)", cls, this, "DoSetLoopMarked()");
184       
185     fAutoLoadTime = new TEveGValuator(f, "Time: ", 110, 0);
186     f->AddFrame(fAutoLoadTime);
187     fAutoLoadTime->SetShowSlider(kFALSE);
188     fAutoLoadTime->SetNELength(4);
189     fAutoLoadTime->Build();
190     fAutoLoadTime->SetLimits(0, 1000);
191     fAutoLoadTime->SetToolTip("Automatic event loading time in seconds.");
192     fAutoLoadTime->Connect("ValueSet(Double_t)", cls, this, "DoSetAutoLoadTime()");
193
194     fTrigSel = new TGComboBox(f);
195     fTrigSel->Resize(4*width,b->GetDefaultHeight());
196     fTrigSel->AddEntry("No trigger selection",-1);
197     fTrigSel->Select(-1,kFALSE);
198     f->AddFrame(fTrigSel, new TGLayoutHints(kLHintsNormal, 10, 5, 0, 0));
199     fTrigSel->Connect("Selected(char*)", cls, this, "DoSetTrigSel()");
200
201     fStorageStatus = MkLabel(f,"Storage: Waiting",0,8,8);
202     fEventServerStatus = MkLabel(f,"Event Server: Waiting",0,10,10);
203       
204   }
205     
206   fEventInfo = new TGTextView(this, 400, 600);
207   AddFrame(fEventInfo, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
208
209    fM->Connect("NewEventLoaded()", cls, this, "Update(=1)");
210    fM->Connect("NoEventLoaded()", cls, this, "Update(=0)");
211    fM->Connect("StorageManagerOk()",cls,this,"StorageManagerChangedState(=1)");
212    fM->Connect("StorageManagerDown()",cls,this,"StorageManagerChangedState(=0)");
213
214   SetCleanup(kDeepCleanup);
215   Layout();
216   MapSubwindows();
217   MapWindow();
218 }
219
220 //______________________________________________________________________________
221 AliEveEventManagerWindow::~AliEveEventManagerWindow()
222 {
223   // Destructor.
224
225   fM->Disconnect("NewEventLoaded()", this);
226 }
227
228 //______________________________________________________________________________
229 void AliEveEventManagerWindow::DoFirstEvent()
230 {
231   // Load previous event
232   fM->GotoEvent(0);
233 }
234
235 //______________________________________________________________________________
236 void AliEveEventManagerWindow::DoPrevEvent()
237 {
238   // Load previous event
239   // fM->PrevEvent();
240   if (fM->IsOnlineMode()) {
241     fM->GotoEvent(1);
242   }
243   else {
244     fM->GotoEvent((Int_t) fEventId->GetNumber()-1);
245
246   }
247
248 }
249
250 //______________________________________________________________________________
251 void AliEveEventManagerWindow::DoNextEvent()
252 {
253   // Load next event
254   // fM->NextEvent();
255   if (fM->IsOnlineMode()) {
256       cout<<"next event, online node"<<endl;
257     fM->GotoEvent(2);
258   }
259   else {
260       cout<<"next event, offline mode"<<endl;
261     fM->GotoEvent((Int_t) fEventId->GetNumber()+1);
262   }
263 }
264
265 //______________________________________________________________________________
266 void AliEveEventManagerWindow::DoLastEvent()
267 {
268   // Load previous event
269   fM->GotoEvent(-1);
270 }
271
272 //______________________________________________________________________________
273 void AliEveEventManagerWindow::DoMarkEvent()
274 {
275   // Mark current event
276   fM->MarkCurrentEvent();
277 }
278
279 //______________________________________________________________________________
280 void AliEveEventManagerWindow::DoRestartReco()
281 {
282     ifstream configFile (GetConfigFilePath());
283     string username,hostname;
284     
285     if (configFile.is_open())
286     {
287         string line;
288         int from,to;
289         while(configFile.good())
290         {
291             getline(configFile,line);
292             from = line.find("\"")+1;
293             to = line.find_last_of("\"");
294             if(line.find("EVENT_SERVER=")==0)
295             {
296                 hostname=line.substr(from,to-from);
297             }
298             else if(line.find("EVENT_SERVER_USER=")==0)
299             {
300                 username=line.substr(from,to-from);
301             }
302         }
303         if(configFile.eof()){configFile.clear();}
304         configFile.close();
305     }
306     else{cout<<"Event Manager Editor -- Unable to open config file"<<endl;}
307
308     // Kill reconstruction server
309     gSystem->Exec(Form("ssh -n -f %s@%s \"killall alieventserver\"",username.c_str(),hostname.c_str()));
310 }
311
312 void AliEveEventManagerWindow::DoRestartManager()
313 {
314     ifstream configFile (GetConfigFilePath());
315     string username,hostname;
316     
317     if (configFile.is_open())
318     {
319         string line;
320         int from,to;
321         while(configFile.good())
322         {
323             getline(configFile,line);
324             from = line.find("\"")+1;
325             to = line.find_last_of("\"");
326             if(line.find("STORAGE_SERVER=")==0)
327             {
328                 hostname=line.substr(from,to-from);
329             }
330             else if(line.find("STORAGE_SERVER_USER=")==0)
331             {
332                 username=line.substr(from,to-from);
333             }
334         }
335         if(configFile.eof()){configFile.clear();}
336         configFile.close();
337     }
338     else{cout<<"Event Manager Editor -- Unable to open config file"<<endl;}
339
340     
341     // Kill storage manager
342     gSystem->Exec(Form("ssh -n -f %s@%s \"killall alistorage\"",username.c_str(),hostname.c_str()));
343 }
344
345 //______________________________________________________________________________
346 void AliEveEventManagerWindow::DoSetEvent()
347 {
348   // Set current event
349   fM->GotoEvent((Int_t) fEventId->GetNumber());
350 }
351
352 //______________________________________________________________________________
353 void AliEveEventManagerWindow::DoRefresh()
354 {
355   // Refresh event status.
356
357   Int_t ev = fM->GetEventId();
358   fM->Close();
359   fM->Open();
360   fM->GotoEvent(ev);
361 }
362
363 //______________________________________________________________________________
364 void AliEveEventManagerWindow::DoSetAutoLoad()
365 {
366   // Set the auto-load flag
367
368   fM->SetAutoLoad(fAutoLoad->IsOn());
369   Update(fM->NewEventAvailable());
370 }
371
372 //______________________________________________________________________________
373 void AliEveEventManagerWindow::DoSetLoopMarked()
374 {
375     // Set the auto-load flag
376     fM->SetLoopMarked(fLoopMarked->IsOn());
377 //    Update(fM->NewEventAvailable());
378 }
379
380 //______________________________________________________________________________
381 void AliEveEventManagerWindow::DoSetAutoLoadTime()
382 {
383   // Set the auto-load time in seconds
384
385   fM->SetAutoLoadTime(fAutoLoadTime->GetValue());
386 }
387
388 //______________________________________________________________________________
389 void AliEveEventManagerWindow::DoSetTrigSel()
390 {
391   // Set the trigger selection
392
393   fM->SetTrigSel(fTrigSel->GetSelectedEntry()->EntryId());
394 }
395
396 //______________________________________________________________________________
397 void AliEveEventManagerWindow::Update(int state)
398 {
399
400   Bool_t autoLoad = fM->GetAutoLoad();
401   Bool_t extCtrl  = fM->IsUnderExternalControl();
402   Bool_t evNavOn  = !autoLoad && !extCtrl;
403
404 #ifdef ZMQ
405
406   AliESDEvent*  esd = fM->GetESD();
407   AliStorageAdministratorPanelListEvents* listEventsTab = AliStorageAdministratorPanelListEvents::GetInstance();
408   AliEveConfigManager *configManager = AliEveConfigManager::GetMaster();
409
410   if (!fM->IsOnlineMode()) {
411
412       listEventsTab->SetOfflineMode(kTRUE);
413
414       fFirstEvent->SetEnabled(!autoLoad);
415       fPrevEvent ->SetEnabled(!autoLoad);
416       fLastEvent ->SetEnabled(!autoLoad);
417       fNextEvent ->SetEnabled(!autoLoad);
418       fMarkEvent ->SetEnabled(kFALSE);
419
420       fInfoLabel->SetText(Form("/ %d", fM->GetMaxEventId()));
421
422   }
423   else if (1 == state && fStorageStatus->GetText()->Contains("DOWN")) {
424     fEventServerStatus->SetText("Event Server: OK");
425     fFirstEvent->SetEnabled(kFALSE);
426     fPrevEvent ->SetEnabled(kFALSE);
427     fLastEvent ->SetEnabled(!autoLoad);
428     fNextEvent ->SetEnabled(kFALSE);
429     fMarkEvent ->SetEnabled(kFALSE);
430     listEventsTab->SetOfflineMode(kTRUE);
431     fInfoLabel->SetText(Form("/ %d",fM->GetEventId()));
432   }
433   else if (0 == state && fStorageStatus->GetText()->Contains("DOWN")) {
434     fEventServerStatus->SetText("Event Server: Waiting");
435     fFirstEvent->SetEnabled(kFALSE);
436     fPrevEvent ->SetEnabled(kFALSE);
437     fLastEvent ->SetEnabled(!autoLoad);
438     fNextEvent ->SetEnabled(kFALSE);
439     fMarkEvent ->SetEnabled(kFALSE);
440     listEventsTab->SetOfflineMode(kTRUE);
441   }
442   else if (0 == state && fStorageStatus->GetText()->Contains("OK")) {
443     fEventServerStatus->SetText("Event Server: Waiting");
444     fFirstEvent->SetEnabled(!autoLoad);
445     fPrevEvent ->SetEnabled(!autoLoad);
446     fLastEvent ->SetEnabled(!autoLoad);
447     fNextEvent ->SetEnabled(!autoLoad);
448     fMarkEvent ->SetEnabled(kTRUE);
449     listEventsTab->SetOfflineMode(kFALSE);
450   }
451   else {
452     fEventServerStatus->SetText("Event Server: OK");
453     fFirstEvent->SetEnabled(!autoLoad);
454     fPrevEvent ->SetEnabled(!autoLoad);
455     fLastEvent ->SetEnabled(!autoLoad);
456     fNextEvent ->SetEnabled(!autoLoad);
457     fMarkEvent ->SetEnabled(kTRUE);
458     listEventsTab->SetOfflineMode(kFALSE);
459   }
460 #endif
461
462   if (1 == state) {
463     fRefresh   ->SetEnabled(evNavOn);
464
465     fEventId->SetNumber(fM->GetEventId());
466     fEventId->SetState(evNavOn);
467     // fInfoLabel->SetText(Form("/ %d", fM->GetMaxEventId()));
468
469     fAutoLoad->SetState(fM->GetAutoLoad() ? kButtonDown : kButtonUp);
470     fAutoLoadTime->SetValue(fM->GetAutoLoadTime());
471
472     // Loop over active trigger classes
473     if (fM->GetESD()) {
474       for(Int_t iTrig = 0; iTrig < AliESDRun::kNTriggerClasses; iTrig++) {
475         TString trigName = fM->GetESD()->GetESDRun()->GetTriggerClass(iTrig);
476         if (trigName.IsNull()) {
477           if (fTrigSel->GetListBox()->GetEntry(iTrig)) {
478             if (fTrigSel->GetSelected() == iTrig) fTrigSel->Select(-1);
479             fTrigSel->RemoveEntry(iTrig);
480           }
481           continue;
482         }
483         if (!fTrigSel->FindEntry(trigName.Data()))
484           fTrigSel->AddEntry(trigName.Data(),iTrig);
485       }
486     }
487     fTrigSel->SetEnabled(!evNavOn);
488
489 //    fEventInfo->LoadBuffer(fM->GetEventInfoHorizontal());
490
491     Layout();
492   }
493 }
494
495 void AliEveEventManagerWindow::StorageManagerChangedState(int state)
496 {
497 #ifdef ZMQ
498
499   Bool_t autoLoad = fM->GetAutoLoad();
500   AliStorageAdministratorPanelListEvents* listEventsTab = AliStorageAdministratorPanelListEvents::GetInstance();
501   AliEveConfigManager *configManager = AliEveConfigManager::GetMaster();
502
503   if (fM->IsOnlineMode()) {
504     if (state == 0)
505       {
506         fStorageStatus->SetText("Storage: DOWN");
507         fMarkEvent->SetEnabled(kFALSE);
508         fNextEvent->SetEnabled(kFALSE);
509         fLastEvent->SetEnabled(!autoLoad);
510         fPrevEvent->SetEnabled(kFALSE);
511         fFirstEvent->SetEnabled(kFALSE);
512         listEventsTab->SetOfflineMode(kTRUE);
513         fEventId->SetState(kFALSE);
514       }
515     else if(state == 1)
516       {
517         listEventsTab->SetOfflineMode(kFALSE);
518
519         fStorageStatus->SetText("Storage: OK");
520         fMarkEvent->SetEnabled(kTRUE);
521         fNextEvent->SetEnabled(!autoLoad);
522         fLastEvent->SetEnabled(!autoLoad);
523         fPrevEvent->SetEnabled(!autoLoad);
524         fFirstEvent->SetEnabled(!autoLoad);
525         fEventId->SetState(!autoLoad);
526       }
527   }
528 #endif
529 }
530
531 //------------------------------------------------------------------------------
532 // Protected methods
533 //------------------------------------------------------------------------------
534
535 //______________________________________________________________________________
536 TGTextButton* AliEveEventManagerWindow::MkTxtButton(TGCompositeFrame* p,
537                                                     const char* txt, Int_t width,
538                                                     Int_t lo, Int_t ro, Int_t to, Int_t bo)
539 {
540   // Create a standard button.
541   // If width is not zero, the fixed-width flag is set.
542
543   TGTextButton* b = new TGTextButton(p, txt);
544   if (width > 0) {
545     b->SetWidth(width);
546     b->ChangeOptions(b->GetOptions() | kFixedWidth);
547   }
548   p->AddFrame(b, new TGLayoutHints(kLHintsNormal, lo,ro,to,bo));
549   return b;
550 }
551
552 //______________________________________________________________________________
553 TGLabel* AliEveEventManagerWindow::MkLabel(TGCompositeFrame* p,
554                                            const char* txt, Int_t width,
555                                            Int_t lo, Int_t ro, Int_t to, Int_t bo)
556 {
557   // Create a standard button.
558   // If width is not zero, the fixed-width flag is set.
559
560   TGLabel* l = new TGLabel(p, txt);
561   if (width > 0) {
562     l->SetWidth(width);
563     l->ChangeOptions(l->GetOptions() | kFixedWidth);
564   }
565   p->AddFrame(l, new TGLayoutHints(kLHintsNormal, lo,ro,to,bo));
566   return l;
567 }
568