From 0f8669d34e01c9530d90abf0cdfa3cd567ec68ee Mon Sep 17 00:00:00 2001
From: Default Online user <Markus.Frank@cern.ch>
Date: Tue, 16 Nov 2021 12:35:32 +0100
Subject: [PATCH 1/3] Fix nightly build warnings

---
 Online/GauchoAppl/src/components/BusySvc.cpp | 268 +++++++++----------
 Online/GauchoAppl/src/components/BusySvc.h   |  69 ++---
 Online/GauchoAppl/src/components/PubSvc.cpp  |   1 +
 Online/OnlineAlign/CMakeLists.txt            |   2 +-
 4 files changed, 169 insertions(+), 171 deletions(-)

diff --git a/Online/GauchoAppl/src/components/BusySvc.cpp b/Online/GauchoAppl/src/components/BusySvc.cpp
index cce57009e..c8f5d8b6b 100644
--- a/Online/GauchoAppl/src/components/BusySvc.cpp
+++ b/Online/GauchoAppl/src/components/BusySvc.cpp
@@ -15,6 +15,7 @@
 #include <Gaucho/GenTimer.h>
 #include <RTL/strdef.h>
 
+using namespace Online;
 DECLARE_COMPONENT( BusySvc )
 
 namespace {
@@ -33,7 +34,7 @@ namespace {
   }
 }
 
