From b35d3e3e55148998c37e4e3a642936f90d78f43c Mon Sep 17 00:00:00 2001
From: Dominik Smith <smith@th.physik.uni-frankfurt.de>
Date: Fri, 23 Jun 2023 12:41:30 +0200
Subject: [PATCH] Introduced monitoring for cbm::algo::EventBuilder.

---
 algo/evbuild/EventBuilder.cxx     | 34 ++++++++++++++++++++++-----
 algo/evbuild/EventBuilder.h       | 39 +++++++++++++++++++++++++++----
 algo/test/_GTestEventBuilder.cxx  | 27 ++++++++++++++++++---
 reco/mq/CbmDevBuildEvents.cxx     |  2 +-
 reco/tasks/CbmTaskBuildEvents.cxx |  4 ++--
 5 files changed, 90 insertions(+), 16 deletions(-)

diff --git a/algo/evbuild/EventBuilder.cxx b/algo/evbuild/EventBuilder.cxx
index cfe2b45401..2f04b6f131 100644
--- a/algo/evbuild/EventBuilder.cxx
+++ b/algo/evbuild/EventBuilder.cxx
@@ -14,16 +14,30 @@ namespace cbm
   namespace algo
   {
     // --- Execution
-    std::vector<CbmDigiEvent> EventBuilder::operator()(const CbmDigiTimeslice& ts, const vector<double> triggers) const
+    EventBuilder::resultType EventBuilder::operator()(const CbmDigiTimeslice& ts, const vector<double> triggers) const
     {
-      vector<CbmDigiEvent> eventVec(triggers.size());
-      std::transform(triggers.begin(), triggers.end(), eventVec.begin(),
-                     [&ts, this](const double& trigger) { return BuildEvent(ts, trigger); });
-      return eventVec;
+      // --- Output data
+      resultType result = {};
+      result.first.resize(triggers.size());
+
+      std::transform(triggers.begin(), triggers.end(), result.first.begin(),
+                     [&ts, &result, this](const double& trigger) { return BuildEvent(ts, result.second, trigger); });
+
+      EventBuilderMonitorData& monitor = result.second;
+      monitor.fSts.fNum += ts.fData.fSts.fDigis.size();
+      monitor.fRich.fNum += ts.fData.fRich.fDigis.size();
+      monitor.fMuch.fNum += ts.fData.fMuch.fDigis.size();
+      monitor.fTrd.fNum += ts.fData.fTrd.fDigis.size();
+      monitor.fTrd2d.fNum += ts.fData.fTrd2d.fDigis.size();
+      monitor.fTof.fNum += ts.fData.fTof.fDigis.size();
+      monitor.fPsd.fNum += ts.fData.fPsd.fDigis.size();
+      monitor.fBmon.fNum += ts.fData.fT0.fDigis.size();
+      return result;
     }
 
     // --- Build a single event
-    CbmDigiEvent EventBuilder::BuildEvent(const CbmDigiTimeslice& ts, double trigger) const
+    CbmDigiEvent EventBuilder::BuildEvent(const CbmDigiTimeslice& ts, EventBuilderMonitorData& monitor,
+                                          double trigger) const
     {
       CbmDigiEvent event;
       event.fTime = trigger;
@@ -72,6 +86,14 @@ namespace cbm
           default: break;
         }
       }
+      monitor.fSts.fNumInEvents += event.fData.fSts.fDigis.size();
+      monitor.fRich.fNumInEvents += event.fData.fRich.fDigis.size();
+      monitor.fMuch.fNumInEvents += event.fData.fMuch.fDigis.size();
+      monitor.fTrd.fNumInEvents += event.fData.fTrd.fDigis.size();
+      monitor.fTrd2d.fNumInEvents += event.fData.fTrd2d.fDigis.size();
+      monitor.fTof.fNumInEvents += event.fData.fTof.fDigis.size();
+      monitor.fPsd.fNumInEvents += event.fData.fPsd.fDigis.size();
+      monitor.fBmon.fNumInEvents += event.fData.fT0.fDigis.size();
       return event;
     }
   }  // namespace algo
