Autorun functionality added (Matevz)
authorcvetan <cvetan@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 8 Oct 2009 12:19:48 +0000 (12:19 +0000)
committercvetan <cvetan@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 8 Oct 2009 12:19:48 +0000 (12:19 +0000)
MONITOR/AliDimIntNotifier.cxx
MONITOR/AliDimIntNotifier.h
MONITOR/AliOnlineReco.cxx
MONITOR/AliOnlineReco.h
MONITOR/alionlinemonitor.cxx

index 99de6c2..39ee16e 100644 (file)
@@ -8,7 +8,7 @@
  **************************************************************************/
 
 #include "AliDimIntNotifier.h"
-
+#include <TError.h>
 #include <signal.h>
 
 //______________________________________________________________________________
@@ -27,7 +27,6 @@ void AliDimIntNotifier::SetMainThreadId()
 AliDimIntNotifier::AliDimIntNotifier(const TString& service) :
   DimUpdatedInfo(service, -1),
   fNotifyLck(kTRUE),
-  fNotifyCnd(&fNotifyLck),
   fLastMessage(-1)
 {
   fReThreader.Connect("Timeout()", "AliDimIntNotifier", this, "DimMessage()");
@@ -54,11 +53,10 @@ void AliDimIntNotifier::infoHandler()
   if (TThread::SelfId() != fgMainThreadId)
   {
     StartTimer();
-    fNotifyCnd.Wait();
   }
   else
   {
-    Warning("infoHandler", "DIM message received from CINT thread.");
+    ::Warning("DIMinfoHandler", "DIM message received from CINT thread.");
     DimMessage();
   }
   fNotifyLck.UnLock();
@@ -73,7 +71,6 @@ void AliDimIntNotifier::infoHandlerTest(Int_t fake)
   if (TThread::SelfId() != fgMainThreadId)
   {
     StartTimer();
-    fNotifyCnd.Wait();
   }
   else
   {
@@ -89,13 +86,5 @@ void AliDimIntNotifier::DimMessage(Int_t)
   if (fLastMessage != -1)
   {
     Emit("DimMessage(Int_t)", fLastMessage);
-    printf("Notify %d\n", fLastMessage);
-  }
-  else
-  {
-    printf("NOTNotify %d\n", fLastMessage);
   }
-  fNotifyLck.Lock();
-  fNotifyCnd.Signal();
-  fNotifyLck.UnLock();
 }
index 8d2fc85..7e18b53 100644 (file)
@@ -58,11 +58,10 @@ private:
   void StartTimer();
   void StopTimer();
 
-  TTimer       fReThreader;
-  TMutex       fNotifyLck;
-  TCondition   fNotifyCnd;
+  TTimer fReThreader;
+  TMutex fNotifyLck;
 
-  Int_t        fLastMessage;
+  Int_t  fLastMessage;
 
   static Long_t fgMainThreadId;
 
index 237f736..a256ca5 100644 (file)
@@ -2,7 +2,7 @@
 // Author: Matevz Tadel 2007
 
 /**************************************************************************
- * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
+ * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *)
  * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
  * full copyright notice.                                                 *
  **************************************************************************/
@@ -13,6 +13,8 @@
 #include "AliCDBManager.h"
 #include "AliGRPPreprocessor.h"
 
+#include <TTimer.h>
+
 #include <TGListBox.h>
 #include <TGButton.h>
 
@@ -28,8 +30,8 @@ ClassImp(AliOnlineReco)
 AliOnlineReco::AliOnlineReco() :
   TGMainFrame(gClient->GetRoot(), 400, 400),
 
-  fRunList(0), fStartButt(0), fStopButt(0), fXyzzButt(0),
-
+  fRunList(0), fAutoRun(0), fStartButt(0), fStopButt(0), fExitButt(0),
+  fAutoRunTimer(0), fAutoRunScheduled(0), fAutoRunRunning(0),
   fTestMode(kFALSE)
 {
   // GUI components.
@@ -38,6 +40,10 @@ AliOnlineReco::AliOnlineReco() :
 
   TGHorizontalFrame *hf = new TGHorizontalFrame(this, 1, 20);
 
+  fAutoRun = new TGCheckButton(hf, "AutoRun");
+  hf->AddFrame(fAutoRun, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
+  fAutoRun->Connect("Clicked()", "AliOnlineReco", this, "DoAutoRun()");
+
   fStartButt = new TGTextButton(hf, "Start");
   hf->AddFrame(fStartButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
   fStartButt->Connect("Clicked()", "AliOnlineReco", this, "DoStart()");
@@ -46,9 +52,9 @@ AliOnlineReco::AliOnlineReco() :
   hf->AddFrame(fStopButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
   fStopButt->Connect("Clicked()", "AliOnlineReco", this, "DoStop()");
 
-  fXyzzButt = new TGTextButton(hf, "Exit");
-  hf->AddFrame(fXyzzButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
-  fXyzzButt->Connect("Clicked()", "AliOnlineReco", this, "DoXyzz()");
+  fExitButt = new TGTextButton(hf, "Exit");
+  hf->AddFrame(fExitButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
+  fExitButt->Connect("Clicked()", "AliOnlineReco", this, "DoExit()");
 
   AddFrame(hf, new TGLayoutHints(kLHintsNormal | kLHintsExpandX));
 
@@ -69,15 +75,47 @@ AliOnlineReco::AliOnlineReco() :
       fSOR[i] = new AliDimIntNotifier(Form("/LOGBOOK/SUBSCRIBE/DAQ_SOR_PHYSICS_%d", i));
       fEOR[i] = new AliDimIntNotifier(Form("/LOGBOOK/SUBSCRIBE/DAQ_EOR_PHYSICS_%d", i));
     }
+
     fSOR[i]->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "StartOfRun(Int_t)");
     fEOR[i]->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "EndOfRun(Int_t)");
   }
 
+  const Int_t autoRunDelay = 10; // should go to config
+  fAutoRunTimer = new TTimer(autoRunDelay * 1000l);
+  fAutoRunTimer->Connect("Timeout()", "AliOnlineReco", this, "AutoRunTimerTimeout()");
+
   // Signal handlers
   // ROOT's TSignalHAndler works not SIGCHLD ...
   AliChildProcTerminator::Instance()->Connect("ChildProcTerm(Int_t,Int_t)", "AliOnlineReco", this, "ChildProcTerm(Int_t,Int_t)");
 }
 
+AliOnlineReco::~AliOnlineReco()
+{
+  delete fAutoRunTimer;
+}
+
+Int_t AliOnlineReco::GetLastRun() const
+{
+  return fRun2PidMap.empty() ? 0 : fRun2PidMap.rbegin()->first;
+}
+
+Bool_t AliOnlineReco::GetAutoRunMode() const
+{
+  return fAutoRun->IsOn();
+}
+
+void AliOnlineReco::SetAutoRunMode(Bool_t ar)
+{
+  if (ar == fAutoRun->IsOn())
+    return;
+
+  fAutoRun->SetState(ar ? kButtonDown : kButtonUp, kTRUE);
+}
+
+//------------------------------------------------------------------------------
+// Private methods
+//------------------------------------------------------------------------------
+
 AliOnlineReco::mIntInt_i AliOnlineReco::FindMapEntryByPid(Int_t pid)
 {
   for (mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); ++i)
@@ -89,6 +127,142 @@ AliOnlineReco::mIntInt_i AliOnlineReco::FindMapEntryByPid(Int_t pid)
   return fRun2PidMap.end();
 }
 
+void AliOnlineReco::StartAliEve(mIntInt_i& mi)
+{
+  Int_t run = mi->first;
+
+  if (mi->second == 0)
+  {
+    pid_t pid = fork();
+    if (pid == -1)
+    {
+      perror("DoStart -- Fork failed");
+      return;
+    }
+
+    if (pid)
+    {
+      mi->second = pid;
+      fRunList->RemoveEntry(run);
+      fRunList->AddEntrySort(TString::Format("%-20d -- RUNNING", run), run);
+      fRunList->Layout();
+    }
+    else
+    {
+      int s;
+      if (fTestMode)
+      {
+       s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0);
+      }
+      else
+      {
+       Int_t procPID = gSystem->GetPid();
+       TString logFile = Form("%s/reco/log/run%d_%d.log",
+                              gSystem->Getenv("ONLINERECO_BASE_DIR"),
+                              run,
+                              (Int_t)procPID);
+       Info("DoStart","Reconstruction log will be written to %s",logFile.Data());
+       gSystem->RedirectOutput(logFile.Data());
+
+       gSystem->cd(Form("%s/reco",gSystem->Getenv("ONLINERECO_BASE_DIR")));
+
+       TString gdcs;
+       if (RetrieveGRP(run,gdcs) <= 0 || gdcs.IsNull()) 
+         gSystem->Exit(1);
+
+       gSystem->Setenv("DATE_RUN_NUMBER", Form("%d", run));
+       // Setting CDB
+//     AliCDBManager * man = AliCDBManager::Instance();
+//     man->SetDefaultStorage("local:///local/cdb");
+//     man->SetSpecificStorage("GRP/GRP/Data",
+//                           Form("local://%s",gSystem->pwd()));
+//     man->SetSpecificStorage("GRP/CTP/Config",
+//                           Form("local://%s",gSystem->pwd()));
+//     man->SetSpecificStorage("ACORDE/Align/Data",
+//                             "local://$ALICE_ROOT/OCDB");
+
+       gSystem->mkdir(Form("run%d_%d", run, (Int_t)procPID));
+       gSystem->cd(Form("run%d_%d", run, (Int_t)procPID));
+
+       const char *recMacroPath = "$ALICE_ROOT/test/cosmic/rec.C";
+
+       s = execlp("alieve",
+                  "alieve",
+                  "-q",
+                  Form("%s(\"mem://@*:\")", gSystem->ExpandPathName(recMacroPath)),
+                  (char*) 0);
+      }
+
+      if (s == -1)
+      {
+       perror("execlp failed - this will not end well");
+       gSystem->Exit(1);
+      }
+    }
+  }
+  else
+  {
+    Error("DoStart", "Process already running.");
+  }
+}
+
+void AliOnlineReco::KillPid(Int_t pid)
+{
+  // Send terminate signal to process ...
+
+  if (fTestMode)
+  {
+    kill(pid, SIGTERM);
+  }
+  else
+  {
+    // alieve will auto-destruct on SIGUSR1
+    kill(pid, SIGUSR1);
+  }
+}
+
+void AliOnlineReco::StartAutoRunTimer(Int_t run)
+{
+  // Start timer for given run.
+  // If an auto-started run is already active, this call is ignored.
+  // If timer is already active, it is restarted.
+
+  if (fAutoRunRunning)
+    return;
+
+  fAutoRunTimer->Reset();
+  fAutoRunTimer->TurnOn();
+  fAutoRunScheduled = run;
+
+  Info("StartAutoRunTimer", "Scheduling run %d for auto-display.", run);
+}
+
+void AliOnlineReco::StopAutoRunTimer()
+{
+  fAutoRunTimer->TurnOff();
+  fAutoRunScheduled = 0;
+}
+
+void AliOnlineReco::AutoRunTimerTimeout()
+{
+  Int_t run = fAutoRunScheduled;
+
+  StopAutoRunTimer();
+
+  mIntInt_i i = fRun2PidMap.find(run);
+
+  if (i == fRun2PidMap.end())
+  {
+    Warning("AutoRunTimerTimeout", "run no longer active.");
+    return;
+  }
+
+  Info("AutoRunTimerTimeout", "Starting display for run %d.", run);
+
+  StartAliEve(i);
+  fAutoRunRunning = run;
+}
+
 //------------------------------------------------------------------------------
 // Handlers of DIM signals.
 //------------------------------------------------------------------------------
