From 30c60e3e066c33231b34533544f33d0cc5af7f17 Mon Sep 17 00:00:00 2001
From: P-A Loizeau <p.-a.loizeau@gsi.de>
Date: Mon, 19 Jul 2021 22:30:03 +0200
Subject: [PATCH] Add building of the channel address map to the Tof Par class
 + cleanup

---
 core/detectors/tof/CbmMcbm2018TofPar.cxx | 334 +++++++++++++++++++++++
 core/detectors/tof/CbmMcbm2018TofPar.h   |  11 +
 2 files changed, 345 insertions(+)

diff --git a/core/detectors/tof/CbmMcbm2018TofPar.cxx b/core/detectors/tof/CbmMcbm2018TofPar.cxx
index 4fbb4484a5..145ab9684d 100644
--- a/core/detectors/tof/CbmMcbm2018TofPar.cxx
+++ b/core/detectors/tof/CbmMcbm2018TofPar.cxx
@@ -17,6 +17,8 @@
 #include "TString.h"
 
 #include "gDpbMessv100.h"
+#include "CbmTofAddress.h"
+#include "CbmTofDetectorId_v14a.h"  // in cbmdata/tof
 
 // -----   Standard constructor   ------------------------------------------
 CbmMcbm2018TofPar::CbmMcbm2018TofPar(const char* name, const char* title, const char* context)
@@ -144,6 +146,8 @@ Bool_t CbmMcbm2018TofPar::getParams(FairParamList* l)
   if (!l->fill("StarTriggerWinSize", &fdStarTriggerWinSize)) return kFALSE;
   if (!l->fill("TsDeadtimePeriod", &fdTsDeadtimePeriod)) return kFALSE;
 
+  BuildChannelsUidMap();
+
   return kTRUE;
 }
 // -------------------------------------------------------------------------
@@ -199,6 +203,336 @@ Double_t CbmMcbm2018TofPar::GetPadiThresholdVal(UInt_t uCode)
   }  // else of if( uCode < GetNrOfPadiThrCodes() )
 }
 // -------------------------------------------------------------------------
