2 // Author: Matevz Tadel 2007
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 **************************************************************************/
10 #include "AliOnlineReco.h"
11 #include "AliChildProcTerminator.h"
12 #include "AliDimIntNotifier.h"
13 #include "AliCDBManager.h"
14 #include "AliGRPPreprocessor.h"
18 #include <TGListBox.h>
21 #include <TInterpreter.h>
27 //______________________________________________________________________________
28 // Full description of AliOnlineReco
31 ClassImp(AliOnlineReco)
33 AliOnlineReco::AliOnlineReco() :
34 TGMainFrame(gClient->GetRoot(), 400, 400),
36 fRunList(0), fAutoRun(0), fStartButt(0), fStopButt(0), fExitButt(0),
37 fAutoRunTimer(0), fAutoRunScheduled(0), fAutoRunRunning(0),
45 fRunList = new TGListBox(this);
46 AddFrame(fRunList, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
48 TGHorizontalFrame *hf = new TGHorizontalFrame(this, 1, 20);
50 fAutoRun = new TGCheckButton(hf, "AutoRun");
51 hf->AddFrame(fAutoRun, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
52 fAutoRun->Connect("Clicked()", "AliOnlineReco", this, "DoAutoRun()");
54 fStartButt = new TGTextButton(hf, "Start");
55 hf->AddFrame(fStartButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
56 fStartButt->Connect("Clicked()", "AliOnlineReco", this, "DoStart()");
58 fStopButt = new TGTextButton(hf, "Stop");
59 hf->AddFrame(fStopButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
60 fStopButt->Connect("Clicked()", "AliOnlineReco", this, "DoStop()");
62 fExitButt = new TGTextButton(hf, "Exit");
63 hf->AddFrame(fExitButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
64 fExitButt->Connect("Clicked()", "AliOnlineReco", this, "DoExit()");
66 AddFrame(hf, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
70 SetWindowName("Alice Online Reconstruction");
73 for (Int_t i = 0; i < 5; ++i)
77 fSOR[i] = new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_SOR_PHYSICS");
78 fEOR[i] = new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_EOR_PHYSICS");
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));
86 fSOR[i]->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "StartOfRun(Int_t)");
87 fEOR[i]->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "EndOfRun(Int_t)");
90 const Int_t autoRunDelay = 10; // should go to config
91 fAutoRunTimer = new TTimer(autoRunDelay * 1000l);
92 fAutoRunTimer->Connect("Timeout()", "AliOnlineReco", this, "AutoRunTimerTimeout()");
95 // ROOT's TSignalHAndler works not SIGCHLD ...
96 AliChildProcTerminator::Instance()->Connect("ChildProcTerm(Int_t,Int_t)", "AliOnlineReco", this, "ChildProcTerm(Int_t,Int_t)");
98 // we need this by OnExit() to kill next process child after another
99 Connect("ChildProcTerm(Int_t,Int_t)", "AliOnlineReco", this, "ExitLoopChildProcTerm()");
102 AliOnlineReco::~AliOnlineReco()
106 delete fAutoRunTimer;
109 Int_t AliOnlineReco::GetLastRun() const
111 // Returns the last started run.
113 return fRun2PidMap.empty() ? 0 : fRun2PidMap.rbegin()->first;
116 Bool_t AliOnlineReco::GetAutoRunMode() const
118 // Return state of auto-run flag.
120 return fAutoRun->IsOn();
123 void AliOnlineReco::SetAutoRunMode(Bool_t ar)
125 // Set auto-run flag.
127 if (ar == fAutoRun->IsOn())
130 fAutoRun->SetState(ar ? kButtonDown : kButtonUp, kTRUE);
133 //------------------------------------------------------------------------------
135 //------------------------------------------------------------------------------
137 AliOnlineReco::mIntInt_i AliOnlineReco::FindMapEntryByPid(Int_t pid)
139 // Find run-to-pid map iterator by pid.
140 // Requires iteration over map.
142 for (mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); ++i)
144 if (i->second == pid)
148 return fRun2PidMap.end();
151 void AliOnlineReco::StartAliEve(mIntInt_i& mi)
153 // Start alieve to process run given my the run-pid entry.
155 Int_t run = mi->first;
162 perror("DoStart -- Fork failed");
169 fRunList->RemoveEntry(run);
170 fRunList->AddEntrySort(TString::Format("%-20d -- RUNNING", run), run);
177 struct sigaction sac;
178 memset(&sac, 0, sizeof(sac));
179 sac.sa_handler = NULL;
180 sigemptyset(&sac.sa_mask);
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__)) && \
188 sac.sa_restorer= NULL;
190 sigaction(SIGCHLD, &sac, NULL);
195 s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0);
199 Int_t procPID = gSystem->GetPid();
200 TString logFile = Form("%s/reco/log/run%d_%d.log",
201 gSystem->Getenv("ONLINERECO_BASE_DIR"),
204 Info("DoStart","Reconstruction log will be written to %s",logFile.Data());
205 gSystem->RedirectOutput(logFile.Data());
207 gSystem->cd(Form("%s/reco",gSystem->Getenv("ONLINERECO_BASE_DIR")));
210 if (RetrieveGRP(run,gdcs) <= 0 || gdcs.IsNull())
213 gSystem->Setenv("DATE_RUN_NUMBER", Form("%d", run));
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");
224 gSystem->mkdir(Form("run%d_%d", run, (Int_t)procPID));
225 gSystem->cd(Form("run%d_%d", run, (Int_t)procPID));
227 TString recMacroPath(gSystem->Getenv("ONLINERECO_MACRO"));
228 if (recMacroPath.IsNull()) {
229 recMacroPath = "$ALICE_ROOT/MONITOR/rec.C";
235 Form("%s(\"mem://@*:\")", gSystem->ExpandPathName(recMacroPath.Data())),
242 perror("execlp failed - this will not end well");
249 Error("DoStart", "Process already running.");
253 void AliOnlineReco::KillPid(Int_t pid)
255 // Terminate process given by pid.
257 // Send terminate signal to process ...
265 // alieve will auto-destruct on SIGUSR1
270 void AliOnlineReco::StartAutoRunTimer(Int_t run)
272 // Start timer for given run.
273 // If an auto-started run is already active, this call is ignored.
274 // If timer is already active, it is restarted.
279 fAutoRunTimer->Reset();
280 fAutoRunTimer->TurnOn();
281 fAutoRunScheduled = run;
283 Info("StartAutoRunTimer", "Scheduling run %d for auto-display.", run);
286 void AliOnlineReco::StopAutoRunTimer()
288 // Stop auto-run timer.
290 fAutoRunTimer->TurnOff();
291 fAutoRunScheduled = 0;
294 void AliOnlineReco::AutoRunTimerTimeout()
296 // Slot called on auto-timer timeout.
298 Int_t run = fAutoRunScheduled;
302 mIntInt_i i = fRun2PidMap.find(run);
304 if (i == fRun2PidMap.end())
306 Warning("AutoRunTimerTimeout", "run no longer active.");
310 Info("AutoRunTimerTimeout", "Starting display for run %d.", run);
313 fAutoRunRunning = run;
316 //------------------------------------------------------------------------------
317 // Handlers of DIM signals.
318 //------------------------------------------------------------------------------
320 void AliOnlineReco::StartOfRun(Int_t run)
322 // Slot called from DIM handler on start of run.
324 mIntInt_i i = fRun2PidMap.find(run);
325 if (i == fRun2PidMap.end())
327 fRun2PidMap[run] = 0;
328 fRunList->AddEntrySort(TString::Format("%d", run), run);
331 if (fAutoRun->IsOn())
333 StartAutoRunTimer(run);
338 Error("StartOfRun", "Run %d already registered.", run);
342 void AliOnlineReco::EndOfRun(Int_t run)
344 // Slot called from DIM handler on stop of run.
346 mIntInt_i i = fRun2PidMap.find(run);
347 if (i != fRun2PidMap.end())
349 Int_t pid = i->second;
350 fRunList->RemoveEntry(run);
352 fRun2PidMap.erase(i);
357 gClient->NeedRedraw(fRunList);
359 if (fAutoRunRunning == run)
366 Error("EndOfRun", "Run %d not registered.", run);
370 //------------------------------------------------------------------------------
371 // Handlers of OS signals.
372 //------------------------------------------------------------------------------
374 void AliOnlineReco::ChildProcTerm(Int_t pid, Int_t status)
376 // Slot called on termination of child process.
378 printf("child process termination pid=%d, status=%d...\n", pid, status);
380 mIntInt_i i = FindMapEntryByPid(pid);
381 if (i != fRun2PidMap.end())
383 Int_t run = i->first;
384 fRunList->RemoveEntry(run);
386 // clean (remove) run's reconstructed directory
387 gSystem->Exec(Form("rm -rf %s/reco/run%d_%d",gSystem->Getenv("ONLINERECO_BASE_DIR"),run,pid));
391 fRunList->AddEntrySort(TString::Format("%-20d -- PROCESSED", run), run);
395 fRunList->AddEntrySort(TString::Format("%-20d -- PROCESSED [%d]", run, status), run);
398 fRun2PidMap.erase(i);
400 if (fAutoRunRunning == run && fAutoRun->IsOn())
403 StartAutoRunTimer(run);
412 Warning("ChildProcTerm", "Process with pid=%d not registered.", pid);
415 Emit("ChildProcTerm(Int_t, Int_t)");
418 void AliOnlineReco::ExitLoopChildProcTerm()
424 //------------------------------------------------------------------------------
425 // Handlers of button signals.
426 //------------------------------------------------------------------------------
428 void AliOnlineReco::DoAutoRun()
430 // Slot called from auto-run check-box.
432 Bool_t autoRun = fAutoRun->IsOn();
435 fStartButt->SetEnabled(kFALSE);
437 fStartButt->SetEnabled(kTRUE);
440 void AliOnlineReco::DoStart()
442 // Slot called from Start button.
444 Int_t run = fRunList->GetSelected();
445 mIntInt_i i = fRun2PidMap.find(run);
447 if (i == fRun2PidMap.end())
449 Error("DoStart", "no selection");
456 void AliOnlineReco::DoStop()
458 // Slot called from Stop button.
460 Int_t run = fRunList->GetSelected();
461 mIntInt_i i = fRun2PidMap.find(run);
463 if (i == fRun2PidMap.end())
465 Error("DoStop", "no selection");
469 Int_t pid = i->second;
476 Error("DoStop", "Process not running.");
480 void AliOnlineReco::DoExit()
482 // Slot called from Exit button or CloseWindow.
484 // kill all started processes
487 // disable all widgets & AutoRunTimer
488 // so that user does not initiate other GUI signals
490 fAutoRun->SetEnabled(kFALSE);
491 fStartButt->SetEnabled(kFALSE);
492 fStopButt->SetEnabled(kFALSE);
493 fExitButt->SetEnabled(kFALSE);
497 gROOT->SetInterrupt(kTRUE);
500 gSystem->ProcessEvents();
502 // clear runs std::map
503 for(mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); i++)
509 fRun2PidMap.erase(i); // if process is not started just remove it from map
513 // send kill signal to started process
516 // we need to exit loop to let ROOT process events list
517 // after kill signal above, process pid starts signal AliChildProcTerminator::ChildProcTerm(int, int)
518 // and arrives in AliOnlineReco::ChildProcTerm(int, int)
519 // after this we return in DoExit() to process next run
525 // we can exit after we killed all processes
526 if(fRun2PidMap.empty() ) gSystem->ExitLoop();
529 void AliOnlineReco::CloseWindow()
531 // Virtual method called when window-manager close-window button is pressed.
537 Int_t AliOnlineReco::RetrieveGRP(UInt_t run, TString &gdc)
539 // Retrieve GRP entry for given run from aldaqdb.
541 TString dbHost = gSystem->Getenv("ONLINERECO_DB_HOST");
547 TString dbPort = gSystem->Getenv("ONLINERECO_DB_PORT");
553 TString dbName = gSystem->Getenv("ONLINERECO_DB_NAME");
559 TString user = gSystem->Getenv("ONLINERECO_DB_USER");
565 TString password = gSystem->Getenv("ONLINERECO_DB_PASSWORD");
566 if (password.IsNull())
571 Int_t ret=AliGRPPreprocessor::ReceivePromptRecoParameters(run, dbHost.Data(),
572 dbPort.Atoi(), dbName.Data(),
573 user.Data(), password.Data(),
574 Form("local://%s",gSystem->pwd()),
577 if(ret>0) Info("RetrieveGRP","Last run of the same type is: %d",ret);
578 else if(ret==0) Warning("RetrieveGRP","No previous run of the same type found");
579 else if(ret<0) Error("Retrieve","Error code while retrieving GRP parameters returned: %d",ret);