@@ -101,6 +275,11 @@ void AliOnlineReco::StartOfRun(Int_t run)
     fRun2PidMap[run] = 0;
     fRunList->AddEntrySort(TString::Format("%d", run), run);
     fRunList->Layout();
+
+    if (fAutoRun->IsOn())
+    {
+      StartAutoRunTimer(run);
+    }
   }
   else
   {
@@ -119,18 +298,14 @@ void AliOnlineReco::EndOfRun(Int_t run)
     fRun2PidMap.erase(i);
     if (pid)
     {
-      // Send terminate signal to process ...
-      if (fTestMode)
-      {
-       kill(pid, SIGTERM);
-      }
-      else
-      {
-       // alieve will auto-destruct on SIGUSR1
-       kill(pid, SIGUSR1);
-      }
+      KillPid(pid);
     }
     gClient->NeedRedraw(fRunList);
+
+    if (fAutoRunRunning == run)
+    {
+      fAutoRunRunning = 0;
+    }
   }
   else
   {
@@ -161,6 +336,16 @@ void AliOnlineReco::ChildProcTerm(Int_t pid, Int_t status)
     }
     fRunList->Layout();
     i->second = 0;
+
+    if (fAutoRunRunning == run && fAutoRun->IsOn())
+    {
+      fAutoRunRunning = 0;
+      StartAutoRunTimer(run);
+    }
+    else
+    {
+      fAutoRunRunning = 0;
+    }
   }
   else
   {
@@ -172,6 +357,16 @@ void AliOnlineReco::ChildProcTerm(Int_t pid, Int_t status)
 // Handlers of button signals.
 //------------------------------------------------------------------------------
 
+void AliOnlineReco::DoAutoRun()
+{
+  Bool_t autoRun = fAutoRun->IsOn();
+
+  if (autoRun)
+    fStartButt->SetEnabled(kFALSE);
+  else
+    fStartButt->SetEnabled(kTRUE);    
+}
+
 void AliOnlineReco::DoStart()
 {
   Int_t run = fRunList->GetSelected();
@@ -183,80 +378,7 @@ void AliOnlineReco::DoStart()
     return;
   }
 
-  if (i->second == 0)
-  {
-    pid_t pid = fork();
-    if (pid == -1)
-    {
-      perror("DoStart -- Fork failed");
-      return;
-    }
-
-    if (pid)
-    {
-      i->second = pid;
-      fRunList->RemoveEntry(run);
-      fRunList->AddEntrySort(TString::Format("%-20d -- RUNNING", run), run);
-      fRunList->Layout();
-    }
-    else
-    {
-      int s;
-      if (fTestMode)
-      {
-       s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0);
-      }
-      else
-      {
-       Int_t procPID = gSystem->GetPid();
-       TString logFile = Form("%s/reco/log/run%d_%d.log",
-                              gSystem->Getenv("ONLINERECO_BASE_DIR"),
-                              run,
-                              (Int_t)procPID);
-       Info("DoStart","Reconstruction log will be written to %s",logFile.Data());
-       gSystem->RedirectOutput(logFile.Data());
-
-       gSystem->cd(Form("%s/reco",gSystem->Getenv("ONLINERECO_BASE_DIR")));
-
-       TString gdcs;
-       if ((RetrieveGRP(run,gdcs) <= 0) ||
-           gdcs.IsNull()) 
-         gSystem->Exit(1);
-
-       gSystem->Setenv("DATE_RUN_NUMBER",Form("%d",run));
-       // Setting CDB
-//     AliCDBManager * man = AliCDBManager::Instance();
-//     man->SetDefaultStorage("local:///local/cdb");
-//     man->SetSpecificStorage("GRP/GRP/Data",
-//                           Form("local://%s",gSystem->pwd()));
-//     man->SetSpecificStorage("GRP/CTP/Config",
-//                           Form("local://%s",gSystem->pwd()));
-//     man->SetSpecificStorage("ACORDE/Align/Data",
-//                             "local://$ALICE_ROOT/OCDB");
-
-       gSystem->mkdir(Form("run%d_%d",run,(Int_t)procPID));
-       gSystem->cd(Form("run%d_%d",run,(Int_t)procPID));
-
-       const char *recMacroPath = "$ALICE_ROOT/test/cosmic/rec.C";
-
-       s = execlp("alieve",
-                  "alieve",
-                  "-q",
-                  Form("%s(\"mem://@*:\")",gSystem->ExpandPathName(recMacroPath)),
-                  (char*) 0);
-      }
-
-      if (s == -1)
-      {
-       perror("execlp failed - this will not end well");
-       gSystem->Exit(1);
-      }
-    }
-  }
-  else
-  {
-    Error("DoStart", "Process already running.");
-  }
+  StartAliEve(i);
 }
 
 void AliOnlineReco::DoStop()
