diff --git a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h
index 7791a02d9d3d3046eb09508f3c0eed10b282d677..dd342dd04cc973df072e81062de26424f1b6c1f2 100644
--- a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h
+++ b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h
@@ -5,12 +5,14 @@
 #ifndef CBMALGOBUILDRAWEVENTS_H
 #define CBMALGOBUILDRAWEVENTS_H
 
-/// FAIRROOT headers
-#include "FairTask.h"
-
 /// CBMROOT headers
 #include "CbmDefs.h"
 
+/// FAIRROOT headers
+
+/// FAIRSOFT headers (geant, boost, ...)
+#include "TFolder.h"
+
 /// C/C++ headers
 #include <boost/any.hpp>
 
diff --git a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx
index 2ea706c2818f8b368bfe6e7cd4494727d8c4f343..ab21ac81e6eedca8334058d8cf083862bc43f801 100644
--- a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx
+++ b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx
@@ -32,6 +32,14 @@ CbmTaskBuildRawEvents::~CbmTaskBuildRawEvents()
   if (fTempDigiTimes) delete fTempDigiTimes;
   if (fTimer) delete fTimer;
   if (fCopyTimer) delete fCopyTimer;
+  if (fDigiEvents) {
+    fDigiEvents->clear();
+    delete fDigiEvents;
+  }
+  else if (fEvents) {
+    fEvents->Delete();
+    delete fEvents;
+  }
 }
 
 CbmTaskBuildRawEvents::CbmTaskBuildRawEvents() : FairTask("BuildRawEvents")
@@ -125,10 +133,19 @@ InitStatus CbmTaskBuildRawEvents::Init()
   InitDigis(ECbmModuleId::kPsd, &fPsdDigis);
   InitDigis(ECbmModuleId::kT0, &fT0Digis);
 
-  /// Register output array (CbmEvent)
-  fEvents = new TClonesArray("CbmEvent", 100);
-  ioman->Register("CbmEvent", "Cbm_Event", fEvents, IsOutputBranchPersistent("CbmEvent"));
-  if (!fEvents) LOG(fatal) << "Output branch was not created";
+  /// Register output (array of CbmEvent or vector of CbmDigiEvents)
+  if (fbDigiEvtOut) {
+    if (fbUseMuchBeamtimeDigi) LOG(fatal) << "DigiEvent output branch not compatible with MuchBeamtimeDigi";
+
+    fDigiEvents = new std::vector<CbmDigiEvent>();
+    ioman->RegisterAny("DigiEvent", fDigiEvents, kTRUE);
+    if (!fDigiEvents) LOG(fatal) << "Output branch was not created";
+  }
+  else {
+    fEvents = new TClonesArray("CbmEvent", 100);
+    ioman->Register("CbmEvent", "Cbm_Event", fEvents, IsOutputBranchPersistent("CbmEvent"));
+    if (!fEvents) LOG(fatal) << "Output branch was not created";
+  }
 
   // Set timeslice meta data
   fpAlgo->SetTimeSliceMetaDataArray(dynamic_cast<TClonesArray*>(ioman->GetObject("TimesliceMetaData")));
@@ -193,7 +210,14 @@ void CbmTaskBuildRawEvents::Exec(Option_t* /*option*/)
   logOut << std::setw(20) << std::left << GetName() << " [";
   logOut << std::fixed << std::setw(8) << std::setprecision(1) << std::right << timer.RealTime() * 1000. << " ms] ";
   logOut << "TS " << fNofTs;
-  if (fEvents) logOut << ", events " << fEvents->GetEntriesFast();
+  if (fbDigiEvtOut) {
+    logOut << ", events " << fDigiEvents->size();
+    fNofEvents += fDigiEvents->size();
+  }
+  else {
+    logOut << ", events " << fEvents->GetEntriesFast();
+    fNofEvents += fEvents->GetEntriesFast();
+  }
   LOG(info) << logOut.str();
   if (fSeedFinderSlidingWindow) {
     const size_t seedCount = fSeedFinderSlidingWindow->GetNofSeeds();
@@ -201,7 +225,6 @@ void CbmTaskBuildRawEvents::Exec(Option_t* /*option*/)
     fTotalSeedCount += seedCount;
   }
   fNofTs++;
-  fNofEvents += fEvents->GetEntriesFast();
   fTime += timer.RealTime();
 
   LOG(debug2) << "CbmTaskBuildRawEvents::Exec => Done";
