Autorun functionality added (Matevz)
[u/mrichter/AliRoot.git] / MONITOR / AliOnlineReco.cxx
CommitLineData
c6d78c69 1// @(#)root/eve:$Id$
2// Author: Matevz Tadel 2007
3
4/**************************************************************************
dc836d53 5 * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *)
c6d78c69 6 * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for *
7 * full copyright notice. *
8 **************************************************************************/
9
10#include "AliOnlineReco.h"
93624d6b 11#include "AliChildProcTerminator.h"
c6d78c69 12#include "AliDimIntNotifier.h"
a15a9f84 13#include "AliCDBManager.h"
14#include "AliGRPPreprocessor.h"
c6d78c69 15
dc836d53 16#include <TTimer.h>
17
c6d78c69 18#include <TGListBox.h>
19#include <TGButton.h>
20
21#include <unistd.h>
22#include <signal.h>
23
24//______________________________________________________________________________
25// Full description of AliOnlineReco
26//
27
28ClassImp(AliOnlineReco)
29
30AliOnlineReco::AliOnlineReco() :
31 TGMainFrame(gClient->GetRoot(), 400, 400),
32
dc836d53 33 fRunList(0), fAutoRun(0), fStartButt(0), fStopButt(0), fExitButt(0),
34 fAutoRunTimer(0), fAutoRunScheduled(0), fAutoRunRunning(0),
c6d78c69 35 fTestMode(kFALSE)
36{
37 // GUI components.
38 fRunList = new TGListBox(this);
39 AddFrame(fRunList, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
40
41 TGHorizontalFrame *hf = new TGHorizontalFrame(this, 1, 20);
42
dc836d53 43 fAutoRun = new TGCheckButton(hf, "AutoRun");
44 hf->AddFrame(fAutoRun, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
45 fAutoRun->Connect("Clicked()", "AliOnlineReco", this, "DoAutoRun()");
46
c6d78c69 47 fStartButt = new TGTextButton(hf, "Start");
48 hf->AddFrame(fStartButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
49 fStartButt->Connect("Clicked()", "AliOnlineReco", this, "DoStart()");
50
51 fStopButt = new TGTextButton(hf, "Stop");
52 hf->AddFrame(fStopButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
53 fStopButt->Connect("Clicked()", "AliOnlineReco", this, "DoStop()");
54
dc836d53 55 fExitButt = new TGTextButton(hf, "Exit");
56 hf->AddFrame(fExitButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
57 fExitButt->Connect("Clicked()", "AliOnlineReco", this, "DoExit()");
c6d78c69 58
59 AddFrame(hf, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
60
61 MapSubwindows();
62 Layout();
63 SetWindowName("Alice Online Reconstruction");
64
e35c7687 65 // DIM interface.
66 for (Int_t i = 0; i < 5; ++i)
67 {
68 if (i == 0)
69 {
70 fSOR[i] = new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_SOR_PHYSICS");
71 fEOR[i] = new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_EOR_PHYSICS");
72 }
73 else
74 {
75 fSOR[i] = new AliDimIntNotifier(Form("/LOGBOOK/SUBSCRIBE/DAQ_SOR_PHYSICS_%d", i));
76 fEOR[i] = new AliDimIntNotifier(Form("/LOGBOOK/SUBSCRIBE/DAQ_EOR_PHYSICS_%d", i));
77 }
dc836d53 78
e35c7687 79 fSOR[i]->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "StartOfRun(Int_t)");
80 fEOR[i]->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "EndOfRun(Int_t)");
81 }
c6d78c69 82
dc836d53 83 const Int_t autoRunDelay = 10; // should go to config
84 fAutoRunTimer = new TTimer(autoRunDelay * 1000l);
85 fAutoRunTimer->Connect("Timeout()", "AliOnlineReco", this, "AutoRunTimerTimeout()");
86
c6d78c69 87 // Signal handlers
88 // ROOT's TSignalHAndler works not SIGCHLD ...
93624d6b 89 AliChildProcTerminator::Instance()->Connect("ChildProcTerm(Int_t,Int_t)", "AliOnlineReco", this, "ChildProcTerm(Int_t,Int_t)");
c6d78c69 90}
91
dc836d53 92AliOnlineReco::~AliOnlineReco()
93{
94 delete fAutoRunTimer;
95}
96
97Int_t AliOnlineReco::GetLastRun() const
98{
99 return fRun2PidMap.empty() ? 0 : fRun2PidMap.rbegin()->first;
100}
101
102Bool_t AliOnlineReco::GetAutoRunMode() const
103{
104 return fAutoRun->IsOn();
105}
106
107void AliOnlineReco::SetAutoRunMode(Bool_t ar)
108{
109 if (ar == fAutoRun->IsOn())
110 return;
111
112 fAutoRun->SetState(ar ? kButtonDown : kButtonUp, kTRUE);
113}
114
115//------------------------------------------------------------------------------
116// Private methods
117//------------------------------------------------------------------------------
118
c6d78c69 119AliOnlineReco::mIntInt_i AliOnlineReco::FindMapEntryByPid(Int_t pid)
120{
121 for (mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); ++i)
122 {
123 if (i->second == pid)
124 return i;
125 }
126
127 return fRun2PidMap.end();
128}
129
dc836d53 130void AliOnlineReco::StartAliEve(mIntInt_i& mi)
131{
132 Int_t run = mi->first;
133
134 if (mi->second == 0)
135 {
136 pid_t pid = fork();
137 if (pid == -1)
138 {
139 perror("DoStart -- Fork failed");
140 return;
141 }
142
143 if (pid)
144 {
145 mi->second = pid;
146 fRunList->RemoveEntry(run);
147 fRunList->AddEntrySort(TString::Format("%-20d -- RUNNING", run), run);
148 fRunList->Layout();
149 }
150 else
151 {
152 int s;
153 if (fTestMode)
154 {
155 s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0);
156 }
157 else
158 {
159 Int_t procPID = gSystem->GetPid();
160 TString logFile = Form("%s/reco/log/run%d_%d.log",
161 gSystem->Getenv("ONLINERECO_BASE_DIR"),
162 run,
163 (Int_t)procPID);
164 Info("DoStart","Reconstruction log will be written to %s",logFile.Data());
165 gSystem->RedirectOutput(logFile.Data());
166
167 gSystem->cd(Form("%s/reco",gSystem->Getenv("ONLINERECO_BASE_DIR")));
168
169 TString gdcs;
170 if (RetrieveGRP(run,gdcs) <= 0 || gdcs.IsNull())
171 gSystem->Exit(1);
172
173 gSystem->Setenv("DATE_RUN_NUMBER", Form("%d", run));
174 // Setting CDB
175// AliCDBManager * man = AliCDBManager::Instance();
176// man->SetDefaultStorage("local:///local/cdb");
177// man->SetSpecificStorage("GRP/GRP/Data",
178// Form("local://%s",gSystem->pwd()));
179// man->SetSpecificStorage("GRP/CTP/Config",
180// Form("local://%s",gSystem->pwd()));
181// man->SetSpecificStorage("ACORDE/Align/Data",
182// "local://$ALICE_ROOT/OCDB");
183
184 gSystem->mkdir(Form("run%d_%d", run, (Int_t)procPID));
185 gSystem->cd(Form("run%d_%d", run, (Int_t)procPID));
186
187 const char *recMacroPath = "$ALICE_ROOT/test/cosmic/rec.C";
188
189 s = execlp("alieve",
190 "alieve",
191 "-q",
192 Form("%s(\"mem://@*:\")", gSystem->ExpandPathName(recMacroPath)),
193 (char*) 0);
194 }
195
196 if (s == -1)
197 {
198 perror("execlp failed - this will not end well");
199 gSystem->Exit(1);
200 }
201 }
202 }
203 else
204 {
205 Error("DoStart", "Process already running.");
206 }
207}
208
209void AliOnlineReco::KillPid(Int_t pid)
210{
211 // Send terminate signal to process ...
212
213 if (fTestMode)
214 {
215 kill(pid, SIGTERM);
216 }
217 else
218 {
219 // alieve will auto-destruct on SIGUSR1
220 kill(pid, SIGUSR1);
221 }
222}
223
224void AliOnlineReco::StartAutoRunTimer(Int_t run)
225{
226 // Start timer for given run.
227 // If an auto-started run is already active, this call is ignored.
228 // If timer is already active, it is restarted.
229
230 if (fAutoRunRunning)
231 return;
232
233 fAutoRunTimer->Reset();
234 fAutoRunTimer->TurnOn();
235 fAutoRunScheduled = run;
236
237 Info("StartAutoRunTimer", "Scheduling run %d for auto-display.", run);
238}
239
240void AliOnlineReco::StopAutoRunTimer()
241{
242 fAutoRunTimer->TurnOff();
243 fAutoRunScheduled = 0;
244}
245
246void AliOnlineReco::AutoRunTimerTimeout()
247{
248 Int_t run = fAutoRunScheduled;
249
250 StopAutoRunTimer();
251
252 mIntInt_i i = fRun2PidMap.find(run);
253
254 if (i == fRun2PidMap.end())
255 {
256 Warning("AutoRunTimerTimeout", "run no longer active.");
257 return;
258 }
259
260 Info("AutoRunTimerTimeout", "Starting display for run %d.", run);
261
262 StartAliEve(i);
263 fAutoRunRunning = run;
264}
265
c6d78c69 266//------------------------------------------------------------------------------
267// Handlers of DIM signals.
268//------------------------------------------------------------------------------
269
270void AliOnlineReco::StartOfRun(Int_t run)
271{
272 mIntInt_i i = fRun2PidMap.find(run);
273 if (i == fRun2PidMap.end())
274 {
275 fRun2PidMap[run] = 0;
276 fRunList->AddEntrySort(TString::Format("%d", run), run);
277 fRunList->Layout();
dc836d53 278
279 if (fAutoRun->IsOn())
280 {
281 StartAutoRunTimer(run);
282 }
c6d78c69 283 }
284 else
285 {
286 Error("StartOfRun", "Run %d already registered.", run);
287 }
288}
289
290void AliOnlineReco::EndOfRun(Int_t run)
291{
292 mIntInt_i i = fRun2PidMap.find(run);
293 if (i != fRun2PidMap.end())
294 {
295 Int_t pid = i->second;
296 fRunList->RemoveEntry(run);
297 fRunList->Layout();
298 fRun2PidMap.erase(i);
299 if (pid)
300 {
dc836d53 301 KillPid(pid);
c6d78c69 302 }
303 gClient->NeedRedraw(fRunList);
dc836d53 304
305 if (fAutoRunRunning == run)
306 {
307 fAutoRunRunning = 0;
308 }
c6d78c69 309 }
310 else
311 {
312 Error("EndOfRun", "Run %d not registered.", run);
313 }
314}
315
316//------------------------------------------------------------------------------
317// Handlers of OS signals.
318//------------------------------------------------------------------------------
319
93624d6b 320void AliOnlineReco::ChildProcTerm(Int_t pid, Int_t status)
c6d78c69 321{
93624d6b 322 printf("child process termination pid=%d, status=%d...\n", pid, status);
c6d78c69 323
324 mIntInt_i i = FindMapEntryByPid(pid);
325 if (i != fRun2PidMap.end())
326 {
327 Int_t run = i->first;
328 fRunList->RemoveEntry(run);
329 if (status == 0)
330 {
82142d1d 331 fRunList->AddEntrySort(TString::Format("%-20d -- PROCESSED", run), run);
c6d78c69 332 }
333 else
334 {
82142d1d 335 fRunList->AddEntrySort(TString::Format("%-20d -- PROCESSED [%d]", run, status), run);
c6d78c69 336 }
337 fRunList->Layout();
338 i->second = 0;
dc836d53 339
340 if (fAutoRunRunning == run && fAutoRun->IsOn())
341 {
342 fAutoRunRunning = 0;
343 StartAutoRunTimer(run);
344 }
345 else
346 {
347 fAutoRunRunning = 0;
348 }
c6d78c69 349 }
350 else
351 {
93624d6b 352 Warning("ChildProcTerm", "Process with pid=%d not registered.", pid);
c6d78c69 353 }
354}
355
356//------------------------------------------------------------------------------
357// Handlers of button signals.
358//------------------------------------------------------------------------------
359
dc836d53 360void AliOnlineReco::DoAutoRun()
361{
362 Bool_t autoRun = fAutoRun->IsOn();
363
364 if (autoRun)
365 fStartButt->SetEnabled(kFALSE);
366 else
367 fStartButt->SetEnabled(kTRUE);
368}
369
c6d78c69 370void AliOnlineReco::DoStart()
371{
372 Int_t run = fRunList->GetSelected();
373 mIntInt_i i = fRun2PidMap.find(run);
374
375 if (i == fRun2PidMap.end())
376 {
377 Error("DoStart", "no selection");
378 return;
379 }
380
dc836d53 381 StartAliEve(i);
c6d78c69 382}
383
384void AliOnlineReco::DoStop()
385{
386 Int_t run = fRunList->GetSelected();
387 mIntInt_i i = fRun2PidMap.find(run);
388
389 if (i == fRun2PidMap.end())
390 {
391 Error("DoStop", "no selection");
392 return;
393 }
394
395 Int_t pid = i->second;
396 if (pid)
397 {
dc836d53 398 KillPid(pid);
c6d78c69 399 }
400 else
401 {
402 Error("DoStop", "Process not running.");
403 }
404}
405
dc836d53 406void AliOnlineReco::DoExit()
c6d78c69 407{
408 gSystem->ExitLoop();
409}
410
411void AliOnlineReco::CloseWindow()
412{
413 gSystem->ExitLoop();
414}
a15a9f84 415
416Int_t AliOnlineReco::RetrieveGRP(UInt_t run, TString &gdc) {
417
418 Int_t ret=AliGRPPreprocessor::ReceivePromptRecoParameters(run, "aldaqdb", 0, "LOGBOOK", "logbook", "alice",
419 Form("local://%s",gSystem->pwd()),
420 gdc);
421 if(ret>0) Info("RetrieveGRP","Last run of the same type is: %d",ret);
422 else if(ret==0) Warning("RetrieveGRP","No previous run of the same type found");
423 else if(ret<0) Error("Retrieve","Error code while retrieving GRP parameters returned: %d",ret);
424 return(ret);
425}