diff --git a/reco/detectors/rich/unpack/CbmRichUnpackAlgo.cxx b/reco/detectors/rich/unpack/CbmRichUnpackAlgo.cxx
index ca31db39bdaa8d509ab0df71d20dbd13c04e67b2..ff5b18c608b7a7fb6d8e93e24fae12d51ed83d98 100644
--- a/reco/detectors/rich/unpack/CbmRichUnpackAlgo.cxx
+++ b/reco/detectors/rich/unpack/CbmRichUnpackAlgo.cxx
@@ -26,7 +26,7 @@ std::vector<std::pair<std::string, std::shared_ptr<FairParGenericSet>>>*
 
   // // Get parameter container
   temppath = basepath + "mRichPar.par";
-  LOG(info) << "HelloWorld " << temppath;
+
   fParContVec.emplace_back(std::make_pair(temppath, std::make_shared<CbmMcbm2018RichPar>()));
 
   return &fParContVec;
@@ -39,7 +39,7 @@ double CbmRichUnpackAlgo::calculateTime(uint32_t epoch, uint32_t coarse, uint32_
 }
 
 // ---- getLogHeader
-std::string CbmRichUnpackAlgo::getLogHeader(CbmMcbm2018RichMicrosliceReader& reader)
+std::string CbmRichUnpackAlgo::getLogHeader(CbmRichUnpackAlgoMicrosliceReader& reader)
 {
   std::stringstream stream;
   stream << "[" << fNrProcessedTs << "-" << reader.GetWordCounter() << "/" << reader.GetSize() / 4 << " "
@@ -87,7 +87,7 @@ bool CbmRichUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, U
   const fles::MicrosliceView mv            = ts->get_microslice(icomp, imslice);
   const fles::MicrosliceDescriptor& msDesc = mv.desc();
 
-  CbmMcbm2018RichMicrosliceReader reader;
+  CbmRichUnpackAlgoMicrosliceReader reader;
   reader.SetData(mv.content(), msDesc.size);
 
   // There are a lot of MS  with 8 bytes size
@@ -112,7 +112,176 @@ bool CbmRichUnpackAlgo::unpack(const fles::Timeslice* ts, std::uint16_t icomp, U
   return true;
 }
 
-void CbmRichUnpackAlgo::processTrbPacket(CbmMcbm2018RichMicrosliceReader& reader)
+void CbmRichUnpackAlgo::processHubBlock(CbmRichUnpackAlgoMicrosliceReader& reader)
+{
+  uint32_t word    = reader.NextWord();
+  uint32_t hubId   = word & 0xffff;          // 16 bits
+  uint32_t hubSize = (word >> 16) & 0xffff;  // 16 bits
+  if (isLog())
+    LOG(debug4) << getLogHeader(reader) << "hubId:0x" << std::hex << hubId << std::dec << " hubSize:" << hubSize;
+
+  //if ((HubId == 0xc001) || (HubId == 0xc000)) //CTS subevent?
+  //if (HubId == 0x5555)
+  //if (((HubId >> 8) & 0xff) == 0x82) // TRB subevent? // TODO: check if it starts from 0x82
+
+  // if true then it is CTS sub-sub-event
+  bool isLast      = false;
+  size_t counter   = 0;
+  size_t totalSize = 0;
+  while (!isLast) {
+    word                     = reader.NextWord();
+    uint32_t subSubEventId   = word & 0xffff;                              // 16 bits
+    uint32_t subSubEventSize = (word >> 16) & 0xffff;                      // 16 bits
+    isLast                   = reader.IsLastSubSubEvent(subSubEventSize);  // if true then it is CTS sub-sub-event
+    counter++;
+    totalSize += (1 + subSubEventSize);
+
+    if (isLog())
+      LOG(debug4) << getLogHeader(reader) << counter << ((isLast) ? " CTS" : " DiRICH") << " subSubEventId:0x"
+                  << std::hex << subSubEventId << std::dec << " subSubEventSize:" << subSubEventSize;
+
+    if (!isLast) {  // DiRICH event
+      // check correctness of subsub event, for safety reasons
+      if (((subSubEventId >> 12) & 0xF) != 0x7) {
+        LOG(error) << getLogHeader(reader) << "ERROR: subSubEventId has strange value:0x" << std::hex << subSubEventId
+                   << std::dec;
+      }
+      processSubSubEvent(reader, subSubEventSize, subSubEventId);
+    }
+    else {  // CTS event
+      processCtsSubSubEvent(reader, subSubEventSize, subSubEventId);
+    }
+
+    //  if (fbDebugMonitorMode) {
+    //    //This address calculation is just for mCBM; will be a problem when using full CBM RICH acceptance
+    //    uint16_t histAddr = ((subSubEventId >> 8) & 0xF) * 18 + ((subSubEventId >> 4) & 0xF) * 2 + (subSubEventId & 0xF);
+    //    fhSubSubEventSize->Fill(histAddr, subSubEventSize);  // Words in a DiRICH
+    //  }
+
+    if ((totalSize == hubSize && !isLast) || (totalSize != hubSize && isLast)) {
+      if (isLog()) LOG(error) << "ERROR: totalSize OR isLast is wrong";
+    }
+
+    if (totalSize >= hubSize || isLast) break;
+  }
+
+  // read last words
+  int lastWordsCounter = 0;
+  while (true) {
+    lastWordsCounter++;
+    word = reader.NextWord();
+    if (isLog()) LOG(debug4) << getLogHeader(reader);
+    if (word == 0x600dda7a) break;
+    if (lastWordsCounter >= 7) {
+      LOG(error) << getLogHeader(reader)
+                 << "CbmMcbm2018UnpackerAlgoRich::ProcessHubBlock() ERROR: No word == 0x600dda7a";
+    }
+  }
+}
+
+void CbmRichUnpackAlgo::processCtsSubSubEvent(CbmRichUnpackAlgoMicrosliceReader& reader, uint32_t subSubEventSize,
+                                              uint32_t subSubEventId)
+{
+  uint32_t word         = reader.NextWord();
+  uint32_t ctsState     = word & 0xffff;                                                                   // 16 bits
+  uint32_t nofInputs    = (word >> 16) & 0xf;                                                              // 4 bits
+  uint32_t nofTrigCh    = (word >> 20) & 0x1f;                                                             // 5 bits
+  uint32_t inclLastIdle = (word >> 25) & 0x1;                                                              // 1 bit
+  uint32_t inclTrigInfo = (word >> 26) & 0x1;                                                              // 1 bit
+  uint32_t inclTime     = (word >> 27) & 0x1;                                                              // 1 bit
+  uint32_t ETM          = (word >> 28) & 0x3;                                                              // 2 bits
+  uint32_t ctsInfoSize  = 2 * nofInputs + 2 * nofTrigCh + 2 * inclLastIdle + 3 * inclTrigInfo + inclTime;  // in words
+  switch (ETM) {
+    case 0: break;
+    case 1: ctsInfoSize += 1; break;
+    case 2: ctsInfoSize += 4; break;
+    case 3: break;
+  }
+  if (isLog()) LOG(debug4) << getLogHeader(reader) << "CTS ctsState:" << ctsState << " ctsInfoSize:" << ctsInfoSize;
+  for (uint32_t i = 0; i < ctsInfoSize; i++) {
+    word = reader.NextWord();  // do nothing?
+    if (isLog()) LOG(debug4) << getLogHeader(reader) << "CTS info words";
+  }
+  int nofTimeWords = subSubEventSize - ctsInfoSize - 1;
+  processSubSubEvent(reader, nofTimeWords, subSubEventId);
+}
+
+void CbmRichUnpackAlgo::processSubSubEvent(CbmRichUnpackAlgoMicrosliceReader& reader, int nofTimeWords,
+                                           uint32_t subSubEventId)
+{
+  // Store if a certain TDC word type was analysed,
+  // later one can check if the order is correct
+  bool wasHeader   = false;
+  bool wasEpoch    = false;
+  bool wasTime     = false;
+  bool wasTrailer  = false;
+  uint32_t epoch   = 0;  // store last epoch obtained in sub-sub-event
+  bool errorInData = false;
+
+  // Store last raising edge time for each channel or -1. if no time
+  // this array is used to match raising and falling edges
+  std::vector<double> raisingTime(33, -1.);
+
+  for (int i = 0; i < nofTimeWords; i++) {
+    uint32_t word                     = reader.NextWord();
+    CbmRichUnpackAlgoTdcWordType type = CbmRichUnpackAlgoTdcWordReader::GetTdcWordType(word);
+
+    if (type == CbmRichUnpackAlgoTdcWordType::TimeData) {
+      if (!wasHeader || !wasEpoch || wasTrailer) {
+        LOG(error) << getLogHeader(reader) << "illegal position of TDC Time (before header/epoch or after trailer)";
+        errorInData = true;
+        continue;
+      }
+      wasTime = true;
+      processTimeDataWord(reader, i, epoch, word, subSubEventId, raisingTime);
+    }
+    else if (type == CbmRichUnpackAlgoTdcWordType::Epoch) {
+      if (!wasHeader || wasTrailer) {
+        LOG(error) << getLogHeader(reader) << "illegal position of TDC Epoch (before header or after trailer)";
+        errorInData = true;
+        continue;
+      }
+      wasEpoch = true;
+      epoch    = CbmRichUnpackAlgoTdcWordReader::ProcessEpoch(word);
+      if (isLog()) LOG(debug4) << getLogHeader(reader) << "SubSubEv[" << i << "] epoch:" << epoch;
+    }
+    else if (type == CbmRichUnpackAlgoTdcWordType::Header) {
+      if (wasEpoch || wasTime || wasTrailer) {
+        LOG(error) << getLogHeader(reader) << "illegal position of TDC Header (after time/epoch/trailer)";
+        errorInData = true;
+        continue;
+      }
+      wasHeader = true;
+      // uint16_t errorBits = CbmRichUnpackAlgoTdcWordReader::ProcessHeader(word);
+      // ErrorMsg(errorBits, CbmRichUnpackAlgoErrorType::tdcHeader, subSubEventId);
+      if (isLog()) LOG(debug4) << getLogHeader(reader) << "SubSubEv[" << i << "] header";
+    }
+    else if (type == CbmRichUnpackAlgoTdcWordType::Trailer) {
+      if (!wasEpoch || !wasTime || !wasHeader) {
+        LOG(error) << getLogHeader(reader) << "illegal position of TDC Trailer (before time/epoch/header)";
+        errorInData = true;
+        continue;
+      }
+      wasTrailer = true;
+      // uint16_t errorBits = CbmRichUnpackAlgoTdcWordReader::ProcessTrailer(word);
+      // ErrorMsg(errorBits, CbmRichUnpackAlgoErrorType::tdcTrailer, subSubEventId);
+      if (isLog()) LOG(debug4) << getLogHeader(reader) << "SubSubEv[" << i << "] trailer";
+    }
+    else if (type == CbmRichUnpackAlgoTdcWordType::Debug) {
+      // for the moment do nothing
+    }
+    else if (type == CbmRichUnpackAlgoTdcWordType::Error) {
+      LOG(error) << getLogHeader(reader) << "Wrong TDC word!!! marker:" << ((word >> 29) & 0x7);
+      errorInData = true;
+    }
+  }
+
+  if (errorInData) {
+    //TODO:
+  }
+}
+
+void CbmRichUnpackAlgo::processTrbPacket(CbmRichUnpackAlgoMicrosliceReader& reader)
 {
   processMbs(reader, false);  // Current MBS
   processMbs(reader, true);   // Previous MBS
@@ -123,7 +292,7 @@ void CbmRichUnpackAlgo::processTrbPacket(CbmMcbm2018RichMicrosliceReader& reader
   processHubBlock(reader);
 }
 
-void CbmRichUnpackAlgo::processMbs(CbmMcbm2018RichMicrosliceReader& reader, bool isPrev)
+void CbmRichUnpackAlgo::processMbs(CbmRichUnpackAlgoMicrosliceReader& reader, bool isPrev)
 {
   uint32_t word     = reader.NextWord();
   uint32_t mbsNum   = word & 0xffffff;      //24 bits
@@ -134,12 +303,12 @@ void CbmRichUnpackAlgo::processMbs(CbmMcbm2018RichMicrosliceReader& reader, bool
 
   for (uint32_t i = 0; i < nofCtsCh; i++) {
     uint32_t wordEpoch = reader.NextWord();
-    uint32_t epoch     = CbmMcbm2018RichTdcWordReader::ProcessEpoch(wordEpoch);
+    uint32_t epoch     = CbmRichUnpackAlgoTdcWordReader::ProcessEpoch(wordEpoch);
     if (isLog()) LOG(debug4) << getLogHeader(reader) << "MBS ch:" << i << " epoch:" << epoch;
 
     uint32_t wordTime = reader.NextWord();
-    CbmMcbm2018RichTdcTimeData td;
-    CbmMcbm2018RichTdcWordReader::ProcessTimeData(wordTime, td);
+    CbmRichUnpackAlgoTdcTimeData td;
+    CbmRichUnpackAlgoTdcWordReader::ProcessTimeData(wordTime, td);
     if (isLog()) LOG(debug4) << getLogHeader(reader) << "MBS ch:" << i << " " << td.ToString();
 
     double fullTime = calculateTime(epoch, td.fCoarse, td.fFine);
@@ -155,11 +324,11 @@ void CbmRichUnpackAlgo::processMbs(CbmMcbm2018RichMicrosliceReader& reader, bool
 }
 
 // ---- processTimeDataWord ----
-void CbmRichUnpackAlgo::processTimeDataWord(CbmMcbm2018RichMicrosliceReader& reader, int iTdc, uint32_t epoch,
+void CbmRichUnpackAlgo::processTimeDataWord(CbmRichUnpackAlgoMicrosliceReader& reader, int iTdc, uint32_t epoch,
                                             uint32_t tdcWord, uint32_t subSubEventId, std::vector<double>& raisingTime)
 {
-  CbmMcbm2018RichTdcTimeData td;
-  CbmMcbm2018RichTdcWordReader::ProcessTimeData(tdcWord, td);
+  CbmRichUnpackAlgoTdcTimeData td;
+  CbmRichUnpackAlgoTdcWordReader::ProcessTimeData(tdcWord, td);
   double fullTime = calculateTime(epoch, td.fCoarse, td.fFine);
 
 
diff --git a/reco/detectors/rich/unpack/CbmRichUnpackAlgo.h b/reco/detectors/rich/unpack/CbmRichUnpackAlgo.h
index ac52e93e9de36d6134e229817e37178aabc9b579..e87175ca6e0815ff54c969a404e0019efa146ac6 100644
--- a/reco/detectors/rich/unpack/CbmRichUnpackAlgo.h
+++ b/reco/detectors/rich/unpack/CbmRichUnpackAlgo.h
@@ -36,165 +36,165 @@
 #include <memory>
 #include <utility>
 
+enum class CbmRichUnpackAlgoErrorType
+{
+  mtsError,
+  tdcHeader,
+  tdcTrailer,
+  ctsHeader,
+  ctsTrailer,
+  subEventError
+};
 
-class CbmRichUnpackAlgo : public CbmRecoUnpackAlgo<CbmRichDigi> {
+enum class CbmRichUnpackAlgoTdcWordType
+{
+  TimeData,
+  Header,
+  Epoch,
+  Trailer,
+  Debug,
+  Error
+};
+
+class CbmRichUnpackAlgoTdcTimeData {
 public:
-  enum class CbmMcbm2018RichErrorType
+  uint32_t fCoarse  = 0;  // 11 bits
+  uint32_t fEdge    = 0;  // 1 bit
+  uint32_t fFine    = 0;  // 10 bits
+  uint32_t fChannel = 0;  // 7 bits
+
+  std::string ToString()
   {
-    mtsError,
-    tdcHeader,
-    tdcTrailer,
-    ctsHeader,
-    ctsTrailer,
-    subEventError
-  };
-
-  enum class CbmMcbm2018RichTdcWordType
+    std::stringstream stream;
+    stream << "channel:" << fChannel << " coarse:" << fCoarse << " fine:" << fFine
+           << " edge:" << ((fEdge == 1) ? "R" : "F");
+    return stream.str();
+  }
+
+  bool IsRisingEdge() { return (fEdge == 1); }
+};
+
+class CbmRichUnpackAlgoTdcWordReader {
+public:
+  static CbmRichUnpackAlgoTdcWordType GetTdcWordType(uint32_t tdcWord)
   {
-    TimeData,
-    Header,
-    Epoch,
-    Trailer,
-    Debug,
-    Error
-  };
-
-  class CbmMcbm2018RichTdcTimeData {
-  public:
-    uint32_t fCoarse  = 0;  // 11 bits
-    uint32_t fEdge    = 0;  // 1 bit
-    uint32_t fFine    = 0;  // 10 bits
-    uint32_t fChannel = 0;  // 7 bits
-
-    std::string ToString()
-    {
-      std::stringstream stream;
-      stream << "channel:" << fChannel << " coarse:" << fCoarse << " fine:" << fFine
-             << " edge:" << ((fEdge == 1) ? "R" : "F");
-      return stream.str();
+    uint32_t tdcTimeDataMarker = (tdcWord >> 31) & 0x1;  // 1 bit
+    uint32_t tdcMarker         = (tdcWord >> 29) & 0x7;  // 3 bits
+
+    if (tdcTimeDataMarker == 0x1) {
+      // TODO: I also include tdcMarker == 0x5, some tdc time data words have this marker. Is it correct?
+      if (tdcMarker == 0x4 || tdcMarker == 0x5) { return CbmRichUnpackAlgoTdcWordType::TimeData; }
+      else {
+        return CbmRichUnpackAlgoTdcWordType::Error;
+      }
     }
 
-    bool IsRisingEdge() { return (fEdge == 1); }
-  };
-
-  class CbmMcbm2018RichTdcWordReader {
-  public:
-    static CbmMcbm2018RichTdcWordType GetTdcWordType(uint32_t tdcWord)
-    {
-      uint32_t tdcTimeDataMarker = (tdcWord >> 31) & 0x1;  // 1 bit
-      uint32_t tdcMarker         = (tdcWord >> 29) & 0x7;  // 3 bits
-
-      if (tdcTimeDataMarker == 0x1) {
-        // TODO: I also include tdcMarker == 0x5, some tdc time data words have this marker. Is it correct?
-        if (tdcMarker == 0x4 || tdcMarker == 0x5) { return CbmMcbm2018RichTdcWordType::TimeData; }
-        else {
-          return CbmMcbm2018RichTdcWordType::Error;
-        }
-      }
+    if (tdcMarker == 0x0) return CbmRichUnpackAlgoTdcWordType::Trailer;
+    if (tdcMarker == 0x1) return CbmRichUnpackAlgoTdcWordType::Header;
+    if (tdcMarker == 0x2) return CbmRichUnpackAlgoTdcWordType::Debug;
+    if (tdcMarker == 0x3) return CbmRichUnpackAlgoTdcWordType::Epoch;
 
-      if (tdcMarker == 0x0) return CbmMcbm2018RichTdcWordType::Trailer;
-      if (tdcMarker == 0x1) return CbmMcbm2018RichTdcWordType::Header;
-      if (tdcMarker == 0x2) return CbmMcbm2018RichTdcWordType::Debug;
-      if (tdcMarker == 0x3) return CbmMcbm2018RichTdcWordType::Epoch;
+    return CbmRichUnpackAlgoTdcWordType::Error;
+  }
 
-      return CbmMcbm2018RichTdcWordType::Error;
-    }
+  static void ProcessTimeData(uint32_t tdcWord, CbmRichUnpackAlgoTdcTimeData& outData)
+  {
+    outData.fCoarse  = static_cast<uint32_t>(tdcWord & 0x7ff);          // 11 bits
+    outData.fEdge    = static_cast<uint32_t>((tdcWord >> 11) & 0x1);    // 1 bit
+    outData.fFine    = static_cast<uint32_t>((tdcWord >> 12) & 0x3ff);  // 10 bits
+    outData.fChannel = static_cast<uint32_t>((tdcWord >> 22) & 0x7f);   // 7 bits
+  }
 
-    static void ProcessTimeData(uint32_t tdcWord, CbmMcbm2018RichTdcTimeData& outData)
-    {
-      outData.fCoarse  = static_cast<uint32_t>(tdcWord & 0x7ff);          // 11 bits
-      outData.fEdge    = static_cast<uint32_t>((tdcWord >> 11) & 0x1);    // 1 bit
-      outData.fFine    = static_cast<uint32_t>((tdcWord >> 12) & 0x3ff);  // 10 bits
-      outData.fChannel = static_cast<uint32_t>((tdcWord >> 22) & 0x7f);   // 7 bits
-    }
+  static uint32_t ProcessEpoch(uint32_t tdcWord) { return static_cast<uint32_t>(tdcWord & 0xfffffff); }
 
-    static uint32_t ProcessEpoch(uint32_t tdcWord) { return static_cast<uint32_t>(tdcWord & 0xfffffff); }
+  static uint16_t ProcessHeader(uint32_t tdcWord)
+  {
+    // for the moment just extract error bits
+    return static_cast<uint16_t>(tdcWord & 0xff);  //8 bits
+  }
 
-    static uint16_t ProcessHeader(uint32_t tdcWord)
-    {
-      // for the moment just extract error bits
-      return static_cast<uint16_t>(tdcWord & 0xff);  //8 bits
-    }
+  static uint16_t ProcessTrailer(uint32_t tdcWord)
+  {
+    // for the moment just extract error bits
+    return static_cast<uint16_t>(tdcWord & 0xffff);
+  }
 
-    static uint16_t ProcessTrailer(uint32_t tdcWord)
-    {
-      // for the moment just extract error bits
-      return static_cast<uint16_t>(tdcWord & 0xffff);
-    }
+  static void ProcessDebug(uint32_t tdcWord)
+  {
+    LOG(debug4) << "ProcessDebug is not implemented. tdcWord:0x" << std::hex << tdcWord << std::dec;
+    // for the moment do nothing
+  }
+};
 
-    static void ProcessDebug(uint32_t tdcWord)
-    {
-      LOG(debug4) << "ProcessDebug is not implemented. tdcWord:0x" << std::hex << tdcWord << std::dec;
-      // for the moment do nothing
-    }
-  };
-
-  class CbmMcbm2018RichMicrosliceReader {
-  private:
-    const uint8_t* fData = nullptr;
-    size_t fSize         = 0;
-    size_t fOffset       = 0;  // offset in bytes
-    size_t fWordCounter  = 0;
-    uint32_t fCurWord;
-
-  public:
-    void SetData(const uint8_t* data, size_t size)
-    {
-      fData        = data;
-      fSize        = size;
-      fOffset      = 0;
-      fWordCounter = 0;
-      fCurWord     = 0;
-    }
+class CbmRichUnpackAlgoMicrosliceReader {
+private:
+  const uint8_t* fData = nullptr;
+  size_t fSize         = 0;
+  size_t fOffset       = 0;  // offset in bytes
+  size_t fWordCounter  = 0;
+  uint32_t fCurWord;
 
-    const uint8_t* GetData() { return fData; }
+public:
+  void SetData(const uint8_t* data, size_t size)
+  {
+    fData        = data;
+    fSize        = size;
+    fOffset      = 0;
+    fWordCounter = 0;
+    fCurWord     = 0;
+  }
 
-    size_t GetSize() { return fSize; }
+  const uint8_t* GetData() { return fData; }
 
-    size_t GetOffset() { return fOffset; }
+  size_t GetSize() { return fSize; }
 
-    size_t GetWordCounter() { return fWordCounter; }
+  size_t GetOffset() { return fOffset; }
 
-    uint32_t GetCurWord() { return fCurWord; }
+  size_t GetWordCounter() { return fWordCounter; }
 
-    std::string GetWordAsHexString(uint32_t word)
-    {
-      std::stringstream stream;
-      stream << "0x" << std::setfill('0') << std::setw(sizeof(uint32_t) * 2) << std::hex << word;
-      return stream.str();
-    }
+  uint32_t GetCurWord() { return fCurWord; }
 
-    uint32_t NextWord()
-    {
-      //mRichSupport::SwapBytes(4, fData + fOffset);
-      //Int_t* dataPtr = (Int_t*) (fData + fOffset);
-      uint32_t i = ((uint32_t*) (fData + fOffset))[0];
-      //swap bytes
-      i = (i >> 24) | ((i << 8) & 0x00FF0000) | ((i >> 8) & 0x0000FF00) | (i << 24);
-      //i = ((i&0xFF)<<24) | (((i>>8)&0xFF)<<16) |   (((i>>16)&0xFF)<<8) | (((i>>24)&0xFF)<<0);
-
-      fOffset += 4;
-      fWordCounter++;
-      fCurWord = i;
-      //return (Int_t)(dataPtr[0]);
-      return i;
-    }
+  std::string GetWordAsHexString(uint32_t word)
+  {
+    std::stringstream stream;
+    stream << "0x" << std::setfill('0') << std::setw(sizeof(uint32_t) * 2) << std::hex << word;
+    return stream.str();
+  }
 
-    bool IsNextPadding()
-    {
-      uint32_t nextWord = ((uint32_t*) (fData + fOffset))[0];
-      if (nextWord == 0xffffffff) return true;
-      return false;
-    }
+  uint32_t NextWord()
+  {
+    //mRichSupport::SwapBytes(4, fData + fOffset);
+    //Int_t* dataPtr = (Int_t*) (fData + fOffset);
+    uint32_t i = ((uint32_t*) (fData + fOffset))[0];
+    //swap bytes
+    i = (i >> 24) | ((i << 8) & 0x00FF0000) | ((i >> 8) & 0x0000FF00) | (i << 24);
+    //i = ((i&0xFF)<<24) | (((i>>8)&0xFF)<<16) |   (((i>>16)&0xFF)<<8) | (((i>>24)&0xFF)<<0);
+
+    fOffset += 4;
+    fWordCounter++;
+    fCurWord = i;
+    //return (Int_t)(dataPtr[0]);
+    return i;
+  }
 
-    bool IsLastSubSubEvent(uint32_t subSubEventSize)
-    {
-      uint32_t i = ((uint32_t*) (fData + fOffset + 4 * subSubEventSize))[0];
-      i          = (i >> 24) | ((i << 8) & 0x00ff0000) | ((i >> 8) & 0x0000ff00) | (i << 24);
-      if (i == 0x00015555) return true;
-      return false;
-    }
-  };
+  bool IsNextPadding()
+  {
+    uint32_t nextWord = ((uint32_t*) (fData + fOffset))[0];
+    if (nextWord == 0xffffffff) return true;
+    return false;
+  }
+
+  bool IsLastSubSubEvent(uint32_t subSubEventSize)
+  {
+    uint32_t i = ((uint32_t*) (fData + fOffset + 4 * subSubEventSize))[0];
+    i          = (i >> 24) | ((i << 8) & 0x00ff0000) | ((i >> 8) & 0x0000ff00) | (i << 24);
+    if (i == 0x00015555) return true;
+    return false;
+  }
+};
+
+class CbmRichUnpackAlgo : public CbmRecoUnpackAlgo<CbmRichDigi> {
+public:
   /** @brief Create the Cbm Trd Unpack AlgoBase object */
   CbmRichUnpackAlgo();
 
@@ -233,7 +233,7 @@ protected:
   /** @brief Function that allows special calls during Finish in the derived algos */
   virtual void finishDerived() { return; }
 
-  std::string getLogHeader(CbmMcbm2018RichMicrosliceReader& reader);
+  std::string getLogHeader(CbmRichUnpackAlgoMicrosliceReader& reader);
 
   Int_t getPixelUID(Int_t fpgaID, Int_t ch) const
   {
@@ -267,17 +267,18 @@ protected:
 
   bool isLog();
 
-  void processTrbPacket(CbmMcbm2018RichMicrosliceReader& reader);
+  void processTrbPacket(CbmRichUnpackAlgoMicrosliceReader& reader);
 
-  void processMbs(CbmMcbm2018RichMicrosliceReader& reader, bool isPrev);
+  void processMbs(CbmRichUnpackAlgoMicrosliceReader& reader, bool isPrev);
 
-  void processHubBlock(CbmMcbm2018RichMicrosliceReader& reader);
+  void processHubBlock(CbmRichUnpackAlgoMicrosliceReader& reader);
 
-  void processCtsSubSubEvent(CbmMcbm2018RichMicrosliceReader& reader, uint32_t subSubEventSize, uint32_t subSubEventId);
+  void processCtsSubSubEvent(CbmRichUnpackAlgoMicrosliceReader& reader, uint32_t subSubEventSize,
+                             uint32_t subSubEventId);
 
-  void processSubSubEvent(CbmMcbm2018RichMicrosliceReader& reader, int nofTimeWords, uint32_t subSubEventId);
+  void processSubSubEvent(CbmRichUnpackAlgoMicrosliceReader& reader, int nofTimeWords, uint32_t subSubEventId);
 
-  void processTimeDataWord(CbmMcbm2018RichMicrosliceReader& reader, int iTdc, uint32_t epoch, uint32_t tdcWord,
+  void processTimeDataWord(CbmRichUnpackAlgoMicrosliceReader& reader, int iTdc, uint32_t epoch, uint32_t tdcWord,
                            uint32_t subSubEventId, std::vector<double>& raisingTime);
 
   /**