From bdffe87e41fc0375323ce5b8198542e815933a47 Mon Sep 17 00:00:00 2001
From: Dominik Smith <d.smith@gsi.de>
Date: Tue, 23 Aug 2022 12:37:33 +0200
Subject: [PATCH] Added new unpackers to CbmTaskUnpack.

---
 algo/CMakeLists.txt          |   1 +
 algo/data/CMakeLists.txt     |   2 +-
 reco/tasks/CbmTaskUnpack.cxx | 158 ++++++++++++++++++++++++++++-------
 reco/tasks/CbmTaskUnpack.h   |  17 +++-
 4 files changed, 144 insertions(+), 34 deletions(-)

diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt
index 4f7e36be31..dafbf5fbc5 100644
--- a/algo/CMakeLists.txt
+++ b/algo/CMakeLists.txt
@@ -27,6 +27,7 @@ target_include_directories(Algo
          ${CMAKE_CURRENT_SOURCE_DIR}/detectors/sts
          ${CMAKE_CURRENT_SOURCE_DIR}/detectors/much
          ${CMAKE_CURRENT_SOURCE_DIR}/detectors/tof
+         ${CMAKE_CURRENT_SOURCE_DIR}/detectors/t0
  )
 
 target_link_libraries(Algo PUBLIC OnlineData ROOT::GenVector INTERFACE FairLogger::FairLogger external::fles_ipc)
diff --git a/algo/data/CMakeLists.txt b/algo/data/CMakeLists.txt
index 71edcd9f9f..f2b9167a41 100644
--- a/algo/data/CMakeLists.txt
+++ b/algo/data/CMakeLists.txt
@@ -26,7 +26,7 @@ set(SRCS
   ${CMAKE_SOURCE_DIR}/core/data/psd/CbmPsdDigi.cxx
   ${CMAKE_SOURCE_DIR}/core/data/psd/CbmPsdAddress.cxx
 
-
+  ${CMAKE_SOURCE_DIR}/core/data/raw/CriGet4Mess001.cxx
   ${CMAKE_SOURCE_DIR}/core/data/raw/StsXyterMessage.cxx
 )
 
diff --git a/reco/tasks/CbmTaskUnpack.cxx b/reco/tasks/CbmTaskUnpack.cxx
index 63915d8754..5249821317 100644
--- a/reco/tasks/CbmTaskUnpack.cxx
+++ b/reco/tasks/CbmTaskUnpack.cxx
@@ -38,6 +38,10 @@ using cbm::algo::UnpackMuchElinkPar;
 using cbm::algo::UnpackMuchPar;
 using cbm::algo::UnpackStsElinkPar;
 using cbm::algo::UnpackStsPar;
+using cbm::algo::UnpackT0ElinkPar;
+using cbm::algo::UnpackT0Par;
+using cbm::algo::UnpackTofElinkPar;
+using cbm::algo::UnpackTofPar;
 
 // -----   Constructor   -----------------------------------------------------
 CbmTaskUnpack::CbmTaskUnpack() : FairTask("Unpack") {}
@@ -52,6 +56,31 @@ CbmTaskUnpack::~CbmTaskUnpack()
 // ---------------------------------------------------------------------------
 
 
