diff --git a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx
index 7dbc8bc3e45d9ed33f2ed1a1aa6d1fbdafc37c5c..9477202f2bdcc98c51557aa387a2e918b6c5d297 100644
--- a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx
+++ b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx
@@ -33,6 +33,18 @@
 template<>
 void CbmAlgoBuildRawEvents::LoopOnSeeds<Double_t>();
 
+template<class Digi>
+uint32_t GetTofDetType(const Digi* /*pDigi*/)
+{
+  return 0;
+}
+
+uint32_t GetTofDetType(const CbmTofDigi* pDigi)
+{
+  /// Used only if TOF digi, otherwise template with 0 return is called
+  return CbmTofAddress::GetSmType(pDigi->GetAddress());
+}
+
 Bool_t CbmAlgoBuildRawEvents::InitAlgo()
 {
   LOG(info) << "CbmAlgoBuildRawEvents::InitAlgo => Starting sequence";
@@ -271,13 +283,44 @@ template<class DigiSeed>
 void CbmAlgoBuildRawEvents::LoopOnSeeds()
 {
   if (ECbmModuleId::kT0 == fRefDet.detId) {
-    const UInt_t uNbRefDigis = fT0DigiVec->size();
-    /// Loop on size of vector
-    for (UInt_t uDigi = 0; uDigi < uNbRefDigis; ++uDigi) {
-      LOG(debug) << Form("Checking seed %6u / %6u", uDigi, uNbRefDigis);
-      Double_t dTime = fT0DigiVec->at(uDigi).GetTime();
-      /// Check Seed and build event if needed
-      CheckSeed(dTime, uDigi);
+    if (0 == fuDetTypeT0) {
+      const UInt_t uNbRefDigis = fT0DigiVec->size();
+      /// Loop on size of vector
+      for (UInt_t uDigi = 0; uDigi < uNbRefDigis; ++uDigi) {
+        LOG(debug) << Form("Checking seed %6u / %6u", uDigi, uNbRefDigis);
+        Double_t dTime = fT0DigiVec->at(uDigi).GetTime();
+
+        /// Check if seed in acceptance window
+        if (dTime < fdSeedWindowBeg) { continue; }
+        else if (fdSeedWindowEnd < dTime) {
+          break;
+        }
+        /// Check Seed and build event if needed
+        CheckSeed(dTime, uDigi);
+      }
+    }
+    else {
+      // filter T0 digis from Tof (remove this block if T0 properly implemented)
+      const UInt_t uNbRefDigis = GetNofDigis(ECbmModuleId::kTof);
+      /// Loop on size of vector
+      for (UInt_t uDigi = 0; uDigi < uNbRefDigis; ++uDigi) {
+        LOG(debug) << Form("Checking seed %6u / %6u", uDigi, uNbRefDigis);
+
+        const DigiSeed* pDigi = GetDigi<DigiSeed>(uDigi);
+
+        // filter T0 digis from Tof
+        if (GetTofDetType(pDigi) != fuDetTypeT0) { continue; }
+
+        const Double_t dTime = pDigi->GetTime();
+
+        /// Check if seed in acceptance window
+        if (dTime < fdSeedWindowBeg) { continue; }
+        else if (fdSeedWindowEnd < dTime) {
+          break;
+        }
+        /// Check Seed and build event if needed
+        CheckSeed(dTime, uDigi);
+      }
     }
   }
   else {
@@ -289,7 +332,7 @@ void CbmAlgoBuildRawEvents::LoopOnSeeds()
       const DigiSeed* pDigi = GetDigi<DigiSeed>(uDigi);
 
       // filter T0 digis from Tof (remove this line if T0 properly implemented)
-      if (fRefDet.detId == ECbmModuleId::kTof && pDigi->GetAddress() == fuT0Address) { continue; }
+      if (fRefDet.detId == ECbmModuleId::kTof && 0 != fuDetTypeT0 && GetTofDetType(pDigi) == fuDetTypeT0) { continue; }
 
       const Double_t dTime = pDigi->GetTime();
 
@@ -359,10 +402,22 @@ void CbmAlgoBuildRawEvents::CheckSeed(Double_t dSeedTime, UInt_t uSeedDigiIdx)
     if (fRefDet.fdTimeWinBeg < fRefDet.fdTimeWinEnd) {
       SearchMatches(dSeedTime, fRefDet);
       /// Also add the seed if the window starts after the seed
-      if (0 < fRefDet.fdTimeWinBeg) AddDigiToEvent(fRefDet, uSeedDigiIdx);
+      if (0 < fRefDet.fdTimeWinBeg) {
+        if (ECbmModuleId::kT0 == fRefDet.detId && 0 != fuDetTypeT0) {
+          AddDigiToEvent(kRawEventBuilderDetTof, uSeedDigiIdx);
+        }
+        else {
+          AddDigiToEvent(fRefDet, uSeedDigiIdx);
+        }
+      }
     }
     else {
-      AddDigiToEvent(fRefDet, uSeedDigiIdx);
+      if (ECbmModuleId::kT0 == fRefDet.detId && 0 != fuDetTypeT0) {
+        AddDigiToEvent(kRawEventBuilderDetTof, uSeedDigiIdx);
+      }
+      else {
+        AddDigiToEvent(fRefDet, uSeedDigiIdx);
+      }
     }
   }
 
@@ -468,12 +523,73 @@ void CbmAlgoBuildRawEvents::SearchMatches(Double_t dSeedTime, RawEventBuilderDet
 
   /// Check the Digis until out of window
   if (ECbmModuleId::kT0 == detMatch.detId) {
+    if (0 == fuDetTypeT0) {
+      /// Loop on size of vector
+      const UInt_t uNbSelDigis = fT0DigiVec->size();
+      for (UInt_t uDigi = detMatch.fuStartIndex; uDigi < uNbSelDigis; ++uDigi) {
+        const Double_t dTime     = fT0DigiVec->at(uDigi).GetTime();
+        const Double_t dTimeDiff = dTime - dSeedTime;
+
+        /// Check if within time window, update start/stop indices if needed
+        if (dTimeDiff < detMatch.fdTimeWinBeg) {
+          ++uLocalIndexStart;
+          continue;
+        }
+        else if (detMatch.fdTimeWinEnd < dTimeDiff) {
+          /// Store as end the first digi out of window to avoid double counting in case of
+          /// merged overlap event mode
+          uLocalIndexEnd = uDigi;
+          break;
+        }
+        AddDigiToEvent(detMatch, uDigi);
+        if (fdPrevEvtEndTime < dTime) fdPrevEvtEndTime = dTime;
+      }
 
+      /// catch the case where we reach the end of the vector before being out of the time window
+      if (uLocalIndexEnd < uLocalIndexStart) uLocalIndexEnd = uNbSelDigis;
+    }
+    else {
+      // filter T0 digis from Tof (remove this block if T0 properly implemented)
+      const UInt_t uNbSelDigis = GetNofDigis(ECbmModuleId::kTof);
+      /// Loop on size of vector
+      for (UInt_t uDigi = detMatch.fuStartIndex; uDigi < uNbSelDigis; ++uDigi) {
+        const DigiCheck* pDigi = GetDigi<DigiCheck>(uDigi);
+
+        const Double_t dTime     = pDigi->GetTime();
+        const Double_t dTimeDiff = dTime - dSeedTime;
+        LOG(debug4) << detMatch.sName << Form(" => Checking match %6u / %6u, dt %f", uDigi, uNbSelDigis, dTimeDiff);
+
+        /// Check if within time window, update start/stop indices if needed
+        if (dTimeDiff < detMatch.fdTimeWinBeg) {
+          ++uLocalIndexStart;
+          continue;
+        }
+        else if (detMatch.fdTimeWinEnd < dTimeDiff) {
+          /// Store as end the first digi out of window to avoid double counting in case of
+          /// merged overlap event mode
+          uLocalIndexEnd = uDigi;
+          break;
+        }
+
+        // filter T0 digis from Tof
+        if (GetTofDetType(pDigi) != fuDetTypeT0) { continue; }
+
+        AddDigiToEvent(kRawEventBuilderDetTof, uDigi);
+        if (fdPrevEvtEndTime < dTime) fdPrevEvtEndTime = dTime;
+      }
+      /// catch the case where we reach the end of the vector before being out of the time window
+      if (uLocalIndexEnd < uLocalIndexStart) uLocalIndexEnd = uNbSelDigis;
+    }
+  }
+  else {
+    const UInt_t uNbSelDigis = GetNofDigis(detMatch.detId);
     /// Loop on size of vector
-    const UInt_t uNbSelDigis = fT0DigiVec->size();
     for (UInt_t uDigi = detMatch.fuStartIndex; uDigi < uNbSelDigis; ++uDigi) {
-      const Double_t dTime     = fT0DigiVec->at(uDigi).GetTime();
+      const DigiCheck* pDigi = GetDigi<DigiCheck>(uDigi);
+
+      const Double_t dTime     = pDigi->GetTime();
       const Double_t dTimeDiff = dTime - dSeedTime;
+      LOG(debug4) << detMatch.sName << Form(" => Checking match %6u / %6u, dt %f", uDigi, uNbSelDigis, dTimeDiff);
 
       /// Check if within time window, update start/stop indices if needed
       if (dTimeDiff < detMatch.fdTimeWinBeg) {
@@ -486,18 +602,6 @@ void CbmAlgoBuildRawEvents::SearchMatches(Double_t dSeedTime, RawEventBuilderDet
         uLocalIndexEnd = uDigi;
         break;
       }
-      AddDigiToEvent(detMatch, uDigi);
-      if (fdPrevEvtEndTime < dTime) fdPrevEvtEndTime = dTime;
-    }
-
-    /// catch the case where we reach the end of the vector before being out of the time window
-    if (uLocalIndexEnd < uLocalIndexStart) uLocalIndexEnd = uNbSelDigis;
-  }
-  else {
-    const UInt_t uNbSelDigis = GetNofDigis(detMatch.detId);
-    /// Loop on size of vector
-    for (UInt_t uDigi = detMatch.fuStartIndex; uDigi < uNbSelDigis; ++uDigi) {
-      const DigiCheck* pDigi = GetDigi<DigiCheck>(uDigi);
 
       // Filter TRD2D digis if 1D and reverse
       if (detMatch.detId == ECbmModuleId::kTrd) {
@@ -514,23 +618,8 @@ void CbmAlgoBuildRawEvents::SearchMatches(Double_t dSeedTime, RawEventBuilderDet
       }
 
       // filter T0 digis from Tof (remove this line if T0 properly implemented)
-      //if (detMatch.detId == ECbmModuleId::kTof && pDigi->GetAddress() == fuT0Address) { continue; }
-
-      const Double_t dTime     = pDigi->GetTime();
-      const Double_t dTimeDiff = dTime - dSeedTime;
-      LOG(debug4) << detMatch.sName << Form(" => Checking match %6u / %6u, dt %f", uDigi, uNbSelDigis, dTimeDiff);
+      if (detMatch.detId == ECbmModuleId::kTof && 0 != fuDetTypeT0 && GetTofDetType(pDigi) == fuDetTypeT0) { continue; }
 
-      /// Check if within time window, update start/stop indices if needed
-      if (dTimeDiff < detMatch.fdTimeWinBeg) {
-        ++uLocalIndexStart;
-        continue;
-      }
-      else if (detMatch.fdTimeWinEnd < dTimeDiff) {
-        /// Store as end the first digi out of window to avoid double counting in case of
-        /// merged overlap event mode
-        uLocalIndexEnd = uDigi;
-        break;
-      }
       AddDigiToEvent(detMatch, uDigi);
       if (fdPrevEvtEndTime < dTime) fdPrevEvtEndTime = dTime;
     }
@@ -543,7 +632,7 @@ void CbmAlgoBuildRawEvents::SearchMatches(Double_t dSeedTime, RawEventBuilderDet
   detMatch.fuEndIndex   = uLocalIndexEnd;
 }
 
-void CbmAlgoBuildRawEvents::AddDigiToEvent(RawEventBuilderDetector& det, Int_t _entry)
+void CbmAlgoBuildRawEvents::AddDigiToEvent(const RawEventBuilderDetector& det, Int_t _entry)
 {
   fCurrentEvent->AddData(det.dataType, _entry);
 }
@@ -586,7 +675,7 @@ Bool_t CbmAlgoBuildRawEvents::HasTrigger(CbmEvent* event)
   return kTRUE;
 }
 
-Bool_t CbmAlgoBuildRawEvents::CheckTriggerConditions(CbmEvent* event, RawEventBuilderDetector& det)
+Bool_t CbmAlgoBuildRawEvents::CheckTriggerConditions(CbmEvent* event, const RawEventBuilderDetector& det)
 {
   /// Check if both Trigger conditions disabled for this detector
   if (0 == det.fuTriggerMinDigis && det.fiTriggerMaxDigis < 0) { return kTRUE; }
@@ -600,7 +689,30 @@ Bool_t CbmAlgoBuildRawEvents::CheckTriggerConditions(CbmEvent* event, RawEventBu
   }
 
   /// Check trigger rejection by minimal number or absence
-  const Int_t iNbDigis = event->GetNofData(det.dataType);
+  int32_t iNbDigis = event->GetNofData(det.dataType);
+  if (0 != fuDetTypeT0) {
+    // filter T0 digis from Tof (remove this block if T0 properly implemented)
+    if (ECbmModuleId::kT0 == det.detId || ECbmModuleId::kTof == det.detId) {
+      iNbDigis                 = 0;
+      int32_t uNbSelDigisTofT0 = event->GetNofData(kRawEventBuilderDetTof.dataType);
+      /// Loop on size of vector
+      for (int32_t iDigi = 0; iDigi < uNbSelDigisTofT0; ++iDigi) {
+        uint idx                = event->GetIndex(kRawEventBuilderDetTof.dataType, iDigi);
+        const CbmTofDigi* pDigi = GetDigi<CbmTofDigi>(idx);
+        if (nullptr == pDigi) continue;
+
+        // filter T0 digis from Tof
+        if (GetTofDetType(pDigi) == fuDetTypeT0) {  //
+          if (ECbmModuleId::kT0 == det.detId) {     //
+            iNbDigis++;
+          }
+        }
+        else if (ECbmModuleId::kTof == det.detId) {  //
+          iNbDigis++;
+        }
+      }
+    }
+  }
   if ((-1 == iNbDigis) || (static_cast<UInt_t>(iNbDigis) < det.fuTriggerMinDigis)) {
     LOG(debug2) << "Event does not have enough digis: " << iNbDigis << " vs " << det.fuTriggerMinDigis << " for "
                 << det.sName;
@@ -663,14 +775,14 @@ Bool_t CbmAlgoBuildRawEvents::CheckTriggerConditions(CbmEvent* event, RawEventBu
         break;
       }
       case ECbmModuleId::kMuch: {
-        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for "
+        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckTriggerConditions => Fired layers check not implemented yet for "
                    << det.sName;
         return kFALSE;
         break;
       }
       case ECbmModuleId::kTrd2d:  // Same data storage as trd 1d
       case ECbmModuleId::kTrd: {
-        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for "
+        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckTriggerConditions => Fired layers check not implemented yet for "
                    << det.sName;
         return kFALSE;
         break;
@@ -716,25 +828,25 @@ Bool_t CbmAlgoBuildRawEvents::CheckTriggerConditions(CbmEvent* event, RawEventBu
         break;
       }
       case ECbmModuleId::kRich: {
-        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for "
+        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckTriggerConditions => Fired layers check not implemented yet for "
                    << det.sName;
         return kFALSE;
         break;
       }
       case ECbmModuleId::kPsd: {
-        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for "
+        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckTriggerConditions => Fired layers check not implemented yet for "
                    << det.sName;
         return kFALSE;
         break;
       }
       case ECbmModuleId::kT0: {
-        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for "
+        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckTriggerConditions => Fired layers check not implemented yet for "
                    << det.sName;
         return kFALSE;
         break;
       }
       default: {
-        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => Fired layers check not implemented yet for "
+        LOG(fatal) << "CbmAlgoBuildRawEvents::CheckTriggerConditions => Fired layers check not implemented yet for "
                    << det.sName;
         return kFALSE;
         break;
@@ -748,7 +860,7 @@ Bool_t CbmAlgoBuildRawEvents::CheckTriggerConditions(CbmEvent* event, RawEventBu
 
 //----------------------------------------------------------------------
 
-Bool_t CbmAlgoBuildRawEvents::CheckDataAvailable(RawEventBuilderDetector& det)
+Bool_t CbmAlgoBuildRawEvents::CheckDataAvailable(const RawEventBuilderDetector& det)
 {
   if (!CheckDataAvailable(det.detId)) {
     LOG(info) << "No " << det.sName << " digi input found.";
@@ -783,7 +895,9 @@ bool CbmAlgoBuildRawEvents::CheckDataAvailable(ECbmModuleId detId)
       return fPsdDigis != nullptr;
     }
     case ECbmModuleId::kT0: {
-      return fT0DigiVec != nullptr;
+      if (0 != fuDetTypeT0) return fTofDigis != nullptr;
+      else
+        return fT0DigiVec != nullptr;
     }
     default: {
       LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => "
@@ -819,7 +933,9 @@ UInt_t CbmAlgoBuildRawEvents::GetNofDigis(ECbmModuleId detId)
       return fPsdDigis->size();
     }
     case ECbmModuleId::kT0: {
-      return fT0DigiVec->size();  //what to do here? Not in digi manager.
+      if (0 != fuDetTypeT0) return fTofDigis->size();
+      else
+        return fT0DigiVec->size();  //what to do here? Not in digi manager.
     }
     default: {
       LOG(fatal) << "CbmAlgoBuildRawEvents::GetNofDigis => "
@@ -889,6 +1005,13 @@ void CbmAlgoBuildRawEvents::CreateHistograms()
   }
 
   /// Same plots for the reference detector
+  TH2I* hNbDigiPerEvtTimeDet = new TH2I(Form("hNbDigiPerEvtTime%s", fRefDet.sName.data()),
+                                        Form("nb of %s digis per event vs seed time of the events; Seed time in TS "
+                                             "[s]; Nb Digis []; Events []",
+                                             fRefDet.sName.data()),
+                                        1000, 0, 0.2, 5000, 0, 5000);
+  fvhNbDigiPerEvtTimeDet.push_back(hNbDigiPerEvtTimeDet);
+
   TH1I* hNbDigiPerEvtDet =
     new TH1I(Form("hNbDigiPerEvt%s", fRefDet.sName.data()),
              Form("nb of %s digis per event; Nb Digis []", fRefDet.sName.data()), 10000, 0, 10000);
@@ -1008,13 +1131,53 @@ void CbmAlgoBuildRawEvents::FillHistos()
     fhNbDigiPerEvtTime->Fill(evt->GetStartTime() * 1e-9, evt->GetNofData());
 
     /// Loop on selection detectors
+    uint32_t uNbDataT0    = 0;  // filter T0 digis from Tof (remove this block if T0 properly implemented)
+    uint32_t uNbDataTof   = 0;  // filter T0 digis from Tof (remove this block if T0 properly implemented)
     uint32_t uNbDataTrd1d = 0;
     uint32_t uNbDataTrd2d = 0;
     for (UInt_t uDetIdx = 0; uDetIdx < fvDets.size(); ++uDetIdx) {
       if (nullptr == fvhNbDigiPerEvtDet[uDetIdx]) continue;
 
-      fvhNbDigiPerEvtDet[uDetIdx]->Fill(TMath::Max(0, evt->GetNofData(fvDets[uDetIdx].dataType)));
-      if (nullptr == fvhTDiff[uDetIdx]) continue;
+      if (0 != fuDetTypeT0) {
+        // filter T0 digis from Tof (remove this block if T0 properly implemented)
+        if (ECbmDataType::kT0Digi == fvDets[uDetIdx].dataType) {
+          for (int idigi = 0; idigi < evt->GetNofData(ECbmDataType::kTofDigi); ++idigi) {
+            double dTimeDiff = 1.E30;
+            uint idx         = evt->GetIndex(ECbmDataType::kTofDigi, idigi);
+            auto pDigi       = GetDigi<CbmTofDigi>(idx);
+            if (nullptr == pDigi) continue;
+
+            // filter T0 digis from Tof
+            if (GetTofDetType(pDigi) == fuDetTypeT0) {
+              uNbDataT0++;
+              dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
+              if (dTimeDiff < 1.E30) {  //
+                fvhTDiff[uDetIdx]->Fill(dTimeDiff);
+              }
+            }
+          }
+          continue;
+        }  // if (ECbmDataType::kT0Digi == fvDets[uDetIdx].dataType)
+        else if (ECbmDataType::kTofDigi == fvDets[uDetIdx].dataType) {
+          for (int idigi = 0; idigi < evt->GetNofData(fvDets[uDetIdx].dataType); ++idigi) {
+            double dTimeDiff = 1.E30;
+            uint idx         = evt->GetIndex(fvDets[uDetIdx].dataType, idigi);
+            auto pDigi       = GetDigi<CbmTofDigi>(idx);
+            if (nullptr == pDigi) continue;
+
+            // filter T0 digis from Tof
+            if (GetTofDetType(pDigi) != fuDetTypeT0) {
+              uNbDataTof++;
+              dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
+              if (dTimeDiff < 1.E30) {  //
+                fvhTDiff[uDetIdx]->Fill(dTimeDiff);
+              }
+            }
+          }
+          continue;
+        }  // else if (ECbmDataType::kTofDigi == fvDets[uDetIdx].dataType)
+      }
+
       for (int idigi = 0; idigi < evt->GetNofData(fvDets[uDetIdx].dataType); ++idigi) {
         double dTimeDiff = 1.E30;
         uint idx         = evt->GetIndex(fvDets[uDetIdx].dataType, idigi);
@@ -1080,77 +1243,127 @@ void CbmAlgoBuildRawEvents::FillHistos()
 
         if (dTimeDiff < 1.E30) fvhTDiff[uDetIdx]->Fill(dTimeDiff);
       }
+
+      if (ECbmDataType::kT0Digi == fvDets[uDetIdx].dataType) {
+        uNbDataT0 = TMath::Max(0, evt->GetNofData(fvDets[uDetIdx].dataType));
+      }
+      if (ECbmDataType::kTofDigi == fvDets[uDetIdx].dataType) {
+        uNbDataTof = TMath::Max(0, evt->GetNofData(fvDets[uDetIdx].dataType));
+      }
     }
     /// Reference detector
     uint32_t uRefDetIdx = fvDets.size();
     if (nullptr != fvhNbDigiPerEvtDet[uRefDetIdx]) {
 
-      fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(TMath::Max(0, evt->GetNofData(fRefDet.dataType)));
-      if (nullptr == fvhTDiff[uRefDetIdx]) continue;
-      for (int idigi = 0; idigi < evt->GetNofData(fRefDet.dataType); ++idigi) {
-        double dTimeDiff = 1.E30;
-        uint idx         = evt->GetIndex(fRefDet.dataType, idigi);
-        switch (fRefDet.dataType) {
-          case ECbmDataType::kT0Digi: {
-            if (fT0DigiVec->size() <= idx) continue;
-            dTimeDiff = fT0DigiVec->at(idx).GetTime() - evt->GetStartTime();
-            break;
+      if (0 != fuDetTypeT0 && ECbmDataType::kT0Digi == fRefDet.dataType) {
+        // filter T0 digis from Tof (remove this block if T0 properly implemented)
+        for (int idigi = 0; idigi < evt->GetNofData(ECbmDataType::kTofDigi); ++idigi) {
+          double dTimeDiff = 1.E30;
+          uint idx         = evt->GetIndex(ECbmDataType::kTofDigi, idigi);
+          auto pDigi       = GetDigi<CbmTofDigi>(idx);
+          if (nullptr == pDigi) continue;
+
+          // filter T0 digis from Tof
+          if (GetTofDetType(pDigi) == fuDetTypeT0) {
+            uNbDataT0++;
+            dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
+            if (dTimeDiff < 1.E30) {  //
+              fvhTDiff[uRefDetIdx]->Fill(dTimeDiff);
+            }
           }
-          case ECbmDataType::kStsDigi: {
-            auto pDigi = GetDigi<CbmStsDigi>(idx);
-            if (nullptr == pDigi) continue;
+        }
+      }  // if (0 != fuDetTypeT0 && ECbmDataType::kT0Digi == fRefDet.dataType)
+      else if (0 != fuDetTypeT0 && ECbmDataType::kTofDigi == fRefDet.dataType) {
+        // filter T0 digis from Tof (remove this block if T0 properly implemented)
+        for (int idigi = 0; idigi < evt->GetNofData(fRefDet.dataType); ++idigi) {
+          double dTimeDiff = 1.E30;
+          uint idx         = evt->GetIndex(fRefDet.dataType, idigi);
+          auto pDigi       = GetDigi<CbmTofDigi>(idx);
+          if (nullptr == pDigi) continue;
+
+          // filter T0 digis from Tof
+          if (GetTofDetType(pDigi) != fuDetTypeT0) {
+            uNbDataTof++;
             dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
-            break;
+            if (dTimeDiff < 1.E30) {  //
+              fvhTDiff[uRefDetIdx]->Fill(dTimeDiff);
+            }
           }
-          case ECbmDataType::kMuchDigi: {
-            if (fbUseMuchBeamtimeDigi) {
-              auto pDigi = GetDigi<CbmMuchBeamTimeDigi>(idx);
+        }
+      }  // else if (0 != fuDetTypeT0 && ECbmDataType::kTofDigi == fRefDet.dataType)
+      else {
+        for (int idigi = 0; idigi < evt->GetNofData(fRefDet.dataType); ++idigi) {
+          double dTimeDiff = 1.E30;
+          uint idx         = evt->GetIndex(fRefDet.dataType, idigi);
+          switch (fRefDet.dataType) {
+            case ECbmDataType::kT0Digi: {
+              if (fT0DigiVec->size() <= idx) continue;
+              dTimeDiff = fT0DigiVec->at(idx).GetTime() - evt->GetStartTime();
+              break;
+            }
+            case ECbmDataType::kStsDigi: {
+              auto pDigi = GetDigi<CbmStsDigi>(idx);
               if (nullptr == pDigi) continue;
               dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
+              break;
             }
-            else {
-              auto pDigi = GetDigi<CbmMuchDigi>(idx);
+            case ECbmDataType::kMuchDigi: {
+              if (fbUseMuchBeamtimeDigi) {
+                auto pDigi = GetDigi<CbmMuchBeamTimeDigi>(idx);
+                if (nullptr == pDigi) continue;
+                dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
+              }
+              else {
+                auto pDigi = GetDigi<CbmMuchDigi>(idx);
+                if (nullptr == pDigi) continue;
+                dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
+              }
+              break;
+            }
+            case ECbmDataType::kTofDigi: {
+              auto pDigi = GetDigi<CbmTofDigi>(idx);
               if (nullptr == pDigi) continue;
               dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
+              break;
             }
-            break;
-          }
-          case ECbmDataType::kTofDigi: {
-            auto pDigi = GetDigi<CbmTofDigi>(idx);
-            if (nullptr == pDigi) continue;
-            dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
-            break;
-          }
-          case ECbmDataType::kTrdDigi: {
-            auto pDigi = GetDigi<CbmTrdDigi>(idx);
-            if (nullptr == pDigi) continue;
-            dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
-            if (pDigi->GetType() == CbmTrdDigi::eCbmTrdAsicType::kSPADIC) {
-              if (fRefDet.sName == "kTrd2D") continue;
-              ++uNbDataTrd1d;
+            case ECbmDataType::kTrdDigi: {
+              auto pDigi = GetDigi<CbmTrdDigi>(idx);
+              if (nullptr == pDigi) continue;
+              dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
+              if (pDigi->GetType() == CbmTrdDigi::eCbmTrdAsicType::kSPADIC) {
+                if (fRefDet.sName == "kTrd2D") continue;
+                ++uNbDataTrd1d;
+              }
+              else if (pDigi->GetType() == CbmTrdDigi::eCbmTrdAsicType::kFASP) {
+                if (fRefDet.sName == "kTrd") continue;
+                ++uNbDataTrd2d;
+              }
+              break;
             }
-            else if (pDigi->GetType() == CbmTrdDigi::eCbmTrdAsicType::kFASP) {
-              if (fRefDet.sName == "kTrd") continue;
-              ++uNbDataTrd2d;
+            case ECbmDataType::kRichDigi: {
+              auto pDigi = GetDigi<CbmRichDigi>(idx);  // FIXME, need to find the proper digi template
+              if (nullptr == pDigi) continue;
+              dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
+              break;
             }
-            break;
-          }
-          case ECbmDataType::kRichDigi: {
-            auto pDigi = GetDigi<CbmRichDigi>(idx);  // FIXME, need to find the proper digi template
-            if (nullptr == pDigi) continue;
-            dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
-            break;
-          }
-          case ECbmDataType::kPsdDigi: {
-            auto pDigi = GetDigi<CbmPsdDigi>(idx);  // FIXME, need to find the proper digi template
-            if (nullptr == pDigi) continue;
-            dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
-            break;
+            case ECbmDataType::kPsdDigi: {
+              auto pDigi = GetDigi<CbmPsdDigi>(idx);  // FIXME, need to find the proper digi template
+              if (nullptr == pDigi) continue;
+              dTimeDiff = pDigi->GetTime() - evt->GetStartTime();
+              break;
+            }
+            default: LOG(error) << "Unkown dataType " << fRefDet.dataType;
           }
-          default: LOG(error) << "Unkown dataType " << fRefDet.dataType;
+
+          if (dTimeDiff < 1.E30) fvhTDiff[uRefDetIdx]->Fill(dTimeDiff);
         }
 
-        if (dTimeDiff < 1.E30) fvhTDiff[uRefDetIdx]->Fill(dTimeDiff);
+        if (ECbmDataType::kT0Digi == fRefDet.dataType) {  //
+          uNbDataT0 = TMath::Max(0, evt->GetNofData(fRefDet.dataType));
+        }
+        if (ECbmDataType::kTofDigi == fRefDet.dataType) {
+          uNbDataTof = TMath::Max(0, evt->GetNofData(fRefDet.dataType));
+        }
       }
     }
 
@@ -1158,16 +1371,55 @@ void CbmAlgoBuildRawEvents::FillHistos()
     for (UInt_t uDetIdx = 0; uDetIdx < fvDets.size(); ++uDetIdx) {
       if (nullptr == fvhNbDigiPerEvtTimeDet[uDetIdx]) continue;
 
-      if (fvDets[uDetIdx].sName == "kTrd") {
+      if (0 != fuDetTypeT0 && fvDets[uDetIdx].sName == "T0") {
+        // filter T0 digis from Tof (remove this block if T0 properly implemented)
+        fvhNbDigiPerEvtDet[uDetIdx]->Fill(uNbDataT0);
+        fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataT0);
+      }
+      else if (0 != fuDetTypeT0 && fvDets[uDetIdx].sName == "Tof") {
+        // filter T0 digis from Tof (remove this block if T0 properly implemented)
+        fvhNbDigiPerEvtDet[uDetIdx]->Fill(uNbDataTof);
+        fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTof);
+      }
+      else if (fvDets[uDetIdx].sName == "kTrd") {
+        fvhNbDigiPerEvtDet[uDetIdx]->Fill(uNbDataTrd1d);
         fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTrd1d);
       }
       else if (fvDets[uDetIdx].sName == "kTrd2D") {
+        fvhNbDigiPerEvtDet[uDetIdx]->Fill(uNbDataTrd2d);
         fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTrd2d);
       }
       else {
-        fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, evt->GetNofData(fvDets[uDetIdx].dataType));
+        fvhNbDigiPerEvtDet[uDetIdx]->Fill(TMath::Max(0, evt->GetNofData(fvDets[uDetIdx].dataType)));
+        fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9,
+                                              TMath::Max(0, evt->GetNofData(fvDets[uDetIdx].dataType)));
       }
     }
+    /// Same for the reference detector
+    if (0 != fuDetTypeT0 && fRefDet.sName == "T0") {
+      // filter T0 digis from Tof (remove this block if T0 properly implemented)
+      fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(uNbDataT0);
+      fvhNbDigiPerEvtTimeDet[uRefDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataT0);
+    }
+    else if (0 != fuDetTypeT0 && fRefDet.sName == "Tof") {
+      // filter T0 digis from Tof (remove this block if T0 properly implemented)
+      fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(uNbDataTof);
+      fvhNbDigiPerEvtTimeDet[uRefDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTof);
+    }
+    else if (fRefDet.sName == "kTrd") {
+      fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(uNbDataTrd1d);
+      fvhNbDigiPerEvtTimeDet[uRefDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTrd1d);
+    }
+    else if (fRefDet.sName == "kTrd2D") {
+      fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(uNbDataTrd2d);
+      fvhNbDigiPerEvtTimeDet[uRefDetIdx]->Fill(evt->GetStartTime() * 1e-9, uNbDataTrd2d);
+    }
+    else {
+      fvhNbDigiPerEvtDet[uRefDetIdx]->Fill(TMath::Max(0, evt->GetNofData(fRefDet.dataType)));
+      fvhNbDigiPerEvtTimeDet[uRefDetIdx]->Fill(evt->GetStartTime() * 1e-9,
+                                               TMath::Max(0, evt->GetNofData(fRefDet.dataType)));
+    }
+
     dPreEvtTime = evt->GetStartTime();
   }
 }
@@ -1192,6 +1444,7 @@ void CbmAlgoBuildRawEvents::ResetHistograms(Bool_t /*bResetTime*/)
   for (std::vector<TH1*>::iterator itHist = fvhTDiff.begin(); itHist != fvhTDiff.end(); ++itHist) {
     (*itHist)->Reset();
   }
+
   /*
    if( kTRUE == bResetTime )
    {
diff --git a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h
index 1309b0d296b9c4b80bfdcc957954ee3d065e01a4..546786cde5f4b27172e6dc1123082941e1ca79de 100644
--- a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h
+++ b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h
@@ -113,8 +113,6 @@ static const RawEventBuilderDetector kRawEventBuilderDetUndef = RawEventBuilderD
 
 class CbmAlgoBuildRawEvents {
 public:
-  const static uint32_t fuT0Address = 10246;
-
   /** Default constructor **/
   CbmAlgoBuildRawEvents() = default;
 
@@ -177,6 +175,8 @@ public:
 
   void ChangeMuchBeamtimeDigiFlag(Bool_t bFlagIn = kFALSE) { fbUseMuchBeamtimeDigi = bFlagIn; }
 
+  void SetT0InTofDetType(uint32_t uTypeIn = 5) { fuDetTypeT0 = uTypeIn; }
+
   /// For monitor algos
   void AddHistoToVector(TNamed* pointer, std::string sFolder = "")
   {
@@ -224,7 +224,7 @@ public:
 
 private:
   /// Internal methods
-  Bool_t CheckDataAvailable(RawEventBuilderDetector& det);
+  Bool_t CheckDataAvailable(const RawEventBuilderDetector& det);
   void InitTs();
   void InitSeedWindow();
   void BuildEvents();
@@ -241,9 +241,9 @@ private:
   template<class DigiCheck>
   void SearchMatches(Double_t dSeedTime, RawEventBuilderDetector& detMatch);
   void SearchMatches(Double_t dSeedTime, RawEventBuilderDetector& detMatch);
-  void AddDigiToEvent(RawEventBuilderDetector& det, Int_t uIdx);
+  void AddDigiToEvent(const RawEventBuilderDetector& det, Int_t uIdx);
   Bool_t HasTrigger(CbmEvent*);
-  Bool_t CheckTriggerConditions(CbmEvent* event, RawEventBuilderDetector& det);
+  Bool_t CheckTriggerConditions(CbmEvent* event, const RawEventBuilderDetector& det);
 
   void UpdateTimeWinBoundariesExtrema();
   void UpdateWidestTimeWinRange();
@@ -261,8 +261,10 @@ private:
   Bool_t fbUseMuchBeamtimeDigi = kTRUE;   //! Switch between MUCH digi classes
   Bool_t fbGetTimings          = kFALSE;  //! Measure CPU time using stopwatch
   Bool_t fbUseTsMetaData       = kTRUE;   //! Read Ts Parameters from input tree
-    /// Event building mode and detectors selection
+  /// Event building mode and detectors selection
   EOverlapModeRaw fOverMode {EOverlapModeRaw::AllowOverlap};
+  /// for filtering T0 digis from Tof (remove this line if T0 properly implemented)
+  uint32_t fuDetTypeT0 = 0;
 
   TStopwatch* fTimer = nullptr;  //! is create when fbGetTimings is set before init
 
diff --git a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx
index 28a6cf3d795b25bfa59188625bc1a0fd917cca0d..35a7e39ad46f1b0f75744130dabfa31275c4a79a 100644
--- a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx
+++ b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx
@@ -266,8 +266,8 @@ void CbmTaskBuildRawEvents::FillSeedTimesFromDetList(std::vector<Double_t>* vdSe
       if (DigiCounters[system.detId] < DigiNumbers[system.detId]) {
 
         // filter T0 digis from Tof (remove this statement if T0 properly implemented)
-        if (system.detId == ECbmModuleId::kTof
-            && (fTofDigis->at(DigiCounters[system.detId])).GetAddress() == CbmAlgoBuildRawEvents::fuT0Address) {
+        if (system.detId == ECbmModuleId::kTof && 0 != fuDetTypeT0
+            && (fTofDigis->at(DigiCounters[system.detId])).GetType() == fuDetTypeT0) {
           DigiCounters[system.detId]++;
           continue;
         }  // end of T0 filter
@@ -329,8 +329,7 @@ void CbmTaskBuildRawEvents::FillSeedTimesFromSlidingWindow(const RawEventBuilder
     for (Int_t i = 0; i < fDigiMan->GetNofDigis(seedDet->detId); i++) {
 
       // filter T0 digis from Tof (remove this statement if T0 properly implemented)
-      if (seedDet->detId == ECbmModuleId::kTof
-          && (fTofDigis->at(i)).GetAddress() == CbmAlgoBuildRawEvents::fuT0Address) {
+      if (seedDet->detId == ECbmModuleId::kTof && 0 != fuDetTypeT0 && (fTofDigis->at(i)).GetType() == fuDetTypeT0) {
         continue;
       }  // end of T0 filter
 
@@ -352,23 +351,42 @@ void CbmTaskBuildRawEvents::FillSeedTimesFromSlidingWindow(const RawEventBuilder
     case ECbmModuleId::kSts: fSeedFinderSlidingWindow->FillSeedTimes(fStsDigis, fvDigiMatchQa); break;
     case ECbmModuleId::kTrd: fSeedFinderSlidingWindow->FillSeedTimes(fTrdDigis, fvDigiMatchQa); break;
     case ECbmModuleId::kTof: {
-
-      // filter T0 digis from Tof (remove this statement if T0 properly implemented)
-      std::vector<CbmTofDigi> vFilteredTofDigis;
-      for (const auto& tofDigi : *fTofDigis) {
-        if (tofDigi.GetAddress() == CbmAlgoBuildRawEvents::fuT0Address) { continue; }
-        vFilteredTofDigis.push_back(tofDigi);
+      if (0 != fuDetTypeT0) {
+        // filter T0 digis from Tof (remove this block if T0 properly implemented)
+        std::vector<CbmTofDigi> vFilteredTofDigis;
+        for (const auto& tofDigi : *fTofDigis) {
+          if (tofDigi.GetType() == fuDetTypeT0) { continue; }
+          vFilteredTofDigis.push_back(tofDigi);
+        }
+        fSeedFinderSlidingWindow->FillSeedTimes(&vFilteredTofDigis, fvDigiMatchQa);
+        // end of T0 filter
+      }
+      else {
+        // original version (no T0 filter)
+        fSeedFinderSlidingWindow->FillSeedTimes(fTofDigis, fvDigiMatchQa);
       }
-      fSeedFinderSlidingWindow->FillSeedTimes(&vFilteredTofDigis, fvDigiMatchQa);
       break;
-      // end of T0 filter
-
-      //original version (no T0 filter)
-      //fSeedFinderSlidingWindow->FillSeedTimes(fTofDigis, fvDigiMatchQa); break;
     }
     case ECbmModuleId::kRich: fSeedFinderSlidingWindow->FillSeedTimes(fRichDigis, fvDigiMatchQa); break;
     case ECbmModuleId::kPsd: fSeedFinderSlidingWindow->FillSeedTimes(fPsdDigis, fvDigiMatchQa); break;
-    case ECbmModuleId::kT0: fSeedFinderSlidingWindow->FillSeedTimes(fT0Digis, fvDigiMatchQa); break;
+    case ECbmModuleId::kT0: {
+      if (0 != fuDetTypeT0) {
+        // filter T0 digis in Tof array (remove this block if T0 properly implemented)
+        // => This T0 seed finding is untested and without ensurance
+        std::vector<CbmTofDigi> vFilteredTofDigis;
+        for (const auto& tofDigi : *fTofDigis) {
+          if (tofDigi.GetType() != fuDetTypeT0) { continue; }
+          vFilteredTofDigis.push_back(tofDigi);
+        }
+        fSeedFinderSlidingWindow->FillSeedTimes(&vFilteredTofDigis, fvDigiMatchQa);
+        // end of T0 filter
+      }
+      else {
+        // original version (no T0 filter needed)
+        fSeedFinderSlidingWindow->FillSeedTimes(fT0Digis, fvDigiMatchQa);
+      }
+      break;
+    }
     default: break;
   }
 }
diff --git a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h
index 39b18c2f498a1a9cb390a7693eae7e42edccf95f..7633830ed61d467ccf27eec6f232fcd8b3122114 100644
--- a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h
+++ b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h
@@ -118,6 +118,11 @@ public:
     if (nullptr != fpAlgo) fpAlgo->SetTimings(bFlagIn);
     fbGetTimings = bFlagIn;
   }
+  void SetT0InTofDetType(uint32_t uTypeIn = 5)
+  {
+    if (nullptr != fpAlgo) fpAlgo->SetT0InTofDetType(uTypeIn);
+    fuDetTypeT0 = uTypeIn;
+  }
 
   void SetSeedFinderQa(Bool_t bFlagIn = kTRUE);
   void PrintTimings();
@@ -183,6 +188,8 @@ private:
   Bool_t fbFillHistos {kTRUE};             //! Switch ON/OFF filling of histograms
   Bool_t fbWriteHistosToFairSink {kTRUE};  //! Write histos to FairRootManager instead of separate file
   Bool_t fbGetTimings = kFALSE;            //! Measure CPU time using stopwatch
+  /// for filtering T0 digis from Tof (remove this line if T0 properly implemented)
+  uint32_t fuDetTypeT0 = 0;
 
   /** Name of the histogram output file **/
   TString fsOutFileName {"data/HistosEvtWin.root"};
diff --git a/reco/steer/CbmRecoUnpack.cxx b/reco/steer/CbmRecoUnpack.cxx
index 7035638408ec2b60e7ad3b2b262ad7fa0360dfbf..a3518735e80bca898a397fd9d3e53adac82d55ce 100644
--- a/reco/steer/CbmRecoUnpack.cxx
+++ b/reco/steer/CbmRecoUnpack.cxx
@@ -360,6 +360,10 @@ void CbmRecoUnpack::Unpack(unique_ptr<Timeslice> ts)
           fCbmTsEventHeader->AddNDigisBmon(unpack(systemId, &timeslice, component, fBmonConfig,
                                                   fBmonConfig->GetOptOutAVec(), fBmonConfig->GetOptOutBVec()));
         }
+        else if (fTofConfig) {
+          fCbmTsEventHeader->AddNDigisTof(unpack(fkFlesTof, &timeslice, component, fTofConfig,
+                                                 fTofConfig->GetOptOutAVec(), fTofConfig->GetOptOutBVec()));
+        }
         break;
       }
       default: {