From 819c026f64ecbb74fbd3c378f08186e7e80e9a5e Mon Sep 17 00:00:00 2001
From: Alexandru Bercuci <abercuci@niham.nipne.ro>
Date: Fri, 20 May 2022 19:12:48 +0300
Subject: [PATCH] add support for multiple CRI boards in the TRD2D detectors

---
 core/detectors/trd/CbmTrdParFasp.h            |  2 ++
 macro/run/run_unpack_online.C                 | 27 +++++++++++++---
 macro/run/run_unpack_tsa.C                    | 27 +++++++++++++---
 .../trd/unpack/CbmTrdUnpackFaspAlgo.cxx       | 32 +++++++++++++++----
 .../trd/unpack/CbmTrdUnpackFaspAlgo.h         | 11 +++++--
 .../trd/unpack/CbmTrdUnpackFaspConfig.cxx     |  7 ++++
 .../trd/unpack/CbmTrdUnpackFaspConfig.h       |  8 ++++-
 7 files changed, 93 insertions(+), 21 deletions(-)

diff --git a/core/detectors/trd/CbmTrdParFasp.h b/core/detectors/trd/CbmTrdParFasp.h
index 8648992d7b..6a5a0320d3 100644
--- a/core/detectors/trd/CbmTrdParFasp.h
+++ b/core/detectors/trd/CbmTrdParFasp.h
@@ -6,6 +6,8 @@
 #define CBMTRDPARFASP_H
 
 #define NFASPMOD 180
+#define NCRIMOD 5
+#define NFASPCRI NFASPMOD / NCRIMOD
 #define NFASPCH 16
 
 #include "CbmTrdParAsic.h"  // for CbmTrdParAsic
