Bug #55488: Better messsaging in the online reco GUI. Change in the ECS policy -...
[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 "AliChildProcTerminator.h"
12 #include "AliDimIntNotifier.h"
13 #include "AliCDBManager.h"
14 #include "AliGRPPreprocessor.h"
15
16 #include <TGListBox.h>
17 #include <TGButton.h>
18
19 #include <unistd.h>
20 #include <signal.h>
21
22 //______________________________________________________________________________
23 // Full description of AliOnlineReco
24 //
25
26 ClassImp(AliOnlineReco)
27
28 AliOnlineReco::AliOnlineReco() :
29   TGMainFrame(gClient->GetRoot(), 400, 400),
30
31   fRunList(0), fStartButt(0), fStopButt(0), fXyzzButt(0),
32
33   fSOR(new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_SOR_PHYSICS")),
34   fEOR(new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_EOR_PHYSICS")),
35
36   fTestMode(kFALSE)
37 {
38   // GUI components.
39   fRunList = new TGListBox(this);
40   AddFrame(fRunList, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
41
42   TGHorizontalFrame *hf = new TGHorizontalFrame(this, 1, 20);
43
44   fStartButt = new TGTextButton(hf, "Start");
45   hf->AddFrame(fStartButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
46   fStartButt->Connect("Clicked()", "AliOnlineReco", this, "DoStart()");
47
48   fStopButt = new TGTextButton(hf, "Stop");
49   hf->AddFrame(fStopButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
50   fStopButt->Connect("Clicked()", "AliOnlineReco", this, "DoStop()");
51
52   fXyzzButt = new TGTextButton(hf, "Exit");
53   hf->AddFrame(fXyzzButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
54   fXyzzButt->Connect("Clicked()", "AliOnlineReco", this, "DoXyzz()");
55
56   AddFrame(hf, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
57
58   MapSubwindows();
59   Layout();
60   SetWindowName("Alice Online Reconstruction");
61
62   // DIM interface.
63   fSOR->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "StartOfRun(Int_t)");
64   fEOR->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "EndOfRun(Int_t)");
65
66   // Signal handlers
67   // ROOT's TSignalHAndler works not SIGCHLD ...
68   AliChildProcTerminator::Instance()->Connect("ChildProcTerm(Int_t,Int_t)", "AliOnlineReco", this, "ChildProcTerm(Int_t,Int_t)");
69 }
70
71 AliOnlineReco::mIntInt_i AliOnlineReco::FindMapEntryByPid(Int_t pid)
72 {
73   for (mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); ++i)
74   {
75     if (i->second == pid)
76       return i;
77   }
78
79   return fRun2PidMap.end();
80 }
81
82 //------------------------------------------------------------------------------
83 // Handlers of DIM signals.
84 //------------------------------------------------------------------------------
85
86 void AliOnlineReco::StartOfRun(Int_t run)
87 {
88   mIntInt_i i = fRun2PidMap.find(run);
89   if (i == fRun2PidMap.end())
90   {
91     fRun2PidMap[run] = 0;
92     fRunList->AddEntrySort(TString::Format("%d", run), run);
93     fRunList->Layout();
94   }
95   else
96   {
97     Error("StartOfRun", "Run %d already registered.", run);
98   }
99 }
100
101 void AliOnlineReco::EndOfRun(Int_t run)
102 {
103   mIntInt_i i = fRun2PidMap.find(run);
104   if (i != fRun2PidMap.end())
105   {
106     Int_t pid = i->second;
107     fRunList->RemoveEntry(run);
108     fRunList->Layout();
109     fRun2PidMap.erase(i);
110     if (pid)
111     {
112       // Send terminate signal to process ...
113       if (fTestMode)
114       {
115         kill(pid, SIGTERM);
116       }
117       else
118       {
119         // alieve will auto-destruct on SIGUSR1
120         kill(pid, SIGUSR1);
121       }
122     }
123     gClient->NeedRedraw(fRunList);
124   }
125   else
126   {
127     Error("EndOfRun", "Run %d not registered.", run);
128   }
129 }
130
131 //------------------------------------------------------------------------------
132 // Handlers of OS signals.
133 //------------------------------------------------------------------------------
134
135 void AliOnlineReco::ChildProcTerm(Int_t pid, Int_t status)
136 {
137   printf("child process termination pid=%d, status=%d...\n", pid, status);
138
139   mIntInt_i i = FindMapEntryByPid(pid);
140   if (i != fRun2PidMap.end())
141   {
142     Int_t run = i->first;
143     fRunList->RemoveEntry(run);
144     if (status == 0)
145     {
146       fRunList->AddEntrySort(TString::Format("%-20d -- PROCESSED", run), run);
147     }
148     else
149     {
150       fRunList->AddEntrySort(TString::Format("%-20d -- PROCESSED [%d]", run, status), run);
151     }
152     fRunList->Layout();
153     i->second = 0;
154   }
155   else
156   {
157     Warning("ChildProcTerm", "Process with pid=%d not registered.", pid);
158   }
159 }
160
161 //------------------------------------------------------------------------------
162 // Handlers of button signals.
163 //------------------------------------------------------------------------------
164
165 void AliOnlineReco::DoStart()
166 {
167   Int_t run = fRunList->GetSelected();
168   mIntInt_i i = fRun2PidMap.find(run);
169
170   if (i == fRun2PidMap.end())
171   {
172     Error("DoStart", "no selection");
173     return;
174   }
175
176   if (i->second == 0)
177   {
178     pid_t pid = fork();
179     if (pid == -1)
180     {
181       perror("DoStart -- Fork failed");
182       return;
183     }
184
185     if (pid)
186     {
187       i->second = pid;
188       fRunList->RemoveEntry(run);
189       fRunList->AddEntrySort(TString::Format("%-20d -- RUNNING", run), run);
190       fRunList->Layout();
191     }
192     else
193     {
194       int s;
195       if (fTestMode)
196       {
197         s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0);
198       }
199       else
200       {
201         Int_t procPID = gSystem->GetPid();
202         TString logFile = Form("%s/reco/log/run%d_%d.log",
203                                gSystem->Getenv("ONLINERECO_BASE_DIR"),
204                                run,
205                                (Int_t)procPID);
206         Info("DoStart","Reconstruction log will be written to %s",logFile.Data());
207         gSystem->RedirectOutput(logFile.Data());
208
209         gSystem->cd(Form("%s/reco",gSystem->Getenv("ONLINERECO_BASE_DIR")));
210
211         TString gdcs;
212         if ((RetrieveGRP(run,gdcs) <= 0) ||
213             gdcs.IsNull()) 
214           gSystem->Exit(1);
215
216         gSystem->Setenv("DATE_RUN_NUMBER",Form("%d",run));
217         // Setting CDB
218 //      AliCDBManager * man = AliCDBManager::Instance();
219 //      man->SetDefaultStorage("local:///local/cdb");
220 //      man->SetSpecificStorage("GRP/GRP/Data",
221 //                            Form("local://%s",gSystem->pwd()));
222 //      man->SetSpecificStorage("GRP/CTP/Config",
223 //                            Form("local://%s",gSystem->pwd()));
224 //      man->SetSpecificStorage("ACORDE/Align/Data",
225 //                              "local://$ALICE_ROOT/OCDB");
226
227         gSystem->mkdir(Form("run%d_%d",run,(Int_t)procPID));
228         gSystem->cd(Form("run%d_%d",run,(Int_t)procPID));
229
230         const char *recMacroPath = "$ALICE_ROOT/test/cosmic/rec.C";
231
232         s = execlp("alieve",
233                    "alieve",
234                    "-q",
235                    Form("%s(\"mem://@*:\")",gSystem->ExpandPathName(recMacroPath)),
236                    (char*) 0);
237       }
238
239       if (s == -1)
240       {
241         perror("execlp failed - this will not end well");
242         gSystem->Exit(1);
243       }
244     }
245   }
246   else
247   {
248     Error("DoStart", "Process already running.");
249   }
250 }
251
252 void AliOnlineReco::DoStop()
253 {
254   Int_t run = fRunList->GetSelected();
255   mIntInt_i i = fRun2PidMap.find(run);
256
257   if (i == fRun2PidMap.end())
258   {
259     Error("DoStop", "no selection");
260     return;
261   }
262
263   Int_t pid = i->second;
264   if (pid)
265   {
266     if (fTestMode)
267     {
268       kill(pid, SIGTERM);
269     }
270     else
271     {
272       // alieve will auto-destruct on SIGUSR1
273       kill(pid, SIGUSR1);
274     }
275   }
276   else
277   {
278     Error("DoStop", "Process not running.");
279   }
280 }
281
282 void AliOnlineReco::DoXyzz()
283 {
284   gSystem->ExitLoop();
285 }
286
287 void AliOnlineReco::CloseWindow()
288 {
289   gSystem->ExitLoop();
290 }
291
292 Int_t AliOnlineReco::RetrieveGRP(UInt_t run, TString &gdc) {
293
294   Int_t ret=AliGRPPreprocessor::ReceivePromptRecoParameters(run, "aldaqdb", 0, "LOGBOOK", "logbook", "alice",
295                                                             Form("local://%s",gSystem->pwd()),
296                                                             gdc);
297   if(ret>0) Info("RetrieveGRP","Last run of the same type is: %d",ret);
298   else if(ret==0) Warning("RetrieveGRP","No previous run of the same type found");
299   else if(ret<0) Error("Retrieve","Error code while retrieving GRP parameters returned: %d",ret);
300   return(ret);
301 }