@@ -273,15 +395,7 @@ void AliOnlineReco::DoStop()
   Int_t pid = i->second;
   if (pid)
   {
-    if (fTestMode)
-    {
-      kill(pid, SIGTERM);
-    }
-    else
-    {
-      // alieve will auto-destruct on SIGUSR1
-      kill(pid, SIGUSR1);
-    }
+    KillPid(pid);
   }
   else
   {
@@ -289,7 +403,7 @@ void AliOnlineReco::DoStop()
   }
 }
 
-void AliOnlineReco::DoXyzz()
+void AliOnlineReco::DoExit()
 {
   gSystem->ExitLoop();
 }
index bcbb2e5..221bbc1 100644 (file)
 
 class AliDimIntNotifier;
 
+class TTimer;
+
 class TGTextButton;
+class TGCheckButton;
 class TGListBox;
 
 //______________________________________________________________________________
@@ -30,11 +33,16 @@ class AliOnlineReco : public TGMainFrame
 {
 public:
   AliOnlineReco();
-  virtual ~AliOnlineReco() {}
+  virtual ~AliOnlineReco();
 
   AliDimIntNotifier* GetSOR(Int_t i) const { return fSOR[i]; }
   AliDimIntNotifier* GetEOR(Int_t i) const { return fEOR[i]; }
 
+  Int_t  GetLastRun() const;
+
+  Bool_t GetAutoRunMode() const;
+  void   SetAutoRunMode(Bool_t ar);
+
   void SetTestMode() { fTestMode = kTRUE; }
 
   //------------------------------------------------------------------------------
@@ -54,9 +62,10 @@ public:
   // Handlers of button signals.
   //------------------------------------------------------------------------------
 
+  void DoAutoRun();
   void DoStart();
   void DoStop();
-  void DoXyzz();
+  void DoExit();
 
   virtual void CloseWindow();
 
@@ -68,14 +77,20 @@ private:
 
   // GUI components.
   TGListBox     *fRunList;
+  TGCheckButton *fAutoRun;
   TGTextButton  *fStartButt;
   TGTextButton  *fStopButt;
-  TGTextButton  *fXyzzButt;
+  TGTextButton  *fExitButt;
 
-  // DIM interface. Could do without ...
+  // DIM interface. Could do without members and just leak them ...
   AliDimIntNotifier *fSOR[5];
   AliDimIntNotifier *fEOR[5];
 
+  // AutoRun state and timer
+  TTimer        *fAutoRunTimer;
+  Int_t          fAutoRunScheduled;
+  Int_t          fAutoRunRunning;
+
   // Run-state, process mngmnt
   typedef std::map<Int_t, Int_t> mIntInt_t; // value should be struct { pid, state, ... };
   typedef mIntInt_t::iterator    mIntInt_i;
@@ -86,6 +101,16 @@ private:
 
   mIntInt_i FindMapEntryByPid(Int_t pid);
 
+  void StartAliEve(mIntInt_i& mi);
+  void KillPid(Int_t pid);
+
+  void StartAutoRunTimer(Int_t run);
+  void StopAutoRunTimer();
+
+  // Things that should be private but have to be public for CINT.
+public:
+  void AutoRunTimerTimeout();
+
   ClassDef(AliOnlineReco, 0);
 };
 
