From 697b59b87a45d5ca04c1132da7f9002ddc8d9691 Mon Sep 17 00:00:00 2001
From: Alexandru Bercuci <abercuci@niham.nipne.ro>
Date: Wed, 22 Sep 2021 16:23:15 +0000
Subject: [PATCH] add self-trigger data manipulation protect against missing
 par files update steering macro for the new TRD-2D interface incorporate
 parameter calibration into the FASP read-out data protect the code for the
 case of par un-consistency (found e.g. for TRD-2Dh) add user interface to the
 Asic param set rename modules in the TRD setup extend the TRD module type
 index above one digit adding class definition to allow SPADIC info generation
 during unpacking

---
 core/detectors/trd/CbmTrdGeoHandler.cxx       |  13 +-
 core/detectors/trd/CbmTrdParSet.cxx           |   8 +
 core/detectors/trd/CbmTrdParSet.h             |   1 +
 core/detectors/trd/CbmTrdParSetAsic.cxx       |  18 +-
 core/detectors/trd/CbmTrdParSetAsic.h         |   1 +
 .../geometry/trd/Create_TRD_Geometry_v21a.C   |   9 +-
 macro/run/run_unpack_tsa.C                    |   2 +-
 reco/detectors/trd/CbmTrdRecoLinkDef.h        |   1 +
 .../trd/unpack/CbmTrdUnpackAlgoFasp2D.cxx     | 161 ++++++++++++++++--
 .../trd/unpack/CbmTrdUnpackAlgoFasp2D.h       |  23 ++-
 .../trd/unpack/CbmTrdUnpackMonitor.cxx        |   1 +
 11 files changed, 214 insertions(+), 24 deletions(-)

diff --git a/core/detectors/trd/CbmTrdGeoHandler.cxx b/core/detectors/trd/CbmTrdGeoHandler.cxx
index d0e082225f..cff3dcf2e5 100644
--- a/core/detectors/trd/CbmTrdGeoHandler.cxx
+++ b/core/detectors/trd/CbmTrdGeoHandler.cxx
@@ -192,10 +192,17 @@ void CbmTrdGeoHandler::NavigateTo(const TString& path)
     Double_t local[3] = {0., 0., 0.};  // Local center of volume
     gGeoManager->LocalToMaster(local, fGlobal);
     fGlobalMatrix = gGeoManager->GetCurrentMatrix();
-    // Get module type information which is decoded in copy number.
-    const char* moduleName = gGeoManager->GetMother()->GetName();
-    fModuleType            = std::atoi(string(1, *(moduleName + 6)).c_str());  // 6th element module type
 
+    // Get module type information which is decoded in copy number.
+    std::string moduleName = gGeoManager->GetMother()->GetName();
+    auto typeposstart      = moduleName.find("module") + 6;
+    uint ndigits           = 0;
+    auto partoftype        = moduleName.at(typeposstart);
+    while (std::isdigit(partoftype) && (ndigits + typeposstart) < moduleName.size()) {
+      partoftype = moduleName.at(typeposstart + ndigits);
+      ++ndigits;
+    }
+    fModuleType = std::atoi(moduleName.substr(typeposstart, ndigits).data());  // 6th element+ module type
     // We take the mother of the mother node (layer) of the current node we are in (gas).
     TGeoNode* layernode = gGeoManager->GetMother(2);  // get layer
     Int_t layercopyNr   = layernode->GetNumber();
diff --git a/core/detectors/trd/CbmTrdParSet.cxx b/core/detectors/trd/CbmTrdParSet.cxx
index f58ba93b4c..98165360d5 100644
--- a/core/detectors/trd/CbmTrdParSet.cxx
+++ b/core/detectors/trd/CbmTrdParSet.cxx
@@ -53,6 +53,14 @@ const CbmTrdParMod* CbmTrdParSet::GetModulePar(Int_t detId) const
   return imod->second;
 }
 
