diff --git a/core/detectors/trd/CbmTrdFASP.cxx b/core/detectors/trd/CbmTrdFASP.cxx
index fcd255666bdbb3fce900ebe56451b804a8f838d6..99f4b5c6f8acbbea2c75a16a206ff62daf9e2199 100644
--- a/core/detectors/trd/CbmTrdFASP.cxx
+++ b/core/detectors/trd/CbmTrdFASP.cxx
@@ -30,12 +30,14 @@
 
 using namespace std;
 
-Bool_t CbmTrdFASP::fgNeighbour = kTRUE;  // by default enable neighbour trigger
+// Bool_t CbmTrdFASP::fgNeighbour = kTRUE;  // by default enable neighbour trigger
+Bool_t CbmTrdFASP::fgNeighbour = kFALSE;  // AB : match HW on mCBM22
 // Float_t CbmTrdFASP::fgShaperThr       = 0.2;  // [V]
 // Float_t CbmTrdFASP::fgNeighbourThr    = 0.07; // [V]
-Float_t CbmTrdFASP::fgShaperThr       = 0.05;   // [V]
-Float_t CbmTrdFASP::fgNeighbourThr    = 0.04;   // [V]
-Float_t CbmTrdFASP::fgBaseline        = 0.25;   // [V]
+//Float_t CbmTrdFASP::fgShaperThr       = 0.05;  // [V]
+Float_t CbmTrdFASP::fgShaperThr       = 0.08;   //[V]  AB : match HW on mCBM22
+Float_t CbmTrdFASP::fgNeighbourThr    = 0.04;   //[V]
+Float_t CbmTrdFASP::fgBaseline        = 0.25;   //[V]  AB : match HW on mCBM22
 Float_t CbmTrdFASP::fgOutGain         = 2.025;  // [V/ 4095 ADC chs]
 const Int_t CbmTrdFASP::fgkNclkFT     = 14;     // [clk]
 Int_t CbmTrdFASP::fgNclkLG            = 31;     // [clk]
@@ -43,27 +45,6 @@ const Int_t CbmTrdFASP::fgkBufferKeep = 400;    // [5*ns]
 //___________________________________________________________________
 CbmTrdFASP::CbmTrdFASP(UInt_t uslice)
   : TObject()