+// ----------------- Microslice loop ------------------------------------------
+template<class Digi, class UnpackAlgo>
+uint64_t CbmTaskUnpack::MsLoop(const fles::Timeslice* timeslice, UnpackAlgo& algo, const uint64_t comp,
+                               std::vector<Digi>* digis, size_t* numBytesInComp, size_t* numDigisInComp)
+{
+  const uint64_t numMsInComp = timeslice->num_microslices(comp);
+
+  for (uint64_t mslice = 0; mslice < numMsInComp; mslice++) {
+    const auto msDescriptor = timeslice->descriptor(comp, mslice);
+    const auto msContent    = timeslice->content(comp, mslice);
+    *numBytesInComp += msDescriptor.size;
+    auto result = algo(msContent, msDescriptor, timeslice->start_time());
+    LOG(debug1) << GetName() << ": Component " << comp << ", microslice " << mslice << ", digis " << result.first.size()
+                << ", errors " << result.second.fNumNonHitOrTsbMessage << " | " << result.second.fNumErrElinkOutOfRange
+                << " | " << result.second.fNumErrInvalidFirstMessage << " | " << result.second.fNumErrInvalidMsSize
+                << " | " << result.second.fNumErrTimestampOverflow << " | ";
+    *numDigisInComp += result.first.size();
+#pragma omp critical(insert_digis)
+    digis->insert(digis->end(), result.first.begin(), result.first.end());
+  }
+  return numMsInComp;
+}
+// ----------------------------------------------------------------------------
+
+
 // -----   Execution   -------------------------------------------------------
 void CbmTaskUnpack::Exec(Option_t*)
 {
@@ -86,6 +115,7 @@ void CbmTaskUnpack::Exec(Option_t*)
 
     auto systemId = static_cast<fles::SubsystemIdentifier>(timeslice->descriptor(comp, 0).sys_id);
 
+    // STS
     if (systemId == fles::SubsystemIdentifier::STS) {
       const uint16_t equipmentId = timeslice->descriptor(comp, 0).eq_id;
       const auto algoIt          = fAlgoSts.find(equipmentId);
@@ -98,25 +128,13 @@ void CbmTaskUnpack::Exec(Option_t*)
       assert(timeslice->descriptor(comp, 0).sys_ver == 0x20);
 
       // --- Microslice loop
-      numMsInComp = timeslice->num_microslices(comp);
-      for (uint64_t mslice = 0; mslice < numMsInComp; mslice++) {
-        const auto msDescriptor = timeslice->descriptor(comp, mslice);
-        const auto msContent    = timeslice->content(comp, mslice);
-        numBytesInComp += msDescriptor.size;
-        auto result = (algoIt->second)(msContent, msDescriptor, timeslice->start_time());
-        LOG(debug1) << GetName() << ": Component " << comp << ", microslice " << mslice << ", digis "
-                    << result.first.size() << ", errors " << result.second.fNumNonHitOrTsbMessage << " | "
-                    << result.second.fNumErrElinkOutOfRange << " | " << result.second.fNumErrInvalidFirstMessage
-                    << " | " << result.second.fNumErrInvalidMsSize << " | " << result.second.fNumErrTimestampOverflow
-                    << " | ";
-        numDigisInComp += result.first.size();
-#pragma omp critical(insert_sts_digis)
-        fTimeslice->fData.fSts.fDigis.insert(fTimeslice->fData.fSts.fDigis.end(), result.first.begin(),
-                                             result.first.end());
-      }  //# microslice
+      numMsInComp =
+        MsLoop(timeslice, algoIt->second, comp, &fTimeslice->fData.fSts.fDigis, &numBytesInComp, &numDigisInComp);
+
       numCompUsed++;
     }  // system STS
 
+    // MUCH
     if (systemId == fles::SubsystemIdentifier::MUCH) {
       const uint16_t equipmentId = timeslice->descriptor(comp, 0).eq_id;
       const auto algoIt          = fAlgoMuch.find(equipmentId);
@@ -129,25 +147,50 @@ void CbmTaskUnpack::Exec(Option_t*)
       assert(timeslice->descriptor(comp, 0).sys_ver == 0x20);
 
       // --- Microslice loop
-      numMsInComp = timeslice->num_microslices(comp);
-      for (uint64_t mslice = 0; mslice < numMsInComp; mslice++) {
-        const auto msDescriptor = timeslice->descriptor(comp, mslice);
-        const auto msContent    = timeslice->content(comp, mslice);
-        numBytesInComp += msDescriptor.size;
-        auto result = (algoIt->second)(msContent, msDescriptor, timeslice->start_time());
-        LOG(debug1) << GetName() << ": Component " << comp << ", microslice " << mslice << ", digis "
-                    << result.first.size() << ", errors " << result.second.fNumNonHitOrTsbMessage << " | "
-                    << result.second.fNumErrElinkOutOfRange << " | " << result.second.fNumErrInvalidFirstMessage
-                    << " | " << result.second.fNumErrInvalidMsSize << " | " << result.second.fNumErrTimestampOverflow
-                    << " | ";
-        numDigisInComp += result.first.size();
-#pragma omp critical(insert_much_digis)
-        fTimeslice->fData.fMuch.fDigis.insert(fTimeslice->fData.fMuch.fDigis.end(), result.first.begin(),
-                                              result.first.end());
-      }  //# microslice
+      numMsInComp =
+        MsLoop(timeslice, algoIt->second, comp, &fTimeslice->fData.fMuch.fDigis, &numBytesInComp, &numDigisInComp);
+
       numCompUsed++;
     }  // system MUCH
 
+    // TOF
+    if (systemId == fles::SubsystemIdentifier::RPC) {
+      const uint16_t equipmentId = timeslice->descriptor(comp, 0).eq_id;
+      const auto algoIt          = fAlgoTof.find(equipmentId);
+      assert(algoIt != fAlgoTof.end());
+
+      // The current algorithm works for the TOF data format version XXXX used in 2021.
+      // Other versions are not yet supported.
+      // In the future, different data formats will be supported by instantiating different
+      // algorithms depending on the version.
+      //assert(timeslice->descriptor(comp, 0).sys_ver == XXXX);
+
+      // --- Microslice loop
+      numMsInComp =
+        MsLoop(timeslice, algoIt->second, comp, &fTimeslice->fData.fTof.fDigis, &numBytesInComp, &numDigisInComp);
+
+      numCompUsed++;
+    }  // system TOF
+
+    // T0
+    if (systemId == fles::SubsystemIdentifier::T0) {
+      const uint16_t equipmentId = timeslice->descriptor(comp, 0).eq_id;
+      const auto algoIt          = fAlgoT0.find(equipmentId);
+      assert(algoIt != fAlgoT0.end());
+
+      // The current algorithm works for the T0 data format version XXXX used in 2021.
+      // Other versions are not yet supported.
+      // In the future, different data formats will be supported by instantiating different
+      // algorithms depending on the version.
+      //assert(timeslice->descriptor(comp, 0).sys_ver == XXXX);
+
+      // --- Microslice loop
+      numMsInComp =
+        MsLoop(timeslice, algoIt->second, comp, &fTimeslice->fData.fT0.fDigis, &numBytesInComp, &numDigisInComp);
+
+      numCompUsed++;
+    }  // system T0
+
     compTimer.Stop();
     LOG(debug) << GetName() << ": Component " << comp << ", microslices " << numMsInComp << " input size "
                << numBytesInComp << " bytes, "
@@ -165,11 +208,19 @@ void CbmTaskUnpack::Exec(Option_t*)
             [](CbmStsDigi digi1, CbmStsDigi digi2) { return digi1.GetTime() < digi2.GetTime(); });
   std::sort(std::execution::par_unseq, fTimeslice->fData.fMuch.fDigis.begin(), fTimeslice->fData.fMuch.fDigis.end(),
             [](CbmMuchDigi digi1, CbmMuchDigi digi2) { return digi1.GetTime() < digi2.GetTime(); });