+void CbmMcbm2018TofPar::BuildChannelsUidMap()
+{
+  UInt_t uNrOfGbtx = fiNrOfGbtx;
+  UInt_t uNrOfGet4 = fiNrOfGdpb * fiNrOfFeesPerGdpb * fiNrOfGet4PerFee;
+  UInt_t uNrOfChannels = uNrOfGet4 * fiNrOfChannelsPerGet4;
+  fviRpcChUId.resize(uNrOfChannels);
+
+  UInt_t uCh = 0;
+  for (UInt_t uGbtx = 0; uGbtx < uNrOfGbtx; ++uGbtx) {
+    switch (fiRpcType[uGbtx]) {
+      case 0: {
+        // CBM modules
+        BuildChannelsUidMapCbm(uCh, uGbtx);
+        break;
+      }
+      case 1: {
+        // STAR eTOF  modules
+        BuildChannelsUidMapStar(uCh, uGbtx);
+        break;
+      }
+      case 5: {
+        /// Special Treatment for the T0 diamond
+        BuildChannelsUidMapT0(uCh, uGbtx);
+        break;
+      }
+      case 78: {
+        // cern-20-gap + ceramic module
+        BuildChannelsUidMapCern(uCh, uGbtx);
+      }
+        [[fallthrough]];  // fall through is intended
+      case 8:             // ceramics
+      {
+        BuildChannelsUidMapCera(uCh, uGbtx);
+        break;
+      }
+      case 4:  // intended fallthrough
+        [[fallthrough]];
+      case 9:  // Star2 boxes
+      {
+        BuildChannelsUidMapStar2(uCh, uGbtx);
+        break;
+      }
+      case 6:  // Buc box
+      {
+        BuildChannelsUidMapBuc(uCh, uGbtx);
+        break;
+      }
+      case -1: {
+        LOG(info) << " Found unused GBTX link at uCh = " << uCh;
+        uCh += 160;
+        break;
+      }
+      default: {
+        LOG(error) << "Invalid Tof Type  specifier ";
+      }
+    } // switch (fiRpcType[uGbtx])
+  } // for (UInt_t uGbtx = 0; uGbtx < uNrOfGbtx; ++uGbtx)
+
+}
+// -------------------------------------------------------------------------
+void CbmMcbm2018TofPar::BuildChannelsUidMapCbm(UInt_t & uCh, UInt_t uGbtx)
+{
+  if (fiRpcSide[uGbtx] < 2) {  // mTof modules
+    LOG(info) << " Map mTof box " << fiModuleId[uGbtx] << " at GBTX  -  uCh = " << uCh;
+    const Int_t RpcMap[5] = {4, 2, 0, 3, 1};
+    for (Int_t iRpc = 0; iRpc < fiNrOfRpc[uGbtx]; iRpc++) {
+      Int_t iStrMax = 32;
+      UInt_t uChNext = 1;
+
+      for (Int_t iStr = 0; iStr < iStrMax; iStr++) {
+        Int_t iStrMap = iStr;
+        Int_t iRpcMap = RpcMap[iRpc];
+
+        if (fiRpcSide[uGbtx] == 0) iStrMap = 31 - iStr;
+        if (fiModuleId[uGbtx] > -1)
+          fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], iRpcMap, iStrMap,
+                                                             fiRpcSide[uGbtx], fiRpcType[uGbtx]);
+        else
+          fviRpcChUId[uCh] = 0;
+        //  LOG(debug)<<Form("Map Ch %d to Address 0x%08x",uCh,fviRpcChUId[uCh]);
+        uCh += uChNext;
+      } // for (Int_t iStr = 0; iStr < iStrMax; iStr++)
+    } // for (Int_t iRpc = 0; iRpc < fiNrOfRpc[uGbtx]; iRpc++)
+  } // if (fiRpcSide[uGbtx] < 2)
+}
+// -------------------------------------------------------------------------
+void CbmMcbm2018TofPar::BuildChannelsUidMapStar(UInt_t & uCh, UInt_t uGbtx)
+{
+  if (fiRpcSide[uGbtx] < 2) {
+    // mTof modules
+    LOG(info) << "Start eTOF module side " << fiRpcSide[uGbtx] << " at " << uCh;
+    const Int_t RpcMap[3] = {0, 1, 2};
+    for (Int_t iRpc = 0; iRpc < fiNrOfRpc[uGbtx]; iRpc++) {
+      Int_t iStrMax = 32;
+      Int_t uChNext = 1;
+
+      for (Int_t iStr = 0; iStr < iStrMax; iStr++) {
+        Int_t iStrMap = iStr;
+        Int_t iRpcMap = RpcMap[iRpc];
+
+        if (fiRpcSide[uGbtx] == 0) iStrMap = 31 - iStr;
+        if (fiModuleId[uGbtx] > -1)
+          fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], iRpcMap, iStrMap,
+                                                             fiRpcSide[uGbtx], fiRpcType[uGbtx]);
+        else
+          fviRpcChUId[uCh] = 0;
+        //  LOG(DEBUG)<<Form("Map Ch %d to Address 0x%08x",uCh,fviRpcChUId[uCh]);
+        uCh += uChNext;
+      }
+    }
+  }
+  uCh += 64;
+}
+// -------------------------------------------------------------------------
+void CbmMcbm2018TofPar::BuildChannelsUidMapT0(UInt_t & uCh, UInt_t uGbtx)
+{
+  LOG(info) << " Map diamond  at GBTX  -  uCh = " << uCh;
+  for (UInt_t uFee = 0; uFee < kuNbFeePerGbtx; ++uFee) {
+    for (UInt_t uFeeCh = 0; uFeeCh < kuNbChannelsPerFee; ++uFeeCh) {
+      /// Mapping for the 2019 beamtime
+      if (0 == uFee && 1 == fiNrOfRpc[uGbtx]) {
+        switch (uCh % 8) {
+          case 0:
+          case 2:
+          case 4: {
+            /// 2019 mapping with 320/640 Mb/s FW
+            /// => 4 GET4 per GBTx
+            /// => 1 T0 channel per GET4
+            /// => 1-2 eLinks per GET4 => GET4 ID = GET4 * 2 (+ 1)
+            UInt_t uChannelT0 = uFeeCh / 8 + 4 * fiRpcSide[uGbtx];
+            fviRpcChUId[uCh] =
+              CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], 0, uChannelT0, 0, fiRpcType[uGbtx]);
+            LOG(info) << Form("T0 channel: %u from GBTx %2u Fee %2u "
+                              "Channel %2u, indx %d address %08x",
+                              uChannelT0, uGbtx, uFeeCh, uCh, uCh, fviRpcChUId[uCh]);
+            break;
+          }  // Valid T0 channel
+          default: {
+            fviRpcChUId[uCh] = 0;
+          }  // Invalid T0 channel
+        }    // switch( uCh % 4 )
+      }      // if( 0 == uFee )
+
+      uCh++;
+    }  // for( UInt_t uCh = 0; uCh < kuNbFeePerGbtx; ++uCh )
+  }    // for( UInt_t uFee = 0; uFee < kuNbChannelsPerFee; ++uFee )
+}
+// -------------------------------------------------------------------------
+void CbmMcbm2018TofPar::BuildChannelsUidMapCern(UInt_t & uCh, UInt_t /*uGbtx*/)
+{
+  LOG(info) << " Map CERN 20 gap  at GBTX  -  uCh = " << uCh;
+  // clang-format off
+  const Int_t StrMap[32] = {0,  1,  2,  3,  4,  31, 5,  6,  7,  30, 8,
+                            9,  10, 29, 11, 12, 13, 14, 28, 15, 16, 17,
+                            18, 27, 26, 25, 24, 23, 22, 21, 20, 19};
+  // clang-format on
+  Int_t iModuleId   = 0;
+  Int_t iModuleType = 7;
+  Int_t iRpcMap     = 0;
+  for (Int_t iFeet = 0; iFeet < 2; iFeet++) {
+    for (Int_t iStr = 0; iStr < 32; iStr++) {
+      Int_t iStrMap  = 31 - 12 - StrMap[iStr];
+      Int_t iSideMap = iFeet;
+      if (iStrMap < 20)
+        fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(iModuleId, iRpcMap, iStrMap, iSideMap, iModuleType);
+      else
+        fviRpcChUId[uCh] = 0;
+      uCh++;
+    }
+  }
+  LOG(info) << " Map end CERN 20 gap  at GBTX  -  uCh = " << uCh;
+}
+// -------------------------------------------------------------------------
+void CbmMcbm2018TofPar::BuildChannelsUidMapCera(UInt_t & uCh, UInt_t /*uGbtx*/)
+{
+  Int_t iModuleId   = 0;
+  Int_t iModuleType = 8;
+  for (Int_t iRpc = 0; iRpc < 8; iRpc++) {
+    fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(iModuleId, 7 - iRpc, 0, 0, iModuleType);
+    uCh++;
+  }
+  uCh += (24 + 2 * 32);
+  LOG(info) << " Map end ceramics  box  at GBTX  -  uCh = " << uCh;
+}
+// -------------------------------------------------------------------------
+void CbmMcbm2018TofPar::BuildChannelsUidMapStar2(UInt_t & uCh, UInt_t uGbtx)
+{
+  LOG(info) << " Map Star2 box " << fiModuleId[uGbtx] << " at GBTX  -  uCh = " << uCh;
+  const Int_t iRpc[5]  = {1, -1, 1, 0, 0};
+  const Int_t iSide[5] = {1, -1, 0, 1, 0};
+  for (Int_t iFeet = 0; iFeet < 5; iFeet++) {
+    for (Int_t iStr = 0; iStr < 32; iStr++) {
+      Int_t iStrMap  = iStr;
+      Int_t iRpcMap  = iRpc[iFeet];
+      Int_t iSideMap = iSide[iFeet];
+      if (iSideMap == 0) iStrMap = 31 - iStr;
+      switch (fiRpcSide[uGbtx]) {
+        case 0:; break;
+        case 1:;
+          iRpcMap = 1 - iRpcMap;  // swap counters
+          break;
+        case 2:
+          switch (iFeet) {
+            case 1:
+              iRpcMap  = iRpc[4];
+              iSideMap = iSide[4];
+              iStrMap  = 31 - iStrMap;
+              break;
+            case 4:
+              iRpcMap  = iRpc[1];
+              iSideMap = iSide[1];
+              break;
+            default:;
+          }
+          break;
+      }
+      if (iSideMap > -1)
+        fviRpcChUId[uCh] =
+          CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], iRpcMap, iStrMap, iSideMap, fiRpcType[uGbtx]);
+      else
+        fviRpcChUId[uCh] = 0;
+      uCh++;
+    }
+  }
+}
+// -------------------------------------------------------------------------
+void CbmMcbm2018TofPar::BuildChannelsUidMapBuc(UInt_t & uCh, UInt_t uGbtx)
+{
+  LOG(info) << " Map Buc box  at GBTX  -  uCh = " << uCh;
+
+  Int_t iModuleIdMap = fiModuleId[uGbtx];
+  const Int_t iRpc[5]  = {0, -1, 0, 1, 1};
+  const Int_t iSide[5] = {1, -1, 0, 1, 0};
+  for (Int_t iFeet = 0; iFeet < 5; iFeet++) {
+    for (Int_t iStr = 0; iStr < 32; iStr++) {
+      Int_t iStrMap  = iStr;
+      Int_t iRpcMap  = iRpc[iFeet];
+      Int_t iSideMap = iSide[iFeet];
+      switch (fiRpcSide[uGbtx]) {
+        case 0:; break;
+        case 1:  // HD cosmic 2019, Buc2018, v18n
+          iStrMap = 31 - iStr;
+          iRpcMap = 1 - iRpcMap;
+          break;
+        case 2:  // v18m_cosmicHD
+          //   iStrMap=31-iStr;
+          iSideMap = 1 - iSideMap;
+          break;
+        case 3:
+          iStrMap  = 31 - iStr;
+          iRpcMap  = 1 - iRpcMap;
+          iSideMap = 1 - iSideMap;
+          break;
+        case 4:  // HD cosmic 2019, Buc2018, v18o
+          iRpcMap = 1 - iRpcMap;
+          break;
+        case 5:  // HD cosmic 2020, Buc2018, v20a
+          iStrMap = 31 - iStr;
+          break;
+        case 6:  //BUC special
+        {
+          switch (fiModuleId[uGbtx]) {
+            case 0: iRpcMap = 0; break;
+            case 1: iRpcMap = 1; break;
+          }
+          if (iFeet % 2 == 1) iModuleIdMap = 1;
+          else
+            iModuleIdMap = 0;
+
+          switch (iFeet) {
+            case 0:
+            case 3: iSideMap = 0; break;
+            case 1:
+            case 2: iSideMap = 1; break;
+          }
+        } break;
+
+        case 7: {
+          // clang-format off
+          const Int_t iChMap[160]={
+          127, 126, 125, 124,  12,  13,  14,  15,   7,   6,   5,   4,  28,  29,  30,  31, 123, 122, 121, 120,   8,   9,  10,  11, 107, 106, 105, 104, 108, 109, 110, 111,
+           39,  38,  37,  36,  52,  53,  54,  55,  63,  62,  61,  60, 128, 129, 130, 131,  43,  42,  41,  40, 148, 149, 150, 151,  59,  58,  57,  56, 132, 133, 134, 135,
+          139, 138, 137, 136, 140, 141, 142, 143,  99,  98,  97,  96,  64,  65,  66,  67, 103, 102, 101, 100,  84,  85,  86,  87, 155, 154, 153, 152,  68,  69,  70,  71,
+          159, 158, 157, 156, 144, 145, 146, 147,  47,  46,  45,  44,  76,  77,  78,  79,  51,  50,  49,  48,  20,  21,  22,  23,  35,  34,  33,  32, 116, 117, 118, 119,
+           75,  74,  73,  72,  92,  93,  94,  95,  19,  18,  17,  16,  80,  81,  82,  83, 115, 114, 113, 112,  24,  25,  26,  27,  91,  90,  89,  88,   0,   1,   2,   3
+          };
+          // clang-format on
+          Int_t iInd = iFeet * 32 + iStr;
+          Int_t i    = 0;
+          for (; i < 160; i++)
+            if (iInd == iChMap[i]) break;
+          iStrMap        = i % 32;
+          Int_t iFeetInd = (i - iStrMap) / 32;
+          switch (iFeet) {
+            case 0:
+              iRpcMap  = 0;
+              iSideMap = 1;
+              break;
+            case 1:
+              iRpcMap  = 1;
+              iSideMap = 1;
+              break;
+            case 2:
+              iRpcMap  = 0;
+              iSideMap = 0;
+              break;
+            case 3:
+              iRpcMap  = 1;
+              iSideMap = 0;
+              break;
+            case 4: iSideMap = -1; break;
+          }
+          iModuleIdMap = fiModuleId[uGbtx];
+          LOG(info) << "Buc of GBTX " << uGbtx << " Ch " << uCh
+                    << Form(", Feet %1d, Str %2d, Ind %3d, i %3d, FeetInd %1d, Rpc %1d, Side %1d, Str %2d ",
+                            iFeet, iStr, iInd, i, iFeetInd, iRpcMap, iSideMap, iStrMap);
+        } break;
+        default:;
+      } // switch (fiRpcSide[uGbtx])
+      if (iSideMap > -1)
+        fviRpcChUId[uCh] =
+          CbmTofAddress::GetUniqueAddress(iModuleIdMap, iRpcMap, iStrMap, iSideMap, fiRpcType[uGbtx]);
+      else
+        fviRpcChUId[uCh] = 0;
+
+      uCh++;
+    } // for (Int_t iStr = 0; iStr < 32; iStr++)
+  } // for (Int_t iFeet = 0; iFeet < 5; iFeet++)
+}
+// -------------------------------------------------------------------------
 
 
 ClassImp(CbmMcbm2018TofPar)