index 47277a3..22452bf 100644 (file)
@@ -20,6 +20,12 @@ int main(int argc, char **argv)
   AliOnlineReco *win = new AliOnlineReco;
   win->MapWindow();
 
+  TString autoRun(gSystem->Getenv("ONLINERECO_AUTORUN"));
+  if (autoRun == "1" || autoRun.CompareTo("true", TString::kIgnoreCase) == 0)
+  {
+    win->SetAutoRunMode(kTRUE);
+  }
+
   if (test)
   {
     win->SetTestMode();
@@ -31,10 +37,11 @@ int main(int argc, char **argv)
 
     printf("win = (AliOnlineReco*) 0x%lx\n", (unsigned long)win);
   }
-  else {
-
+  else
+  {
     TString baseDir = gSystem->Getenv("ONLINERECO_BASE_DIR");
-    if (baseDir.IsNull()) {
+    if (baseDir.IsNull())
+    {
       printf("ERROR: ONLINERECO_BASE_DIR is not set. Exiting...");
       return 0;
     }
@@ -55,15 +62,19 @@ int main(int argc, char **argv)
     sqlQuery.Form("SELECT run FROM logbook WHERE DAQ_time_start > %u AND DAQ_time_end IS NULL AND partition REGEXP 'PHYSICS.*'",
                  ts.GetSec()-86400);
     TSQLResult* result = server->Query(sqlQuery);
-    if (!result) {
+    if (!result)
+    {
       printf("ERROR: Can't execute query <%s>!", sqlQuery.Data());
       return 0;
     }
-    if (result->GetRowCount() == 0) {
+    if (result->GetRowCount() == 0)
+    {
       printf("No active physics runs found");
     }
-    else {
-      for (Int_t iRow = 0; iRow < result->GetRowCount(); iRow++) {
+    else
+    {
+      for (Int_t iRow = 0; iRow < result->GetRowCount(); iRow++)
+      {
        TSQLRow* row = result->Next();
        TString runStr = row->GetField(0);
        if (runStr.IsDigit())