@@ -415,17 +438,26 @@ void CbmTaskBuildRawEvents::Finish()
 
 void CbmTaskBuildRawEvents::FillOutput()
 {
-  /// Clear TClonesArray before usage.
-  fEvents->Delete();
-
   /// Get vector reference from algo
   std::vector<CbmEvent*> vEvents = fpAlgo->GetEventVector();
 
-  /// Move CbmEvent from temporary vector to TClonesArray
-  for (CbmEvent* event : vEvents) {
-    LOG(debug) << "Vector: " << event->ToString();
-    new ((*fEvents)[fEvents->GetEntriesFast()]) CbmEvent(std::move(*event));
-    LOG(debug) << "TClonesArray: " << static_cast<CbmEvent*>(fEvents->At(fEvents->GetEntriesFast() - 1))->ToString();
+  if (fbDigiEvtOut) {
+    /// Clear data from previous TS before usage.
+    fDigiEvents->clear();
+
+    /// Convert each CbmEvent to a CbmDigiEvent by extracting the corresponding data from the input vectors
+    ExtractSelectedData(vEvents);
+  }
+  else {
+    /// Clear TClonesArray before usage.
+    fEvents->Delete();
+
+    /// Move CbmEvent from temporary vector to TClonesArray
+    for (CbmEvent* event : vEvents) {
+      LOG(debug) << "Vector: " << event->ToString();
+      new ((*fEvents)[fEvents->GetEntriesFast()]) CbmEvent(std::move(*event));
+      LOG(debug) << "TClonesArray: " << static_cast<CbmEvent*>(fEvents->At(fEvents->GetEntriesFast() - 1))->ToString();
+    }
   }
   /// Clear event vector after usage
   fpAlgo->ClearEventVector();
@@ -497,4 +529,93 @@ void CbmTaskBuildRawEvents::DumpSeedTimesFromDetList()
   exit(0);  //terminate as this method should only be used for diagnostics
 }
 
+void CbmTaskBuildRawEvents::ExtractSelectedData(std::vector<CbmEvent*> vEvents)
+{
+  /// Move CbmEvent from temporary vector to std::vector of full objects
+  LOG(debug) << "In Vector size: " << vEvents.size();
+
+  fDigiEvents->reserve(vEvents.size());
+  for (CbmEvent* event : vEvents) {
+    CbmDigiEvent selEvent;
+    selEvent.fTime   = event->GetStartTime();
+    selEvent.fNumber = event->GetNumber();
+
+    /// FIXME: for pure digi based event, we select "continuous slices of digis"
+    ///        => Copy block of [First Digi index, last digi index] with assign(it_start, it_stop)
+    /// FIXME: Keep TRD1D + TRD2D support, may lead to holes in the digi sequence!
+    ///        => Would need to keep the loop
+
+    /// Get the proper order for block selection as TRD1D and TRD2D may insert indices in separate loops
+    /// => Needed to ensure that the start and stop of the block copy do not trigger a vector size exception
+    event->SortIndices();
+
+    /// for each detector, find the data in the Digi vectors and copy them
+    /// TODO: Template + loop on list of data types?
+    /// ==> T0
+    uint32_t uNbDigis = (0 < event->GetNofData(ECbmDataType::kT0Digi) ? event->GetNofData(ECbmDataType::kT0Digi) : 0);
+    if (0 < uNbDigis) {
+      auto startIt = fT0Digis->begin() + event->GetIndex(ECbmDataType::kT0Digi, 0);
+      auto stopIt  = fT0Digis->begin() + event->GetIndex(ECbmDataType::kT0Digi, uNbDigis - 1);
+      ++stopIt;
+      selEvent.fData.fT0.fDigis.assign(startIt, stopIt);
+    }
+
+    /// ==> STS
+    uNbDigis = (0 < event->GetNofData(ECbmDataType::kStsDigi) ? event->GetNofData(ECbmDataType::kStsDigi) : 0);
+    if (0 < uNbDigis) {
+      auto startIt = fStsDigis->begin() + event->GetIndex(ECbmDataType::kStsDigi, 0);
+      auto stopIt  = fStsDigis->begin() + event->GetIndex(ECbmDataType::kStsDigi, uNbDigis - 1);
+      ++stopIt;
+      selEvent.fData.fSts.fDigis.assign(startIt, stopIt);
+    }
+
+    /// ==> MUCH
+    uNbDigis = (0 < event->GetNofData(ECbmDataType::kMuchDigi) ? event->GetNofData(ECbmDataType::kMuchDigi) : 0);
+    if (0 < uNbDigis) {
+      auto startIt = fMuchDigis->begin() + event->GetIndex(ECbmDataType::kMuchDigi, 0);
+      auto stopIt  = fMuchDigis->begin() + event->GetIndex(ECbmDataType::kMuchDigi, uNbDigis - 1);
+      ++stopIt;
+      selEvent.fData.fMuch.fDigis.assign(startIt, stopIt);
+    }
+
+    /// ==> TRD + TRD2D
+    uNbDigis = (0 < event->GetNofData(ECbmDataType::kTrdDigi) ? event->GetNofData(ECbmDataType::kTrdDigi) : 0);
+    if (0 < uNbDigis) {
+      auto startIt = fTrdDigis->begin() + event->GetIndex(ECbmDataType::kTrdDigi, 0);
+      auto stopIt  = fTrdDigis->begin() + event->GetIndex(ECbmDataType::kTrdDigi, uNbDigis - 1);
+      ++stopIt;
+      selEvent.fData.fTrd.fDigis.assign(startIt, stopIt);
+    }
+
+    /// ==> TOF
+    uNbDigis = (0 < event->GetNofData(ECbmDataType::kTofDigi) ? event->GetNofData(ECbmDataType::kTofDigi) : 0);
+    if (0 < uNbDigis) {
+      auto startIt = fTofDigis->begin() + event->GetIndex(ECbmDataType::kTofDigi, 0);
+      auto stopIt  = fTofDigis->begin() + event->GetIndex(ECbmDataType::kTofDigi, uNbDigis - 1);
+      ++stopIt;
+      selEvent.fData.fTof.fDigis.assign(startIt, stopIt);
+    }
+
+    /// ==> RICH
+    uNbDigis = (0 < event->GetNofData(ECbmDataType::kRichDigi) ? event->GetNofData(ECbmDataType::kRichDigi) : 0);
+    if (0 < uNbDigis) {
+      auto startIt = fRichDigis->begin() + event->GetIndex(ECbmDataType::kRichDigi, 0);
+      auto stopIt  = fRichDigis->begin() + event->GetIndex(ECbmDataType::kRichDigi, uNbDigis - 1);
+      ++stopIt;
+      selEvent.fData.fRich.fDigis.assign(startIt, stopIt);
+    }
+
+    /// ==> PSD
+    uNbDigis = (0 < event->GetNofData(ECbmDataType::kPsdDigi) ? event->GetNofData(ECbmDataType::kPsdDigi) : 0);
+    if (0 < uNbDigis) {
+      auto startIt = fPsdDigis->begin() + event->GetIndex(ECbmDataType::kPsdDigi, 0);
+      auto stopIt  = fPsdDigis->begin() + event->GetIndex(ECbmDataType::kPsdDigi, uNbDigis - 1);
+      ++stopIt;
+      selEvent.fData.fPsd.fDigis.assign(startIt, stopIt);
+    }
+
+    fDigiEvents->push_back(std::move(selEvent));
+  }
+}
+
 ClassImp(CbmTaskBuildRawEvents)
diff --git a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h
index add558dfd7a14f39498ae4887a758a5f8572d482..1eb520d98b3349974f544676cb1a010a1ffa9c44 100644
--- a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h
+++ b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h
@@ -5,13 +5,9 @@
 #ifndef CBMTASKBUILDRAWEVENTS_H
 #define CBMTASKBUILDRAWEVENTS_H
 
-/// FAIRROOT headers
-#include "FairTask.h"
-
-/// FAIRSOFT headers (geant, boost, ...)
-
 /// CBMROOT headers
 #include "CbmAlgoBuildRawEvents.h"
+#include "CbmDigiEvent.h"
 #include "CbmMuchBeamTimeDigi.h"
 #include "CbmMuchDigi.h"
 #include "CbmPsdDigi.h"
@@ -21,6 +17,11 @@
 #include "CbmTrdDigi.h"
 #include "CbmTzdDigi.h"
 
+/// FAIRROOT headers
+#include "FairTask.h"
+
+/// FAIRSOFT headers (geant, boost, ...)
+
 /// C/C++ headers
 #include <array>
 #include <map>
@@ -29,6 +30,7 @@
 #include <vector>
 
 class CbmDigiManager;
+class CbmEvent;
 class CbmMatch;
 class CbmSeedFinderSlidingWindow;
 class RawEventBuilderDetector;
@@ -136,6 +138,8 @@ public:
   void DumpSeedTimesFromDetList();
   void SetSeedTimeWindow(Double_t beg, Double_t end) { fpAlgo->SetSeedTimeWindow(beg, end); }
 
+  void SetDigiEventOutput(Bool_t bFlagIn = kTRUE) { fbDigiEvtOut = bFlagIn; }
+
 private:
   /** Read digis from input, call seed finder, then build events **/
   void BuildEvents();
@@ -186,7 +190,11 @@ private:
 
   CbmAlgoBuildRawEvents* fpAlgo = nullptr;
 
-  TClonesArray* fEvents = nullptr;  //! output container of CbmEvents
+  Bool_t fbDigiEvtOut                    = kFALSE;
+  TClonesArray* fEvents                  = nullptr;  //! output container of CbmEvents
+  std::vector<CbmDigiEvent>* fDigiEvents = nullptr;  //! output container of CbmEvents
+
+  void ExtractSelectedData(std::vector<CbmEvent*> vEvents);
 
   Bool_t fbFillHistos {kTRUE};             //! Switch ON/OFF filling of histograms
   Bool_t fbWriteHistosToFairSink {kTRUE};  //! Write histos to FairRootManager instead of separate file