]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MONITOR/AliOnlineReco.cxx
Added AliRsnAction, fix for AliRsnPIDRange, lego_train macros updated
[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
d2a137c1 21#include <TInterpreter.h>
e849dadd 22#include <TROOT.h>
d2a137c1 23
c6d78c69 24#include <unistd.h>
25#include <signal.h>
26
27//______________________________________________________________________________
28// Full description of AliOnlineReco
29//
30
31ClassImp(AliOnlineReco)
32
33AliOnlineReco::AliOnlineReco() :
34 TGMainFrame(gClient->GetRoot(), 400, 400),
35
dc836d53 36 fRunList(0), fAutoRun(0), fStartButt(0), fStopButt(0), fExitButt(0),
37 fAutoRunTimer(0), fAutoRunScheduled(0), fAutoRunRunning(0),
4f6eef9f 38 fRun2PidMap(),
e849dadd 39 fTestMode(kFALSE),
40 fDoExit(kFALSE)
c6d78c69 41{
48c0589a 42 // Constructor.
43
c6d78c69 44 // GUI components.
45 fRunList = new TGListBox(this);
46 AddFrame(fRunList, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
47
48 TGHorizontalFrame *hf = new TGHorizontalFrame(this, 1, 20);
49
dc836d53 50 fAutoRun = new TGCheckButton(hf, "AutoRun");
51 hf->AddFrame(fAutoRun, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
52 fAutoRun->Connect("Clicked()", "AliOnlineReco", this, "DoAutoRun()");
53
c6d78c69 54 fStartButt = new TGTextButton(hf, "Start");
55 hf->AddFrame(fStartButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
56 fStartButt->Connect("Clicked()", "AliOnlineReco", this, "DoStart()");
57
58 fStopButt = new TGTextButton(hf, "Stop");
59 hf->AddFrame(fStopButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
60 fStopButt->Connect("Clicked()", "AliOnlineReco", this, "DoStop()");
61
dc836d53 62 fExitButt = new TGTextButton(hf, "Exit");
63 hf->AddFrame(fExitButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
64 fExitButt->Connect("Clicked()", "AliOnlineReco", this, "DoExit()");
c6d78c69 65
66 AddFrame(hf, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
67
68 MapSubwindows();
69 Layout();
70 SetWindowName("Alice Online Reconstruction");
71
e35c7687 72 // DIM interface.
73 for (Int_t i = 0; i < 5; ++i)
74 {
75 if (i == 0)
76 {
77 fSOR[i] = new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_SOR_PHYSICS");
78 fEOR[i] = new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_EOR_PHYSICS");
79 }
80 else
81 {
82 fSOR[i] = new AliDimIntNotifier(Form("/LOGBOOK/SUBSCRIBE/DAQ_SOR_PHYSICS_%d", i));
83 fEOR[i] = new AliDimIntNotifier(Form("/LOGBOOK/SUBSCRIBE/DAQ_EOR_PHYSICS_%d", i));
84 }
dc836d53 85
e35c7687 86 fSOR[i]->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "StartOfRun(Int_t)");
87 fEOR[i]->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "EndOfRun(Int_t)");
88 }
c6d78c69 89
dc836d53 90 const Int_t autoRunDelay = 10; // should go to config
91 fAutoRunTimer = new TTimer(autoRunDelay * 1000l);
92 fAutoRunTimer->Connect("Timeout()", "AliOnlineReco", this, "AutoRunTimerTimeout()");
93
b6269fdc 94 // OS Signal handlers
c6d78c69 95 // ROOT's TSignalHAndler works not SIGCHLD ...
93624d6b 96 AliChildProcTerminator::Instance()->Connect("ChildProcTerm(Int_t,Int_t)", "AliOnlineReco", this, "ChildProcTerm(Int_t,Int_t)");
e849dadd 97
98 // we need this by OnExit() to kill next process child after another
99 Connect("ChildProcTerm(Int_t,Int_t)", "AliOnlineReco", this, "ExitLoopChildProcTerm()");
c6d78c69 100}
101
dc836d53 102AliOnlineReco::~AliOnlineReco()
103{
48c0589a 104 // Destructor.
105
dc836d53 106 delete fAutoRunTimer;
107}
108
109Int_t AliOnlineReco::GetLastRun() const
110{
48c0589a 111 // Returns the last started run.
112
dc836d53 113 return fRun2PidMap.empty() ? 0 : fRun2PidMap.rbegin()->first;
114}
115
116Bool_t AliOnlineReco::GetAutoRunMode() const
117{
48c0589a 118 // Return state of auto-run flag.
119
dc836d53 120 return fAutoRun->IsOn();
121}
122
123void AliOnlineReco::SetAutoRunMode(Bool_t ar)
124{
48c0589a 125 // Set auto-run flag.
126
dc836d53 127 if (ar == fAutoRun->IsOn())
128 return;
129
130 fAutoRun->SetState(ar ? kButtonDown : kButtonUp, kTRUE);
131}
132
133//------------------------------------------------------------------------------
134// Private methods
135//------------------------------------------------------------------------------
136
c6d78c69 137AliOnlineReco::mIntInt_i AliOnlineReco::FindMapEntryByPid(Int_t pid)
138{
48c0589a 139 // Find run-to-pid map iterator by pid.
140 // Requires iteration over map.
141
c6d78c69 142 for (mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); ++i)
143 {
144 if (i->second == pid)
145 return i;
146 }
147
148 return fRun2PidMap.end();
149}
150
dc836d53 151void AliOnlineReco::StartAliEve(mIntInt_i& mi)
152{
48c0589a 153 // Start alieve to process run given my the run-pid entry.
154
dc836d53 155 Int_t run = mi->first;
156
157 if (mi->second == 0)
158 {
159 pid_t pid = fork();
160 if (pid == -1)
161 {
162 perror("DoStart -- Fork failed");
163 return;
164 }
165
166 if (pid)
167 {
168 mi->second = pid;
169 fRunList->RemoveEntry(run);
170 fRunList->AddEntrySort(TString::Format("%-20d -- RUNNING", run), run);
171 fRunList->Layout();
172 }
173 else
174 {
d2a137c1 175 gCINTMutex = 0;
176
177 struct sigaction sac;
b6269fdc 178 memset(&sac, 0, sizeof(sac));
179 sac.sa_handler = NULL;
d2a137c1 180 sigemptyset(&sac.sa_mask);
181 sac.sa_flags = 0;
07f75a04 182
183 // The sa_restorer field is Not POSIX and obsolete.
184 // This is for compilation on other systems
185 #if defined(__linux) && \
186 (defined(__i386__) || defined(__x86_64__)) && \
187 defined(__GNUC__)
188 sac.sa_restorer= NULL;
189 #endif
b6269fdc 190 sigaction(SIGCHLD, &sac, NULL);
191
dc836d53 192 int s;
193 if (fTestMode)
194 {
b6269fdc 195 s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0);
dc836d53 196 }
197 else
198 {
b6269fdc 199 Int_t procPID = gSystem->GetPid();
200 TString logFile = Form("%s/reco/log/run%d_%d.log",
201 gSystem->Getenv("ONLINERECO_BASE_DIR"),
202 run,
203 (Int_t)procPID);
204 Info("DoStart","Reconstruction log will be written to %s",logFile.Data());
205 gSystem->RedirectOutput(logFile.Data());
206
207 gSystem->cd(Form("%s/reco",gSystem->Getenv("ONLINERECO_BASE_DIR")));
208
209 TString gdcs;
210 if (RetrieveGRP(run,gdcs) <= 0 || gdcs.IsNull())
211 gSystem->Exit(1);
212
213 gSystem->Setenv("DATE_RUN_NUMBER", Form("%d", run));
214 // Setting CDB
215 // AliCDBManager * man = AliCDBManager::Instance();
216 // man->SetDefaultStorage("local:///local/cdb");
217 // man->SetSpecificStorage("GRP/GRP/Data",
218 // Form("local://%s",gSystem->pwd()));
219 // man->SetSpecificStorage("GRP/CTP/Config",
220 // Form("local://%s",gSystem->pwd()));
221 // man->SetSpecificStorage("ACORDE/Align/Data",
222 // "local://$ALICE_ROOT/OCDB");
223
224 gSystem->mkdir(Form("run%d_%d", run, (Int_t)procPID));
225 gSystem->cd(Form("run%d_%d", run, (Int_t)procPID));
226
227 TString recMacroPath(gSystem->Getenv("ONLINERECO_MACRO"));
228 if (recMacroPath.IsNull()) {
229 recMacroPath = "$ALICE_ROOT/MONITOR/rec.C";
230 }
e849dadd 231
b6269fdc 232 s = execlp("alieve",
233 "alieve",
234 "-q",
235 Form("%s(\"mem://@*:\")", gSystem->ExpandPathName(recMacroPath.Data())),
236 (char*) 0);
237
238 gSystem->Exec(Form("rm -rf %s/reco/run%d_%d",gSystem->Getenv("ONLINERECO_BASE_DIR"),run,(Int_t)procPID));
dc836d53 239 }
240
241 if (s == -1)
242 {
b6269fdc 243 perror("execlp failed - this will not end well");
244 gSystem->Exit(1);
dc836d53 245 }
246 }
247 }
248 else
249 {
250 Error("DoStart", "Process already running.");
251 }
252}
253
254void AliOnlineReco::KillPid(Int_t pid)
255{
48c0589a 256 // Terminate process given by pid.
257
dc836d53 258 // Send terminate signal to process ...
259
260 if (fTestMode)
261 {
262 kill(pid, SIGTERM);
263 }
264 else
265 {
266 // alieve will auto-destruct on SIGUSR1
267 kill(pid, SIGUSR1);
268 }
269}
270
271void AliOnlineReco::StartAutoRunTimer(Int_t run)
272{
273 // Start timer for given run.
274 // If an auto-started run is already active, this call is ignored.
275 // If timer is already active, it is restarted.
276
277 if (fAutoRunRunning)
278 return;
279
280 fAutoRunTimer->Reset();
281 fAutoRunTimer->TurnOn();
282 fAutoRunScheduled = run;
283
284 Info("StartAutoRunTimer", "Scheduling run %d for auto-display.", run);
285}
286
287void AliOnlineReco::StopAutoRunTimer()
288{
48c0589a 289 // Stop auto-run timer.
290
dc836d53 291 fAutoRunTimer->TurnOff();
292 fAutoRunScheduled = 0;
293}
294
295void AliOnlineReco::AutoRunTimerTimeout()
296{
48c0589a 297 // Slot called on auto-timer timeout.
298
dc836d53 299 Int_t run = fAutoRunScheduled;
300
301 StopAutoRunTimer();
302
303 mIntInt_i i = fRun2PidMap.find(run);
304
305 if (i == fRun2PidMap.end())
306 {
307 Warning("AutoRunTimerTimeout", "run no longer active.");
308 return;
309 }
310
311 Info("AutoRunTimerTimeout", "Starting display for run %d.", run);
312
313 StartAliEve(i);
314 fAutoRunRunning = run;
315}
316
c6d78c69 317//------------------------------------------------------------------------------
318// Handlers of DIM signals.
319//------------------------------------------------------------------------------
320
321void AliOnlineReco::StartOfRun(Int_t run)
322{
48c0589a 323 // Slot called from DIM handler on start of run.
324
c6d78c69 325 mIntInt_i i = fRun2PidMap.find(run);
326 if (i == fRun2PidMap.end())
327 {
328 fRun2PidMap[run] = 0;
329 fRunList->AddEntrySort(TString::Format("%d", run), run);
330 fRunList->Layout();
dc836d53 331
332 if (fAutoRun->IsOn())
333 {
334 StartAutoRunTimer(run);
335 }
c6d78c69 336 }
337 else
338 {
339 Error("StartOfRun", "Run %d already registered.", run);
340 }
341}
342
343void AliOnlineReco::EndOfRun(Int_t run)
344{
48c0589a 345 // Slot called from DIM handler on stop of run.
346
c6d78c69 347 mIntInt_i i = fRun2PidMap.find(run);
348 if (i != fRun2PidMap.end())
349 {
350 Int_t pid = i->second;
351 fRunList->RemoveEntry(run);
352 fRunList->Layout();
353 fRun2PidMap.erase(i);
354 if (pid)
355 {
dc836d53 356 KillPid(pid);
c6d78c69 357 }
358 gClient->NeedRedraw(fRunList);
dc836d53 359
360 if (fAutoRunRunning == run)
361 {
362 fAutoRunRunning = 0;
363 }
c6d78c69 364 }
365 else
366 {
367 Error("EndOfRun", "Run %d not registered.", run);
368 }
369}
370
371//------------------------------------------------------------------------------
372// Handlers of OS signals.
373//------------------------------------------------------------------------------
374
93624d6b 375void AliOnlineReco::ChildProcTerm(Int_t pid, Int_t status)
c6d78c69 376{
48c0589a 377 // Slot called on termination of child process.
b6269fdc 378
93624d6b 379 printf("child process termination pid=%d, status=%d...\n", pid, status);
c6d78c69 380
381 mIntInt_i i = FindMapEntryByPid(pid);
382 if (i != fRun2PidMap.end())
383 {
384 Int_t run = i->first;
385 fRunList->RemoveEntry(run);
386 if (status == 0)
387 {
82142d1d 388 fRunList->AddEntrySort(TString::Format("%-20d -- PROCESSED", run), run);
c6d78c69 389 }
390 else
391 {
82142d1d 392 fRunList->AddEntrySort(TString::Format("%-20d -- PROCESSED [%d]", run, status), run);
c6d78c69 393 }
394 fRunList->Layout();
e849dadd 395 fRun2PidMap.erase(i);
dc836d53 396
397 if (fAutoRunRunning == run && fAutoRun->IsOn())
398 {
399 fAutoRunRunning = 0;
400 StartAutoRunTimer(run);
401 }
402 else
403 {
404 fAutoRunRunning = 0;
405 }
c6d78c69 406 }
407 else
408 {
93624d6b 409 Warning("ChildProcTerm", "Process with pid=%d not registered.", pid);
c6d78c69 410 }
e849dadd 411
412 Emit("ChildProcTerm(Int_t, Int_t)");
413}
414
415void AliOnlineReco::ExitLoopChildProcTerm()
416{
417 if(fDoExit)
418 DoExit();
c6d78c69 419}
420
421//------------------------------------------------------------------------------
422// Handlers of button signals.
423//------------------------------------------------------------------------------
424
dc836d53 425void AliOnlineReco::DoAutoRun()
426{
48c0589a 427 // Slot called from auto-run check-box.
428
dc836d53 429 Bool_t autoRun = fAutoRun->IsOn();
430
431 if (autoRun)
432 fStartButt->SetEnabled(kFALSE);
433 else
434 fStartButt->SetEnabled(kTRUE);
435}
436
c6d78c69 437void AliOnlineReco::DoStart()
438{
48c0589a 439 // Slot called from Start button.
440
c6d78c69 441 Int_t run = fRunList->GetSelected();
442 mIntInt_i i = fRun2PidMap.find(run);
443
444 if (i == fRun2PidMap.end())
445 {
446 Error("DoStart", "no selection");
447 return;
448 }
449
dc836d53 450 StartAliEve(i);
c6d78c69 451}
452
453void AliOnlineReco::DoStop()
454{
48c0589a 455 // Slot called from Stop button.
456
c6d78c69 457 Int_t run = fRunList->GetSelected();
458 mIntInt_i i = fRun2PidMap.find(run);
459
460 if (i == fRun2PidMap.end())
461 {
462 Error("DoStop", "no selection");
463 return;
464 }
465
466 Int_t pid = i->second;
467 if (pid)
468 {
dc836d53 469 KillPid(pid);
c6d78c69 470 }
471 else
472 {
473 Error("DoStop", "Process not running.");
474 }
475}
476
dc836d53 477void AliOnlineReco::DoExit()
c6d78c69 478{
e849dadd 479 // Slot called from Exit button or CloseWindow.
480
481 // kill all started processes
482 Int_t pid;
483
484 // disable all widgets & AutoRunTimer
485 // so that user does not initiate other GUI signals
486 if(!fDoExit){
487 fAutoRun->SetEnabled(kFALSE);
488 fStartButt->SetEnabled(kFALSE);
489 fStopButt->SetEnabled(kFALSE);
490 fExitButt->SetEnabled(kFALSE);
491
492 StopAutoRunTimer();
493 fDoExit = kTRUE;
494 gROOT->SetInterrupt(kTRUE);
495 }
496
497 gSystem->ProcessEvents();
498
499 // clear runs std::map
500 for(mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); i++)
501 {
502 pid = i->second;
503
504 if(pid==0)
505 {
506 fRun2PidMap.erase(i); // if process is not started just remove it from map
507 }
508 else
509 {
510 // send kill signal to started process
511 KillPid(pid);
512
513 // we need to exit loop to let ROOT process events list
514 // after kill signal above, process pid starts signal AliChildProcTerminator::ChildProcTerm(int, int)
515 // and arrives in AliOnlineReco::ChildProcTerm(int, int)
516 // after this we return in DoExit() to process next run
517 break;
518 }
519
520 }
521
522 // we can exit after we killed all processes
523 if(fRun2PidMap.empty() ) gSystem->ExitLoop();
c6d78c69 524}
525
526void AliOnlineReco::CloseWindow()
527{
48c0589a 528 // Virtual method called when window-manager close-window button is pressed.
e849dadd 529
530 DoExit();
531
c6d78c69 532}
a15a9f84 533
48c0589a 534Int_t AliOnlineReco::RetrieveGRP(UInt_t run, TString &gdc)
535{
536 // Retrieve GRP entry for given run from aldaqdb.
a15a9f84 537
8f772d4b 538 TString dbHost = gSystem->Getenv("ONLINERECO_DB_HOST");
539 if (dbHost.IsNull())
540 {
541 dbHost = "aldaqdb";
542 }
543
544 TString dbPort = gSystem->Getenv("ONLINERECO_DB_PORT");
545 if (dbPort.IsNull())
546 {
547 dbPort = "0";
548 }
549
550 TString dbName = gSystem->Getenv("ONLINERECO_DB_NAME");
551 if (dbName.IsNull())
552 {
553 dbName = "LOGBOOK";
554 }
555
556 TString user = gSystem->Getenv("ONLINERECO_DB_USER");
557 if (user.IsNull())
558 {
559 user = "logbook";
560 }
561
562 TString password = gSystem->Getenv("ONLINERECO_DB_PASSWORD");
563 if (password.IsNull())
564 {
565 password = "alice";
566 }
567
568 Int_t ret=AliGRPPreprocessor::ReceivePromptRecoParameters(run, dbHost.Data(),
b6269fdc 569 dbPort.Atoi(), dbName.Data(),
570 user.Data(), password.Data(),
571 Form("local://%s",gSystem->pwd()),
572 gdc);
8f772d4b 573
a15a9f84 574 if(ret>0) Info("RetrieveGRP","Last run of the same type is: %d",ret);
575 else if(ret==0) Warning("RetrieveGRP","No previous run of the same type found");
576 else if(ret<0) Error("Retrieve","Error code while retrieving GRP parameters returned: %d",ret);
577 return(ret);
578}