From b04f1afa2bac9e656ed33526addf9043f7132700 Mon Sep 17 00:00:00 2001
From: "s.zharko@gsi.de" <s.zharko@gsi.de>
Date: Fri, 19 Apr 2024 21:52:18 +0200
Subject: [PATCH] online: Introduction of the TOF tracking station parameter
 and the tof::TrackingInterface class

---
 algo/CMakeLists.txt                          |  2 +
 algo/base/SubChain.h                         |  7 ++-
 algo/ca/SetupInterface.cxx                   | 21 +++++++
 algo/ca/SetupInterface.h                     | 65 ++++++++++++++++++++
 algo/ca/TrackingChain.cxx                    |  7 ++-
 algo/ca/TrackingChain.h                      |  3 +
 algo/detectors/tof/Config.h                  | 61 ------------------
 algo/detectors/tof/HitfindSetup.h            |  2 +
 algo/detectors/tof/TrackingInterface.cxx     | 62 +++++++++++++++++++
 algo/detectors/tof/TrackingInterface.h       | 43 +++++++++++++
 reco/tasks/CbmTaskTofClusterizerParWrite.cxx |  1 +
 11 files changed, 209 insertions(+), 65 deletions(-)
 create mode 100644 algo/ca/SetupInterface.cxx
 create mode 100644 algo/ca/SetupInterface.h
 delete mode 100644 algo/detectors/tof/Config.h
 create mode 100644 algo/detectors/tof/TrackingInterface.cxx
 create mode 100644 algo/detectors/tof/TrackingInterface.h

diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt
index aaadf755c8..9db6cc5d37 100644
--- a/algo/CMakeLists.txt
+++ b/algo/CMakeLists.txt
@@ -110,6 +110,7 @@ set(SRCS
   detectors/tof/Unpack.cxx
   detectors/tof/UnpackMS.cxx
   detectors/tof/Hitfind.cxx
+  detectors/tof/TrackingInterface.cxx
   detectors/tof/HitfinderChain.cxx
   detectors/tof/CalibratorChain.cxx
   detectors/tof/config/ReadoutPars_mCBM2022.cxx
@@ -145,6 +146,7 @@ set(SRCS
   qa/PadConfig.cxx
   qa/QaData.cxx
   qa/unpack/StsDigiQa.cxx
+  ca/SetupInterface.cxx
   ca/TrackingChain.cxx
   ca/qa/CaInputQa.cxx
   ca/qa/CaOutputQa.cxx
diff --git a/algo/base/SubChain.h b/algo/base/SubChain.h
index a541e75764..63599cd9d4 100644
--- a/algo/base/SubChain.h
+++ b/algo/base/SubChain.h
@@ -13,7 +13,9 @@ namespace cbm::algo
   class SubChain {
 
    public:
-    void SetContext(ChainContext* ctx) { fContext = ctx; }
+    const ChainContext* GetContext() { return fContext; }
+
+    void SetContext(const ChainContext* ctx) { fContext = ctx; }
 
     const Options& Opts() const { return gsl::make_not_null(fContext)->opts; }
     const RecoParams& Params() const { return gsl::make_not_null(fContext)->recoParams; }
@@ -27,8 +29,9 @@ namespace cbm::algo
       return *gsl::make_not_null(fContext)->monitor;
     }
 
+
    private:
-    ChainContext* fContext = nullptr;
+    const ChainContext* fContext = nullptr;
   };
 }  // namespace cbm::algo
 
