Brand new GUI application for online display/reco by Matevz.
[u/mrichter/AliRoot.git] / MONITOR / AliOnlineReco.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 "AliOnlineReco.h"
11 #include "AliChildReaper.h"
12 #include "AliDimIntNotifier.h"
13
14 #include <TGListBox.h>
15 #include <TGButton.h>
16
17 #include <unistd.h>
18 #include <signal.h>
19
20 //______________________________________________________________________________
21 // Full description of AliOnlineReco
22 //
23
24 ClassImp(AliOnlineReco)
25
26 AliOnlineReco::AliOnlineReco() :
27   TGMainFrame(gClient->GetRoot(), 400, 400),
28
29   fRunList(0), fStartButt(0), fStopButt(0), fXyzzButt(0),
30
31   fSOR(new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_SOR_PHYSICS")),
32   fEOR(new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_EOR_PHYSICS")),
33
34   fTestMode(kFALSE)
35 {
36   // GUI components.
37   fRunList = new TGListBox(this);
38   AddFrame(fRunList, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
39
40   TGHorizontalFrame *hf = new TGHorizontalFrame(this, 1, 20);
41
42   fStartButt = new TGTextButton(hf, "Start");
43   hf->AddFrame(fStartButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
44   fStartButt->Connect("Clicked()", "AliOnlineReco", this, "DoStart()");
45
46   fStopButt = new TGTextButton(hf, "Stop");
47   hf->AddFrame(fStopButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
48   fStopButt->Connect("Clicked()", "AliOnlineReco", this, "DoStop()");
49
50   fXyzzButt = new TGTextButton(hf, "Exit");
51   hf->AddFrame(fXyzzButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
52   fXyzzButt->Connect("Clicked()", "AliOnlineReco", this, "DoXyzz()");
53
54   AddFrame(hf, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
55
56   MapSubwindows();
57   Layout();
58   SetWindowName("Alice Online Reconstruction");
59
60   // DIM interface.
61   fSOR->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "StartOfRun(Int_t)");
62   fEOR->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "EndOfRun(Int_t)");
63
64   // Signal handlers
65   // ROOT's TSignalHAndler works not SIGCHLD ...
66   AliChildReaper::Instance()->Connect("ChildDeath(Int_t,Int_t)", "AliOnlineReco", this, "ChildDeath(Int_t,Int_t)");
67 }
68
69 AliOnlineReco::mIntInt_i AliOnlineReco::FindMapEntryByPid(Int_t pid)
70 {
71   for (mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); ++i)
72   {
73     if (i->second == pid)
74       return i;
75   }
76
77   return fRun2PidMap.end();
78 }
79
80 //------------------------------------------------------------------------------
81 // Handlers of DIM signals.
82 //------------------------------------------------------------------------------
83
84 void AliOnlineReco::StartOfRun(Int_t run)
85 {
86   mIntInt_i i = fRun2PidMap.find(run);
87   if (i == fRun2PidMap.end())
88   {
89     fRun2PidMap[run] = 0;
90     fRunList->AddEntrySort(TString::Format("%d", run), run);
91     fRunList->Layout();
92   }
93   else
94   {
95     Error("StartOfRun", "Run %d already registered.", run);
96   }
97 }
98
99 void AliOnlineReco::EndOfRun(Int_t run)
100 {
101   mIntInt_i i = fRun2PidMap.find(run);
102   if (i != fRun2PidMap.end())
103   {
104     Int_t pid = i->second;
105     fRunList->RemoveEntry(run);
106     fRunList->Layout();
107     fRun2PidMap.erase(i);
108     if (pid)
109     {
110       // Send terminate signal to process ...
111       if (fTestMode)
112       {
113         kill(pid, SIGTERM);
114       }
115       else
116       {
117         // alieve will auto-destruct on SIGUSR1
118         kill(pid, SIGUSR1);
119       }
120     }
121     gClient->NeedRedraw(fRunList);
122   }
123   else
124   {
125     Error("EndOfRun", "Run %d not registered.", run);
126   }
127 }
128
129 //------------------------------------------------------------------------------
130 // Handlers of OS signals.
131 //------------------------------------------------------------------------------
132
133 void AliOnlineReco::ChildDeath(Int_t pid, Int_t status)
134 {
135   printf("child death pid=%d, statues=%d...\n", pid, status);
136
137   mIntInt_i i = FindMapEntryByPid(pid);
138   if (i != fRun2PidMap.end())
139   {
140     Int_t run = i->first;
141     fRunList->RemoveEntry(run);
142     if (status == 0)
143     {
144       fRunList->AddEntrySort(TString::Format("%-20d -- FINISHED", run), run);
145     }
146     else
147     {
148       fRunList->AddEntrySort(TString::Format("%-20d -- CRASHED [%d]", run, status), run);
149     }
150     fRunList->Layout();
151     i->second = 0;
152   }
153   else
154   {
155     Warning("ChildDeath", "Process with pid=%d not registered.", pid);
156   }
157 }
158
159 //------------------------------------------------------------------------------
160 // Handlers of button signals.
161 //------------------------------------------------------------------------------
162
163 void AliOnlineReco::DoStart()
164 {
165   Int_t run = fRunList->GetSelected();
166   mIntInt_i i = fRun2PidMap.find(run);
167
168   if (i == fRun2PidMap.end())
169   {
170     Error("DoStart", "no selection");
171     return;
172   }
173
174   if (i->second == 0)
175   {
176     pid_t pid = fork();
177     if (pid == -1)
178     {
179       perror("DoStart -- Fork failed");
180       return;
181     }
182
183     if (pid)
184     {
185       i->second = pid;
186       fRunList->RemoveEntry(run);
187       fRunList->AddEntrySort(TString::Format("%-20d -- RUNNING", run), run);
188       fRunList->Layout();
189     }
190     else
191     {
192       int s;
193       if (fTestMode)
194       {
195         s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0);
196       }
197       else
198       {
199         // !!!! Cvetan, add proper args here ...
200         s = execlp("alieve", "alieve", TString::Format("%d", run).Data(), (char*) 0);
201       }
202
203       if (s == -1)
204       {
205         perror("execlp failed - this will not end well");
206         gSystem->Exit(1);
207       }
208     }
209   }
210   else
211   {
212     Error("DoStart", "Process already running.");
213   }
214 }
215
216 void AliOnlineReco::DoStop()
217 {
218   Int_t run = fRunList->GetSelected();
219   mIntInt_i i = fRun2PidMap.find(run);
220
221   if (i == fRun2PidMap.end())
222   {
223     Error("DoStop", "no selection");
224     return;
225   }
226
227   Int_t pid = i->second;
228   if (pid)
229   {
230     if (fTestMode)
231     {
232       kill(pid, SIGTERM);
233     }
234     else
235     {
236       // alieve will auto-destruct on SIGUSR1
237       kill(pid, SIGUSR1);
238     }
239   }
240   else
241   {
242     Error("DoStop", "Process not running.");
243   }
244 }
245
246 void AliOnlineReco::DoXyzz()
247 {
248   gSystem->ExitLoop();
249 }
250
251 void AliOnlineReco::CloseWindow()
252 {
253   gSystem->ExitLoop();
254 }