diff --git a/algo/evbuild/EventBuilder.h b/algo/evbuild/EventBuilder.h
index 945fb70f1e..2d6128801f 100644
--- a/algo/evbuild/EventBuilder.h
+++ b/algo/evbuild/EventBuilder.h
@@ -17,7 +17,6 @@ namespace cbm
 {
   namespace algo
   {
-
     /** @brief Time comparison of two objects with time stamps (class implementing GetTime()) **/
     template<typename Data1, typename Data2>
     bool IsBefore(const Data1& obj1, const Data2& obj2)
@@ -25,6 +24,35 @@ namespace cbm
       return obj1.GetTime() < obj2.GetTime();
     }
 
+
+    /** @struct EventBuilderDetectorMonitorData
+     ** @author Dominik Smith <d.smith@gsi.de>
+     ** @since 23 Jun 2023
+     ** @brief Monitoring data for event building for one detector
+     **/
+    struct EventBuilderDetectorMonitorData {
+      size_t fNumInEvents;  ///< Number of digis collected into events
+      size_t fNum;          ///< Full number of digis in input source
+    };
+
+
+    /** @struct EventBuilderMonitorData
+     ** @author Dominik Smith <d.smith@gsi.de>
+     ** @since 23 Jun 2023
+     ** @brief Monitoring data for event building
+     **/
+    struct EventBuilderMonitorData {
+      EventBuilderDetectorMonitorData fSts;    ///< Monitoring data for STS
+      EventBuilderDetectorMonitorData fMuch;   ///< Monitoring data for MUCH
+      EventBuilderDetectorMonitorData fTof;    ///< Monitoring data for TOF
+      EventBuilderDetectorMonitorData fBmon;   ///< Monitoring data for T0
+      EventBuilderDetectorMonitorData fTrd;    ///< Monitoring data for TRD
+      EventBuilderDetectorMonitorData fTrd2d;  ///< Monitoring data for TRD2D
+      EventBuilderDetectorMonitorData fRich;   ///< Monitoring data for RICH
+      EventBuilderDetectorMonitorData fPsd;    ///< Monitoring data for PSD
+    };
+
+
     /** @class EventBuilder
      ** @author Volker Friese <v.friese@gsi.de>
      ** @since 2021
@@ -43,6 +71,8 @@ namespace cbm
     class EventBuilder {
 
     public:
+      typedef std::pair<std::vector<CbmDigiEvent>, EventBuilderMonitorData> resultType;
+
       /** @brief Constructor **/
       EventBuilder() {};
 
@@ -54,17 +84,18 @@ namespace cbm
       /** @brief Execution
        ** @param  ts       Digi source (timeslice)
        ** @param  triggers List of trigger times
-       ** @return Vector of constructed events
+       ** @return Vector of constructed events and monitoring data
        **/
-      std::vector<CbmDigiEvent> operator()(const CbmDigiTimeslice& ts, const std::vector<double> triggers) const;
+      resultType operator()(const CbmDigiTimeslice& ts, const std::vector<double> triggers) const;
 
 
       /** @brief Build a single event from a trigger time
        ** @param  ts      Digi source (timeslice)
+       ** @param  monitor Monitoring data
        ** @param  trigger Trigger time
        ** @return Digi event
        **/
-      CbmDigiEvent BuildEvent(const CbmDigiTimeslice& ts, double trigger) const;
+      CbmDigiEvent BuildEvent(const CbmDigiTimeslice& ts, EventBuilderMonitorData& monitor, double trigger) const;
 
 
       /** @brief Configure the event windows
diff --git a/algo/test/_GTestEventBuilder.cxx b/algo/test/_GTestEventBuilder.cxx
index 934d9346aa..6227df9cb6 100644
--- a/algo/test/_GTestEventBuilder.cxx
+++ b/algo/test/_GTestEventBuilder.cxx
@@ -29,12 +29,14 @@ TEST(_GTestEventBuilder, CheckEventBuilderAlgorithmSimple)
     tsIn.fData.fMuch.fDigis.push_back(CbmMuchDigi(1111, 1, i * inputSpacing));
     tsIn.fData.fSts.fDigis.push_back(CbmStsDigi(268502050, 1, i * inputSpacing, 1.0));
     tsIn.fData.fTof.fDigis.push_back(CbmTofDigi(1111, i * inputSpacing, 1.0));
-    //tsIn.fData.fTrd.fDigis.push_back(CbmTrdDigi(0, 1.0, 1.0, i * inputSpacing));
+    tsIn.fData.fTrd.fDigis.push_back(
+      CbmTrdDigi(475, 37, 150, i * inputSpacing, CbmTrdDigi::eTriggerType::kBeginTriggerTypes, 0));
     tsIn.fData.fRich.fDigis.push_back(CbmRichDigi(1111, i * inputSpacing, 1.0));
     tsIn.fData.fPsd.fDigis.push_back(CbmPsdDigi(1111, i * inputSpacing, 1.0));
     tsIn.fData.fT0.fDigis.push_back(CbmBmonDigi(1111, i * inputSpacing, 1.0));
   }
 
+
   std::vector<double> triggerIn;
   const uint nTrigger         = 99;
   const double triggerSpacing = 100.0;
@@ -43,17 +45,36 @@ TEST(_GTestEventBuilder, CheckEventBuilderAlgorithmSimple)
     triggerIn.push_back(i * triggerSpacing);
   }
 
-  std::vector<CbmDigiEvent> eventsOut = evbuild(tsIn, triggerIn);
+  cbm::algo::EventBuilder::resultType result  = evbuild(tsIn, triggerIn);
+  std::vector<CbmDigiEvent>& eventsOut        = result.first;
+  cbm::algo::EventBuilderMonitorData& monitor = result.second;
+
   EXPECT_EQ(eventsOut.size(), nTrigger);
 
   for (uint i = 0; i < eventsOut.size(); i++) {
     EXPECT_EQ(eventsOut[i].fData.fMuch.fDigis.size(), 9);
     EXPECT_EQ(eventsOut[i].fData.fSts.fDigis.size(), 9);
     EXPECT_EQ(eventsOut[i].fData.fTof.fDigis.size(), 9);
-    //EXPECT_EQ(eventsOut[i].fData.fTrd.fDigis.size(), 9);
+    EXPECT_EQ(eventsOut[i].fData.fTrd.fDigis.size(), 9);
     EXPECT_EQ(eventsOut[i].fData.fRich.fDigis.size(), 9);
     EXPECT_EQ(eventsOut[i].fData.fPsd.fDigis.size(), 9);
     EXPECT_EQ(eventsOut[i].fData.fT0.fDigis.size(), 9);
     EXPECT_EQ(eventsOut[i].fTime, triggerIn[i]);
   }
+
+  EXPECT_EQ(monitor.fMuch.fNumInEvents, 9 * nTrigger);
+  EXPECT_EQ(monitor.fSts.fNumInEvents, 9 * nTrigger);
+  EXPECT_EQ(monitor.fTof.fNumInEvents, 9 * nTrigger);
+  EXPECT_EQ(monitor.fTrd.fNumInEvents, 9 * nTrigger);
+  EXPECT_EQ(monitor.fRich.fNumInEvents, 9 * nTrigger);
+  EXPECT_EQ(monitor.fPsd.fNumInEvents, 9 * nTrigger);
+  EXPECT_EQ(monitor.fBmon.fNumInEvents, 9 * nTrigger);
+
+  EXPECT_EQ(monitor.fMuch.fNum, nInput);
+  EXPECT_EQ(monitor.fSts.fNum, nInput);
+  EXPECT_EQ(monitor.fTof.fNum, nInput);
+  EXPECT_EQ(monitor.fTrd.fNum, nInput);
+  EXPECT_EQ(monitor.fRich.fNum, nInput);
+  EXPECT_EQ(monitor.fPsd.fNum, nInput);
+  EXPECT_EQ(monitor.fBmon.fNum, nInput);
 }
diff --git a/reco/mq/CbmDevBuildEvents.cxx b/reco/mq/CbmDevBuildEvents.cxx
index 5d336b8f8a..08f6f4f757 100644
--- a/reco/mq/CbmDevBuildEvents.cxx
+++ b/reco/mq/CbmDevBuildEvents.cxx
@@ -219,7 +219,7 @@ bool CbmDevBuildEvents::HandleData(FairMQParts& parts, int /*index*/)
   LOG(debug) << "triggers: " << triggers.size();
 
   /// Create events