diff --git a/algo/ca/SetupInterface.cxx b/algo/ca/SetupInterface.cxx
new file mode 100644
index 0000000000..566330e712
--- /dev/null
+++ b/algo/ca/SetupInterface.cxx
@@ -0,0 +1,21 @@
+/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   SetupInterface.h
+/// \date   19.04.2024
+/// \brief  A detector setup interface used for tracking input data initialization (source)
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#include "SetupInterface.h"
+
+using cbm::algo::SetupInterface;
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void SetupInterface::Init()
+{
+
+  fTof.SetContext(this->GetContext());
+  fTof.Init();
+}
diff --git a/algo/ca/SetupInterface.h b/algo/ca/SetupInterface.h
new file mode 100644
index 0000000000..cb80c33021
--- /dev/null
+++ b/algo/ca/SetupInterface.h
@@ -0,0 +1,65 @@
+/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   SetupInterface.h
+/// \date   19.04.2024
+/// \brief  A detector setup interface used for tracking input data initialization (header)
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#pragma once
+
+#include "SubChain.h"
+#include "TrackingDefs.h"
+#include "tof/TrackingInterface.h"
+
+#include <type_traits>
+
+// TODO: SZh 19.04.2024: Provide interfaces for other subsystems and redefine access
+
+namespace cbm::algo
+{
+  /// \class SetupInterface
+  /// \brief A detector setup interface class for tracking input data initialization
+  class SetupInterface : public SubChain {
+   private:
+    /// \brief A helper temporary function to enable a method for a given detector subsystem
+    template<ca::EDetectorID DetID>
+    static constexpr bool EnableDet()
+    {
+      return DetID == ca::EDetectorID::Tof;
+    }
+
+   public:
+    /// \brief Default constructor
+    SetupInterface() = default;
+
+    /// \brief Copy constructor
+    SetupInterface(const SetupInterface&) = delete;
+
+    /// \brief Move constructor
+    SetupInterface(SetupInterface&&) = delete;
+
+    /// \brief Destructor
+    ~SetupInterface() = default;
+
+    /// \brief Initializer function
+    void Init();
+
+    /// \brief   Returns tracking station index by the TOF address
+    /// \param   address  Unique address of a TOF element
+    /// \return  Local index of tracking station
+    template<ca::EDetectorID DetID, std::enable_if_t<EnableDet<DetID>(), bool> = true>
+    int GetTrackingStation(uint32_t address) const
+    {
+      if constexpr (DetID == ca::EDetectorID::Tof) {
+        return fTof.GetTrackingStation(address);
+      }
+      return -1;
+    }
+
+
+   private:
+    tof::TrackingInterface fTof;  ///< TOF tracking interface
+  };
+}  // namespace cbm::algo
diff --git a/algo/ca/TrackingChain.cxx b/algo/ca/TrackingChain.cxx
index c960c0f3c3..7c2f7679c2 100644
--- a/algo/ca/TrackingChain.cxx
+++ b/algo/ca/TrackingChain.cxx
@@ -13,7 +13,6 @@
 #include "CaHit.h"
 #include "CaInitManager.h"
 #include "CaParameters.h"
-#include "tof/Config.h"
 #include "yaml/Yaml.h"
 
 #include <boost/archive/binary_oarchive.hpp>
