From 507af4ce65edcd06063a2ea72e13261405b15782 Mon Sep 17 00:00:00 2001
From: Dominik Smith <d.smith@gsi.de>
Date: Mon, 17 Jan 2022 16:49:28 +0100
Subject: [PATCH] Generalized CbmTaskTriggerDigi from STS to all detectors.

---
 core/data/base/CbmDigiData.h      |  2 -
 macro/reco/reco_digi.C            |  1 +
 reco/tasks/CbmTaskTriggerDigi.cxx | 80 ++++++++++++++++++++-----------
 reco/tasks/CbmTaskTriggerDigi.h   | 36 +++++++++++++-
 4 files changed, 88 insertions(+), 31 deletions(-)

diff --git a/core/data/base/CbmDigiData.h b/core/data/base/CbmDigiData.h
index 10aa53796e..01d6444aa8 100644
--- a/core/data/base/CbmDigiData.h
+++ b/core/data/base/CbmDigiData.h
@@ -52,8 +52,6 @@ typedef DigiVec<CbmPsdDigi> PsdDigiData;
  **
  ** If no detector-specific collection class is provided, the simplest form (DigiVector)
  ** is used.
- **
- ** The current implementation uses STS only - to be expanded for all systems.
  **/
 struct CbmDigiData {
   friend class boost::serialization::access;
diff --git a/macro/reco/reco_digi.C b/macro/reco/reco_digi.C
index 849ac2be70..75328e1f34 100644
--- a/macro/reco/reco_digi.C
+++ b/macro/reco/reco_digi.C
@@ -119,6 +119,7 @@ void reco_digi(TString input = "", Int_t nTimeSlices = -1, Int_t firstTimeSlice
   int32_t minNumDigis  = 100;  // Trigger threshold in number of digis
   double deadTime      = 50.;  // Minimum time between two triggers
   trigger->SetAlgoParams(triggerWindow, minNumDigis, deadTime);
+  trigger->AddSystem(ECbmModuleId::kSts);
   LOG(info) << myName << ": Added task " << trigger->GetName();
   run->AddTask(trigger.release());
   // ------------------------------------------------------------------------
diff --git a/reco/tasks/CbmTaskTriggerDigi.cxx b/reco/tasks/CbmTaskTriggerDigi.cxx
index 0e34cf7e13..e284c946ba 100644
--- a/reco/tasks/CbmTaskTriggerDigi.cxx
+++ b/reco/tasks/CbmTaskTriggerDigi.cxx
@@ -2,18 +2,21 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Volker Friese [committer] */
 
-
 #include "CbmTaskTriggerDigi.h"
 
 #include "CbmDefs.h"
-#include "CbmDigiBranchBase.h"
 #include "CbmDigiManager.h"
+#include "CbmModuleList.h"
+#include "CbmMuchDigi.h"
+#include "CbmPsdDigi.h"
+#include "CbmRichDigi.h"
 #include "CbmStsDigi.h"
+#include "CbmTofDigi.h"
+#include "CbmTrdDigi.h"
 
 #include <FairLogger.h>
 
 #include "TimeClusterTrigger.h"
-#include <TStopwatch.h>
 
 #include <algorithm>
 #include <cassert>
@@ -21,15 +24,10 @@
 #include <iostream>
 #include <vector>
 
-
-using namespace std;
-
-
 // -----   Constructor   -----------------------------------------------------
 CbmTaskTriggerDigi::CbmTaskTriggerDigi() : FairTask("TriggerDigi") {}
 // ---------------------------------------------------------------------------
 
-
 // -----   Destructor   ------------------------------------------------------
 CbmTaskTriggerDigi::~CbmTaskTriggerDigi()
 {
@@ -37,7 +35,6 @@ CbmTaskTriggerDigi::~CbmTaskTriggerDigi()
 }
 // ---------------------------------------------------------------------------
 
-
 // -----   Execution   -------------------------------------------------------
 void CbmTaskTriggerDigi::Exec(Option_t*)
 {
@@ -47,18 +44,45 @@ void CbmTaskTriggerDigi::Exec(Option_t*)
   TStopwatch timerTot;
   timerTot.Start();
 
-  // --- Get input digi vector
-  CbmDigiBranchBase* stsBranch      = fDigiMan->GetBranch(ECbmModuleId::kSts);
-  const vector<CbmStsDigi>* digiVec = boost::any_cast<const vector<CbmStsDigi>*>(stsBranch->GetBranchContainer());
-  assert(digiVec);
-
-  // --- Extract digi times into to a vector
-  timerStep.Start();
-  std::vector<double> digiTimes(digiVec->size());
-  std::transform(digiVec->begin(), digiVec->end(), digiTimes.begin(),
-                 [](const CbmStsDigi& digi) { return digi.GetTime(); });
-  timerStep.Stop();
-  fTimeExtract += timerStep.RealTime();
+  // --- Get digi times
+  std::vector<double> digiTimes;
+  for (const auto& system : fSystems) {
+    CbmDigiBranchBase* digiBranch = fDigiMan->GetBranch(system);
+    std::vector<double> locDigiTimes;
+    switch (system) {
+      case ECbmModuleId::kMuch: {  //we do not support the "MuchBeamTimeDigi"
+        locDigiTimes = GetDigiTimes<CbmMuchDigi>(digiBranch);
+        break;
+      }
+      case ECbmModuleId::kSts: {
+        locDigiTimes = GetDigiTimes<CbmStsDigi>(digiBranch);
+        break;
+      }
+      case ECbmModuleId::kTof: {
+        locDigiTimes = GetDigiTimes<CbmTofDigi>(digiBranch);
+        break;
+      }
+      case ECbmModuleId::kTrd: {
+        locDigiTimes = GetDigiTimes<CbmTrdDigi>(digiBranch);
+        break;
+      }
+      case ECbmModuleId::kRich: {
+        locDigiTimes = GetDigiTimes<CbmRichDigi>(digiBranch);
+        break;
+      }
+      case ECbmModuleId::kPsd: {
+        locDigiTimes = GetDigiTimes<CbmPsdDigi>(digiBranch);
+        break;
+      }
+      case ECbmModuleId::kT0: {  //T0 has Tof digis
+        locDigiTimes = GetDigiTimes<CbmTofDigi>(digiBranch);
+        break;
+      }
+      default: LOG(fatal) << GetName() << ": Reading digis from unknown detector type!";
+    }
+    digiTimes.insert(digiTimes.end(), locDigiTimes.begin(), locDigiTimes.end());
+  }
+  if (fSystems.size() > 1) { std::sort(digiTimes.begin(), digiTimes.end()); }
 
   // --- Call the trigger algorithm
   timerStep.Start();
@@ -67,7 +91,7 @@ void CbmTaskTriggerDigi::Exec(Option_t*)
   fTimeFind += timerStep.RealTime();
 
   // --- Timeslice statistics
-  size_t numDigis    = digiVec->size();
+  size_t numDigis    = digiTimes.size();
   size_t numTriggers = fTriggers->size();
 
   // --- Timeslice log
@@ -123,12 +147,14 @@ InitStatus CbmTaskTriggerDigi::Init()
   LOG(info) << "==================================================";
   LOG(info) << GetName() << ": Initialising...";
 
-  // --- Check input data (STS only for the time being)
-  if (!fDigiMan->IsPresent(ECbmModuleId::kSts)) {
-    LOG(fatal) << GetName() << ": No digi branch for STS";
-    return kFATAL;
+  // --- Check input data
+  for (const auto& system : fSystems) {
+    if (!fDigiMan->IsPresent(system)) {
+      LOG(fatal) << GetName() << ": No digi branch for " << CbmModuleList::GetModuleNameCaps(system);
+      return kFATAL;
+    }
+    LOG(info) << "--- Found digi branch for " << CbmModuleList::GetModuleNameCaps(system);
   }
-  LOG(info) << "--- Found branch STS digi";
 
   // --- Register output array (Triggers)
   if (ioman->GetObject("Trigger")) {
diff --git a/reco/tasks/CbmTaskTriggerDigi.h b/reco/tasks/CbmTaskTriggerDigi.h
index e5325fa82c..30453cc90e 100644
--- a/reco/tasks/CbmTaskTriggerDigi.h
+++ b/reco/tasks/CbmTaskTriggerDigi.h
@@ -2,21 +2,25 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Volker Friese [committer] */
 
-
 #ifndef CBMTASKTRIGGERDIGI_H
 #define CBMTASKTRIGGERDIGI_H 1
 
-
 #include "CbmDefs.h"
+#include "CbmDigiBranchBase.h"
 
 #include <FairTask.h>
 
 #include "TimeClusterTrigger.h"
+#include <TStopwatch.h>
+
+#include <boost/any.hpp>
 
 #include <vector>
 
+class CbmDigiBranchBase;
 class CbmDigiManager;
 
+using namespace std;
 
 /** @class CbmTaskTriggerDigi
  ** @brief Task class for minimum-bias event trigger from time-distribution of digi data
@@ -67,11 +71,39 @@ public:
     fDeadTime      = deadTime;
   }
 
+  /** @brief Add a detector system to the trigger algorithm
+   ** @param system    System to be added
+   **/
+  void AddSystem(ECbmModuleId system)
+  {
+    if (std::find(fSystems.begin(), fSystems.end(), system) != fSystems.end()) return;
+    fSystems.push_back(system);
+  }
 
 private:  // methods
   /** @brief Task initialisation **/
   virtual InitStatus Init();
 
+  /** @brief Extract digi times from digi branch
+   ** @param digiBranch    Digi branch for one detector
+   **/
+  template<class TDigi>
+  std::vector<double> GetDigiTimes(const CbmDigiBranchBase* digiBranch)
+  {
+    TStopwatch timerStep;
+    // --- Get input digi vector
+    const vector<TDigi>* digiVec = boost::any_cast<const vector<TDigi>*>(digiBranch->GetBranchContainer());
+    assert(digiVec);
+
+    // --- Extract digi times into to a vector
+    timerStep.Start();
+    std::vector<double> digiTimes(digiVec->size());
+    std::transform(digiVec->begin(), digiVec->end(), digiTimes.begin(),
+                   [](const TDigi& digi) { return digi.GetTime(); });
+    timerStep.Stop();
+    fTimeExtract += timerStep.RealTime();
+    return digiTimes;
+  }
 
 private:                                     // members
   CbmDigiManager* fDigiMan = nullptr;        //! Input data
-- 
GitLab