-  , fStartTime(0)
-  , fProcTime(0)
-  , fCol(-1)
-  , fRow(-1)
-  , fAsicId(-1)
-  , fNraw(0)
-  , fDigi(nullptr)
-  , fHitThPrev(uslice)
-  , fShaper(uslice)
-  , fShaperNext(uslice)
-  , fDigiProc()
-  , fPar(nullptr)
-  , fTimeLG(-1)
-  , fTimeFT(-1)
-  , fTimeDY(-1)
-  , fFT(0)
-  , fGraphId(0)
-  , fOut()
-  , fGraphMap()
-  , fGthr(nullptr)
-  , fMonitor(nullptr)
 {
   /** Build the FASP simulator for a microslice of 5*uslice [ns]
    */
@@ -104,106 +85,134 @@ void CbmTrdFASP::Clear(Option_t* opt)
 {
   //  printf("CbmTrdFASP::Clear : Nphys[0] = %d\n", fNphys[0]);
 
-  if (fNphys[0]) ProcessShaper('R');        // process last rect channel without interference from current tilt
+  if (fNphys[1]) ProcessShaper('R');        // process last rect channel without interference from current tilt
   fHitThPrev.assign(fHitThPrev.size(), 0);  //*sizeof(Bool_t));
   WriteDigi();                              // finalize fDigi list
   if (strcmp(opt, "draw") == 0) Draw();
 }
 
 //___________________________________________________________________
-void CbmTrdFASP::Draw(Option_t* /*opt*/)
+void CbmTrdFASP::InitChannel(int id, const CbmTrdParFaspChannel* par, int asicId, int chId)
 {
-  //  printf("CbmTrdFASP::Draw : row[%2d] col[%2d] asic[%2d]\n", fRow, fCol, fAsicId);
-  if (!DRAW) return;
-  if (!fGraphMap.size()) return;
+  if (id < 0 || id > 1) {
+    LOG(error) << "FASP simulator supports only two channels at time. Request for channel " << id << " was skipped.";
+    return;
+  }
+  fPar[id]    = par;
+  fAsicId[id] = asicId;
+  if (asicId < 0) {
+    fChId[id] = -1;
+    return;
+  }
 
-  Int_t nasic(0), last(-1), nlast(0);
-  vector<pair<Int_t, Int_t>>::iterator ig = fGraphMap.begin();
-  while (ig != fGraphMap.end()) {
-    if (last < 0 || ig->first != last) {
-      nasic++;
-      last  = ig->first;
-      nlast = 0;
+  if (chId < 0 || chId >= NFASPCH) {
+    LOG(warn) << "FASP ASIC implements " << NFASPCH << " channels. Channel identifier " << chId << " not considered.";
+    fChId[id] = -1;
+    return;
+  }
+  else
+    fChId[id] = chId;
+
+  if (DRAW) {
+    if (fGraphMap.find(fAsicId[id]) == fGraphMap.end()) fGraphMap[fAsicId[id]] = {0};
+    else {
+      int jg = fGraphMap[fAsicId[id]][fChId[id]];
+      if (jg > 0) {
+        memset(fGraph[jg]->GetY(), 0, fGraph[jg]->GetN() * sizeof(double));
+        memset(fGraphShp[jg]->GetY(), 0, fGraphShp[jg]->GetN() * sizeof(double));
+        memset(fGraphPhys[jg]->GetY(), 0, fGraphPhys[jg]->GetN() * sizeof(double));
+      }
     }
-    nlast++;
-    ig++;
   }
-  if (nasic <= 1) return;
+}
+
+//___________________________________________________________________
+int CbmTrdFASP::AddGraph(char typ)
+{
+  int gid(0);
+  if (fNgraph >= NGRAPH) {
+    LOG(warn) << "CbmTrdFASP::AddGraph : Draw buffer size " << NGRAPH << " exhausted. Expert setting.";
+    return gid;
+  }
+
+  int id(typ == 'T' ? 0 : 1);
+  gid         = fNgraph;
+  fGraph[gid] = new TGraph(/*fOut.size()*/);
+  fGraph[gid]->SetNameTitle(Form("g%03d", gid),
+                            Form("FASP id/ch [%3d / %2d] pad[%3d][%c]", fAsicId[id], fChId[id], fPad, typ));
+  fGraph[gid]->SetFillStyle(0);
+  fGraph[gid]->SetMarkerStyle(7);
+  fGraph[gid]->SetLineColor(kRed);
+  fGraph[gid]->SetMarkerColor(kRed);
+
+  fGraphShp[gid] = (TGraph*) fGraph[gid]->Clone();
+  fGraphShp[gid]->SetName(Form("gs%03d", gid));
+  fGraphShp[gid]->SetLineColor(kBlack);
+  fGraphShp[gid]->SetMarkerColor(kBlack);
+
+  fGraphPhys[gid] = (TGraph*) fGraph[gid]->Clone();
+  fGraphPhys[gid]->SetName(Form("gp%03d", gid));
+  fGraphPhys[gid]->SetMarkerStyle(20);
+  fGraphPhys[gid]->SetLineWidth(2);
+  for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5)
+    fGraphPhys[gid]->SetPoint(ip, tm, 0.);
+
+  fNgraph++;
+
+  return gid;
+}
+
+//___________________________________________________________________
+void CbmTrdFASP::Draw(Option_t* /*opt*/)
+{
+  if (!DRAW) return;
+  if (!fGraphMap.size()) return;
 
   TH1* h(nullptr);
-  TString st, sch;
-  Int_t ch, jg;
   TVirtualPad* c1(nullptr);
   if (!fMonitor) {
-    fMonitor = new TCanvas("c", "FASP Simulator", 10, 10, 1500, 2000);
-    fMonitor->Divide(2, 8, 1.e-5, 1.e-5);
-    for (Int_t ic(0); ic < 16; ic++) {
-      c1 = fMonitor->cd(ic + 1);
+    fMonitor = new TCanvas("c", "FASP Simulator", 10, 10, 1850, 2500);
+    fMonitor->Divide(4, 4, 1.e-5, 1.e-5);
+    for (Int_t ic(1); ic <= NFASPCH; ic++) {
+      c1 = fMonitor->cd(ic);
+      c1->SetLogy();
       c1->SetLeftMargin(0.03580097);
       c1->SetRightMargin(0.006067961);
       c1->SetTopMargin(0.01476793);
     }
-    //     fMonitor = new TCanvas("c", "FASP Simulator",10,10,500,1000);
-    //     fMonitor->Divide(1,2,1.e-5, 1.e-5);
-    //     for(Int_t ic(0); ic<2; ic++){
-    //       c1 = fMonitor->cd(ic+1);
-    //       c1->SetLeftMargin(0.03580097);
-    //       c1->SetRightMargin(0.006067961);
-    //       c1->SetTopMargin(0.01476793);
-    //     }
     fGthr = new TLine();
     fGthr->SetLineStyle(2);
   }
 
-  ig   = fGraphMap.begin();
-  last = ig->first;
-  for (Int_t iasic(0); iasic < nasic - 1; iasic++) {
-    while (ig != fGraphMap.end()) {
-      if (ig->first != last) {  // save graphs
-        fMonitor->Modified();
-        fMonitor->Update();
-        fMonitor->SaveAs(Form("FASP_analog_ASIC%03d.gif", last));
-        for (Int_t ic(0); ic < /*2*/ 16; ic++)
-          fMonitor->cd(ic + 1)->Clear();
-        last = ig->first;
-        break;
-      }
-      jg  = ig->second;
-      st  = fGraph[jg]->GetTitle();
-      sch = st(st.Sizeof() - 3, 2);
-      ch  = sch.Atoi();
-      if (ch >= 8) c1 = fMonitor->cd(2 + 2 * (ch - 8));  //->SetLogy();
+  for (auto iasic : fGraphMap) {
+    for (Int_t ic(0); ic < NFASPCH; ic++)
+      fMonitor->cd(ic + 1)->Clear();
+    for (int ich(0), jg(0); ich < NFASPCH; ich++) {
+      if (!(jg = iasic.second[ich])) continue;
+
+      int rch = ich / 4, cch = ich % 4;
+      c1 = fMonitor->cd(4 * cch + rch + 1);
+
+      if (!fGraph[jg]) LOG(error) << "Missing graph for " << jg;
+      else
+        fGraph[jg]->Draw("al");
+      if (!fGraphShp[jg]) LOG(error) << "Missing shaper graph for " << jg;
       else
-        c1 = fMonitor->cd(1 + 2 * ch);
-      fGraph[jg]->Draw("al");
-      fGraphShp[jg]->Draw("l");
-      fGraphPhys[jg]->Draw("lp");
+        fGraphShp[jg]->Draw("l");
+      if (!fGraphPhys[jg]) LOG(error) << "Missing physics graph for " << jg;
+      else
+        fGraphPhys[jg]->Draw("lp");
       fGthr->SetLineColor(kGreen);
       fGthr->DrawLine(0, fgShaperThr + 0.2, 5 * fOut.size(), fgShaperThr + 0.2);
       fGthr->SetLineColor(kRed);
       fGthr->DrawLine(0, fgNeighbourThr + 0.2, 5 * fOut.size(), fgNeighbourThr + 0.2);
       h = fGraph[jg]->GetHistogram();
-      h->GetYaxis()->SetRangeUser(0.01, 5.3);
-
-      ig++;
+      h->GetYaxis()->SetRangeUser(0.1, 6);
     }
+    fMonitor->Modified();
+    fMonitor->Update();
+    fMonitor->SaveAs(Form("FASP%03d_sim.png", iasic.first));
   }
-
-  //swap draw buffer
-  TGraph* buffer[NGRAPH] = {nullptr};
-  memcpy(buffer, fGraph, (jg + 1) * sizeof(TGraph*));
-  memcpy(fGraph, &fGraph[jg + 1], nlast * sizeof(TGraph*));
-  memcpy(&fGraph[nlast], buffer, (jg + 1) * sizeof(TGraph*));
-  memcpy(buffer, fGraphShp, (jg + 1) * sizeof(TGraph*));
-  memcpy(fGraphShp, &fGraphShp[jg + 1], nlast * sizeof(TGraph*));
-  memcpy(&fGraphShp[nlast], buffer, (jg + 1) * sizeof(TGraph*));
-  memcpy(buffer, fGraphPhys, (jg + 1) * sizeof(TGraph*));
-  memcpy(fGraphPhys, &fGraphPhys[jg + 1], nlast * sizeof(TGraph*));
-  memcpy(&fGraphPhys[nlast], buffer, (jg + 1) * sizeof(TGraph*));
-  fGraphId -= jg + 1;
-  fGraphMap.clear();
-  for (Int_t ich(0); ich < nlast; ich++)
-    fGraphMap.push_back(make_pair(last, ich));
 }
 
 //___________________________________________________________________
@@ -245,17 +254,17 @@ void CbmTrdFASP::GetShaperSignal(Double_t charge)
   }
 
   if (idx0 < 0) {  // above calibrated region
-    if (VERBOSE) printf("refMax[%2d]=%5.1f\n", fgkNDB - 1, fgkCharge[fgkNDB - 1]);
+    if (VERBOSE) printf(" refMax[%2d]=%5.1f", fgkNDB - 1, fgkCharge[fgkNDB - 1]);
     memcpy(fSignal, fgkShaper[fgkNDB - 1], FASP_WINDOW * sizeof(Float_t));
   }
   else if (idx0 == 0 && charge < fgkCharge[0]) {  // below calibrated region
-    if (VERBOSE) printf("refMin[0]={%5.1f}\n", fgkCharge[0]);
+    if (VERBOSE) printf(" refMin[0]={%5.1f}", fgkCharge[0]);
     for (Int_t it(0); it < FASP_WINDOW; it++)
       fSignal[it] = charge * fgkShaper[0][it] / fgkCharge[0];
   }
   else {
     idx1 = idx0 + 1;
-    if (VERBOSE) printf("ref={%5.1f[%2d] %5.1f[%2d]}\n", fgkCharge[idx0], idx0, fgkCharge[idx1], idx1);
+    if (VERBOSE) printf(" ref={%5.1f[%2d] %5.1f[%2d]}", fgkCharge[idx0], idx0, fgkCharge[idx1], idx1);
     // linear interpolation
     Double_t dq(fgkCharge[idx0] - fgkCharge[idx1]);
     for (Int_t it(0); it < FASP_WINDOW; it++)
@@ -265,9 +274,6 @@ void CbmTrdFASP::GetShaperSignal(Double_t charge)
   }
 }
 
-//___________________________________________________________________
-void CbmTrdFASP::Init(Int_t /*col*/, CbmTrdParFaspChannel* /*par*/) {}
-
 //___________________________________________________________________
 Double_t CbmTrdFASP::MakeOut(Int_t time)
 {
@@ -295,14 +301,14 @@ Double_t CbmTrdFASP::MakeOut(Int_t time)
 }
 
 //___________________________________________________________________
-void CbmTrdFASP::PhysToRaw(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi, Int_t col, Int_t row)
+void CbmTrdFASP::PhysToRaw(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi)
 {
   /** Public interface for converting physical digi to raw digi. See ScanDigi and ScanDigiNE for 
    * the actual algorithms  
    */
-  if (fgNeighbour) ScanDigiNE(vdigi, col, row);
+  if (fgNeighbour) ScanDigiNE(vdigi);
   else
-    ScanDigi(vdigi, col, row);
+    ScanDigi(vdigi);
 }
 
 //___________________________________________________________________
@@ -311,7 +317,7 @@ void CbmTrdFASP::Print(Option_t* opt) const
   /** Dump settings for the FASP simulator and optionally the content of the current buffers.
    */
 
-  printf("FASP Simulator : Col[%2d] NeighbourTrigger[%c]\n", fCol, fgNeighbour ? 'y' : 'n');
+  printf("FASP Simulator : Pad[%3d] NeighbourTrigger[%c]\n", fPad, fgNeighbour ? 'y' : 'n');
   printf("  Main CH      : Trigger[V]=%4.2f Flat-Top[ns]=%5.1f\n", fgShaperThr,
          fgkNclkFT * CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP));
   printf("  Neighbour CH : Trigger[V]=%4.2f Linear-gate[ns]=%5.1f\n", fgNeighbourThr,
@@ -342,12 +348,13 @@ Int_t CbmTrdFASP::ProcessShaper(Char_t typ)
    * Optionally the analog input and output for the current channel are also saved if DRAW is defined.
    */
 
+  int id(typ == 'T' ? 0 : 1), chId = fChId[id], asicId = fAsicId[id];
   if (VERBOSE)
-    printf("    CbmTrdFASP::ProcessShaper(%c) : row[%2d] col[%2d] asic[%4d] "
-           "PhysDigi[%d] GraphPtr[%d] ...\n",
-           typ, fRow, fCol, fAsicId, fNphys[0], (DRAW ? fGraphId : -1));
-  fTimeFT = -1;
-  fTimeLG = -1;
+    printf("    CbmTrdFASP::ProcessShaper(%c) : pad [%3d] asic/ch[%4d/%2d] "
+           "digis[%d] ...\n",
+           typ, fPad, asicId, chId, fNphys[id]);
+  fTimeFT = -1;  // length of the FT gate in 5ns bins (see fgkNclkFT)
+  fTimeLG = -1;  // length of the LG gate in 5ns bins (see fgkNclkLG)
   fFT     = 0;
   // digital signals
   Bool_t ht(0), htf(0),       // hit_threshold level/front for current FASP channel
@@ -356,19 +363,21 @@ Int_t CbmTrdFASP::ProcessShaper(Char_t typ)
     pk_cmd(0),                // peak_command level
     lg_cmd(0),                // linear-gate_command level
     trigger(0);               // trigger type [1] = self [0]=neighbour
-  UInt_t n(0),                // no of raw digi found in current shaper
-    htime(0);                 // hit time on current channel
-  Double_t out, max(-1), old(-1);
+  uint n(0),                  // no of raw digi found in current shaper
+    ht_time(0),               // hit time on current channel
+    cs_time(0);               // CS time on current channel
+  double out, max(-1), old(-1);
   for (size_t i = 1; i < fShaper.size() - 1; i++) {
     // compute hit threshold level/front for current and neighbour channels
     htf_prev = 0;
     htf      = 0;
     htf_next = 0;
-    if (/*fShaper[i-1]<fgNeighbourThr && */ fShaper[i] >= fgNeighbourThr) htime = i * 5;
+    //TODO NE if (/*fShaper[i-1]<fgNeighbourThr && */ fShaper[i] >= fgNeighbourThr) ht_time = i * 5;
     if (fShaper[i - 1] < fgShaperThr && fShaper[i] >= fgShaperThr) {
       ht      = 1;
       htf     = 1;
       trigger = 1;
+      ht_time = i * 5;
       if (VERBOSE) printf("      %4lu : HT 1\n", i * 5);
     }
     else if (fShaper[i - 1] >= fgShaperThr && fShaper[i] < fgShaperThr) {
@@ -396,8 +405,11 @@ Int_t CbmTrdFASP::ProcessShaper(Char_t typ)
     if (fTimeLG < 0) {  // check if linear-gate is closed
       if ((fgNeighbour && (htf_prev || htf || htf_next)) || (!fgNeighbour && htf)) {
         lg_cmd  = 1;
-        fTimeLG = i + 0.2 * fgNclkLG * CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP);
-        if (VERBOSE) printf("      %4lu : LG_CMD 1 -> MinGateEnd[ns]=%d\n", i * 5, fTimeLG * 5);
+        fTimeLG =
+          i
+          + 0.2 * fgNclkLG
+              * CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP);  // compute the end time of LG in FASP-sim 5ns clks
+        if (VERBOSE) printf("      %4lu : LG_CMD 1 -> LG_End[ns]=%d\n", i * 5, fTimeLG * 5);
       }
     }
     else if (static_cast<size_t>(fTimeLG) < i && !ht && !pk_cmd && (fgNeighbour && (!fHitThPrev[i] && !ht_next))) {
@@ -424,18 +436,21 @@ Int_t CbmTrdFASP::ProcessShaper(Char_t typ)
         max = out;
         if (VERBOSE) printf("      %4lu : MAX[V]=%5.2f\n", i * 5, max);
       }
-      if (out < max - 0.05) {
+      // start digital processing when the analog signal drops 50 mV under the max value.
+      // Adjust this value to the measured data in order to correctly describe the time difference spectra obtained (e.g. mCBM22)
+      if (out < max - 0.02) {
         fTimeFT = i + 0.2 * fgkNclkFT * CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP);
         fTimeDY = -1;
         fFT     = max + 0.01;
+        cs_time = uint((i + 3) * 5);
         // save data for digi update
         fDigiProc.push_back(make_tuple(
-          htime, UInt_t((i + 3) * 5), UInt_t(4095 * TMath::Min(Float_t(1.), (fgBaseline + fFT) / fgOutGain)), trigger));
+          ht_time, cs_time, UInt_t(4095 * TMath::Min(Float_t(1.), (fgBaseline + fFT) / fgOutGain)), trigger));
         n++;
         if (VERBOSE)
-          printf("      %4lu : HT[ns]=%4d FT[V]=%5.2f CS[ns]+=15 |CS[ns]=%d "
+          printf("      %4lu : HT[ns]=%4u FT[V]=%5.2f CS[ns]=%4u CS_End[ns]=%d "
                  "Trig[%c]\n",
-                 i * 5, htime, fFT, fTimeFT * 5, trigger ? 'S' : 'N');
+                 i * 5, ht_time, fFT, cs_time, fTimeFT * 5, trigger ? 'S' : 'N');
       }
     }
     if (fTimeFT > 0 && static_cast<size_t>(fTimeFT) <= i) {
@@ -458,91 +473,72 @@ Int_t CbmTrdFASP::ProcessShaper(Char_t typ)
 
   // save results for draw
   if (DRAW) {
-    if (fGraphId < NGRAPH - 1) {
-      Int_t ch = 2 * (fCol % 8) + (typ == 'R' ? 1 : 0), ip(0), time = fStartTime;
-      if (!fGraph[fGraphId]) {
-        fGraph[fGraphId] = new TGraph(fOut.size());
-        fGraph[fGraphId]->SetName(Form("g%03d", fGraphId));
-        fGraph[fGraphId]->SetFillStyle(0);
-        fGraph[fGraphId]->SetMarkerStyle(7);
-        fGraph[fGraphId]->SetLineColor(kRed);
-        fGraph[fGraphId]->SetMarkerColor(kRed);
-        fGraphShp[fGraphId] = (TGraph*) fGraph[fGraphId]->Clone();
-        fGraphShp[fGraphId]->SetName(Form("gs%03d", fGraphId));
-        fGraphShp[fGraphId]->SetLineColor(kBlack);
-        fGraphShp[fGraphId]->SetMarkerColor(kBlack);
-      }
-      fGraph[fGraphId]->SetTitle(Form("Col[%2d] Row[%2d] ASIC[%3d] Channel = %2d", fCol, fRow, fAsicId, ch));
-      fGraphMap.push_back(make_pair(fAsicId, fGraphId));
-      vector<Float_t>::const_iterator ot = fOut.cbegin(), st = fShaper.cbegin();
-      while (ot != fOut.cend()) {
-        fGraph[fGraphId]->SetPoint(ip, time, 0.3 + *ot);
-        ot++;
-        fGraphShp[fGraphId]->SetPoint(ip, time, 0.2 + *st);
-        st++;
-        time += 5;
-        ip++;
+    int gid = fGraphMap[asicId][chId];
+    if (!gid)
+      LOG(warn) << "CbmTrdFASP::ProcessShaper : Draw representation missing for "
+                << Form(" FASP id/ch[%3d/%2d].", asicId, chId);
+    else {
+      double time = fStartTime;
+      //printf("AB :: g%d[%s] size[%lu]\n", gid, fGraph[gid]->GetName(), fShaper.size());
+      for (uint ip(0); ip < fShaper.size(); ip++, time += 5.) {
+        //printf("time[%3d]=%.0f out[%f] shp[%f]\n", ip, time, 0.3+fOut[ip], 0.2+fShaper[ip]);
+        fGraph[gid]->SetPoint(ip, time, 0.3 + fOut[ip]);
+        fGraphShp[gid]->SetPoint(ip, time, 0.2 + fShaper[ip]);
       }
-      fGraphId += 1;
     }
-    else
-      LOG(warn) << "CbmTrdFASP::ProcessShaper : Draw buffer exhausted. Expert setting.";
   }
   // move to the next channel
   memcpy(fShaper.data(), fShaperNext.data(), fShaper.size() * sizeof(Float_t));
   memset(fShaperNext.data(), 0, fShaperNext.size() * sizeof(Float_t));
-  fNphys[0] = fNphys[1];
-  fNphys[1] = 0;
 
   return n;
 }
 
 //___________________________________________________________________
-void CbmTrdFASP::ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi, Int_t col, Int_t row)
+void CbmTrdFASP::ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi)
 {
   /** Transform point like time distribution of digis into the time dependent analog signal of the first FASP shaper
    */
 
-  CbmTrdDigi* digi(nullptr);
-  ULong64_t time;
-  Int_t dt, gid, asic = row * 9 + col / 8;
-  Double_t t, r;
-  if (fAsicId < 0) fAsicId = asic;  // init asic identifier
-  fCol    = col;
-  fRow    = row;
-  fAsicId = asic;
-  if (DRAW) {
-    gid = fGraphId + 1;
-    if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t));
-    else {
-      fGraphPhys[gid] = new TGraph(fOut.size());
-      fGraphPhys[gid]->SetName(Form("gp%03d", gid));
-      fGraphPhys[gid]->SetMarkerStyle(20);
-      fGraphPhys[gid]->SetLineWidth(2);
-      for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5)
-        fGraphPhys[gid]->SetPoint(ip, tm, 0.);
-    }
-  }
+  fPad      = -1;
+  fNphys[0] = 0;
+  fNphys[1] = 0;
+
   // process digi
