diff --git a/MQ/mcbm/CbmDeviceEventBuilder.cxx b/MQ/mcbm/CbmDeviceEventBuilder.cxx
index 878db861efb7c18eea772398f79f15e384760b06..8dad9cb974eb3ff9b8494bae5770581a4fa59005 100644
--- a/MQ/mcbm/CbmDeviceEventBuilder.cxx
+++ b/MQ/mcbm/CbmDeviceEventBuilder.cxx
@@ -129,6 +129,7 @@ try {
   }
 
   /// Extract detector to add if any
+  /*
   for (std::vector<std::string>::const_iterator itStrAdd = vsAddDet.begin(); itStrAdd != vsAddDet.end(); ++itStrAdd) {
     const ECbmModuleId addDet = GetDetectorId(*itStrAdd);
     if (ECbmModuleId::kNotExist != addDet) { fEvbuildAlgo.AddSystem(addDet); }
@@ -139,6 +140,7 @@ try {
       continue;
     }
   }
+  */
 
   /// Extract event builder window to add if any
   for (std::vector<std::string>::const_iterator itStrEvbuildWin = vsSetEvbuildWin.begin();
@@ -177,7 +179,7 @@ try {
     charPosDel++;
     double dWinEnd = std::stod(sNext.substr(charPosDel));
 
-    fEvbuildAlgo.SetTriggerWindow(selDet, dWinBeg, dWinEnd);
+    fEvbuildAlgo.SetEventWindow(selDet, dWinBeg, dWinEnd);
   }
 }
 catch (InitTaskError& e) {
diff --git a/algo/evbuild/EventBuilder.cxx b/algo/evbuild/EventBuilder.cxx
index 8186c792f07f257056943275ad718b6fe2a0f5b5..04455c4d9bc83f3b26ba6824f76b9ecd5e402ed4 100644
--- a/algo/evbuild/EventBuilder.cxx
+++ b/algo/evbuild/EventBuilder.cxx
@@ -30,35 +30,30 @@ namespace cbm
       event.fTime = trigger;
 
       // --- Loop over systems
-      for (const auto& system : fSystems) {
+      for (auto entry : fEventWindows) {
 
-        // --- Look for trigger window in list
-        if (fTriggerWindows.find(system) == fTriggerWindows.end()) {
-          //LOG(fatal) << "EventBuilder::BuildEvent(): no trigger window supplied for requested detector.";
-          std::cout << "EventBuilder::BuildEvent(): no trigger window supplied for requested detector." << std::endl;
-          exit(1);
-        }
-        const double tMin = trigger + fTriggerWindows.find(system)->second.first;
-        const double tMax = trigger + fTriggerWindows.find(system)->second.second;
+        auto system       = entry.first;
+        const double tMin = trigger + entry.second.first;
+        const double tMax = trigger + entry.second.second;
 
         // --- Build the event using trigger window
         switch (system) {
-          case ECbmModuleId::kMuch: {  //we do not support the "MuchBeamTimeDigi"
-            assert(is_sorted(ts.fData.fMuch.fDigis.begin(), ts.fData.fMuch.fDigis.end(),
-                             IsBefore<CbmMuchDigi, CbmMuchDigi>));
-            event.fData.fMuch.fDigis = CopyRange(ts.fData.fMuch.fDigis, tMin, tMax);
-            break;
-          }
           case ECbmModuleId::kSts: {
             assert(
               is_sorted(ts.fData.fSts.fDigis.begin(), ts.fData.fSts.fDigis.end(), IsBefore<CbmStsDigi, CbmStsDigi>));
             event.fData.fSts.fDigis = CopyRange(ts.fData.fSts.fDigis, tMin, tMax);
             break;
           }
-          case ECbmModuleId::kTof: {
-            assert(
-              is_sorted(ts.fData.fTof.fDigis.begin(), ts.fData.fTof.fDigis.end(), IsBefore<CbmTofDigi, CbmTofDigi>));
-            event.fData.fTof.fDigis = CopyRange(ts.fData.fTof.fDigis, tMin, tMax);
+          case ECbmModuleId::kRich: {
+            assert(is_sorted(ts.fData.fRich.fDigis.begin(), ts.fData.fRich.fDigis.end(),
+                             IsBefore<CbmRichDigi, CbmRichDigi>));
+            event.fData.fRich.fDigis = CopyRange(ts.fData.fRich.fDigis, tMin, tMax);
+            break;
+          }
+          case ECbmModuleId::kMuch: {
+            assert(is_sorted(ts.fData.fMuch.fDigis.begin(), ts.fData.fMuch.fDigis.end(),
+                             IsBefore<CbmMuchDigi, CbmMuchDigi>));
+            event.fData.fMuch.fDigis = CopyRange(ts.fData.fMuch.fDigis, tMin, tMax);
             break;
           }
           case ECbmModuleId::kTrd: {
@@ -67,10 +62,10 @@ namespace cbm
             event.fData.fTrd.fDigis = CopyRange(ts.fData.fTrd.fDigis, tMin, tMax);
             break;
           }
-          case ECbmModuleId::kRich: {
-            assert(is_sorted(ts.fData.fRich.fDigis.begin(), ts.fData.fRich.fDigis.end(),
-                             IsBefore<CbmRichDigi, CbmRichDigi>));
-            event.fData.fRich.fDigis = CopyRange(ts.fData.fRich.fDigis, tMin, tMax);
+          case ECbmModuleId::kTof: {
+            assert(
+              is_sorted(ts.fData.fTof.fDigis.begin(), ts.fData.fTof.fDigis.end(), IsBefore<CbmTofDigi, CbmTofDigi>));
+            event.fData.fTof.fDigis = CopyRange(ts.fData.fTof.fDigis, tMin, tMax);
             break;
           }
           case ECbmModuleId::kPsd: {
@@ -84,11 +79,7 @@ namespace cbm
             event.fData.fT0.fDigis = CopyRange(ts.fData.fT0.fDigis, tMin, tMax);
             break;
           }
-          default: {
-            //LOG(fatal) << "EventBuilder::BuildEvent():GetName(): Reading digis from unknown detector type!";
-            std::cout << "EventBuilder::BuildEvent():GetName(): Reading digis from unknown detector type!" << std::endl;
-            exit(1);
-          }
+          default: break;
         }
       }
       return event;
diff --git a/algo/evbuild/EventBuilder.h b/algo/evbuild/EventBuilder.h
index e224963781d02da689bf601d3868c164ddb4c40f..bc34137464c139caaba9ccec1e251d72e2e35a18 100644
--- a/algo/evbuild/EventBuilder.h
+++ b/algo/evbuild/EventBuilder.h
@@ -48,65 +48,55 @@ namespace cbm
       /** @brief Constructor **/
       EventBuilder() {};
 
+
       /** @brief Destructor **/
       virtual ~EventBuilder() {};
 
+
       /** @brief Execution
-         ** @param  ts       Digi source (timeslice)
-         ** @param  triggers List of trigger times
-         ** @return Vector of constructed events
-         **/
+       ** @param  ts       Digi source (timeslice)
+       ** @param  triggers List of trigger times
+       ** @return Vector of constructed events
+       **/
       std::vector<CbmDigiEvent> operator()(const CbmDigiTimeslice& ts, const std::vector<double> triggers) const;
 
+
       /** @brief Build a single event from a trigger time
-         ** @param  ts      Digi source (timeslice)
-         ** @param  trigger Trigger time
-         ** @return Digi event
-         **/
+       ** @param  ts      Digi source (timeslice)
+       ** @param  trigger Trigger time
+       ** @return Digi event
+       **/
       CbmDigiEvent BuildEvent(const CbmDigiTimeslice& ts, double trigger) const;
 
-      /** @brief Add a detector system 
- 	 ** @param system    System to be added
-	 **/
-      void AddSystem(ECbmModuleId system)
-      {
-        if (std::find(fSystems.begin(), fSystems.end(), system) != fSystems.end()) return;
-        fSystems.push_back(system);
-      }
 
-      /** @brief Configure the trigger windows
-         ** @param system  Detector system identifier
-         ** @param tMin    Trigger window start time w.r.t. trigger time
-         ** @param tMax    Trigger window end time w.r.t. trigger time
-         **/
-      void SetTriggerWindow(ECbmModuleId system, double tMin, double tMax)
+      /** @brief Configure the event windows
+       ** @param system  Detector system identifier
+       ** @param tMin    Event window start time w.r.t. event time
+       ** @param tMax    Event window end time w.r.t. event time
+       **/
+      void SetEventWindow(ECbmModuleId system, double tMin, double tMax)
       {
-        if (std::find(fSystems.begin(), fSystems.end(), system) == fSystems.end()) {
-          //LOG(fatal) << "EventBuilder::SetTriggerWindow(): setting trigger window for non-added detector.";
-          std::cout << "EventBuilder::SetTriggerWindow(): setting trigger window for non-added detector." << std::endl;
-          exit(1);
-        }
-        fTriggerWindows[system] = std::make_pair(tMin, tMax);
+        fEventWindows[system] = std::make_pair(tMin, tMax);
       }
 
     private:  // methods
       /** @brief Copy data objects in a given time interval from the source to the target vector
-         ** @param source Source data vector
-         ** @param tMin   Minimal time
-         ** @param tMax   Maximal time
-         ** @return Target data vector
-         **
-         ** The Data class specialisation must implement the method double GetTime(), which is used to
-         ** check whether the Data object falls into the specified time interval.
-         **
-         ** The source vector must be ordered w.r.t. GetTime(), otherwise the behaviour is undefined.
-         **
-         ** TODO: The current implementation searches, for each trigger, the entire source vector. This
-         ** can surely be optimised when the contract that the trigger vector be sorted is properly exploited,
-         ** e.g., by starting the search for the first digi in the trigger window from the start of the
-         ** previous trigger window. This, however, requires bookkeeping hardly to be realised without
-         ** changing the state of the class. I leave this for the future and for bright specialists.
-         **/
+       ** @param source Source data vector
+       ** @param tMin   Minimal time
+       ** @param tMax   Maximal time
+       ** @return Target data vector
+       **
+       ** The Data class specialisation must implement the method double GetTime(), which is used to
+       ** check whether the Data object falls into the specified time interval.
+       **
+       ** The source vector must be ordered w.r.t. GetTime(), otherwise the behaviour is undefined.
+       **
+       ** TODO: The current implementation searches, for each trigger, the entire source vector. This
+       ** can surely be optimised when the contract that the trigger vector be sorted is properly exploited,
+       ** e.g., by starting the search for the first digi in the trigger window from the start of the
+       ** previous trigger window. This, however, requires bookkeeping hardly to be realised without
+       ** changing the state of the class. I leave this for the future and for bright specialists.
+       **/
       template<typename Data>
       static typename std::vector<Data> CopyRange(const std::vector<Data>& source, double tMin, double tMax)
       {
@@ -117,9 +107,12 @@ namespace cbm
         return std::vector<Data>(lower, upper);
       }
 
+
     private:  // data members
-      std::map<ECbmModuleId, std::pair<double, double>> fTriggerWindows;
-      std::vector<ECbmModuleId> fSystems {};  //  List of detector systems
+      /** Event time window relative to the trigger time for each detector system
+       ** Key is system identifier, value is (t_min, t_max).
+       **/
+      std::map<ECbmModuleId, std::pair<double, double>> fEventWindows;
     };
   }  // namespace algo
 }  // namespace cbm
diff --git a/algo/test/_GTestEventBuilder.cxx b/algo/test/_GTestEventBuilder.cxx
index acdc317e4c1ac1147bc509978a8df3ffa33ae5db..5a3ab80f0f787215354e52f1e6088275500be29a 100644
--- a/algo/test/_GTestEventBuilder.cxx
+++ b/algo/test/_GTestEventBuilder.cxx
@@ -12,20 +12,13 @@ TEST(_GTestEventBuilder, CheckEventBuilderAlgorithmSimple)
 
   //Initialize event builder
   cbm::algo::EventBuilder evbuild;
-  evbuild.AddSystem(ECbmModuleId::kMuch);
-  evbuild.AddSystem(ECbmModuleId::kSts);
-  evbuild.AddSystem(ECbmModuleId::kTof);
-  evbuild.AddSystem(ECbmModuleId::kTrd);
-  evbuild.AddSystem(ECbmModuleId::kRich);
-  evbuild.AddSystem(ECbmModuleId::kPsd);
-  evbuild.AddSystem(ECbmModuleId::kT0);
-  evbuild.SetTriggerWindow(ECbmModuleId::kMuch, -45.0, 45.0);
-  evbuild.SetTriggerWindow(ECbmModuleId::kSts, -45.0, 45.0);
-  evbuild.SetTriggerWindow(ECbmModuleId::kTof, -45.0, 45.0);
-  evbuild.SetTriggerWindow(ECbmModuleId::kTrd, -45.0, 45.0);
-  evbuild.SetTriggerWindow(ECbmModuleId::kRich, -45.0, 45.0);
-  evbuild.SetTriggerWindow(ECbmModuleId::kPsd, -45.0, 45.0);
-  evbuild.SetTriggerWindow(ECbmModuleId::kT0, -45.0, 45.0);
+  evbuild.SetEventWindow(ECbmModuleId::kMuch, -45.0, 45.0);
+  evbuild.SetEventWindow(ECbmModuleId::kSts, -45.0, 45.0);
+  evbuild.SetEventWindow(ECbmModuleId::kTof, -45.0, 45.0);
+  evbuild.SetEventWindow(ECbmModuleId::kTrd, -45.0, 45.0);
+  evbuild.SetEventWindow(ECbmModuleId::kRich, -45.0, 45.0);
+  evbuild.SetEventWindow(ECbmModuleId::kPsd, -45.0, 45.0);
+  evbuild.SetEventWindow(ECbmModuleId::kT0, -45.0, 45.0);
 
   CbmDigiTimeslice tsIn;
   const uint nInput         = 1000;
diff --git a/macro/reco/reco_digi.C b/macro/reco/reco_digi.C
index 2958207696a4d7471225ace7c7dc3a20f0c90118..8b8c7b55157154842640ffec8c7923e51df50019 100644
--- a/macro/reco/reco_digi.C
+++ b/macro/reco/reco_digi.C
@@ -127,8 +127,7 @@ void reco_digi(TString input = "", Int_t nTimeSlices = -1, Int_t firstTimeSlice
 
   // -----   Event building   -----------------------------------------------
   auto evtBuild = std::make_unique<CbmTaskBuildEvents>();
-  evtBuild->AddSystem(ECbmModuleId::kSts);
-  evtBuild->SetTimeWindow(ECbmModuleId::kSts, -20., 30.);  // event building time window for STS
+  evtBuild->SetEventWindow(ECbmModuleId::kSts, -20., 30.);  // event building time window for STS
   LOG(info) << myName << ": Added task " << evtBuild->GetName();
   run->AddTask(evtBuild.release());
   // ------------------------------------------------------------------------
diff --git a/reco/tasks/CbmTaskBuildEvents.cxx b/reco/tasks/CbmTaskBuildEvents.cxx
index 2f25362b8e8956725ddf15aa481ca9b19a9e8749..a3983dd65f6f9f4f2e27c8461a2c3c61f5f4cda3 100644
--- a/reco/tasks/CbmTaskBuildEvents.cxx
+++ b/reco/tasks/CbmTaskBuildEvents.cxx
@@ -36,16 +36,10 @@ CbmTaskBuildEvents::~CbmTaskBuildEvents()
 CbmDigiTimeslice CbmTaskBuildEvents::FillTimeSlice()
 {
   CbmDigiTimeslice ts;
-  for (const auto& system : fSystems) {
+  for (const auto& entry : fEventWindows) {
+    auto system                   = entry.first;
     CbmDigiBranchBase* digiBranch = fDigiMan->GetBranch(system);
     switch (system) {
-      case ECbmModuleId::kMuch: {  //we do not support the "MuchBeamTimeDigi"
-        const vector<CbmMuchDigi>* digiVec =
-          boost::any_cast<const vector<CbmMuchDigi>*>(digiBranch->GetBranchContainer());
-        assert(digiVec);
-        ts.fData.fMuch.fDigis = *digiVec;
-        break;
-      }
       case ECbmModuleId::kSts: {
         const vector<CbmStsDigi>* digiVec =
           boost::any_cast<const vector<CbmStsDigi>*>(digiBranch->GetBranchContainer());
@@ -53,11 +47,18 @@ CbmDigiTimeslice CbmTaskBuildEvents::FillTimeSlice()
         ts.fData.fSts.fDigis = *digiVec;
         break;
       }
-      case ECbmModuleId::kTof: {
-        const vector<CbmTofDigi>* digiVec =
-          boost::any_cast<const vector<CbmTofDigi>*>(digiBranch->GetBranchContainer());
+      case ECbmModuleId::kRich: {
+        const vector<CbmRichDigi>* digiVec =
+          boost::any_cast<const vector<CbmRichDigi>*>(digiBranch->GetBranchContainer());
         assert(digiVec);
-        ts.fData.fTof.fDigis = *digiVec;
+        ts.fData.fRich.fDigis = *digiVec;
+        break;
+      }
+      case ECbmModuleId::kMuch: {
+        const vector<CbmMuchDigi>* digiVec =
+          boost::any_cast<const vector<CbmMuchDigi>*>(digiBranch->GetBranchContainer());
+        assert(digiVec);
+        ts.fData.fMuch.fDigis = *digiVec;
         break;
       }
       case ECbmModuleId::kTrd: {
@@ -67,11 +68,11 @@ CbmDigiTimeslice CbmTaskBuildEvents::FillTimeSlice()
         ts.fData.fTrd.fDigis = *digiVec;
         break;
       }
-      case ECbmModuleId::kRich: {
-        const vector<CbmRichDigi>* digiVec =
-          boost::any_cast<const vector<CbmRichDigi>*>(digiBranch->GetBranchContainer());
+      case ECbmModuleId::kTof: {
+        const vector<CbmTofDigi>* digiVec =
+          boost::any_cast<const vector<CbmTofDigi>*>(digiBranch->GetBranchContainer());
         assert(digiVec);
-        ts.fData.fRich.fDigis = *digiVec;
+        ts.fData.fTof.fDigis = *digiVec;
         break;
       }
       case ECbmModuleId::kPsd: {
@@ -88,11 +89,13 @@ CbmDigiTimeslice CbmTaskBuildEvents::FillTimeSlice()
         ts.fData.fT0.fDigis = *digiVec;
         break;
       }
-      default: LOG(fatal) << GetName() << ": Reading digis from unknown detector type!";
+      default: LOG(fatal) << GetName() << ": Unknown detector type!";
     }
   }
   return ts;
 }
+// ---------------------------------------------------------------------------
+
 
 // -----   Execution   -------------------------------------------------------
 void CbmTaskBuildEvents::Exec(Option_t*)
@@ -102,74 +105,44 @@ void CbmTaskBuildEvents::Exec(Option_t*)
   TStopwatch timerStep;
   TStopwatch timerTot;
   timerTot.Start();
+  std::map<ECbmModuleId, size_t> numDigisTs;
+  std::map<ECbmModuleId, size_t> numDigisEv;
 
   // --- Clear output vector
   fEvents->clear();
 
-  // --- Construct a DigiTimeslice from the data in CbmDigiManager
-  timerStep.Start();
-  CbmDigiTimeslice ts = FillTimeSlice();
-  timerStep.Stop();
-  fTimeFillTs += timerStep.RealTime();
+  // --- If the input is already CbmDigiTimeslice (from unpacking), use that directly
+  if (fTimeslice) {
+    LOG(info) << "Exec timeslice " << fNumTs << " with " << fTriggers->size() << " triggers"
+              << " from " << *(fTriggers->begin()) << " to " << fTriggers->back();
+    timerStep.Start();
+    *fEvents = fAlgo(*fTimeslice, *fTriggers);
+    timerStep.Stop();
+    fTimeBuildEvt += timerStep.RealTime();
+    for (const auto& entry : fEventWindows)
+      numDigisTs[entry.first] = GetNumDigis(fTimeslice->fData, entry.first);
+  }
 
-  // --- Call event builder algorithm
-  timerStep.Start();
-  *fEvents = fAlgo(ts, *fTriggers);
-  timerStep.Stop();
-  fTimeBuildEvt += timerStep.RealTime();
+  // --- If input is not DigiTimeslice: construct a transientDigiTimeslice from the data in CbmDigiManager
+  else {
+    timerStep.Start();
+    CbmDigiTimeslice ts = FillTimeSlice();
+    for (const auto& entry : fEventWindows)
+      numDigisTs[entry.first] = GetNumDigis(ts.fData, entry.first);
+    timerStep.Stop();
+    fTimeFillTs += timerStep.RealTime();
+    timerStep.Start();
+    *fEvents = fAlgo(ts, *fTriggers);
+    timerStep.Stop();
+    fTimeBuildEvt += timerStep.RealTime();
+  }
 
   // --- Timeslice statistics
   size_t numTriggers = fTriggers->size();
   size_t numEvents   = fEvents->size();
-  std::map<ECbmModuleId, size_t> NumDigisTs;
-  std::map<ECbmModuleId, size_t> NumDigisEv;
-
-  for (const auto& system : fSystems) {
-    NumDigisEv[system] = 0;
-    switch (system) {
-      case ECbmModuleId::kMuch: {
-        NumDigisTs[system] = ts.fData.fMuch.fDigis.size();
-        for (auto& event : (*fEvents))
-          NumDigisEv[system] += event.fData.fMuch.fDigis.size();
-        break;
-      }
-      case ECbmModuleId::kSts: {
-        NumDigisTs[system] = ts.fData.fSts.fDigis.size();
-        for (auto& event : (*fEvents))
-          NumDigisEv[system] += event.fData.fSts.fDigis.size();
-        break;
-      }
-      case ECbmModuleId::kTof: {
-        NumDigisTs[system] = ts.fData.fTof.fDigis.size();
-        for (auto& event : (*fEvents))
-          NumDigisEv[system] += event.fData.fTof.fDigis.size();
-        break;
-      }
-      case ECbmModuleId::kTrd: {
-        NumDigisTs[system] = ts.fData.fTrd.fDigis.size();
-        for (auto& event : (*fEvents))
-          NumDigisEv[system] += event.fData.fTrd.fDigis.size();
-        break;
-      }
-      case ECbmModuleId::kRich: {
-        NumDigisTs[system] = ts.fData.fRich.fDigis.size();
-        for (auto& event : (*fEvents))
-          NumDigisEv[system] += event.fData.fRich.fDigis.size();
-        break;
-      }
-      case ECbmModuleId::kPsd: {
-        NumDigisTs[system] = ts.fData.fPsd.fDigis.size();
-        for (auto& event : (*fEvents))
-          NumDigisEv[system] += event.fData.fPsd.fDigis.size();
-        break;
-      }
-      case ECbmModuleId::kT0: {
-        NumDigisTs[system] = ts.fData.fT0.fDigis.size();
-        for (auto& event : (*fEvents))
-          NumDigisEv[system] += event.fData.fT0.fDigis.size();
-        break;
-      }
-      default: break;
+  for (const auto& entry : fEventWindows) {
+    for (auto& event : (*fEvents)) {
+      numDigisEv[entry.first] += GetNumDigis(event.fData, entry.first);
     }
   }
 
@@ -181,9 +154,10 @@ void CbmTaskBuildEvents::Exec(Option_t*)
   logOut << fixed << setw(8) << setprecision(1) << right << timerTot.RealTime() * 1000. << " ms] ";
   logOut << "TS " << fNumTs << ", triggers " << numTriggers << ", events " << numEvents;
 
-  for (const auto& system : fSystems) {
+  for (const auto& entry : fEventWindows) {
+    auto system = entry.first;
     logOut << ", frac " << CbmModuleList::GetModuleNameCaps(system) << " digis "
-           << 100. * double(NumDigisEv[system]) / double(NumDigisTs[system]) << " %";
+           << 100. * double(numDigisEv[system]) / double(numDigisTs[system]) << " %";
   }
 
   LOG(info) << logOut.str();
@@ -193,9 +167,10 @@ void CbmTaskBuildEvents::Exec(Option_t*)
   fNumTriggers += numTriggers;
   fNumEvents += numEvents;
 
-  for (const auto& system : fSystems) {
-    fNumDigisTs[system] += NumDigisTs[system];
-    fNumDigisEv[system] += NumDigisEv[system];
+  for (const auto& entry : fEventWindows) {
+    auto system = entry.first;
+    fNumDigisTs[system] += numDigisTs[system];
+    fNumDigisEv[system] += numDigisEv[system];
   }
 }
 // ----------------------------------------------------------------------------
@@ -211,7 +186,8 @@ void CbmTaskBuildEvents::Finish()
   LOG(info) << "Triggers           : " << fNumTriggers;
   LOG(info) << "Events             : " << fNumEvents;
 
-  for (const auto& system : fSystems) {
+  for (const auto& entry : fEventWindows) {
+    auto system = entry.first;
     LOG(info) << CbmModuleList::GetModuleNameCaps(system) << " digis in timeslice : " << fNumDigisTs[system];
     LOG(info) << CbmModuleList::GetModuleNameCaps(system) << " digis in events    : " << fNumDigisEv[system] << " = "
               << fixed << setprecision(2) << 100. * double(fNumDigisEv[system]) / double(fNumDigisTs[system]) << " %";
@@ -227,6 +203,25 @@ void CbmTaskBuildEvents::Finish()
 // ----------------------------------------------------------------------------
 
 
+// -----  Number of digis in the timeslice   ----------------------------------
+size_t CbmTaskBuildEvents::GetNumDigis(const CbmDigiData& data, ECbmModuleId system)
+{
+  size_t result = 0;
+  switch (system) {
+    case ECbmModuleId::kSts: result = data.fSts.fDigis.size(); break;
+    case ECbmModuleId::kRich: result = data.fRich.fDigis.size(); break;
+    case ECbmModuleId::kMuch: result = data.fMuch.fDigis.size(); break;
+    case ECbmModuleId::kTrd: result = data.fTrd.fDigis.size(); break;
+    case ECbmModuleId::kTof: result = data.fTof.fDigis.size(); break;
+    case ECbmModuleId::kPsd: result = data.fPsd.fDigis.size(); break;
+    case ECbmModuleId::kT0: result = data.fT0.fDigis.size(); break;
+    default: result = 0; break;
+  }
+  return result;
+}
+// ----------------------------------------------------------------------------
+
+
 // -----   Initialisation   ---------------------------------------------------
 InitStatus CbmTaskBuildEvents::Init()
 {
@@ -243,16 +238,26 @@ InitStatus CbmTaskBuildEvents::Init()
   LOG(info) << GetName() << ": Initialising...";
 
   // --- Check input data
-  for (const auto& system : fSystems) {
-    if (!fDigiMan->IsPresent(system)) {
-      LOG(fatal) << GetName() << ": No digi branch for " << CbmModuleList::GetModuleNameCaps(system);
-      return kFATAL;
+  // --- DigiTimeslice: Unpacked data from FLES
+  fTimeslice = ioman->InitObjectAs<const CbmDigiTimeslice*>("DigiTimeslice.");
+  if (fTimeslice) { LOG(info) << GetName() << ": Found branch DigiTimeslice."; }
+  // --- DigiManager: Simulated digi data
+  else {
+    fDigiMan = CbmDigiManager::Instance();
+    fDigiMan->Init();
+    for (const auto& entry : fEventWindows) {
+      auto system = entry.first;
+      if (!fDigiMan->IsPresent(system)) {
+        LOG(fatal) << GetName() << ": No digi branch for " << CbmModuleList::GetModuleNameCaps(system);
+        return kFATAL;
+      }
+      LOG(info) << "--- Found digi branch for " << CbmModuleList::GetModuleNameCaps(system);
     }
-    LOG(info) << "--- Found digi branch for " << CbmModuleList::GetModuleNameCaps(system);
   }
 
   // --- Initialize diagnostics
-  for (const auto& system : fSystems) {
+  for (const auto& entry : fEventWindows) {
+    auto system         = entry.first;
     fNumDigisTs[system] = 0;
     fNumDigisEv[system] = 0;
   }
@@ -279,13 +284,11 @@ InitStatus CbmTaskBuildEvents::Init()
   LOG(info) << "--- Registered branch DigiEvent";
 
   // --- Configure algorithm
-  for (const auto& system : fSystems) {
-    if (fTriggerWindows.find(system) == fTriggerWindows.end()) {
-      LOG(fatal) << GetName() << ": no trigger window supplied for requested detector.";
-    }
-    const double tMin = fTriggerWindows.find(system)->second.first;
-    const double tMax = fTriggerWindows.find(system)->second.second;
-    fAlgo.SetTriggerWindow(system, tMin, tMax);
+  for (const auto& entry : fEventWindows) {
+    auto system       = entry.first;
+    const double tMin = entry.second.first;
+    const double tMax = entry.second.second;
+    fAlgo.SetEventWindow(system, tMin, tMax);
     LOG(info) << "--- Use algo EventBuilder with event window [" << tMin << ", " << tMax << "] ns for "
               << CbmModuleList::GetModuleNameCaps(system);
   }
diff --git a/reco/tasks/CbmTaskBuildEvents.h b/reco/tasks/CbmTaskBuildEvents.h
index 4deee10f43368d6a3d5be805c8f65ed7c1557ee9..6cb231842e9fbc6b8dab56e1418712986e046d2f 100644
--- a/reco/tasks/CbmTaskBuildEvents.h
+++ b/reco/tasks/CbmTaskBuildEvents.h
@@ -33,59 +33,62 @@ public:
   /** @brief Constructor **/
   CbmTaskBuildEvents();
 
+
   /** @brief Copy constructor (disabled) **/
   CbmTaskBuildEvents(const CbmTaskBuildEvents&) = delete;
 
+
   /** @brief Destructor **/
   virtual ~CbmTaskBuildEvents();
 
+
   /** @brief Task execution **/
   virtual void Exec(Option_t* opt);
 
+
   /** @brief Finish timeslice **/
   virtual void Finish();
 
+
   /** @brief Assignment operator (disabled) **/
   CbmTaskBuildEvents& operator=(const CbmTaskBuildEvents&) = delete;
 
-  /** @brief Add a detector system to the event builder algorithm
-   ** @param system    System to be added
-   **/
-  void AddSystem(ECbmModuleId system)
-  {
-    fAlgo.AddSystem(system);
-    if (std::find(fSystems.begin(), fSystems.end(), system) != fSystems.end()) return;
-    fSystems.push_back(system);
-  }
 
   /** @brief Configure the event building time intervals
    ** @param system  Detector system identifier
-   ** @param tMin    Trigger window start time w.r.t. trigger time
-   ** @param tMax    Trigger window end time w.r.t. trigger time
+   ** @param tMin    Event window start time w.r.t. event time
+   ** @param tMax    Event window end time w.r.t. event time
    **/
-  void SetTimeWindow(ECbmModuleId system, double tMin, double tMax)
+  void SetEventWindow(ECbmModuleId system, double tMin, double tMax)
   {
-    if (std::find(fSystems.begin(), fSystems.end(), system) == fSystems.end()) {
-      LOG(fatal) << GetName() << ": setting time window for non-added detector.";
-    }
-    fTriggerWindows[system] = std::make_pair(tMin, tMax);
+    fEventWindows[system] = std::make_pair(tMin, tMax);
   }
 
 private:  // methods
   /** @brief Task initialisation **/
   virtual InitStatus Init();
 
+
   /** @brief Construct a DigiTimeslice from the data in CbmDigiManager **/
   CbmDigiTimeslice FillTimeSlice();
 
+
+  /** @brief Number of digis for a given system
+   ** @param data    CbmDigiData object (DigiTimeslice or DigiEvent)
+   ** @param system  System identifier (enum ECbmModuleId)
+   ** @return        Number of digis for the system
+   **/
+  size_t GetNumDigis(const CbmDigiData& data, ECbmModuleId system);
+
+
 private:                                           // members
-  CbmDigiManager* fDigiMan             = nullptr;  //! Input data (digis)
+  const CbmDigiTimeslice* fTimeslice   = nullptr;  //! Input data (from unpacking)
+  CbmDigiManager* fDigiMan             = nullptr;  //! Input data (from simulation)
   const std::vector<double>* fTriggers = nullptr;  //! Input data (triggers)
-  std::vector<ECbmModuleId> fSystems {};           //  List of detector systems
-  std::vector<CbmDigiEvent>* fEvents = nullptr;    //! Output data (events)
+  std::vector<CbmDigiEvent>* fEvents   = nullptr;  //! Output data (events)
   cbm::algo::EventBuilder fAlgo {};                //! Algorithm
 
-  std::map<ECbmModuleId, std::pair<double, double>> fTriggerWindows;
+  std::map<ECbmModuleId, std::pair<double, double>> fEventWindows;
 
   // for diagnostics
   std::map<ECbmModuleId, size_t> fNumDigisTs;  //  Number of digis in timeslices
diff --git a/reco/tasks/CbmTaskTriggerDigi.cxx b/reco/tasks/CbmTaskTriggerDigi.cxx
index e284c946bad75440382345c3d173fa04a9fa2a69..de60973e9f9734613b9c1994fc5fd215decad49a 100644
--- a/reco/tasks/CbmTaskTriggerDigi.cxx
+++ b/reco/tasks/CbmTaskTriggerDigi.cxx
@@ -6,6 +6,7 @@
 
 #include "CbmDefs.h"
 #include "CbmDigiManager.h"
+#include "CbmDigiTimeslice.h"
 #include "CbmModuleList.h"
 #include "CbmMuchDigi.h"
 #include "CbmPsdDigi.h"
@@ -46,43 +47,59 @@ void CbmTaskTriggerDigi::Exec(Option_t*)
 
   // --- Get digi times
   std::vector<double> digiTimes;
-  for (const auto& system : fSystems) {
-    CbmDigiBranchBase* digiBranch = fDigiMan->GetBranch(system);
-    std::vector<double> locDigiTimes;
-    switch (system) {
-      case ECbmModuleId::kMuch: {  //we do not support the "MuchBeamTimeDigi"
-        locDigiTimes = GetDigiTimes<CbmMuchDigi>(digiBranch);
-        break;
-      }
-      case ECbmModuleId::kSts: {
-        locDigiTimes = GetDigiTimes<CbmStsDigi>(digiBranch);
-        break;
-      }
-      case ECbmModuleId::kTof: {
-        locDigiTimes = GetDigiTimes<CbmTofDigi>(digiBranch);
-        break;
-      }
-      case ECbmModuleId::kTrd: {
-        locDigiTimes = GetDigiTimes<CbmTrdDigi>(digiBranch);
-        break;
-      }
-      case ECbmModuleId::kRich: {
-        locDigiTimes = GetDigiTimes<CbmRichDigi>(digiBranch);
-        break;
-      }
-      case ECbmModuleId::kPsd: {
-        locDigiTimes = GetDigiTimes<CbmPsdDigi>(digiBranch);
-        break;
-      }
-      case ECbmModuleId::kT0: {  //T0 has Tof digis
-        locDigiTimes = GetDigiTimes<CbmTofDigi>(digiBranch);
-        break;
+
+  // --- Case: input CbmDigiTimeslice
+  if (fTimeslice) {
+    for (const auto& system : fSystems) {
+      std::vector<double> systemDigiTimes = GetDigiTimes(system);
+      digiTimes.insert(digiTimes.end(), systemDigiTimes.begin(), systemDigiTimes.end());
+    }
+    if (fSystems.size() > 1) { std::sort(digiTimes.begin(), digiTimes.end()); }
+  }
+
+  // --- Case: input digi branches
+  else {
+    for (const auto& system : fSystems) {
+      CbmDigiBranchBase* digiBranch = fDigiMan->GetBranch(system);
+      std::vector<double> locDigiTimes;
+      switch (system) {
+        case ECbmModuleId::kMuch: {  //we do not support the "MuchBeamTimeDigi"
+          locDigiTimes = GetDigiTimes<CbmMuchDigi>(digiBranch);
+          break;
+        }
+        case ECbmModuleId::kSts: {
+          locDigiTimes = GetDigiTimes<CbmStsDigi>(digiBranch);
+          break;
+        }
+        case ECbmModuleId::kTof: {
+          locDigiTimes = GetDigiTimes<CbmTofDigi>(digiBranch);
+          break;
+        }
+        case ECbmModuleId::kTrd: {
+          locDigiTimes = GetDigiTimes<CbmTrdDigi>(digiBranch);
+          break;
+        }
+        case ECbmModuleId::kRich: {
+          locDigiTimes = GetDigiTimes<CbmRichDigi>(digiBranch);
+          break;
+        }
+        case ECbmModuleId::kPsd: {
+          locDigiTimes = GetDigiTimes<CbmPsdDigi>(digiBranch);
+          break;
+        }
+        case ECbmModuleId::kT0: {  //T0 has Tof digis
+          locDigiTimes = GetDigiTimes<CbmTofDigi>(digiBranch);
+          break;
+        }
+        default: {
+          LOG(error) << GetName() << ": Unknown detector type!";
+          break;
+        }
       }
-      default: LOG(fatal) << GetName() << ": Reading digis from unknown detector type!";
+      digiTimes.insert(digiTimes.end(), locDigiTimes.begin(), locDigiTimes.end());
     }
-    digiTimes.insert(digiTimes.end(), locDigiTimes.begin(), locDigiTimes.end());
+    if (fSystems.size() > 1) { std::sort(digiTimes.begin(), digiTimes.end()); }
   }
-  if (fSystems.size() > 1) { std::sort(digiTimes.begin(), digiTimes.end()); }
 
   // --- Call the trigger algorithm
   timerStep.Start();
@@ -111,6 +128,72 @@ void CbmTaskTriggerDigi::Exec(Option_t*)
 // ----------------------------------------------------------------------------
 
 
+// -----   Get digi times from CbmDigiTimeslice   -----------------------------
+std::vector<double> CbmTaskTriggerDigi::GetDigiTimes(ECbmModuleId system)
+{
+  assert(fTimeslice);
+  std::vector<double> result;
+  switch (system) {
+    case ECbmModuleId::kSts: {
+      result.resize(fTimeslice->fData.fSts.fDigis.size());
+      auto it1 = fTimeslice->fData.fSts.fDigis.begin();
+      auto it2 = fTimeslice->fData.fSts.fDigis.end();
+      std::transform(it1, it2, result.begin(), [](const CbmStsDigi& digi) { return digi.GetTime(); });
+      break;
+    }
+    case ECbmModuleId::kRich: {
+      result.resize(fTimeslice->fData.fRich.fDigis.size());
+      auto it1 = fTimeslice->fData.fRich.fDigis.begin();
+      auto it2 = fTimeslice->fData.fRich.fDigis.end();
+      std::transform(it1, it2, result.begin(), [](const CbmRichDigi& digi) { return digi.GetTime(); });
+      break;
+    }
+    case ECbmModuleId::kMuch: {
+      result.resize(fTimeslice->fData.fMuch.fDigis.size());
+      auto it1 = fTimeslice->fData.fMuch.fDigis.begin();
+      auto it2 = fTimeslice->fData.fMuch.fDigis.end();
+      std::transform(it1, it2, result.begin(), [](const CbmMuchDigi& digi) { return digi.GetTime(); });
+      break;
+    }
+    case ECbmModuleId::kTrd: {
+      result.resize(fTimeslice->fData.fTrd.fDigis.size());
+      auto it1 = fTimeslice->fData.fTrd.fDigis.begin();
+      auto it2 = fTimeslice->fData.fTrd.fDigis.end();
+      std::transform(it1, it2, result.begin(), [](const CbmTrdDigi& digi) { return digi.GetTime(); });
+      break;
+    }
+    case ECbmModuleId::kTof: {
+      result.resize(fTimeslice->fData.fTof.fDigis.size());
+      auto it1 = fTimeslice->fData.fTof.fDigis.begin();
+      auto it2 = fTimeslice->fData.fTof.fDigis.end();
+      std::transform(it1, it2, result.begin(), [](const CbmTofDigi& digi) { return digi.GetTime(); });
+      break;
+    }
+    case ECbmModuleId::kPsd: {
+      result.resize(fTimeslice->fData.fPsd.fDigis.size());
+      auto it1 = fTimeslice->fData.fPsd.fDigis.begin();
+      auto it2 = fTimeslice->fData.fPsd.fDigis.end();
+      std::transform(it1, it2, result.begin(), [](const CbmPsdDigi& digi) { return digi.GetTime(); });
+      break;
+    }
+    case ECbmModuleId::kT0: {
+      result.resize(fTimeslice->fData.fT0.fDigis.size());
+      auto it1 = fTimeslice->fData.fT0.fDigis.begin();
+      auto it2 = fTimeslice->fData.fT0.fDigis.end();
+      std::transform(it1, it2, result.begin(), [](const CbmTofDigi& digi) { return digi.GetTime(); });
+      break;
+    }
+    default: {
+      LOG(error) << GetName() << ": Unknown system " << system;
+      break;
+    }
+  }  //? system
+
+  return result;
+}
+// ----------------------------------------------------------------------------
+
+
 // -----   End-of-timeslice action   ------------------------------------------
 void CbmTaskTriggerDigi::Finish()
 {
@@ -139,21 +222,25 @@ InitStatus CbmTaskTriggerDigi::Init()
   FairRootManager* ioman = FairRootManager::Instance();
   assert(ioman);
 
-  // --- DigiManager instance
-  fDigiMan = CbmDigiManager::Instance();
-  fDigiMan->Init();
-
   std::cout << std::endl;
   LOG(info) << "==================================================";
   LOG(info) << GetName() << ": Initialising...";
 
   // --- Check input data
-  for (const auto& system : fSystems) {
-    if (!fDigiMan->IsPresent(system)) {
-      LOG(fatal) << GetName() << ": No digi branch for " << CbmModuleList::GetModuleNameCaps(system);
-      return kFATAL;
+  // --- DigiTimeslice: Unpacked data from FLES
+  fTimeslice = ioman->InitObjectAs<const CbmDigiTimeslice*>("DigiTimeslice.");
+  if (fTimeslice) { LOG(info) << GetName() << ": Found branch DigiTimeslice."; }
+  // --- DigiManager: Simulated digi data
+  else {
+    fDigiMan = CbmDigiManager::Instance();
+    fDigiMan->Init();
+    for (const auto& system : fSystems) {
+      if (!fDigiMan->IsPresent(system)) {
+        LOG(fatal) << GetName() << ": No digi branch for " << CbmModuleList::GetModuleNameCaps(system);
+        return kFATAL;
+      }
+      LOG(info) << "--- Found digi branch for " << CbmModuleList::GetModuleNameCaps(system);
     }
-    LOG(info) << "--- Found digi branch for " << CbmModuleList::GetModuleNameCaps(system);
   }
 
   // --- Register output array (Triggers)
diff --git a/reco/tasks/CbmTaskTriggerDigi.h b/reco/tasks/CbmTaskTriggerDigi.h
index 30453cc90e4149302164028fb7fc39b8105bb3d1..61060979847d39ad0ea7c89d56bd67f18d8e7340 100644
--- a/reco/tasks/CbmTaskTriggerDigi.h
+++ b/reco/tasks/CbmTaskTriggerDigi.h
@@ -19,6 +19,7 @@
 
 class CbmDigiBranchBase;
 class CbmDigiManager;
+struct CbmDigiTimeslice;
 
 using namespace std;
 
@@ -105,11 +106,20 @@ private:  // methods
     return digiTimes;
   }
 
-private:                                     // members
-  CbmDigiManager* fDigiMan = nullptr;        //! Input data
-  std::vector<ECbmModuleId> fSystems {};     //  List of detector systems
-  std::vector<double>* fTriggers = nullptr;  //! Output data
-  cbm::algo::TimeClusterTrigger fAlgo {};    //! Algorithm
+
+  /** @brief Extract digi times from CbmDigiTimeslice
+   ** @param system Detector system (enum ECbmModuleId)
+   ** @return Vector of digi times for the specified system
+   **/
+  std::vector<double> GetDigiTimes(ECbmModuleId system);
+
+
+private:                                         // members
+  const CbmDigiTimeslice* fTimeslice = nullptr;  //! Input data (from unpacking)
+  CbmDigiManager* fDigiMan           = nullptr;  //! Input data (from simulation)
+  std::vector<ECbmModuleId> fSystems {};         //  List of detector systems
+  std::vector<double>* fTriggers = nullptr;      //! Output data
+  cbm::algo::TimeClusterTrigger fAlgo {};        //! Algorithm
   double fTriggerWindow = 0.;
   int32_t fMinNumDigis  = 0;
   double fDeadTime      = 0.;