diff --git a/macro/run/run_unpack_tsa_algo.C b/macro/run/run_unpack_tsa_algo.C
index 2fd9dcd58a51c013bb271882da7a530b35ae5780..e2ea853e0b9a04bf981925e8154ed1e96f115327 100644
--- a/macro/run/run_unpack_tsa_algo.C
+++ b/macro/run/run_unpack_tsa_algo.C
@@ -29,7 +29,7 @@
 #endif
 
 void run_unpack_tsa_algo(std::string infile, std::string outpath, std::string paramsdir, UInt_t runid,
-                         std::int32_t nevents = -1)
+                         std::int32_t nevents = -1, bool bCbmrootLikeOutput = false)
 {
 
   // ========================================================================
@@ -75,7 +75,9 @@ void run_unpack_tsa_algo(std::string infile, std::string outpath, std::string pa
 
   // -----    Algo Unpacker -------------------------------------------------
   //run->AddTask(new CbmTaskUnpack());
-  run->AddTask(new CbmTaskUnpack(paramsdir, runid));
+  auto unpackTask = new CbmTaskUnpack(paramsdir, runid);
+  unpackTask->SetOutputModeCbmrootLike(bCbmrootLikeOutput);
+  run->AddTask(unpackTask);
 
   run->SetSink(sink);
   auto eventheader = new CbmTsEventHeader();
diff --git a/reco/steer/CbmSourceDigiTimeslice.cxx b/reco/steer/CbmSourceDigiTimeslice.cxx
index 780d1d25e12727cd3ff76252ae4315e8c802d5cc..707d9a824f4ecaf3cc6b4343d80ba9a9c519ee92 100644
--- a/reco/steer/CbmSourceDigiTimeslice.cxx
+++ b/reco/steer/CbmSourceDigiTimeslice.cxx
@@ -63,8 +63,6 @@ Bool_t CbmSourceDigiTimeslice::Init()
   FairRootManager* ioman = FairRootManager::Instance();
   assert(ioman);
 
-  auto* pEvtHeader = FairRun::Instance()->GetEventHeader();
-
   if (!(fTsEventHeader = dynamic_cast<CbmTsEventHeader*>(FairRun::Instance()->GetEventHeader()))) {
     LOG(fatal) << "CbmSourceDigiTimeslice::Init() no CbmTsEventHeader was added to the run. Without it, we can not "
                   "store the UTC of the "
diff --git a/reco/tasks/CbmTaskUnpack.cxx b/reco/tasks/CbmTaskUnpack.cxx
index 9fa2a88fdae8899afee3f4badb03fe37d339d3d5..db0d9042fe6123738a7225636377b34a6eb23c3f 100644
--- a/reco/tasks/CbmTaskUnpack.cxx
+++ b/reco/tasks/CbmTaskUnpack.cxx
@@ -11,12 +11,14 @@
 #include "CbmDigiManager.h"
 #include "CbmDigiTimeslice.h"
 #include "CbmSourceTs.h"
+#include "CbmTimeSlice.h"
 #include "CbmTrdParFasp.h"
 #include "CbmTrdParModAsic.h"
 #include "CbmTrdParModDigi.h"
 #include "CbmTrdParSetAsic.h"
 #include "CbmTrdParSetDigi.h"
 #include "CbmTrdParSpadic.h"
+#include "CbmTsEventHeader.h"
 #include "MicrosliceDescriptor.hpp"
 #include "ParFiles.h"
 #include "System.hpp"
@@ -89,7 +91,17 @@ CbmTaskUnpack::CbmTaskUnpack(fs::path paramsDir, uint32_t runId) : FairTask("Unp
 // -----   Destructor   ------------------------------------------------------
 CbmTaskUnpack::~CbmTaskUnpack()
 {
-  if (fTimeslice) delete fTimeslice;
+  if (fDigiTimeslice) delete fDigiTimeslice;
+
+  if (fCbmrootFormatOutput) {
+    // Clear output vectors
+    fBmonDigis->clear();
+    fStsDigis->clear();
+    fMuchDigis->clear();
+    fTrdDigis->clear();
+    fTofDigis->clear();
+    fRichDigis->clear();
+  }
 }
 // ---------------------------------------------------------------------------
 
@@ -97,10 +109,6 @@ CbmTaskUnpack::~CbmTaskUnpack()
 // -----   Execution   -------------------------------------------------------
 void CbmTaskUnpack::Exec(Option_t*)
 {
-
-  // --- Reset output branch (CbmDigiTimeslice)
-  fTimeslice->Clear();
-
   // --- Get FLES timeslice
   assert(fSource);
   fles::Timeslice* timeslice = fSource->GetTimeslice();
@@ -122,12 +130,42 @@ void CbmTaskUnpack::Exec(Option_t*)
   digis.fTrd   = RunUnpacker(fTrdUnpack, *timeslice, monitor);
   digis.fTrd2d = RunUnpacker(fTrd2dUnpack, *timeslice, monitor);
 
-  // Use lines below to combine TRD 1D and 2D
-  //auto& digis1d = digis.fTrd;
-  //auto& digis2d = digis.fTrd2d;
-  //std::copy(digis2d.begin(), digis2d.end(), std::back_inserter(digis1d));
+  if (fCbmrootFormatOutput) {
+    // Clear output vectors
+    fBmonDigis->clear();
+    fStsDigis->clear();
+    fMuchDigis->clear();
+    fTrdDigis->clear();
+    fTofDigis->clear();
+    fRichDigis->clear();
+
+    fTsEventHeader->SetTsIndex(timeslice->index());
+    fTsEventHeader->SetTsStartTime(timeslice->start_time());
+
+    fTimeslice->SetStartTime(timeslice->start_time());
+
+    std::move(digis.fBmon.begin(), digis.fBmon.end(), std::back_inserter(*fBmonDigis));
+    std::move(digis.fSts.begin(), digis.fSts.end(), std::back_inserter(*fStsDigis));
+    std::move(digis.fMuch.begin(), digis.fMuch.end(), std::back_inserter(*fMuchDigis));
+    std::move(digis.fTrd2d.begin(), digis.fTrd2d.end(), std::back_inserter(*fTrdDigis));
+    std::move(digis.fTrd.begin(), digis.fTrd.end(), std::back_inserter(*fTrdDigis));
+    std::move(digis.fTof.begin(), digis.fTof.end(), std::back_inserter(*fTofDigis));
+    std::move(digis.fRich.begin(), digis.fRich.end(), std::back_inserter(*fRichDigis));
+
+    // Time-sort the TRD vector as we merged TRD1D and TRD2D (needed for compatibility with legacy unpackers)
+    Timesort(fTrdDigis);
+  }
+  else {
+    // --- Reset output branch (CbmDigiTimeslice)
+    fDigiTimeslice->Clear();
 
-  fTimeslice->fData = digis.ToStorable();
+    // Use lines below to combine TRD 1D and 2D
+    //auto& digis1d = digis.fTrd;
+    //auto& digis2d = digis.fTrd2d;
+    //std::copy(digis2d.begin(), digis2d.end(), std::back_inserter(digis1d));
+
+    fDigiTimeslice->fData = digis.ToStorable();
+  }
 
   // --- Timeslice log
   timer.Stop();
@@ -180,6 +218,20 @@ void CbmTaskUnpack::Finish()
 
 
 // -----   Initialisation   ---------------------------------------------------
+template<typename TVecobj>
+Bool_t CbmTaskUnpack::RegisterVector(FairRootManager* ioman, std::vector<TVecobj>*& vec)
+{
+  if (ioman->GetObject(TVecobj::GetBranchName())) {
+    LOG(fatal) << GetName() << ": Branch " << TVecobj::GetBranchName() << " already exists!";
+    return kFALSE;
+  }
+
+  ioman->RegisterAny(TVecobj::GetBranchName(), vec, kTRUE);
+  LOG(info) << GetName() << ": Registered branch " << TVecobj::GetBranchName() << " at " << vec;
+
+  return kTRUE;
+}
+
 InitStatus CbmTaskUnpack::Init()
 {
   LOG(info) << "==================================================";
@@ -205,9 +257,67 @@ InitStatus CbmTaskUnpack::Init()
     LOG(fatal) << GetName() << ": Branch DigiTimeslice already exists!";
     return kFATAL;
   }
-  fTimeslice = new CbmDigiTimeslice();
-  ioman->RegisterAny("DigiTimeslice.", fTimeslice, IsOutputBranchPersistent("DigiTimeslice."));
-  LOG(info) << "--- Registered branch DigiTimeslice.";
+
+  if (fCbmrootFormatOutput) {
+
+    if (!(fTsEventHeader = dynamic_cast<CbmTsEventHeader*>(FairRun::Instance()->GetEventHeader()))) {
+      LOG(fatal) << "CbmSourceDigiTimeslice::Init() no CbmTsEventHeader was added to the run. "
+                    "Without it, we can not store the UTC of the Timeslices correctly. "
+                    "Hence, this causes a fatal. Please add it to the Run in the steering macro.";
+      return kFATAL;
+    }
+
+    // TimeSlice. branch initialization
+    if (ioman->GetObject("TimeSlice.")) {
+      LOG(fatal) << "Source: Branch TimeSlice. already exists!";
+      return kFATAL;
+    }
+    else {
+      // NOTE: the max time of timeslice is 1.28e8, taken from CbmRecoUnpack.cxx
+      fTimeslice = new CbmTimeSlice(0., 1.28e8 + 1.28e6);
+      ioman->Register("TimeSlice.", "DAQ", fTimeslice, kTRUE);
+    }
+
+    fBmonDigis = new std::vector<CbmBmonDigi>();
+    if (kFALSE == RegisterVector<CbmBmonDigi>(ioman, fBmonDigis)) {
+      return kFATAL;
+    }
+
+
+    fStsDigis = new std::vector<CbmStsDigi>();
+    if (kFALSE == RegisterVector<CbmStsDigi>(ioman, fStsDigis)) {
+      return kFATAL;
+    }
+
+
+    fMuchDigis = new std::vector<CbmMuchDigi>();
+    if (kFALSE == RegisterVector<CbmMuchDigi>(ioman, fMuchDigis)) {
+      return kFATAL;
+    }
+
+
+    fTrdDigis = new std::vector<CbmTrdDigi>();
+    if (kFALSE == RegisterVector<CbmTrdDigi>(ioman, fTrdDigis)) {
+      return kFATAL;
+    }
+
+
+    fTofDigis = new std::vector<CbmTofDigi>();
+    if (kFALSE == RegisterVector<CbmTofDigi>(ioman, fTofDigis)) {
+      return kFATAL;
+    }
+
+
+    fRichDigis = new std::vector<CbmRichDigi>();
+    if (kFALSE == RegisterVector<CbmRichDigi>(ioman, fRichDigis)) {
+      return kFATAL;
+    }
+  }
+  else {
+    fDigiTimeslice = new CbmDigiTimeslice();
+    ioman->RegisterAny("DigiTimeslice.", fDigiTimeslice, IsOutputBranchPersistent("DigiTimeslice."));
+    LOG(info) << "--- Registered branch DigiTimeslice.";
+  }
 
   return kSUCCESS;
 }
diff --git a/reco/tasks/CbmTaskUnpack.h b/reco/tasks/CbmTaskUnpack.h
index 69cec6e193a28324643c168000f593ecba5bb76a..c091dd2873c62b087bc130309801813065f25ba3 100644
--- a/reco/tasks/CbmTaskUnpack.h
+++ b/reco/tasks/CbmTaskUnpack.h
@@ -39,6 +39,9 @@ namespace cbm
 
 class CbmDigiManager;
 class CbmSourceTs;
+class CbmTimeSlice;
+class CbmTsEventHeader;
+class FairRootManager;
 
 namespace fs = boost::filesystem;
 
@@ -99,6 +102,10 @@ class CbmTaskUnpack : public FairTask {
   void SetMonitor(cbm::Monitor* monitor) { fMonitor = monitor; }
 
 
+  /** @brief Set the output file in "as if cbmroot digi file" mode (default is "as if rra") **/
+  void SetOutputModeCbmrootLike(bool flag = true) { fCbmrootFormatOutput = flag; }
+
+
  private:  // methods
   /** @brief Task initialisation **/
   virtual InitStatus Init();
@@ -117,18 +124,45 @@ class CbmTaskUnpack : public FairTask {
   std::unique_ptr<cbm::algo::trd::Unpack> fTrdUnpack;
   std::unique_ptr<cbm::algo::trd2d::Unpack> fTrd2dUnpack;
 
-  size_t fNumTs                = 0;
-  size_t fNumMs                = 0;
-  size_t fNumBytes             = 0;
-  size_t fNumDigis             = 0;
-  double fTime                 = 0.;
-  CbmDigiTimeslice* fTimeslice = nullptr;  ///< Output data
+  size_t fNumTs                    = 0;
+  size_t fNumMs                    = 0;
+  size_t fNumBytes                 = 0;
+  size_t fNumDigis                 = 0;
+  double fTime                     = 0.;
+  CbmDigiTimeslice* fDigiTimeslice = nullptr;  ///< Output data if writing root files "as if rra"
+
+  /// Output data if writing root file "as if cbmroot digi file"
+  /// Flag controlling the output mode
+  bool fCbmrootFormatOutput = false;
+  /// => Time-slice header (old version, class about to be deprecated? one should use only CbmTsEventHeader soon?)
+  CbmTimeSlice* fTimeslice = nullptr;
+  /// Time-slice event header
+  CbmTsEventHeader* fTsEventHeader = nullptr;
+  /// => Branch vectors of Digis
+  std::vector<CbmBmonDigi>* fBmonDigis = nullptr;
+  std::vector<CbmStsDigi>* fStsDigis   = nullptr;
+  std::vector<CbmMuchDigi>* fMuchDigis = nullptr;
+  std::vector<CbmTrdDigi>* fTrdDigis   = nullptr;
+  std::vector<CbmTofDigi>* fTofDigis   = nullptr;
+  std::vector<CbmRichDigi>* fRichDigis = nullptr;
 
   template<class Unpacker>
   auto RunUnpacker(const std::unique_ptr<Unpacker>& unpacker, const fles::Timeslice& ts, Monitor& monitor)
     -> cbm::algo::algo_traits::Output_t<Unpacker>;
 
-  ClassDef(CbmTaskUnpack, 3);
+  template<typename TVecobj>
+  Bool_t RegisterVector(FairRootManager* ioman, std::vector<TVecobj>*& vec);
+
+  template<typename TVecobj>
+  typename std::enable_if<std::is_member_function_pointer<decltype(&TVecobj::GetTime)>::value, void>::type
+  Timesort(std::vector<TVecobj>* vec = nullptr)
+  {
+    if (vec == nullptr) return;
+    std::sort(vec->begin(), vec->end(),
+              [](const TVecobj& a, const TVecobj& b) -> bool { return a.GetTime() < b.GetTime(); });
+  }
+
+  ClassDef(CbmTaskUnpack, 4);
 };
 
 #endif /* CBMTASKUNPACK_H */