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