diff --git a/macro/run/run_unpack_online.C b/macro/run/run_unpack_online.C
index 986bb3b6bd..7ca3a48f11 100644
--- a/macro/run/run_unpack_online.C
+++ b/macro/run/run_unpack_online.C
@@ -254,15 +254,32 @@ void run_unpack_online(std::vector<std::string> publisher = {"tcp://localhost:55
     // Activate the line below to write Trd1D digis to a separate "TrdFaspDigi" branch. Can be used to separate between Fasp and Spadic digis
     //trdfasp2dconfig->SetOutputBranchName("TrdFaspDigi");
     uint8_t map[NFASPMOD];
+    uint16_t cri_map[NCRIMOD];
+    for (int i(0); i < NFASPMOD; i++)
+      map[i] = i;
     if (runid <= 1588) {
+      const size_t nfasps = 12;
       uint8_t map21[] = {9, 2, 3, 11, 10, 7, 8, 0, 1, 4, 6, 5};
-      for (int i(0); i < NFASPMOD; i++)
-        map[i] = (i < 12 ? map21[i] : i);
+      for (int i(0); i < nfasps; i++)
+        map[i] = map21[i];
+    }
+    else if (runid >= 2335) {
+      const size_t nfasp0 = 72;
+      const size_t nfasps = 36;
+      uint8_t map22[]     = {
+        96,  97,  98,  99,  100, 101,  // FEB9/0xffc1
+        102, 103, 104, 105, 106, 107,  // FEB8/0xffc1
+        72,  73,  74,  75,  76,  77,   // FEB14/0xffc1
+        78,  79,  80,  81,  82,  83,   // FEB17/0xffc1
+        84,  85,  86,  87,  88,  89,   // FEB18/0xffc1
+        90,  91,  92,  93,  94,  95    // FEB16/0xffc1
+      };
+      for (int i(0); i < nfasps; i++)
+        map[i + nfasp0] = map22[i];
+      cri_map[0] = {0xffc2, 0xffc5, 0xffc1, 0, 0};
     }
-    else
-      for (int i(0); i < NFASPMOD; i++)
-        map[i] = i;
     trdfasp2dconfig->SetFaspMapping(5, map);
+    trdfasp2dconfig->SetCriMapping(5, cri_map);
     std::string parfilesbasepathTrdfasp2d = Form("%s/parameters/trd", srcDir.Data());
     trdfasp2dconfig->SetParFilesBasePath(parfilesbasepathTrdfasp2d);
     trdfasp2dconfig->SetSystemTimeOffset(-1800);  // [ns] value to be updated
diff --git a/macro/run/run_unpack_tsa.C b/macro/run/run_unpack_tsa.C
index faed834f2d..10d1287d5d 100644
--- a/macro/run/run_unpack_tsa.C
+++ b/macro/run/run_unpack_tsa.C
@@ -282,15 +282,32 @@ void run_unpack_tsa(std::vector<std::string> infile = {"test.tsa"}, UInt_t runid
     // Activate the line below to write Trd1D digis to a separate "TrdFaspDigi" branch. Can be used to separate between Fasp and Spadic digis
     // trdfasp2dconfig->SetOutputBranchName("TrdFaspDigi");
     uint8_t map[NFASPMOD];
+    uint16_t cri_map[NCRIMOD];
+    for (int i(0); i < NFASPMOD; i++)
+      map[i] = i;
     if (runid <= 1588) {
+      const size_t nfasps = 12;
       uint8_t map21[] = {9, 2, 3, 11, 10, 7, 8, 0, 1, 4, 6, 5};
-      for (int i(0); i < NFASPMOD; i++)
-        map[i] = (i < 12 ? map21[i] : i);
+      for (int i(0); i < nfasps; i++)
+        map[i] = map21[i];
+    }
+    else if (runid >= 2335) {
+      const size_t nfasp0 = 72;
+      const size_t nfasps = 36;
+      uint8_t map22[]     = {
+        96,  97,  98,  99,  100, 101,  // FEB9/0xffc1
+        102, 103, 104, 105, 106, 107,  // FEB8/0xffc1
+        72,  73,  74,  75,  76,  77,   // FEB14/0xffc1
+        78,  79,  80,  81,  82,  83,   // FEB17/0xffc1
+        84,  85,  86,  87,  88,  89,   // FEB18/0xffc1
+        90,  91,  92,  93,  94,  95    // FEB16/0xffc1
+      };
+      for (int i(0); i < nfasps; i++)
+        map[i + nfasp0] = map22[i];
+      cri_map[0] = {0xffc2, 0xffc5, 0xffc1, 0, 0};
     }
-    else
-      for (int i(0); i < NFASPMOD; i++)
-        map[i] = i;
     trdfasp2dconfig->SetFaspMapping(5, map);
+    trdfasp2dconfig->SetCriMapping(5, cri_map);
     std::string parfilesbasepathTrdfasp2d = Form("%s/parameters/trd", srcDir.Data());
     trdfasp2dconfig->SetParFilesBasePath(parfilesbasepathTrdfasp2d);
     trdfasp2dconfig->SetSystemTimeOffset(-1800);  // [ns] value to be updated
diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx
index d245ff7670..ebb8260582 100644
--- a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx
+++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.cxx
@@ -127,6 +127,13 @@ void CbmTrdUnpackFaspAlgo::SetAsicMapping(const std::map<uint32_t, uint8_t[NFASP
   }
 }
 
+//_________________________________________________________________________________
+void CbmTrdUnpackFaspAlgo::SetCriMapping(const std::map<uint32_t, uint16_t[NCRIMOD]>& map)
+{
+  if (fCriMap) delete fCriMap;
+  fCriMap = new std::map<uint32_t, uint16_t[NCRIMOD]>(map);
+}
+
 //_________________________________________________________________________________
 void CbmTrdUnpackFaspAlgo::PrintAsicMapping()
 {
@@ -214,13 +221,13 @@ bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFas
     if (lFasp == 0xff) {
       lFasp = messes[0]->fasp;
       // link data to the position on the padplane
-      if (!(faspPar = (CbmTrdParFasp*) fAsicPar.GetAsicPar(imess->cri * 1000 + lFasp))) {
-        LOG(error) << GetName() << "::pushDigis - Par for FASP " << (int) lFasp << " in module " << imess->cri
+      if (!(faspPar = (CbmTrdParFasp*) fAsicPar.GetAsicPar(imess->mod * 1000 + lFasp))) {
+        LOG(error) << GetName() << "::pushDigis - Par for FASP " << (int) lFasp << " in module " << imess->mod
                    << " missing. Skip.";
         return false;
       }
-      if (!(digiPar = (CbmTrdParModDigi*) fDigiSet->GetModulePar(imess->cri))) {
-        LOG(error) << GetName() << "::pushDigis - DIGI par for module " << imess->cri << " missing. Skip.";
+      if (!(digiPar = (CbmTrdParModDigi*) fDigiSet->GetModulePar(imess->mod))) {
+        LOG(error) << GetName() << "::pushDigis - DIGI par for module " << imess->mod << " missing. Skip.";
         return false;
       }
       if (VERBOSE) faspPar->Print();
@@ -267,7 +274,7 @@ bool CbmTrdUnpackFaspAlgo::pushDigis(std::vector<CbmTrdUnpackFaspAlgo::CbmTrdFas
 
     if (!use) {
       CbmTrdDigi* digi = new CbmTrdDigi(pad, lchT, lchR, imess->tlab);
-      digi->SetAddressModule(imess->cri);
+      digi->SetAddressModule(imess->mod);
       digis.push_back(digi);
     }
     delete imess;
@@ -296,6 +303,8 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp
   //LOG(info) << "Component " << icomp << " connected to config CbmTrdUnpackConfig2D. Slice "<<imslice;
 
   uint32_t mod_id = 5;
+  uint8_t cri_id  = 0;
+  uint16_t eq_id;
   bool unpackOk   = true;
   //Double_t fdMsSizeInNs = 1.28e6;
 
@@ -304,6 +313,14 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp
   if (VERBOSE) printf("time start %lu\n", static_cast<size_t>(msdesc.idx));
   // define time wrt start of time slice in TRD/FASP clks [80 MHz]
   fTime[0] = ULong64_t((msdesc.idx - fTsStartTime - fSystemTimeOffset) / 12.5);
+  eq_id    = msdesc.eq_id;  // read the CROB id
+  for (; cri_id < NCRIMOD; cri_id++) {
+    if (((*fCriMap)[mod_id])[cri_id] == eq_id) break;
+  }
+  if (cri_id == NCRIMOD) {
+    LOG(error) << GetName() << "::unpack - CRI eq_id=" << eq_id << " not registered in the unpacker.";
+    return false;
+  }
 
   // Get the µslice size in bytes to calculate the number of completed words
   auto mssize = msdesc.size;
@@ -338,7 +355,7 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp
     uint8_t slice   = (w >> 5) & 0x7f;
     uint16_t data   = (w >> 12) & 0x3fff;
     uint32_t epoch  = (w >> 5) & 0x1fffff;
-    uint8_t fasp_id = (w >> 26) & 0x3f;
+    uint8_t fasp_id = ((w >> 26) & 0x3f) + cri_id * NFASPCRI;
     // std::cout<<"fasp_id="<<static_cast<unsigned int>(fasp_id)<<" ch_id="<<static_cast<unsigned int>(ch_id)<<" isaux="<<static_cast<unsigned int>(isaux)<<std::endl;
     if (isaux) {
       if (!ch_id) {
@@ -383,7 +400,8 @@ bool CbmTrdUnpackFaspAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp
       mess->tlab = slice;
       mess->data = data >> 1;
       mess->fasp = lFaspOld;
-      mess->cri  = mod_id;
+      mess->mod  = mod_id;
+      mess->cri  = cri_id;
       vDigi.push_back(mess);
     }
     //prt_wd(*wd);
diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h
index 3eedd67f9a..b947ed25fd 100644
--- a/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h
+++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspAlgo.h
@@ -38,7 +38,8 @@
 #include <memory>
 #include <utility>
 
-#define NCRI 40  // no of CRI in the system (1/TRD-2D_FASP module)
+// TODO to be defined in correlation with time offsets (AB 20.05.22)
+#define NCRI 40  // no of CRI in the system (5/TRD-2D_FASP module)
 #define NCOLS 8  // no of cols / FASP
 
 class CbmTrdParSetDigi;
@@ -94,8 +95,9 @@ public:
     uint8_t tlab;
     uint16_t data;
     uint32_t epoch;
-    uint8_t fasp;
+    uint32_t mod;
     uint8_t cri;
+    uint8_t fasp;
   };
 
   /**
@@ -113,6 +115,8 @@ public:
 
   /** @brief Introduce fasp index mapping*/
   void SetAsicMapping(const std::map<uint32_t, uint8_t[NFASPMOD]>& map);
+  /** @brief Initialize CRI mapping for all modules*/
+  void SetCriMapping(const std::map<uint32_t, uint16_t[NCRIMOD]>& map);
   /** @brief Set a predefined monitor 
    *  @param monitor predefined unpacking monitor */
   void SetMonitor(std::shared_ptr<CbmTrdUnpackFaspMonitor> monitor) { fMonitor = monitor; }
@@ -185,7 +189,8 @@ protected:
 
 private:
   void prt_wd(uint32_t w);
-  std::map<uint32_t, uint8_t[NFASPMOD]>* fFaspMap = nullptr;
+  std::map<uint32_t, uint8_t[NFASPMOD]>* fFaspMap = nullptr;  ///> FASP mapping update wrt the default setting
+  std::map<uint32_t, uint16_t[NCRIMOD]>* fCriMap  = nullptr;  ///> CRI mapping setting
   /** @brief Potential (online) monitor for the unpacking process */
   std::shared_ptr<CbmTrdUnpackFaspMonitor> fMonitor = nullptr;
   std::vector<Int_t> fModuleId;
diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx
index 34909da4e5..bee277f6ae 100644
--- a/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx
+++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.cxx
@@ -35,6 +35,7 @@ void CbmTrdUnpackFaspConfig::InitAlgo()
 {
   if (fDoLog) LOG(info) << fName << "::InitAlgo - Setup Fasp mapping";
   fAlgo->SetAsicMapping(fFaspMap);
+  fAlgo->SetCriMapping(fCriMap);
   /*if (fDoLog) */ fAlgo->PrintAsicMapping();
 
   // If we have a monitor in the config add it to the algo
@@ -56,4 +57,10 @@ void CbmTrdUnpackFaspConfig::SetFaspMapping(int modAddress, uint8_t faspMap[NFAS
   memcpy(fFaspMap[modAddress], faspMap, NFASPMOD * sizeof(uint8_t));
 }
 
+//_____________________________________________________________________
+void CbmTrdUnpackFaspConfig::SetCriMapping(int modAddress, uint16_t criMap[NCRIMOD])
+{
+  memcpy(fCriMap[modAddress], criMap, NCRIMOD * sizeof(uint16_t));
+}
+
 ClassImp(CbmTrdUnpackFaspConfig)
diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h
index ec9435808a..64f9f9d34e 100644
--- a/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h
+++ b/reco/detectors/trd/unpack/CbmTrdUnpackFaspConfig.h
@@ -72,6 +72,11 @@ public:
    * @param faspMap mapped ids of FASP ASICs for module
    */
   void SetFaspMapping(int modAddress, uint8_t faspMap[NFASPMOD]);
+  /** @brief define cri id mapping for each module
+   * @param modAddress module address according to geometry
+   * @param criMap mapped ids of CRIs eq_id for module
+   */
+  void SetCriMapping(int modAddress, uint16_t criMap[NFASPMOD]);
 
   /** @brief Add a monitor to the unpacker. 
    *  @param value CbmTrdUnpackFaspMonitor */
@@ -86,7 +91,8 @@ protected:
   virtual std::shared_ptr<CbmTrdUnpackFaspAlgo> chooseAlgo();
 
 private:
-  std::map<uint32_t, uint8_t[NFASPMOD]> fFaspMap;  ///> DAQ packing of FASP id
+  std::map<uint32_t, uint8_t[NFASPMOD]> fFaspMap;  ///> Module address to FASP id mapping
+  std::map<uint32_t, uint16_t[NCRIMOD]> fCriMap;   ///> Module address to CRI id mapping
   /** @brief pointer to the monitor object */
   std::shared_ptr<CbmTrdUnpackFaspMonitor> fMonitor = nullptr;
 
-- 
GitLab