-  std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator iv = vdigi->begin();
   vector<Float_t>::iterator itb;
-  while (iv != vdigi->end()) {
-    digi = iv->first;
-    time = (digi->GetTimeDAQ() - fStartTime) / 5;  // get time in 5ns bins
+  for (auto iv : (*vdigi)) {
+    CbmTrdDigi* digi = iv.first;
+
+    // first time initialize geographic location
+    if (fPad < 0) {
+      fPad = digi->GetAddressChannel();
+
+      if (VERBOSE > 1)
+        printf("  AB :: (%3d) fStartTime = %llu N=%lu ASIC=[%3d | %2d] ASIC=[%3d | %2d]\n", fPad, fStartTime,
+               vdigi->size(), fAsicId[0], fChId[0], fAsicId[1], fChId[1]);
+    }
+    ULong64_t time = (digi->GetTime() - fStartTime) / 5;  // get time in 5ns bins
+
+    if (VERBOSE > 1) printf("  AB :: digi->GetTime() = %f sim->time = %llu\n", digi->GetTime(), time * 5);
     if (time + FASP_WINDOW > fShaper.size()) {
-      LOG(debug) << "CbmTrdFASP::ScanDigi() : Digi @ row[" << row << "] col[" << col << "] time[" << digi->GetTimeDAQ()
+      LOG(debug) << "CbmTrdFASP::ScanDigi() : Digi @ pad[" << fPad << " time[" << digi->GetTime()
                  << "] dows not fit in the current buffer starting @ " << fStartTime << "ns. Skip this time.";
       break;
     }
 
-    r = digi->GetCharge(t, dt);
+    int dt;
+    double t, r = digi->GetCharge(t, dt);
     t /= 10;
     r /= 10;
     if (VERBOSE)
       printf("  time buffer[5ns]=%4llu / phys[ns]=%llu charge[fC]=%5.1f / %5.1f", time, digi->GetTimeDAQ(), t, r);
     // tilt pad channel
-    if (t > 0) {
-      if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), t / 100.);
+    if (t > 0 && fChId[0] >= 0) {
+      if (DRAW) {
+        int gid = fGraphMap[fAsicId[0]][fChId[0]];
+        if (!gid) fGraphMap[fAsicId[0]][fChId[0]] = gid = AddGraph('T');
+        if (gid) fGraphPhys[gid]->SetPoint(time, digi->GetTime(), t / 10.);
+      }
       GetShaperSignal(t);
       itb = fShaper.begin();
       itb += time;
@@ -550,11 +546,14 @@ void CbmTrdFASP::ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi,
         (*itb) += fSignal[it];
       fNphys[0]++;
     }
-    else if (VERBOSE)
-      printf("\n");
+
     // rect pad channel
-    if (r > 0) {
-      if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), r / 100.);
+    if (r > 0 && fChId[1] >= 0) {
+      if (DRAW) {
+        int gid = fGraphMap[fAsicId[1]][fChId[1]];
+        if (!gid) fGraphMap[fAsicId[1]][fChId[1]] = gid = AddGraph('R');
+        fGraphPhys[gid]->SetPoint(time, digi->GetTime(), r / 10.);
+      }
       GetShaperSignal(r);
       itb = fShaperNext.begin();
       itb += time + dt;
@@ -562,176 +561,185 @@ void CbmTrdFASP::ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi,
         (*itb) += fSignal[it];
       fNphys[1]++;
     }
