diff --git a/core/data/test/trd/_GTestCbmTrdDigi.cxx b/core/data/test/trd/_GTestCbmTrdDigi.cxx
index 19f1e73e8c50225c027645b1a0603ba4c1d61dcc..f531d96b4bb4967d690b525062854f341c9c1d0e 100644
--- a/core/data/test/trd/_GTestCbmTrdDigi.cxx
+++ b/core/data/test/trd/_GTestCbmTrdDigi.cxx
@@ -9,21 +9,38 @@ TEST(_GTestCbmTrdDigi , CheckDefaultConstructor)
 {
   // Create object
   CbmTrdDigi test;
-
-  compareTrdDigiDataMembers(test, ToIntegralType(ECbmModuleId::kTrd), ECbmModuleId::kTrd, 0, 0);
+  compareTrdDigiDataMembers(test, 0, ECbmModuleId::kTrd, 0, 0);
 
   CbmTrdDigi* test1 = new CbmTrdDigi();
 
-  compareTrdDigiDataMembers(*test1, ToIntegralType(ECbmModuleId::kTrd), ECbmModuleId::kTrd, 0, 0);
+  compareTrdDigiDataMembers(*test1, 0, ECbmModuleId::kTrd, 0, 0);
 
 }
 
+TEST(_GTestCbmTrdDigi , CheckStandardConstructor)
+{
+  // Create object
+  // This creates a Spadic standard digi, fasp test to be added here
+  Int_t padChNr = 42;
+  Double_t charge = 42.42;
+  ULong64_t digiTime = 42001;
+  Int_t errClass = 0;
+  CbmTrdDigi test(padChNr, charge, digiTime, ((Int_t)CbmTrdDigi::kSelf), errClass);
+  compareTrdDigiDataMembers(test, padChNr, ECbmModuleId::kTrd, digiTime, charge);
+
+  CbmTrdDigi* test1 = new CbmTrdDigi(padChNr, charge, digiTime, ((Int_t)CbmTrdDigi::kSelf), errClass);
+
+  compareTrdDigiDataMembers(*test1, padChNr, ECbmModuleId::kTrd, digiTime, charge);;
+
+}
+
+
 TEST(_GTestCbmTrdDigi, CheckGetClassName)
 {
   // Create object
   CbmTrdDigi test;
 
-  compareTrdDigiDataMembers(test, ToIntegralType(ECbmModuleId::kTrd), ECbmModuleId::kTrd, 0, 0);
+  compareTrdDigiDataMembers(test, 0, ECbmModuleId::kTrd, 0, 0);
 
   EXPECT_STREQ("CbmTrdDigi", test.GetClassName());
 }
diff --git a/core/data/test/trd/compareTrdDigi.h b/core/data/test/trd/compareTrdDigi.h
index 7a8e7f324397f43906be560d40baf278633cf439..632cfa379f1efcf016f26a671e6df6cc18cd849d 100644
--- a/core/data/test/trd/compareTrdDigi.h
+++ b/core/data/test/trd/compareTrdDigi.h
@@ -2,15 +2,23 @@
 #define COMPARETRDDIGI_H 1
 
 void compareTrdDigiDataMembers(CbmTrdDigi& test, 
-    Int_t address, ECbmModuleId systemid, ULong64_t time,
-    Int_t charge)
+    Int_t padChNr, ECbmModuleId systemid, ULong64_t time,
+    Double_t charge)
 {
   Int_t retValInt{-222};
   Double_t retValDouble{-222.};
   ECbmModuleId retVal{ECbmModuleId::kNotExist};
 
+  retValInt = test.GetAddressChannel();
+  EXPECT_EQ(padChNr, retValInt);
+
+  test.SetAddressModule(5);
+  retValInt = test.GetAddressModule();
+  EXPECT_EQ(5, retValInt);
+
+  // GetAddress() returns the full Address part of the fInfo data member. However, since Module-5 translated via CbmTrdAddress corresponds to the value 0 it should return the setted channel number.
   retValInt = test.GetAddress();
-  EXPECT_EQ(address, retValInt);
+  EXPECT_EQ(padChNr, retValInt);
 
   retVal = test.GetSystem();
   EXPECT_EQ(systemid, retVal);
@@ -19,7 +27,7 @@ void compareTrdDigiDataMembers(CbmTrdDigi& test,
   EXPECT_FLOAT_EQ(static_cast<Double_t>(time), retValDouble);
 
   retValDouble = test.GetCharge();
-  EXPECT_EQ(static_cast<Double_t>(charge), retValDouble);
+  EXPECT_FLOAT_EQ(static_cast<Double_t>(charge), retValDouble);
 }
 
 #endif // COMPARETRDDIGI_H
diff --git a/core/data/trd/CbmTrdDigi.cxx b/core/data/trd/CbmTrdDigi.cxx
index 8d49e02ace23f3e6f8e5321f06028a5274780939..eeecdad8a620fabdb2145a067a93d56f95d4ba0d 100644
--- a/core/data/trd/CbmTrdDigi.cxx
+++ b/core/data/trd/CbmTrdDigi.cxx
@@ -15,7 +15,7 @@ using std::stringstream;
 using std::string;
 
 /**
- * fAddress defition ATTf.ffnn nLLL.LMMM MMMM.pppp pppp.pppp
+ * fInfo defition ATTf.ffnn nLLL.LMMM MMMM.pppp pppp.pppp
  * A - Asic type according to CbmTrdAsicType
  * T - trigger type according to CbmTrdTriggerType
  * f - flags according to CbmTrdDigiDef
@@ -28,14 +28,14 @@ Double_t CbmTrdDigi::fgClk[] = {62.5, 12.5};
 Float_t CbmTrdDigi::fgPrecission[] = {1.e3, 1.};
 //__________________________________________________________________________________________
 CbmTrdDigi::CbmTrdDigi()
-  : fAddress(0)
+  : fInfo(0)
   ,fCharge(0)
   ,fTime(0)
 {  
 }
 //__________________________________________________________________________________________
-CbmTrdDigi::CbmTrdDigi(Int_t address, Float_t chargeT, Float_t chargeR, ULong64_t time)
-  : fAddress(0)
+CbmTrdDigi::CbmTrdDigi(Int_t padChNr, Float_t chargeT, Float_t chargeR, ULong64_t time)
+  : fInfo(0)
   ,fCharge(0.)
   ,fTime(time)
 {  
@@ -50,13 +50,13 @@ CbmTrdDigi::CbmTrdDigi(Int_t address, Float_t chargeT, Float_t chargeR, ULong64_
  * r - rectangle paired charge
  */
   SetAsic(kFASP);
-  SetChannel(address); 
+  SetChannel(padChNr); 
   SetCharge(chargeT, chargeR);
 }
 
 //__________________________________________________________________________________________
