From 6bd1700ef6b14e8bedc6c7c0e5c906cf3775ec11 Mon Sep 17 00:00:00 2001
From: praisig <praisig@ikf.uni-frankfurt.de>
Date: Wed, 26 Aug 2020 17:32:52 +0200
Subject: [PATCH] Fix spadic 2.2 channel mapping in asic coordinates

---
 core/detectors/trd/CbmTrdParManager.cxx       | 21 +++++++++++++-----
 core/detectors/trd/CbmTrdParSpadic.cxx        | 22 +++++++++++++------
 core/detectors/trd/CbmTrdParSpadic.h          |  5 ++---
 .../unpacker/CbmMcbm2018UnpackerAlgoTrdR.cxx  |  9 ++++----
 reco/detectors/trd/CMakeLists.txt             |  4 ++--
 ...CbmTrdRecLinkDef.h => CbmTrdRecoLinkDef.h} |  0
 6 files changed, 39 insertions(+), 22 deletions(-)
 rename reco/detectors/trd/{CbmTrdRecLinkDef.h => CbmTrdRecoLinkDef.h} (100%)

diff --git a/core/detectors/trd/CbmTrdParManager.cxx b/core/detectors/trd/CbmTrdParManager.cxx
index 4e20a67915..0b747d2f1c 100644
--- a/core/detectors/trd/CbmTrdParManager.cxx
+++ b/core/detectors/trd/CbmTrdParManager.cxx
@@ -278,15 +278,24 @@ void CbmTrdParManager::CreateModuleParameters(const TString& path) {
       chAddressesVec.clear();
       chAddressesVec.resize(nAsicChannels);
 
-      Int_t iAsicChannel(0);
+      Int_t iAsicChannel =
+        0;  // This is the nth asic channel as it is written to the raw messages
       for (auto channelAddress : chAddressesVec) {
-        // Each row of asic channels for one spadic has its own eLink. The numbering of the channels is stored in the GetElinkChannel() function
-        channelAddress = asic->GetElinkChannel(iAsicChannel);
-        if ((iAsicChannel % 2 != 0))
-          channelAddress +=
-            nModuleColumns;  // one asic is split over two rows with odd channels in the top row, thus there address is placed in the next column
+        // Now apply the asic specific mapping
+        channelAddress = asic->GetAsicChAddress(
+          iAsicChannel);  // returns the channeladdress in the scope of one asic
+
+        // Get the channel addressed to the top or bottom row of the single asic
+        if ((channelAddress / (nAsicChannels / 2)) > 0) {
+          // if the address corresponds to the second 16 channels 16..31 it goes into the next row
+          channelAddress -= (nAsicChannels / 2);
+          // since we have only 16 channels per row we have to subtract 16 from channels 16..31
+          channelAddress += nModuleColumns;
+        }
+        // move channel address to the correct column according to the asic column position
         channelAddress +=
           nThAsicColumn * nAsicChannels / 2;  // one asic is split over two rows
+        // move channel address to the correct row according to the asic row position
         channelAddress +=
           nThAsicRow * nModuleColumns * 2;  // one asic is split over two rows
 
diff --git a/core/detectors/trd/CbmTrdParSpadic.cxx b/core/detectors/trd/CbmTrdParSpadic.cxx
index e7fa47c77c..6b66fe56b2 100644
--- a/core/detectors/trd/CbmTrdParSpadic.cxx
+++ b/core/detectors/trd/CbmTrdParSpadic.cxx
@@ -183,13 +183,21 @@ Int_t CbmTrdParSpadic::GetNasicsPerCrob(Int_t moduleType) {
   return nAsicsPerCrob;
 }
 
-// ---- GetElinkChannel ----------------------------------------------------
-Int_t CbmTrdParSpadic::GetElinkChannel(Int_t channelNumber) {
-  ///< Returns the asic channel number from 00..15 (2 eLinks) in asic coordinates. Spadic channels are not mapped from 00 to 31 in padplane coordinates, this function returns the asic channel in padplane coordinates in the system of one asic (not in the channel map of a full module!)
-  std::vector<Int_t> spadicChannelMap = {
-    15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8, 8,
-    7,  7,  6,  6,  5,  5,  4,  4,  3,  3,  2,  2,  1, 1, 0, 0};
-  return spadicChannelMap.at(channelNumber);
+// ---- GetAsicChAddress ----
+Int_t CbmTrdParSpadic::GetAsicChAddress(const Int_t asicChannel) {
+  Int_t address = -1;
+  ///< Returns the nth asic Channel in asic coordinates in single asic padplane coordinates. Spadic channels are not mapped from 00 to 31 in padplane coordinates, this function returns the padplane channelnumber in the system of one asic(not in the channel map of a full module !)
+  auto elinkCh = asicChannel;
+  if (asicChannel > 15)
+    elinkCh -= NSPADICCH / 2;  // The mapping is symmetric for the elinks
+  std::vector<Int_t> chvec = {
+    15, 7, 14, 6, 13, 11, 5, 12, 10, 4, 3, 9, 8, 2, 1, 0};
+  address = chvec.at(elinkCh);
+  if (asicChannel > 15)
+    address +=
+      NSPADICCH
+      / 2;  // Get the correct value for the channels in the second elink
+  return address;
 }
 
 ClassImp(CbmTrdParSpadic)
diff --git a/core/detectors/trd/CbmTrdParSpadic.h b/core/detectors/trd/CbmTrdParSpadic.h
index 6ad0b85959..4d70a2b716 100644
--- a/core/detectors/trd/CbmTrdParSpadic.h
+++ b/core/detectors/trd/CbmTrdParSpadic.h
@@ -69,9 +69,8 @@ public:
   UInt_t GetAddressOnModule() const {
     return fAddress % 1000;
   }  ///< Returns the number of the asic on the module counted from top left
-  Int_t GetElinkChannel(
-    Int_t
-      channelNumber);  ///< Returns the asic channel number from 00..15 (2 eLinks) in asic coordinates. Spadic channels are not mapped from 00 to 31 in padplane coordinates, this function returns the asic channel in padplane coordinates in the system of one asic (not in the channel map of a full module!)
+  Int_t GetAsicChAddress(const Int_t asicChannel);
+  ///< Returns the nth asic Channel in asic coordinates in single asic padplane coordinates. Spadic channels are not mapped from 00 to 31 in padplane coordinates, this function returns the padplane channelnumber in the system of one asic(not in the channel map of a full module !)
 
 
 private:
diff --git a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.cxx b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.cxx
index b570b68c36..6947b99895 100644
--- a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.cxx
+++ b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.cxx
@@ -884,10 +884,11 @@ CbmMcbm2018UnpackerAlgoTrdR::MakeDigi(CbmTrdRawMessageSpadic raw) {
   Int_t uniqueModuleId = asicAddress / 1000;
   // Int_t layerId(CbmTrdAddress::GetLayerId(uniqueModuleId));
   // Int_t moduleId(CbmTrdAddress::GetModuleId(uniqueModuleId));
-  Int_t asicChannelId(0);
-  asicChannelId = (raw.GetElinkId() % 2) == fIsFirstChannelsElinkEven
-                    ? raw.GetChannelId()
-                    : raw.GetChannelId() + NSPADICCH / 2;
+
+  auto asicChannelId = (raw.GetElinkId() % 2) == fIsFirstChannelsElinkEven
+                         ? raw.GetChannelId()
+                         : raw.GetChannelId() + NSPADICCH / 2;
+
   digiAddress = (fAsicChannelMap.find(asicAddress))->second.at(asicChannelId);
 
   std::shared_ptr<CbmTrdDigi> digi =
diff --git a/reco/detectors/trd/CMakeLists.txt b/reco/detectors/trd/CMakeLists.txt
index 80ccdd9671..71cdd58f51 100644
--- a/reco/detectors/trd/CMakeLists.txt
+++ b/reco/detectors/trd/CMakeLists.txt
@@ -73,8 +73,8 @@ ELSE (SSE_FOUND)
   "-O3")
 ENDIF (SSE_FOUND)
 
-set(LINKDEF CbmTrdRecLinkDef.h)
-Set(LIBRARY_NAME CbmTrdRec)
+set(LINKDEF CbmTrdRecoLinkDef.h)
+Set(LIBRARY_NAME CbmTrdReco)
 Set(DEPENDENCIES
     CbmRecoBase CbmBase CbmData Base CbmTrdBase TMVA
 )
diff --git a/reco/detectors/trd/CbmTrdRecLinkDef.h b/reco/detectors/trd/CbmTrdRecoLinkDef.h
similarity index 100%
rename from reco/detectors/trd/CbmTrdRecLinkDef.h
rename to reco/detectors/trd/CbmTrdRecoLinkDef.h
-- 
GitLab