-    else if (VERBOSE)
-      printf("\n");
-    iv++;
-  }
+
+    if (VERBOSE) printf("\n");
+  }  // end reading the digis
+
   if (fNphys[0]) fNraw = ProcessShaper('T');  // process tilt
   if (fNphys[1]) ProcessShaper('R');          // process rect
+
   fDigi = vdigi;
   WriteDigi();
 }
 
 //___________________________________________________________________
-void CbmTrdFASP::ScanDigiNE(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* vdigi, Int_t col, Int_t row)
+void CbmTrdFASP::ScanDigiNE(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* /*vdigi*/)
 {
   /** Transform point like time distribution of digis into the time dependent analog signal 
    * of the first FASP shaper and process output (see ProcessShaper())
    */
 
-  CbmTrdDigi* digi(nullptr);
-  ULong64_t time;
-  Int_t dt, gid, asic = row * 9 + col / 8;
-  Double_t t, r;
-  std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator iv;
-  vector<Float_t>::iterator itb;
-
-  if (fAsicId < 0) fAsicId = asic;  // init asic identifier
-
-  // printf("CbmTrdFASP::ScanDigiNE : fCol[%2d] col[%2d] graph[%d]\n", fCol, col, fGraphId);
-  // No interference from the previous data
-  if (fCol < 0 ||                        // first data in the module
-      (fCol >= 0 && col != fCol + 1) ||  // column jump
-      (fRow >= 0 && row != fRow)) {      // row jump
-    Clear((fAsicId != asic ? "draw" : ""));
-
-    if (DRAW) {
-      gid = fGraphId;
-      if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t));
-      else {
-        fGraphPhys[gid] = new TGraph(fOut.size());
-        fGraphPhys[gid]->SetName(Form("gp%03d", gid));
-        fGraphPhys[gid]->SetMarkerStyle(20);
-        fGraphPhys[gid]->SetLineWidth(2);
-        for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5)
-          fGraphPhys[gid]->SetPoint(ip, tm, 0.);
-      }
-    }
-
-    // load data from current tilt channel
-    iv = vdigi->begin();
-    while (iv != vdigi->end()) {
-      digi = iv->first;
-      time = (digi->GetTimeDAQ() - fStartTime) / 5;  // get time from buffer start in 5ns bins
-      if (time + FASP_WINDOW > fShaper.size()) {
-        LOG(debug) << "CbmTrdFASP::ScanDigiNE() : T-Digi @ row[" << row << "] col[" << col << "] time["
-                   << digi->GetTimeDAQ() << "] does not fit in the current buffer starting @ " << fStartTime
-                   << "ns. Skip this time.";
-        break;
-      }
-      digi->GetCharge(t, dt);
-      t /= 10.;
+  LOG(info) << "CbmTrdFASP::ScanDigiNE() : **Method under construction**. Use CbmTrdFASP::ScanDigi() instead by "
+               "selecting CbmTrdFASP:: SetNeighbourTrigger(0)";
+  return;
       if (VERBOSE)
         printf("  [T] time buffer[5ns]=%4llu / phys[ns]=%llu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), t);
-      // tilt pad channel
-      if (t > 0) {
-        if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), t / 100.);
-        GetShaperSignal(t);
-        itb = fShaper.begin();
-        itb += time;
-        for (Int_t it(0); it < FASP_WINDOW && itb != fShaper.end(); it++, itb++)
-          (*itb) += fSignal[it];
-        fNphys[0]++;
-      }
-      else if (VERBOSE)
-        printf("\n");
-      iv++;
-    }
-  }
-  else {
-    if (DRAW) {
-      gid = fGraphId + 1;
-      if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t));
-      else {
-        fGraphPhys[gid] = new TGraph(fOut.size());
-        fGraphPhys[gid]->SetName(Form("gp%03d", gid));
-        fGraphPhys[gid]->SetMarkerStyle(20);
-        fGraphPhys[gid]->SetLineWidth(2);
-        for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5)
-          fGraphPhys[gid]->SetPoint(ip, tm, 0.);
-      }
-    }
-
-    // load tilt digi to account for neighbour trigger
-    iv = vdigi->begin();
-    while (iv != vdigi->end()) {
-      digi = iv->first;
-      time = (digi->GetTimeDAQ() - fStartTime) / 5;  // get time from buffer start in 5ns bins
-      if (time + FASP_WINDOW > fShaper.size()) {
-        LOG(debug) << "CbmTrdFASP::ScanDigiNE() : T-Digi @ row[" << row << "] col[" << col << "] time["
-                   << digi->GetTimeDAQ() << "] does not fit in the current buffer starting @ " << fStartTime
-                   << "ns. Skip this time.";
-        break;
-      }
-      digi->GetCharge(t, dt);
-      t /= 10.;
-
       if (VERBOSE)
         printf("  [T] time buffer[5ns]=%4llu / phys[ns]=%llu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), t);
-      // tilt pad channel
-      if (t > 0) {
-        if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), t / 100.);
-        GetShaperSignal(t);
-        itb = fShaperNext.begin();
-        itb += time;
-        for (Int_t it(0); it < FASP_WINDOW && itb != fShaperNext.end(); it++, itb++)
-          (*itb) += fSignal[it];
-        fNphys[1]++;
-      }
-      else if (VERBOSE)
-        printf("\n");
-      iv++;
-    }
-    ProcessShaper('R');  // process previous rect channel
-    WriteDigi();         // finalize fDigi list
-  }
-
-  fCol    = col;
-  fRow    = row;
-  fAsicId = asic;
-
-  if (DRAW) {
-    gid = fGraphId + 1;
-    if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t));
-    else {
-      fGraphPhys[gid] = new TGraph(fOut.size());
-      fGraphPhys[gid]->SetName(Form("gp%03d", gid));
-      fGraphPhys[gid]->SetMarkerStyle(20);
-      fGraphPhys[gid]->SetLineWidth(2);
-      for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5)
-        fGraphPhys[gid]->SetPoint(ip, tm, 0.);
-    }
-  }
-  iv = vdigi->begin();
-  while (iv != vdigi->end()) {
-    digi = iv->first;
-    time = (digi->GetTimeDAQ() - fStartTime) / 5;  // get time from buffer start in 5ns bins
-    if (time + FASP_WINDOW > fShaper.size()) {
-      LOG(debug) << "CbmTrdFASP::ScanDigiNE() : R-Digi @ row[" << row << "] col[" << col << "] time["
-                 << digi->GetTimeDAQ() << "] dows not fit in the current buffer starting @ " << fStartTime
-                 << "ns. Skip this time.";
-      break;
-    }
-    r = digi->GetCharge(t, dt);
-    r /= 10.;
     if (VERBOSE) printf("  [R] time buffer[5ns]=%4llu / phys[ns]=%llu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), r);
 
-    // rect pad channel
-    if (r > 0) {
-      if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), r / 100.);
-      GetShaperSignal(r);
-      itb = fShaperNext.begin();
-      itb += time + dt;
-      for (Int_t it(0); it < FASP_WINDOW && itb != fShaperNext.end(); it++, itb++)
-        (*itb) += fSignal[it];
-      fNphys[1]++;
-    }
-    else if (VERBOSE)
-      printf("\n");
-    iv++;
-  }
-  fNraw = ProcessShaper('T');  // process tilt on current channel
-  fDigi = vdigi;               // save link for further processing
+  //   CbmTrdDigi* digi(nullptr);
+  //   ULong64_t time;
+  //   Int_t dt, gid, asic = row * 9 + col / 8;  // TODO should come from calibration
+  //   Double_t t, r;
+  //   std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator iv;
+  //   vector<Float_t>::iterator itb;
+  //
+  //   if (fAsicId < 0) fAsicId = asic;  // init asic identifier
+  //
+  //   // printf("CbmTrdFASP::ScanDigiNE : fCol[%2d] col[%2d] graph[%d]\n", fCol, col, fGraphId);
+  //   // No interference from the previous data
+  //   if (fCol < 0 ||                        // first data in the module
+  //       (fCol >= 0 && col != fCol + 1) ||  // column jump
+  //       (fRow >= 0 && row != fRow)) {      // row jump
+  //     Clear((fAsicId != asic ? "draw" : ""));
+  //
+  //     if (DRAW) {
+  //       gid = fGraphId;
+  //       if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t));
+  //       else {
+  //         fGraphPhys[gid] = new TGraph(fOut.size());
+  //         fGraphPhys[gid]->SetName(Form("gp%03d", gid));
+  //         fGraphPhys[gid]->SetMarkerStyle(20);
+  //         fGraphPhys[gid]->SetLineWidth(2);
+  //         for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5)
+  //           fGraphPhys[gid]->SetPoint(ip, tm, 0.);
+  //       }
+  //     }
+  //
+  //     // load data from current tilt channel
+  //     iv = vdigi->begin();
+  //     while (iv != vdigi->end()) {
+  //       digi = iv->first;
+  //       // TODO:AB  GetTimeDAQ() [clk] and fStartTime [ns]
+  //       time = (digi->GetTimeDAQ() - fStartTime) / 5;  // get time from buffer start in 5ns bins
+  //       if (time + FASP_WINDOW > fShaper.size()) {
+  //         LOG(debug) << "CbmTrdFASP::ScanDigiNE() : T-Digi @ row[" << row << "] col[" << col << "] time["
+  //                    << digi->GetTimeDAQ() << "] does not fit in the current buffer starting @ " << fStartTime
+  //                    << "ns. Skip this time.";
+  //         break;
+  //       }
+  //       digi->GetCharge(t, dt);
+  //       t /= 10.;
+  //       if (VERBOSE) printf("  [T] time buffer[5ns]=%4llu / phys[ns]=%lu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), t);
+  //       // tilt pad channel
+  //       if (t > 0) {
+  //         if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), t / 100.);
+  //         GetShaperSignal(t);
+  //         itb = fShaper.begin();
+  //         itb += time;
+  //         for (Int_t it(0); it < FASP_WINDOW && itb != fShaper.end(); it++, itb++)
+  //           (*itb) += fSignal[it];
+  //         fNphys[0]++;
+  //       }
+  //       else if (VERBOSE)
+  //         printf("\n");
+  //       iv++;
+  //     }
+  //   }
+  //   else {
+  //     if (DRAW) {
+  //       gid = fGraphId + 1;
+  //       if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t));
+  //       else {
+  //         fGraphPhys[gid] = new TGraph(fOut.size());
+  //         fGraphPhys[gid]->SetName(Form("gp%03d", gid));
+  //         fGraphPhys[gid]->SetMarkerStyle(20);
+  //         fGraphPhys[gid]->SetLineWidth(2);
+  //         for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5)
+  //           fGraphPhys[gid]->SetPoint(ip, tm, 0.);
+  //       }
+  //     }
+  //
+  //     // load tilt digi to account for neighbour trigger
+  //     iv = vdigi->begin();
+  //     while (iv != vdigi->end()) {
+  //       digi = iv->first;
+  //       time = (digi->GetTimeDAQ() - fStartTime) / 5;  // get time from buffer start in 5ns bins
+  //       if (time + FASP_WINDOW > fShaper.size()) {
+  //         LOG(debug) << "CbmTrdFASP::ScanDigiNE() : T-Digi @ row[" << row << "] col[" << col << "] time["
+  //                    << digi->GetTimeDAQ() << "] does not fit in the current buffer starting @ " << fStartTime
+  //                    << "ns. Skip this time.";
+  //         break;
+  //       }
+  //       digi->GetCharge(t, dt);
+  //       t /= 10.;
+  //
+  //       if (VERBOSE) printf("  [T] time buffer[5ns]=%4llu / phys[ns]=%lu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), t);
+  //       // tilt pad channel
+  //       if (t > 0) {
+  //         if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), t / 100.);
+  //         GetShaperSignal(t);
+  //         itb = fShaperNext.begin();
+  //         itb += time;
+  //         for (Int_t it(0); it < FASP_WINDOW && itb != fShaperNext.end(); it++, itb++)
+  //           (*itb) += fSignal[it];
+  //         fNphys[1]++;
+  //       }
+  //       else if (VERBOSE)
+  //         printf("\n");
+  //       iv++;
+  //     }
+  //     ProcessShaper('R');  // process previous rect channel
+  //     WriteDigi();         // finalize fDigi list
+  //   }
+  //
+  //   fCol    = col;
+  //   fRow    = row;
+  //   fAsicId = asic;
+  //
+  //   if (DRAW) {
+  //     gid = fGraphId + 1;
+  //     if (fGraphPhys[gid]) memset(fGraphPhys[gid]->GetY(), 0, fGraphPhys[gid]->GetN() * sizeof(Double_t));
+  //     else {
+  //       fGraphPhys[gid] = new TGraph(fOut.size());
+  //       fGraphPhys[gid]->SetName(Form("gp%03d", gid));
+  //       fGraphPhys[gid]->SetMarkerStyle(20);
+  //       fGraphPhys[gid]->SetLineWidth(2);
+  //       for (UInt_t ip(0), tm(fStartTime / 5); ip < fOut.size(); ip++, tm += 5)
+  //         fGraphPhys[gid]->SetPoint(ip, tm, 0.);
+  //     }
+  //   }
+  //   iv = vdigi->begin();
+  //   while (iv != vdigi->end()) {
+  //     digi = iv->first;
+  //     time = (digi->GetTimeDAQ() - fStartTime) / 5;  // get time from buffer start in 5ns bins
+  //     if (time + FASP_WINDOW > fShaper.size()) {
+  //       LOG(debug) << "CbmTrdFASP::ScanDigiNE() : R-Digi @ row[" << row << "] col[" << col << "] time["
+  //                  << digi->GetTimeDAQ() << "] dows not fit in the current buffer starting @ " << fStartTime
+  //                  << "ns. Skip this time.";
+  //       break;
+  //     }
+  //     r = digi->GetCharge(t, dt);
+  //     r /= 10.;
+  //     if (VERBOSE) printf("  [R] time buffer[5ns]=%4llu / phys[ns]=%lu charge[fC]=%5.1f ", time, digi->GetTimeDAQ(), r);
+  //
+  //     // rect pad channel
+  //     if (r > 0) {
+  //       if (DRAW) fGraphPhys[gid]->SetPoint(time, digi->GetTimeDAQ(), r / 100.);
+  //       GetShaperSignal(r);
+  //       itb = fShaperNext.begin();
+  //       itb += time + dt;
+  //       for (Int_t it(0); it < FASP_WINDOW && itb != fShaperNext.end(); it++, itb++)
+  //         (*itb) += fSignal[it];
+  //       fNphys[1]++;
+  //     }
+  //     else if (VERBOSE)
+  //       printf("\n");
+  //     iv++;
+  //   }
+  //   fNraw = ProcessShaper('T');  // process tilt on current channel
+  //   fDigi = vdigi;               // save link for further processing
 }
 
 //___________________________________________________________________