-class BusySvc::IdleTimer : public Online::GenTimer   {
+class BusySvc::IdleTimer : public GenTimer   {
 public:
   BusySvc *m_bsysvc;
   IdleTimer(BusySvc *master, int period = 5000) : GenTimer(period), m_bsysvc(master)  {
@@ -44,6 +45,13 @@ public:
   }
 };
 
+BusySvc::BusySvc(const std::string& nam, ISvcLocator* sl) : Service(nam,sl)  {
+  declareProperty("BogusMips",          m_bogus = 0.0);
+  declareProperty("ExtendedMonitoring", m_extendedMonitoring = false);
+  ::memset(m_times_old, 0, sizeof(m_times_old));
+  m_first = true;
+}
+
 StatusCode BusySvc::initialize()   {
   StatusCode sc = Service::initialize();
   if( !sc.isSuccess() )  {
@@ -54,39 +62,41 @@ StatusCode BusySvc::initialize()   {
     return StatusCode::FAILURE;
   }
   if (m_bogus == 0.0)  {
-    getBogus(m_Mybogus);
+    m_mybogus = this->getBogus();
   }
-  m_NodeName = RTL::str_upper(RTL::nodeNameShort());
-  NodeClass(m_NodeClass);
-  m_NodeClass = "PLUS";
-  m_bogus = m_Mybogus;
-  m_numCores = m_NumCores;
+  auto node_name = RTL::str_upper(RTL::nodeNameShort());
+  auto node_class = this->nodeClass(node_name);
+  node_class = "PLUS";
+  m_bogus     = m_mybogus;
+  m_numCores  = m_numCores;
   calcIdle();
   m_timer = std::make_unique<IdleTimer>(this);
-  m_monitorSvc->declareInfo(m_NodeName+"/NodeBusy",m_BusyFraction,"",this);
-//  m_monitorSvc->declareInfo("IdleFraction",m_idlebogus,"",this);
-//  m_monitorSvc->declareInfo("BogoMIPS",m_bogus,"",this);
-//  m_monitorSvc->declareInfo("BusyFraction",m_busybogus,"",this);
-//  m_monitorSvc->declareInfo("NumCores",m_numCores,"",this);
-//
-//  m_monitorSvc->declareInfo("TotMemory",m_Memtot,"",this);
-//  m_monitorSvc->declareInfo("FreeMemory",m_Memfree,"",this);
-//  m_monitorSvc->declareInfo("MemBuffers",m_Membuff,"",this);
-//  m_monitorSvc->declareInfo("SwapSpaceTot",m_MemSwaptot,"",this);
-//  m_monitorSvc->declareInfo("SwapSpaceFree",m_MemSwapfree,"",this);
-//  m_monitorSvc->declareInfo("MemAvail",m_MemAvail,"",this);
-//
-//  m_monitorSvc->declareInfo(m_NodeClass+"/IdleFraction",m_idlebogus,"",this);
-//  m_monitorSvc->declareInfo(m_NodeClass+"/BogoMIPS",m_bogus,"",this);
-//  m_monitorSvc->declareInfo(m_NodeClass+"/BusyFraction",m_busybogus,"",this);
-//  m_monitorSvc->declareInfo(m_NodeClass+"/NumCores",m_numCores,"",this);
-//
-//  m_monitorSvc->declareInfo(m_NodeClass+"/TotMemory",m_Memtot,"",this);
-//  m_monitorSvc->declareInfo(m_NodeClass+"/FreeMemory",m_Memfree,"",this);
-//  m_monitorSvc->declareInfo(m_NodeClass+"/MemBuffers",m_Membuff,"",this);
-//  m_monitorSvc->declareInfo(m_NodeClass+"/SwapSpaceTot",m_MemSwaptot,"",this);
-//  m_monitorSvc->declareInfo(m_NodeClass+"/SwapSpaceFree",m_MemSwapfree,"",this);
-//  m_monitorSvc->declareInfo(m_NodeClass+"/MemAvail",m_MemAvail,"",this);
+  m_monitorSvc->declareInfo(node_name+"/NodeBusy",m_busyFraction,"",this);
+  if ( m_extendedMonitoring )   {
+    m_monitorSvc->declareInfo("IdleFraction",m_idlebogus,"",this);
+    m_monitorSvc->declareInfo("BogoMIPS",m_bogus,"",this);
+    m_monitorSvc->declareInfo("busyFraction",m_busybogus,"",this);
+    m_monitorSvc->declareInfo("NumCores",m_numCores,"",this);
+  
+    m_monitorSvc->declareInfo("TotMemory",m_memtot,"",this);
+    m_monitorSvc->declareInfo("FreeMemory",m_memfree,"",this);
+    m_monitorSvc->declareInfo("MemBuffers",m_membuff,"",this);
+    m_monitorSvc->declareInfo("SwapSpaceTot",m_memSwaptot,"",this);
+    m_monitorSvc->declareInfo("SwapSpaceFree",m_memSwapfree,"",this);
+    m_monitorSvc->declareInfo("MemAvail",m_memAvail,"",this);
+  
+    m_monitorSvc->declareInfo(node_class+"/IdleFraction",m_idlebogus,"",this);
+    m_monitorSvc->declareInfo(node_class+"/BogoMIPS",m_bogus,"",this);
+    m_monitorSvc->declareInfo(node_class+"/busyFraction",m_busybogus,"",this);
+    m_monitorSvc->declareInfo(node_class+"/NumCores",m_numCores,"",this);
+  
+    m_monitorSvc->declareInfo(node_class+"/TotMemory",m_memtot,"",this);
+    m_monitorSvc->declareInfo(node_class+"/FreeMemory",m_memfree,"",this);
+    m_monitorSvc->declareInfo(node_class+"/MemBuffers",m_membuff,"",this);
+    m_monitorSvc->declareInfo(node_class+"/SwapSpaceTot",m_memSwaptot,"",this);
+    m_monitorSvc->declareInfo(node_class+"/SwapSpaceFree",m_memSwapfree,"",this);
+    m_monitorSvc->declareInfo(node_class+"/MemAvail",m_memAvail,"",this);
+  }
   return StatusCode::SUCCESS;
 }
 
@@ -98,84 +108,64 @@ StatusCode BusySvc::finalize()  {
 
 StatusCode BusySvc::start()  {
   StatusCode sc = this->Service::start();
-  this->m_bogus = m_Mybogus;
-  this->m_timer->start();
-  return StatusCode::SUCCESS;
+  if ( sc.isSuccess() )   {
+    this->m_bogus = m_mybogus;
+    this->m_timer->start();
+  }
+  return sc;
 }
 
-void BusySvc::NodeClass(std::string &c)   {
-  FILE *f=fopen("/group/online/ecs/FarmNodes.txt","r");
-  c = "";
-  if ( f == 0 )  {
-    return;
-  }
-  char line[256];
-  char *stat = line;
-  while (stat != 0)  {
-    stat = fgets(line,sizeof(line),f);
-    if (stat == 0) break;
-    auto l = RTL::str_split(line," ");
-    if (l.at(0) == m_NodeName)    {
-      c = l.at(1);
-      break;
+std::string BusySvc::nodeClass(const std::string& node_name)  const  {
+  FILE *f = std::fopen("/group/online/ecs/FarmNodes.txt","r");
+  std::string c = "";
+  if ( f != nullptr )  {
+    char  line[256];
+    char *stat = line;
+    while (stat != 0)  {
+      stat = std::fgets(line,sizeof(line),f);
+      if ( stat )   {
+	auto l = RTL::str_split(line," ");
+	if ( l.at(0) == node_name)    {
+	  c = l.at(1);
+	  break;
+	}
+      }
     }
+    fclose(f);
   }
-  fclose(f);
-  return;
+  return c;
 }
 
-BusySvc::BusySvc(const std::string& name, ISvcLocator* sl) : Service(name,sl)  {
-  m_idlebogus=0.0;
-  m_busybogus=0.0;
-  m_bogus=0.0;
-  m_Mybogus=0.0;
-  m_NumCores = 0;
-  m_numCores = 0;
-  m_timer = 0;
-  m_Memtot = 0;
-  m_Memfree = 0;
-  m_Membuff = 0;
-  m_MemSwaptot = 0;
-  m_MemSwapfree = 0;
-  m_MemAvail = 0;
-  declareProperty("BogusMips",          m_bogus       = 0.0);
-  m_first = true;
-}
-
-void BusySvc::getBogus(double &bogus)   {
-  char line[256];
-  char bogoline[256];
-  char modelnameline[256];
-  float bogo;
-  int model;
-  int proc = 0;
-  bogus = 0;
-  FILE *g = fopen("/proc/cpuinfo", "r");
+double BusySvc::getBogus()   {
+  char   line[256];
+  float  bogo  = 0e0;
+  int    model = 0;
+  int    proc  = 0;
+  double bogus = 0e0;
+  FILE *input = std::fopen("/proc/cpuinfo", "r");
   char *stat = line;
+  m_numCores = 0;
   while (stat != 0)  {
-    stat = fgets(line, sizeof(line), g);
+    stat = std::fgets(line, sizeof(line), input);
     if (stat == 0)
       break;
     if (strstr(line, "processor\t") != 0)    {
-      strcpy(modelnameline, line);
       auto l = RTL::str_split(line, ":");
-      sscanf(l.at(1).c_str(), "%d", &proc);
-      m_NumCores++;
+      std::sscanf(l.at(1).c_str(), "%d", &proc);
+      m_numCores++;
     }
     else if (strstr(line, "bogomips\t") != 0)    {
-      strcpy(bogoline, line);
       auto l = RTL::str_split(line, ":");
-      sscanf(l.at(1).c_str(), "%f", &bogo);
+      std::sscanf(l.at(1).c_str(), "%f", &bogo);
       bogus += bogo;
     }
     else if (strstr(line, "model\t") != 0)    {
-      strcpy(modelnameline, line);
       auto l = RTL::str_split(line, ":");
-      sscanf(l.at(1).c_str(), "%d", &model);
+      std::sscanf(l.at(1).c_str(), "%d", &model);
     }
   }
-  fclose(g);
-  ::lib_rtl_output(LIB_RTL_INFO,"Number of Cores: %d.\n",m_NumCores);
+  std::fclose(input);
+  ::lib_rtl_output(LIB_RTL_INFO,"Number of Cores: %d.\n",m_numCores);
 //  if (model == 23)
 //  {
 //    bogus = 270.0;
@@ -190,62 +180,64 @@ void BusySvc::getBogus(double &bogus)   {
 //  }
 //  bogus = bogo;
   //  printf ("Bogomips %f %f\n",bogo,bogus);
-  return;
+  return bogus;
 }
-void BusySvc::calcIdle()
-{
-  char line[256];
-  long dtimes[7],times[7];
-  double p_id=0.0;
-  FILE *f = fopen("/proc/stat","r");
-  char *stat = line;
-  while (stat != 0)  {
-    stat = fgets(line,sizeof(line),f);
-    if (stat == 0) break;
-    if (strstr(line,"cpu ")!=0)    {
-      auto l = RTL::str_split(line," ");
-      long t=0;
-      for (int i=1;i<=7;i++)   {
-        sscanf(l.at(i).c_str(), "%ld",&times[i-1]);
-      }
-      if (!m_first)    {
-        for (int i=0;i<7;i++)    {
-          dtimes[i] = times[i]-m_times_old[i];
-          t +=dtimes[i];
-        }
-        p_id = double(dtimes[3])/t;
+
+void BusySvc::calcIdle()   {
+  char   line[256];
+  double p_id = 0.0;
+  long   dtimes[7], times[7];
+  FILE  *input = std::fopen("/proc/stat","r");
+  char  *stat = line;
+  while ( stat != 0 )  {
+    stat = std::fgets(line,sizeof(line),input);
+    if ( stat != 0 )   {
+      if ( std::strstr(line,"cpu ") != 0 )    {
+	auto l = RTL::str_split(line," ");
+	long t = 0;
+	for (int i=1;i<=7;i++)   {
+	  std::sscanf(l.at(i).c_str(), "%ld",&times[i-1]);
+	}
+	if (!m_first)    {
+	  for (int i=0;i<7;i++)    {
+	    dtimes[i] = times[i]-m_times_old[i];
+	    t += dtimes[i];
+	  }
+	  p_id = double(dtimes[3])/t;
+	}
+	::memcpy(m_times_old, times, sizeof(m_times_old));
+	m_first = false;
+	break;
       }
-      memcpy(m_times_old,times,sizeof(times));
-      m_first = false;
-      break;
     }
   }
-  m_bogus = m_Mybogus;
-  m_idlebogus = p_id*m_bogus;
-  m_BusyFraction = (1.0-p_id);
-  m_busybogus = (1.0-p_id)*m_bogus;
-  m_numCores = m_NumCores;
-  fclose(f);
+  std::fclose(input);
+  m_bogus        = m_mybogus;
+  m_idlebogus    = p_id*m_bogus;
+  m_busyFraction = (1.0-p_id);
+  m_busybogus    = (1.0-p_id)*m_bogus;
 
-  f = fopen("/proc/meminfo","r");
+  input = std::fopen("/proc/meminfo","r");
   stat = line;
   while (stat != 0)  {
-    stat = fgets(line, sizeof(line), f);
-    if (stat == 0) break;
-    auto toks = RTL::str_split(line," ");
-    const auto& tok = toks.at(0);
-    if (tok.find("MemTotal") != std::string::npos)
-      m_Memtot = mem_in_bytes(toks);
-    if (toks.at(0).find("MemFree") != std::string::npos)
-      m_Memfree = mem_in_bytes(toks);
-    else if (toks.at(0).find("Buffers") != std::string::npos)
-      m_Membuff = mem_in_bytes(toks);
-    else if (tok.find("SwapTotal") != std::string::npos)
-      m_MemSwaptot = mem_in_bytes(toks);
-    else if (tok.find("SwapFree") != std::string::npos)
-      m_MemSwapfree = mem_in_bytes(toks);
-    else if (tok.find("MemAvailable") != std::string::npos)
-      m_MemAvail = mem_in_bytes(toks);
+    stat = std::fgets(line, sizeof(line), input);
+    if ( stat != 0 )    {
+      auto toks = RTL::str_split(line," ");
+      const auto& tok = toks.at(0);
+
+      if ( tok.find("MemTotal") != std::string::npos )
+	m_memtot = mem_in_bytes(toks);
+      else if ( tok.find("MemFree") != std::string::npos )
+	m_memfree = mem_in_bytes(toks);
+      else if ( tok.find("Buffers") != std::string::npos )
+	m_membuff = mem_in_bytes(toks);
+      else if ( tok.find("SwapTotal") != std::string::npos )
+	m_memSwaptot = mem_in_bytes(toks);
+      else if ( tok.find("SwapFree") != std::string::npos )
+	m_memSwapfree = mem_in_bytes(toks);
+      else if ( tok.find("MemAvailable") != std::string::npos )
+	m_memAvail = mem_in_bytes(toks);
+    }
   }
-  fclose(f);
+  std::fclose(input);
 }
diff --git a/Online/GauchoAppl/src/components/BusySvc.h b/Online/GauchoAppl/src/components/BusySvc.h
index 2bc139da4..7cbb79c05 100644
--- a/Online/GauchoAppl/src/components/BusySvc.h
+++ b/Online/GauchoAppl/src/components/BusySvc.h
@@ -15,38 +15,43 @@
 #include <GaudiKernel/Service.h>
 class IMonitorSvc;
 
-class BusySvc : public Service    {
-private:
-  class IdleTimer;
+/// Online namespace declaration
+namespace Online   {
+  class BusySvc : public Service    {
+  private:
+    class IdleTimer;
 
-  std::string  m_NodeClass;
-  std::string  m_NodeName;
-  long         m_times_old[7];
-  double       m_idlebogus;
-  double       m_busybogus;
-  double       m_bogus;
-  double       m_Mybogus;
-  double       m_BusyFraction;
-  long         m_Memtot;
-  long         m_Memfree;
-  long         m_Membuff;
-  long         m_MemSwaptot;
-  long         m_MemSwapfree;
-  long         m_MemAvail;
-  int          m_NumCores;
-  int          m_numCores;
-  bool         m_first;
-  SmartIF<IMonitorSvc> m_monitorSvc;
-  std::unique_ptr<IdleTimer> m_timer;
+    SmartIF<IMonitorSvc>       m_monitorSvc;
+    std::unique_ptr<IdleTimer> m_timer;
 
-  void calcIdle();
-  void getBogus(double &bogus);
-  void NodeClass(std::string &);
- public:
-  BusySvc(const std::string& name, ISvcLocator* sl);
-  virtual ~BusySvc() = default;
-  StatusCode start()       override;
-  StatusCode initialize()  override;
-  StatusCode finalize()    override;
-};
+    double       m_bogus         { 0e0 };
+    bool         m_extendedMonitoring { false };
+
+    long         m_times_old[7];
+
+    /// Monitoring quantities
+    double       m_idlebogus     { 0e0 };
+    double       m_busybogus     { 0e0 };
+    double       m_mybogus       { 0e0 };
+    double       m_busyFraction  { 0e0 };
+    long         m_memtot        { 0 };
+    long         m_memfree       { 0 };
+    long         m_membuff       { 0 };
+    long         m_memSwaptot    { 0 };
+    long         m_memSwapfree   { 0 };
+    long         m_memAvail      { 0 };
+    int          m_numCores      { 0 };
+    bool         m_first         { true };
+
+    void calcIdle();
+    double getBogus();
+    std::string nodeClass(const std::string& node_name)   const;
+  public:
+    BusySvc(const std::string& name, ISvcLocator* sl);
+    virtual ~BusySvc() = default;
+    virtual StatusCode start()       override;
+    virtual StatusCode initialize()  override;
+    virtual StatusCode finalize()    override;
+  };
+}
 #endif // ONLINE_GAUCHO_BUSYSVC_H
diff --git a/Online/GauchoAppl/src/components/PubSvc.cpp b/Online/GauchoAppl/src/components/PubSvc.cpp
index 36256598b..2cb85535a 100644
--- a/Online/GauchoAppl/src/components/PubSvc.cpp
+++ b/Online/GauchoAppl/src/components/PubSvc.cpp
@@ -108,6 +108,7 @@ StatusCode PubSvc::start()
   m_prevupdate = 0;
   StatusCode sc = Service::start();
   if ( !sc.isSuccess() )    {
+    return sc;
   }
   if ( !m_errh )   {
     m_errh = new MyErrh(this->name());
diff --git a/Online/OnlineAlign/CMakeLists.txt b/Online/OnlineAlign/CMakeLists.txt
index aeaa7bba5..3ab1884a2 100644
--- a/Online/OnlineAlign/CMakeLists.txt
+++ b/Online/OnlineAlign/CMakeLists.txt
@@ -13,7 +13,7 @@
 #===============================================================================
 gaudi_subdir(OnlineAlign v0r10)
 
-gaudi_depends_on_subdirs(Online/GaudiKernel
+gaudi_depends_on_subdirs(GaudiKernel
                          Online/Gaucho)
 
 find_package(ROOT COMPONENTS Minuit)
-- 
GitLab


From ea7c5cc361b32b753e8fc07a7def0b65b6535657 Mon Sep 17 00:00:00 2001
From: Default Online user <Markus.Frank@cern.ch>
Date: Tue, 16 Nov 2021 12:41:55 +0100
Subject: [PATCH 2/3] Fix nightly build warnings

---
 Online/GauchoBase/src/HistSaver.cpp |  2 +-
 Online/OnlineAlign/src/AlignDrv.cpp | 45 ++++++++++++++---------------
 2 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/Online/GauchoBase/src/HistSaver.cpp b/Online/GauchoBase/src/HistSaver.cpp
index 0514902a2..49e722fec 100644
--- a/Online/GauchoBase/src/HistSaver.cpp
+++ b/Online/GauchoBase/src/HistSaver.cpp
@@ -155,7 +155,7 @@ void HistSaver::i_makeDirs(int runno)   {
   std::stringstream str;
   str << dir << "/" << this->taskname << "-" << runno << "-" 
       << timestr << (this->EOR ? "-EOR.root" : ".root");
-  this->currFileName = std::move(str.str());
+  this->currFileName = str.str();
 }
 
 std::unique_ptr<TFile> HistSaver::openFile()  {
diff --git a/Online/OnlineAlign/src/AlignDrv.cpp b/Online/OnlineAlign/src/AlignDrv.cpp
index 9b9342c3f..1c1b52417 100644
--- a/Online/OnlineAlign/src/AlignDrv.cpp
+++ b/Online/OnlineAlign/src/AlignDrv.cpp
@@ -81,30 +81,29 @@ StatusCode AlignDrv::stop()   {
 
 StatusCode AlignDrv::initialize()  {
   StatusCode sc = Service::initialize().ignore();
-  if ( !sc.isSuccess() )   {
-    return sc;
-  }
-  m_monitoringSvc = service("MonitorSvc", true);
-  if ( m_monitoringSvc.get() )  {
-    error() << "Cannot access monitoring service of type MonitorSvc." << endmsg;
-    return StatusCode::FAILURE;
-  }
-  m_toolSvc = service("ToolSvc", true);
-  sc = m_toolSvc->retrieveTool(m_FitterClass,m_FitterName,m_fitter.pRef(),this,true);
-  if ( !sc.isSuccess() )  {
-    error() << "Failed to retriev Fitter Tool: " << m_FitterName << " of Class " << m_FitterClass << endmsg;
-    return StatusCode::FAILURE;
-  }
-  m_incidentSvc = service("IncidentSvc", true);
-  if ( m_incidentSvc.get() )  {
-    error() << "Cannot access incident service of type IncidentSvc." << endmsg;
-    return StatusCode::FAILURE;
-  }
-  m_incidentSvc->addListener(this,"DAQ_PAUSE");
-  if (m_RefFileName.empty()) {
-     m_RefFileName = "/group/online/dataflow/options/"+m_PartitionName+"/Alignment_Reference_File.txt";
+  if ( sc.isSuccess() )   {
+    m_monitoringSvc = service("MonitorSvc", true);
+    if ( m_monitoringSvc.get() )  {
+      error() << "Cannot access monitoring service of type MonitorSvc." << endmsg;
+      return StatusCode::FAILURE;
+    }
+    m_toolSvc = service("ToolSvc", true);
+    sc = m_toolSvc->retrieveTool(m_FitterClass, m_FitterName, m_fitter.pRef(), this, true);
+    if ( !sc.isSuccess() )  {
+      error() << "Failed to retriev Fitter Tool: " << m_FitterName << " of Class " << m_FitterClass << endmsg;
+      return StatusCode::FAILURE;
+    }
+    m_incidentSvc = service("IncidentSvc", true);
+    if ( m_incidentSvc.get() )  {
+      error() << "Cannot access incident service of type IncidentSvc." << endmsg;
+      return StatusCode::FAILURE;
+    }
+    m_incidentSvc->addListener(this, "DAQ_PAUSE");
+    if (m_RefFileName.empty()) {
+      m_RefFileName = "/group/online/dataflow/options/"+m_PartitionName+"/Alignment_Reference_File.txt";
+    }
   }
-  return StatusCode::SUCCESS;
+  return sc;
 }
 
 StatusCode AlignDrv::finalize()  {
-- 
GitLab


From 7ec20bb996404784560c9a5c828e52ecdf08241a Mon Sep 17 00:00:00 2001
From: Default Online user <Markus.Frank@cern.ch>
Date: Tue, 16 Nov 2021 14:21:25 +0100
Subject: [PATCH 3/3] On data from PCIE40, if ODIN is missing, take last known
 'good' run number for building the event header

---
 Online/EventData/EventData/EventTraits.h     |  4 +-
 Online/EventData/src/EventAccess.cpp         |  3 +-
 Online/EventData/src/EventHandler.cpp        | 47 ++++++++++++++------
 Online/EventData/src/MBMEventAccess.cpp      |  2 +-
 Online/PCIE40Data/PCIE40Data/pcie40.h        | 14 ++++--
 Online/PCIE40Data/PCIE40Data/pcie40decoder.h |  5 +++
 Online/PCIE40Data/src/pcie40decoder.cpp      | 23 ++++++++--
 7 files changed, 75 insertions(+), 23 deletions(-)

diff --git a/Online/EventData/EventData/EventTraits.h b/Online/EventData/EventData/EventTraits.h
index 2cd1785dc..0b96a037a 100644
--- a/Online/EventData/EventData/EventTraits.h
+++ b/Online/EventData/EventData/EventTraits.h
@@ -78,7 +78,6 @@ namespace Online   {
       typedef EventHeader     event_type;
       typedef record_t        record_type;
       static constexpr int data_type = TELL1_DATA_TYPE;
-
       struct bank_iteration_t  {
 	const bank_type* _first;
 	const bank_type* _last;
@@ -114,6 +113,9 @@ namespace Online   {
 	{  return pcie40::add_ptr<bank_type>(prev, sizeof(bank_type)); }
       };
     };
+    inline bool is_tell1_type(int typ)   {  return typ == tell1::data_type;   }
+    inline bool is_tell40_type(int typ)  {  return typ == tell40::data_type;  }
+
   }      // End namespace event_traits
 }        // End namespace Online
 #endif   // ONLINE_EVENTDATA_EVENTTRAITS_H
diff --git a/Online/EventData/src/EventAccess.cpp b/Online/EventData/src/EventAccess.cpp
index 47dc6256a..f9e86d496 100644
--- a/Online/EventData/src/EventAccess.cpp
+++ b/Online/EventData/src/EventAccess.cpp
@@ -178,6 +178,7 @@ size_t EventAccess::numQueuedBurst()   {
 /// Clear burst queue and update counters
 size_t EventAccess::clear()   {
   size_t count = 0;
+  pcie40::decoder_t::reset_last_good_run_number();
   for(shared_guard_t burst=dequeueBurst(); burst.get(); burst=dequeueBurst())  {
     lock_t lock(m_eventLock);
     monitor.eventsBuffered -= burst->num_bx();
@@ -343,7 +344,7 @@ EventAccess::convertPCIE40MEP(datapointer_t start, size_t len)    {
   } printer(*m_logger);
   pair<long, unique_ptr<pcie40::event_collection_t> > events;
   pcie40::decoder_t::logger_t logger = printer;
-  pcie40::decoder_t                           decoder(logger);
+  pcie40::decoder_t           decoder(logger);
   datapointer_t end = start + len;
   
   if ( end > start )   {
diff --git a/Online/EventData/src/EventHandler.cpp b/Online/EventData/src/EventHandler.cpp
index f07303109..385491c66 100644
--- a/Online/EventData/src/EventHandler.cpp
+++ b/Online/EventData/src/EventHandler.cpp
@@ -95,6 +95,21 @@ namespace {
     sub_hdr->setTriggerMask(m);
   }
   
+
+  std::unique_ptr<unsigned char []> _make_tmp_odin_pcie40()   {
+    std::size_t len = sizeof(Tell1Bank)+sizeof(pcie40::sodin_t)+sizeof(uint32_t); // 32 bit padding
+    std::unique_ptr<unsigned char[]> tmp(new unsigned char[len]);
+    ::memset(tmp.get(), 0, len);
+    Tell1Bank* b = (Tell1Bank*)tmp.get();
+    b->setMagic();
+    b->setVersion(0);
+    b->setSourceID(0);
+    b->setType(Tell1Bank::ODIN);
+    b->setSize(sizeof(pcie40::sodin_t));
+    b->begin<pcie40::sodin_t>()->_run_number = pcie40::decoder_t::last_good_run_number();
+    return tmp;
+  }
+
   size_t _event_length(const EventHandler::evt_data_t& event)
   {
     size_t len = 0;
@@ -483,7 +498,7 @@ namespace Online  {
   template <typename traits>
   size_t EventHandler::output_mdf(const evt_data_t& event,
 				  mask_t&           routing_mask,
-				  bool              requireODIN,
+				  bool              /* requireODIN */,
 				  EventOutput&      output)  const
   {
     typedef typename traits::bank_type bank_type;
@@ -509,11 +524,15 @@ namespace Online  {
       data_len += bank->totalSize();
     }
 
-    if ( !odin.first && requireODIN )    {
-      m_logger->except("Failed to access the ODIN bank! Event output failed.");      
-      ::lib_rtl_sleep(2000);
+    /// Create temorary odin bank for event header if not present.
+    /// Worst case: run number is 1234 (default from pcie40 decoder)
+    std::unique_ptr<unsigned char []> temp_odin_buffer;
+    if ( !odin.first )  {
+      temp_odin_buffer = _make_tmp_odin_pcie40();
+      Tell1Bank* b = (Tell1Bank*)temp_odin_buffer.get();
+      odin = std::make_pair(b, b->data());
     }
-    
+
     unsigned int m[] = { ~0x0U, ~0x0U, ~0x0U, ~0x0U };
     _update_mask(m, routing_mask);
     if ( hlt_mask )    {
@@ -534,7 +553,8 @@ namespace Online  {
     }
     EventHeader* ev_hdr = tr->get<EventHeader>();
     _setEventHeader(ev_hdr, data_len-hdr_len, odin, m);
-    if ( !odin.first && evthdr )   {
+    /// Patch event header if no odin bank, but original header....
+    if ( temp_odin_buffer.get() && evthdr )   {
       auto* h = ev_hdr->subHeader().H1;
       const auto* dh = evthdr->subHeader().H1;
       h->setRunNumber(dh->runNumber());
@@ -639,15 +659,14 @@ namespace Online  {
 	}
       }
     }
-#if 0
-    static unsigned int last_good_run_number = 0;
-    if ( odin.first )    {
-      if ( odin.first->magic() == RawBank40::MagicPattern )
-	last_good_run_number = CPP::_PtrItem<pcie40::sodin_t>(odin.second).data().run_number();
-      else if ( odin.first->magic() == Tell1Bank::MagicPattern )
-	last_good_run_number = CPP::_PtrItem<RunInfo>(odin.second).data().run_number();
+    /// Create temorary odin bank for event header if not present.
+    /// Worst case: run number is 1234 (default from pcie40 decoder)
+    std::unique_ptr<unsigned char []> temp_odin_buffer;
+    if ( !odin.first )  {
+      temp_odin_buffer = _make_tmp_odin_pcie40();
+      Tell1Bank* b = (Tell1Bank*)temp_odin_buffer.get();
+      odin = std::make_pair(b, b->data());
     }
-#endif
 
     auto* tr = output.getTransaction(total_len);
     if ( !tr )   {
diff --git a/Online/EventData/src/MBMEventAccess.cpp b/Online/EventData/src/MBMEventAccess.cpp
index 19f0c25a6..a43dd370b 100644
--- a/Online/EventData/src/MBMEventAccess.cpp
+++ b/Online/EventData/src/MBMEventAccess.cpp
@@ -18,7 +18,6 @@
 #include <RTL/strdef.h>
 
 /// C/C++ include files
-//#include <iomanip>
 
 using namespace std;
 using namespace Online;
@@ -275,6 +274,7 @@ int MBMEventAccess::connect(const string&         input,
   }
   config.input = input;
   m_inhibit = false;
+  this->EventAccess::clear();
   return ONLINE_OK;
 }
 
diff --git a/Online/PCIE40Data/PCIE40Data/pcie40.h b/Online/PCIE40Data/PCIE40Data/pcie40.h
index 8b82bcf8d..4bc1708b1 100644
--- a/Online/PCIE40Data/PCIE40Data/pcie40.h
+++ b/Online/PCIE40Data/PCIE40Data/pcie40.h
@@ -369,11 +369,19 @@ namespace Online {
      */
     class event_collection_t  {
     public:
-      MAGIC_WORD                /// Magic word -- if enabled
-      const mep_header_t* mep;  /// Reference to MEP header
+      MAGIC_WORD                     /// Magic word -- if enabled
+      const mep_header_t* mep;       /// Reference to MEP header
       std::size_t   length;          /// Number of events in the collection
       std::size_t   capacity;        /// Capacity of the event collection
-      event_t  events[1];       /// Array of events in the data section
+      /// Flags structure
+      union _flags  {
+	unsigned long     raw;          /// Raw flag number
+	struct _detail  {
+	  uint32_t run_number;          /// Last known "good" run number
+	  unsigned spare:        32;    /// Spare
+	} detail;
+      } flags;
+      event_t  events[1];            /// Array of events in the data section
 
       static constexpr std::size_t data_offset = DATA_OFFSET(2*sizeof(std::size_t));
 
diff --git a/Online/PCIE40Data/PCIE40Data/pcie40decoder.h b/Online/PCIE40Data/PCIE40Data/pcie40decoder.h
index d088ea28a..e4c8e6d3b 100644
--- a/Online/PCIE40Data/PCIE40Data/pcie40decoder.h
+++ b/Online/PCIE40Data/PCIE40Data/pcie40decoder.h
@@ -74,6 +74,11 @@ namespace Online {
       /// Default destructor
       ~decoder_t();
 
+      /// Access last known good run-rumber (if any at all, otherwise 1234)
+      static uint32_t last_good_run_number();
+      /// Reset last known good run-rumber (default: 1234)
+      static void reset_last_good_run_number();
+
       /// Initialize user data structure
       event_collection_t* initialize(std::unique_ptr<event_collection_t>& event_collection, size_t num_events)  const;
       /// Decode MEP fragment
diff --git a/Online/PCIE40Data/src/pcie40decoder.cpp b/Online/PCIE40Data/src/pcie40decoder.cpp
index c62822d54..0669a04f3 100644
--- a/Online/PCIE40Data/src/pcie40decoder.cpp
+++ b/Online/PCIE40Data/src/pcie40decoder.cpp
@@ -31,6 +31,8 @@ using namespace Online::pcie40;
 
 namespace {
 
+  static uint32_t s_last_good_run_number = 1234;
+
   void _error(const char* fmt,...)  {
     char text[1024];
     va_list args;
@@ -240,6 +242,7 @@ public:
 	  e->flags.detail.tae_central  = sodin->_tae_central;
 	  e->flags.detail.tae_window   = sodin->_tae_window;
 	  e->flags.detail.event_type   = sodin->_event_type;
+	  s_last_good_run_number       = sodin->_run_number;
 	}
 	b->setMagic();
 	b->setSize(length);
@@ -265,6 +268,7 @@ public:
     c->length = 0;
     c->mep = nullptr;
     c->capacity = num_events;
+    c->flags.detail.run_number = s_last_good_run_number;
     c->setPattern();
     for(std::size_t j=0; j<num_events; ++j)   {
       auto* e = c->at(j);
@@ -289,6 +293,7 @@ public:
   void _initialize(event_collection_writer_t* ec)    {
     ec->length = 0;
     ec->mep = nullptr;
+    ec->flags.detail.run_number = s_last_good_run_number;
     for(std::size_t j=0; j < ec->capacity; ++j)   {
       auto* e = ec->at(j);
       e->flags.raw = 0;
@@ -339,6 +344,16 @@ decoder_t::~decoder_t()   {
   implementation = nullptr;
 }
 
+/// Access last known good run-rumber
+uint32_t decoder_t::last_good_run_number()   {
+  return s_last_good_run_number;
+}
+
+/// Reset last known good run-rumber (default: 1234)
+void decoder_t::reset_last_good_run_number()   {
+  s_last_good_run_number = 1234;
+}
+
 /// Initialize user data structure
 event_collection_t* decoder_t::initialize(std::unique_ptr<event_collection_t>& c, std::size_t num_events)  const  {
   if ( !c.get() || c->capacity < num_events )  {
@@ -369,10 +384,10 @@ void decoder_t::decode(std::unique_ptr<event_collection_t>& ev_coll,
     if ( num_fragments > 0 )   {
       const multi_fragment_t *last_mfp = nullptr;
       std::size_t packing  = mep->multi_fragment(0)->packingFactor();
-      auto ec = (event_collection_writer_t*)initialize(ev_coll, packing);
-      ec->mep = mep;
+      auto ec    = (event_collection_writer_t*)initialize(ev_coll, packing);
+      ec->mep    = mep;
       ec->length = packing;
-      for(uint32_t i=0; i<num_fragments; ++i)    {
+      for( uint32_t i = 0; i < num_fragments; ++i )    {
 	const auto* mfp = mep->multi_fragment(i);
 	const auto& hdr = mfp->header;
 	uint16_t src_id = hdr.source_id;
@@ -424,9 +439,11 @@ void decoder_t::decode(std::unique_ptr<event_collection_t>& ev_coll,
 			      "+++ Got %ld fragments with inconsistent packing factor!\n",
 			      num_err_packing);
       }
+      ec->flags.detail.run_number = s_last_good_run_number;
       return;
     }
   }
   auto ec = (event_collection_writer_t*)initialize(ev_coll, 0);
+  ec->flags.detail.run_number  = s_last_good_run_number;
   ec->length = 0;
 }
-- 
GitLab