From 655dcada152d03949f6bf6ae9c2055d2a4636866 Mon Sep 17 00:00:00 2001
From: Felix Weiglhofer <weiglhofer@fias.uni-frankfurt.de>
Date: Tue, 16 May 2023 16:06:44 +0000
Subject: [PATCH] algo: Add STS Unpack chain.

---
 algo/detectors/sts/StsUnpackChain.cxx | 108 ++++++++++++++++++++++++++
 algo/detectors/sts/StsUnpackChain.h   |  41 ++++++++++
 2 files changed, 149 insertions(+)
 create mode 100644 algo/detectors/sts/StsUnpackChain.cxx
 create mode 100644 algo/detectors/sts/StsUnpackChain.h

diff --git a/algo/detectors/sts/StsUnpackChain.cxx b/algo/detectors/sts/StsUnpackChain.cxx
new file mode 100644
index 0000000000..3f3a7a55f9
--- /dev/null
+++ b/algo/detectors/sts/StsUnpackChain.cxx
@@ -0,0 +1,108 @@
+/* Copyright (C) 2022 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer]*/
+#include "StsUnpackChain.h"
+
+#include "CbmStsDigi.h"
+
+#include <Timeslice.hpp>
+
+#include <fairlogger/Logger.h>
+
+#include <xpu/host.h>
+
+using namespace cbm::algo;
+
+void sts::UnpackChain::Init(StsReadoutConfig config)
+{
+  fConfig = config;
+
+  // Copied from CbmTaskUnpack in CBMRoot.
+
+  // --- Common parameters for all components for STS
+  uint32_t numChansPerAsicSts   = 128;  // R/O channels per ASIC for STS
+  uint32_t numAsicsPerModuleSts = 16;   // Number of ASICs per module for STS
+
+  // Create one algorithm per component for STS and configure it with parameters
+  auto equipIdsSts = fConfig->GetEquipmentIds();
+  for (auto equip : equipIdsSts) {
+    std::unique_ptr<UnpackStsPar> par(new UnpackStsPar());
+    par->fNumChansPerAsic   = numChansPerAsicSts;
+    par->fNumAsicsPerModule = numAsicsPerModuleSts;
+    const size_t numElinks  = fConfig->GetNumElinks(equip);
+    for (size_t elink = 0; elink < numElinks; elink++) {
+      UnpackStsElinkPar elinkPar;
+      auto mapEntry        = fConfig->Map(equip, elink);
+      elinkPar.fAddress    = mapEntry.first;   // Module address for this elink
+      elinkPar.fAsicNr     = mapEntry.second;  // ASIC number within module
+      elinkPar.fTimeOffset = 0.;
+      elinkPar.fAdcOffset  = 1.;
+      elinkPar.fAdcGain    = 1.;
+      // elinkPar.fIsPulser   = mapEntry.pulser;
+      // TODO: Add parameters for time and ADC calibration
+      par->fElinkParams.push_back(elinkPar);
+    }
+    fAlgoSts[equip].SetParams(std::move(par));
+    LOG(debug) << "--- Configured STS equipment " << equip << " with " << numElinks << " elinks";
+  }  //# equipments
+}
+
+std::vector<CbmStsDigi> sts::UnpackChain::Run(const fles::Timeslice& timeslice)
+{
+  assert(fConfig.has_value() && "UnpackChain: Configuration not initialized (call Init first))");
+
+  xpu::scoped_timer t_("STS Unpacker");
+
+  std::vector<CbmStsDigi> digis;
+  size_t numPulsers = 0;
+
+  for (uint64_t comp = 0; comp < timeslice.num_components(); comp++) {
+
+    // --- Component log
+    size_t numDigisInComp = 0;
+    uint64_t numMsInComp  = 0;
+
+    auto systemId = static_cast<fles::SubsystemIdentifier>(timeslice.descriptor(comp, 0).sys_id);
+
+    if (systemId == fles::SubsystemIdentifier::STS) {
+      const uint16_t equipmentId = timeslice.descriptor(comp, 0).eq_id;
+      // std::cout << "STS Unpacker: Component " << comp << ", equipment ID " << equipmentId << std::endl;
+      // for (auto e : fAlgoSts) {
+      //   std::cout << "STS Unpacker: Equipment ID " << e.first << std::endl;
+      // }
+      const auto algoIt = fAlgoSts.find(equipmentId);
+      assert(algoIt != fAlgoSts.end());
+
+      // The current algorithm works for the STS data format version 0x20 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 == 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);
+
+        xpu::t_add_bytes(msDescriptor.size);
+
+        auto result = (algoIt->second)(msContent, msDescriptor, timeslice.start_time());
+        LOG(debug1) << "STS Unpacker: Component " << comp << ", microslice " << mslice << ", digis "
+                    << result.first.size() << ", errors " << result.second.fNumNonHitOrTsbMessage << " | "
+                    << result.second.fNumErrElinkOutOfRange << " | " << result.second.fNumErrInvalidFirstMessage
+                    << " | " << result.second.fNumErrInvalidMsSize << " | " << result.second.fNumErrTimestampOverflow
+                    << " | ";
+
+        // numPulsers += result.second.fNumPulserHits;
+        numDigisInComp += result.first.size();
+
+        digis.insert(digis.end(), result.first.begin(), result.first.end());
+      }  //# microslice
+    }    // system STS
+
+  }  // component
+
+  LOG(info) << "Timeslice contains " << digis.size() << " STS digis (discarded " << numPulsers << " pulser hits)";
+  return digis;
+}
diff --git a/algo/detectors/sts/StsUnpackChain.h b/algo/detectors/sts/StsUnpackChain.h
new file mode 100644
index 0000000000..e5d7a83751
--- /dev/null
+++ b/algo/detectors/sts/StsUnpackChain.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2022 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Felix Weiglhofer [committer]*/
+#ifndef CBM_ALGO_DETECTORS_STS_UNPACKCHAIN_H
+#define CBM_ALGO_DETECTORS_STS_UNPACKCHAIN_H
+
+#include <optional>
+#include <unordered_map>
+#include <vector>
+
+#include <xpu/defines.h>
+#include <yaml-cpp/yaml.h>
+
+#include "Prelude.h"
+#include "StsReadoutConfig.h"
+#include "SubChain.h"
+#include "UnpackSts.h"
+
+class CbmStsDigi;
+namespace fles
+{
+  class Timeslice;
+}
+
+namespace cbm::algo::sts
+{
+
+  class UnpackChain : public SubChain {
+
+  public:
+    void Init(StsReadoutConfig config);
+    std::vector<CbmStsDigi> Run(const fles::Timeslice& ts);
+
+  private:
+    std::unordered_map<u16, UnpackSts> fAlgoSts;
+    std::optional<StsReadoutConfig> fConfig;
+  };
+
+}  // namespace cbm::algo::sts
+
+#endif  // CBM_ALGO_DETECTORS_STS_UNPACKCHAIN_H
-- 
GitLab