From 2bd0753d665dfb43979a8a567cc77cb66799eb93 Mon Sep 17 00:00:00 2001
From: scott snyder <sss@karma>
Date: Thu, 30 May 2019 17:34:41 +0200
Subject: [PATCH] LumiBlockComps: Migrate LB duration calculation to a
 conditions algorithm.

Implement the LB duration calculation from LuminosityTool
as a conditions algorithm.
---
 LumiBlock/LumiBlockComps/CMakeLists.txt       |   6 +
 .../python/LBDurationCondAlgDefault.py        |  29 +++++
 .../share/LBDurationCondAlg_test.ref          |  23 ++++
 .../share/LBDurationCondAlg_test.txt          |   3 +
 .../LumiBlockComps/src/LBDurationCondAlg.cxx  |  70 ++++++++++++
 .../LumiBlockComps/src/LBDurationCondAlg.h    |  55 +++++++++
 .../src/components/LumiBlockComps_entries.cxx |   2 +
 .../test/LBDurationCondAlg_test.cxx           | 105 ++++++++++++++++++
 8 files changed, 293 insertions(+)
 create mode 100644 LumiBlock/LumiBlockComps/python/LBDurationCondAlgDefault.py
 create mode 100644 LumiBlock/LumiBlockComps/share/LBDurationCondAlg_test.ref
 create mode 100644 LumiBlock/LumiBlockComps/share/LBDurationCondAlg_test.txt
 create mode 100644 LumiBlock/LumiBlockComps/src/LBDurationCondAlg.cxx
 create mode 100644 LumiBlock/LumiBlockComps/src/LBDurationCondAlg.h
 create mode 100644 LumiBlock/LumiBlockComps/test/LBDurationCondAlg_test.cxx