+  std::sort(std::execution::par_unseq, fTimeslice->fData.fTof.fDigis.begin(), fTimeslice->fData.fTof.fDigis.end(),
+            [](CbmTofDigi digi1, CbmTofDigi digi2) { return digi1.GetTime() < digi2.GetTime(); });
+  std::sort(std::execution::par_unseq, fTimeslice->fData.fT0.fDigis.begin(), fTimeslice->fData.fT0.fDigis.end(),
+            [](CbmTofDigi digi1, CbmTofDigi digi2) { return digi1.GetTime() < digi2.GetTime(); });
 #else
   std::sort(fTimeslice->fData.fSts.fDigis.begin(), fTimeslice->fData.fSts.fDigis.end(),
             [](CbmStsDigi digi1, CbmStsDigi digi2) { return digi1.GetTime() < digi2.GetTime(); });
   std::sort(fTimeslice->fData.fMuch.fDigis.begin(), fTimeslice->fData.fMuch.fDigis.end(),
             [](CbmMuchDigi digi1, CbmMuchDigi digi2) { return digi1.GetTime() < digi2.GetTime(); });
+  std::sort(fTimeslice->fData.fTof.fDigis.begin(), fTimeslice->fData.fTof.fDigis.end(),
+            [](CbmTofDigi digi1, CbmTofDigi digi2) { return digi1.GetTime() < digi2.GetTime(); });
+  std::sort(fTimeslice->fData.fT0.fDigis.begin(), fTimeslice->fData.fT0.fDigis.end(),
+            [](CbmTofDigi digi1, CbmTofDigi digi2) { return digi1.GetTime() < digi2.GetTime(); });
 #endif
 
   // --- Timeslice log
@@ -279,8 +330,51 @@ InitStatus CbmTaskUnpack::Init()
     LOG(info) << "--- Configured equipment " << equip << " with " << numElinks << " elinks";
   }
 