@@ -748,55 +756,53 @@ void CbmTrdFASP::WriteDigi()
 {
 
   if (!fDigi) return;
-  if (VERBOSE)
-    printf("      CbmTrdFASP::WriteDigi(T[%d], R[%d]) ...\n", fNraw + 1, Int_t(fDigiProc.size()) - fNraw + 1);
+  if (VERBOSE) printf("    CbmTrdFASP::WriteDigi(T[%d], R[%d]) ...\n", fNraw, Int_t(fDigiProc.size()) - fNraw);
 
-  vector<tuple<UInt_t, UInt_t, UInt_t, Bool_t>>::iterator it = fDigiProc.begin(),  // begin [tilt] iterator
-    jt                                                       = it + fNraw,         // middle [rect] iterator
-    lt                                                       = jt;                 // middle iterator
+  auto it = fDigiProc.begin(),  // [tilt] iterator
+    ir    = it + fNraw,         // [rect] iterator
+    im    = ir;                 // middle iterator
   CbmTrdDigi *digi(nullptr), *digi1(nullptr);
   CbmMatch* dmatch(nullptr);
-  ULong64_t time, dtime;
-  Int_t dt, ddt, trigger(0);
-  Double_t t, r, t0, r0;
-  UInt_t hTime,  // hit time [ns]
-    csTime,      // CS time  [ns]
+  ULong64_t time,  // relative time[ns] of PHYSICAL digi wrt the simulator window start
+    dtime;         // relative time[ns] of DIGITAL digi wrt the simulator window start
+  int dt, ddt, trigger(0);
+  double t, r, t0, r0;
+  uint ht_time,  // hit time [ns]
+    cs_time,     // CS time  [ns]
     tADC,        // tilt channel signal [ADC]
     rADC;        // rect channel signal [ADC]
   //Bool_t mask(0), pileup(0);
-  std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator jv, iv = fDigi->begin();
-
-  while (iv != fDigi->end()) {
-    digi   = iv->first;
-    dmatch = iv->second;
-    time   = (digi->GetTimeDAQ() - fStartTime);  // digi time in [ns] from buffer start
+  for (auto dd : (*fDigi)) {
+    digi   = dd.first;
+    dmatch = dd.second;
+    time   = (digi->GetTime() - fStartTime);  // digi time in [ns] from buffer start
     // stop digi finalize
     if (time > fProcTime) break;
     r = digi->GetCharge(t, dt);
     r /= 10.;
     t /= 10.;
-    if (VERBOSE) cout << "        IN : " << digi->ToString() << "         " << dmatch->ToString();
+    if (VERBOSE) cout << "      IN : " << digi->ToString() << "         " << dmatch->ToString();
 
     rADC    = 0;
     tADC    = 0;
-    dtime   = 0;
-    ddt     = 0; /*mask=0; pileup=0;*/
+    dtime   = 0;  // relative time of the prompt(T and R) CS signals expressed in ns
+    ddt     = 0;  // time difference between the T and R signals expressed in clks
     trigger = 0;
-    hTime   = 0;
-    while (it != lt) {
-      hTime = get<0>(*it);
-      if (VERBOSE) printf("        [T] htime[ns]=%d FT[ADC]=%4d ... \n", hTime, get<2>(*it));
-      if (hTime > time) break;
+    ht_time = 0;
+    while (it != im) {
+      ht_time = get<0>(*it);
+      if (VERBOSE) printf("      [T] htime[ns]=%d FT[ADC]=%4d ... \n", ht_time, get<2>(*it));
+      if (ht_time > time) break;
       it++;
     }
-    if (t > 0. && it != lt) {
-      csTime = get<1>(*it);
-      //printf("match T htime[%d] time[%d]\n", hTime, time);
-      if (hTime - time < 400) {  // found converted hit
+    if (t > 0. && it != im) {
+      cs_time = get<1>(*it);
+      //printf("match T htime[%d] time[%llu]\n", ht_time, time);
+      if (ht_time - time < 400) {  // found converted hit
         if (VERBOSE)
-          printf("        [T] ht[ns]=%4d CS[ns]=%4d FT[ADC]=%4u Trg[%s]\n", hTime, csTime, get<2>(*it),
+          printf("      [T] ht[ns]=%4d CS[ns]=%4d FT[ADC]=%4u Trg[%s]\n", ht_time, cs_time, get<2>(*it),
                  (get<3>(*it) ? "S" : "N"));
-        dtime = csTime;
+        dtime = cs_time;
         tADC  = get<2>(*it);
         if (get<3>(*it)) trigger |= 1;
         //if(csTime-hTime > 350) pileup = kTRUE; // 350 ns max peak time
@@ -804,59 +810,60 @@ void CbmTrdFASP::WriteDigi()
       }  //else if(t>40.) mask=kTRUE; // hit not converted : possible under threshold, masked
       // 40fC threshold
     }
+    //printf("AB :: time[%llu] dtime[%llu] dt[%d]\n", time, dtime, dt);
 
     time += dt;
-    hTime = 0;
-    while (jt != fDigiProc.end()) {
-      hTime = get<0>(*jt);
-      if (VERBOSE) printf("        [R] htime[ns]=%d FT[ADC]=%4d ...\n", hTime, get<2>(*jt));
-      if (hTime > time) break;
-      jt++;
+    ht_time = 0;
+    while (ir != fDigiProc.end()) {
+      ht_time = get<0>(*ir);
+      if (VERBOSE) printf("      [R] htime[ns]=%d FT[ADC]=%4d ...\n", ht_time, get<2>(*ir));
+      if (ht_time > time) break;
+      ir++;
     }
-    if (r > 0. && jt != fDigiProc.end()) {
-      csTime = get<1>(*jt);
-      //printf("match R htime[%d] time[%d]\n", hTime, time);
-      if (hTime - time < 400) {  // found converted hit
+    if (r > 0. && ir != fDigiProc.end()) {
+      cs_time = get<1>(*ir);
+      //printf("match R htime[%d] time[%llu]\n", ht_time, time);
+      if (ht_time - time < 400) {  // found converted hit
         if (VERBOSE)
-          printf("        [R] ht[ns]=%4d CS[ns]=%4d FT[ADC]=%4u Trg[%s]\n", hTime, csTime, get<2>(*jt),
-                 (get<3>(*jt) ? "S" : "N"));
+          printf("      [R] ht[ns]=%4d CS[ns]=%4d FT[ADC]=%4u Trg[%s]\n", ht_time, cs_time, get<2>(*ir),
+                 (get<3>(*ir) ? "S" : "N"));
         if (dtime) {
-          if (csTime > dtime)
-            ddt = TMath::Ceil(Int_t(csTime - dtime) / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP));
+          if (cs_time > dtime)
+            ddt = TMath::Ceil(Int_t(cs_time - dtime) / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP));
           else
-            ddt = TMath::Floor(Int_t(csTime - dtime) / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP));
+            ddt = TMath::Floor(Int_t(cs_time - dtime) / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP));
         }
         else
-          dtime = csTime;
-        rADC = get<2>(*jt);
-        if (get<3>(*jt)) trigger |= 2;
+          dtime = cs_time;
+        rADC = get<2>(*ir);
+        if (get<3>(*ir)) trigger |= 2;
         //if(csTime-hTime > 350) pileup = kTRUE; // 350 ns max peak time
-        jt++;
+        ir++;
       }  //else if(r>40.) mask=kTRUE;  // hit not converted : possible under threshold, masked
       // 40fC threshold
     }
 
+    //printf("AB :: time[%llu] dtime[%llu] ddt[%d]\n", time, dtime, ddt);
     //update digi
     digi->SetMasked(1);  // mark as processed
     if (dtime) {
       digi->SetTime(fStartTime + dtime);
       digi->SetCharge(tADC, rADC, ddt);
       digi->SetTriggerType(trigger);
-      if (VERBOSE) cout << "        OUT: " << digi->ToString();
+      if (VERBOSE) cout << "      OUT: " << digi->ToString();
     }
     else
       digi->SetFlag(0, kTRUE);  // mark for deletion
     if (VERBOSE)
       cout << "    ===================================="
            << "\n";
-    iv++;
   }
 
   // try to merge digits
   ULong64_t time0, time1;
   Char_t type0,  // prompt digi. kTRUE if rectangle
     type1;       // late digi. kTRUE if rectangle
-  for (iv = fDigi->begin(); iv != fDigi->end(); iv++) {
+  for (auto iv = fDigi->begin(); iv != fDigi->end(); iv++) {
     digi = iv->first;
     if (digi->IsFlagged(0)) continue;  // no output
     if (!digi->IsMasked()) break;      // not finalized
@@ -864,7 +871,7 @@ void CbmTrdFASP::WriteDigi()
     if (r0 > 0. && t0 > 0.) continue;  // already complete
     type0 = (r0 > 0. ? 1 : 0);         // mark type for prompt digi
     time0 = digi->GetTimeDAQ();        // mark time for prompt digi
-    for (jv = iv + 1; jv != fDigi->end(); jv++) {
+    for (auto jv = iv + 1; jv != fDigi->end(); jv++) {
       digi1 = jv->first;
       if (digi1->IsFlagged(0)) continue;  // no output
       r = digi1->GetCharge(t, dt);
diff --git a/core/detectors/trd/CbmTrdFASP.h b/core/detectors/trd/CbmTrdFASP.h
index f30a2a643e4fa75c9bb79452b6e762ff6bdb6e06..25ee4e0407cd1ec6aa6e71228561de5e4380cc42 100644
--- a/core/detectors/trd/CbmTrdFASP.h
+++ b/core/detectors/trd/CbmTrdFASP.h
@@ -5,13 +5,15 @@
 #ifndef CBMTRDFASP_H
 #define CBMTRDFASP_H
 
+#include "CbmTrdParFasp.h"
+
 #include <Rtypes.h>      // for THashConsistencyHolder, ClassDef
 #include <RtypesCore.h>  // for Int_t, Float_t, ULong64_t, UInt_t, Bool_t
 #include <TObject.h>     // for TObject
 #include <tuple>         // for tuple
 
+#include <map>      // for map
 #include <utility>  // for pair
-#include <vector>   // for vector
 
 class CbmMatch;
 class CbmTrdDigi;
@@ -22,7 +24,7 @@ class TLine;
 
 #define FASP_WINDOW 200
 #define SHAPER_LUT 80
-#define NGRAPH 160
+#define NGRAPH (NFASPMOD * NFASPCH + 1)
 
 /** \brief FASP channel simulator **/
 class CbmTrdFASP : public TObject {
@@ -42,23 +44,19 @@ public:
   static Float_t GetBaselineCorr() { return 4095. * fgBaseline / fgOutGain; }
   /** \brief Check if there is enough time elapsed from fStartTime to run simulator*/
   virtual Bool_t Go(ULong64_t time);
-  /** \brief [Re]Start processing of one channel
-   * \param[in] col current column
-   * \param[in] par FASP channel parametrization
+  /** \brief [Re]Initialize one of the two FASP channels 
+   * \param[in] id FASP-CHANNEL identifier
+   * \param[in] par FASP-CHANNEL parametrization
+   * \param[in] asicId FASP id on the module (as in the DAQ mapping) to be used on drawing
+   * \param[in] chId FASP-CHANNEL id on the module (as in the DAQ mapping) to be used on drawing
    */
-  virtual void Init(Int_t col, CbmTrdParFaspChannel* par);
+  virtual void InitChannel(int id, const CbmTrdParFaspChannel* par, int asicId = -1, int chId = -1);
   /** \brief Convert physics information in digi to the raw format
-   * \param[in] digi list of digits for the current channel
-   * \param[in] col column of current digis
-   * \param[in] row row of current digis
+   * \param[in] digi list of digits for the current pad
    */
-  virtual void PhysToRaw(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi, Int_t col = 0, Int_t row = 0);
+  virtual void PhysToRaw(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi);
   /** \brief Print-out FASP analog/digital response to currently stored data*/
   virtual void Print(Option_t* opt = "") const;
-  /** \brief Set column for the current channel
-   * \param[in] col column number in the current row. Default -1 for the first data
-   */
-  void SetCol(Int_t col) { fCol = col; }
   /** \brief Set linear-gate minimum length
    * \param[in] nclk number of clock cycles at current clock frequency
    */
@@ -81,6 +79,7 @@ public:
   void SetStartTime(ULong64_t t) { fStartTime = t; }
 
 protected:
+  int AddGraph(char typ = 'T');
   /** \brief Retrive linear interpolation of CADENCE for signal
    * \param[in] charge charge on channel
    */
@@ -91,46 +90,50 @@ protected:
    * \return no. of raw digi found
    */
   Int_t ProcessShaper(Char_t typ = 'T');
-  /** \brief Read digi array for single channel processing */
-  void ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi, Int_t col, Int_t row);
+  /** \brief Read digi array for one pair T/R defined by the pad column
+    \param[in] digi the set of digi and their MC info if avilable
+    */
+  void ScanDigi(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi);
   /** \brief Read digi array for neighbour trigger processing */
-  void ScanDigiNE(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi, Int_t col, Int_t row);
+  void ScanDigiNE(std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* digi);
   /** \brief Write processed digi to output array */
   void WriteDigi();
 
-  ULong64_t fStartTime;  ///< time offset [ns] for the current simulation
-  UInt_t fProcTime;      ///< time window [ns] for actual digi processing (excluded fgkBufferKeep)
-  Int_t fCol;            ///< current column
-  Int_t fRow;            ///< current row
-  Int_t fAsicId;         ///< identifier of FASP in module
+  ULong64_t fStartTime = 0;   ///< time offset [ns] for the current simulation
+  UInt_t fProcTime     = 0;   ///< time window [ns] for actual digi processing (excluded fgkBufferKeep)
+  int fPad             = -1;  ///< current pad as defined by CbmTrdModuleAbstract::GetPadAddress()
   Int_t fNphys[2];       ///< number of physical digi in the current [0] and next [1] shaper
-  Int_t fNraw;           ///< number of raw digi for the tilt channel
-  std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* fDigi;  ///< link to digi vector to be transformed
+  Int_t fNraw                                           = 0;        ///< number of raw digi for the tilt channel
+  std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>* fDigi = nullptr;  ///< link to digi vector to be transformed
 
   // analog support
-  std::vector<bool> fHitThPrev;      ///< previous channel hit threshold
-  std::vector<Float_t> fShaper;      ///< current channel shaper analog
-  std::vector<Float_t> fShaperNext;  ///< next channel shaper analog
-  std::vector<std::tuple<UInt_t, UInt_t, UInt_t, Bool_t>>
-    fDigiProc;                   ///< proccessed info <hit_time[ns], CS_time[ns], OUT[ADC], trigger>
-  Float_t fSignal[FASP_WINDOW];  ///< temporary array to store shaper analog signal for current charge interpolation
+  std::vector<bool> fHitThPrev     = {0};   ///< previous channel hit threshold
+  std::vector<Float_t> fShaper     = {0.};  ///< current channel shaper analog
+  std::vector<Float_t> fShaperNext = {0.};  ///< next channel shaper analog
+  std::vector<std::tuple<UInt_t, UInt_t, UInt_t, Bool_t>> fDigiProc =
+    {};  ///< proccessed info wrt fStartTime <hit_time[ns], CS_time[ns], OUT[ADC], trigger>
+  Float_t fSignal[FASP_WINDOW] = {
+    0.};  ///< temporary array to store shaper analog signal for current charge interpolation
 
   // FASP channel characteristics
-  CbmTrdParFaspChannel* fPar;  ///< current FASP channel parametrization
-  Int_t fTimeLG;               ///< Linear gate time length [5*ns]
-  Int_t fTimeFT;               ///< Chip Select time legth [5*ns]
-  Int_t fTimeDY;               ///< Time decay from FT [5*ns]
-  Float_t fFT;                 ///< Flat Top value [V]
-
-  // draw support
-  Int_t fGraphId;                                  ///< current graph to be filled if draw support is compiled
-  std::vector<Float_t> fOut;                       ///< analog output for the current channel
-  std::vector<std::pair<Int_t, Int_t>> fGraphMap;  ///<  map of ASIC id and output FASP signals
-  TGraph* fGraph[NGRAPH];                          ///< graph representations of analog FASP response
-  TGraph* fGraphShp[NGRAPH];                       ///< graph representations of FASP shaper
-  TGraph* fGraphPhys[NGRAPH];                      ///< graph representations of physics digi
-  TLine* fGthr;                                    ///< graph representation of various thresholds
-  TCanvas* fMonitor;                               ///< monitor canvas when drawing
+  const CbmTrdParFaspChannel* fPar[2] = {nullptr};  ///< current FASP ASIC parametrization
+  Int_t fTimeLG                       = -1;         ///< Linear gate time length [5*ns]
+  Int_t fTimeFT                       = -1;         ///< Chip Select time legth [5*ns]
+  Int_t fTimeDY                       = -1;         ///< Time decay from FT [5*ns]
+  Float_t fFT                         = 0.;         ///< Flat Top value [V]
+
+  // FASP graphic support
+  int fNgraph               = 1;         ///< No of graphs generated
+  int fAsicId[2]            = {-1, -1};  ///< identifier of FASP(s) in module
+  int fChId[2]              = {-1, -1};  ///< FASP channels being processed
+  std::vector<Float_t> fOut = {0.};      ///< analog output for the current channel
+  std::map<int, std::array<int, NFASPCH>> fGraphMap =
+    {};                                    ///<  map of ASIC_id and (ch_id, output_id of FASP signals graphs) pairs
+  TGraph* fGraph[NGRAPH]     = {nullptr};  ///< graph representations of analog FASP response
+  TGraph* fGraphShp[NGRAPH]  = {nullptr};  ///< graph representations of FASP shaper
+  TGraph* fGraphPhys[NGRAPH] = {nullptr};  ///< graph representations of physics digi
+  TLine* fGthr               = nullptr;    ///< graph representation of various thresholds
+  TCanvas* fMonitor          = nullptr;    ///< monitor canvas when drawing
 
   // CADENCE parameters
   static const Int_t fgkNDB = 53;                       ///< DB shaper size
diff --git a/sim/detectors/trd/CbmTrdDigitizer.cxx b/sim/detectors/trd/CbmTrdDigitizer.cxx
index 64786daa32001a677185a6def50efb6e88300b27..a328d179b11f3b10bdea1b7a1eaf5c8766fc18ee 100644
--- a/sim/detectors/trd/CbmTrdDigitizer.cxx
+++ b/sim/detectors/trd/CbmTrdDigitizer.cxx
@@ -210,7 +210,6 @@ void CbmTrdDigitizer::Exec(Option_t*)
     nofLatticeHits += n1;
     nofPointsAboveThreshold += n2;
     std::map<Int_t, std::pair<CbmTrdDigi*, CbmMatch*>>* digis = imod->second->GetDigiMap();
-    //printf("  Digits[%d] %d\n", imod->first, digis->size());
     for (std::map<Int_t, pair<CbmTrdDigi*, CbmMatch*>>::iterator it = digis->begin(); it != digis->end(); it++) {
       assert(it->second.second);
       CbmTrdDigi* digi = it->second.first;
@@ -309,6 +308,8 @@ CbmTrdModuleSim* CbmTrdDigitizer::AddModule(Int_t detId)
     else
       SetUseFASP();
     module = fModuleMap[moduleAddress] = new CbmTrdModuleSim2D(moduleAddress, lyId, orientation, UseFASP());
+    // AB :: calibration wrt the Tof detector as the T0 simulation is still in development (14.07.2022)
+    module->SetTimeSysOffset(-400);
     Int_t rType(-1);
     if ((rType = geoHandler.GetRadiatorType(path)) >= 0) {
       if (!fRadiator2D) {  // strong TRD-2D entrance window
diff --git a/sim/detectors/trd/CbmTrdModuleSim.h b/sim/detectors/trd/CbmTrdModuleSim.h
index 478adae7c61a2674e479e346eb703e06d647569c..777cae79e6f8d2ef775197c6bc88400a50339e3b 100644
--- a/sim/detectors/trd/CbmTrdModuleSim.h
+++ b/sim/detectors/trd/CbmTrdModuleSim.h
@@ -86,12 +86,14 @@ public:
   virtual void ResetCounters() { ; }
   virtual void SetMessageConverter(CbmTrdRawToDigiR* conv = NULL) = 0;
   virtual void SetQA(CbmTrdCheckUtil* qa = NULL)                  = 0;
+  virtual void SetTimeSysOffset(int dt) { fTimeSysOffset = dt; }
 
 protected:
   // definitions of MC input
   Int_t fPointId;               ///< MC point id being processed
   Int_t fEventId;               ///< MC event id being processed
   Int_t fInputId;               ///< MC input file number
+  Int_t fTimeSysOffset = 0;     ///< Time offset of TRD digis to align them with other detectors (T0, ToF)
   Double_t fXYZ[3];             ///< MC position of the point in module coordinates
   CbmTrdDigitizer* fDigitizer;  //! Pointer to digitizer
 
diff --git a/sim/detectors/trd/CbmTrdModuleSim2D.cxx b/sim/detectors/trd/CbmTrdModuleSim2D.cxx
index 0e064138b21a7eebe5e4cf02d97f0f1aada23809..6196159cc56e28e6782f21964e3b0d379f373697 100644
--- a/sim/detectors/trd/CbmTrdModuleSim2D.cxx
+++ b/sim/detectors/trd/CbmTrdModuleSim2D.cxx
@@ -49,7 +49,7 @@ CbmTrdModuleSim2D::CbmTrdModuleSim2D(Int_t mod, Int_t ly, Int_t rot, Bool_t FASP
   , fTimeSlice(NULL)
   , fTimeOld(0)
 {
-  SetNameTitle(Form("TrdSimT%d", mod), "Simulator for triangular read-out.");
+  SetNameTitle(Form("TrdSim2D%d", mod), "Simulator for triangular read-out.");
   SetFasp(FASP);
 }
 
@@ -546,7 +546,8 @@ void CbmTrdModuleSim2D::AddDigi(Int_t address, Double_t* charge, Double_t time /
   // make digi
   CbmTrdDigi *digi(NULL), *sdigi(NULL);
   CbmMatch* digiMatch(NULL);
-  digi = new CbmTrdDigi(address, charge[0], charge[1], ULong64_t(TMath::Ceil(time)));
+  digi = new CbmTrdDigi(address, charge[0], charge[1],
+                        ULong64_t(TMath::Ceil(time / CbmTrdDigi::Clk(CbmTrdDigi::eCbmTrdAsicType::kFASP))));
   digi->SetAddressModule(fModAddress);  // may not be needed in the future
   digiMatch          = new CbmMatch();
   Double_t weighting = fChmbPar->EfCkeV(charge[0] * 0.1);  // save th. energy which is seen by pads;
@@ -586,12 +587,11 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time)
  *  Calculate timely interaction between digits which are produced either on different anode wires for the same particle or
  * are produced by 2 particle close by. Also take into account FASP dead time and mark such digits correspondingly
  */
-
   if (UseFasp()) {
     if (!fFASP) {  // Build & configure FASP simulator
-      fFASP = new CbmTrdFASP(1000);
-      fFASP->SetNeighbourTrigger(1);
-      fFASP->SetLGminLength(31);
+      fFASP = new CbmTrdFASP(1000);   // initialize the FASP simulator for a time window of 5*1000 [ns]
+      fFASP->SetNeighbourTrigger(0);  // process neighbor trigger`
+      fFASP->SetLGminLength(31);      // linear gate length in [clk]
     }
   }
   else {
@@ -603,7 +603,10 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time)
     fTimeSlice             = (CbmTimeSlice*) ioman->GetObject("TimeSlice.");
   }
   Bool_t closeTS(kFALSE);
-  if (fTimeSlice) closeTS = (fTimeOld - fTimeSlice->GetEndTime() - 1000) > 0.;
+  if (fTimeSlice) {
+    closeTS = (fTimeOld - fTimeSlice->GetEndTime() - 1000) > 0.;
+    if (!time) closeTS = true;
+  }
   fTimeOld = time;
 
   if (VERBOSE)
@@ -620,58 +623,62 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time)
     cout << "\nPHYS DIGITS : \n";
     DumpBuffer();
   }
-  Int_t /*n1(0),*/ rowOld(-1), asicId, asicOld(-1);
-  CbmTrdDigi* digi(NULL);
-  CbmMatch* digiMatch(NULL);
-  // CbmTrdParFasp *fasp(NULL); const CbmTrdParFaspChannel *chFasp[2]={NULL}; (VF) not used
+  Int_t asicId, asicOld(-1);
+  CbmTrdDigi* digi(nullptr);
+  CbmMatch* digiMatch(nullptr);
+  CbmTrdParFasp* fasp(nullptr);
+  const CbmTrdParFaspChannel* chFasp[2] = {nullptr};
 
   // write from saved buffer
-  Int_t localAddress(0), ndigi(0) /*, n2(0)*/;
+  Int_t padAddress(0), ndigi(0);
   std::map<Int_t, std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>>::iterator it = fBuffer.begin();
   for (; it != fBuffer.end(); it++) {
-    localAddress = it->first;
-    ndigi        = fBuffer[localAddress].size();
+    padAddress = it->first;  // pad-column address
+    ndigi      = fBuffer[padAddress].size();
+    //printf("AB :: pad_address_%d [ndigi=%d (%lu)]\n", padAddress, ndigi, it->second.size());
     if (!ndigi) {
       //printf("FOUND saved vector empty @ %d\n", localAddress);
       continue;
     }
     // compute CBM address
-    Int_t col, row = GetPadRowCol(localAddress, col);
-
-    // get ASIC channel calibration
-    Int_t asicAddress = fAsicPar->GetAsicAddress(localAddress << 1);
-    if (asicAddress < 0) {
-      LOG(debug) << GetName() << "::FlushBuffer: FASP Calibration for ro_ch " << localAddress << " in module "
-                 << fModAddress << " missing.";
+    Int_t col, row = GetPadRowCol(padAddress, col);
+
+    // query FASP calibration
+    int chId[]       = {-1, -1},                              // read-out channels on the FASP ASIC
+      localAddress[] = {2 * padAddress, 2 * padAddress + 1},  // local channel address in module
+      faspIdOnMod[]  = {                                      // fasp identifier in module according to par mapping
+                       fAsicPar->GetAsicAddress(localAddress[0]), fAsicPar->GetAsicAddress(localAddress[1])};
+    // missing read-out; remove digis
+    if (faspIdOnMod[0] < 0 && faspIdOnMod[1] < 0) {
+      LOG(debug) << GetName() << "::FlushBuffer: FASP Calibration for pad " << padAddress << " at r/c=" << row << "/"
+                 << col << " in module " << fModAddress << " missing.";
       // clear physical digi for which there is no ASIC model available
-      for (auto iv = fBuffer[localAddress].begin(); iv != fBuffer[localAddress].end(); iv++)
+      for (auto iv = fBuffer[padAddress].begin(); iv != fBuffer[padAddress].end(); iv++)
         delete (*iv).first;
-      fBuffer[localAddress].clear();
-    }
-    else {
-      LOG(debug2) << GetName() << "::FlushBuffer: Found FASP " << asicAddress % 1000 << " for ro_ch " << localAddress
-                  << " in module " << fModAddress;
-      // fasp  = (CbmTrdParFasp*)fAsicPar->GetAsicPar(asicAddress); (VF) not used
-      //fasp->Print();
-      //       chFasp[0] = fasp->GetChannel(localAddress, 0);
-      //       chFasp[1] = fasp->GetChannel(localAddress, 1);
-    }
-
-    if (rowOld < 0) {  // first row
-      rowOld = row;
-      //printf("PROCESS FIRST ROW %d\n", row);
-    }
-    asicId = row * 9 + col / 8;
-    if (asicOld < 0) {  // first row
-      asicOld = asicId;
-      //printf("PROCESS FIRST ASIC %d\n", asicId);
+      fBuffer[padAddress].clear();
+      continue;
     }
-    if (row != rowOld || asicId != asicOld) {  // next row
-      //printf("PROCESS ASIC[%3d] ROW[%2d]\n", asicId, row);
-      rowOld  = row;
-      asicOld = asicId;
+    for (int ifasp(0); ifasp < 2; ifasp++) {
+      asicId = faspIdOnMod[ifasp];
+      // check FASP individually
+      if (asicId < 0) {
+        fFASP->InitChannel(ifasp, nullptr);
+        continue;
+      }
+      // load relevant FASP parameters if needed
+      if (asicId != asicOld) {
+        asicOld = asicId;
+
+        LOG(debug) << GetName() << "::FlushBuffer: Found FASP " << asicId % 1000 << " for module " << fModAddress
+                   << " local " << localAddress[ifasp];
+        fasp = (CbmTrdParFasp*) fAsicPar->GetAsicPar(asicId);
+        if (VERBOSE > 1) fasp->Print();
+      }
+      chId[ifasp]   = fasp->QueryChannel(localAddress[ifasp]);
+      chFasp[ifasp] = fasp->GetChannel(chId[ifasp]);
+      fFASP->InitChannel(ifasp, chFasp[ifasp], asicId, chId[ifasp]);
     }
-    fFASP->PhysToRaw(&(it->second), col, row);
+    fFASP->PhysToRaw(&(it->second));
   }
   if (fFASP) fFASP->Clear("draw");  // clear buffer
 
@@ -683,24 +690,23 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time)
 
   //save digitisation results
   Int_t n(0), nDigiLeft(0);
-  Double_t timeMin(-1), timeMax(0);
-  ULong64_t newStartTime(0);
+  double timeMin(-1), timeMax(0),  // time [ns]
+    newStartTime(0);
   it = fBuffer.begin();
-  std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::iterator iv;
   while (it != fBuffer.end()) {
-    localAddress = it->first;
-    if (!fBuffer[localAddress].size()) {
+    padAddress = it->first;
+    if (!fBuffer[padAddress].size()) {
       it++;
       continue;
     }
 
     digiMatch = NULL;
     Int_t col(-1), row(-1), srow, sec;
-    iv = fBuffer[localAddress].begin();
-    while (iv != fBuffer[localAddress].end()) {
+    auto iv = fBuffer[padAddress].begin();
+    while (iv != fBuffer[padAddress].end()) {
       digi = iv->first;
       if (!digi->IsMasked()) {  // no more digi processed
-        if (newStartTime == 0 || digi->GetTimeDAQ() < newStartTime) newStartTime = digi->GetTimeDAQ();
+        if (digi->GetTime() < newStartTime) newStartTime = digi->GetTime();
         break;
       }
       if (digi->IsFlagged(0)) {  // phys digi didn't produce CS/FT update last digiMatch
@@ -709,12 +715,12 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time)
           digiMatch->AddLink(iv->second->GetLink(0));
           if (VERBOSE) cout << "\t" << digiMatch->ToString();
         }
-        iv = fBuffer[localAddress].erase(iv);  // remove from saved buffer
+        iv = fBuffer[padAddress].erase(iv);  // remove from saved buffer
         continue;
       }
 
       if (col < 0) {
-        row = GetPadRowCol(localAddress, col);
+        row = GetPadRowCol(padAddress, col);
         sec = fDigiPar->GetSector(row, srow);
         if (VERBOSE)
           printf("CbmTrdModuleSim2D::FlushBuffer : request ly[%d] mod[%d] "
@@ -736,13 +742,13 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time)
       if (r > 1) r += (noise[1] - 0.5) * CbmTrdParFaspChannel::fgkSgmCh;
       digi->SetCharge(t, r, dt);
 
-      fDigitizer->SendData(digi->GetTime(), digi, digiMatch);
+      fDigitizer->SendData(digi->GetTime() + fTimeSysOffset, digi, digiMatch);
       n++;
-      iv = fBuffer[localAddress].erase(iv);  // remove from saved buffer
+      iv = fBuffer[padAddress].erase(iv);  // remove from saved buffer
     }
     // clear address if there are no more digits available
-    if (fBuffer[localAddress].size()) {
-      nDigiLeft += fBuffer[localAddress].size();
+    if (fBuffer[padAddress].size()) {
+      nDigiLeft += fBuffer[padAddress].size();
       //printf("%d left-overs @ %d\n", fBuffer[localAddress].size(), localAddress);
       it++;
     }
@@ -750,11 +756,13 @@ Int_t CbmTrdModuleSim2D::FlushBuffer(ULong64_t time)
       it = fBuffer.erase(it);
   }
   if (VERBOSE)
-    printf("CbmTrdModuleSim2D::FlushBuffer : write %d digis from %duns to "
-           "%duns. Digits still in buffer %d\n",
+    printf("CbmTrdModuleSim2D::FlushBuffer : write %d digis in [%d - "
+           "%d]ns. Digits still in buffer %d\n",
            n, TMath::Nint(timeMin), TMath::Nint(timeMax), nDigiLeft);
-  fFASP->SetStartTime(newStartTime);
-  fFASP->SetProcTime();
+  if (newStartTime > 0) fFASP->SetStartTime(newStartTime);
+  else
+    fFASP->SetStartTime(fFASP->GetEndTime());
+  fFASP->SetProcTime(time);
 
   //iteratively process all digi at the end of run
   if (time == 0 && nDigiLeft) n += FlushBuffer();
@@ -767,11 +775,11 @@ void CbmTrdModuleSim2D::DumpBuffer() const
   for (std::map<Int_t, std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>>::const_iterator it = fBuffer.begin();
        it != fBuffer.end(); it++) {
     if (!it->second.size()) continue;
-    printf("address[%10d] n[%2d]\n", it->first, (Int_t) it->second.size());
+    if (VERBOSE > 1) printf("address[%10d] n[%2d]\n", it->first, (Int_t) it->second.size());
     for (std::vector<std::pair<CbmTrdDigi*, CbmMatch*>>::const_iterator iv = it->second.cbegin();
          iv != it->second.cend(); iv++) {
       cout << "\t" << (iv->first->IsFlagged(0) ? 'P' : 'D') << "[" << iv->first << "] " << iv->first->ToString();
-      cout << "\t" << iv->second->ToString();
+      if (VERBOSE > 2) cout << "\t" << iv->second->ToString();
     }
   }
 }