+//_______________________________________________________________________________
+CbmTrdParMod* CbmTrdParSet::GetModulePar(Int_t detId)
+{
+  map<Int_t, CbmTrdParMod*>::const_iterator imod = fModuleMap.find(detId);
+  if (imod == fModuleMap.end()) return nullptr;
+  return imod->second;
+}
+
 //_______________________________________________________________________________
 Bool_t CbmTrdParSet::getParams(FairParamList* l)
 {
diff --git a/core/detectors/trd/CbmTrdParSet.h b/core/detectors/trd/CbmTrdParSet.h
index f736bc1de6..e57ac3954a 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 CbmTrdParMod* GetModulePar(Int_t detId);
   virtual Int_t GetNrOfModules() const { return fNrOfModules; }
   std::map<Int_t, CbmTrdParMod*> GetModuleMap() { return fModuleMap; }
   virtual void addParam(CbmTrdParMod* mod);
diff --git a/core/detectors/trd/CbmTrdParSetAsic.cxx b/core/detectors/trd/CbmTrdParSetAsic.cxx
index bcd84aeaa5..51e8bf4476 100644
--- a/core/detectors/trd/CbmTrdParSetAsic.cxx
+++ b/core/detectors/trd/CbmTrdParSetAsic.cxx
@@ -43,9 +43,20 @@ CbmTrdParSetAsic::~CbmTrdParSetAsic()
     fModPar.clear();
   }
 }
+
+//_______________________________________________________________________________
+void CbmTrdParSetAsic::addParam(CbmTrdParMod* mod)
+{
+  if (mod->IsA() != CbmTrdParFasp::Class() && mod->IsA() != CbmTrdParSpadic::Class()) return;
+
+  fModuleMap[((CbmTrdParAsic*) mod)->GetAddress()] = mod;
+  fNrOfModules++;
+}
+
 //_______________________________________________________________________________
 Bool_t CbmTrdParSetAsic::getParams(FairParamList* l)
 {
+  //LOG(info) << GetName() << "::getParams(FairParamList*)";
   if (!l) return kFALSE;
   if (!l->fill("NrOfModules", &fNrOfModules)) return kFALSE;
   TArrayI moduleId(fNrOfModules);
@@ -60,6 +71,7 @@ Bool_t CbmTrdParSetAsic::getParams(FairParamList* l)
     if (nAsic[imod] > maxNrAsics) maxNrAsics = nAsic[imod];
   }
   Int_t address(0);
+  fType = 0xff;
 
   CbmTrdParAsic* asic(nullptr);
   for (Int_t i = 0; i < fNrOfModules; i++) {
@@ -74,10 +86,12 @@ Bool_t CbmTrdParSetAsic::getParams(FairParamList* l)
       for (Int_t iasic = 0; iasic < nAsic[i]; iasic++) {
         Int_t offset = iasic * (sizePerFasp);
         address      = values[offset + 0];
+        if (address == moduleId[i] * 1000 + 999) continue;
         asic         = new CbmTrdParFasp(address);
         static_cast<CbmTrdParFasp*>(asic)->LoadParams(values, iasic);
         fModPar[moduleId[i]]->SetAsicPar(address, asic);
       }
+      fModPar[moduleId[i]]->SetAsicType(1);
     }
     else {
       Int_t maxValues = maxNrAsics * (5 + NSPADICCH);
@@ -97,6 +111,7 @@ Bool_t CbmTrdParSetAsic::getParams(FairParamList* l)
         asic->SetChannelAddresses(addresses);
         fModPar[moduleId[i]]->SetAsicPar(address, asic);
       }
+      fModPar[moduleId[i]]->SetAsicType(0);
     }
   }
   return kTRUE;