+  // --- Common parameters for all components for TOF
+  uint32_t numChansPerAsicTof = 4;  // R/O channels per ASIC for TOF
+
+  // Create one algorithm per component and configure it with parameters
+  auto equipIdsTof = fTofConfig.GetEquipmentIds();
+  for (auto& equip : equipIdsTof) {
+    std::unique_ptr<UnpackTofPar> par(new UnpackTofPar());
+    par->fNumChansPerAsic  = numChansPerAsicTof;
+    const size_t numElinks = fTofConfig.GetNumElinks(equip);
+    for (size_t elink = 0; elink < numElinks; elink++) {
+      UnpackTofElinkPar elinkPar;
+      elinkPar.fChannelUId = fTofConfig.Map(equip, elink);  // Vector of TOF addresses for this elink
+      elinkPar.fTimeOffset = 0.;
+      par->fElinkParams.push_back(elinkPar);
+    }
+    fAlgoTof[equip].SetParams(std::move(par));
+    LOG(info) << "--- Configured equipment " << equip << " with " << numElinks << " elinks";
+  }
+
+  // --- Common parameters for all components for T0
+  uint32_t numChansPerAsicT0 = 4;  // R/O channels per ASIC for T0
+
+  // Create one algorithm per component and configure it with parameters
+  auto equipIdsT0 = fT0Config.GetEquipmentIds();
+  for (auto& equip : equipIdsT0) {
+    std::unique_ptr<UnpackT0Par> par(new UnpackT0Par());
+    par->fNumChansPerAsic  = numChansPerAsicT0;
+    const size_t numElinks = fT0Config.GetNumElinks(equip);
+    for (size_t elink = 0; elink < numElinks; elink++) {
+      UnpackT0ElinkPar elinkPar;
+      elinkPar.fChannelUId = fT0Config.Map(equip, elink);  // Vector of T0 addresses for this elink
+      elinkPar.fTimeOffset = 0.;
+      par->fElinkParams.push_back(elinkPar);
+    }
+    fAlgoT0[equip].SetParams(std::move(par));
+    LOG(info) << "--- Configured equipment " << equip << " with " << numElinks << " elinks";
+  }
+
+
   LOG(info) << "--- Configured " << fAlgoSts.size() << " unpacker algorithms for STS.";
   LOG(debug) << "Readout map:" << fStsConfig.PrintReadoutMap();
+  LOG(info) << "--- Configured " << fAlgoMuch.size() << " unpacker algorithms for MUCH.";
+  LOG(info) << "--- Configured " << fAlgoTof.size() << " unpacker algorithms for TOF.";
+  LOG(info) << "--- Configured " << fAlgoT0.size() << " unpacker algorithms for T0.";
+
   LOG(info) << "==================================================";
 
   return kSUCCESS;
diff --git a/reco/tasks/CbmTaskUnpack.h b/reco/tasks/CbmTaskUnpack.h
index 940ee17c33..4c8cccc4ea 100644
--- a/reco/tasks/CbmTaskUnpack.h
+++ b/reco/tasks/CbmTaskUnpack.h
@@ -11,6 +11,9 @@
 
 #include <FairTask.h>
 
+#include "T0ReadoutConfig.h"
+#include "TofReadoutConfig.h"
+
 #include <sstream>
 #include <vector>
 
@@ -19,6 +22,8 @@
 #include "StsReadoutConfig.h"
 #include "UnpackMuch.h"
 #include "UnpackSts.h"
+#include "UnpackT0.h"
+#include "UnpackTof.h"
 
 class CbmDigiManager;
 class CbmSourceTs;
@@ -77,6 +82,12 @@ private:  // members
   std::map<uint16_t, cbm::algo::UnpackMuch> fAlgoMuch = {};
   cbm::algo::MuchReadoutConfig fMuchConfig {};
 
+  std::map<uint16_t, cbm::algo::UnpackTof> fAlgoTof = {};
+  cbm::algo::TofReadoutConfig fTofConfig {};
+
+  std::map<uint16_t, cbm::algo::UnpackT0> fAlgoT0 = {};
+  cbm::algo::T0ReadoutConfig fT0Config {};
+
   size_t fNumTs                = 0;
   size_t fNumMs                = 0;
   size_t fNumBytes             = 0;
@@ -84,8 +95,12 @@ private:  // members
   double fTime                 = 0.;
   CbmDigiTimeslice* fTimeslice = nullptr;  ///< Output data
 
+  //Microslice loop
+  template<class Digi, class UnpackAlgo>
+  uint64_t MsLoop(const fles::Timeslice* timeslice, UnpackAlgo& algo, const uint64_t comp, std::vector<Digi>* digis,
+                  size_t* numBytesInComp, size_t* numDigisInComp);
 
-  ClassDef(CbmTaskUnpack, 1);
+  ClassDef(CbmTaskUnpack, 2);
 };
 
 #endif /* CBMTASKUNPACK_H */
-- 
GitLab