@@ -50,6 +49,10 @@ TrackingChain::TrackingChain(std::shared_ptr<HistogramSender> histoSender)
 //
 void TrackingChain::Init()
 {
+  // ------ Initialize setup interface
+  fSetup.SetContext(this->GetContext());
+  fSetup.Init();
+
   // ------ Read tracking chain parameters from the config
   fConfig = yaml::ReadFromFile<TrackingChainConfig>(Opts().ParamsDir() / "TrackingChainConfig.yaml");
 
@@ -252,7 +255,7 @@ void TrackingChain::ReadHits(PartitionedSpan<const ca::HitTypes_t::at<DetID>> hi
       iStLocal = (extHitAddress >> 4) & 0xF;
     }
     if constexpr (IsTof) {
-      iStLocal = cbm::algo::tof::Config::GetTofTrackingStation(extHitAddress);
+      iStLocal = fSetup.GetTrackingStation<DetID>(extHitAddress);
       if (tof::Config::IsBmon(extHitAddress)) {
         continue;
       }  // skip hits from Bmon
diff --git a/algo/ca/TrackingChain.h b/algo/ca/TrackingChain.h
index 9adc9528da..6f04c432c9 100644
--- a/algo/ca/TrackingChain.h
+++ b/algo/ca/TrackingChain.h
@@ -19,6 +19,7 @@
 #include "HistogramSender.h"
 #include "PartitionedSpan.h"
 #include "RecoResults.h"
+#include "SetupInterface.h"
 #include "SubChain.h"
 #include "TrackingChainConfig.h"
 #include "TrackingDefs.h"
@@ -107,6 +108,8 @@ namespace cbm::algo
     ca::InputQa fInputQa;    ///< CA input QA builder
     ca::OutputQa fOutputQa;  ///< CA output QA builder
 
+    SetupInterface fSetup;  ///< setup interface
+
     // ************************
     // **  Auxilary variables
 
diff --git a/algo/detectors/tof/Config.h b/algo/detectors/tof/Config.h
deleted file mode 100644
index 36ccae9b99..0000000000
--- a/algo/detectors/tof/Config.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
-   SPDX-License-Identifier: GPL-3.0-only
-   Authors: Dominik Smith [committer] */
-
-#ifndef CBM_ALGO_TOF_CONFIG
-#define CBM_ALGO_TOF_CONFIG 1
-
-#include "CbmTofAddress.h"
-
-#include <cstdint>
-
-namespace cbm::algo::tof
-{
-  /** @class Config
-   ** @author Dominik Smith <d.smith@gsi.de>
-   ** @since 2022
-   ** @brief
-   **
-   **/
-  class Config {
-
-   public:
-    /// @brief Function to get tracking station index by the TOF address
-    static int32_t GetTofTrackingStation(uint32_t address)
-    {
-      return GetTofTrackingStation(CbmTofAddress::GetSmType(address), CbmTofAddress::GetSmId(address),
-                                   CbmTofAddress::GetRpcId(address));
-    }
-
-    static bool IsBmon(uint32_t address) { return 5 == CbmTofAddress::GetSmType(address); }
-
-    static int32_t GetTofTrackingStation(const uint32_t smType, const uint32_t sm, const uint32_t rpc)
-    {
-      const uint8_t numSmTypes                 = 10;
-      const uint8_t numRpc[numSmTypes]         = {5, 3, 5, 1, 1, 1, 2, 2, 1, 2};
-      const uint8_t numSm[numSmTypes]          = {5, 0, 1, 0, 0, 1, 1, 1, 2, 1};
-      const uint8_t trkStation[numSmTypes][25] = {
-        {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3},
-        {0, 0, 0, 0, 0},
-        {2, 2, 2, 2, 2},
-        {0, 0, 0, 0, 0},
-        {0, 0, 0, 0, 0},
-        {0, 0, 0, 0, 0},
-        {1, 1, 0, 0, 0},
-        {1, 1, 0, 0, 0},
-        {0, 0, 0, 0, 0},
-        {2, 2, 2, 2, 0}};
-
-      if (smType < numSmTypes) {
-        if (sm < numSm[smType] && rpc < numRpc[smType])
-          return trkStation[smType][sm * numRpc[smType] + rpc];
-        else
-          return 0;
-      }
-      else
-        return 0;
-    }
-  };
-}  // namespace cbm::algo::tof
-
-#endif /* CBM_ALGO_TOF_CONFIG */
diff --git a/algo/detectors/tof/HitfindSetup.h b/algo/detectors/tof/HitfindSetup.h
index 103166bca8..ebbdad71b8 100644
--- a/algo/detectors/tof/HitfindSetup.h
+++ b/algo/detectors/tof/HitfindSetup.h
@@ -47,6 +47,7 @@ namespace cbm::algo::tof
       double sigVel;
       double timeRes;
       Cell cell;
+      int trackingStationId;
       double CPTOffYBinWidth;
       double CPTOffYRange;
       std::vector<double> CPTOffY;
@@ -59,6 +60,7 @@ namespace cbm::algo::tof
                         yaml::Property(&Rpc::sigVel, "sigVel", "signal velocity"),
                         yaml::Property(&Rpc::timeRes, "timeRes", "time resolution"),
                         yaml::Property(&Rpc::cell, "cell", "cell parameters"),
+                        yaml::Property(&Rpc::trackingStationId, "trackingStationId", "tracking station index"),
                         yaml::Property(&Rpc::CPTOffYBinWidth, "CPTOffYBinWidth", "CPT Y offset bin width"),
                         yaml::Property(&Rpc::CPTOffYRange, "CPTOffYRange", "CPT Y offset range"),
                         yaml::Property(&Rpc::CPTOffY, "CPTOffY", "CPT Y offset array"),
diff --git a/algo/detectors/tof/TrackingInterface.cxx b/algo/detectors/tof/TrackingInterface.cxx
new file mode 100644
index 0000000000..a669b2dcca
--- /dev/null
+++ b/algo/detectors/tof/TrackingInterface.cxx
@@ -0,0 +1,62 @@
+/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   TrackingInterface.cxx
+/// \date   19.04.2024
+/// \brief  A TOF-parameter and geometry interface used for tracking input data initialization (source)
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#include "TrackingInterface.h"
+
+#include "CbmTofAddress.h"
+#include "HitfindSetup.h"
+#include "fmt/format.h"
+#include "log.hpp"
+
+using cbm::algo::tof::HitfindSetup;
+using cbm::algo::tof::TrackingInterface;
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void TrackingInterface::Init()
+{
+  // Read NbSm, NbRpc and tracking station ids from the config
+  auto setup = yaml::ReadFromFile<HitfindSetup>(Opts().ParamsDir() / "TofHitfinderPar.yaml");
+  fvNofSm    = std::move(setup.NbSm);
+  fvNofRpc   = std::move(setup.NbRpc);
+  assert(fvNofSm.size() == fvNofRpc.size());
+  int nSmTypes = fvNofSm.size();
+  fvTrackingStationId.resize(nSmTypes);
+  for (int iSmType = 0; iSmType < nSmTypes; ++iSmType) {
+    int nSm        = fvNofSm[iSmType];
+    int nRpc       = fvNofRpc[iSmType];
+    auto& vStaIds  = fvTrackingStationId[iSmType];
+    auto& vRpcPars = setup.rpcs[iSmType];
+    vStaIds.resize(nSm * nRpc);
+    for (int iSm = 0; iSm < nSm; ++iSm) {
+      for (int iRpc = 0; iRpc < nRpc; ++iRpc) {
+        int iGlobRpc      = iSm * nRpc + iRpc;
+        vStaIds[iGlobRpc] = vRpcPars[iGlobRpc].trackingStationId;
+      }
+    }
+  }
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+int TrackingInterface::GetTrackingStation(uint32_t address) const
+{
+  int iSmType = CbmTofAddress::GetSmType(address);
+  int iSm     = CbmTofAddress::GetSmId(address);
+  int iRpc    = CbmTofAddress::GetRpcId(address);
+  if (iSmType < fvNofSm.size()) {
+    if (iSm < fvNofSm[iSmType] && iRpc < fvNofRpc[iSmType]) {
+      return fvTrackingStationId[iSmType][iSm * fvNofRpc[iSmType] + iRpc];
+    }
+  }
+
+  L_(error) << "Undefined RPC address " << fmt::format("{#x}", address) << " (iSmType = " << iSmType
+            << ", iSm = " << iSm << ", iRpc = " << iRpc << ')';
+  return -1;  // iSmType, iSm or iRpc are out of range
+}
diff --git a/algo/detectors/tof/TrackingInterface.h b/algo/detectors/tof/TrackingInterface.h
new file mode 100644
index 0000000000..c6ce0f937b
--- /dev/null
+++ b/algo/detectors/tof/TrackingInterface.h
@@ -0,0 +1,43 @@
+/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   TrackingInterface.h
+/// \date   19.04.2024
+/// \brief  A TOF-parameter and geometry interface used for tracking input data initialization (header)
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#pragma once
+
+#include "SubChain.h"
+
+namespace cbm::algo::tof
+{
+  class TrackingInterface : public SubChain {
+   public:
+    /// \brief Default constructor
+    TrackingInterface() = default;
+
+    /// \brief Copy constructor
+    TrackingInterface(const TrackingInterface&) = delete;
+
+    /// \brief Move constructor
+    TrackingInterface(TrackingInterface&&) = delete;
+
+    /// \brief Destructor
+    ~TrackingInterface() = default;
+
+    /// \brief Initializer function
+    void Init();
+
+    /// \brief   Returns tracking station index by the TOF address
+    /// \param   address  Unique address of a TOF element
+    /// \return  Local index of tracking station
+    int GetTrackingStation(uint32_t address) const;
+
+   private:
+    std::vector<int> fvNofRpc;                          ///< Number of RPCs [NbSmt]
+    std::vector<int> fvNofSm;                           ///< Number of super modules [NbSmt]
+    std::vector<std::vector<int>> fvTrackingStationId;  ///< Index of tracking station [NbSmt][NbSm * NbRpc]
+  };
+}  // namespace cbm::algo::tof
diff --git a/reco/tasks/CbmTaskTofClusterizerParWrite.cxx b/reco/tasks/CbmTaskTofClusterizerParWrite.cxx
index 95d273af30..ee6a4448aa 100644
--- a/reco/tasks/CbmTaskTofClusterizerParWrite.cxx
+++ b/reco/tasks/CbmTaskTofClusterizerParWrite.cxx
@@ -472,6 +472,7 @@ bool CbmTaskTofClusterizerParWrite::InitAlgos()
         par.maxSpaceDist       = fdMaxSpaceDist;
         par.sigVel             = fDigiBdfPar->GetSigVel(iSmType, iSm, iRpc);
         par.timeRes            = 0.08;
+        par.trackingStationId  = fDigiBdfPar->GetTrackingStation(iSmType, iSm, iRpc);
         par.CPTOffYBinWidth    = fvCPTOffYBinWidth[iSmType][iSm * iNbRpc + iRpc];
         par.CPTOffY            = fvCPTOffY[iSmType][iSm * iNbRpc + iRpc];
         par.CPTOffYRange       = fvCPTOffYRange[iSmType][iSm * iNbRpc + iRpc];
-- 
GitLab