diff --git a/core/detectors/tof/CbmMcbm2018TofPar.h b/core/detectors/tof/CbmMcbm2018TofPar.h
index 6295603e1c..6657d5224c 100644
--- a/core/detectors/tof/CbmMcbm2018TofPar.h
+++ b/core/detectors/tof/CbmMcbm2018TofPar.h
@@ -72,6 +72,7 @@ public:
   inline Int_t GetRpcType(Int_t i) { return fiRpcType[i]; }
   inline Int_t GetRpcSide(Int_t i) { return fiRpcSide[i]; }
   inline Int_t GetModuleId(Int_t i) { return fiModuleId[i]; }
+  inline std::vector< Int_t > GetRpcChUidMap() { return fviRpcChUId; }
 
   inline Int_t GetNbMsTot() { return fiNbMsTot; }
   inline Int_t GetNbMsOverlap() { return fiNbMsOverlap; }
@@ -83,6 +84,15 @@ public:
   inline Double_t GetTsDeadtimePeriod() { return fdTsDeadtimePeriod; }
 
 private:
+  void BuildChannelsUidMap();
+  void BuildChannelsUidMapCbm(UInt_t & uCh, UInt_t uGbtx);
+  void BuildChannelsUidMapStar(UInt_t & uCh, UInt_t uGbtx);
+  void BuildChannelsUidMapT0(UInt_t & uCh, UInt_t uGbtx);
+  void BuildChannelsUidMapCern(UInt_t & uCh, UInt_t uGbtx);
+  void BuildChannelsUidMapCera(UInt_t & uCh, UInt_t uGbtx);
+  void BuildChannelsUidMapStar2(UInt_t & uCh, UInt_t uGbtx);
+  void BuildChannelsUidMapBuc(UInt_t & uCh, UInt_t uGbtx);
+
   /// Constants
   /// Data format
   static const uint32_t kuBytesPerMessage = 8;
@@ -142,6 +152,7 @@ private:
   TArrayI fiRpcType;   // type of Rpcs connected to Gbtx link
   TArrayI fiRpcSide;   // side of Rpcs connected to Gbtx link, i.e. 0 or 1
   TArrayI fiModuleId;  // Module Identifier connected to Gbtx link, has to match geometry
+  std::vector<Int_t> fviRpcChUId = {};  // UID/address for each channel, build from type, side and module
 
   Int_t fiNbMsTot;        // Total number of MS per link in TS
   Int_t fiNbMsOverlap;    // Number of overlap MS per TS
-- 
GitLab