diff --git a/LumiBlock/LumiBlockComps/CMakeLists.txt b/LumiBlock/LumiBlockComps/CMakeLists.txt
index 9397b7a6d7e..7d7d26c9d8f 100644
--- a/LumiBlock/LumiBlockComps/CMakeLists.txt
+++ b/LumiBlock/LumiBlockComps/CMakeLists.txt
@@ -81,3 +81,9 @@ atlas_add_executable( getLumi
 # Install files from the package:
 atlas_install_python_modules( python/*.py )
 atlas_install_joboptions( share/*.py )
+atlas_install_joboptions( share/*.txt )
+
+atlas_add_test( LBDurationCondAlg_test
+   SOURCES test/LBDurationCondAlg_test.cxx
+   LINK_LIBRARIES GaudiKernel LumiBlockCompsLib )
+
diff --git a/LumiBlock/LumiBlockComps/python/LBDurationCondAlgDefault.py b/LumiBlock/LumiBlockComps/python/LBDurationCondAlgDefault.py
new file mode 100644
index 00000000000..f4536327bea
--- /dev/null
+++ b/LumiBlock/LumiBlockComps/python/LBDurationCondAlgDefault.py
@@ -0,0 +1,29 @@
+# Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+#
+# File: LumiBlockComps/python/LBDurationCondAlgDefault.py
+# Created: May 2019, sss
+# Purpose: Configure LBDurationCondAlg.
+#
+
+from AthenaCommon.AlgSequence import AthSequencer
+
+def LBDurationCondAlgDefault():
+    name = 'LBDurationCondAlg'
+    condSeq = AthSequencer ('AthCondSeq')
+
+    if hasattr (condSeq, name):
+        return getattr (condSeq, name)
+
+    from IOVDbSvc.CondDB import conddb
+    folder = "/TRIGGER/LUMI/LBLB"
+    if not conddb.folderRequested( folder ):
+        conddb.addFolder ('TRIGGER', folder,
+                          className = 'AthenaAttributeList')
+
+    from LumiBlockComps.LumiBlockCompsConf import LBDurationCondAlg
+    alg = LBDurationCondAlg (name,
+                             LBLBFolderInputKey = folder,
+                             LBDurationOutputKey = 'LBDurationCondData')
+    condSeq += alg
+
+    return alg
diff --git a/LumiBlock/LumiBlockComps/share/LBDurationCondAlg_test.ref b/LumiBlock/LumiBlockComps/share/LBDurationCondAlg_test.ref
new file mode 100644
index 00000000000..8e8489e6c24
--- /dev/null
+++ b/LumiBlock/LumiBlockComps/share/LBDurationCondAlg_test.ref
@@ -0,0 +1,23 @@
+LumiBlockComps/LBDurationCondAlg
+
+
+Initializing Gaudi ApplicationMgr using job opts ../share/LBDurationCondAlg_test.txt
+JobOptionsSvc        INFO # =======> /home/sss/nobackup/atlas/build/../tests/../share/LBDurationCondAlg_test.txt
+JobOptionsSvc        INFO # (1,1): ApplicationMgr.ExtSvc = ["StoreGateSvc/ConditionStore"]
+JobOptionsSvc        INFO # (2,1): LBDurationCondAlg.LBLBFolderInputKey = "testLBLB"
+JobOptionsSvc        INFO # (3,1): LBDurationCondAlg.LBDurationOutputKey = "LBDurationCondData"
+JobOptionsSvc        INFO Job options successfully read in from ../share/LBDurationCondAlg_test.txt
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v27r1p99)
+                                          running on karma on Fri May 17 13:28:07 2019
+====================================================================================================================================
+ApplicationMgr       INFO Application Manager Configured successfully
+ClassIDSvc           INFO  getRegistryEntries: read 2851 CLIDRegistry entries for module ALL
+EventLoopMgr      WARNING Unable to locate service "EventSelector" 
+EventLoopMgr      WARNING No events will be processed from external input.
+HistogramPersis...WARNING Histograms saving not required.
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr Ready
+test1
+ClassIDSvc           INFO  getRegistryEntries: read 372 CLIDRegistry entries for module ALL
diff --git a/LumiBlock/LumiBlockComps/share/LBDurationCondAlg_test.txt b/LumiBlock/LumiBlockComps/share/LBDurationCondAlg_test.txt
new file mode 100644
index 00000000000..e1220526523
--- /dev/null
+++ b/LumiBlock/LumiBlockComps/share/LBDurationCondAlg_test.txt
@@ -0,0 +1,3 @@
+ApplicationMgr.ExtSvc = {"StoreGateSvc/ConditionStore"};
+LBDurationCondAlg.LBLBFolderInputKey = "testLBLB";
+LBDurationCondAlg.LBDurationOutputKey = "LBDurationCondData";
diff --git a/LumiBlock/LumiBlockComps/src/LBDurationCondAlg.cxx b/LumiBlock/LumiBlockComps/src/LBDurationCondAlg.cxx
new file mode 100644
index 00000000000..567b1c116a2
--- /dev/null
+++ b/LumiBlock/LumiBlockComps/src/LBDurationCondAlg.cxx
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration.
+ */
+/**
+ * @file LumiBlockComps/src/LBDurationCondAlg.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2019
+ * @brief Produce LBDurationCondData from /TRIGGER/LUMI/LBLB.
+ */
+
+
+#include "LBDurationCondAlg.h"
+#include "CoolKernel/IObject.h"
+#include "GaudiKernel/SystemOfUnits.h"
+
+
+using Gaudi::Units::second;
+using Gaudi::Units::nanosecond;
+
+
+/**
+ * @brief Gaudi initialize method.
+ */
+StatusCode
+LBDurationCondAlg::initialize()
+{
+  ATH_CHECK( m_lblbFolderInputKey.initialize() );
+  ATH_CHECK( m_lbDurationOutputKey.initialize() );
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm execute method.
+ * @param ctx Event Context.
+ */
+StatusCode
+LBDurationCondAlg::execute (const EventContext& ctx) const
+{
+  SG::ReadCondHandle<AthenaAttributeList> lblbFolder
+    (m_lblbFolderInputKey, ctx);
+  EventIDRange range;
+  ATH_CHECK( lblbFolder.range (range) );
+
+  if ((**lblbFolder)["StartTime"].isNull()) {
+    ATH_MSG_ERROR( "StartTime is NULL in " << m_lblbFolderInputKey.key() << "!" );
+    return StatusCode::FAILURE;
+  }
+
+  if ((**lblbFolder)["EndTime"].isNull()) {
+    ATH_MSG_ERROR( "EndTime is NULL in " << m_lblbFolderInputKey.key() << "!" );
+    return StatusCode::FAILURE;
+  }
+
+  // Times in nanoseconds.
+  cool::UInt63 startTime = (**lblbFolder)["StartTime"].data<cool::UInt63>();
+  cool::UInt63 endTime = (**lblbFolder)["EndTime"].data<cool::UInt63>();
+
+  // Convert to seconds.
+  double duration = (endTime-startTime) * (nanosecond / second);
+
+  auto lbdur = std::make_unique<LBDurationCondData> (duration);
+
+  SG::WriteCondHandle<LBDurationCondData> lbDurationCondData
+    (m_lbDurationOutputKey, ctx);
+  ATH_CHECK( lbDurationCondData.record (range, std::move (lbdur)) );
+  return StatusCode::SUCCESS;
+}
+
+
diff --git a/LumiBlock/LumiBlockComps/src/LBDurationCondAlg.h b/LumiBlock/LumiBlockComps/src/LBDurationCondAlg.h
new file mode 100644
index 00000000000..aafceb640c6
--- /dev/null
+++ b/LumiBlock/LumiBlockComps/src/LBDurationCondAlg.h
@@ -0,0 +1,55 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+/*
+ * Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration.
+ */
+/**
+ * @file LumiBlockComps/src/LBDurationCondAlg.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2019
+ * @brief Produce LBDurationCondData from /TRIGGER/LUMI/LBLB.
+ */
+
+
+#ifndef LUMIBLOCKCOMPS_LBDURATIONCONDALG_H
+#define LUMIBLOCKCOMPS_LBDURATIONCONDALG_H
+
+
+#include "LumiBlockData/LBDurationCondData.h"
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "PersistentDataModel/AthenaAttributeList.h"
+#include "StoreGate/ReadCondHandleKey.h"
+#include "StoreGate/WriteCondHandleKey.h"
+
+
+/**
+ * @brief Produce LBDurationCondData from /TRIGGER/LUMI/LBLB.
+ */
+class LBDurationCondAlg
+  : public AthReentrantAlgorithm
+{
+public:
+  /// Forward base class ctor.
+  using AthReentrantAlgorithm::AthReentrantAlgorithm;
+
+
+  /// Gaudi initialize method.
+  virtual StatusCode initialize() override;
+
+
+  /// Algorithm execute method.
+  virtual StatusCode execute (const EventContext& ctx) const override;
+
+
+private:
+  /// Input COOL folder.
+  SG::ReadCondHandleKey<AthenaAttributeList> m_lblbFolderInputKey
+  { this, "LBLBFolderInputKey", "/TRIGGER/LUMI/LBLB", "" };
+
+
+  /// Output conditions object.
+  SG::WriteCondHandleKey<LBDurationCondData> m_lbDurationOutputKey
+  {this, "LBDurationOutputKey", "LBDurationCondData", "" };
+};
+
+
+#endif // not LUMIBLOCKCOMPS_LBDURATIONCONDALG_H
diff --git a/LumiBlock/LumiBlockComps/src/components/LumiBlockComps_entries.cxx b/LumiBlock/LumiBlockComps/src/components/LumiBlockComps_entries.cxx
index 780dd362d12..58b7359a3d9 100644
--- a/LumiBlock/LumiBlockComps/src/components/LumiBlockComps_entries.cxx
+++ b/LumiBlock/LumiBlockComps/src/components/LumiBlockComps_entries.cxx
@@ -9,6 +9,7 @@
 #include "LumiBlockComps/TrigLivefractionTool.h"
 #include "LumiBlockComps/LumiCalcSvc.h"
 #include "LumiBlockComps/LumiBlockTester.h"
+#include "../LBDurationCondAlg.h"
 #endif
 
 DECLARE_COMPONENT( CreateLumiBlockCollectionFromFile )
@@ -19,6 +20,7 @@ DECLARE_COMPONENT( LumiBlockMuTool )
 DECLARE_COMPONENT( LuminosityTool )
 DECLARE_COMPONENT( TrigLivefractionTool )
 DECLARE_COMPONENT( LumiCalcSvc )
+DECLARE_COMPONENT( LBDurationCondAlg )
 #endif
 DECLARE_COMPONENT( LumiBlockMetaDataTool )
 
diff --git a/LumiBlock/LumiBlockComps/test/LBDurationCondAlg_test.cxx b/LumiBlock/LumiBlockComps/test/LBDurationCondAlg_test.cxx
new file mode 100644
index 00000000000..aee2c092092
--- /dev/null
+++ b/LumiBlock/LumiBlockComps/test/LBDurationCondAlg_test.cxx
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration.
+ */
+/**
+ * @file LumiBlockComps/test/LBDurationCondAlg_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2019
+ * @brief Unit test for LBDurationCondAlg.
+ */
+
+
+#undef NDEBUG
+#include "../src/LBDurationCondAlg.h"
+#include "LumiBlockData/LBDurationCondData.h"
+#include "AthenaKernel/ExtendedEventContext.h"
+#include "PersistentDataModel/AthenaAttributeList.h"
+#include "TestTools/initGaudi.h"
+#include "CoolKernel/IObject.h"
+#include <iostream>
+#include <cassert>
+
+
+class TestRCUSvc
+  : public Athena::IRCUSvc
+{
+public:
+  virtual StatusCode remove (Athena::IRCUObject* /*obj*/) override
+  {
+    return StatusCode::SUCCESS;
+  }
+  virtual size_t getNumSlots() const override { return 1; }
+  virtual void add (Athena::IRCUObject* /*obj*/) override
+  { }
+
+  virtual unsigned long addRef() override { std::abort(); }
+  virtual unsigned long release() override { std::abort(); }
+  virtual StatusCode queryInterface(const InterfaceID &/*ti*/, void** /*pp*/) override { std::abort(); }
+};
+
+
+EventIDBase timestamp (int t)
+{
+  return EventIDBase (EventIDBase::UNDEFNUM,  // run
+                      EventIDBase::UNDEFEVT,  // event
+                      t);
+}
+
+
+void test1 (ISvcLocator* svcloc)
+{
+  std::cout << "test1\n";
+
+  EventContext ctx;
+  ctx.setExtension (Atlas::ExtendedEventContext());
+  EventIDBase eid (0, 0, 0, 0);
+  ctx.setEventID (eid);
+
+  LBDurationCondAlg alg ("LBDurationCondAlg", svcloc);
+  alg.addRef();
+  assert( alg.sysInitialize().isSuccess() );
+
+  TestRCUSvc rcu;
+  DataObjID id1 ("testLBLB");
+  auto cc1 = std::make_unique<CondCont<AthenaAttributeList> > (rcu, id1);
+  DataObjID id2 ("LBDurationCondData");
+  
+  auto attrs = std::make_unique<AthenaAttributeList>();
+  attrs->extend ("StartTime", "unsigned long long");
+  attrs->extend ("EndTime",   "unsigned long long");
+  (*attrs)["StartTime"].setValue (static_cast<cool::UInt63> (123*1e9));
+  (*attrs)["EndTime"].setValue   (static_cast<cool::UInt63> (125.5*1e9));
+
+  const EventIDRange range (timestamp (0), timestamp (100));
+  assert( cc1->insert (range, std::move(attrs), ctx).isSuccess() );
+
+  ServiceHandle<StoreGateSvc> conditionStore ("ConditionStore", "test");
+  assert( conditionStore->record (std::move (cc1), "testLBLB") );
+
+  assert( alg.execute (ctx).isSuccess() );
+
+  CondCont<LBDurationCondData>* cc2 = nullptr;
+  assert( conditionStore->retrieve (cc2, "LBDurationCondData").isSuccess() );
+  const LBDurationCondData* data = 0;
+  const EventIDRange* range2p = nullptr;
+  assert (cc2->find (eid, data, &range2p));
+  assert (range2p->start().time_stamp() == timestamp(0).time_stamp());
+  assert (range2p->stop().time_stamp() == timestamp(100).time_stamp());
+
+  assert (data->lbDuration() == 2.5);
+}
+
+
+int main()
+{
+  std::cout << "LumiBlockComps/LBDurationCondAlg_test\n";
+
+  ISvcLocator* svcloc = nullptr;
+  if (!Athena_test::initGaudi("LumiBlockComps/LBDurationCondAlg_test.txt", svcloc)) {
+    return 1;
+  }
+
+
+  test1 (svcloc);
+  return 0;
+}
-- 
GitLab