From 4d97df4133a174bd5864e4d624daedc9d0533b25 Mon Sep 17 00:00:00 2001
From: Rosen Matev <rosen.matev@cern.ch>
Date: Fri, 19 Apr 2024 03:15:34 +0200
Subject: [PATCH] TAE handling for EvtStoreSvc

---
 Kernel/LHCbAlgs/CMakeLists.txt                |  1 +
 .../LHCbAlgs/include/LHCbAlgs/CopyAnyData.h   | 32 ++++++++++
 Kernel/LHCbAlgs/src/CopyUnsignedInt.cpp       | 13 +++++
 PyConf/python/PyConf/application.py           | 58 ++++++++-----------
 4 files changed, 71 insertions(+), 33 deletions(-)
 create mode 100644 Kernel/LHCbAlgs/include/LHCbAlgs/CopyAnyData.h
 create mode 100644 Kernel/LHCbAlgs/src/CopyUnsignedInt.cpp

diff --git a/Kernel/LHCbAlgs/CMakeLists.txt b/Kernel/LHCbAlgs/CMakeLists.txt
index 95b75ab50af..b3d51c0c049 100644
--- a/Kernel/LHCbAlgs/CMakeLists.txt
+++ b/Kernel/LHCbAlgs/CMakeLists.txt
@@ -25,6 +25,7 @@ gaudi_add_module(LHCbAlgs
         src/AddressKillerAlg.cpp
         src/ApplicationVersionFilter.cpp
         src/Barrier.cpp
+        src/CopyUnsignedInt.cpp
         src/DQFilter.cpp
         src/DataCopy.cpp
         src/DataObjectVersionFilter.cpp
diff --git a/Kernel/LHCbAlgs/include/LHCbAlgs/CopyAnyData.h b/Kernel/LHCbAlgs/include/LHCbAlgs/CopyAnyData.h
new file mode 100644
index 00000000000..50aab3d9d55
--- /dev/null
+++ b/Kernel/LHCbAlgs/include/LHCbAlgs/CopyAnyData.h
@@ -0,0 +1,32 @@
+/*****************************************************************************\
+* (c) Copyright 2000-2024 CERN for the benefit of the LHCb Collaboration      *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+#include "GaudiAlg/GaudiAlgorithm.h"
+
+namespace LHCb::Algorithm {
+  template <typename T>
+  class CopyAnyData final : public GaudiAlgorithm {
+  public:
+    using GaudiAlgorithm::GaudiAlgorithm;
+    StatusCode execute() override {
+      auto* object = getIfExists<AnyDataWrapper<T>>( m_input );
+      if ( object ) {
+        T    copy      = object->getData();
+        auto newObject = std::make_unique<AnyDataWrapper<T>>( std::move( copy ) );
+        put( newObject.release(), m_output );
+      }
+      return StatusCode::SUCCESS;
+    }
+
+  private:
+    Gaudi::Property<std::string> m_input{this, "Input", ""};
+    Gaudi::Property<std::string> m_output{this, "Output", ""};
+  };
+} // namespace LHCb::Algorithm
diff --git a/Kernel/LHCbAlgs/src/CopyUnsignedInt.cpp b/Kernel/LHCbAlgs/src/CopyUnsignedInt.cpp
new file mode 100644
index 00000000000..f25190463ee
--- /dev/null
+++ b/Kernel/LHCbAlgs/src/CopyUnsignedInt.cpp
@@ -0,0 +1,13 @@
+/*****************************************************************************\
+* (c) Copyright 2000-2024 CERN for the benefit of the LHCb Collaboration      *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+#include "LHCbAlgs/CopyAnyData.h"
+
+DECLARE_COMPONENT_WITH_ID( LHCb::Algorithm::CopyAnyData<unsigned int>, "CopyUnsignedInt" )
diff --git a/PyConf/python/PyConf/application.py b/PyConf/python/PyConf/application.py
index f771c985f40..e097fe8ef17 100644
--- a/PyConf/python/PyConf/application.py
+++ b/PyConf/python/PyConf/application.py
@@ -166,30 +166,25 @@ def mdf_writer(path,
         Connection=path)
 
 
-def online_writer(location, enable_tae=False):
+def online_writer(location, stream, enable_tae=False):
     """Return an OnlineAlg writer which writes a single  TES `location`."""
     from PyConf.Algorithms import Online__OutputAlg, Online__RawEventToBanks
 
-    # Grab the RawGuard output of the Online__InputAlg component
-    # TODO find a less ugly/fragile way to do that
-    guard = default_raw_event(
-        bank_types=["VP"], maker=make_raw_event_with_Online
-    ).producer.inputs["RawData"].producer.RawGuard
-
     tae_properties = {}
     if enable_tae:
         tae_properties = dict(
             UseTAELeaves=True,  # Enable writing of TAE output
-            BankDirectory=
-            "OutputBanks",  # See the Hlt2TAE line Moore/Hlt/Hlt2Conf/python/Hlt2Conf/lines/hlt2calib/__init__.py
+            BankDirectory="/Event/Banks",
+            CentralFromRawData=True,
+            # See the Hlt2Calib_TAE line in Moore/Hlt/Hlt2Conf/python/Hlt2Conf/lines/calibration/calibration.py
+            TAEHalfWindow=force_location("/Event/Banks/TAEHalfWindowOutput"),
         )
 
     raw_data = Online__RawEventToBanks(RawEvent=location).RawData
     return Online__OutputAlg(
-        name="EventOutput_{hash}",
+        name=f"EventOutput_{stream}",
         RawData=raw_data,
-        # outputs={'RawGuard': force_location(location)},  # TODO this should also work and we can get rid of the producer.inputs["RawData"].producer.RawGuard stuff above
-        RawGuard=guard,
+        RawGuard=force_location("/Event/Banks/RawDataGuard"),
         **tae_properties,
     )
 
@@ -640,12 +635,14 @@ def make_raw_event_with_Online(location, bank_type=""):
     tae = location.removeprefix("/Event").replace("DAQ/RawEvent", "").replace(
         "/", "")
 
-    def transform(RawData, RawGuard, **outputs):
-        # FIXME check outputs have the same prefix
+    def transform(RawData, RawGuard, DAQErrors, **outputs):
+        dirs = set(os.path.dirname(o) for o in outputs.values())
+        assert len(dirs) == 1, str(outputs)
         return {
-            "BankDirectory": "Banks",
+            "BankDirectory": dirs.pop(),
             "RawData": RawData,
             "RawGuard": RawGuard,
+            "DAQErrors": DAQErrors,
             "ExtraOutputs": list(outputs.values())
         }
 
@@ -653,33 +650,28 @@ def make_raw_event_with_Online(location, bank_type=""):
         location = "/Event/" + location
 
     raw_data_loc = re.sub(r"/Event/(Prev|Next)[0-9]+", "/Event", location)
-    tae_locs = ({
-        f"Prev{i}": force_location(
-            raw_data_loc.replace("/Event", f"/Event/Prev{i}"))
+    tae_locs = {
+        "TAEHalfWindow": force_location("/Event/Banks/TAEHalfWindow"),
+    }
+    tae_locs |= {
+        f"Prev{i}": force_location(f"/Event/Banks/Prev{i}")
         for i in range(10)
-    } | {
-        f"Next{i}": force_location(
-            raw_data_loc.replace("/Event", f"/Event/Next{i}"))
+    }
+    tae_locs |= {
+        f"Next{i}": force_location(f"/Event/Banks/Next{i}")
         for i in range(10)
-    })
-    tae_locs = (
-        {f"Prev{i}": force_location(f"Banks/Prev{i}")
-         for i in range(10)}
-        | {f"Next{i}": force_location(f"Banks/Next{i}")
-           for i in range(10)})
-
-    # print(location, raw_data_loc, tae_locs, flush=True)
-    # assert False
+    }
+
     alg = Online__InputAlg(
         name="Online__InputAlg",
         outputs={
             "RawData": force_location(raw_data_loc),
-            "RawGuard": None,
+            "RawGuard": force_location("/Event/Banks/RawDataGuard"),
             "DAQErrors": None,
         } | tae_locs,
         output_transform=transform,
-        DeclareData=True,  # TODO what does this do?
-        DeclareEvent=True,  # TODO what does this do?
+        DeclareData=True,  # output RawGuard
+        DeclareEvent=True,  # output RawData (incl. TAE crossings)
         DeclareErrors=False,
     )
     return Online__BanksToRawEvent(
-- 
GitLab