-  std::vector<CbmDigiEvent> vEvents = fEvbuildAlgo(ts, triggers);
+  std::vector<CbmDigiEvent> vEvents = fEvbuildAlgo(ts, triggers).first;
   LOG(debug) << "vEvents size: " << vEvents.size();
 
   /// Send output message
diff --git a/reco/tasks/CbmTaskBuildEvents.cxx b/reco/tasks/CbmTaskBuildEvents.cxx
index 9088dbb930..8312e9f83a 100644
--- a/reco/tasks/CbmTaskBuildEvents.cxx
+++ b/reco/tasks/CbmTaskBuildEvents.cxx
@@ -120,7 +120,7 @@ void CbmTaskBuildEvents::Exec(Option_t*)
   // --- If the input is already CbmDigiTimeslice (from unpacking), use that directly
   if (fTimeslice) {
     timerStep.Start();
-    *fEvents = fAlgo(*fTimeslice, *fTriggers);
+    *fEvents = fAlgo(*fTimeslice, *fTriggers).first;
     timerStep.Stop();
     fTimeBuildEvt += timerStep.RealTime();
     for (const auto& entry : fEventWindows)
@@ -136,7 +136,7 @@ void CbmTaskBuildEvents::Exec(Option_t*)
     timerStep.Stop();
     fTimeFillTs += timerStep.RealTime();
     timerStep.Start();
-    *fEvents = fAlgo(ts, *fTriggers);
+    *fEvents = fAlgo(ts, *fTriggers).first;
     timerStep.Stop();
     fTimeBuildEvt += timerStep.RealTime();
   }
-- 
GitLab