-CbmTrdDigi::CbmTrdDigi(Int_t address, Float_t charge, ULong64_t time, Int_t triggerType, Int_t errClass)
-  : fAddress(0)
+CbmTrdDigi::CbmTrdDigi(Int_t padChNr, Float_t charge, ULong64_t time, Int_t triggerType, Int_t errClass)
+  : fInfo(0)
   ,fCharge(0.)
   ,fTime(time)
 {
@@ -71,7 +71,7 @@ CbmTrdDigi::CbmTrdDigi(Int_t address, Float_t charge, ULong64_t time, Int_t trig
  * fCharge definition UInt_t(charge*fgPrecission)
 */
   SetAsic(kSPADIC);
-  SetChannel(address); 
+  SetChannel(padChNr); 
   SetCharge(charge);
   SetTriggerType(triggerType);
   SetErrorClass(errClass);
@@ -117,7 +117,7 @@ Int_t CbmTrdDigi::GetAddressChannel() const
 {
 /**  Returns index of the read-out unit in the module in the format row x ncol + col
  */
-  return (fAddress>>fgkRoOffset)&0xfff;
+  return (fInfo>>fgkRoOffset)&0xfff;
 }
 
 //__________________________________________________________________________________________
@@ -166,7 +166,7 @@ Double_t CbmTrdDigi::GetChargeError()  const
 Bool_t CbmTrdDigi::IsFlagged(const Int_t iflag)  const
 {
   if(iflag<0||iflag>=kNflags) return kFALSE;
-  return (fAddress>>(fgkFlgOffset+iflag))&0x1;
+  return (fInfo>>(fgkFlgOffset+iflag))&0x1;
 }
 
 //__________________________________________________________________________________________
@@ -179,8 +179,8 @@ void CbmTrdDigi::SetAddress(Int_t address)
 //__________________________________________________________________________________________
 void CbmTrdDigi::SetAsic(CbmTrdAsicType ty)
 { 
-  if(ty==kSPADIC) CLRBIT(fAddress, fgkTypOffset);
-  else  SETBIT(fAddress, fgkTypOffset);
+  if(ty==kSPADIC) CLRBIT(fInfo, fgkTypOffset);
+  else  SETBIT(fInfo, fgkTypOffset);
 }
 
 //__________________________________________________________________________________________
@@ -216,8 +216,8 @@ void CbmTrdDigi::SetCharge(Float_t c)
 void CbmTrdDigi::SetFlag(const Int_t iflag, Bool_t set)
 {
   if(iflag<0||iflag>=kNflags) return;
-  if(set) SETBIT(fAddress, fgkFlgOffset+iflag);
-  else CLRBIT(fAddress, fgkFlgOffset+iflag);
+  if(set) SETBIT(fInfo, fgkFlgOffset+iflag);
+  else CLRBIT(fInfo, fgkFlgOffset+iflag);
 }
 
 //__________________________________________________________________________________________
@@ -237,8 +237,8 @@ void CbmTrdDigi::SetTimeOffset(Char_t t)
 //__________________________________________________________________________________________
 void CbmTrdDigi::SetTriggerType(const Int_t ttype)
 {
-  if(ttype<0||ttype>=kNTrg) return;
-  fAddress|=(ttype<<fgkTrgOffset);
+  if(ttype<kBeginTriggerTypes||ttype>=kNTrg) return;
+  fInfo|=(ttype<<fgkTrgOffset);
 }
 
 //__________________________________________________________________________________________
diff --git a/core/data/trd/CbmTrdDigi.h b/core/data/trd/CbmTrdDigi.h
index 6541b23e42fbabed3919693ad180c148c0a8ff86..6b6a49e75a7cb9028c36cc16069eeb8ac8ffc8d2 100644
--- a/core/data/trd/CbmTrdDigi.h
+++ b/core/data/trd/CbmTrdDigi.h
@@ -16,8 +16,9 @@ public:
     ,kFASP
     ,kNTypes 
   };
-  enum CbmTrdTriggerType{
-    kSelf = 0
+  enum ECbmTrdTriggerType{
+    kBeginTriggerTypes = 0
+    ,kSelf = kBeginTriggerTypes
     ,kNeighbor 
     ,kMulti 
     ,kTrg2 
@@ -35,28 +36,28 @@ public:
   CbmTrdDigi();
   /**
    * \brief Constructor for the FASP type.
-   * \param[in] address  Unique channel address in the module.
+   * \param[in] padChNr Unique channel address in the module.
    * \param[in] chargeT Charge for tilt pad parring.
    * \param[in] chargeR Charge for rectangle pad parring.
    * \param[in] time   Absolute time [ASIC clocks].
    */
-  CbmTrdDigi(Int_t address, Float_t chargeT, Float_t chargeR, ULong64_t time);
+  CbmTrdDigi(Int_t padChNr, Float_t chargeT, Float_t chargeR, ULong64_t time);
   /**
    * \brief Constructor for the SPADIC type.
-   * \param[in] address  Unique channel address in the module.
+   * \param[in] padChNr Unique channel address in the module.
    * \param[in] charge Charge.
-   * \param[in] time   Absolute time [ASIC clocks].
+   * \param[in] time   Absolute time [ns].
    * \param[in] triggerType SPADIC trigger type see CbmTrdTriggerType.
    * \param[in] errClass SPADIC signal error parametrization based on message type.
    */
-  CbmTrdDigi(Int_t address, Float_t charge, ULong64_t time, Int_t triggerType, Int_t errClass/*nrSamples*/);
+  CbmTrdDigi(Int_t padChNr, Float_t charge, ULong64_t time, Int_t triggerType, Int_t errClass/*nrSamples*/);
   
   /**
    * \brief Constructor for backward compatibillity.
    * Does not do anything.
    */
   CbmTrdDigi(Int_t /*address*/, Double_t /*fullTime*/, Int_t /*triggerType*/, Int_t /*infoType*/, Int_t /*stopType*/, Int_t /*nrSamples*/, Float_t* /*samples*/) 
-  : fAddress(0)
+  : fInfo(0)
   ,fCharge(0)
   ,fTime(0)
   {;}
@@ -73,9 +74,9 @@ public:
   void      AddCharge(Double_t c, Double_t f=1);
   /** \brief DAQ clock accessor for each ASIC*/
   static Float_t Clk(CbmTrdAsicType ty)     { return (ty==kNTypes?0:fgClk[ty]);}
-  /** \brief Address getter for module in the format defined by CbmTrdAddress
+  /** \brief Address getter for module in the format defined by CbmTrdDigi (format of CbmTrdAddress can be accessed via CbmTrdParModDigi)
    */
-  Int_t     GetAddress() const              { return GetAddressModule();}
+  Int_t     GetAddress() const              {return (fInfo>>fgkRoOffset)&0x7fffff;}
   /** \brief Getter read-out id.
    * \return index of row-column read-out unit in the module
    */
@@ -95,7 +96,7 @@ public:
   /** \brief Charge error parametrisation. SPADIC specific see GetErrorClass()*/
   Double_t  GetChargeError()  const;
   /** \brief Channel status. SPADIC specific see LUT*/
-  Int_t     GetErrorClass() const           { return (fAddress>>fgkErrOffset)&0x7;}
+  Int_t     GetErrorClass() const           { return (fInfo>>fgkErrOffset)&0x7;}
 
   /** System ID (static)
   ** @return System identifier (ECbmModuleId)
@@ -115,9 +116,9 @@ public:
   /** \brief Getter for global DAQ time [clk]. Differs for each ASIC. In FASP case DAQ time is already stored in fTime.*/
   ULong64_t GetTimeDAQ() const { return (GetType()==kFASP)?fTime:fTime/fgClk[GetType()];}
   /** \brief Channel trigger type. SPADIC specific see CbmTrdTriggerType*/
-  Int_t     GetTriggerType() const          { return (fAddress>>fgkTrgOffset)&0x3;}
+  Int_t     GetTriggerType() const          { return (fInfo>>fgkTrgOffset)&0x3;}
   /** \brief Channel FEE SPADIC/FASP according to CbmTrdAsicType*/
-  CbmTrdAsicType  GetType() const     { return ((fAddress>>fgkTypOffset)&0x1)?kFASP:kSPADIC;} 
+  CbmTrdAsicType  GetType() const     { return ((fInfo>>fgkTypOffset)&0x1)?kFASP:kSPADIC;} 
 
   /** \brief Query digi mask (FASP only)*/
   Bool_t    IsMasked() const {return (GetType()==kFASP)&&IsFlagged(kFlag3);}
@@ -125,8 +126,8 @@ public:
   Bool_t    IsPileUp() const {return (GetType()==kFASP)&&IsFlagged(kFlag2);}
   /** \brief Query flag status (generic)*/
   Bool_t    IsFlagged(const Int_t iflag)  const;
-  Int_t     Layer() const    { return (fAddress>>fgkLyOffset)&0xf;}
-  Int_t     Module() const   { return (fAddress>>fgkModOffset)&0x7f;}
+  Int_t     Layer() const    { return (fInfo>>fgkLyOffset)&0xf;}
+  Int_t     Module() const   { return (fInfo>>fgkModOffset)&0x7f;}
 
   /** \brief Module address setter for digi
    * \param[in] a module address as it is defined in CbmTrdAddress
@@ -161,8 +162,8 @@ public:
   /** \brief Set digi trigger type (SPADIC only)*/
   void      SetTriggerType(const Int_t ttype);
   /** \brief Set digi error class (SPADIC only)*/
-  void      SetErrorClass(const Int_t n)    { fAddress&= ~(0x7<<fgkErrOffset);
-                                              fAddress|=((n&0x7)<<fgkErrOffset);}
+  void      SetErrorClass(const Int_t n)    { fInfo&= ~(0x7<<fgkErrOffset);
+                                              fInfo|=((n&0x7)<<fgkErrOffset);}
   /** \brief String representation of a TRD digi. Account for digi type and specific information.*/
   std::string ToString() const;
   
@@ -178,14 +179,14 @@ public:
   Float_t* GetSamples() {return nullptr;}
 
 protected:
-  void      SetChannel(const Int_t a){ fAddress&= ~(0xfff<<fgkRoOffset); 
-                                       fAddress|=(a&0xfff)<<fgkRoOffset;}
-  void      SetLayer(const Int_t a)  { fAddress&= ~(0xf<<fgkLyOffset); 
-                                       fAddress|=((a&0xf)<<fgkLyOffset);}
-  void      SetModule(const Int_t a) { fAddress&= ~(0x7f<<fgkModOffset); 
-                                       fAddress|=((a&0x7f)<<fgkModOffset);}
-
-  UInt_t    fAddress;     //< pad address and extra information
+  void      SetChannel(const Int_t a){ fInfo&= ~(0xfff<<fgkRoOffset); 
+                                       fInfo|=(a&0xfff)<<fgkRoOffset;}
+  void      SetLayer(const Int_t a)  { fInfo&= ~(0xf<<fgkLyOffset); 
+                                       fInfo|=((a&0xf)<<fgkLyOffset);}
+  void      SetModule(const Int_t a) { fInfo&= ~(0x7f<<fgkModOffset); 
+                                       fInfo|=((a&0x7f)<<fgkModOffset);}
+
+  UInt_t    fInfo;     //< pad address and extra information
   UInt_t    fCharge;      //< measured charge. For SPADIC is Int_t(charge*1eN) where N is the precission while 
                           //< for FASP it contains the R and T charges each on 12bits and the time difference between R and T pads in CLK (8 bits).
   ULong64_t fTime;        //< global time of the digi: For SPADIC in ns, for FASP in ASIC clock
diff --git a/core/detectors/trd/CbmTrdHardwareSetupR.cxx b/core/detectors/trd/CbmTrdHardwareSetupR.cxx
index 1cb1d14e490d68e4fa7c495b5bc2f4672e3f428b..7fc8a19fd3b8593c9039b13dddf0bbd212eea96f 100644
--- a/core/detectors/trd/CbmTrdHardwareSetupR.cxx
+++ b/core/detectors/trd/CbmTrdHardwareSetupR.cxx
@@ -3,7 +3,7 @@
  * Created Date: Thursday March 5th 2020
  * Author: Pascal Raisig -- praisig@ikf.uni-frankfurt.de
  * -----
- * Last Modified: Tuesday March 24th 2020 15:02:04
+ * Last Modified: Friday June 5th 2020 16:34:54
  * Modified By: Pascal Raisig
  * -----
  * Purpose: This class contains the hardware mapping for asics at a given beamtime and provides the functionalities to
@@ -235,21 +235,54 @@ bool CbmTrdHardwareSetupR::WriteComponentIdsToParams()
 
 }
 
+// ---- SelectComponentIdMap ----------------------------------------------------
+void CbmTrdHardwareSetupR::SelectComponentIdMap(TString geoTag)
+{
+    ECbmTrdHardwareSetupVersion hwSetupVersion(ECbmTrdHardwareSetupVersion::kUndefined);
+    if(geoTag.Contains("mcbm"))
+    {
+        hwSetupVersion = ECbmTrdHardwareSetupVersion::kMcbm2020;
+    }
+    else if(geoTag.Contains("trd_ikfLabOneSpadic"))
+    {
+        hwSetupVersion = ECbmTrdHardwareSetupVersion::kLabIkfOneSpadic;
+    }
+    else if(geoTag.Contains("trd_Desy2019"))
+    {
+        hwSetupVersion = ECbmTrdHardwareSetupVersion::kDesy2019;
+    }
+    else if(geoTag.Contains("trd_v"))
+    {
+        hwSetupVersion = ECbmTrdHardwareSetupVersion::kCbm2025;
+    }
+    else
+    {
+        LOG(fatal) << Form("CbmTrdHardwareSetupR::SelectComponentIdMap(%s), unknown geoTag", geoTag.Data());
+    }
+    SelectComponentIdMap(hwSetupVersion);
+}
+
 // ---- SelectComponentIdMap ----------------------------------------------------
 void CbmTrdHardwareSetupR::SelectComponentIdMap(ECbmTrdHardwareSetupVersion hwSetup)
 {
     switch (hwSetup)
     {
+    case ECbmTrdHardwareSetupVersion::kUndefined :
+        fComponentIdMap = {{0,0}};
+        break;
     case ECbmTrdHardwareSetupVersion::kMcbm2020 :
-        // REMARK This map is incomplete! eLinkId status from 03/24/2020. CriId status 03/24/3030.  Needs to be filled with correct values, whenever they are known.
+        // REMARK eLinkId status from 03/24/2020. CriId status 03/24/3030.  Needs to be filled with correct values, whenever they are known.
         fComponentIdMap = 
         { 
             // Module 5
-            {5000, 2498200098}, {5001, 2498200000}, {5002, 2498200002}, {5003, 2498200004}, {5004, 2498200006}, {5005, 2498200008}, {5006, 2498200010}, {5007, 2498200012},
+            {5000, 2498200098}, {5001, 2498200028}, {5002, 2498200030}, {5003, 2498200032}, {5004, 2498200034}, {5005, 2498200036}, {5006, 2498200038}, {5007, 2498200040},
+
             {5008, 2498200098}, {5009, 2498200014}, {5010, 2498200016}, {5011, 2498200018}, {5012, 2498200020}, {5013, 2498200022}, {5014, 2498200024}, {5015, 2498200026},
-            {5016, 2498200098}, {5017, 2498200028}, {5018, 2498200030}, {5019, 2498200032}, {5020, 2498200034}, {5021, 2498200036}, {5022, 2498200038}, {5023, 2498200040}
+
+            {5016, 2498200098}, {5017, 2498200000}, {5018, 2498200002}, {5019, 2498200004}, {5020, 2498200006}, {5021, 2498200008}, {5022, 2498200010}, {5023, 2498200012},
+            
             // Module 21
-            , {21000, 2498200098}, {21001, 2498200000}, {21002, 2498200002}, {21003, 2498200004}, {21004, 2498200006}, {21005, 2498200008}, {21006, 2498200010}, {21007, 2498200012},
+            {21000, 2498200098}, {21001, 2498200000}, {21002, 2498200002}, {21003, 2498200004}, {21004, 2498200006}, {21005, 2498200008}, {21006, 2498200010}, {21007, 2498200012},
             {21008, 2498200098}, {21009, 2498200014}, {21010, 2498200016}, {21011, 2498200018}, {21012, 2498200020}, {21013, 2498200022}, {21014, 2498200024}, {21015, 2498200026},
             {21016, 2498200098}, {21017, 2498200028}, {21018, 2498200030}, {21019, 2498200032}, {21020, 2498200034}, {21021, 2498200036}, {21022, 2498200038}, {21023, 2498200040}
         };
@@ -264,7 +297,22 @@ void CbmTrdHardwareSetupR::SelectComponentIdMap(ECbmTrdHardwareSetupVersion hwSe
             {5016, 100098}, {5017, 100098}, {5018, 100098}, {5019, 100098}, {5020, 100098}, {5021, 100098}, {5022, 100098}, {5023, 100098}
         };
         break;
-    
+    case ECbmTrdHardwareSetupVersion::kDesy2019 :
+        // Map for the DESY 2019 beamtime setup, 5012 - in beam, 5006 - Fe source.
+        fComponentIdMap = 
+        { 
+            // Module 5
+            {5000, 100098}, {5001, 100098}, {5002, 100098}, {5003, 100098},
+            {5004, 100098}, {5005, 100098}, {5006, 4352000002}, {5007, 100098},
+
+            {5008, 100098}, {5009, 100098}, {5010, 100098}, {5011, 100098},
+            {5012, 4352000000}, {5013, 100098}, {5014, 100098}, {5015, 100098},
+
+            {5016, 100098}, {5017, 100098}, {5018, 100098}, {5019, 100098},
+            {5020, 100098}, {5021, 100098}, {5022, 100098}, {5023, 100098},
+        };
+        break;
+
     case ECbmTrdHardwareSetupVersion::kCbm2025 :
         // REMARK This map is a dummy! Needs to be filled with correct values, whenever they are known.
         fComponentIdMap = 
diff --git a/core/detectors/trd/CbmTrdHardwareSetupR.h b/core/detectors/trd/CbmTrdHardwareSetupR.h
index 89d36002c56948783fc8188e7687a77286cc08a3..bbaf9269ab0901c5b0fd1cdf9784173099cd2643 100644
--- a/core/detectors/trd/CbmTrdHardwareSetupR.h
+++ b/core/detectors/trd/CbmTrdHardwareSetupR.h
@@ -3,7 +3,7 @@
  * Created Date: Thursday March 5th 2020
  * Author: Pascal Raisig -- praisig@ikf.uni-frankfurt.de
  * -----
- * Last Modified: Saturday March 21st 2020 14:30:16
+ * Last Modified: Friday June 5th 2020 16:24:20
  * Modified By: Pascal Raisig
  * -----
  * Purpose: This class contains the hardware mapping for asics at a given beamtime and provides the functionalities to
@@ -28,6 +28,7 @@ enum class ECbmTrdHardwareSetupVersion : Int_t
     kUndefined = 0
     , kMcbm2020  = 1
     , kLabIkfOneSpadic
+    , kDesy2019
     , kCbm2025
 }; ///< Enum for hardware setup versions, they are for example correlated to the componentId setup.
 
@@ -50,6 +51,7 @@ public:
     std::map<std::uint64_t, Int_t> CreateHwToSwAsicAddressTranslatorMap(bool isLoadedParameters);
     std::map<Int_t, std::vector<Int_t>> CreateAsicChannelMap(bool isLoadedParameters);
     void SelectComponentIdMap(ECbmTrdHardwareSetupVersion hwSetup);
+    void SelectComponentIdMap(TString geoTag);
     bool WriteComponentIdsToParams();
 
 private:
diff --git a/core/detectors/trd/CbmTrdParManager.cxx b/core/detectors/trd/CbmTrdParManager.cxx
index 2dc25b378be34a9923122671ff512a9f618ca017..4b1ccff6dc68c1bcc8a20f7c24faf4a189bdae69 100644
--- a/core/detectors/trd/CbmTrdParManager.cxx
+++ b/core/detectors/trd/CbmTrdParManager.cxx
@@ -48,6 +48,8 @@ CbmTrdParManager::CbmTrdParManager(Bool_t fasp)
   ,fGasPar(nullptr)
   ,fGainPar(nullptr)
   ,fGeoHandler(new CbmTrdGeoHandler())
+  ,fGeometryTag("")
+  ,fHardwareSetup()
 {
   // Get the maximum number of sectors. All arrays will have this number of entries.
   fMaxSectors = fst1_sect_count;
@@ -89,6 +91,8 @@ InitStatus CbmTrdParManager::Init()
     TGeoNode* node = static_cast<TGeoNode*>(nodes->At(iNode));
     if (!TString(node->GetName()).Contains("trd")) continue; // trd_vXXy top node, e.g. trd_v13a, trd_v14b
     TGeoNode* station = node;
+    fGeometryTag = station->GetName();
+    fHardwareSetup.SelectComponentIdMap(fGeometryTag);
     TObjArray* layers = station->GetNodes();
     for (Int_t iLayer = 0; iLayer < layers->GetEntriesFast(); iLayer++) {
         TGeoNode* layer = static_cast<TGeoNode*>(layers->At(iLayer));
@@ -167,9 +171,7 @@ void CbmTrdParManager::CreateModuleParameters(const TString& path)
   // Orientation of the detector layers
   // Odd  layers (1,3,5..) have resolution in x-direction (isRotated == 0) - vertical pads
   // Even layers (2,4,6..) have resolution in y-direction (isRotated == 1) - horizontal pads
-  //   Int_t layerNr = CbmTrdAddress::GetLayerId(moduleAddress) + 1;
-  //   Int_t isRotated = fGeoHandler->GetModuleOrientation(path);
-  //      printf("layer %02d %d isRotated\n", layerNr, isRotated);   // check, if even layers are isRotated == 1
+  // Int_t isRotated = fGeoHandler->GetModuleOrientation(path);
   //   if( (isRotated%2) == 1 ) {  // flip pads for even layers
   //      Double_t copybuf;
   //      for (Int_t i = 0; i < fMaxSectors; i++) {
@@ -231,21 +233,22 @@ void CbmTrdParManager::CreateModuleParameters(const TString& path)
   else {
     asics = new CbmTrdParSetAsic("TrdParModSpadic", Form("Spadic set for Module %d", moduleAddress));     asics->SetAsicType(moduleType);
     CbmTrdParSpadic *asic(nullptr);
-    Int_t nAsicsPerCrob = CbmTrdParSpadic::GetNasicsPerCrob(moduleType);
-    Int_t cRobCounter(0);
-    Int_t cRobId(0);
-    Int_t eLinkId(98);  // default for undefined, since 98 should never be in use
+    // Int_t nAsicsPerCrob = CbmTrdParSpadic::GetNasicsPerCrob(moduleType);
+    // Int_t cRobCounter(0);
+    // Int_t cRobId(0);
+    // Int_t eLinkId(98);  // default for undefined, since 98 should never be in use
     Int_t nModuleColumns(digi->GetNofColumns());
     Int_t nModuleRows(digi->GetNofRows());
+    Int_t nModuleChannels(nModuleColumns * nModuleRows);
     
     Int_t nAsicsAlongColumns(-1);
     
     std::vector<Int_t> chAddressesVec;
     for (Int_t iAsic = 0; iAsic < CbmTrdParSpadic::GetNasicsOnModule(moduleType); iAsic++)
     {
-      asic = new CbmTrdParSpadic( 1000 *  moduleAddress + iAsic); // nTh-asic + module address define asicAddress
-      eLinkId = (iAsic % nAsicsPerCrob) * 2;
-      cRobCounter = iAsic / nAsicsPerCrob;
+      asic = new CbmTrdParSpadic( 1000 *  moduleAddress + iAsic); // nTh-asic + module address define asicAddress counting for asic starts at bottom left and goes left to right row by row
+      // eLinkId = (iAsic % nAsicsPerCrob) * 2;
+      // cRobCounter = iAsic / nAsicsPerCrob;
       Int_t nAsicChannels(asic->GetNchannels());
       nAsicsAlongColumns = nModuleColumns < nModuleRows ? nModuleRows / 2 : nModuleColumns / (nAsicChannels/2) ;
       Int_t nThAsicRow(iAsic / nAsicsAlongColumns);
@@ -259,19 +262,26 @@ void CbmTrdParManager::CreateModuleParameters(const TString& path)
       for (auto channelAddress : chAddressesVec)
       {
         channelAddress = asic->GetElinkChannel(iAsicChannel);
-        if((iAsicChannel % 2 == 0)) channelAddress += nModuleColumns; // one asic is split over two rows thus, with even channels in the bottom row, thus there address is placed in the next column 
-        
+        if((iAsicChannel % 2 != 0)) channelAddress += nModuleColumns; // one asic is split over two rows thus, with odd channels in the top row, thus there address is placed in the next column 
         channelAddress += nThAsicColumn * nAsicChannels / 2; // one asic is split over two rows
         channelAddress += nThAsicRow    * nModuleColumns * 2; // one asic is split over two rows
+        if(orientation == 2)
+        {
+          channelAddress *= (-1);
+          channelAddress += (nModuleChannels-1);
+        } 
         chAddressesVec.at(iAsicChannel) = channelAddress;
         iAsicChannel++;
       }
 
       asic->SetChannelAddresses(chAddressesVec);
-      asic->SetComponentId(moduleAddress * CbmTrdParAsic::kCriIdPosition + cRobId * CbmTrdParAsic::kCrobIdPosition + cRobCounter * CbmTrdParAsic::kCrobNrPosition + eLinkId * CbmTrdParAsic::kElinkIdPosition); // Remark: This is and will not be the correct componentId (CRI/AFCK Id). However, every asic connected to the nTh cRob of a given module will have the same componentId. Thus, this makes it easier to change to the correct Id for all relevant asics.
+      // asic->SetComponentId(moduleAddress * CbmTrdParAsic::kCriIdPosition + cRobId * CbmTrdParAsic::kCrobIdPosition + cRobCounter * CbmTrdParAsic::kCrobNrPosition + eLinkId * CbmTrdParAsic::kElinkIdPosition); // Remark: This is and will not be the correct componentId (CRI/AFCK Id). However, every asic connected to the nTh cRob of a given module will have the same componentId. Thus, this makes it easier to change to the correct Id for all relevant asics.
+      asic->SetComponentId(fHardwareSetup.GetComponentId(asic->GetAddress()));
       asics->SetAsicPar(asic->GetAddress(), asic);
     }
   }
+  
+  
   asics->Print();
   fAsicPar->AddParameters(asics);
 
diff --git a/core/detectors/trd/CbmTrdParManager.h b/core/detectors/trd/CbmTrdParManager.h
index 4441a856cefdf9c631b80ffe847e8df26a670cc2..24511fbb036fb9fed5b2e8d878a39533fdf1b81f 100644
--- a/core/detectors/trd/CbmTrdParManager.h
+++ b/core/detectors/trd/CbmTrdParManager.h
@@ -20,6 +20,8 @@
 
 #include "FairTask.h"    // for FairTask, InitStatus
 
+#include "CbmTrdHardwareSetupR.h" //for CbmTrdHardwareSetupR
+
 class CbmTrdGeoHandler;
 class CbmTrdParSetAsic;
 class CbmTrdParSetDigi;
@@ -95,6 +97,9 @@ private:
 
    CbmTrdGeoHandler* fGeoHandler;
 
+   TString fGeometryTag;
+   CbmTrdHardwareSetupR fHardwareSetup;
+
    CbmTrdParManager(const CbmTrdParManager&);
    CbmTrdParManager& operator=(const CbmTrdParManager&);
 
diff --git a/core/detectors/trd/CbmTrdParModDigi.cxx b/core/detectors/trd/CbmTrdParModDigi.cxx
index ed0ab30f0db941b68a294ce8206e65f28bb788db..b2e8b555544b970f2bcb5c729742ced97f3ac849 100644
--- a/core/detectors/trd/CbmTrdParModDigi.cxx
+++ b/core/detectors/trd/CbmTrdParModDigi.cxx
@@ -725,52 +725,39 @@ void CbmTrdParModDigi::GetPadPosition(
  * Get address of a pad, return position relative to module center
  */
 
-  Double_t posX = 0;
-  Double_t posY = 0;
-  Double_t posZ = 0;
+  // Double_t posX = 0;
+  // Double_t posY = 0;
+  // Double_t posZ = 0;
    
   Int_t sectorId = CbmTrdAddress::GetSectorId(padAddress);
   Int_t rowId    = CbmTrdAddress::GetRowId(padAddress);
   Int_t columnId = CbmTrdAddress::GetColumnId(padAddress);
 
-  Double_t padsizex = fPadSizeX.At(sectorId);
-  Double_t padsizey = fPadSizeY.At(sectorId);
+  return GetPadPosition(sectorId, rowId, columnId, padPos, padPosErr);
+}
 
-  // calculate position in sector coordinate system 
-  // with the origin in the lower left corner (looking upstream)
-  posX = (((Double_t)columnId + 0.5) * padsizex);
-  posY = (((Double_t)rowId    + 0.5) * padsizey);
+//___________________________________________________________________________
+void CbmTrdParModDigi::GetPadPosition(
+				      const Int_t padAddress,
+              bool isCbmTrdDigiAddress,
+				      TVector3& padPos,
+				      TVector3& padPosErr) const
+{
+/** 
+ * Get address of a pad, based on the channel address stored in the CbmTrdDigi
+ */
+  if(!isCbmTrdDigiAddress) LOG(error) << "Trying to get a CbmTrd PadPosition from DigiAddress format function without digiAddress format";
 
-  //  LOG(info) << "  sector: "<< sectorId<<"   row: " << rowId<<"   col: " << columnId
-  //            <<"   size x: " << padsizex<<"  size y: "<< padsizey<<" posx: "<< posX<<" posY: "<< posY;
   
-  // calculate position in module coordinate system
-  // with the origin in the lower left corner (looking upstream)
-  posX += fSectorBeginX.GetAt(sectorId);
-  posY += fSectorBeginY.GetAt(sectorId);
+  Int_t row = GetPadRow(padAddress);
+  Int_t col = GetPadColumn(padAddress);
 
-  //  LOG(info)<<"  posX: "<< posX<<"   posY: "<< posY;
-  
-  // calculate position in the module coordinate system
-  // with origin in the middle of the module
-  posX -= fSizeX;
-  posY -= fSizeY;
-  posZ  = 0; // fSizeZ;
+  Int_t srow(-1);
+  Int_t sector= GetSectorRow(row, srow);
 
-  //  LOG(info)<<"  posX: "<< posX<<"   posY: "<< posY;
-  
-  // check limits
-  if ( fabs(posX) > fSizeX )
-    LOG(fatal) << "CbmTrdParModDigi::GetPadPosition posX=" << posX << " is out of bounds!";
-  // check limits
-  if ( fabs(posY) > fSizeY )
-    LOG(fatal) << "CbmTrdParModDigi::GetPadPosition posY=" << posY << " is out of bounds!";
-
-  padPos.SetXYZ(posX, posY, posZ);
-  padPosErr.SetXYZ(padsizex/2.,padsizey/2., 0.);
+  return GetPadPosition(sector, col, srow, padPos, padPosErr);
 }
 
-
 //___________________________________________________________________________
 void CbmTrdParModDigi::GetPosition(
 //         Int_t moduleAddress,
@@ -860,4 +847,33 @@ void CbmTrdParModDigi::GetPosition(
   padSize.SetXYZ(padsizex,padsizey, 0.);
 }
 
+//___________________________________________________________________________
+Int_t CbmTrdParModDigi::GetPadColumn(const Int_t channelNumber) const
+{
+  // calculate the pad column based on
+  // the channeNumber as defined in the
+  // CbmTrdDigi
+
+  Int_t ncols = GetNofColumns();
+  Int_t col = channelNumber % ncols;
+
+  return col;
+}
+
+//___________________________________________________________________________
+Int_t CbmTrdParModDigi::GetPadRow(const Int_t channelNumber) const
+{
+  // calculate the pad row based on
+  // the channeNumber as defined in the
+  // CbmTrdDigi
+
+  Int_t ncols = GetNofColumns();
+  Int_t row = channelNumber / ncols;
+
+  return row;
+}
+
+
+
+
 ClassImp(CbmTrdParModDigi)
diff --git a/core/detectors/trd/CbmTrdParModDigi.h b/core/detectors/trd/CbmTrdParModDigi.h
index 879ac2d88a675f3be5b4938ddf3b7e603e06b29d..7e4094c638160c046ad3325f8daf33f3faff3deb 100644
--- a/core/detectors/trd/CbmTrdParModDigi.h
+++ b/core/detectors/trd/CbmTrdParModDigi.h
@@ -1,150 +1,153 @@
 #ifndef CBMTRDPARMODDIGI_H
 #define CBMTRDPARMODDIGI_H
 
-#include <Rtypes.h>        // for THashConsistencyHolder, ClassDef
-#include <RtypesCore.h>    // for Double_t, Int_t, Bool_t, Option_t
-#include <TArrayD.h>       // for TArrayD
+#include <Rtypes.h>     // for THashConsistencyHolder, ClassDef
+#include <RtypesCore.h> // for Double_t, Int_t, Bool_t, Option_t
+#include <TArrayD.h>    // for TArrayD
 
-#include "CbmTrdParMod.h"  // for CbmTrdParMod
+#include "CbmTrdParMod.h" // for CbmTrdParMod
 
 class CbmTrdPoint;
 class TVector3;
 
 /** \brief Definition of chamber gain conversion for one TRD module **/
-class CbmTrdParModDigi : public CbmTrdParMod
-{
+class CbmTrdParModDigi : public CbmTrdParMod {
 public:
   CbmTrdParModDigi();
-  CbmTrdParModDigi(Double_t x, Double_t y, Double_t z,
-                Double_t sizex, Double_t sizey, Double_t sizez, Int_t nofSectors,Int_t orientation,
-        const TArrayD& sectorSizeX, const TArrayD& sectorSizeY,
-        const TArrayD& padSizeX, const TArrayD& padSizeY);
-  virtual ~CbmTrdParModDigi() {;}
-  Int_t     GetNofColumns() const;
-  Int_t     GetNofRows() const;
-
-  Int_t     GetNofColumnsInSector(Int_t i) const;
-  Int_t     GetNofRowsInSector(Int_t i) const;
-  Int_t     GetOrientation() const          { return fOrientation; }
-  Double_t  GetPadSizeX(Int_t i) const      { return fPadSizeX.At(i); }
-  Double_t  GetPadSizeY(Int_t i) const      { return fPadSizeY.At(i); }
-  Double_t  GetSectorBeginX(Int_t i) const  { return fSectorBeginX.At(i); }
-  Double_t  GetSectorBeginY(Int_t i) const  { return fSectorBeginY.At(i); }
-  Double_t  GetSectorSizeX(Int_t i) const   { return fSectorSizeX.At(i); }
-  Double_t  GetSectorSizeY(Int_t i) const   { return fSectorSizeY.At(i); }
-
-  Double_t  GetAnodeWireToPadPlaneDistance() const { return fAnodeWireToPadPlaneDistance; }
-  Double_t  GetAnodeWireOffset() const      { return fAnodeWireOffset; }
-  Double_t  GetAnodeWireSpacing() const     { return fAnodeWireSpacing; }
-
-  Int_t     GetNofSectors() const           { return fNofSectors; }
-
-  Int_t     GetModuleRow(Int_t& sectorId, Int_t& rowId) const;
+  CbmTrdParModDigi(Double_t x, Double_t y, Double_t z, Double_t sizex,
+                   Double_t sizey, Double_t sizez, Int_t nofSectors,
+                   Int_t orientation, const TArrayD &sectorSizeX,
+                   const TArrayD &sectorSizeY, const TArrayD &padSizeX,
+                   const TArrayD &padSizeY);
+  virtual ~CbmTrdParModDigi() { ; }
+  Int_t GetNofColumns() const;
+  Int_t GetNofRows() const;
+
+  Int_t GetNofColumnsInSector(Int_t i) const;
+  Int_t GetNofRowsInSector(Int_t i) const;
+  Int_t GetOrientation() const { return fOrientation; }
+  Double_t GetPadSizeX(Int_t i) const { return fPadSizeX.At(i); }
+  Double_t GetPadSizeY(Int_t i) const { return fPadSizeY.At(i); }
+  Double_t GetSectorBeginX(Int_t i) const { return fSectorBeginX.At(i); }
+  Double_t GetSectorBeginY(Int_t i) const { return fSectorBeginY.At(i); }
+  Double_t GetSectorSizeX(Int_t i) const { return fSectorSizeX.At(i); }
+  Double_t GetSectorSizeY(Int_t i) const { return fSectorSizeY.At(i); }
+
+  Double_t GetAnodeWireToPadPlaneDistance() const {
+    return fAnodeWireToPadPlaneDistance;
+  }
+  Double_t GetAnodeWireOffset() const { return fAnodeWireOffset; }
+  Double_t GetAnodeWireSpacing() const { return fAnodeWireSpacing; }
+
+  Int_t GetNofSectors() const { return fNofSectors; }
+
+  Int_t GetModuleRow(Int_t &sectorId, Int_t &rowId) const;
   /**
-   * \brief Find the sector wise row given the module row. Inverse of GetModuleRow()
-   * \param[in] growId Module wise row id. 
+   * \brief Find the sector wise row given the module row. Inverse of
+   *GetModuleRow()
+   * \param[in] growId Module wise row id.
    * \param[out] srowId On return sector wise row id.
-   * \return Sector id. 
+   * \return Sector id.
    **/
-  Int_t     GetSectorRow(Int_t  growId, Int_t& srowId) const;
-
-  Bool_t    GetPadInfo(
-        const Double_t* local_point,
-        Int_t& sectorId,
-        Int_t& columnId,
-        Int_t& rowId) const;
-
-  void      GetPadInfo(
-      const CbmTrdPoint* trdPoint,
-      Int_t& sectorId,
-      Int_t& columnId,
-      Int_t& rowId) const;
-
-  //function for the pad position with the new address format for rectangular modules
-  void GetPadPosition(
-          const Int_t sector,
-	  const Int_t col,
-	  const Int_t row,
-          TVector3& padPos,
-          TVector3& padPosErr) const;
-
-  //standard implementation of the pad position
-  void      GetPadPosition(
-          const Int_t padAddress,
-          TVector3& padPos,
-          TVector3& padPosErr) const;
-
-  void      GetPosition(
-       //Int_t moduleAddress,
-       Int_t sectorId,
-       Int_t columnId,
-       Int_t rowId,
-       TVector3& padPos,
-       TVector3& padSize) const;
-       
-  Int_t     GetSector(Int_t npady, Int_t& rowId) const;
-  Double_t  GetSizeX() const                            { return fSizeX;}
-  Double_t  GetSizeY() const                            { return fSizeY;}
-  Double_t  GetSizeZ() const                            { return fSizeZ;}
-  Double_t  GetX() const                                { return fX;}
-  Double_t  GetY() const                                { return fY;}
-  Double_t  GetZ() const                                { return fZ;}
-  void      Print(Option_t *opt="") const;
-
-  void      ProjectPositionToNextAnodeWire(Double_t* local_point) const;
-  void      SetAnodeWireToPadPlaneDistance(Double_t d)  { fAnodeWireToPadPlaneDistance=d; }
-  void      SetAnodeWireOffset(Double_t off)            { fAnodeWireOffset=off; }
-  void      SetAnodeWireSpacing(Double_t dw)            { fAnodeWireSpacing=dw; }
-  void      TransformHitError(TVector3& hitErr) const;
-
-  void      TransformToLocalPad(const Double_t* local_point, Double_t& posX, Double_t& posY) const;
-
-private:  
+  Int_t GetSectorRow(Int_t growId, Int_t &srowId) const;
+
+  Bool_t GetPadInfo(const Double_t *local_point, Int_t &sectorId,
+                    Int_t &columnId, Int_t &rowId) const;
+
+  void GetPadInfo(const CbmTrdPoint *trdPoint, Int_t &sectorId, Int_t &columnId,
+                  Int_t &rowId) const;
+
+  // function for the pad position with the new address format for rectangular
+  // modules
+  void GetPadPosition(const Int_t sector, const Int_t col, const Int_t row,
+                      TVector3 &padPos, TVector3 &padPosErr) const;
+
+  // get pad position from channel number in CbmTrdDigi implementation of the
+  // pad position
+  void GetPadPosition(const Int_t padAddress, bool isCbmTrdDigiAddress,
+                      TVector3 &padPos, TVector3 &padPosErr) const;
+
+  // standard implementation of the pad position
+  void GetPadPosition(const Int_t padAddress, TVector3 &padPos,
+                      TVector3 &padPosErr) const;
+
+  void GetPosition(
+      // Int_t moduleAddress,
+      Int_t sectorId, Int_t columnId, Int_t rowId, TVector3 &padPos,
+      TVector3 &padSize) const;
+
+  Int_t GetPadColumn(const Int_t channelNumber) const; // calculate the pad column based on
+                                           // the channeNumber as defined in the
+                                           // CbmTrdDigi
+  Int_t GetPadRow(const Int_t channelNumber) const;    // calculate the pad row based on
+                                           // the channeNumber as defined in the
+                                           // CbmTrdDigi
+
+  Int_t GetSector(Int_t npady, Int_t &rowId) const;
+  Double_t GetSizeX() const { return fSizeX; }
+  Double_t GetSizeY() const { return fSizeY; }
+  Double_t GetSizeZ() const { return fSizeZ; }
+  Double_t GetX() const { return fX; }
+  Double_t GetY() const { return fY; }
+  Double_t GetZ() const { return fZ; }
+  void Print(Option_t *opt = "") const;
+
+  void ProjectPositionToNextAnodeWire(Double_t *local_point) const;
+  void SetAnodeWireToPadPlaneDistance(Double_t d) {
+    fAnodeWireToPadPlaneDistance = d;
+  }
+  void SetAnodeWireOffset(Double_t off) { fAnodeWireOffset = off; }
+  void SetAnodeWireSpacing(Double_t dw) { fAnodeWireSpacing = dw; }
+  void TransformHitError(TVector3 &hitErr) const;
+
+  void TransformToLocalPad(const Double_t *local_point, Double_t &posX,
+                           Double_t &posY) const;
+
+private:
   CbmTrdParModDigi(const CbmTrdParModDigi &ref);
-  const CbmTrdParModDigi& operator=(const CbmTrdParModDigi &ref);
-  
-  void      GetModuleInformation(
-          /*Int_t moduleAddress, */const Double_t* local_point, Int_t& sectorId, Int_t& columnId, Int_t& rowId) const;
-
-  void TransformToLocalCorner(
-            const Double_t* local_point,
-            Double_t& posX,
-            Double_t& posY) const;
-
-  void TransformToLocalSector(
-            const Double_t* local_point,
-            Double_t& posX,
-            Double_t& posY) const;
-
-  Int_t GetSector(
-      const Double_t* local_point) const;
-
-  Int_t fNofSectors;    ///< number sectors for this module
-  Int_t fOrientation;   ///< angle between long pad axis and y-axis in steps of 90 deg [0..3]
-  Double_t fAnodeWireOffset;              ///< Anode Wire Offset [cm]
-  Double_t fAnodeWireSpacing;             ///< anode wire pitch [cm]
-  Double_t fAnodeWireToPadPlaneDistance;  ///< Anode Wire to PadPlane Distance [cm]
-
-  Double_t fX;          ///< center of module in global c.s. [cm]
-  Double_t fY;          ///< center of module in global c.s. [cm]
-  Double_t fZ;          ///< center of module in global c.s. [cm]
-  Double_t fSizeX;      ///< module half size in x [cm]
-  Double_t fSizeY;      ///< module half size in y [cm]
-  Double_t fSizeZ;      ///< module half size in z [cm]
-  TArrayD fSectorX;     ///< center of sectors local c.s. [cm]
-  TArrayD fSectorY;     ///< center of sectors local c.s. [cm]
-  TArrayD fSectorZ;     ///< center of sectors local c.s. [cm]
-  TArrayD fSectorBeginX;///< begin of sector [cm]
-  TArrayD fSectorBeginY;///< begin of sector [cm]
-  TArrayD fSectorEndX;  ///< end of sector [cm]
-  TArrayD fSectorEndY;  ///< end of sector [cm]
-  TArrayD fSectorSizeX; ///< sector size in x [cm]
-  TArrayD fSectorSizeY; ///< sector size in y [cm]
-
-  TArrayD fPadSizeX;    ///< size of the readout pad in x [cm]
-  TArrayD fPadSizeY;    ///< size of the readout pad in y [cm]
-
-  ClassDef(CbmTrdParModDigi, 1)  // Definition of read-out parameters for one TRD module
+  const CbmTrdParModDigi &operator=(const CbmTrdParModDigi &ref);
+
+  void GetModuleInformation(
+      /*Int_t moduleAddress, */ const Double_t *local_point, Int_t &sectorId,
+      Int_t &columnId, Int_t &rowId) const;
+
+  void TransformToLocalCorner(const Double_t *local_point, Double_t &posX,
+                              Double_t &posY) const;
+
+  void TransformToLocalSector(const Double_t *local_point, Double_t &posX,
+                              Double_t &posY) const;
+
+  Int_t GetSector(const Double_t *local_point) const;
+
+  Int_t fNofSectors;  ///< number sectors for this module
+  Int_t fOrientation; ///< angle between long pad axis and y-axis in steps of 90
+                      ///deg [0..3]
+  Double_t fAnodeWireOffset;  ///< Anode Wire Offset [cm]
+  Double_t fAnodeWireSpacing; ///< anode wire pitch [cm]
+  Double_t
+      fAnodeWireToPadPlaneDistance; ///< Anode Wire to PadPlane Distance [cm]
+
+  Double_t fX;           ///< center of module in global c.s. [cm]
+  Double_t fY;           ///< center of module in global c.s. [cm]
+  Double_t fZ;           ///< center of module in global c.s. [cm]
+  Double_t fSizeX;       ///< module half size in x [cm]
+  Double_t fSizeY;       ///< module half size in y [cm]
+  Double_t fSizeZ;       ///< module half size in z [cm]
+  TArrayD fSectorX;      ///< center of sectors local c.s. [cm]
+  TArrayD fSectorY;      ///< center of sectors local c.s. [cm]
+  TArrayD fSectorZ;      ///< center of sectors local c.s. [cm]
+  TArrayD fSectorBeginX; ///< begin of sector [cm]
+  TArrayD fSectorBeginY; ///< begin of sector [cm]
+  TArrayD fSectorEndX;   ///< end of sector [cm]
+  TArrayD fSectorEndY;   ///< end of sector [cm]
+  TArrayD fSectorSizeX;  ///< sector size in x [cm]
+  TArrayD fSectorSizeY;  ///< sector size in y [cm]
+
+  TArrayD fPadSizeX; ///< size of the readout pad in x [cm]
+  TArrayD fPadSizeY; ///< size of the readout pad in y [cm]
+
+  ClassDef(CbmTrdParModDigi,
+           1) // Definition of read-out parameters for one TRD module
 };
 
 #endif
diff --git a/core/detectors/trd/CbmTrdParSet.h b/core/detectors/trd/CbmTrdParSet.h
index 8aa2cb5a8291ad8a0dc5dc61fbb349e1318f3dbd..faedf2f4476edee815b17ca23e08ce192d873482 100644
--- a/core/detectors/trd/CbmTrdParSet.h
+++ b/core/detectors/trd/CbmTrdParSet.h
@@ -34,6 +34,7 @@ public:
   virtual Int_t         GetModuleId(Int_t i) const;
   virtual const CbmTrdParMod* GetModulePar(Int_t detId) const;
   virtual Int_t         GetNrOfModules() const { return fNrOfModules; }
+  std::map<Int_t, CbmTrdParMod*> GetModuleMap() { return fModuleMap; }
   virtual void          addParam(CbmTrdParMod *mod);
   virtual Bool_t        getParams(FairParamList*);
   virtual void          putParams(FairParamList*);
diff --git a/core/detectors/trd/CbmTrdParSetAsic.cxx b/core/detectors/trd/CbmTrdParSetAsic.cxx
index 7739952901769a2b8ad0fe43ccd68a1ffc12ce15..a2fafdc620c124bc09e3a618b328cad27f11d007 100644
--- a/core/detectors/trd/CbmTrdParSetAsic.cxx
+++ b/core/detectors/trd/CbmTrdParSetAsic.cxx
@@ -169,7 +169,7 @@ void CbmTrdParSetAsic::putParams(FairParamList *l)
       for (auto iModuleIt : mod->fModuleMap) {
         int offset = iAsicNr * sizePerFasp;
         asicInfo[ offset ] = iModuleIt.first;
-	Int_t nchannels(((CbmTrdParAsic*)iModuleIt.second)->GetNchannels());
+	      Int_t nchannels(((CbmTrdParAsic*)iModuleIt.second)->GetNchannels());
         CbmTrdParFasp *fasp = (CbmTrdParFasp*)iModuleIt.second;
 
         for(Int_t ich(0); ich<nchannels; ich+=2){
diff --git a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.cxx b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.cxx
index 9b7088ef095e3441b3523656f56dff53d19cb0e8..7f7d32cd15b96ee71123c69a63f576e178fe7738 100644
--- a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.cxx
+++ b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.cxx
@@ -1,6 +1,7 @@
 #include "CbmMcbm2018UnpackerAlgoTrdR.h"
 #include "CbmTrdHardwareSetupR.h"
 #include "CbmTrdParSpadic.h"
+#include "CbmTrdParModDigi.h"
 #include "CbmTrdAddress.h"
 
 #include "FairLogger.h"
@@ -10,37 +11,42 @@
 
 #include "TObjString.h"
 #include "TSystem.h"
+#include "TH2I.h"
+#include "TProfile.h"
+#include "TVector3.h"
 
 #include <iostream>
 #include <map>
 
 CbmMcbm2018UnpackerAlgoTrdR::CbmMcbm2018UnpackerAlgoTrdR()
-    : CbmStar2019Algo(),
-      //fRawToDigi( new CbmTrdRawToDigiR ),
-      fdMsSizeInCC(0),
-      fbMonitorMode(kFALSE),
-      fbDebugMonitorMode(kFALSE),
-      fbWriteOutput(kTRUE),
-      fbDebugWriteOutput(kFALSE),
-      fbBaselineAvg(kFALSE),
-      fTrdDigiVector(nullptr),
-      fTrdRawMessageVector(nullptr),
-      fSpadicInfoMsgVector(nullptr),
-      //fHistoMap(),
-      fHistoArray(),
-      fNbTimeslices(0),
-      fCurrTsIdx(0),
-      fMsIndex(0),
-      fTsStartTime(0.0),
-      fTsStopTimeCore(0.0),
-      fMsTime(0.0),
-      fSpadicEpoch(0),
-      fLastFulltime(0),
-      fNbSpadicRawMsg(0),
-      fNbWildRda(0),
-      fNbSpadicErrorMsg(0),
-      fNbUnkownWord(0),
-      fNbSpadicEpochMsg(0)
+    : CbmStar2019Algo()
+      //, fRawToDigi( new CbmTrdRawToDigiR )
+      , fdMsSizeInCC(0)
+      , fbMonitorMode(kFALSE)
+      , fbDebugMonitorMode(kFALSE)
+      , fbWriteOutput(kTRUE)
+      , fbDebugWriteOutput(kFALSE)
+      , fbBaselineAvg(kFALSE)
+      , fTrdDigiVector(nullptr)
+      , fTrdRawMessageVector(nullptr)
+      , fSpadicInfoMsgVector(nullptr)
+      //, fHistoMap()
+      , fIsActiveHistoVec(ECbmTrdUnpackerHistograms::kEndDefinedHistos, false)
+      , fHistoArray()
+      , fLastDigiTimeVec()
+      , fNbTimeslices(0)
+      , fCurrTsIdx(0)
+      , fMsIndex(0)
+      , fTsStartTime(0.0)
+      , fTsStopTimeCore(0.0)
+      , fMsTime(0.0)
+      , fSpadicEpoch(0)
+      , fLastFulltime(0)
+      , fNbSpadicRawMsg(0)
+      , fNbWildRda(0)
+      , fNbSpadicErrorMsg(0)
+      , fNbUnkownWord(0)
+      , fNbSpadicEpochMsg(0)
       , fParContList(nullptr)
       , fRefGeoTag("trd_v18q_mcbm")
       , fAsicPar(nullptr)
@@ -66,7 +72,7 @@ Bool_t CbmMcbm2018UnpackerAlgoTrdR::Init()
     LOG(debug) << "Initializing CbmMcbm2018UnpackerAlgoTrdR";
     //fRawToDigi->Init();
     fbIgnoreOverlapMs = kTRUE ;
-    fdMsSizeInNs = 1.28e6; //FIXME time should come from parameter file
+    // fdMsSizeInNs = 1.28e6; //FIXME time should come from parameter file
     fdMsSizeInCC = fdMsSizeInNs / 62.5;
 
     return kTRUE ;
@@ -211,6 +217,14 @@ Bool_t CbmMcbm2018UnpackerAlgoTrdR::ProcessTs(const fles::Timeslice &ts)
 
             if (kFALSE == ProcessMs(ts, uMsComp, MsIndex))
             {
+                /// Sort the output vector according to the time
+                /// => this assumes all digis before failure were OK. If not we should instead clear it!
+                std::sort(fTrdDigiVector->begin(), fTrdDigiVector->end(),
+                    [](const CbmTrdDigi & a, const CbmTrdDigi & b) -> bool
+                    {
+                      return a.GetTime() < b.GetTime();
+                    });
+
                 LOG(error) << "Failed to process ts " << fCurrTsIdx << " MS " << MsIndex
                            << " for component " << uMsComp;
                 return kFALSE;
@@ -232,9 +246,9 @@ Bool_t CbmMcbm2018UnpackerAlgoTrdR::ProcessTs(const fles::Timeslice &ts)
 Bool_t CbmMcbm2018UnpackerAlgoTrdR::ProcessMs(const fles::Timeslice &ts, size_t uMsCompIdx, size_t uMsIdx)
 {
     fles::MicrosliceDescriptor msDesc = ts.descriptor(uMsCompIdx, uMsIdx ) ;
-//    uint16_t msEquipmentID = msDesc.eq_id;   ///< Equipment identifier. Specifies the FLES input link. #FU 27.03.20 unused
+    // uint16_t msEquipmentID = msDesc.eq_id;   ///< Equipment identifier. Specifies the FLES input link. #FU 27.03.20 unused
     uint32_t msSize = msDesc.size;     ///< Content size. This is the size (in bytes) of the microslice data content.
-//    uint64_t msTime = msDesc.idx;      ///< Start time of the microslice in ns since global time zero. #FU 27.03.20 unused
+    // uint64_t msTime = msDesc.idx;      ///< Start time of the microslice in ns since global time zero. #FU 27.03.20 unused
     uint32_t msNbWords = ( msSize - (msSize % kBytesPerWord )) / kBytesPerWord ;   ///< Number of complete Words in the input MS buffer.
 
     const uint8_t * msPointer = reinterpret_cast<const uint8_t*>( ts.content( uMsCompIdx, uMsIdx ) );
@@ -277,51 +291,20 @@ Bool_t CbmMcbm2018UnpackerAlgoTrdR::ProcessMs(const fles::Timeslice &ts, size_t
 
             /// Message should now be complete. TODO: Generate Digi and save raw message if needed.
             std::shared_ptr<CbmTrdDigi> digi = MakeDigi(raw);
-            fTrdDigiVector->push_back(*digi);
-
+            if(digi)    fTrdDigiVector->emplace_back(*digi);
             /// Save raw message:
             if ( fbDebugWriteOutput && (fTrdRawMessageVector != nullptr) )
             {
-                fTrdRawMessageVector->push_back(raw) ;
+                fTrdRawMessageVector->emplace_back(raw) ;
             }
 
-
             /// Fill histograms:
             if (fbMonitorMode || fbDebugMonitorMode )
             {
-                TString HistName = "RawMessage_Signalshape_all";
-                for (unsigned int i = 0; i < raw.GetSamples().size(); i++)
-                {
-                    //fHistoMap.at(HistName.Data())->Fill(i, raw.GetSamples()[i]);
-                    ((TH2I*)fHistoArray.FindObject(HistName.Data()))->Fill(i, raw.GetSamples()[i]) ;
-                }
-
-                if (raw.GetChannelId() == 9 && raw.GetElinkId() == 0 )//&& ( iWord >= msNbWords-10  || iWord <= 10 ) )
-                {
-                    HistName = "Delta_T";
-                    Long64_t dt = ((Long64_t)raw.GetFullTime() - (Long64_t)fLastFulltime);
-                    //if ( dt != 0 )
-                    //if ( abs(dt) > 2048 ) LOG(warning) << "[CbmMcbm2018UnpackerAlgoTrdR::ProcessMs]  |dt| = " << dt ;
-                    //if (dt<0)
-                        //std::cout << "[CbmMcbm2018UnpackerAlgoTrdR::ProcessMs]  dt = " << dt << std::endl ;
-                    /*std::cout << raw.GetFullTime() << std::endl;
-                    std::cout << fLastFulltime << std::endl; */
-                    ((TH1I *)fHistoArray.FindObject(HistName.Data()))->Fill(dt);
-                    fLastFulltime = raw.GetFullTime();
-                }
-
-                if (raw.GetHitType() < 2 && !raw.GetMultiHit())
-                {
-                    HistName = "RawMessage_Signalshape_filtered";
-                    for (unsigned int i = 0; i < raw.GetSamples().size(); i++)
-                    {
-                        //fHistoMap.at(HistName.Data())->Fill(i, raw.GetSamples()[i]);
-                        ((TH2I*)fHistoArray.FindObject(HistName.Data()))->Fill(i, raw.GetSamples()[i]) ;
-                    }
-                }
+                FillHistograms(); // fill histograms not based on digi or rawMessage input
+                if(digi && fbMonitorMode) if(!FillHistograms(*digi)) LOG(error) << "Failed to fill CbmTrdDigi histograms"; // fill digi histograms
+                if(fbDebugMonitorMode)    if(!FillHistograms(raw)) LOG(error) << "Failed to fill CbmTrdRawMessageSpadic histograms";  // fill rawMessage histograms
             }
-
-
         } // endif (wordType == kSOM )
 
         if ( wordType == Spadic::MsMessageType::kRDA )
@@ -336,26 +319,16 @@ Bool_t CbmMcbm2018UnpackerAlgoTrdR::ProcessMs(const fles::Timeslice &ts, size_t
             /// Save info message if needed.
             if (fbDebugWriteOutput && (fSpadicInfoMsgVector != nullptr))
             {
-                fSpadicInfoMsgVector->push_back(std::make_pair(fLastFulltime, curWord));
+                fSpadicInfoMsgVector->emplace_back(std::make_pair(fLastFulltime, curWord));
             }
             fNbSpadicErrorMsg++;
 
             Spadic::MsInfoType infoType = GetInfoType(curWord);
-            TString HistName = "Spadic_Info_Types";
-            ((TH2I*)fHistoArray.FindObject(HistName.Data()))->Fill(fLastFulltime, (Int_t)infoType) ;
-
-/* FU 270320 Only for debug purpose see Redmine issue #1653
-            Int_t channel = 0;
-            if ( infoType != Spadic::MsInfoType::kMIS )
+            // "Spadic_Info_Types";
+            if(fIsActiveHistoVec[kSpadic_Info_Types])
             {
-                uint64_t mask = 0x0F;
-                channel = (Int_t)( curWord & mask );
+                ((TH2I*)fHistoArray.At(kSpadic_Info_Types))->Fill(fLastFulltime, (Int_t)infoType) ;
             }
-
-            uint8_t elink = 0;
-            uint64_t mask = 0x3F ;
-            elink = (uint8_t)((curWord >> 54 ) & mask );
-*/
         }
 
         if ( wordType == Spadic::MsMessageType::kNUL )
@@ -378,7 +351,7 @@ Bool_t CbmMcbm2018UnpackerAlgoTrdR::ProcessMs(const fles::Timeslice &ts, size_t
             mask = mask << 32;
             uint64_t uTS_MSB = (uint64_t)((curWord & mask) >> 32);
             Long64_t dt_epoch = uTS_MSB - fSpadicEpoch;
-            if ( dt_epoch != 1 ) LOG(warning) << "[CbmMcbm2018UnpackerAlgoTrdR::ProcessMs]  dt_epoch = " << dt_epoch ;
+            if ( dt_epoch != 1 ) LOG(debug4) << "[CbmMcbm2018UnpackerAlgoTrdR::ProcessMs]  dt_epoch = " << dt_epoch ;
 
             //fLastFulltime = uTS_MSB;
             fNbSpadicEpochMsg++;
@@ -397,8 +370,8 @@ void CbmMcbm2018UnpackerAlgoTrdR::AddMsComponentToList(size_t component, UShort_
         if (component == fvMsComponentsList[uCompIdx])
             return;
 
-    /// Add to lis
-    fvMsComponentsList.push_back(component);
+    /// Add to list
+    fvMsComponentsList.emplace_back(component);
 
     LOG(info) << "CbmMcbm2018UnpackerAlgoTrdR::AddMsComponentToList => Component "
               << component << " with detector ID 0x"
@@ -417,54 +390,377 @@ Bool_t CbmMcbm2018UnpackerAlgoTrdR::CreateHistograms()
 {
     if (!fbMonitorMode && !fbDebugMonitorMode )
         return kFALSE;
-    /*
-    TString HistName = "RawMessage_Signalshape_all";
-    fHistoMap.insert(std::make_pair(HistName.Data(), std::make_shared<TH2I>(TH2I(HistName.Data(), HistName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5))));
-    AddHistoToVector(fHistoMap.at(HistName.Data()).get(), "");
 
-    HistName = "RawMessage_Signalshape_filtered";
-    fHistoMap.insert(std::make_pair(HistName.Data(), std::make_shared<TH2I>(TH2I(HistName.Data(), HistName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5))));
-    AddHistoToVector(fHistoMap.at(HistName.Data()).get(), "");
-    */
     fHistoArray.SetOwner(kTRUE);
 
-    TString HistName = "RawMessage_Signalshape_all";
-    fHistoArray.Add(new TH2I(HistName.Data(), HistName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5) );
-    AddHistoToVector( (TH2I*)fHistoArray.Last(), "");
+    Bool_t createHistosOk = kTRUE;
+    Int_t iHisto(ECbmTrdUnpackerHistograms::kBeginDefinedHistos);
+    for (auto isActive : fIsActiveHistoVec)
+    {
+        if(isActive)
+        {
+            createHistosOk &= CreateHistogram((ECbmTrdUnpackerHistograms)iHisto);
+        }
+        iHisto++;
+    }
+
+    return createHistosOk;
+}
+
+// ----    CreateHistogram    ----
+Bool_t CbmMcbm2018UnpackerAlgoTrdR::CreateHistogram(ECbmTrdUnpackerHistograms iHisto)
+{
+    Bool_t createHistoOk = kFALSE;
+    TString histName = "";
+    TH1 *newHisto = nullptr;
+    std::map<Int_t, CbmTrdParMod*> parDigiModuleMap = (std::map<Int_t, CbmTrdParMod*>)fDigiPar->GetModuleMap();
+    // Raw Message Histos still need to be separated into module wise histo
+    for (auto mapIt : parDigiModuleMap)
+    {
+        CbmTrdParModDigi* parDigiModule = (CbmTrdParModDigi*) mapIt.second;
+        Int_t moduleId = parDigiModule->GetModuleId();
+        histName.Form("Module%d-", moduleId);
+        switch (iHisto)
+        {
+        case kRawMessage_Signalshape_all:
+            histName += "RawMessage_Signalshape_all";
+            newHisto = new TH2I(histName.Data(), histName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5);
+            newHisto->SetXTitle("time [cc]");
+            newHisto->SetYTitle("Pulse height [ADC channels]");
+            break;
+        case kRawMessage_Signalshape_St:
+            histName += "RawMessage_Signalshape_St";
+            newHisto = new TH2I(histName.Data(), histName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5);
+            newHisto->SetXTitle("time [cc]");
+            newHisto->SetYTitle("Pulse height [ADC channels]");
+            break;
+        case kRawMessage_Signalshape_Nt:
+            histName += "RawMessage_Signalshape_Nt";
+            newHisto = new TH2I(histName.Data(), histName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5);
+            newHisto->SetXTitle("time [cc]");
+            newHisto->SetYTitle("Pulse height [ADC channels]");
+            break;
+        case kRawMessage_Signalshape_filtered:
+            histName += "RawMessage_Signalshape_filtered";
+            newHisto = new TH2I(histName.Data(), histName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5);
+            break;
+        case kRawDistributionMapModule5 :
+            histName += "RawDistributionMapModule5";
+            newHisto = new TH2I(histName.Data(), histName.Data(), 42, -0.5, 41.5, 16, -0.5, 15.5);
+            break;
+        case kRawHitType :
+            histName += "RawHitTypes";
+            newHisto = new TH1I(histName.Data(), histName.Data(), ((Int_t)Spadic::TriggerType::kSandN + 1), ((Int_t)Spadic::TriggerType::kGlobal - 0.5), ((Int_t)Spadic::TriggerType::kSandN) + 0.5);
+            break;
+        case kRawPulserDeltaT:
+            histName += "RawPulserDeltaT";
+            newHisto = new TH1I(histName.Data(), histName.Data(), 40000, 0, 4000000);
+            newHisto->SetXTitle("#Delta t [cc]");
+            newHisto->SetYTitle("Counts");
+            break;
+        case kSpadic_Info_Types:
+            histName += "Spadic_Info_Types";
+            newHisto = new TH2I(histName.Data(), histName.Data(), 500000, 0, 5e9, 5, -0.5, 4.5);
+            ((TH2I*)newHisto)->SetXTitle("t /Clockcycles") ;
+            ((TH2I*)newHisto)->SetYTitle("messagetype") ;
+            ((TH2I*)newHisto)->GetYaxis()->SetBinLabel(1,"BOM") ;
+            ((TH2I*)newHisto)->GetYaxis()->SetBinLabel(2,"MSB") ;
+            ((TH2I*)newHisto)->GetYaxis()->SetBinLabel(3,"BUF") ;
+            ((TH2I*)newHisto)->GetYaxis()->SetBinLabel(4,"UNU") ;
+            ((TH2I*)newHisto)->GetYaxis()->SetBinLabel(5,"MIS") ;
+            break;
+        case kDigiPulserDeltaT:
+            histName += "DigiPulserDeltaT";
+            newHisto = new TH1I(histName.Data(), histName.Data(), 60000, 0, 6e8);
+            newHisto->SetXTitle("#Delta t [ns]");
+            newHisto->SetYTitle("Counts");
+            break;
+        case kDigiDeltaT :
+            histName += "DigiDeltaT";
+            newHisto = new TH1I(histName.Data(), histName.Data(), 6000, -10, ((6e7)-10));
+            // FIXME this should be more flexibel and made available for all modules of a given geometry
+            fLastDigiTimeVec = std::vector<std::uint64_t>(((CbmTrdParModDigi*)fDigiPar->GetModulePar(5))->GetNofColumns()*((CbmTrdParModDigi*)fDigiPar->GetModulePar(5))->GetNofRows(), 0);
+            newHisto->SetXTitle("#Delta t [ns]");
+            newHisto->SetYTitle("Counts");
+            break;
+        case kDigiMeanHitFrequency :
+            histName += "DigiMeanHitFrequency";
+            newHisto = new TProfile(histName.Data(), histName.Data(), parDigiModule->GetNofColumns()* parDigiModule->GetNofRows(), -0.5, parDigiModule->GetNofColumns()* parDigiModule->GetNofRows()-0.5);
+            // FIXME this should be more flexibel and made available for all modules of a given geometry
+            fLastDigiTimeVec = std::vector<std::uint64_t>(((CbmTrdParModDigi*)fDigiPar->GetModulePar(5))->GetNofColumns()*((CbmTrdParModDigi*)fDigiPar->GetModulePar(5))->GetNofRows(), 0);
+            newHisto->SetXTitle("Pad-Channel");
+            newHisto->SetYTitle("Hit frequency [kHz]");
+            break;
+        case kDigiDistributionMap:
+            histName += "DigiDistributionMap";
+            newHisto = new TH2I(histName.Data(), histName.Data(), parDigiModule->GetNofColumns(), -0.5, (parDigiModule->GetNofColumns() - 0.5), parDigiModule->GetNofRows(), -0.5, (parDigiModule->GetNofRows() - 0.5));
+            // newHisto = new TH2I(histName.Data(), histName.Data(), 128, -0.5, 127.5, 6, -0.5, 5.5);  // invert row value since they are count from top to bottom
+            newHisto->SetXTitle("Pad column");
+            newHisto->SetYTitle("Pad row");
+            break;
+        case kDigiDistributionMapSt:
+            histName += "DigiDistributionMapSt";
+            newHisto = new TH2I(histName.Data(), histName.Data(), parDigiModule->GetNofColumns(), -0.5, (parDigiModule->GetNofColumns() - 0.5), parDigiModule->GetNofRows(), -0.5, (parDigiModule->GetNofRows() - 0.5));
+            // newHisto = new TH2I(histName.Data(), histName.Data(), 128, -0.5, 127.5, 6, -0.5, 5.5);  // invert row value since they are count from top to bottom
+            newHisto->SetXTitle("Pad column");
+            newHisto->SetYTitle("Pad row");
+            break;
+        case kDigiDistributionMapNt:
+            histName += "DigiDistributionMapNt";
+            newHisto = new TH2I(histName.Data(), histName.Data(), parDigiModule->GetNofColumns(), -0.5, (parDigiModule->GetNofColumns() - 0.5), parDigiModule->GetNofRows(), -0.5, (parDigiModule->GetNofRows() - 0.5));
+            // newHisto = new TH2I(histName.Data(), histName.Data(), 128, -0.5, 127.5, 6, -0.5, 5.5);  // invert row value since they are count from top to bottom
+            newHisto->SetXTitle("Pad column");
+            newHisto->SetYTitle("Pad row");
+            break;
+        case kDigiChargeSpectrum :
+            histName += "DigiChargeSpectrum";
+            newHisto = new TH1I(histName.Data(), histName.Data(), 512, 0, 512);
+            newHisto->SetYTitle("Counts");
+            newHisto->SetXTitle("MaxAdc [ADC channels]");
+            break;
+        case kDigiChargeSpectrumSt :
+            histName += "DigiChargeSpectrumSt";
+            newHisto = new TH1I(histName.Data(), histName.Data(), 512, 0, 512);
+            newHisto->SetYTitle("Counts");
+            newHisto->SetXTitle("MaxAdc [ADC channels]");
+            break;
+        case kDigiChargeSpectrumNt :
+            histName += "DigiChargeSpectrumNt";
+            newHisto = new TH1I(histName.Data(), histName.Data(), 512, 0, 512);
+            newHisto->SetYTitle("Counts");
+            newHisto->SetXTitle("MaxAdc [ADC channels]");
+            break;
+        case kDigiRelativeTimeMicroslice :
+            histName += "DigiRelativeTimeMicroslice";
+            newHisto = new TH1D(histName.Data(), histName.Data(), fdMsSizeInNs, 0, fdMsSizeInNs);
+            break;
+        case kDigiTriggerType :
+            histName += "DigiTriggerType";
+            newHisto = new TH1I(histName.Data(), histName.Data(), CbmTrdDigi::kNTrg, -0.5,(CbmTrdDigi::kNTrg - 0.5));
+            break;
+        case kDigiHitFrequency :
+            histName += "DigiHitFrequency";
+            newHisto = new TProfile(histName.Data(), histName.Data(), 100000, 0, 100000);
+            newHisto->SetXTitle("Timeslice");
+            newHisto->SetYTitle("#langle hit frequency #rangle");
+            break;
+        default :
+            return createHistoOk;
+            break;
+        }
+        LOG(debug4) << Form("UnpackerTrdAlgo - Histo[%d]-%s - initialize", iHisto, histName.Data());
+        if(newHisto)
+        {
+            TString moduleName(Form("%d", moduleId));
+            if(iHisto < kBeginDigiHistos)
+            {
+                fHistoArray.AddAtAndExpand(newHisto, iHisto);
+            }
+            else
+            {
+                Int_t bitShift = Int_t(std::log2(std::double_t(kEndDefinedHistos))) + 1;
+                Int_t histoPosition = moduleId << bitShift;
+                histoPosition += iHisto;
+                if(iHisto >= kBeginDigiHistos) fHistoArray.AddAtAndExpand(newHisto, histoPosition);
+            }
+            // If new HistosTypes are added, they need to be added here!
+            if(newHisto->IsA() == TProfile::Class())  AddHistoToVector( (TProfile*)newHisto, moduleName.Data());
 
-    HistName = "RawMessage_Signalshape_filtered";
-    fHistoArray.Add(new TH2I(HistName.Data(), HistName.Data(), 32, -0.5, 31.5, 512, -256.5, 255.5) );
-    AddHistoToVector( (TH2I*)fHistoArray.Last(), "");
+            if(newHisto->IsA() == TH2I::Class())  AddHistoToVector( (TH2I*)newHisto, moduleName.Data());
 
-    HistName = "Delta_T";
-    fHistoArray.Add(new TH1I(HistName.Data(), HistName.Data(), 202500, -2500, 200000) );
-    AddHistoToVector( (TH1I*)fHistoArray.Last(), "");
+            if(newHisto->IsA() == TH1I::Class())  AddHistoToVector( (TH1I*)newHisto, moduleName.Data());
 
-    HistName = "Spadic_Info_Types";
-    fHistoArray.Add(new TH2I(HistName.Data(), HistName.Data(), 500000, 0, 5e9, 5, -0.5, 4.5) );
-    ((TH2I*)fHistoArray.Last())->SetXTitle("t /Clockcycles") ;
-    ((TH2I*)fHistoArray.Last())->SetYTitle("messagetype") ;
-    ((TH2I*)fHistoArray.Last())->GetYaxis()->SetBinLabel(1,"BOM") ;
-    ((TH2I*)fHistoArray.Last())->GetYaxis()->SetBinLabel(2,"MSB") ;
-    ((TH2I*)fHistoArray.Last())->GetYaxis()->SetBinLabel(3,"BUF") ;
-    ((TH2I*)fHistoArray.Last())->GetYaxis()->SetBinLabel(4,"UNU") ;
-    ((TH2I*)fHistoArray.Last())->GetYaxis()->SetBinLabel(5,"MIS") ;
-    AddHistoToVector( (TH2I*)fHistoArray.Last(), "");
+            if(newHisto->IsA() == TH1D::Class())  AddHistoToVector( (TH1D*)newHisto, moduleName.Data());
 
-    if (fbDebugMonitorMode)
-    {
-        //create additional histograms here.
+            createHistoOk = kTRUE;
+        }
     }
+    return createHistoOk;
+}
 
+Bool_t CbmMcbm2018UnpackerAlgoTrdR::FillHistograms()
+{
     return kTRUE;
 }
 
-Bool_t CbmMcbm2018UnpackerAlgoTrdR::FillHistograms()
+// ----    FillHistograms(CbmTrdDigi)    ----
+Bool_t CbmMcbm2018UnpackerAlgoTrdR::FillHistograms(CbmTrdDigi const &digi)
+{
+    Bool_t isOkFill = kTRUE;
+    Int_t channelAddress = digi.GetAddressChannel();
+    Int_t histoBaseId = digi.GetAddressModule() << (Int_t(std::log2(std::double_t(kEndDefinedHistos))) + 1);
+    //Digi position monitoring
+    if(fIsActiveHistoVec[kDigiDistributionMap] || fIsActiveHistoVec[kDigiDistributionMapSt] || fIsActiveHistoVec[kDigiDistributionMapNt])
+    {   
+        CbmTrdParModDigi *parModDigi = (CbmTrdParModDigi*) fDigiPar->GetModulePar(digi.GetAddressModule());
+        Int_t rotatedAddress = parModDigi->GetOrientation() == 2 ? (channelAddress*(-1) + (parModDigi->GetNofRows() * parModDigi->GetNofColumns()) - 1) : channelAddress;
+        Int_t row = parModDigi->GetPadRow(rotatedAddress);
+        Int_t column = parModDigi->GetPadColumn(rotatedAddress);
+
+        // "DigiDistributionModule5"
+        if(fIsActiveHistoVec[kDigiDistributionMap])
+        {
+            ((TH2I*)fHistoArray.At(histoBaseId+kDigiDistributionMap))->Fill(column, row);
+        }
+        if(fIsActiveHistoVec[kDigiDistributionMapSt])
+        {
+            if(digi.GetAddressModule() == 5 && digi.GetTriggerType() == CbmTrdDigi::kSelf) ((TH2I*)fHistoArray.At(histoBaseId+kDigiDistributionMapSt))->Fill(column, row);
+        }
+        if(fIsActiveHistoVec[kDigiDistributionMapNt])
+        {
+            if(digi.GetAddressModule() == 5 && digi.GetTriggerType() == CbmTrdDigi::kNeighbor) ((TH2I*)fHistoArray.At(histoBaseId+kDigiDistributionMapNt))->Fill(column, row);
+        }
+    }
+    // "DigiRelativeTinTimeslice"
+    if(fIsActiveHistoVec[kDigiRelativeTimeMicroslice])
+    {
+        std::uint64_t digiTime = digi.GetTime();
+        std::uint64_t deltaT = digiTime - (fSpadicEpoch * fdMsSizeInCC * 62.5); // in clockcycles
+        ((TH1D*)fHistoArray.At(histoBaseId+kDigiRelativeTimeMicroslice))->Fill( deltaT );
+    }
+    // "kDigiChargeSpectrum"
+    if(fIsActiveHistoVec[kDigiChargeSpectrum])
+    {
+        ((TH1I*)fHistoArray.At(histoBaseId+kDigiChargeSpectrum))->Fill( digi.GetCharge());
+    }
+    // "kDigiChargeSpectrumSt"
+    if(fIsActiveHistoVec[kDigiChargeSpectrumSt])
+    {
+        if(digi.GetTriggerType() == CbmTrdDigi::kSelf)
+        ((TH1I*)fHistoArray.At(histoBaseId+kDigiChargeSpectrumSt))->Fill( digi.GetCharge());
+    }
+    // "kDigiChargeSpectrumNt"
+    if(fIsActiveHistoVec[kDigiChargeSpectrumNt])
+    {
+        if(digi.GetTriggerType() == CbmTrdDigi::kNeighbor) ((TH1I*)fHistoArray.At(histoBaseId+kDigiChargeSpectrumNt))->Fill( digi.GetCharge());
+    }
+    // "kDigiChargeSpectrumNt"
+    if(fIsActiveHistoVec[kDigiTriggerType])
+    {
+        ((TH1I*)fHistoArray.At(histoBaseId+kDigiTriggerType))->Fill( digi.GetTriggerType());
+    }
+
+
+
+    // "kDigiDeltaT" // DigiPulserDeltaT // "kDigiMeanHitFrequency" // FIXME this works currently with only one module
+    if(fIsActiveHistoVec[kDigiDeltaT] || fIsActiveHistoVec[kDigiMeanHitFrequency] || fIsActiveHistoVec[kDigiPulserDeltaT])
+    {
+        std::uint64_t dt = ((std::uint64_t)digi.GetTime() - fLastDigiTimeVec.at(channelAddress));
+        if(dt > 0)
+        {
+            // "kDigiDeltaT"
+            if(fIsActiveHistoVec[kDigiDeltaT])
+            {
+                ((TH1I*)fHistoArray.At(histoBaseId+kDigiDeltaT))->Fill(dt);
+            }
+            // "kDigiMeanHitFrequency"
+            if(fIsActiveHistoVec[kDigiMeanHitFrequency])
+            {
+                if(dt > 0 && dt < fdTsFullSizeInNs)
+                {
+                    Double_t hitFreq = (Double_t) dt;
+                    hitFreq *= 1e-9;
+                    hitFreq = 1.0/hitFreq;
+                    hitFreq /= 1000.0;
+                    ((TProfile*)fHistoArray.At(histoBaseId+kDigiMeanHitFrequency))->Fill(channelAddress, hitFreq);
+                }
+            }
+            // DigiPulserDeltaT
+            if(fIsActiveHistoVec[kDigiPulserDeltaT])
+            {
+                Int_t pulserChannelAddress(663);   // status 03/27/2020
+                Int_t pulserModule(5);     // status 03/27/2020
+                if( channelAddress == pulserChannelAddress && digi.GetAddressModule() == pulserModule && digi.GetTriggerType() == CbmTrdDigi::kSelf )
+                {
+                    ((TH1I *)fHistoArray.At(histoBaseId+kDigiPulserDeltaT))->Fill(dt);
+                }
+            }
+            // "kDigiMeanHitFrequency"
+            if(fIsActiveHistoVec[kDigiHitFrequency])
+            {
+                if(dt > 0 && dt < fdTsFullSizeInNs)
+                {
+                    Int_t tsCounter = fNbTimeslices % ((TProfile*)fHistoArray.At(histoBaseId+kDigiHitFrequency))->GetNbinsX();
+                    Double_t hitFreq = (Double_t) dt;
+                    hitFreq *= 1e-9;
+                    hitFreq = 1.0/hitFreq;
+                    hitFreq /= 1000.0;
+                    ((TProfile*)fHistoArray.At(histoBaseId+kDigiHitFrequency))->Fill(tsCounter, hitFreq);
+                    if(tsCounter == 0) ((TProfile*)fHistoArray.At(histoBaseId+kDigiHitFrequency))->Reset();
+                }
+            }
+            fLastDigiTimeVec.at(channelAddress) = (std::uint64_t)digi.GetTime();
+        }
+    }
+    return isOkFill;
+}
+
+// ----    FillHistograms(CbmTrdSpadicRawMessage)    ----
+Bool_t CbmMcbm2018UnpackerAlgoTrdR::FillHistograms(CbmTrdRawMessageSpadic const &raw)
 {
-    // Histograms are being filled in the main message loop in CbmMcbm2018UnpackerAlgoTrdR::ProcessMs.
-  return kTRUE; 
+    Bool_t isOkFill = kTRUE;
+    // "RawMessage_Signalshape_filtered"
+    if(fIsActiveHistoVec[kRawMessage_Signalshape_filtered])
+    {
+        if (raw.GetHitType() < 2 && !raw.GetMultiHit())
+        {
+            for (unsigned int i = 0; i < raw.GetSamples().size(); i++)
+            {
+                ((TH2I*)fHistoArray.At(kRawMessage_Signalshape_filtered))->Fill(i, raw.GetSamples()[i]) ;
+            }
+        }
+    }
+        // "RawMessage_Signalshape_all"
+    if(fIsActiveHistoVec[kRawMessage_Signalshape_all])
+    {
+        for (unsigned int i = 0; i < raw.GetSamples().size(); i++)
+        {
+            //fHistoMap.at(HistName.Data())->Fill(i, raw.GetSamples()[i]);
+            ((TH2I*)fHistoArray.At(kRawMessage_Signalshape_all))->Fill(i, raw.GetSamples()[i]);
+        }
+    }
+    // "kRawMessage_Signalshape_St"
+    if(fIsActiveHistoVec[kRawMessage_Signalshape_St])
+    {
+        for (unsigned int i = 0; i < raw.GetSamples().size(); i++)
+        {
+            if( raw.GetHitType() == (Int_t)Spadic::TriggerType::kSelf || raw.GetHitType() == (Int_t)Spadic::TriggerType::kSandN )   ((TH2I*)fHistoArray.At(kRawMessage_Signalshape_St))->Fill(i, raw.GetSamples()[i]);
+        }
+    }
+    // "kRawMessage_Signalshape_Nt"
+    if(fIsActiveHistoVec[kRawMessage_Signalshape_Nt])
+    {
+        for (unsigned int i = 0; i < raw.GetSamples().size(); i++)
+        {
+            if( raw.GetHitType() == (Int_t)Spadic::TriggerType::kNeigh )   ((TH2I*)fHistoArray.At(kRawMessage_Signalshape_Nt))->Fill(i, raw.GetSamples()[i]);
+        }
+    }
+    // "RawDistributionMapModule5"
+    if(fIsActiveHistoVec[kRawDistributionMapModule5])
+    {
+        ((TH1I *)fHistoArray.At(kRawDistributionMapModule5))->Fill(raw.GetElinkId(), raw.GetChannelId());
+    }
+    // "kRawHitType"
+    if(fIsActiveHistoVec[kRawHitType])
+    {
+        ((TH1I*)fHistoArray.At(kRawHitType))->Fill( raw.GetHitType());
+    }
+    // "RawPulserDeltaT"
+    if(fIsActiveHistoVec[kRawPulserDeltaT])
+    {
+        std::uint8_t pulserChannelId = 0;   // status 03/27/2020
+        std::uint8_t pulserElinkId = 29;     // status 03/27/2020
+        if(raw.GetChannelId() == pulserChannelId && raw.GetElinkId() == pulserElinkId )
+        {
+            Long64_t dt = ((Long64_t)raw.GetFullTime() - (Long64_t)fLastFulltime);
+            ((TH1I *)fHistoArray.At(kRawPulserDeltaT))->Fill(dt);
+            fLastFulltime = raw.GetFullTime();
+        }
+    }
+    return isOkFill;
 }
 
+
 Bool_t CbmMcbm2018UnpackerAlgoTrdR::ResetHistograms()
 {
     /*
@@ -476,7 +772,7 @@ Bool_t CbmMcbm2018UnpackerAlgoTrdR::ResetHistograms()
 
     for ( auto it = fHistoArray.begin() ; it != fHistoArray.end() ; ++it )
     {
-        ((TH2I*)*it)->Reset();
+        ((TH1*)*it)->Reset();
     }
     return kTRUE;
 
@@ -523,9 +819,14 @@ Bool_t CbmMcbm2018UnpackerAlgoTrdR::SetRawOutputPointer(std::vector<CbmTrdRawMes
 std::shared_ptr<CbmTrdDigi> CbmMcbm2018UnpackerAlgoTrdR::MakeDigi(CbmTrdRawMessageSpadic raw)
 {
     Int_t digiAddress = -1;
-    Float_t digiCharge = (Float_t)raw.GetMaxAdc();
-    ULong64_t digiTime = raw.GetFullTime();
-    Int_t digiTriggerType = raw.GetHitType() ; // Spadic::TriggerType
+    Float_t digiCharge = (Float_t)raw.GetMaxAdc() + 256; // REMARK raw.GetMaxADC returns a the value in the range of -256 til 255. However, the digiCharge is stored as unsigned.  // TODO make Settable
+    ULong64_t digiTime = raw.GetFullTime_ns() - fdTimeOffsetNs;
+    // Int_t digiTriggerType = raw.GetHitType() ; // Spadic::TriggerType this does not work 03/27/2020 - PR digiTriggerType is not Spadic::TriggerType!
+    Int_t digiTriggerType = raw.GetHitType();
+    if(digiTriggerType == 1) digiTriggerType = 0; // Shift self trigger to digi selftrigger
+    if(digiTriggerType == 2) digiTriggerType = 1; // Shift neighbour trigger to digi neighbour
+    if(digiTriggerType == 3) digiTriggerType = 0; // Hide spadic kSandN in Self
+
     Int_t digiErrClass = 0;
 
     std::uint64_t spadicHwAddress(0);
@@ -533,7 +834,13 @@ std::shared_ptr<CbmTrdDigi> CbmMcbm2018UnpackerAlgoTrdR::MakeDigi(CbmTrdRawMessa
                     + (CbmTrdParAsic::kCriIdPosition * raw.GetCriId())
                     + (CbmTrdParAsic::kCrobIdPosition * raw.GetCrobId());
     Int_t asicAddress(0);
-    asicAddress = (fSpadicMap.find(spadicHwAddress))->second;
+    auto mapIt = fSpadicMap.find(spadicHwAddress);  // check if asic exists
+    if(mapIt == fSpadicMap.end())
+    {
+        LOG(debug4) << Form("CbmMcbm2018UnpackerAlgoTrdR::MakeDigi - No asic address found for Spadic hardware address %lu", spadicHwAddress);
+        return nullptr;
+    }
+    asicAddress = mapIt->second;
     Int_t uniqueModuleId = asicAddress / 1000;
     Int_t layerId(CbmTrdAddress::GetLayerId(uniqueModuleId));
     Int_t moduleId(CbmTrdAddress::GetModuleId(uniqueModuleId));
@@ -542,9 +849,7 @@ std::shared_ptr<CbmTrdDigi> CbmMcbm2018UnpackerAlgoTrdR::MakeDigi(CbmTrdRawMessa
     digiAddress = (fAsicChannelMap.find(asicAddress))->second.at(asicChannelId);
 
     std::shared_ptr<CbmTrdDigi> digi = std::make_shared<CbmTrdDigi> ( CbmTrdDigi(digiAddress, digiCharge, digiTime, digiTriggerType, digiErrClass) );
-
-    digi->SetAddress(CbmTrdAddress::GetAddress(layerId, moduleId, 0, 0, 0)); // TODO this could be skipped is shifting the address components back and forth, however the digi setter would need to be enhanced
-
+    digi->SetAddress(CbmTrdAddress::GetAddress(layerId, moduleId, 0, 0, 0)); // TODO this could be skipped, it is shifting the address components back and forth, however the digi setter would need to be enhanced 
 
     // Int_t channelAddress = digi->GetAddressChannel();
     // Int_t address = digi->GetAddress();
@@ -626,8 +931,6 @@ CbmTrdRawMessageSpadic CbmMcbm2018UnpackerAlgoTrdR::CreateRawMessage(const uint6
     uint8_t hitType = 0, nSamples = 0;
     bool multihit = false;
     uint16_t timestamp = 0;
-//    uint64_t ts_overlap = 0;  ///< 3bit of th spadic ts and the epoch counter should be the same (FU 270320 Redmine issue#1563)
-    //extract elinkid
     uint64_t mask = 0x3F;
     mask = mask << 55;
     elinkId = (char)((word & mask) >> 55);
@@ -636,18 +939,14 @@ CbmTrdRawMessageSpadic CbmMcbm2018UnpackerAlgoTrdR::CreateRawMessage(const uint6
     mask = mask << 51;
     chId = (char)((word & mask) >> 51);
     //extract timestamp
-    mask = 0x7FF;
+    mask = 0xFFFF;
     mask = mask << 35;
     timestamp = (uint16_t)((word & mask) >> 35);
-    // extract timestamp overlap
-    mask = 0xFF;
-    mask = mask << 46;
-//    ts_overlap = (uint64_t)((word & mask) >> 46); (FU 270320 Redmine issue#1563)
     //extract hitType
     mask = 0x3;
     mask = mask << 33;
     hitType = (uint8_t)((word & mask) >> 33);
-    //extract MultiHi
+    //extract MultiHit
     mask = 0x1;
     mask = mask << 32;
     multihit = (bool)((word & mask) >> 32);
@@ -660,20 +959,13 @@ CbmTrdRawMessageSpadic CbmMcbm2018UnpackerAlgoTrdR::CreateRawMessage(const uint6
     // get the correct fulltime
     uint64_t fulltime = timestamp + (fSpadicEpoch * fdMsSizeInCC); // this is in units of clock cycles
     //uint64_t epoch = fSpadicEpoch >> 3 ;
-    //uint64_t fulltime = timestamp + (ts_overlap << 11 ) + (epoch << 14); // this is in units of clock cycles
-/*
-    mask = 0x7;
-    uint64_t compare = (mask & fSpadicEpoch) ;
-    //LOG(info) << "[CbmMcbm2018UnpackerAlgoTrdR::CreateRawMessage] ts_overlap = " << (UInt_t)ts_overlap ;
-    if ( compare != (uint64_t)ts_overlap ) LOG(warning) << "[CbmMcbm2018UnpackerAlgoTrdR::CreateRawMessage] " << compare << " != " << (UInt_t)ts_overlap ;
-*/
 
 
     // put the first 3 samples, contained in som, into the message.
     std::vector<int16_t> samples;
     for (int i = 0; i < nSamples && i < 3; i++)
     {
-        samples.push_back(ExtractSample(word, i, multihit));
+        samples.emplace_back(ExtractSample(word, i, multihit));
     }
 
     // Create message
@@ -717,7 +1009,6 @@ int16_t CbmMcbm2018UnpackerAlgoTrdR::ExtractSample(const uint64_t word, uint8_t
         LOG(error) << "[CbmMcbm2018UnpackerAlgoTrdR::ExtractSample]  Wrong sample index!";
         return -256;
     }
-
     uint16_t index = indices[sample];
 
     mask = mask << (9 * (6 - index));
diff --git a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.h b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.h
index f700288129ba76cbdc4dff9f63d8c98aaa29d930..9d2cbd073f320deb3137ecd4f4c6341fd61002e7 100644
--- a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.h
+++ b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerAlgoTrdR.h
@@ -69,9 +69,41 @@ public:
   void AddMsComponentToList(size_t component, UShort_t usDetectorId);
   void SetNbMsInTs(size_t uCoreMsNb, size_t uOverlapMsNb);
 
-  Bool_t CreateHistograms();
+  enum ECbmTrdUnpackerHistograms : Int_t 
+  {
+    kBeginDefinedHistos = 0
+    , kRawMessage_Signalshape_all = 0
+    , kRawMessage_Signalshape_St
+    , kRawMessage_Signalshape_Nt
+    , kRawMessage_Signalshape_filtered
+    , kRawDistributionMapModule5
+    , kRawHitType
+    , kRawPulserDeltaT
+    , kSpadic_Info_Types
+    , kBeginDigiHistos
+    , kDigiPulserDeltaT = kBeginDigiHistos
+    , kDigiDeltaT // Heavy histogram add with care
+    , kDigiMeanHitFrequency // Heavy histogram add with care
+    , kDigiHitFrequency
+    , kDigiRelativeTimeMicroslice
+    , kDigiDistributionMap
+    , kDigiDistributionMapSt
+    , kDigiDistributionMapNt
+    , kDigiChargeSpectrum
+    , kDigiChargeSpectrumSt
+    , kDigiChargeSpectrumNt
+    , kDigiTriggerType
+    , kEndDefinedHistos
+  };
+  void   SetActiveHistograms(std::vector<bool> isActiveHistoVec)  { fIsActiveHistoVec = isActiveHistoVec; }
+  Bool_t CreateHistograms();  ///< Goes through fIsActiveHistoVec and creates the activated histograms
+  Bool_t CreateHistogram(ECbmTrdUnpackerHistograms iHisto); ///< create the histogram correlated to iHisto
+  
   Bool_t FillHistograms();
+  Bool_t FillHistograms(CbmTrdDigi const &digi);
+  Bool_t FillHistograms(CbmTrdRawMessageSpadic const &raw);
   Bool_t ResetHistograms();
+  
 
   std::vector<CbmTrdRawMessageSpadic> GetRawMessageVector() { return *(fTrdRawMessageVector); }
   TString GetRefGeoTag() { return fRefGeoTag; }
@@ -80,6 +112,7 @@ public:
   void SetDebugMonitorMode(Bool_t bFlagIn = kTRUE) { fbDebugMonitorMode = bFlagIn; }
   void SetWriteOutput(Bool_t bFlagIn = kTRUE) { fbWriteOutput = bFlagIn; }
   void SetDebugWriteOutput(Bool_t bFlagIn = kTRUE) { fbDebugWriteOutput = bFlagIn; }
+  inline void SetTimeOffsetNs( Double_t dOffsetIn = 0.0 ) { fdTimeOffsetNs = dOffsetIn; }
 
   /**
 	 *  @brief Call this when Spadic Average-Baseline feature is enabled.
@@ -102,6 +135,7 @@ public:
 
   void SetRefGeoTag(TString geoTag)           { fRefGeoTag = geoTag; }
   void SetFirstChannelsElinkEven(bool isEven) { fIsFirstChannelsElinkEven = isEven; }
+  void SetMsSizeInNs( Double_t msSizeInNs )   { fdMsSizeInNs = msSizeInNs; } // TODO handle this with asic parameter files
 
 private:
 
@@ -134,6 +168,9 @@ private:
   Bool_t fbDebugWriteOutput; ///< If ON the raw messages output vector is filled and written to disk.
   Bool_t fbBaselineAvg;      ///< Set to true if Baseline Averaging is activated in Spadic.
 
+  /// User settings: Data correction parameters
+  Double_t fdTimeOffsetNs = 0.0;
+
   /// Output Digi vector
   std::vector<CbmTrdDigi> *fTrdDigiVector;
 
@@ -146,7 +183,9 @@ private:
   //std::map< TString, std::shared_ptr<TH1> > fHistoMap ;
 
   /// Stores all Histograms.
+  std::vector<bool> fIsActiveHistoVec;
   TObjArray fHistoArray;
+  std::vector<std::uint64_t> fLastDigiTimeVec;
 
   /**
    *  @brief Instance of RawToDigi class.
diff --git a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTrdR.cxx b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTrdR.cxx
index e3a2ed1b1b36b5748aaf2788ebda3a443936b924..5fc5ae535caaafabe07d0b90d49f3614fe2302d1 100644
--- a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTrdR.cxx
+++ b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTrdR.cxx
@@ -19,7 +19,9 @@ CbmMcbm2018UnpackerTaskTrdR::CbmMcbm2018UnpackerTaskTrdR()
 	  , fbDebugWriteOutput(kFALSE)
 	  , fbBaselineAvg(kFALSE)
 	  , fSystemIdentifier((std::uint8_t)fles::SubsystemIdentifier::TRD)
+	  , fdMsSizeInNs(1.28e6)  // default value corresponds to mCbm 2020 value
 	  , fMonitorHistoFileName("")
+	  , fIsActiveHistoVec(CbmMcbm2018UnpackerAlgoTrdR::kEndDefinedHistos, false)
 	  , fTrdDigiVector(nullptr)
 	  , fTrdRawMessageVector(nullptr)
 	  , fSpadicInfoMsgVector(nullptr)
@@ -75,6 +77,7 @@ Bool_t CbmMcbm2018UnpackerTaskTrdR::Init()
 		}
 	}
 
+	fUnpackerAlgo->SetMsSizeInNs(fdMsSizeInNs); // TODO handle this with asic parameter files
 	initOK &= fUnpackerAlgo->Init() ;
 
 	if ( initOK ){
@@ -190,6 +193,8 @@ Bool_t CbmMcbm2018UnpackerTaskTrdR::InitContainers()
 	fUnpackerAlgo->SetWriteOutput(fbWriteOutput);
 	fUnpackerAlgo->SetDebugWriteOutput(fbDebugWriteOutput);
 	fUnpackerAlgo->SetBaselineAvg(fbBaselineAvg);
+	// Activate histograms in unpacker
+	fUnpackerAlgo->SetActiveHistograms(fIsActiveHistoVec);
 
 	Bool_t initOK = fUnpackerAlgo->InitContainers();
 
@@ -217,7 +222,10 @@ Bool_t CbmMcbm2018UnpackerTaskTrdR::InitContainers()
 		}
 		else
 		{
-			initOK &= 0;
+			//			initOK &= 0;
+			/// Avoid crash in other unpackers due to the FAIRROOT "feature" that a 0 return value goes on with the run without initializing 
+			/// tasks which are later in the alphabetical order
+			LOG(warning) << "The histograms from CbmMcbm2018UnpackerTaskTrdR will not be available online as no server present";
 		} // end if( nullptr != server )
 	}	 // end if (fbMonitorMode == kTRUE || fbDebugMonitorMode == kTRUE)
 
@@ -258,5 +266,10 @@ void CbmMcbm2018UnpackerTaskTrdR::SetHistoFileName(TString filename)
 	SetMonitorMode(kTRUE);
 }
 
+void CbmMcbm2018UnpackerTaskTrdR::SetTimeOffsetNs( Double_t dOffsetIn )
+{
+	if ( fUnpackerAlgo != nullptr )
+		fUnpackerAlgo->SetTimeOffsetNs( dOffsetIn );
+}
 
 ClassImp(CbmMcbm2018UnpackerTaskTrdR)
diff --git a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTrdR.h b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTrdR.h
index 1ff5925c397151e7e7d4c7dcfa945220d96c94bc..74fc23de1e205aec941e7d7aeb9cf159a7d5dc86 100644
--- a/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTrdR.h
+++ b/fles/mcbm2018/unpacker/CbmMcbm2018UnpackerTaskTrdR.h
@@ -73,14 +73,18 @@ public:
 	void SetWriteOutput(Bool_t bFlagIn = kTRUE) 	 { fbWriteOutput = bFlagIn; }
 	void SetDebugWriteOutput(Bool_t bFlagIn = kTRUE) { fbDebugWriteOutput = bFlagIn; }
 	void SetSystemIdentifier(std::uint8_t id)		 { fSystemIdentifier = id; }	
+	void SetTimeOffsetNs( Double_t dOffsetIn = 0.0 );
 
 	/**
 	 *  @brief Call this when Spadic Average-Baseline feature is enabled.
 	 **/
 	void SetBaselineAvg(Bool_t bFlagIn = kTRUE) { fbBaselineAvg = bFlagIn; }
 
+	void SetActiveHistograms(std::vector<bool> isActiveHistoVec)  { fIsActiveHistoVec = isActiveHistoVec; }
 	void SetHistoFileName(TString filename);
 
+	void SetMsSizeInNs( Double_t msSizeInNs )   { fdMsSizeInNs = msSizeInNs; } // TODO handle this with asic parameter files
+
 private:
 	// Control flags
 	Bool_t fbMonitorMode;	  ///< Switch ON the filling of a minimal set of histograms.
@@ -89,8 +93,10 @@ private:
 	Bool_t fbDebugWriteOutput; ///< If ON the output vector of raw messages is filled and written to disk.
 	Bool_t fbBaselineAvg;	  ///< Set to true if Baseline Averaging is activated in Spadic.
 	std::uint8_t fSystemIdentifier; ///< by default set to: fles::SubsystemIdentifier::TRD, changable via setter
+	Double_t fdMsSizeInNs; 	  ///< microslice size in ns to be passed to the unpacker // TODO handle this with asic parameter files
 
 	TString fMonitorHistoFileName;
+	std::vector<bool> fIsActiveHistoVec;	// Define active histos in algo
 
 	/// Output Digi vector
 	std::vector<CbmTrdDigi> *fTrdDigiVector;
diff --git a/reco/detectors/trd/CbmTrdClusterFinder.cxx b/reco/detectors/trd/CbmTrdClusterFinder.cxx
index f754c5844e41f2c21f5728d39b990ecc65ce39a3..b08fc2963b485161063d6be339ee7bf574fac8a0 100644
--- a/reco/detectors/trd/CbmTrdClusterFinder.cxx
+++ b/reco/detectors/trd/CbmTrdClusterFinder.cxx
@@ -74,9 +74,6 @@ CbmTrdClusterFinder::~CbmTrdClusterFinder()
     fClusters->Delete();
     delete fClusters;
   }
-  if(fDigiPar){
-    delete fDigiPar;
-  }
   if(fGeoPar){
     delete fGeoPar;
   }
diff --git a/reco/detectors/trd/CbmTrdModuleRecR.cxx b/reco/detectors/trd/CbmTrdModuleRecR.cxx
index 92c35e8ea549e2ef632c7f46d279eca127ab8c4b..75f397d6b57548c81d330aa66fbfcabdf03f6c18 100644
--- a/reco/detectors/trd/CbmTrdModuleRecR.cxx
+++ b/reco/detectors/trd/CbmTrdModuleRecR.cxx
@@ -441,17 +441,13 @@ CbmTrdHit* CbmTrdModuleRecR::MakeHit(Int_t clusterId, const CbmTrdCluster* /*clu
     //    if (digiCharge <= 0)     {std::cout<<" charge 0 " << std::endl;continue;}
     if (digiCharge <= 0.05)     {continue;}
 
-    Int_t ncols= fDigiPar->GetNofColumns();
-    //    Int_t nrows= fDigiPar->GetNofRows();
-    Int_t row= digi->GetAddressChannel()/ncols;
-    Int_t col= digi->GetAddressChannel()%ncols; 
-    Int_t srow, sector= fDigiPar->GetSectorRow(row, srow);
     time += digi->GetTime();
     //    time += digi->GetTimeDAQ();
     
     totalCharge += digi->GetCharge();
-    //    fDigiPar->GetPadPosition(digi->GetAddress(), local_pad_posV, local_pad_dposV);
-    fDigiPar->GetPadPosition(sector, col, srow, local_pad_posV, local_pad_dposV);
+    
+    fDigiPar->GetPadPosition(digi->GetAddressChannel(), true, local_pad_posV, local_pad_dposV);
+    
     
     Double_t xMin = local_pad_posV[0] - local_pad_dposV[0];
     Double_t xMax = local_pad_posV[0] + local_pad_dposV[0];