@@ -106,7 +121,7 @@ Bool_t CbmTrdParSetAsic::getParams(FairParamList* l)
 void CbmTrdParSetAsic::putParams(FairParamList* l)
 {
   if (!l) return;
-  LOG(info) << GetName() << "::putParams(FairParamList*)";
+  //LOG(info) << GetName() << "::putParams(FairParamList*)";
 
   Int_t idx(0);
   TArrayI moduleId(fNrOfModules), nAsic(fNrOfModules), typeAsic(fNrOfModules);
@@ -271,6 +286,7 @@ void CbmTrdParSetAsic::SetAsicPar(Int_t address, CbmTrdParAsic* p)
 {
   std::map<Int_t, CbmTrdParMod*>::iterator it = fModuleMap.find(address);
   if (it != fModuleMap.end()) {
+    if (address % 1000 == 999) return;
     LOG(warn) << GetName() << "::SetAsicPar : The ASIC @ " << address << " already initialized. Skip.";
     return;
   }
diff --git a/core/detectors/trd/CbmTrdParSetAsic.h b/core/detectors/trd/CbmTrdParSetAsic.h
index 8009ea17a8..8e7475a7fc 100644
--- a/core/detectors/trd/CbmTrdParSetAsic.h
+++ b/core/detectors/trd/CbmTrdParSetAsic.h
@@ -30,6 +30,7 @@ public:
 
   /** \brief Reset all parameters **/
   virtual void clear() { ; }
+  virtual void addParam(CbmTrdParMod* mod);
   void AddParameters(CbmTrdParSetAsic*);  // (VF) renamed to avoid shadowing of virtual method
   Bool_t getParams(FairParamList*);
   void putParams(FairParamList*);
diff --git a/macro/mcbm/geometry/trd/Create_TRD_Geometry_v21a.C b/macro/mcbm/geometry/trd/Create_TRD_Geometry_v21a.C
index c74c43d849..38bd7c1b17 100644
--- a/macro/mcbm/geometry/trd/Create_TRD_Geometry_v21a.C
+++ b/macro/mcbm/geometry/trd/Create_TRD_Geometry_v21a.C
@@ -329,7 +329,8 @@ const Int_t layer3o[9][11] = {
 // Parameters defining the layout of the different detector modules
 const Int_t NofModuleTypes             = 10;
 const Int_t ModuleType[NofModuleTypes] = {
-  0, 0, 0, 2, 1, 1, 1, 1, 2, 3};  // 0 = small module, 1 = large module, 2 = mCBM Bucharest prototype
+  0, 0, 0, 2, 1, 1,
+  1, 1, 2, 3};  // 0 = small module, 1 = large module, 2 = mCBM Bucharest prototype, 3 = mCBM Bucharest TRD-2Dh prototype
 
 // FEB inclination angle
 const Double_t feb_rotation_angle[NofModuleTypes] = {
@@ -2947,8 +2948,8 @@ void create_detector_layers(Int_t layerId)
 
   //install TRD2D detectors in the TRD setup
   Int_t type = -1;
-  if (layerId == 2 && layerType == 2) type = 9;
-  if (layerId == 3 && layerType == 2) type = 10;
+  if (layerId == 2 && layerType == 2) type = 10;
+  if (layerId == 3 && layerType == 2) type = 9;
   if (type < 0) return;
   Info("create_detector_layers", "add module[0x%p] of type[%d]", (void*) gModules[type - 1], type);
 
@@ -2962,7 +2963,7 @@ void create_detector_layers(Int_t layerId)
 
   module_rotation = new TGeoRotation();
   TGeoCombiTrans* module_placement =
-    new TGeoCombiTrans(xPos, yPos, LayerPosition[0] - (3 - layerId) * LayerThickness / 2,
+    new TGeoCombiTrans(xPos, yPos, LayerPosition[0] - (layerId - 1) * LayerThickness / 2,
                        module_rotation);  // shift by half layer thickness
   Int_t copy = copy_nr(1, 1, 0, PlaneId[layerId], 1);
   gGeoMan->GetVolume(layername)->AddNode(gModules[type - 1], copy, module_placement);
diff --git a/macro/run/run_unpack_tsa.C b/macro/run/run_unpack_tsa.C
index 8629aff0f4..7e9753cb12 100644
--- a/macro/run/run_unpack_tsa.C
+++ b/macro/run/run_unpack_tsa.C
@@ -159,7 +159,7 @@ void run_unpack_tsa(std::vector<std::string> infile = {"test.tsa"}, UInt_t runid
   // ---- TRDFASP2D ----
   std::shared_ptr<CbmTrdUnpackConfigFasp2D> trdfasp2dconfig = nullptr;
 
-  trdfasp2dconfig = std::make_shared<CbmTrdUnpackConfigFasp2D>("", runid);
+  trdfasp2dconfig = std::make_shared<CbmTrdUnpackConfigFasp2D>(trdsetuptag.Data(), 3);
   if (trdfasp2dconfig) {
     // trdfasp2dconfig->SetDebugState();
     trdfasp2dconfig->SetDoWriteOutput();
diff --git a/reco/detectors/trd/CbmTrdRecoLinkDef.h b/reco/detectors/trd/CbmTrdRecoLinkDef.h
index 016bd71606..c0f2d416da 100644
--- a/reco/detectors/trd/CbmTrdRecoLinkDef.h
+++ b/reco/detectors/trd/CbmTrdRecoLinkDef.h
@@ -27,6 +27,7 @@
 #pragma link C++ class CbmTrdRecoQa + ;
 #pragma link C++ class CbmTrdTracksPidQa + ;
 
+#pragma link C++ class std::vector<std::pair<unsigned long, unsigned long>> + ;
 #pragma link C++ class CbmTrdUnpackAlgoBaseR + ;
 #pragma link C++ class CbmTrdUnpackAlgoR + ;
 #pragma link C++ class CbmTrdUnpackAlgoLegacy2020R + ;
diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackAlgoFasp2D.cxx b/reco/detectors/trd/unpack/CbmTrdUnpackAlgoFasp2D.cxx
index 29ac720573..8fe568c024 100644
--- a/reco/detectors/trd/unpack/CbmTrdUnpackAlgoFasp2D.cxx
+++ b/reco/detectors/trd/unpack/CbmTrdUnpackAlgoFasp2D.cxx
@@ -6,8 +6,17 @@
 #include "CbmTrdUnpackAlgoFasp2D.h"
 
 #include "CbmTrdDigi.h"
-
+#include "CbmTrdParFasp.h"
+#include "CbmTrdParModDigi.h"
+#include "CbmTrdParSetDigi.h"
+#include "CbmTrdParSetGain.h"
+#include "CbmTrdParSetGas.h"
+#include "CbmTrdParSpadic.h"
+
+#include <FairParAsciiFileIo.h>
 #include <FairParGenericSet.h>
+#include <FairParamList.h>
+#include <FairRuntimeDb.h>
 #include <FairTask.h>
 #include <Logger.h>
 
@@ -18,13 +27,95 @@
 
 using namespace std;
 
-CbmTrdUnpackAlgoFasp2D::CbmTrdUnpackAlgoFasp2D() : CbmRecoUnpackAlgo("CbmTrdUnpackAlgoFasp2D")
+CbmTrdUnpackAlgoFasp2D::CbmTrdUnpackAlgoFasp2D()
+  : CbmRecoUnpackAlgo("CbmTrdUnpackAlgoFasp2D")
+  , fModuleId()
+  , fAsicPar()
+  , fDigiSet(nullptr)
 {
   memset(fTime, 0, NCRI * sizeof(ULong64_t));
 }
 
+//_________________________________________________________________________________
 CbmTrdUnpackAlgoFasp2D::~CbmTrdUnpackAlgoFasp2D() {}
 
+//_________________________________________________________________________________
+Bool_t CbmTrdUnpackAlgoFasp2D::initParSet(FairParGenericSet* parset)
+{
+  FairParamList parList;
+  Int_t nModules(0);
+  if (strcmp(parset->ClassName(), "CbmTrdParSetAsic") == 0) {
+    CbmTrdParSetAsic* setPar = static_cast<CbmTrdParSetAsic*>(parset);
+    for (auto did : fModuleId) {
+      const CbmTrdParSetAsic* setDet = static_cast<const CbmTrdParSetAsic*>(setPar->GetModuleSet(did));
+      if (!setDet) continue;
+      if (setDet->GetAsicType() != Int_t(CbmTrdDigi::eCbmTrdAsicType::kFASP)) continue;
+      nModules++;
+      std::vector<Int_t> a;
+      setDet->GetAsicAddresses(&a);
+      for (auto add : a) {
+        CbmTrdParAsic* asic = (CbmTrdParAsic*) setDet->GetModulePar(add);
+        if (asic->IsA() == CbmTrdParSpadic::Class()) continue;
+        fAsicPar.addParam(asic);
+        // asic->Print();
+      }
+    }
+    //      setPar->printParams();
+    LOG(info) << GetName() << "::initParSet - for container " << parset->ClassName() << " modules " << nModules
+              << " asics " << fAsicPar.GetNrOfModules();
+  }
+  else if (strcmp(parset->ClassName(), "CbmTrdParSetDigi") == 0) {
+    fDigiSet                          = static_cast<CbmTrdParSetDigi*>(parset);
+    map<Int_t, CbmTrdParMod*> digiPar = fDigiSet->GetModuleMap();
+    for (auto digi : digiPar)
+      fModuleId.emplace_back(digi.first);
+    // setPar->printParams();
+    LOG(info) << GetName() << "::initParSet - for container " << parset->ClassName() << " modules " << fModuleId.size();
+  }
+  else if (strcmp(parset->ClassName(), "CbmTrdParSetGas") == 0) {
+    CbmTrdParSetGas* setPar = static_cast<CbmTrdParSetGas*>(parset);
+    setPar->printParams();
+    nModules = setPar->GetNrOfModules();
+  }
+  else if (strcmp(parset->ClassName(), "CbmTrdParSetGain") == 0) {
+    CbmTrdParSetGain* setPar = static_cast<CbmTrdParSetGain*>(parset);
+    setPar->printParams();
+    nModules = setPar->GetNrOfModules();
+  }
+  else {
+    LOG(error) << "Parameter set " << parset->ClassName() << " not known. Skip.";
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+//_________________________________________________________________________________
+std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>*
+CbmTrdUnpackAlgoFasp2D::GetParContainerRequest(std::string geoTag, std::uint32_t runId)
+{
+  LOG(info) << GetName() << "::GetParContainerRequest - for container " << geoTag.data() << " run " << runId << "  "
+            << fParFilesBasePath.data();
+
+  // Basepath for default Trd parameter sets (those connected to a geoTag)
+  std::string basepath = Form("%s/trd_%s", fParFilesBasePath.data(), geoTag.data());
+  std::string temppath = "";
+
+  // Digest the runId information in case of runId = 0 we use the default fall back
+  std::string runpath = "";
+  if (runId != 0) { runpath = ".run" + std::to_string(runId); }
+
+  temppath = basepath + runpath + ".digi" + ".par";
+  fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetDigi>()));
+  temppath = basepath + runpath + ".asic" + ".par";
+  fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetAsic>()));
+  //   temppath = basepath + runpath + ".gas" + ".par";
+  //   fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetGas>()));
+  //   temppath = basepath + runpath + ".gain" + ".par";
+  //   fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmTrdParSetGain>()));
+
+  return &fParContVec;
+}
+
 //_________________________________________________________________________________
 CbmTrdUnpackAlgoFasp2D::CbmTrdFaspMessageType CbmTrdUnpackAlgoFasp2D::mess_type(uint32_t wd)
 {
@@ -82,25 +173,56 @@ void CbmTrdUnpackAlgoFasp2D::mess_prt(CbmTrdFaspContent* mess)
 bool CbmTrdUnpackAlgoFasp2D::pushDigis(
   std::map<UChar_t, std::vector<CbmTrdUnpackAlgoFasp2D::CbmTrdFaspContent*>> messes)
 {
-  bool use(false);
+  bool use(false), kRowInverted(false);
   UChar_t lFasp(0xff);
   UShort_t lchR, lchT;
   Double_t r, t;
-  Int_t dt, dtime;
+  Int_t dt, dtime, pad, row;
+  ULong64_t tlab;
+  CbmTrdParFasp* faspPar(nullptr);
+  CbmTrdParModDigi* digiPar(nullptr);
   vector<CbmTrdDigi*> digis;
   for (Int_t col(0); col < NCOLS; col++) {
     if (!messes[col].size()) continue;
-    if (lFasp == 0xff) lFasp = messes[col][0]->fasp;
-    //printf("col[%d]=%lu\n", col, messes[col].size());
-    for (vector<CbmTrdFaspContent*>::iterator i = messes[col].begin(); i != messes[col].end(); i++) {
+    vector<CbmTrdFaspContent*>::iterator i = messes[col].begin();
+    if (lFasp == 0xff) {
+      lFasp = messes[col][0]->fasp;
+      // link data to the position on the padplane
+      if (!(faspPar = (CbmTrdParFasp*) fAsicPar.GetAsicPar((*i)->cri * 1000 + lFasp))) {
+        LOG(error) << GetName() << "::pushDigis - FASP par " << (int) lFasp << " for module " << (*i)->cri
+                   << " missing. Skip.";
+        return false;
+      }
+      if (!(digiPar = (CbmTrdParModDigi*) fDigiSet->GetModulePar((*i)->cri))) {
+        LOG(error) << GetName() << "::pushDigis - DIGI par for module " << (*i)->cri << " missing. Skip.";
+        return false;
+      }
+      pad = faspPar->GetChannelAddress(0);
+      row = digiPar->GetPadRow(pad);
+
+      // determine the HW direction in which the FASP channels are ordered
+      if (row % 2 == 0) {  // valid only for mCBM-07.2021 TRD-2D
+        kRowInverted = kTRUE;
+        pad          = faspPar->GetChannelAddress(15 - (*i)->ch);
+      }
+    }
+
+    for (; i != messes[col].end(); i++) {
       if (VERBOSE) mess_prt((*i));
 
       lchR = 0;
       lchT = 0;
       use  = false;
-      if ((*i)->ch % 2) lchR = (*i)->data;
-      else
-        lchT = (*i)->data;
+      if ((*i)->ch % 2 != 0) {
+        if (!kRowInverted) lchR = (*i)->data;
+        else
+          lchT = (*i)->data;
+      }
+      else {
+        if (!kRowInverted) lchT = (*i)->data;
+        else
+          lchR = (*i)->data;
+      }
       for (vector<CbmTrdDigi*>::iterator id = digis.begin(); id != digis.end(); id++) {
         dtime = (*id)->GetTimeDAQ() - (*i)->tlab;
         if (TMath::Abs(dtime) < 5) {
@@ -111,13 +233,21 @@ bool CbmTrdUnpackAlgoFasp2D::pushDigis(
             break;
           }
           else if (lchT && !int(t)) {
+            tlab = (*id)->GetTimeDAQ();
             (*id)->SetCharge(lchT, r, +dtime);
+            (*id)->SetTimeDAQ(ULong64_t(tlab - dtime));
             use = true;
             break;
           }
         }
       }
-      if (!use) digis.push_back(new CbmTrdDigi(lFasp * NCOLS + col, lchT, lchR, (*i)->tlab));
+
+      if (!use) {
+        pad              = faspPar->GetChannelAddress(kRowInverted ? (15 - (*i)->ch) : (*i)->ch);
+        CbmTrdDigi* digi = new CbmTrdDigi(pad, lchT, lchR, (*i)->tlab);
+        digi->SetAddressModule((*i)->cri);
+        digis.push_back(digi);
+      }
       delete (*i);
     }
 
@@ -210,16 +340,25 @@ bool CbmTrdUnpackAlgoFasp2D::unpack(const fles::Timeslice* ts, std::uint16_t ico
         vDigi.clear();
         lFaspOld = fasp_id;
       }
+      if (data & 0x1) {
+        LOG(warn) << GetName() << "::unpack - Data corrupted : detect end bit set.";
+        continue;
+      }
       if (VERBOSE)
         cout << boost::format("    DD : fasp_id=%02d ch_id=%02d slice=%03d data=%4d\n")
                   % static_cast<unsigned int>(fasp_id) % static_cast<unsigned int>(ch_id)
                   % static_cast<unsigned int>(slice) % static_cast<unsigned int>(data >> 1);
+      if (data & 0x2000) {
+        LOG(debug) << GetName() << "::unpack - Self-triggered data.";
+        data &= 0x1fff;
+      }
       mess       = new CbmTrdFaspContent;
       mess->ch   = ch_id;
       mess->type = 1;
       mess->tlab = slice;
       mess->data = data >> 1;
       mess->fasp = lFaspOld;
+      mess->cri  = 53;
       col        = ch_id >> 1;
       vDigi[col].push_back(mess);
     }
diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackAlgoFasp2D.h b/reco/detectors/trd/unpack/CbmTrdUnpackAlgoFasp2D.h
index 6abe90ad4c..7abae638e8 100644
--- a/reco/detectors/trd/unpack/CbmTrdUnpackAlgoFasp2D.h
+++ b/reco/detectors/trd/unpack/CbmTrdUnpackAlgoFasp2D.h
@@ -24,6 +24,7 @@
 
 #include "CbmRecoUnpackAlgo.tmpl"
 #include "CbmTrdDigi.h"
+#include "CbmTrdParSetAsic.h"
 
 #include "Timeslice.hpp"  // timeslice
 
@@ -38,6 +39,7 @@
 #define NCRI 40  // no of CRI in the system (1/TRD-2D_FASP module)
 #define NCOLS 8  // no of cols / FASP
 
+class CbmTrdParSetDigi;
 class CbmTrdUnpackAlgoFasp2D : public CbmRecoUnpackAlgo<CbmTrdDigi> {
 public:
   /** @brief Bytes per FASP frame stored in the microslices (32 bits words) 
@@ -94,7 +96,17 @@ public:
     uint8_t cri;
   };
 
-  // Setters
+  /**
+   * @brief Get the requested parameter containers.
+   * Return the required parameter containers together with the paths to the ascii 
+   * files to.
+   *  
+   * @param[in] std::string geoTag as used in CbmSetup
+   * @param[in] std::uint32_t runId for runwise defined parameters
+   * @return fParContVec
+  */
+  virtual std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>*
+  GetParContainerRequest(std::string geoTag, std::uint32_t runId);
 
 protected:
   /** @brief Get message type from the FASP word */
@@ -126,8 +138,7 @@ protected:
    * @param parset 
    * @return Bool_t initOk 
   */
-  Bool_t initParSet(FairParGenericSet* /*parset*/) { return kTRUE; }
-
+  Bool_t initParSet(FairParGenericSet* parset);
 
   /**
    * @brief Unpack a given microslice.
@@ -163,7 +174,11 @@ protected:
 private:
   void prt_wd(uint32_t w);
 
-  ClassDef(CbmTrdUnpackAlgoFasp2D, 2)
+  std::vector<Int_t> fModuleId;
+  CbmTrdParSetAsic fAsicPar;
+  CbmTrdParSetDigi* fDigiSet;
+
+  ClassDef(CbmTrdUnpackAlgoFasp2D, 2)  // unpack FASP read-out detectors
 };
 
 #endif  // CbmTrdUnpackAlgoFasp2D_H
diff --git a/reco/detectors/trd/unpack/CbmTrdUnpackMonitor.cxx b/reco/detectors/trd/unpack/CbmTrdUnpackMonitor.cxx
index a7e5f7579f..1622a51d86 100644
--- a/reco/detectors/trd/unpack/CbmTrdUnpackMonitor.cxx
+++ b/reco/detectors/trd/unpack/CbmTrdUnpackMonitor.cxx
@@ -446,6 +446,7 @@ std::double_t CbmTrdUnpackMonitor::getDeltaT(CbmTrdDigi* digi)
   if (modulevecpair == fLastDigiTimeMap.end()) {
     auto nchannels = fModuleNrColumns.find(moduleid)->second * fModuleNrRows.find(moduleid)->second;
     std::vector<size_t> channelsvec(nchannels, 0);
+    if (channelid > nchannels) return 0;
     channelsvec.at(channelid) = digi->GetTime();
     auto pair                 = std::make_pair(moduleid, channelsvec);
     fLastDigiTimeMap.emplace(pair);
-- 
GitLab