diff --git a/.clang-format b/.clang-format
index b9adbf55848311365da9464ec060dbe9ba40716c..9c1a5ce060597b1f37947b39b99de636fa6beb16 100644
--- a/.clang-format
+++ b/.clang-format
@@ -1,58 +1,125 @@
 ---
 AccessModifierOffset: -2
+
 AlignAfterOpenBracket: Align
-#AlignConsecutiveMacros: true
 AlignConsecutiveAssignments: true
+AlignConsecutiveBitFields: true
 AlignConsecutiveDeclarations: false
+#AlignConsecutiveMacros: true
 AlignEscapedNewlines: Right
 AlignOperands: true
 AlignTrailingComments: true
-#AllowAllArgumentsOnNextLine: true
-#AllowAllConstructorInitializersOnNextLine: true
+
+AllowAllArgumentsOnNextLine: false
+AllowAllConstructorInitializersOnNextLine: false
 AllowAllParametersOfDeclarationOnNextLine: false
-AllowShortBlocksOnASingleLine: true
+
+AllowShortBlocksOnASingleLine: Always
 AllowShortCaseLabelsOnASingleLine: true
+AllowShortEnumsOnASingleLine: false
 AllowShortFunctionsOnASingleLine: All
-AllowShortIfStatementsOnASingleLine: true
-#AllowShortLambdasOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: Always
+AllowShortLambdasOnASingleLine: All
 AllowShortLoopsOnASingleLine: false
-AlwaysBreakAfterDefinitionReturnType: None
+
+#AlwaysBreakAfterDefinitionReturnType: None
 AlwaysBreakAfterReturnType: None
 AlwaysBreakBeforeMultilineStrings: false
-AlwaysBreakTemplateDeclarations: true
-BinPackArguments: false
-BinPackParameters: false
+AlwaysBreakTemplateDeclarations: Yes
+
+BinPackArguments: true
+BinPackParameters: true
+
+# Discuss
 BreakBeforeBinaryOperators: NonAssignment
-BreakBeforeBraces: Attach
+
+BreakBeforeBraces: Custom
+BraceWrapping:
+  AfterCaseLabel:        false
+  AfterClass:            false
+  AfterControlStatement: Never
+  AfterEnum:             false
+  AfterFunction:         true
+  AfterNamespace:        true
+  AfterObjCDeclaration:  false
+  AfterStruct:           false
+  AfterUnion:            false
+  AfterExternBlock:      false
+  BeforeCatch:           true
+  BeforeElse:            true
+  BeforeLambdaBody:      false
+  BeforeWhile:           false
+  IndentBraces:          false
+  SplitEmptyFunction:    true
+  SplitEmptyRecord:      true
+  SplitEmptyNamespace:   true
+
 BreakBeforeTernaryOperators: true
 BreakConstructorInitializers: BeforeComma
 BreakInheritanceList: AfterColon
-ColumnLimit: 80
+
+#Discuss
+BreakStringLiterals: true
+
+ColumnLimit: 120
 CompactNamespaces: false
 ConstructorInitializerAllOnOneLineOrOnePerLine: true
 ConstructorInitializerIndentWidth: 2
 ContinuationIndentWidth: 2
 Cpp11BracedListStyle: true
+DeriveLineEnding: false
 DerivePointerAlignment: false
 DisableFormat: false
 ExperimentalAutoDetectBinPacking: false
 FixNamespaceComments: true
-IncludeBlocks: Preserve
+
+# Implement ordering of include statements
+IncludeBlocks: Regroup
+IncludeCategories:
+  - Regex:           '^("|<)Cbm'
+    Priority:        1
+  - Regex:           '^("|<).*slice'
+    Priority:        2
+  - Regex:           '^("|<)Fair'
+    Priority:        3
+  - Regex:           '^("|<)Logger.h'
+    Priority:        3
+  - Regex:           '^("|<)T'
+    Priority:        4
+  - Regex:           '^("|<)Rt'
+    Priority:        4
+  - Regex:           '^("|<)boost'
+    Priority:        5
+  - Regex:           '^<.*[^\.h]>'
+    Priority:        6
+  - Regex:           '^<.*>'
+    Priority:        7
+  - Regex:           '.*'
+    Priority:        8
+
+IndentCaseBlocks: false
 IndentCaseLabels: true
+IndentExternBlock: Indent
+IndentGotoLabels: false
 IndentPPDirectives: None
 IndentWidth: 2
 IndentWrappedFunctionNames: false
+
 KeepEmptyLinesAtTheStartOfBlocks: true
 Language: Cpp
 MaxEmptyLinesToKeep: 2
 NamespaceIndentation: All
 ObjCBinPackProtocolList: Auto
 ObjCBlockIndentWidth: 2
+
+#Discuss Penalties
 PenaltyBreakAssignment: 2
+
 PointerAlignment: Left
 ReflowComments: false
 SortIncludes: true
 SortUsingDeclarations: true
+
 SpaceAfterCStyleCast: true
 #SpaceAfterLogicalNot: true
 SpaceAfterTemplateKeyword: false
@@ -62,13 +129,20 @@ SpaceBeforeCtorInitializerColon: true
 SpaceBeforeInheritanceColon: true
 SpaceBeforeParens: ControlStatements
 SpaceBeforeRangeBasedForLoopColon: true
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyBlock: false
 SpaceInEmptyParentheses: false
 SpacesBeforeTrailingComments: 2
 SpacesInAngles: false
 SpacesInCStyleCastParentheses: false
+SpacesInConditionalStatement: false
+SpacesInContainerLiterals: false
 SpacesInParentheses: false
 SpacesInSquareBrackets: false
+
+Standard: c++11
+
 TabWidth: 8
+UseCRLF: false
 UseTab: Never
-
 ...
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f8631d704c591c762421dd76eb0c70b5abad70e0..abc064355eeb2aaaf1f89eead951c9db74df313d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -88,7 +88,7 @@ CodeFormatCheck:
     - echo "export FAIRROOTPATH=/cvmfs/fairroot.gsi.de/fairroot/\${FAIRROOT_VERSION}_fairsoft-\${FAIRSOFT_VERSION}" >> env.sh
     - echo "export BUILDDIR=$PWD/build" >> env.sh
     - echo "export SOURCEDIR=$PWD" >> env.sh
-    - echo "export PATH=/cvmfs/fairroot.gsi.de/clang-format-8.0.1:\$SIMPATH/bin:$PATH:/cvmfs/it.gsi.de/compiler/llvm/6.0.1/bin/" >> env.sh
+    - echo "export PATH=/cvmfs/fairroot.gsi.de/clang-format-11.0.0/bin:\$SIMPATH/bin:$PATH" >> env.sh
     - echo "export LABEL=format-check_MR-\${CI_MERGE_REQUEST_IID}" >> env.sh
     - echo "export FAIRROOT_FORMAT_BASE=upstream/\${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}" >> env.sh
     - . ./env.sh && ctest -S cmake/scripts/checkformat.cmake -VV
diff --git a/core/base/CMakeLists.txt b/core/base/CMakeLists.txt
index 23d40aeb04a5a04cdb9e48a36a7f9ce9c9a089c2..b67dbdd8c2e080b7e1f46e8aec1bf4077981f380 100644
--- a/core/base/CMakeLists.txt
+++ b/core/base/CMakeLists.txt
@@ -57,6 +57,7 @@ report/CbmLatexReportElement.cxx
 utils/CbmUtils.cxx
 utils/CbmGeometryUtils.cxx
 utils/CbmMediaList.cxx
+utils/CbmFileUtils.cxx
 )
 
 Set(LINKDEF CbmBaseLinkDef.h)
diff --git a/core/base/CbmBaseLinkDef.h b/core/base/CbmBaseLinkDef.h
index d80e17ee00a6cac6ab382dd3341d600e3b1dae5d..d8365ddd8adeca75b01e709fa02d83adda4648b4 100644
--- a/core/base/CbmBaseLinkDef.h
+++ b/core/base/CbmBaseLinkDef.h
@@ -73,4 +73,6 @@
 // can not read the file with the CbmMediaList object. For other platforms there is no
 // problem without the line. So generate the correct streamer info in any way.
 #pragma link C++ class std::pair < TString, TString>;
+
+#pragma link C++ function Cbm::File::IsRootFile( string );
 #endif
diff --git a/core/base/utils/CbmFileUtils.cxx b/core/base/utils/CbmFileUtils.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..af4b150a407c65b03903b34160325078da9a55d1
--- /dev/null
+++ b/core/base/utils/CbmFileUtils.cxx
@@ -0,0 +1,99 @@
+#include "CbmFileUtils.h"
+
+#include "FairLogger.h"  // for LOG, info and error
+
+#include "TArchiveFile.h"  // for TArchiveFile
+#include "TFile.h"         // for TFile
+#include "TObjArray.h"
+
+#include <string>  // for string, find, substr
+
+#include <sys/stat.h>  // for stcuct stat
+
+
+namespace Cbm
+{
+  namespace File
+  {
+    bool IsRootFile(std::string filename)
+    {
+      // Currently plain root files and root files stored in a zip file are supported.
+      // The destiction between the two is a "#" in the filename string  which separates the
+      // name of the zip file from the name of the root file which is inside the zip file.
+      // In case the filename contains a hash (e.g. multi.zip#file.root) the hash
+      // separates the name of a zipfile (multi.zip) which contains the real root file
+      // (file.root).
+      // This nameing convention (e.g. multi.zip#file.root) is sed by ROOT.
+
+      // If a filename string contains a hash "#"
+      // split the string at the # in the name of the zipfile and
+      // the name of the contained root file.
+      std::string checkFilename {""};
+      std::string membername {""};
+      std::size_t found = filename.find("#");
+      if (found != std::string::npos) {
+        checkFilename = filename.substr(0, found);
+        membername    = filename.substr(found + 1);
+      }
+      else {
+        checkFilename = filename;
+      }
+
+      bool wasfound = kFALSE;
+
+      // Check if the file exist
+      // In case of a root file contained in a zip archive check if the zip file
+      // exist
+      struct stat buffer;
+      if (stat(checkFilename.c_str(), &buffer) == 0) { wasfound = kTRUE; }
+      else {
+        wasfound = kFALSE;
+        LOG(error) << "Input File " << checkFilename << " not found";
+      }
+
+      // In case of a zip archive check if the archive contains the root file
+      if (membername.compare("") != 0) {
+        TFile* fzip = TFile::Open(checkFilename.c_str());
+        if (fzip->IsOpen()) {
+          TArchiveFile* archive = fzip->GetArchive();
+          if (archive) {
+            TObjArray* members = archive->GetMembers();
+            if (members->FindObject(membername.c_str()) == 0) {
+              LOG(error) << "File " << membername << " not found in zipfile " << checkFilename;
+              wasfound = kFALSE;
+            }
+            else {
+              LOG(info) << "File " << membername << " found in zipfile " << checkFilename;
+              wasfound = kTRUE;
+            }
+          }
+          else {
+            LOG(error) << "Zipfile " << checkFilename << " does not contain an archive";
+            wasfound = kFALSE;
+          }
+          fzip->Close();
+          delete fzip;
+        }
+        else {
+          LOG(error) << "Could not open zipfile " << checkFilename;
+          wasfound = kFALSE;
+        }
+      }
+      else {
+        TFile* rootfile = TFile::Open(checkFilename.c_str());
+        if (rootfile->IsOpen()) {
+          LOG(info) << "File " << checkFilename << " is a ROOT file.";
+          wasfound = kTRUE;
+        }
+        else {
+          LOG(error) << "File " << checkFilename << " is no ROOT file.";
+          wasfound = kFALSE;
+        }
+        rootfile->Close();
+        delete rootfile;
+      }
+
+      return wasfound;
+    }
+  }  // namespace File
+}  // namespace Cbm
diff --git a/core/base/utils/CbmFileUtils.h b/core/base/utils/CbmFileUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..a1be2369aa80f978f2f32255f711e6ee5bd73c60
--- /dev/null
+++ b/core/base/utils/CbmFileUtils.h
@@ -0,0 +1,19 @@
+#ifndef CBMFILEUTILS_H_
+#define CBMFILEUTILS_H_
+
+#include <string>  // for string
+
+namespace Cbm
+{
+  namespace File
+  {
+    /**
+     * \brief Check if a the file exist and is a root file
+     * \param[in] filename The filename of the file to be checked
+     * \value     true if file is an existing root file, 0 in any other case
+    **/
+    bool IsRootFile(std::string filename);
+  }  //namespace File
+}  // namespace Cbm
+
+#endif /* CBMFILEUTILS_H_ */
diff --git a/core/data/tof/CbmTofDetectorId_v21a.cxx b/core/data/tof/CbmTofDetectorId_v21a.cxx
index 78f9372086f9d4c2389fe52ac1926e6f90f68c6f..4a60a162d80b588e297f52708e35295fd94fd67e 100644
--- a/core/data/tof/CbmTofDetectorId_v21a.cxx
+++ b/core/data/tof/CbmTofDetectorId_v21a.cxx
@@ -26,7 +26,7 @@ CbmTofDetectorId_v21a::CbmTofDetectorId_v21a()
     if (i == 4) continue;  // ignore side bit
     modulemask |= (maskarray[i] << shiftarray[i]);
   }
-  char prev = std::cout.fill('x');
+  char prev = std::cout.fill();
   std::cout << "<I> V21a module mask 0x" << std::setfill('0') << std::setw(8)
             << std::right << std::hex << modulemask << std::setfill(prev)
             << std::dec << std::endl;
diff --git a/core/detectors/much/CbmMuchGeoScheme.cxx b/core/detectors/much/CbmMuchGeoScheme.cxx
index 1ae081aba677216e3785b5455050271010a29362..f5425451a88eacad4d9a3ae35539ecec4433feff 100644
--- a/core/detectors/much/CbmMuchGeoScheme.cxx
+++ b/core/detectors/much/CbmMuchGeoScheme.cxx
@@ -135,12 +135,19 @@ void CbmMuchGeoScheme::Init(TObjArray* stations, Int_t flag) {
 // -------------------------------------------------------------------------
 void CbmMuchGeoScheme::Init(TString digiFileName, Int_t flag) {
 
-  TFile* oldfile      = gFile;
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
   TFile* file         = new TFile(digiFileName);
   TObjArray* stations = (TObjArray*) file->Get("stations");
   file->Close();
   file->Delete();
-  gFile = oldfile;
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
+
   Init(stations, flag);
 }
 // -------------------------------------------------------------------------
diff --git a/core/detectors/much/CbmMuchSegmentAuto.cxx b/core/detectors/much/CbmMuchSegmentAuto.cxx
index fe08db8a6dd0db67868eedaef168df2988bef567..672ee236bd3fc422f420b670692e7892c9937eae 100644
--- a/core/detectors/much/CbmMuchSegmentAuto.cxx
+++ b/core/detectors/much/CbmMuchSegmentAuto.cxx
@@ -230,13 +230,18 @@ void CbmMuchSegmentAuto::FinishTask() {
     printf("Station%i segmented\n", i + 1);
   }
 
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
   // Save parameters
-  TFile* oldfile = gFile;
   TFile* f       = new TFile(fDigiFileName, "RECREATE");
   fStations->Write("stations", 1);
 
   f->Close();
-  gFile = oldfile;
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
 
   DrawSegmentation();
 
diff --git a/core/detectors/much/CbmMuchSegmentManual.cxx b/core/detectors/much/CbmMuchSegmentManual.cxx
index e6018f93c5f965d328cc9a800963073f71869601..1162c38b47403d4dbf8f122ca98a0e8f369bdcb7 100644
--- a/core/detectors/much/CbmMuchSegmentManual.cxx
+++ b/core/detectors/much/CbmMuchSegmentManual.cxx
@@ -261,13 +261,18 @@ void CbmMuchSegmentManual::SegmentMuch() {
     printf("Station %i segmented\n", iStation + 1);
   }
 
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
   // Save parameters
-  TFile* oldfile = gFile;
   TFile* f       = new TFile(fDigiFileName, "RECREATE");
   fStations->Write("stations", 1);
 
   f->Close();
-  gFile = oldfile;
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
 
   // Draw colored stations
   DrawSegmentation();
diff --git a/core/detectors/much/CbmMuchSegmentSector.cxx b/core/detectors/much/CbmMuchSegmentSector.cxx
index 283587da2ef584780c5c4b973c138add12bc2a1d..24ec4dc9b0a97f144599f28814ec535af40d82bd 100644
--- a/core/detectors/much/CbmMuchSegmentSector.cxx
+++ b/core/detectors/much/CbmMuchSegmentSector.cxx
@@ -144,13 +144,18 @@ void CbmMuchSegmentSector::SegmentMuch() {
     printf("Station %i segmented\n", iStation + 1);
   }
 
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
   // Save parameters
-  TFile* oldfile = gFile;
   TFile* f       = new TFile(fDigiFileName, "RECREATE");
   fStations->Write("stations", 1);
 
   f->Close();
-  gFile = oldfile;
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
 
   DrawSegmentation();
 }
diff --git a/core/field/CbmBsField.cxx b/core/field/CbmBsField.cxx
index fbe724947ba0326091ab20c755703a3f68d70c2a..c12c858d8ebc0edddd8ce68bf1dc8db1030637e4 100644
--- a/core/field/CbmBsField.cxx
+++ b/core/field/CbmBsField.cxx
@@ -182,16 +182,25 @@ void CbmBsField::CalculateMapFromBs(Int_t pNx, Int_t pNy, Int_t pNz) {
 
 void CbmBsField::writeBsRootfile(const char* name)  // Write Field Splined
 {
-  TFile* oldfile = gFile;
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
   TFile* f       = new TFile(name, "RECREATE");
   this->Write();
   f->Close();
-  if (oldfile) oldfile->cd();
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
 }
 
 void CbmBsField::readBsRootfile(const char* name)  // Read  Field Splined
 {
-  TFile* oldfile = gFile;
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
   TFile* f       = new TFile(name, "READ");
   if (f->IsZombie()) {
     cout << "-E- CbmBsField::readBsRootfile:  can not read from file: " << endl;
@@ -219,7 +228,10 @@ void CbmBsField::readBsRootfile(const char* name)  // Read  Field Splined
   fZ = new TArrayF(*fnew->GetZ());
 
   f->Close();
-  if (oldfile) oldfile->cd();
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
 
   UX1 = fX->GetArray();
   UX2 = fY->GetArray();
diff --git a/core/field/CbmFieldMap.cxx b/core/field/CbmFieldMap.cxx
index 59c831e7c4ba2cc00163d9853516e7c0da71ad3d..c3a7f90cf6df05e04d7aab913849790d8b377c30 100644
--- a/core/field/CbmFieldMap.cxx
+++ b/core/field/CbmFieldMap.cxx
@@ -536,11 +536,18 @@ void CbmFieldMap::WriteAsciiFile(const char* fileName) {
 void CbmFieldMap::WriteRootFile(const char* fileName, const char* mapName) {
 
   CbmFieldMapData* data = new CbmFieldMapData(mapName, *this);
-  TFile* oldFile        = gFile;
+
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
   TFile* file           = new TFile(fileName, "RECREATE");
   data->Write();
   file->Close();
-  if (oldFile) oldFile->cd();
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
 }
 // ------------------------------------------------------------------------
 
@@ -696,9 +703,9 @@ void CbmFieldMap::ReadAsciiFile(const char* fileName) {
 
 // -------------   Read field map from ROOT file (private)  ---------------
 void CbmFieldMap::ReadRootFile(const char* fileName, const char* mapName) {
-
-  // Store gFile pointer
-  TFile* oldFile = gFile;
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
 
   // Open root file
   LOG(info) << "CbmFieldMap: Reading field map from ROOT file " << fileName;
@@ -723,7 +730,10 @@ void CbmFieldMap::ReadRootFile(const char* fileName, const char* mapName) {
   // Close the root file and delete the data object
   file->Close();
   delete data;
-  if (oldFile) oldFile->cd();
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
 }
 // ------------------------------------------------------------------------
 
diff --git a/core/field/CbmFieldMapDistorted.cxx b/core/field/CbmFieldMapDistorted.cxx
index 112ee0b9ce20660c1c3a1060b859be7701a0fd8e..afd117a1d1809c6b3d2a43d53076365e80d873e3 100644
--- a/core/field/CbmFieldMapDistorted.cxx
+++ b/core/field/CbmFieldMapDistorted.cxx
@@ -265,8 +265,10 @@ void CbmFieldMapDistorted::SetFromParent(FairField* field) {
 
 // -----------   Read Distortion Formulas from Distortion File   ------------------------------------------
 void CbmFieldMapDistorted::ReadDistortionInformation(const char* filename) {
-  TFile* filesave = gFile;
-  gFile           = 0;
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
   if (filename) {
     if (strlen(filename)) { fDistortionFilename = filename; }
   }
@@ -299,13 +301,16 @@ void CbmFieldMapDistorted::ReadDistortionInformation(const char* filename) {
       }
     }
   }
-  gFile = filesave;
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
 }
 
 // -----------   Write Distortion Formulas to Distortion File   ------------------------------------------
 void CbmFieldMapDistorted::WriteDistortionInformation(const char* filename) {
-  TFile* filesave = gFile;
-  gFile           = 0;
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
 
   if (filename) {
     if (strlen(filename)) { fDistortionFilename = filename; }
@@ -336,7 +341,9 @@ void CbmFieldMapDistorted::WriteDistortionInformation(const char* filename) {
       }
     }
   }
-  gFile = filesave;
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
 }
 
 // ---------------Getter and Setter for Distortion Formulas------------------------------
diff --git a/external/InstallAnalysisTreeQA.cmake b/external/InstallAnalysisTreeQA.cmake
index 42a1391dbd670abb4fe5dc3a601738f5d4a2c709..1376465a1a9d2ee450497c5962e01a8ad6755ebf 100644
--- a/external/InstallAnalysisTreeQA.cmake
+++ b/external/InstallAnalysisTreeQA.cmake
@@ -29,7 +29,7 @@ ExternalProject_Add(ANALYSISTREEQA
         -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
         -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
         -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}
-        -DCMAKE_CXX_STANDARD=11
+        -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
         -DROOTSYS=${SIMPATH}
         -DBOOST_ROOT=${SIMPATH}
         -DBoost_NO_BOOST_CMAKE=ON
diff --git a/external/InstallParameter.cmake b/external/InstallParameter.cmake
index 4b4bfed9ca947b8b914c62f89391582b5ff0fb17..21e1c39afa331e3e615493f8f9f4516f9d5107c1 100644
--- a/external/InstallParameter.cmake
+++ b/external/InstallParameter.cmake
@@ -1,4 +1,4 @@
-set(PARAMETER_VERSION 884ac67bbc782e6862fccdeb413f8b11b83124ba)
+set(PARAMETER_VERSION 68f0b16c6edace4faaa09f460682173772081976)
 
 set(PARAMETER_SRC_URL "https://git.cbm.gsi.de/CbmSoft/cbmroot_parameter.git")
 
diff --git a/fles/mcbm2018/CMakeLists.txt b/fles/mcbm2018/CMakeLists.txt
index 5bdf6aca6523d969415c01d6a73d71bb97b36bff..5a975a8e91ddf7d125fe57dd6656720c27ff678b 100644
--- a/fles/mcbm2018/CMakeLists.txt
+++ b/fles/mcbm2018/CMakeLists.txt
@@ -130,6 +130,9 @@ Set(SRCS
 
    tasks/CbmMcbmCheckTimingAlgo.cxx
    tasks/CbmMcbmCheckTimingTask.cxx
+
+   tasks/CbmMcbmSpillFindAlgo.cxx
+   tasks/CbmMcbmSpillFindTask.cxx
 )
 
 If(_UINT8_T_EXIST)
diff --git a/fles/mcbm2018/CbmFlibMcbm2018LinkDef.h b/fles/mcbm2018/CbmFlibMcbm2018LinkDef.h
index c19aaf4e36d19a6f48d9eb5c3c9d915406fee443..f4570ee2e4ebcbf358d397228b897b9610758711 100644
--- a/fles/mcbm2018/CbmFlibMcbm2018LinkDef.h
+++ b/fles/mcbm2018/CbmFlibMcbm2018LinkDef.h
@@ -77,4 +77,7 @@
 #pragma link C++ class CbmMcbmCheckTimingAlgo + ;
 #pragma link C++ class CbmMcbmCheckTimingTask + ;
 
+#pragma link C++ class CbmMcbmSpillFindAlgo + ;
+#pragma link C++ class CbmMcbmSpillFindTask + ;
+
 #endif
diff --git a/fles/mcbm2018/CbmMcbm2018Source.cxx b/fles/mcbm2018/CbmMcbm2018Source.cxx
index 0db535ca17644197346095a646ebb37164b7605d..3e42ec0d9cae42ec51812f1eb158e3869e012b4f 100644
--- a/fles/mcbm2018/CbmMcbm2018Source.cxx
+++ b/fles/mcbm2018/CbmMcbm2018Source.cxx
@@ -117,6 +117,73 @@ Bool_t CbmMcbm2018Source::Init() {
                   fTimeSliceMetaDataArray,
                   fbWriteOutput);
 
+  /// Single spill or spills range unpacking
+  /// => Obtain the start and stop TS indices for the TS loop from user supplied vectors
+  /// => Three possibilities linked to output of CbmMcbmSpillFindAlgo,
+  ///    choice controlled by fuFlagSpillStart
+  ///    - Beginning of the spill break
+  ///    - Middle of the spill break
+  ///    - End of the spill break
+  if (0 <= fiUnpSpillIdxStart) {
+    switch (fuFlagSpillStart) {
+      case 0: {
+        /// 0 = Break begin
+        if (fvuSpillBreakBegTs.size() - 1 <= fiUnpSpillIdxStop) {
+          LOG(warning) << "Chosen last spill index larger than spills contained in chosen spill start vector: "
+                       << fiUnpSpillIdxStop << " VS " << fvuSpillBreakBegTs.size() - 1;
+          if (fiUnpSpillIdxStart < fvuSpillBreakBegTs.size() - 1) {
+            fiUnpSpillIdxStop = fvuSpillBreakBegTs.size() - 2;
+            LOG(warning) << "Using last possible spill instead as final one";
+          }  // if( fiUnpSpillIdxStart < fvuSpillBreakBegTs.size() - 1 )
+          else
+            LOG(fatal) << "Start index also too large, exiting";
+        }  // if( fvuSpillBreakBegTs.size() - 1 <= fiUnpSpillIdxStop )
+
+        fuSpillBegTs = fvuSpillBreakBegTs[fiUnpSpillIdxStart];     //!
+        fuSpillEndTs = fvuSpillBreakBegTs[fiUnpSpillIdxStop + 1];  //!
+        break;
+      }
+      case 1: {
+        /// 1 = Break middle
+        if (fvuSpillBreakMidTs.size() - 1 <= fiUnpSpillIdxStop) {
+          LOG(warning) << "Chosen last spill index larger than spills contained in chosen spill start vector: "
+                       << fiUnpSpillIdxStop << " VS " << fvuSpillBreakMidTs.size() - 1;
+          if (fiUnpSpillIdxStart < fvuSpillBreakMidTs.size() - 1) {
+            fiUnpSpillIdxStop = fvuSpillBreakMidTs.size() - 2;
+            LOG(warning) << "Using last possible spill instead as final one";
+          }  // if( fiUnpSpillIdxStart < fvuSpillBreakMidTs.size() - 1 )
+          else
+            LOG(fatal) << "Start index also too large, exiting";
+        }  // if( fvuSpillBreakMidTs.size() - 1 <= fiUnpSpillIdxStop )
+
+        fuSpillBegTs = fvuSpillBreakMidTs[fiUnpSpillIdxStart];     //!
+        fuSpillEndTs = fvuSpillBreakMidTs[fiUnpSpillIdxStop + 1];  //!
+        break;
+      }
+      case 2: {
+        /// 2 = Break end
+        if (fvuSpillBreakEndTs.size() - 1 <= fiUnpSpillIdxStop) {
+          LOG(warning) << "Chosen last spill index larger than spills contained in chosen spill start vector: "
+                       << fiUnpSpillIdxStop << " VS " << fvuSpillBreakEndTs.size() - 1;
+          if (fiUnpSpillIdxStart < fvuSpillBreakEndTs.size() - 1) {
+            fiUnpSpillIdxStop = fvuSpillBreakEndTs.size() - 2;
+            LOG(warning) << "Using last possible spill instead as final one";
+          }  // if( fiUnpSpillIdxStart < fvuSpillBreakEndTs.size() - 1 )
+          else
+            LOG(fatal) << "Start index also too large, exiting";
+        }  // if( fvuSpillBreakEndTs.size() - 1 <= fiUnpSpillIdxStop )
+
+        fuSpillBegTs = fvuSpillBreakEndTs[fiUnpSpillIdxStart];     //!
+        fuSpillEndTs = fvuSpillBreakEndTs[fiUnpSpillIdxStop + 1];  //!
+        break;
+      }
+      default: {
+        LOG(fatal) << "Unknown spill start point option: " << fuFlagSpillStart;
+        break;
+      }
+    }  // switch( fuFlagSpillStart )
+  }    // if (0 <= fiUnpSpillIdxStart)
+
   return kTRUE;
 }
 
@@ -248,34 +315,51 @@ Int_t CbmMcbm2018Source::FillBuffer() {
           }  // for( auto it = it_list.first; it != it_list.second; ++it )
         }    // else of if( it == fUnpackers.end() )
       }      // for (size_t c {0}; c < ts.num_components(); c++)
-    }        // if( 1 == fTSCounter )
-
-    /// Apply TS throttling as set by user (default = 1 => no throttling)
-    if (0 == tsIndex % fuTsReduction) {
-      for (auto itUnp = fUnpackersToRun.begin(); itUnp != fUnpackersToRun.end();
-           ++itUnp) {
-        (*itUnp)->DoUnpack(ts, 0);
-      }  // for( auto itUnp = fUnpackersToRun.begin(); itUnp != fUnpackersToRun.end(); ++ itUnp )
-    }    // if( 0 == tsIndex % fuTsReduction )
 
-    /// Save the TimeSlice meta-data for access by higher level tasks
-    if (fTSCounter == 1) {
+      /// Compute and store the timeslice and microslices properties
       auto nMsInTs = ts.num_core_microslices();
-      if (nMsInTs > 1) {
+      if (nMsInTs > 2) {
         // This assumes that we have a component 0 and component independent ms/ts settings!
-        auto msDescA      = ts.descriptor(0, 0);
-        auto msDescB      = ts.descriptor(0, 1);
+        auto msDescA      = ts.descriptor(0, 1);
+        auto msDescB      = ts.descriptor(0, 2);
         auto msLength     = msDescB.idx - msDescA.idx;
         fTSLength         = msLength * nMsInTs;
         fTSOverlappLength = msLength * (ts.num_microslices(0) - nMsInTs);
-      } else {
+        LOG(info) << "CbmMcbm2018Source::FillBuffer() - TS 1 - Calculated "
+                  << "TimesliceMetaData information from microslices Metadata -> "
+                  << "MS length found to be " << msLength << " ns, TS length " << fTSLength
+                  << " ns, and TS overlap length " << fTSOverlappLength << " ns";
+      }
+      else {
         LOG(warning)
           << "CbmMcbm2018Source::FillBuffer() - TS 1 - Calculate "
              "TimesliceMetaData information - single microslice timeslices -> "
              "TS duration can not be calculated with the given method. Hence, "
              "TimesliceMetaData duration values are filled with 0";
       }
-    }
+    }  // if( 1 == fTSCounter )
+
+    /// Single spill or spills range unpacking
+    if (0 <= fiUnpSpillIdxStart) {
+      if (tsIndex < fuSpillBegTs) {
+        /// Jump all TS until reaching the first TS in the spill we want to unpack
+        continue;
+      }  // if (tsIndex < fuSpillBegTs)
+      else if (fuSpillEndTs <= tsIndex) {
+        /// Stop when reaching the first TS in the next spill
+        return 1;
+      }  // else if
+    }    // if (0 <= fiUnpSpillIdxStart)
+
+
+    /// Apply TS throttling as set by user (default = 1 => no throttling)
+    if (0 == tsIndex % fuTsReduction) {
+      for (auto itUnp = fUnpackersToRun.begin(); itUnp != fUnpackersToRun.end(); ++itUnp) {
+        (*itUnp)->DoUnpack(ts, 0);
+      }  // for( auto itUnp = fUnpackersToRun.begin(); itUnp != fUnpackersToRun.end(); ++ itUnp )
+    }    // if( 0 == tsIndex % fuTsReduction )
+
+    /// Save the TimeSlice meta-data for access by higher level tasks
     new ((*fTimeSliceMetaDataArray)[fTimeSliceMetaDataArray->GetEntriesFast()])
       TimesliceMetaData(
         ts.descriptor(0, 0).idx, fTSLength, fTSOverlappLength, tsIndex);
diff --git a/fles/mcbm2018/CbmMcbm2018Source.h b/fles/mcbm2018/CbmMcbm2018Source.h
index d0d7e394621d5fd8a32194ae86230a053ee8f856..b78341b13e8085dee1b2b95438f10ef44d89acbb 100644
--- a/fles/mcbm2018/CbmMcbm2018Source.h
+++ b/fles/mcbm2018/CbmMcbm2018Source.h
@@ -77,6 +77,33 @@ public:
     fuTsReduction = uTsReduction;
   }
 
+  void UnpackSingleSpill(Int_t uSpillIdx, UInt_t uSpillStart = 1)
+  {
+    fiUnpSpillIdxStart = uSpillIdx;
+    fiUnpSpillIdxStop  = uSpillIdx;
+    fuFlagSpillStart   = uSpillStart;
+  }
+
+  void UnpackSelectSpills(Int_t uSpillIdxStart, Int_t uSpillIdxStop, UInt_t uSpillStart = 1)
+  {
+    fiUnpSpillIdxStart = uSpillIdxStart;
+    fiUnpSpillIdxStop  = uSpillIdxStop;
+    fuFlagSpillStart   = uSpillStart;
+  }
+
+  void LoadTsListSpillBreakBegin(std::vector<ULong64_t> vTsBeg)
+  {
+    fvuSpillBreakBegTs.assign(vTsBeg.begin(), vTsBeg.end());
+  }
+  void LoadTsListSpillBreakEnd(std::vector<ULong64_t> vTsEnd)
+  {
+    fvuSpillBreakEndTs.assign(vTsEnd.begin(), vTsEnd.end());
+  }
+  void LoadTsListSpillBreakMiddle(std::vector<ULong64_t> vTsMid)
+  {
+    fvuSpillBreakMidTs.assign(vTsMid.begin(), vTsMid.end());
+  }
+
   void SetSubscriberHwm(UInt_t val = 1) { fuSubscriberHwm = val; }
 
   void SetWriteOutputFlag(Bool_t bFlagIn) { fbWriteOutput = bFlagIn; }
@@ -105,6 +132,16 @@ private:
 
   UInt_t fuTsReduction;
 
+  Int_t fiUnpSpillIdxStart = -1;  //! >= 0 means unpack only from this spill
+  Int_t fiUnpSpillIdxStop  = -1;  //! >= 0 means unpack only up to this spill (included)
+  UInt_t fuFlagSpillStart  = 0;   //! 0 = Break begin, 1 = Break middle, 2 = Break end
+  UInt_t fuSpillBegTs      = 0;   //!
+  UInt_t fuSpillEndTs      = 0;   //!
+
+  std::vector<ULong64_t> fvuSpillBreakBegTs = {};  //!
+  std::vector<ULong64_t> fvuSpillBreakEndTs = {};  //!
+  std::vector<ULong64_t> fvuSpillBreakMidTs = {};  //!
+
   std::unique_ptr<fles::TimesliceSource> fSource;  //!
 
   UInt_t fuSubscriberHwm;
diff --git a/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoPsd.cxx b/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoPsd.cxx
index 0b14f1c582ae78b20c848e3dd363bff49723f51f..cdcc1f1cfd86abed19b553b5c7da91749ef676e4 100644
--- a/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoPsd.cxx
+++ b/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoPsd.cxx
@@ -39,9 +39,13 @@ CbmMcbm2018MonitorAlgoPsd::CbmMcbm2018MonitorAlgoPsd()
   ,
   /// From the class itself
   fbMonitorMode(kFALSE)
+  , fbMonitorChanMode(kFALSE)
+  , fbMonitorWfmMode(kFALSE)
+  , fbMonitorFitMode(kFALSE)
   , fbDebugMonitorMode(kTRUE)
   , fvbMaskedComponents()
   , fbFirstPackageError(kTRUE)
+  , fbPsdMissedData(kFALSE)
   , fUnpackPar(nullptr)
   , fuNrOfGdpbs(0)
   , fGdpbIdIndexMap()
@@ -51,68 +55,47 @@ CbmMcbm2018MonitorAlgoPsd::CbmMcbm2018MonitorAlgoPsd()
   , fulCurrentTsIdx(0)
   , fulCurrentMsIdx(0)
   , fdTsStartTime(-1.0)
-  , fdTsStopTimeCore(-1.0)
   , fdMsTime(-1.0)
   , fdPrevMsTime(-1.0)
   , fuMsIndex(0)
   , fuCurrentEquipmentId(0)
   , fuCurrDpbId(0)
   , fuCurrDpbIdx(0)
-  , fiRunStartDateTimeSec(-1)
-  , fiBinSizeDatePlots(-1)
-  , fvulCurrentEpoch()
-  , fvulCurrentEpochCycle()
-  , fvulCurrentEpochFull()
   , fdStartTime(-1.0)
-  , fdStartTimeMsSz(0.0)
   , ftStartTimeUnix(std::chrono::steady_clock::now())
   , fuHistoryHistoSize(3600)
   , fviHistoChargeArgs(3, 0)
   , fviHistoAmplArgs(3, 0)
   , fviHistoZLArgs(3, 0)
-  , fuReadEvtCnt(0)
   , fuMsgsCntInMs(0)
   , fuReadMsgsCntInMs(0)
   , fuLostMsgsCntInMs(0)
   , fuReadEvtCntInMs(0)
-  , fvuHitCntChanMs(kuNbChanPsd, 0)
-  , fvuErrorCntChanMs(kuNbChanPsd, 0)
-  , fvuEvtLostCntChanMs(kuNbChanPsd, 0)
-  , fvhHitCntEvoChan(kuNbChanPsd, nullptr)
-  , fvhHitCntPerMsEvoChan(kuNbChanPsd, nullptr)
   , fvhHitChargeChan(kuNbChanPsd, nullptr)
   , fvhHitZeroLevelChan(kuNbChanPsd, nullptr)
   , fvhHitAmplChan(kuNbChanPsd, nullptr)
   , fvhHitChargeByWfmChan(kuNbChanPsd, nullptr)
-  , fvhHitChargeEvoChan(kuNbChanPsd, nullptr)
   , fvhHitWfmChan(kuNbChanPsd, nullptr)
-  , fvhHitFitWfmChan(kuNbChanPsd, nullptr)
   , kvuWfmRanges(kuNbWfmRanges, 0)
   , kvuWfmInRangeToChangeChan(kuNbChanPsd * kuNbWfmRanges, 0)
-  , fv3hHitWfmFlattenedChan(kuNbChanPsd * kuNbWfmRanges * kuNbWfmExamples,
-                            nullptr)
+  , fv3hHitWfmFlattenedChan(kuNbChanPsd * kuNbWfmRanges * kuNbWfmExamples, nullptr)
   , fbSpillOn(kTRUE)
   , fuCurrentSpillIdx(0)
   , fuCurrentSpillPlot(0)
   , fdStartTimeSpill(-1.0)
   , fdLastSecondTime(-1.0)
   , fuCountsLastSecond(0)
-  , fhChannelMap(nullptr)
   , fhHitChargeMap(nullptr)
   , fhHitMapEvo(nullptr)
   , fhChanHitMapEvo(nullptr)
-  , fvhChannelMapSpill()
-  , fhHitsPerSpill(nullptr)
-  , fhMsgsCntEvo(nullptr)
-  , fhReadMsgsCntEvo(nullptr)
-  , fhLostMsgsCntEvo(nullptr)
-  , fhReadEvtsCntEvo(nullptr)
-  , fhAdcTimeEvo(nullptr)
+  , fhMissedData(nullptr)
+  , fhAdcTime(nullptr)
   , fhMsLengthEvo(nullptr)
   , fhMsgsCntPerMsEvo(nullptr)
   , fhReadMsgsCntPerMsEvo(nullptr)
   , fhLostMsgsCntPerMsEvo(nullptr)
   , fhReadEvtsCntPerMsEvo(nullptr)
+  , fvhHitFitWfmChan(kuNbChanPsd, nullptr)
   , fvhFitHarmonic1Chan(kuNbChanPsd, nullptr)
   , fvhFitHarmonic2Chan(kuNbChanPsd, nullptr)
   , fvhFitQaChan(kuNbChanPsd, nullptr)
@@ -121,11 +104,12 @@ CbmMcbm2018MonitorAlgoPsd::CbmMcbm2018MonitorAlgoPsd()
   , fcChargesFPGA(nullptr)
   , fcChargesWfm(nullptr)
   , fcAmplitudes(nullptr)
+  , fcZeroLevels(nullptr)
   , fcGenCntsPerMs(nullptr)
-  , fcSpillCounts(nullptr)
-  , fcSpillCountsHori(nullptr)
   , fcWfmsAllChannels(nullptr)
-  , fvcWfmsChan(kuNbChanPsd, nullptr) {}
+  , fvcWfmsChan(kuNbChanPsd, nullptr)
+{
+}
 CbmMcbm2018MonitorAlgoPsd::~CbmMcbm2018MonitorAlgoPsd() {
   /// Clear buffers
 }
@@ -188,10 +172,6 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::InitParameters() {
               << fUnpackPar->GetGdpbId(i) << std::dec;
   }  // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i )
 
-  /// Internal status initialization
-  fvulCurrentEpoch.resize(fuNrOfGdpbs, 0);
-  fvulCurrentEpochCycle.resize(fuNrOfGdpbs, 0);
-  fvulCurrentEpochFull.resize(fuNrOfGdpbs, 0);
 
   return kTRUE;
 }
@@ -240,10 +220,6 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::ProcessTs(const fles::Timeslice& ts) {
     LOG(info) << "In each TS " << fuNbMsLoop << " MS will be looped over";
   }  // if( -1.0 == fdTsCoreSizeInNs )
 
-  /// Compute time of TS core end
-  fdTsStopTimeCore = fdTsStartTime + fdTsCoreSizeInNs;
-  //      LOG(info) << Form( "TS %5d Start %12f Stop %12f", fulCurrentTsIdx, fdTsStartTime, fdTsStopTimeCore );
-
   /// Loop over core microslices (and overlap ones if chosen)
   for (fuMsIndex = 0; fuMsIndex < fuNbMsLoop; fuMsIndex++) {
     /// Loop over registered components
@@ -334,10 +310,7 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::ProcessMs(const fles::Timeslice& ts,
       if (fbSpillOn && fuCountsLastSecond < kuOffSpillCountLimit) {
         fbSpillOn = kFALSE;
         fuCurrentSpillIdx++;
-        fuCurrentSpillPlot = (fuCurrentSpillPlot + 1) % kuNbSpillPlots;
         fdStartTimeSpill   = fdMsTime;
-        fvhChannelMapSpill[fuCurrentSpillPlot]->Reset();
-        fhHitsPerSpill->SetBinContent(fuCurrentSpillPlot + 1, 0);
       }  // if( fbSpillOn && fuCountsLastSecond < kuOffSpillCountLimit )
       else if (kuOffSpillCountLimit < fuCountsLastSecond)
         fbSpillOn = kTRUE;
@@ -384,13 +357,6 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::ProcessMs(const fles::Timeslice& ts,
     }
   }
 
-  kvuWfmRanges.clear();
-  for (uint8_t i = 0; i <= kuNbWfmRanges; ++i)
-    kvuWfmRanges.push_back(
-      fviHistoChargeArgs.at(1)
-      + i * (fviHistoChargeArgs.at(2) - fviHistoChargeArgs.at(1))
-          / kuNbWfmRanges);
-
   PsdData::PsdGbtReader PsdReader(pInBuff);
   if (gLogger->IsLogNeeded(fair::Severity::debug))
     PsdReader.SetPrintOutMode(true);
@@ -406,11 +372,9 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::ProcessMs(const fles::Timeslice& ts,
 
       if (ReadResult == 0) {
         fuCountsLastSecond++;
-        fhAdcTimeEvo->Fill(fdMsTime - fdStartTime, PsdReader.EvHdrAc.uAdcTime);
-        fuReadEvtCnt++;
+        fhAdcTime->Fill(PsdReader.EvHdrAc.uAdcTime);
         fuReadEvtCntInMs++;
-        fhHitsPerSpill->AddBinContent(fuCurrentSpillPlot + 1,
-                                      PsdReader.EvHdrAb.uHitsNumber);
+
         //hit loop
         for (int hit_iter = 0; hit_iter < PsdReader.EvHdrAb.uHitsNumber;
              hit_iter++) {
@@ -427,112 +391,94 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::ProcessMs(const fles::Timeslice& ts,
             break;
           }
           //Hit header
-          fhChannelMap->Fill(uHitChannel);
           fhHitChargeMap->Fill(uHitChannel, uSignalCharge);
-          fvhChannelMapSpill[fuCurrentSpillPlot]->Fill(
-            uHitChannel);  //should be placed map(channel)
           fhHitMapEvo->Fill(uHitChannel, fdMsTime - fdStartTime);
           fhChanHitMapEvo->Fill(
             uHitChannel,
             fdMsTime - fdStartTime);  //should be placed map(channel)
 
-          fvhHitCntEvoChan[uHitChannel]->Fill(fdMsTime - fdStartTime);
-          fvuHitCntChanMs[uHitChannel]++;
-
-          fvhHitChargeChan[uHitChannel]->Fill(uSignalCharge);
-          fvhHitZeroLevelChan[uHitChannel]->Fill(uZeroLevel);
-          fvhHitChargeEvoChan[uHitChannel]->Fill(fdMsTime - fdStartTime,
-                                                 uSignalCharge);
-
-          //Hit data
-          uint16_t uHitAmlpitude = 0;
-          uint16_t uHitChargeWfm = 0;
-          fvhHitWfmChan[uHitChannel]->Reset();
-          fvhHitFitWfmChan[uHitChannel]->Reset();
-          for (UInt_t wfm_iter = 0; wfm_iter < uWfm.size(); wfm_iter++) {
-            if (uWfm.at(wfm_iter) > uHitAmlpitude)
-              uHitAmlpitude = uWfm.at(wfm_iter);
-            uHitChargeWfm += uWfm.at(wfm_iter) - uZeroLevel;
-            fvhHitWfmChan[uHitChannel]->Fill(wfm_iter, uWfm.at(wfm_iter));
-          }
-          fvhHitWfmChan[uHitChannel]->SetTitle(
-            Form("Waveform channel %03u charge %0u zero level %0u; Time [adc "
-                 "counts]; Amplitude [adc counts]",
-                 uHitChannel,
-                 uSignalCharge,
-                 uZeroLevel));
-          uHitAmlpitude -= uZeroLevel;
-          fvhHitAmplChan[uHitChannel]->Fill(uHitAmlpitude);
-          fvhHitChargeByWfmChan[uHitChannel]->Fill(uHitChargeWfm);
-
-          for (uint8_t i = 0; i < kuNbWfmRanges; ++i) {
-            if (uSignalCharge > kvuWfmRanges.at(i)
-                && uSignalCharge < kvuWfmRanges.at(i + 1)) {
-              UInt_t uFlatIndexOfChange = i * kuNbChanPsd + uHitChannel;
-
-              UInt_t uWfmExampleIter =
-                kvuWfmInRangeToChangeChan.at(uFlatIndexOfChange);
-              UInt_t uFlatIndexHisto =
-                uWfmExampleIter * kuNbWfmRanges * kuNbChanPsd + i * kuNbChanPsd
-                + uHitChannel;
-              fv3hHitWfmFlattenedChan[uFlatIndexHisto]->Reset();
-
-              for (UInt_t wfm_iter = 0; wfm_iter < uWfm.size(); wfm_iter++)
-                fv3hHitWfmFlattenedChan[uFlatIndexHisto]->Fill(
-                  wfm_iter, uWfm.at(wfm_iter));
-              fv3hHitWfmFlattenedChan[uFlatIndexHisto]->SetTitle(
-                Form("Waveform channel %03u charge %0u zero level %0u; Time "
-                     "[adc counts]; Amplitude [adc counts]",
-                     uHitChannel,
-                     uSignalCharge,
-                     uZeroLevel));
-
-              kvuWfmInRangeToChangeChan.at(uFlatIndexOfChange)++;
-              if (kvuWfmInRangeToChangeChan.at(uFlatIndexOfChange)
-                  == kuNbWfmExamples)
-                kvuWfmInRangeToChangeChan.at(uFlatIndexOfChange) = 0;
-
-            }  // if( uSignalCharge > kvuWfmRanges.at(i) && uSignalCharge < kvuWfmRanges.at(i+1) )
-          }    // for (uint8_t i=0; i<kuNbWfmRanges; ++i)
-
-
-          int gate_beg = 0;
-          int gate_end = 7;
-          PsdSignalFitting::PronyFitter Pfitter(2, 2, gate_beg, gate_end);
-
-          Pfitter.SetDebugMode(0);
-          Pfitter.SetWaveform(uWfm, uZeroLevel);
-          int SignalBeg           = 2;
-          Int_t best_signal_begin = Pfitter.ChooseBestSignalBeginHarmonics(
-            SignalBeg - 1, SignalBeg + 1);
-
-          Pfitter.SetSignalBegin(best_signal_begin);
-          Pfitter.CalculateFitHarmonics();
-          Pfitter.CalculateFitAmplitudes();
-
-          Float_t fit_integral = Pfitter.GetIntegral(gate_beg, gate_end);
-          Float_t fit_R2       = Pfitter.GetRSquare(gate_beg, gate_end);
-
-          std::complex<float>* harmonics = Pfitter.GetHarmonics();
-          std::vector<uint16_t> uFitWfm  = Pfitter.GetFitWfm();
-          for (UInt_t wfm_iter = 0; wfm_iter < uFitWfm.size(); wfm_iter++) {
-            fvhHitFitWfmChan[uHitChannel]->Fill(wfm_iter, uFitWfm.at(wfm_iter));
-            fvhHitWfmChan[uHitChannel]->SetTitle(
-              Form("Waveform channel %03u charge %0u zero level %0u R2 %.5f; "
-                   "Time [adc counts]; Amplitude [adc counts]",
-                   uHitChannel,
-                   uSignalCharge,
-                   uZeroLevel,
-                   fit_R2));
-          }
-
-          fvhFitQaChan[uHitChannel]->Fill(fit_integral, fit_R2);
+          if (fbMonitorChanMode) {
+
+            fvhHitChargeChan[uHitChannel]->Fill(uSignalCharge);
+            fvhHitZeroLevelChan[uHitChannel]->Fill(uZeroLevel);
+
+            //Hit data
+            uint16_t uHitAmlpitude = 0;
+            UInt_t uHitChargeWfm   = 0;
+            if (fbMonitorWfmMode) fvhHitWfmChan[uHitChannel]->Reset();
+            if (fbMonitorFitMode) fvhHitFitWfmChan[uHitChannel]->Reset();
+            for (UInt_t wfm_iter = 0; wfm_iter < uWfm.size(); wfm_iter++) {
+              if (uWfm.at(wfm_iter) > uHitAmlpitude) uHitAmlpitude = uWfm.at(wfm_iter);
+              uHitChargeWfm += uWfm.at(wfm_iter) - uZeroLevel;
+              if (fbMonitorWfmMode) fvhHitWfmChan[uHitChannel]->Fill(wfm_iter, uWfm.at(wfm_iter));
+            }
+            uHitAmlpitude -= uZeroLevel;
+            fvhHitAmplChan[uHitChannel]->Fill(uHitAmlpitude);
+            fvhHitChargeByWfmChan[uHitChannel]->Fill(uHitChargeWfm);
+
+            if (fbMonitorWfmMode) {
+              fvhHitWfmChan[uHitChannel]->SetTitle(Form("Waveform channel %03u charge %0u zero level %0u; Time [adc "
+                                                        "counts]; Amplitude [adc counts]",
+                                                        uHitChannel, uSignalCharge, uZeroLevel));
+              for (uint8_t i = 0; i < kuNbWfmRanges; ++i) {
+                if (uSignalCharge > kvuWfmRanges.at(i) && uSignalCharge < kvuWfmRanges.at(i + 1)) {
+                  UInt_t uFlatIndexOfChange = i * kuNbChanPsd + uHitChannel;
+
+                  UInt_t uWfmExampleIter = kvuWfmInRangeToChangeChan.at(uFlatIndexOfChange);
+                  UInt_t uFlatIndexHisto =
+                    uWfmExampleIter * kuNbWfmRanges * kuNbChanPsd + i * kuNbChanPsd + uHitChannel;
+                  fv3hHitWfmFlattenedChan[uFlatIndexHisto]->Reset();
+
+                  for (UInt_t wfm_iter = 0; wfm_iter < uWfm.size(); wfm_iter++)
+                    fv3hHitWfmFlattenedChan[uFlatIndexHisto]->Fill(wfm_iter, uWfm.at(wfm_iter));
+                  fv3hHitWfmFlattenedChan[uFlatIndexHisto]->SetTitle(
+                    Form("Waveform channel %03u charge %0u zero level %0u; Time "
+                         "[adc counts]; Amplitude [adc counts]",
+                         uHitChannel, uSignalCharge, uZeroLevel));
+
+                  kvuWfmInRangeToChangeChan.at(uFlatIndexOfChange)++;
+                  if (kvuWfmInRangeToChangeChan.at(uFlatIndexOfChange) == kuNbWfmExamples)
+                    kvuWfmInRangeToChangeChan.at(uFlatIndexOfChange) = 0;
+
+                }  // if( uSignalCharge > kvuWfmRanges.at(i) && uSignalCharge < kvuWfmRanges.at(i+1) )
+              }    // for (uint8_t i=0; i<kuNbWfmRanges; ++i)
+            }      //if (fbMonitorWfmMode)
+
+
+            if (fbMonitorFitMode) {
+              int gate_beg = 0;
+              int gate_end = 7;
+              PsdSignalFitting::PronyFitter Pfitter(2, 2, gate_beg, gate_end);
+
+              Pfitter.SetDebugMode(0);
+              Pfitter.SetWaveform(uWfm, uZeroLevel);
+              int SignalBeg           = 2;
+              Int_t best_signal_begin = Pfitter.ChooseBestSignalBeginHarmonics(SignalBeg - 1, SignalBeg + 1);
+
+              Pfitter.SetSignalBegin(best_signal_begin);
+              Pfitter.CalculateFitHarmonics();
+              Pfitter.CalculateFitAmplitudes();
+
+              Float_t fit_integral = Pfitter.GetIntegral(gate_beg, gate_end);
+              Float_t fit_R2       = Pfitter.GetRSquare(gate_beg, gate_end);
+
+              std::complex<float>* harmonics = Pfitter.GetHarmonics();
+              std::vector<uint16_t> uFitWfm  = Pfitter.GetFitWfm();
+              for (UInt_t wfm_iter = 0; wfm_iter < uFitWfm.size(); wfm_iter++) {
+                fvhHitFitWfmChan[uHitChannel]->Fill(wfm_iter, uFitWfm.at(wfm_iter));
+                fvhHitWfmChan[uHitChannel]->SetTitle(Form("Waveform channel %03u charge %0u zero level %0u R2 %.5f; "
+                                                          "Time [adc counts]; Amplitude [adc counts]",
+                                                          uHitChannel, uSignalCharge, uZeroLevel, fit_R2));
+              }
+
+              fvhFitQaChan[uHitChannel]->Fill(fit_integral, fit_R2);
+
+              if (fit_R2 > 0.02) continue;
+              fvhFitHarmonic1Chan[uHitChannel]->Fill(std::real(harmonics[1]), std::imag(harmonics[1]));
+              fvhFitHarmonic2Chan[uHitChannel]->Fill(std::real(harmonics[2]), std::imag(harmonics[2]));
+            }  //if (fbMonitorFitMode)
+          }    //if (fbMonitorChanMode)
 
-          if (fit_R2 > 0.02) continue;
-          fvhFitHarmonic1Chan[uHitChannel]->Fill(std::real(harmonics[1]),
-                                                 std::imag(harmonics[1]));
-          fvhFitHarmonic2Chan[uHitChannel]->Fill(std::real(harmonics[2]),
-                                                 std::imag(harmonics[2]));
         }  // for(int hit_iter = 0; hit_iter < PsdReader.EvHdrAb.uHitsNumber; hit_iter++)
 
       } else if (ReadResult == 1) {
@@ -556,6 +502,7 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::ProcessMs(const fles::Timeslice& ts,
     }  // while(PsdReader.GetTotalGbtWordsRead()<uNbMessages)
 
     if (uNbMessages != PsdReader.GetTotalGbtWordsRead()) {
+      fbPsdMissedData = kTRUE;
       LOG(error) << "Wrong amount of messages read!"
                  << " in microslice " << uNbMessages << " by PsdReader "
                  << PsdReader.GetTotalGbtWordsRead();
@@ -578,13 +525,6 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::ProcessMs(const fles::Timeslice& ts,
                  << " in microslice " << fulCurrentMsIdx << " by PsdReader "
                  << PsdReader.EvHdrAb.ulMicroSlice << "\n";
 
-    fhMsgsCntEvo->AddBinContent(fdMsTime - fdStartTime, uNbMessages);
-    fhReadMsgsCntEvo->AddBinContent(fdMsTime - fdStartTime,
-                                    PsdReader.GetTotalGbtWordsRead());
-    fhLostMsgsCntEvo->AddBinContent(
-      fdMsTime - fdStartTime, uNbMessages - PsdReader.GetTotalGbtWordsRead());
-    fhReadEvtsCntEvo->AddBinContent(fdMsTime - fdStartTime, fuReadEvtCnt);
-
     fuMsgsCntInMs += uNbMessages;
     fuReadMsgsCntInMs += PsdReader.GetTotalGbtWordsRead();
     fuLostMsgsCntInMs += uNbMessages - PsdReader.GetTotalGbtWordsRead();
@@ -613,14 +553,9 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::CreateHistograms() {
   /// Logarithmic bining
   uint32_t iNbBinsLog = 0;
   /// Parameters are NbDecadesLog, NbStepsDecade, NbSubStepsInStep
-  std::vector<double> dBinsLogVector = GenerateLogBinArray(4, 9, 1, iNbBinsLog);
+  std::vector<double> dBinsLogVector = GenerateLogBinArray(2, 3, 1, iNbBinsLog);
   double* dBinsLog                   = dBinsLogVector.data();
 
-  fhChannelMap = new TH1I("hChannelMap",
-                          "Map of hits in PSD detector; Chan; Hits Count []",
-                          kuNbChanPsd,
-                          0.,
-                          kuNbChanPsd);
   fhHitChargeMap =
     new TH2I("hHitChargeMap",
              "Map of hits charges in PSD detector; Chan; Charge [adc counts]",
@@ -648,56 +583,11 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::CreateHistograms() {
                              fuHistoryHistoSize,
                              0,
                              fuHistoryHistoSize);
-  for (UInt_t uSpill = 0; uSpill < kuNbSpillPlots; uSpill++) {
-    fvhChannelMapSpill.push_back(
-      new TH1I(Form("hChannelMapSpill%02u", uSpill),
-               Form("Map of hits in PSD detector in current spill %02u; Chan; "
-                    "Hits Count []",
-                    uSpill),
-               kuNbChanPsd,
-               0.,
-               kuNbChanPsd));
-  }  // for( UInt_t uSpill = 0; uSpill < kuNbSpillPlots; uSpill ++)
-  fhHitsPerSpill = new TH1I("hHitsPerSpill",
-                            "Hit count per spill; Spill; Hits Count []",
-                            kuNbSpillPlots,
-                            0,
-                            kuNbSpillPlots);
-
-  fhMsgsCntEvo     = new TH1I("hMsgsCntEvo",
-                          "Evolution of TotalMsgs counts vs time in run; Time "
-                          "in run [s]; Msgs Count []",
-                          fuHistoryHistoSize,
-                          0,
-                          fuHistoryHistoSize);
-  fhReadMsgsCntEvo = new TH1I("hReadMsgsCntEvo",
-                              "Evolution of ReadMsgs counts vs time in run; "
-                              "Time in run [s]; ReadMsgs Count []",
-                              fuHistoryHistoSize,
-                              0,
-                              fuHistoryHistoSize);
-  fhLostMsgsCntEvo = new TH1I("hLostMsgsCntEvo",
-                              "Evolution of LostMsgs counts vs time in run; "
-                              "Time in run [s]; LostMsgs Count []",
-                              fuHistoryHistoSize,
-                              0,
-                              fuHistoryHistoSize);
-  fhReadEvtsCntEvo = new TH1I("hReadEvtsCntEvo",
-                              "Evolution of ReadEvents counts vs time in run; "
-                              "Time in run [s]; ReadEvents Count []",
-                              fuHistoryHistoSize,
-                              0,
-                              fuHistoryHistoSize);
-
-  fhAdcTimeEvo = new TH2I(
-    "hAdcTimeEvo",
-    "Evolution of ADC time vs time in run; Time in run [s]; Adc time *12.5[ns]",
-    fuHistoryHistoSize,
-    0,
-    fuHistoryHistoSize,
-    500,
-    0,
-    9000);
+
+
+  fhMissedData = new TH1I("hMissedData", "PSD Missed data", 2, 0, 2);
+
+  fhAdcTime = new TH1I("hAdcTime", "ADC time; Adc time []", 100, 0, 160000);
 
   fhMsLengthEvo = new TH2I(
     "hMsLengthEvo",
@@ -736,31 +626,18 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::CreateHistograms() {
              fuHistoryHistoSize,
              iNbBinsLog,
              dBinsLog);
-  fhReadEvtsCntPerMsEvo =
-    new TH2I("hReadEvtCntPerMsEvo",
-             "Evolution of ReadEvents, per MS counts vs time in run; Time in "
-             "run [s]; ReadEvents Count/MS []; MS",
-             fuHistoryHistoSize,
-             0,
-             fuHistoryHistoSize,
-             iNbBinsLog,
-             dBinsLog);
+  fhReadEvtsCntPerMsEvo = new TH2I("hReadEvtCntPerMsEvo",
+                                   "Evolution of ReadEvents counts, per MS vs time in run; Time in "
+                                   "run [s]; ReadEvents Count/MS []; MS",
+                                   fuHistoryHistoSize, 0, fuHistoryHistoSize, iNbBinsLog, dBinsLog);
 
   /// Add pointers to the vector with all histo for access by steering class
-  AddHistoToVector(fhChannelMap, sFolder);
   AddHistoToVector(fhHitChargeMap, sFolder);
   AddHistoToVector(fhHitMapEvo, sFolder);
   AddHistoToVector(fhChanHitMapEvo, sFolder);
-  for (UInt_t uSpill = 0; uSpill < kuNbSpillPlots; uSpill++)
-    AddHistoToVector(fvhChannelMapSpill[uSpill], sFolder);
-  AddHistoToVector(fhHitsPerSpill, sFolder);
-
-  AddHistoToVector(fhMsgsCntEvo, sFolder);
-  AddHistoToVector(fhReadMsgsCntEvo, sFolder);
-  AddHistoToVector(fhLostMsgsCntEvo, sFolder);
-  AddHistoToVector(fhReadEvtsCntEvo, sFolder);
 
-  AddHistoToVector(fhAdcTimeEvo, sFolder);
+  AddHistoToVector(fhMissedData, sFolder);
+  AddHistoToVector(fhAdcTime, sFolder);
   AddHistoToVector(fhMsLengthEvo, sFolder);
 
   AddHistoToVector(fhMsgsCntPerMsEvo, sFolder);
@@ -769,163 +646,80 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::CreateHistograms() {
   AddHistoToVector(fhReadEvtsCntPerMsEvo, sFolder);
 
   /*******************************************************************/
-  for (UInt_t uChan = 0; uChan < kuNbChanPsd; ++uChan) {
-    fvhHitCntEvoChan[uChan] =
-      new TH1I(Form("hHitCntEvoChan%03u", uChan),
-               Form("Evolution of Hit counts vs time in run for channel %03u; "
-                    "Time in run [s]; Hits Count []",
-                    uChan),
-               fuHistoryHistoSize,
-               0,
-               fuHistoryHistoSize);
-
-    fvhHitCntPerMsEvoChan[uChan] =
-      new TH2I(Form("hHitCntPerMsEvoChan%03u", uChan),
-               Form("Evolution of Hit counts per MS vs time in run for channel "
-                    "%03u; Time in run [s]; Hits Count/MS []; MS",
-                    uChan),
-               fuHistoryHistoSize,
-               0,
-               fuHistoryHistoSize,
-               iNbBinsLog,
-               dBinsLog);
-
-    fvhHitChargeChan[uChan] = new TH1I(
-      Form("hHitChargeChan%03u", uChan),
-      Form("Hits charge distribution for channel %03u; Charge [adc counts]",
-           uChan),
-      fviHistoChargeArgs.at(0),
-      fviHistoChargeArgs.at(1),
-      fviHistoChargeArgs.at(2));
-
-    fvhHitZeroLevelChan[uChan] = new TH1I(
-      Form("hHitZeroLevelChan%03u", uChan),
-      Form(
-        "Hits zero level distribution for channel %03u; ZeroLevel [adc counts]",
-        uChan),
-      fviHistoZLArgs.at(0),
-      fviHistoZLArgs.at(1),
-      fviHistoZLArgs.at(2));
-
-    fvhHitAmplChan[uChan] = new TH1I(
-      Form("hHitAmplChan%03u", uChan),
-      Form(
-        "Hits amplitude distribution for channel %03u; Amplitude [adc counts]",
-        uChan),
-      fviHistoAmplArgs.at(0),
-      fviHistoAmplArgs.at(1),
-      fviHistoAmplArgs.at(2));
-
-    fvhHitChargeByWfmChan[uChan] =
-      new TH1I(Form("hHitChargeByWfmChan%03u", uChan),
-               Form("Hits charge by waveform distribution for channel %03u; "
-                    "Charge [adc counts]",
-                    uChan),
-               fviHistoChargeArgs.at(0),
-               fviHistoChargeArgs.at(1),
-               fviHistoChargeArgs.at(2));
-
-    fvhHitChargeEvoChan[uChan] =
-      new TH2I(Form("hHitChargeEvoChan%03u", uChan),
-               Form("Evolution of Hit charge vs time in run for channel %03u; "
-                    "Time in run [s]; Charge [adc counts]",
-                    uChan),
-               fuHistoryHistoSize,
-               0,
-               fuHistoryHistoSize,
-               fviHistoChargeArgs.at(0),
-               fviHistoChargeArgs.at(1),
-               fviHistoChargeArgs.at(2));
-
-    fvhHitWfmChan[uChan] = new TH1I(
-      Form("hHitWfmChan%03u", uChan), Form("HitWfmChan%03u", uChan), 8, 0, 8);
-    fvhHitWfmChan[uChan]->SetMarkerStyle(31);
-    fvhHitWfmChan[uChan]->SetMarkerSize(0.5);
-
-    fvhHitFitWfmChan[uChan] = new TH1I(Form("hHitFitWfmChan%03u", uChan),
-                                       Form("HitFitWfmChan%03u", uChan),
-                                       8,
-                                       0,
-                                       8);
-    fvhHitFitWfmChan[uChan]->SetLineColor(kRed);
-    fvhHitFitWfmChan[uChan]->SetLineWidth(2);
-
-    for (UInt_t uWfmRangeIter = 0; uWfmRangeIter < kuNbWfmRanges;
-         uWfmRangeIter++) {
-      for (UInt_t uWfmExampleIter = 0; uWfmExampleIter < kuNbWfmExamples;
-           uWfmExampleIter++) {
-        UInt_t uFlatIndex = uWfmExampleIter * kuNbWfmRanges * kuNbChanPsd
-                            + uWfmRangeIter * kuNbChanPsd + uChan;
-        fv3hHitWfmFlattenedChan[uFlatIndex] =
-          new TH1I(Form("hHitWfmChan%03uRange%02uExample%02u",
-                        uChan,
-                        uWfmRangeIter,
-                        uWfmExampleIter),
-                   Form("HitWfmChan%03uRange%02uExample%02u",
-                        uChan,
-                        uWfmRangeIter,
-                        uWfmExampleIter),
-                   8,
-                   0,
-                   8);
-
-      }  // for( UInt_t uWfmRangeIter = 0; uWfmRangeIter < kuNbWfmRanges; uWfmRangeIter ++)
-    }  // for( UInt_t uWfmExampleIter = 0; uWfmExampleIter < kuNbWfmExamples; uWfmExampleIter ++)
-
-    fvhFitHarmonic1Chan[uChan] = new TH2I(
-      Form("hFitHarmonic1Chan%03u", uChan),
-      Form(
-        "Waveform fit harmonic 1 for channel %03u; Real part []; Imag part []",
-        uChan),
-      400,
-      -2,
-      2,
-      200,
-      -1,
-      1);
-    fvhFitHarmonic1Chan[uChan]->SetMarkerColor(kRed);
-
-    fvhFitHarmonic2Chan[uChan] = new TH2I(
-      Form("hFitHarmonic2Chan%03u", uChan),
-      Form(
-        "Waveform fit harmonic 2 for channel %03u; Real part []; Imag part []",
-        uChan),
-      400,
-      -2,
-      2,
-      200,
-      -1,
-      1);
-    fvhFitHarmonic2Chan[uChan]->SetMarkerColor(kBlue);
-
-    fvhFitQaChan[uChan] = new TH2I(
-      Form("hFitQaChan%03u", uChan),
-      Form("Waveform fit QA for channel %03u;  Integral [adc counts]; R2 []",
-           uChan),
-      fviHistoChargeArgs.at(0),
-      fviHistoChargeArgs.at(1),
-      fviHistoChargeArgs.at(2),
-      500,
-      0,
-      1);
-
-
-    /// Add pointers to the vector with all histo for access by steering class
-    AddHistoToVector(fvhHitCntEvoChan[uChan], sFolder);
-    AddHistoToVector(fvhHitCntPerMsEvoChan[uChan], sFolder);
-    AddHistoToVector(fvhHitChargeChan[uChan], sFolder);
-    AddHistoToVector(fvhHitZeroLevelChan[uChan], sFolder);
-    AddHistoToVector(fvhHitAmplChan[uChan], sFolder);
-    AddHistoToVector(fvhHitChargeByWfmChan[uChan], sFolder);
-    AddHistoToVector(fvhHitChargeEvoChan[uChan], sFolder);
-
-    AddHistoToVector(fvhFitHarmonic1Chan[uChan], sFitFolder);
-    AddHistoToVector(fvhFitHarmonic2Chan[uChan], sFitFolder);
-    AddHistoToVector(fvhFitQaChan[uChan], sFitFolder);
-
-  }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; ++uChan )
-
-
+  if (fbMonitorChanMode) {
+
+    for (UInt_t uChan = 0; uChan < kuNbChanPsd; ++uChan) {
+      fvhHitChargeChan[uChan] = new TH1I(Form("hHitChargeChan%03u", uChan),
+                                         Form("Hits charge distribution for channel %03u; Charge [adc counts]", uChan),
+                                         fviHistoChargeArgs.at(0), fviHistoChargeArgs.at(1), fviHistoChargeArgs.at(2));
+
+      fvhHitZeroLevelChan[uChan] =
+        new TH1I(Form("hHitZeroLevelChan%03u", uChan),
+                 Form("Hits zero level distribution for channel %03u; ZeroLevel [adc counts]", uChan),
+                 fviHistoZLArgs.at(0), fviHistoZLArgs.at(1), fviHistoZLArgs.at(2));
+
+      fvhHitAmplChan[uChan] =
+        new TH1I(Form("hHitAmplChan%03u", uChan),
+                 Form("Hits amplitude distribution for channel %03u; Amplitude [adc counts]", uChan),
+                 fviHistoAmplArgs.at(0), fviHistoAmplArgs.at(1), fviHistoAmplArgs.at(2));
+
+      fvhHitChargeByWfmChan[uChan] =
+        new TH1I(Form("hHitChargeByWfmChan%03u", uChan),
+                 Form("Hits charge by waveform distribution for channel %03u; "
+                      "Charge [adc counts]",
+                      uChan),
+                 fviHistoChargeArgs.at(0), fviHistoChargeArgs.at(1), fviHistoChargeArgs.at(2));
+
+      AddHistoToVector(fvhHitChargeChan[uChan], sFolder);
+      AddHistoToVector(fvhHitZeroLevelChan[uChan], sFolder);
+      AddHistoToVector(fvhHitAmplChan[uChan], sFolder);
+      AddHistoToVector(fvhHitChargeByWfmChan[uChan], sFolder);
+
+      if (fbMonitorWfmMode) {
+        fvhHitWfmChan[uChan] = new TH1I(Form("hHitWfmChan%03u", uChan), Form("HitWfmChan%03u", uChan), 8, 0, 8);
+        fvhHitWfmChan[uChan]->SetMarkerStyle(31);
+        fvhHitWfmChan[uChan]->SetMarkerSize(0.5);
+
+        for (UInt_t uWfmRangeIter = 0; uWfmRangeIter < kuNbWfmRanges; uWfmRangeIter++) {
+          for (UInt_t uWfmExampleIter = 0; uWfmExampleIter < kuNbWfmExamples; uWfmExampleIter++) {
+            UInt_t uFlatIndex = uWfmExampleIter * kuNbWfmRanges * kuNbChanPsd + uWfmRangeIter * kuNbChanPsd + uChan;
+            fv3hHitWfmFlattenedChan[uFlatIndex] =
+              new TH1I(Form("hHitWfmChan%03uRange%02uExample%02u", uChan, uWfmRangeIter, uWfmExampleIter),
+                       Form("HitWfmChan%03uRange%02uExample%02u", uChan, uWfmRangeIter, uWfmExampleIter), 8, 0, 8);
+
+          }  // for( UInt_t uWfmRangeIter = 0; uWfmRangeIter < kuNbWfmRanges; uWfmRangeIter ++)
+        }    // for( UInt_t uWfmExampleIter = 0; uWfmExampleIter < kuNbWfmExamples; uWfmExampleIter ++)
+      }      // if(fbMonitorWfmMode)
+
+      if (fbMonitorFitMode) {
+
+        fvhHitFitWfmChan[uChan] =
+          new TH1I(Form("hHitFitWfmChan%03u", uChan), Form("HitFitWfmChan%03u", uChan), 8, 0, 8);
+        fvhHitFitWfmChan[uChan]->SetLineColor(kRed);
+        fvhHitFitWfmChan[uChan]->SetLineWidth(2);
+
+        fvhFitHarmonic1Chan[uChan] = new TH2I(
+          Form("hFitHarmonic1Chan%03u", uChan),
+          Form("Waveform fit harmonic 1 for channel %03u; Real part []; Imag part []", uChan), 400, -2, 2, 200, -1, 1);
+        fvhFitHarmonic1Chan[uChan]->SetMarkerColor(kRed);
+
+        fvhFitHarmonic2Chan[uChan] = new TH2I(
+          Form("hFitHarmonic2Chan%03u", uChan),
+          Form("Waveform fit harmonic 2 for channel %03u; Real part []; Imag part []", uChan), 400, -2, 2, 200, -1, 1);
+        fvhFitHarmonic2Chan[uChan]->SetMarkerColor(kBlue);
+
+        fvhFitQaChan[uChan] = new TH2I(
+          Form("hFitQaChan%03u", uChan), Form("Waveform fit QA for channel %03u;  Integral [adc counts]; R2 []", uChan),
+          fviHistoChargeArgs.at(0), fviHistoChargeArgs.at(1), fviHistoChargeArgs.at(2), 500, 0, 1);
+
+        AddHistoToVector(fvhFitHarmonic1Chan[uChan], sFitFolder);
+        AddHistoToVector(fvhFitHarmonic2Chan[uChan], sFitFolder);
+        AddHistoToVector(fvhFitQaChan[uChan], sFitFolder);
+
+      }  // if(fbMonitorFitMode)
+    }    // for( UInt_t uChan = 0; uChan < kuNbChanPsd; ++uChan )
+
+  }  // if (fbMonitorChanMode)
   /*******************************************************************/
 
   /// Canvases
@@ -940,16 +734,10 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::CreateHistograms() {
   fcHitMaps->cd(1);
   gPad->SetGridx();
   gPad->SetGridy();
-  gPad->SetLogy();
-  fhChannelMap->Draw();
-
-  fcHitMaps->cd(2);
-  gPad->SetGridx();
-  gPad->SetGridy();
   gPad->SetLogz();
   fhChanHitMapEvo->Draw("colz");
 
-  fcHitMaps->cd(3);
+  fcHitMaps->cd(2);
   gPad->SetGridx();
   gPad->SetGridy();
   gPad->SetLogz();
@@ -967,8 +755,8 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::CreateHistograms() {
   fcSummary->cd(1);
   gPad->SetGridx();
   gPad->SetGridy();
-  gPad->SetLogy();
-  fhChannelMap->Draw();
+  gPad->SetLogz();
+  fhHitChargeMap->Draw("colz");
 
   fcSummary->cd(2);
   gPad->SetGridx();
@@ -979,8 +767,8 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::CreateHistograms() {
   fcSummary->cd(3);
   gPad->SetGridx();
   gPad->SetGridy();
-  gPad->SetLogz();
-  fhHitChargeMap->Draw("colz");
+  gPad->SetLogy();
+  fhMissedData->Draw();
 
   fcSummary->cd(4);
   gPad->SetGridx();
@@ -992,51 +780,6 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::CreateHistograms() {
   AddCanvasToVector(fcSummary, "canvases");
   /*******************************************************************/
 
-  /*******************************************************************/
-  /// Charge from FPGA all channels
-  fcChargesFPGA = new TCanvas(
-    "cChargesFPGA", "Charges spectra in all channels calculated by FPGA", w, h);
-  fcChargesFPGA->DivideSquare(kuNbChanPsd);
-
-  for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
-    fcChargesFPGA->cd(1 + uChan);
-    fvhHitChargeChan[uChan]->Draw();
-  }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; uChan ++)
-
-  AddCanvasToVector(fcChargesFPGA, "canvases");
-  /*******************************************************************/
-
-  /*******************************************************************/
-  /// Charge from Waveform all channels
-  fcChargesWfm =
-    new TCanvas("cChargesWfm",
-                "Charges spectra in all channels calculated over waveform",
-                w,
-                h);
-  fcChargesWfm->DivideSquare(kuNbChanPsd);
-
-  for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
-    fcChargesWfm->cd(1 + uChan);
-    fvhHitChargeByWfmChan[uChan]->Draw();
-  }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; uChan ++)
-
-  AddCanvasToVector(fcChargesWfm, "canvases");
-  /*******************************************************************/
-
-  /*******************************************************************/
-  /// Amplitudes all channels
-  fcAmplitudes =
-    new TCanvas("cAmplitudes", "Amplitude spectra in all channels", w, h);
-  fcAmplitudes->DivideSquare(kuNbChanPsd);
-
-  for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
-    fcAmplitudes->cd(1 + uChan);
-    fvhHitAmplChan[uChan]->Draw();
-  }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; uChan ++)
-
-  AddCanvasToVector(fcAmplitudes, "canvases");
-  /*******************************************************************/
-
   /*******************************************************************/
   /// General summary: Hit maps, Hit rate vs time in run, error fraction vs time un run
   fcGenCntsPerMs = new TCanvas(
@@ -1077,98 +820,133 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::CreateHistograms() {
   AddCanvasToVector(fcGenCntsPerMs, "canvases");
   /*******************************************************************/
 
-  /*******************************************************************/
-  /// General summary: Hit maps, Hit rate vs time in run, error fraction vs time un run
-  fcSpillCounts =
-    new TCanvas("cSpillCounts",
-                "Counts per spill, last 5 spills including current one",
-                w,
-                h);
-  fcSpillCounts->Divide(1, kuNbSpillPlots);
-
-  for (UInt_t uSpill = 0; uSpill < kuNbSpillPlots; uSpill++) {
-    fcSpillCounts->cd(1 + uSpill);
-    gPad->SetGridx();
-    gPad->SetGridy();
-    fvhChannelMapSpill[uSpill]->Draw();
-  }  // for( UInt_t uSpill = 0; uSpill < kuNbSpillPlots; uSpill ++)
-
-  AddCanvasToVector(fcSpillCounts, "canvases");
-  /*******************************************************************/
+  if (fbMonitorChanMode) {
+
+    /*******************************************************************/
+    /// Charge from FPGA all channels
+    fcChargesFPGA = new TCanvas("cChargesFPGA", "Charges spectra in all channels calculated by FPGA", w, h);
+    fcChargesFPGA->DivideSquare(kuNbChanPsd);
+
+    for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
+      fcChargesFPGA->cd(1 + uChan);
+      fvhHitChargeChan[uChan]->Draw();
+    }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; uChan ++)
+
+    AddCanvasToVector(fcChargesFPGA, "canvases");
+    /*******************************************************************/
+
+    /*******************************************************************/
+    /// Charge from Waveform all channels
+    fcChargesWfm = new TCanvas("cChargesWfm", "Charges spectra in all channels calculated over waveform", w, h);
+    fcChargesWfm->DivideSquare(kuNbChanPsd);
+
+    for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
+      fcChargesWfm->cd(1 + uChan);
+      fvhHitChargeByWfmChan[uChan]->Draw();
+    }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; uChan ++)
+
+    AddCanvasToVector(fcChargesWfm, "canvases");
+    /*******************************************************************/
+
+    /*******************************************************************/
+    /// Amplitudes all channels
+    fcAmplitudes = new TCanvas("cAmplitudes", "Amplitude spectra in all channels", w, h);
+    fcAmplitudes->DivideSquare(kuNbChanPsd);
+
+    for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
+      fcAmplitudes->cd(1 + uChan);
+      fvhHitAmplChan[uChan]->Draw();
+    }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; uChan ++)
+
+    AddCanvasToVector(fcAmplitudes, "canvases");
+    /*******************************************************************/
+
+    /*******************************************************************/
+    /// ZeroLevels all channels
+    fcZeroLevels = new TCanvas("cZeroLevels", "Zero Level spectra in all channels", w, h);
+    fcZeroLevels->DivideSquare(kuNbChanPsd);
+
+    for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
+      fcZeroLevels->cd(1 + uChan);
+      fvhHitZeroLevelChan[uChan]->Draw();
+    }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; uChan ++)
+
+    AddCanvasToVector(fcZeroLevels, "canvases");
+    /*******************************************************************/
+
+    if (fbMonitorWfmMode) {
+
+      /*******************************************************************/
+      /// General summary: Hit maps, Hit rate vs time in run, error fraction vs time un run
+      fcWfmsAllChannels = new TCanvas("cWfmsAllChannels", "Last waveforms in PSD fired channels", w, h);
+      fcWfmsAllChannels->DivideSquare(kuNbChanPsd);
+
+      for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
+        fcWfmsAllChannels->cd(1 + uChan);
+        if (!fbMonitorFitMode) fvhHitWfmChan[uChan]->Draw("HIST LP");
+        if (fbMonitorFitMode) {
+          fvhHitWfmChan[uChan]->Draw("HIST P");
+          fvhHitFitWfmChan[uChan]->Draw("L SAME");
+        }
+      }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; uChan ++)
 
-  /*******************************************************************/
-  /// General summary: Hit maps, Hit rate vs time in run, error fraction vs time un run
-  fcWfmsAllChannels = new TCanvas(
-    "cWfmsAllChannels", "Last waveforms in PSD fired channels", w, h);
-  fcWfmsAllChannels->DivideSquare(kuNbChanPsd);
+      AddCanvasToVector(fcWfmsAllChannels, "waveforms");
+      /*******************************************************************/
 
-  for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
-    fcWfmsAllChannels->cd(1 + uChan);
-    fvhHitWfmChan[uChan]->Draw("HIST P");
-    fvhHitFitWfmChan[uChan]->Draw("L SAME");
-  }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; uChan ++)
+      /*******************************************************************/
+      /// General summary: Hit maps, Hit rate vs time in run, error fraction vs time un run
+      for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
+        fvcWfmsChan[uChan] =
+          new TCanvas(Form("cWfmsChan%03u", uChan), Form("Canvas with last waveforms in channel %03u", uChan), w, h);
+        fvcWfmsChan[uChan]->Divide(kuNbWfmExamples, kuNbWfmRanges);
+        UInt_t uHisto = 0;
 
-  AddCanvasToVector(fcWfmsAllChannels, "waveforms");
-  /*******************************************************************/
+        for (UInt_t uWfmRangeIter = 0; uWfmRangeIter < kuNbWfmRanges; uWfmRangeIter++) {
+          for (UInt_t uWfmExampleIter = 0; uWfmExampleIter < kuNbWfmExamples; uWfmExampleIter++) {
+            fvcWfmsChan[uChan]->cd(1 + uHisto);
+            UInt_t uFlatIndex = uWfmExampleIter * kuNbWfmRanges * kuNbChanPsd + uWfmRangeIter * kuNbChanPsd + uChan;
+            fv3hHitWfmFlattenedChan[uFlatIndex]->Draw("HIST LP");
+            uHisto++;
+          }  // for( UInt_t uWfmRangeIter = 0; uWfmRangeIter < kuNbWfmRanges; uWfmRangeIter ++)
+        }    // for( UInt_t uWfmExampleIter = 0; uWfmExampleIter < kuNbWfmExamples; uWfmExampleIter ++)
 
-  /*******************************************************************/
-  /// General summary: Hit maps, Hit rate vs time in run, error fraction vs time un run
-  for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
-    fvcWfmsChan[uChan] =
-      new TCanvas(Form("cWfmsChan%03u", uChan),
-                  Form("Canvas with last waveforms in channel %03u", uChan),
-                  w,
-                  h);
-    fvcWfmsChan[uChan]->Divide(kuNbWfmExamples, kuNbWfmRanges);
-    UInt_t uHisto = 0;
-
-    for (UInt_t uWfmRangeIter = 0; uWfmRangeIter < kuNbWfmRanges;
-         uWfmRangeIter++) {
-      for (UInt_t uWfmExampleIter = 0; uWfmExampleIter < kuNbWfmExamples;
-           uWfmExampleIter++) {
-        fvcWfmsChan[uChan]->cd(1 + uHisto);
-        UInt_t uFlatIndex = uWfmExampleIter * kuNbWfmRanges * kuNbChanPsd
-                            + uWfmRangeIter * kuNbChanPsd + uChan;
-        fv3hHitWfmFlattenedChan[uFlatIndex]->Draw("HIST LP");
-        uHisto++;
-      }  // for( UInt_t uWfmRangeIter = 0; uWfmRangeIter < kuNbWfmRanges; uWfmRangeIter ++)
-    }  // for( UInt_t uWfmExampleIter = 0; uWfmExampleIter < kuNbWfmExamples; uWfmExampleIter ++)
-
-    AddCanvasToVector(fvcWfmsChan[uChan], "waveforms");
-  }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; uChan ++)
+        AddCanvasToVector(fvcWfmsChan[uChan], "waveforms");
+      }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; uChan ++)
 
-  /*******************************************************************/
+      /*******************************************************************/
 
-  fcPronyFit = new TCanvas("cPronyFit", "Prony wfm fitting", w, h);
-  fcPronyFit->Divide(2);
+    }  // if (fbMonitorWfmMode)
 
-  fcPronyFit->cd(1);
-  for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
-    fvhFitHarmonic1Chan[uChan]->Draw("same");
-    fvhFitHarmonic2Chan[uChan]->Draw("same");
-  }
+    if (fbMonitorFitMode) {
 
-  fcPronyFit->cd(2);
-  for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
-    fvhFitQaChan[uChan]->Draw("same");
-  }
+      fcPronyFit = new TCanvas("cPronyFit", "Prony wfm fitting", w, h);
+      fcPronyFit->Divide(2);
 
-  AddCanvasToVector(fcPronyFit, "PronyFit");
+      fcPronyFit->cd(1);
+      for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
+        fvhFitHarmonic1Chan[uChan]->Draw("same");
+        fvhFitHarmonic2Chan[uChan]->Draw("same");
+      }
 
-  /*******************************************************************/
+      fcPronyFit->cd(2);
+      for (UInt_t uChan = 0; uChan < kuNbChanPsd; uChan++) {
+        fvhFitQaChan[uChan]->Draw("same");
+      }
 
-  return kTRUE;
-}
+      AddCanvasToVector(fcPronyFit, "PronyFit");
 
-Bool_t CbmMcbm2018MonitorAlgoPsd::FillHistograms() {
+      /*******************************************************************/
 
-  for (UInt_t uChan = 0; uChan < kuNbChanPsd; ++uChan) {
-    fvhHitCntPerMsEvoChan[uChan]->Fill(fdMsTime - fdStartTime,
-                                       fvuHitCntChanMs[uChan]);
-    fvuHitCntChanMs[uChan] = 0;
+    }  // if (fbMonitorFitMode)
 
-  }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; ++uChan )
+  }  // if (fbMonitorChanMode)
 
+  return kTRUE;
+}
+
+Bool_t CbmMcbm2018MonitorAlgoPsd::FillHistograms()
+{
+  fhMissedData->Fill(fbPsdMissedData);
   fhMsgsCntPerMsEvo->Fill(fdMsTime - fdStartTime, fuMsgsCntInMs);
   fhReadMsgsCntPerMsEvo->Fill(fdMsTime - fdStartTime, fuReadMsgsCntInMs);
   fhLostMsgsCntPerMsEvo->Fill(fdMsTime - fdStartTime, fuLostMsgsCntInMs);
@@ -1181,47 +959,40 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::FillHistograms() {
   return kTRUE;
 }
 
-Bool_t CbmMcbm2018MonitorAlgoPsd::ResetHistograms() {
-  for (UInt_t uChan = 0; uChan < kuNbChanPsd; ++uChan) {
-    fvhHitCntEvoChan[uChan]->Reset();
-    fvhHitCntPerMsEvoChan[uChan]->Reset();
-    fvhHitChargeChan[uChan]->Reset();
-    fvhHitZeroLevelChan[uChan]->Reset();
-    fvhHitAmplChan[uChan]->Reset();
-    fvhHitChargeByWfmChan[uChan]->Reset();
-    fvhHitChargeEvoChan[uChan]->Reset();
-    fvhHitWfmChan[uChan]->Reset();
-    fvhHitFitWfmChan[uChan]->Reset();
-
-    fvhFitHarmonic1Chan[uChan]->Reset();
-    fvhFitHarmonic2Chan[uChan]->Reset();
-    fvhFitQaChan[uChan]->Reset();
-  }  // for( UInt_t uChan = 0; uChan < kuNbChanPsd; ++uChan )
-
-  for (UInt_t uFlatIndex = 0;
-       uFlatIndex < kuNbChanPsd * kuNbWfmRanges * kuNbWfmExamples;
-       ++uFlatIndex)
-    fv3hHitWfmFlattenedChan[uFlatIndex]->Reset();
-  for (UInt_t uWfmIndex = 0; uWfmIndex < kuNbChanPsd * kuNbWfmRanges;
-       ++uWfmIndex)
-    kvuWfmInRangeToChangeChan[uWfmIndex] = 0;
+Bool_t CbmMcbm2018MonitorAlgoPsd::ResetHistograms(Bool_t bResetTime)
+{
+
+  if (fbMonitorChanMode) {
+    for (UInt_t uChan = 0; uChan < kuNbChanPsd; ++uChan) {
+      fvhHitChargeChan[uChan]->Reset();
+      fvhHitZeroLevelChan[uChan]->Reset();
+      fvhHitAmplChan[uChan]->Reset();
+      fvhHitChargeByWfmChan[uChan]->Reset();
+      if (fbMonitorWfmMode) fvhHitWfmChan[uChan]->Reset();
+
+      if (fbMonitorFitMode) {
+        fvhHitFitWfmChan[uChan]->Reset();
+        fvhFitHarmonic1Chan[uChan]->Reset();
+        fvhFitHarmonic2Chan[uChan]->Reset();
+        fvhFitQaChan[uChan]->Reset();
+      }  // if (fbMonitorFitMode)
+    }    // for( UInt_t uChan = 0; uChan < kuNbChanPsd; ++uChan )
+  }      // if(fbMonitorChanMode)
+
+  if (fbMonitorWfmMode) {
+    for (UInt_t uFlatIndex = 0; uFlatIndex < kuNbChanPsd * kuNbWfmRanges * kuNbWfmExamples; ++uFlatIndex)
+      fv3hHitWfmFlattenedChan[uFlatIndex]->Reset();
+    for (UInt_t uWfmIndex = 0; uWfmIndex < kuNbChanPsd * kuNbWfmRanges; ++uWfmIndex)
+      kvuWfmInRangeToChangeChan[uWfmIndex] = 0;
+  }  // if(fbMonitorWfmMode)
 
   fuCurrentSpillIdx  = 0;
-  fuCurrentSpillPlot = 0;
-  fhChannelMap->Reset();
   fhHitChargeMap->Reset();
   fhHitMapEvo->Reset();
   fhChanHitMapEvo->Reset();
-  for (UInt_t uSpill = 0; uSpill < kuNbSpillPlots; uSpill++)
-    fvhChannelMapSpill[uSpill]->Reset();
-  fhHitsPerSpill->Reset();
-
-  fhMsgsCntEvo->Reset();
-  fhReadMsgsCntEvo->Reset();
-  fhLostMsgsCntEvo->Reset();
-  fhReadEvtsCntEvo->Reset();
 
-  fhAdcTimeEvo->Reset();
+  fhMissedData->Reset();
+  fhAdcTime->Reset();
   fhMsLengthEvo->Reset();
 
   fhMsgsCntPerMsEvo->Reset();
@@ -1229,8 +1000,10 @@ Bool_t CbmMcbm2018MonitorAlgoPsd::ResetHistograms() {
   fhLostMsgsCntPerMsEvo->Reset();
   fhReadEvtsCntPerMsEvo->Reset();
 
-  /// Also reset the Start time for the evolution plots!
-  fdStartTime = -1.0;
+  if (kTRUE == bResetTime) {
+    /// Also reset the Start time for the evolution plots!
+    fdStartTime = -1.0;
+  }  // if( kTRUE == bResetTime )
 
 
   return kTRUE;
diff --git a/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoPsd.h b/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoPsd.h
index 4d9d10b4db08c849227803a15c4e2446a1f7f669..15a18e820e5840c9dc2bcce14ff805bfcd95e0f1 100644
--- a/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoPsd.h
+++ b/fles/mcbm2018/monitor/CbmMcbm2018MonitorAlgoPsd.h
@@ -56,16 +56,23 @@ public:
 
   Bool_t CreateHistograms();
   Bool_t FillHistograms();
-  Bool_t ResetHistograms();
+  Bool_t ResetHistograms(Bool_t bResetTime = kTRUE);
 
   inline void SetMonitorMode(Bool_t bFlagIn = kTRUE) {
     fbMonitorMode = bFlagIn;
   }
+  inline void SetMonitorChanMode(Bool_t bFlagIn = kTRUE) { fbMonitorChanMode = bFlagIn; }
+  inline void SetMonitorWfmMode(Bool_t bFlagIn = kTRUE) { fbMonitorWfmMode = bFlagIn; }
+  inline void SetMonitorFitMode(Bool_t bFlagIn = kTRUE) { fbMonitorFitMode = bFlagIn; }
   inline void SetHistoryHistoSize(UInt_t inHistorySizeSec = 1800) {
     fuHistoryHistoSize = inHistorySizeSec;
   }
   inline void SetChargeHistoArgs(std::vector<Int_t> inVec) {
     fviHistoChargeArgs = inVec;
+    kvuWfmRanges.clear();
+    for (uint8_t i = 0; i <= kuNbWfmRanges; ++i)
+      kvuWfmRanges.push_back(fviHistoChargeArgs.at(1)
+                             + i * (fviHistoChargeArgs.at(2) - fviHistoChargeArgs.at(1)) / kuNbWfmRanges);
   }
   inline void SetAmplHistoArgs(std::vector<Int_t> inVec) {
     fviHistoAmplArgs = inVec;
@@ -79,10 +86,14 @@ private:
   /// Control flags
   Bool_t
     fbMonitorMode;  //! Switch ON the filling of a minimal set of histograms
+  Bool_t fbMonitorChanMode;  //! Switch ON the filling channelwise histograms
+  Bool_t fbMonitorWfmMode;   //! Switch ON the filling waveforms histograms
+  Bool_t fbMonitorFitMode;   //! Switch ON the filling waveform fitting histograms
   Bool_t
     fbDebugMonitorMode;  //! Switch ON the filling of a additional set of histograms
   std::vector<Bool_t> fvbMaskedComponents;
   Bool_t fbFirstPackageError;
+  Bool_t fbPsdMissedData;
 
   /// Settings from parameter file
   CbmMcbm2018PsdPar* fUnpackPar;  //!
@@ -105,8 +116,6 @@ private:
   ULong64_t fulCurrentMsIdx;
   Double_t
     fdTsStartTime;  //! Time in ns of current TS from the index of the first MS first component
-  Double_t
-    fdTsStopTimeCore;  //! End Time in ns of current TS Core from the index of the first MS first component
   Double_t
     fdMsTime;  //! Start Time in ns of current MS from its index field in header
   Double_t
@@ -120,21 +129,10 @@ private:
     fuCurrDpbId;  //! Temp holder until Current equipment ID is properly filled in MS
   UInt_t
     fuCurrDpbIdx;  //! Index of the DPB from which the MS currently unpacked is coming
-  Int_t
-    fiRunStartDateTimeSec;  //! Start of run time since "epoch" in s, for the plots with date as X axis
-  Int_t fiBinSizeDatePlots;  //! Bin size in s for the plots with date as X axis
-
-  /// Data format control: Current time references for each GDPB: merged epoch marker, epoch cycle, full epoch [fuNrOfGdpbs]
-  std::vector<ULong64_t> fvulCurrentEpoch;  //! Current epoch index, per DPB
-  std::vector<ULong64_t>
-    fvulCurrentEpochCycle;  //! Epoch cycle from the Ms Start message and Epoch counter flip
-  std::vector<ULong64_t> fvulCurrentEpochFull;  //! Epoch + Epoch Cycle
 
   /// Starting state book-keeping
   Double_t
     fdStartTime; /** Time of first valid hit (epoch available), used as reference for evolution plots**/
-  Double_t
-    fdStartTimeMsSz; /** Time of first microslice, used as reference for evolution plots**/
   std::chrono::steady_clock::time_point
     ftStartTimeUnix; /** Time of run Start from UNIX system, used as reference for long evolution plots against reception time **/
 
@@ -148,7 +146,6 @@ private:
     fviHistoZLArgs; /** ZeroLevel histogram arguments in adc counts **/
 
   /// Histograms
-  UInt_t fuReadEvtCnt;
   UInt_t fuMsgsCntInMs;
   UInt_t fuReadMsgsCntInMs;
   UInt_t fuLostMsgsCntInMs;
@@ -156,17 +153,11 @@ private:
 
   /// Channel rate plots
   std::vector<UInt_t> fvuHitCntChanMs;
-  std::vector<UInt_t> fvuErrorCntChanMs;
-  std::vector<UInt_t> fvuEvtLostCntChanMs;
-  std::vector<TH1*> fvhHitCntEvoChan;
-  std::vector<TH2*> fvhHitCntPerMsEvoChan;
   std::vector<TH1*> fvhHitChargeChan;
   std::vector<TH1*> fvhHitZeroLevelChan;
   std::vector<TH1*> fvhHitAmplChan;
   std::vector<TH1*> fvhHitChargeByWfmChan;
-  std::vector<TH2*> fvhHitChargeEvoChan;
   std::vector<TH1*> fvhHitWfmChan;
-  std::vector<TH1*> fvhHitFitWfmChan;
 
   static const UInt_t kuNbWfmRanges   = 8;
   static const UInt_t kuNbWfmExamples = 8;
@@ -181,25 +172,17 @@ private:
   Double_t fdStartTimeSpill;
   Double_t fdLastSecondTime;
   UInt_t fuCountsLastSecond;
-  static const UInt_t kuNbSpillPlots       = 5;
   static const UInt_t kuOffSpillCountLimit = 200;
 
   const UInt_t kuPsdChanMap[kuNbChanPsd] = {
     0};  // = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; //! Map from electronics channel to PSD physical channel
-  TH1* fhChannelMap;
   TH1* fhHitChargeMap;
   TH1* fhHitMapEvo;
   TH2* fhChanHitMapEvo;
-  std::vector<TH1*> fvhChannelMapSpill;
-  TH1* fhHitsPerSpill;
 
   /// Global Rate
-  TH1* fhMsgsCntEvo;
-  TH1* fhReadMsgsCntEvo;
-  TH1* fhLostMsgsCntEvo;
-  TH1* fhReadEvtsCntEvo;
-
-  TH2* fhAdcTimeEvo;
+  TH1* fhMissedData;
+  TH1* fhAdcTime;
   TH2* fhMsLengthEvo;
 
   TH2* fhMsgsCntPerMsEvo;
@@ -208,6 +191,7 @@ private:
   TH2* fhReadEvtsCntPerMsEvo;
 
   /// Waveform fitting
+  std::vector<TH1*> fvhHitFitWfmChan;
   std::vector<TH2*> fvhFitHarmonic1Chan;
   std::vector<TH2*> fvhFitHarmonic2Chan;
   std::vector<TH2*> fvhFitQaChan;
@@ -218,9 +202,8 @@ private:
   TCanvas* fcChargesFPGA;
   TCanvas* fcChargesWfm;
   TCanvas* fcAmplitudes;
+  TCanvas* fcZeroLevels;
   TCanvas* fcGenCntsPerMs;
-  TCanvas* fcSpillCounts;
-  TCanvas* fcSpillCountsHori;
   TCanvas* fcWfmsAllChannels;
   std::vector<TCanvas*> fvcWfmsChan;
   TCanvas* fcPronyFit;
diff --git a/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskPsd.cxx b/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskPsd.cxx
index 6423306e8ab623f155d2902f19b7acb99deb45d7..861b4c477ba27309183ce13ea5723c98d4e039e6 100644
--- a/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskPsd.cxx
+++ b/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskPsd.cxx
@@ -103,6 +103,9 @@ Bool_t CbmMcbm2018MonitorTaskPsd::InitContainers() {
 
   /// Transfer parameter values set from calling macro
   fMonitorAlgo->SetMonitorMode(fbMonitorMode);
+  fMonitorAlgo->SetMonitorChanMode(fbMonitorChanMode);
+  fMonitorAlgo->SetMonitorWfmMode(fbMonitorWfmMode);
+  fMonitorAlgo->SetMonitorFitMode(fbMonitorFitMode);
   fMonitorAlgo->SetHistoryHistoSize(fuHistoryHistoSize);
   fMonitorAlgo->SetChargeHistoArgs(fviHistoChargeArgs);
   fMonitorAlgo->SetAmplHistoArgs(fviHistoAmplArgs);
diff --git a/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskPsd.h b/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskPsd.h
index 1f1cfdac23244c3663c993f14f12c8e01cc3110f..55c5e4e644aa0dc70c6cad75e3fdd5e9111ef6b4 100644
--- a/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskPsd.h
+++ b/fles/mcbm2018/monitor/CbmMcbm2018MonitorTaskPsd.h
@@ -42,6 +42,9 @@ public:
   inline void SetMonitorMode(Bool_t bFlagIn = kTRUE) {
     fbMonitorMode = bFlagIn;
   }
+  inline void SetMonitorChanMode(Bool_t bFlagIn = kTRUE) { fbMonitorChanMode = bFlagIn; }
+  inline void SetMonitorWfmMode(Bool_t bFlagIn = kTRUE) { fbMonitorWfmMode = bFlagIn; }
+  inline void SetMonitorFitMode(Bool_t bFlagIn = kTRUE) { fbMonitorFitMode = bFlagIn; }
   void SetIgnoreOverlapMs(Bool_t bFlagIn = kTRUE);
   inline void SetHistoryHistoSize(UInt_t inHistorySizeSec = 1800) {
     fuHistoryHistoSize = inHistorySizeSec;
@@ -61,6 +64,9 @@ private:
   /// Control flags
   Bool_t
     fbMonitorMode;  //! Switch ON the filling of a minimal set of histograms
+  Bool_t fbMonitorChanMode;  //! Switch ON the filling channelwise histograms
+  Bool_t fbMonitorWfmMode;   //! Switch ON the filling waveforms histograms
+  Bool_t fbMonitorFitMode;   //! Switch ON the filling waveform fitting histograms
   Bool_t
     fbDebugMonitorMode;  //! Switch ON the filling of a additional set of histograms
 
diff --git a/fles/mcbm2018/tasks/CbmMcbmSpillFindAlgo.cxx b/fles/mcbm2018/tasks/CbmMcbmSpillFindAlgo.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0e97224ad02e4663d0ce9e5f7bcc196883bc652f
--- /dev/null
+++ b/fles/mcbm2018/tasks/CbmMcbmSpillFindAlgo.cxx
@@ -0,0 +1,498 @@
+// -----------------------------------------------------------------------------
+// -----                                                                   -----
+// -----                  CbmMcbmSpillFindAlgo                         -----
+// -----               Created 10.02.2019 by P.-A. Loizeau                 -----
+// -----                                                                   -----
+// -----------------------------------------------------------------------------
+
+#include "CbmMcbmSpillFindAlgo.h"
+
+#include "CbmFlesHistosTools.h"
+#include "CbmFormatMsHeaderPrintout.h"
+#include "CbmMcbm2018TofPar.h"
+#include "CbmTofAddress.h"
+#include "CbmTofDetectorId_v14a.h"  // in cbmdata/tof
+
+#include "FairLogger.h"
+#include "FairRootManager.h"
+#include "FairRun.h"
+#include "FairRunOnline.h"
+#include "FairRuntimeDb.h"
+
+#include "TCanvas.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "TList.h"
+#include "TPaveStats.h"
+#include "TProfile.h"
+#include "TROOT.h"
+#include "TString.h"
+
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+
+#include <stdint.h>
+
+// -------------------------------------------------------------------------
+CbmMcbmSpillFindAlgo::CbmMcbmSpillFindAlgo() : CbmStar2019Algo() {}
+CbmMcbmSpillFindAlgo::~CbmMcbmSpillFindAlgo() {}
+
+// -------------------------------------------------------------------------
+Bool_t CbmMcbmSpillFindAlgo::Init()
+{
+  LOG(info) << "Initializing mCBM T0 2019 monitor algo";
+
+  return kTRUE;
+}
+void CbmMcbmSpillFindAlgo::Reset() {}
+void CbmMcbmSpillFindAlgo::Finish()
+{
+  /// If Spill is On, add a fake spill break to have the last spill
+  /// If Spill is Off, add a fake spill break end so that all modes include last spill
+  if (fbSpillOn) {
+    fvuSpillBreakBegTs.push_back(fulCurrentTsIdx + 1);
+    fvuSpillBreakEndTs.push_back(fulCurrentTsIdx + 1);
+  }  // if (fbSpillOn)
+  else
+    fvuSpillBreakEndTs.push_back(fulCurrentTsIdx + 1);
+
+  /// Fill the vector of spill break middle points
+  std::vector<ULong64_t>::iterator itBreakBeg = fvuSpillBreakBegTs.begin();
+  std::vector<ULong64_t>::iterator itBreakEnd = fvuSpillBreakEndTs.begin();
+
+  if (itBreakBeg != fvuSpillBreakBegTs.end() && itBreakEnd != fvuSpillBreakEndTs.end() && *itBreakEnd < *itBreakBeg) {
+    fvuSpillBreakMidTs.push_back((*itBreakEnd + fulFirstTsIdx) / 2);
+    ++itBreakEnd;
+  }  // if( itBreakBeg != fvuSpillBreakBegTs.end() && itBreakEnd != fvuSpillBreakEndTs.end() && *itBreakEnd < *itBreakBeg )
+
+  while (itBreakBeg != fvuSpillBreakBegTs.end() && itBreakEnd != fvuSpillBreakEndTs.end()) {
+    fvuSpillBreakMidTs.push_back((*itBreakBeg + *itBreakEnd) / 2);
+    ++itBreakBeg;
+    ++itBreakEnd;
+  }  // while( itBreakBeg != fvuSpillBreakBegTs.end() && itBreakEnd != fvuSpillBreakEndTs.end() )
+
+  if (itBreakBeg != fvuSpillBreakBegTs.end()) {
+    fvuSpillBreakMidTs.push_back((*itBreakBeg + fulCurrentTsIdx) / 2);
+    ++itBreakBeg;
+  }  // if( itBreakBeg != fvuSpillBreakBegTs.end() )
+
+  if (itBreakBeg != fvuSpillBreakBegTs.end() || itBreakEnd != fvuSpillBreakEndTs.end()) {
+    LOG(warning) << "Size of spill breaks beginning or end did not match: " << fvuSpillBreakBegTs.size() << " VS "
+                 << fvuSpillBreakEndTs.size();
+  }  // if( itBreakBeg != fvuSpillBreakBegTs.end() || itBreakEnd != fvuSpillBreakEndTs.end() )
+
+  LOG(info) << "**********************************************";
+  LOG(info) << "TS index for beginning of spill breaks:";
+  for (ULong64_t uBeg : fvuSpillBreakBegTs) {
+    LOG(info) << Form("%9llu", uBeg);
+  }  // for (ULong64_t uBeg : fvuSpillBreakBegTs)
+  LOG(info) << "**********************************************";
+  LOG(info) << "TS index for ending of spill breaks:";
+  for (ULong64_t uEnd : fvuSpillBreakEndTs) {
+    LOG(info) << Form("%9llu", uEnd);
+  }  // for (ULong64_t uBeg : fvuSpillBreakBegTs)
+  LOG(info) << "**********************************************";
+  LOG(info) << "TS index for middle of spill breaks:";
+  for (ULong64_t uMid : fvuSpillBreakMidTs) {
+    LOG(info) << Form("%9llu", uMid);
+  }  // for (ULong64_t uBeg : fvuSpillBreakBegTs)
+  LOG(info) << "**********************************************";
+}
+
+// -------------------------------------------------------------------------
+Bool_t CbmMcbmSpillFindAlgo::InitContainers()
+{
+  LOG(info) << "Init parameter containers for CbmMcbmSpillFindAlgo";
+  Bool_t initOK = ReInitContainers();
+
+  return initOK;
+}
+Bool_t CbmMcbmSpillFindAlgo::ReInitContainers()
+{
+  LOG(info) << "**********************************************";
+  LOG(info) << "ReInit parameter containers for CbmMcbmSpillFindAlgo";
+
+  fUnpackPar = (CbmMcbm2018TofPar*) fParCList->FindObject("CbmMcbm2018TofPar");
+  if (nullptr == fUnpackPar) return kFALSE;
+
+  Bool_t initOK = InitParameters();
+
+  return initOK;
+}
+TList* CbmMcbmSpillFindAlgo::GetParList()
+{
+  if (nullptr == fParCList) fParCList = new TList();
+  fUnpackPar = new CbmMcbm2018TofPar("CbmMcbm2018TofPar");
+  fParCList->Add(fUnpackPar);
+
+  return fParCList;
+}
+Bool_t CbmMcbmSpillFindAlgo::InitParameters()
+{
+
+  fuNrOfGdpbs = fUnpackPar->GetNrOfGdpbs();
+  LOG(info) << "Nr. of Tof GDPBs: " << fuNrOfGdpbs;
+
+  fuNrOfFeePerGdpb = fUnpackPar->GetNrOfFeesPerGdpb();
+  LOG(info) << "Nr. of FEES per Tof GDPB: " << fuNrOfFeePerGdpb;
+
+  fuNrOfGet4PerFee = fUnpackPar->GetNrOfGet4PerFee();
+  LOG(info) << "Nr. of GET4 per Tof FEE: " << fuNrOfGet4PerFee;
+
+  fuNrOfChannelsPerGet4 = fUnpackPar->GetNrOfChannelsPerGet4();
+  LOG(info) << "Nr. of channels per GET4: " << fuNrOfChannelsPerGet4;
+
+  fuNrOfChannelsPerFee = fuNrOfGet4PerFee * fuNrOfChannelsPerGet4;
+  LOG(info) << "Nr. of channels per FEE: " << fuNrOfChannelsPerFee;
+
+  fuNrOfGet4 = fuNrOfGdpbs * fuNrOfFeePerGdpb * fuNrOfGet4PerFee;
+  LOG(info) << "Nr. of GET4s: " << fuNrOfGet4;
+
+  fuNrOfGet4PerGdpb = fuNrOfFeePerGdpb * fuNrOfGet4PerFee;
+  LOG(info) << "Nr. of GET4s per GDPB: " << fuNrOfGet4PerGdpb;
+
+  fuNrOfChannelsPerGdpb = fuNrOfGet4PerGdpb * fuNrOfChannelsPerGet4;
+  LOG(info) << "Nr. of channels per GDPB: " << fuNrOfChannelsPerGdpb;
+
+  fGdpbIdIndexMap.clear();
+  for (UInt_t i = 0; i < fuNrOfGdpbs; ++i) {
+    fGdpbIdIndexMap[fUnpackPar->GetGdpbId(i)] = i;
+    LOG(info) << "GDPB Id of TOF  " << i << " : " << std::hex << fUnpackPar->GetGdpbId(i) << std::dec;
+  }  // for( UInt_t i = 0; i < fuNrOfGdpbs; ++i )
+
+  return kTRUE;
+}
+// -------------------------------------------------------------------------
+
+void CbmMcbmSpillFindAlgo::AddMsComponentToList(size_t component, UShort_t usDetectorId)
+{
+  /// Check for duplicates and ignore if it is the case
+  for (UInt_t uCompIdx = 0; uCompIdx < fvMsComponentsList.size(); ++uCompIdx)
+    if (component == fvMsComponentsList[uCompIdx]) return;
+
+  /// Add to list
+  fvMsComponentsList.push_back(component);
+
+  LOG(info) << "CbmMcbmSpillFindAlgo::AddMsComponentToList => Component " << component << " with detector ID 0x"
+            << std::hex << usDetectorId << std::dec << " added to list";
+}
+// -------------------------------------------------------------------------
+
+Bool_t CbmMcbmSpillFindAlgo::ProcessTs(const fles::Timeslice& ts)
+{
+  fulCurrentTsIdx = ts.index();
+  fdTsStartTime   = static_cast<Double_t>(ts.descriptor(0, 0).idx);
+  if (fulCurrentTsIdx < fulFirstTsIdx) fulFirstTsIdx = fulCurrentTsIdx;
+
+  /// Ignore First TS as first MS is typically corrupt
+  if (0 == fulCurrentTsIdx) return kTRUE;
+
+  /// On first TS, extract the TS parameters from header (by definition stable over time)
+  if (-1.0 == fdTsCoreSizeInNs) {
+    fuNbCoreMsPerTs  = ts.num_core_microslices();
+    fuNbOverMsPerTs  = ts.num_microslices(0) - ts.num_core_microslices();
+    fdTsCoreSizeInNs = fdMsSizeInNs * (fuNbCoreMsPerTs);
+    fdTsFullSizeInNs = fdMsSizeInNs * (fuNbCoreMsPerTs + fuNbOverMsPerTs);
+    LOG(info) << "Timeslice parameters: each TS has " << fuNbCoreMsPerTs << " Core MS and " << fuNbOverMsPerTs
+              << " Overlap MS, for a core duration of " << fdTsCoreSizeInNs << " ns and a full duration of "
+              << fdTsFullSizeInNs << " ns";
+
+    /// Ignore overlap ms if flag set by user
+    fuNbMsLoop = fuNbCoreMsPerTs;
+    if (kFALSE == fbIgnoreOverlapMs) fuNbMsLoop += fuNbOverMsPerTs;
+    LOG(info) << "In each TS " << fuNbMsLoop << " MS will be looped over";
+  }  // if( -1.0 == fdTsCoreSizeInNs )
+
+  /// Compute time of TS core end
+  fdTsStopTimeCore = fdTsStartTime + fdTsCoreSizeInNs;
+  //      LOG(info) << Form( "TS %5d Start %12f Stop %12f", fulCurrentTsIdx, fdTsStartTime, fdTsStopTimeCore );
+
+  /// Loop over core microslices (and overlap ones if chosen)
+  for (fuMsIndex = 0; fuMsIndex < fuNbMsLoop; fuMsIndex++) {
+    /// Loop over registered components
+    for (UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx) {
+      UInt_t uMsComp = fvMsComponentsList[uMsCompIdx];
+
+      if (kFALSE == ProcessMs(ts, uMsComp, fuMsIndex)) {
+        LOG(error) << "Failed to process ts " << fulCurrentTsIdx << " MS " << fuMsIndex << " for component " << uMsComp;
+        return kFALSE;
+      }  // if( kFALSE == ProcessMs( ts, uMsCompIdx, fuMsIndex ) )
+    }    // for( UInt_t uMsCompIdx = 0; uMsCompIdx < fvMsComponentsList.size(); ++uMsCompIdx )
+  }      // for( fuMsIndex = 0; fuMsIndex < uNbMsLoop; fuMsIndex ++ )
+
+  /// Fill plots if in monitor mode
+  if (fbMonitorMode) {
+    if (kFALSE == FillHistograms()) {
+      LOG(error) << "Failed to fill histos in ts " << fulCurrentTsIdx;
+      return kFALSE;
+    }  // if( kFALSE == FillHistograms() )
+  }    // if( fbMonitorMode )
+
+  return kTRUE;
+}
+
+Bool_t CbmMcbmSpillFindAlgo::ProcessMs(const fles::Timeslice& ts, size_t uMsCompIdx, size_t uMsIdx)
+{
+  auto msDescriptor        = ts.descriptor(uMsCompIdx, uMsIdx);
+  fuCurrentEquipmentId     = msDescriptor.eq_id;
+  const uint8_t* msContent = reinterpret_cast<const uint8_t*>(ts.content(uMsCompIdx, uMsIdx));
+
+  uint32_t uSize  = msDescriptor.size;
+  fulCurrentMsIdx = msDescriptor.idx;
+  fdMsTime        = (1e-9) * static_cast<double>(fulCurrentMsIdx);
+  LOG(debug) << "Microslice: " << fulCurrentMsIdx << " from EqId " << std::hex << fuCurrentEquipmentId << std::dec
+             << " has size: " << uSize;
+
+  if (0 == fvbMaskedComponents.size()) fvbMaskedComponents.resize(ts.num_components(), kFALSE);
+
+  fuCurrDpbId = static_cast<uint32_t>(fuCurrentEquipmentId & 0xFFFF);
+
+  /*
+ * Should be only for first detected TS
+ */
+  if (fulCurrentTsIdx < 10 && 0 == uMsIdx) {
+    LOG(INFO) << "---------------------------------------------------------------";
+    LOG(INFO) << "Component " << uMsCompIdx << " TS Idx " << fulCurrentTsIdx;
+    LOG(INFO) << "hi hv eqid flag si sv idx/start        crc      size     offset";
+    LOG(INFO) << Form("%02x %02x %04x %04x %02x %02x %016lx %08x %08x %016lx",
+                      static_cast<unsigned int>(msDescriptor.hdr_id), static_cast<unsigned int>(msDescriptor.hdr_ver),
+                      msDescriptor.eq_id, msDescriptor.flags, static_cast<unsigned int>(msDescriptor.sys_id),
+                      static_cast<unsigned int>(msDescriptor.sys_ver), static_cast<unsigned long>(msDescriptor.idx),
+                      msDescriptor.crc, msDescriptor.size, static_cast<unsigned long>(msDescriptor.offset));
+  }  // if( fulCurrentTsIdx < 10 && 0 == uMsIdx )
+     /*
+*/
+
+  /// Check if this sDPB ID was declared in parameter file and stop there if not
+  auto it = fGdpbIdIndexMap.find(fuCurrDpbId);
+  if (it == fGdpbIdIndexMap.end()) {
+    if (kFALSE == fvbMaskedComponents[uMsCompIdx]) {
+      LOG(info) << "---------------------------------------------------------------";
+      /*
+          LOG(info) << "hi hv eqid flag si sv idx/start        crc      size     offset";
+          LOG(info) << Form( "%02x %02x %04x %04x %02x %02x %016llx %08x %08x %016llx",
+                            static_cast<unsigned int>(msDescriptor.hdr_id),
+                            static_cast<unsigned int>(msDescriptor.hdr_ver), msDescriptor.eq_id, msDescriptor.flags,
+                            static_cast<unsigned int>(msDescriptor.sys_id),
+                            static_cast<unsigned int>(msDescriptor.sys_ver), msDescriptor.idx, msDescriptor.crc,
+                            msDescriptor.size, msDescriptor.offset );
+*/
+      LOG(info) << FormatMsHeaderPrintout(msDescriptor);
+      LOG(warning) << "Could not find the gDPB index for AFCK id 0x" << std::hex << fuCurrDpbId << std::dec
+                   << " in timeslice " << fulCurrentTsIdx << " in microslice " << uMsIdx << " component " << uMsCompIdx
+                   << "\n"
+                   << "If valid this index has to be added in the TOF "
+                      "parameter file in the DbpIdArray field";
+      fvbMaskedComponents[uMsCompIdx] = kTRUE;
+    }  // if( kFALSE == fvbMaskedComponents[ uMsComp ] )
+    else
+      return kTRUE;
+
+    /// Try to get it from the second message in buffer (first is epoch cycle without gDPB ID)
+    /// TODO!!!!
+
+    return kFALSE;
+  }  // if( it == fGdpbIdIndexMap.end() )
+  else
+    fuCurrDpbIdx = fGdpbIdIndexMap[fuCurrDpbId];
+
+  /// Spill Detection
+  if (0 == fuCurrDpbIdx) {
+    /// Check only every user defined interval (0.5s per default)
+    if (fdSpillCheckInterval < fdMsTime - fdLastSecondTime) {
+      /// Spill Off detection
+      if (fbSpillOn && fuCountsLastInterval < fuOffSpillCountLimit) {
+        fbSpillOn = kFALSE;
+        fuCurrentSpillIdx++;
+        fdStartTimeSpill = fdMsTime;
+        if (0 < fvuSpillBreakBegTs.size()) {
+          fhSpillDuration->Fill(fulCurrentTsIdx - fvuSpillBreakBegTs.back());
+        }  // if( 0 < fvuSpillBreakBegTs.size() )
+        fvuSpillBreakBegTs.push_back(fulCurrentTsIdx);
+      }  // if( fbSpillOn && fuCountsLastInterval < fuOffSpillCountLimit )
+      else if (!fbSpillOn && fuOffSpillCountLimit < fuCountsLastInterval) {
+        fbSpillOn = kTRUE;
+        if (0 < fvuSpillBreakBegTs.size()) {
+          fhSpillBreakDuration->Fill(fuCurrentSpillIdx, fulCurrentTsIdx - fvuSpillBreakBegTs.back());
+        }  // if( 0 < fvuSpillBreakBegTs.size() )
+        if (0 < fvuSpillBreakEndTs.size()) {
+          fhHitsPerSpill->Fill(fuCurrentSpillIdx, fuCountsLastSpill);
+          fhSpillDuration->Fill(fuCurrentSpillIdx, fulCurrentTsIdx - fvuSpillBreakEndTs.back());
+        }  // if( 0 < fvuSpillBreakEndTs.size() )
+        fvuSpillBreakEndTs.push_back(fulCurrentTsIdx);
+        fuCountsLastSpill = 0;
+      }  // else if (fuOffSpillCountLimit < fuCountsLastInterval)
+
+      fuCountsLastInterval = 0;
+      fdLastSecondTime     = fdMsTime;
+    }  // if( fdSpillCheckInterval < fdMsTime - fdLastSecondTime )
+  }    // if( 0 == fuCurrDpbIdx )
+
+  /// Save start time of first valid MS )
+  if (fdStartTime < 0) fdStartTime = fdMsTime;
+  /// Reset the histograms if reached the end of the evolution histos range
+  else if (fuHistoryHistoSize < fdMsTime - fdStartTime) {
+    ResetHistograms();
+    fdStartTime = fdMsTime;
+  }  // else if( fuHistoryHistoSize < fdMsTime - fdStartTime )
+
+  // If not integer number of message in input buffer, print warning/error
+  if (0 != (uSize % kuBytesPerMessage))
+    LOG(error) << "The input microslice buffer does NOT "
+               << "contain only complete nDPB messages!";
+
+  // Compute the number of complete messages in the input microslice buffer
+  uint32_t uNbMessages = (uSize - (uSize % kuBytesPerMessage)) / kuBytesPerMessage;
+
+  // Prepare variables for the loop on contents
+  Int_t messageType       = -111;
+  ULong64_t ulNbHitsTs    = 0;
+  const uint64_t* pInBuff = reinterpret_cast<const uint64_t*>(msContent);
+  for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx++) {
+    // Fill message
+    uint64_t ulData = static_cast<uint64_t>(pInBuff[uIdx]);
+
+    /// Catch the Epoch cycle block which is always the first 64b of the MS
+    if (0 == uIdx) { continue; }  // if( 0 == uIdx )
+
+    gdpbv100::Message mess(ulData);
+    /// Get message type
+    messageType = mess.getMessageType();
+
+    fuGet4Id = mess.getGdpbGenChipId();
+    fuGet4Nr = fuGet4Id / 2;
+    // UInt_t uChannelT0 = ( fuGet4Id < 32 ) ? ( fuGet4Id / 8 ) : (fuGet4Id / 8 - 1); /// December 2018 mapping
+    // UInt_t uChannelT0 = fuGet4Id / 2 + 4 * fuCurrDpbIdx;  /// 2019 mapping with 320/640 Mb/s FW
+
+    if (fuNrOfGet4PerGdpb <= fuGet4Id && !mess.isStarTrigger() && (gdpbv100::kuChipIdMergedEpoch != fuGet4Id))
+      LOG(warning) << "Message with Get4 ID too high: " << fuGet4Id << " VS " << fuNrOfGet4PerGdpb
+                   << " set in parameters.";
+
+    switch (messageType) {
+      case gdpbv100::MSG_HIT: {
+        if (mess.getGdpbHitIs24b()) {
+          LOG(error) << "This event builder does not support 24b hit message!!!.";
+          continue;
+        }  // if( getGdpbHitIs24b() )
+        else {
+          /// Spill detection
+
+          /// Do not fill the pulser hits to keep counts low for channel 0
+          /// => Check channel != first GET4 per board + TOT
+          UInt_t uTot = mess.getGdpbHit32Tot();
+          if (0 != fuGet4Nr || uTot < fuMinTotPulser || fuMaxTotPulser < uTot) {
+            fuCountsLastInterval++;
+            fuCountsLastSpill++;
+            ulNbHitsTs++;
+          }  // if (0 != fuGet4Nr || uTot < fuMinTotPulser || fuMaxTotPulser < uTot) {
+        }    // else of if( getGdpbHitIs24b() )
+        break;
+      }  // case gdpbv100::MSG_HIT:
+      case gdpbv100::MSG_EPOCH: {
+        break;
+      }  // case gdpbv100::MSG_EPOCH:
+      case gdpbv100::MSG_SLOWC: {
+        break;
+      }  // case gdpbv100::MSG_SLOWC:
+      case gdpbv100::MSG_SYST: {
+        break;
+      }  // case gdpbv100::MSG_SYST:
+      case gdpbv100::MSG_STAR_TRI_A:
+      case gdpbv100::MSG_STAR_TRI_B:
+      case gdpbv100::MSG_STAR_TRI_C:
+      case gdpbv100::MSG_STAR_TRI_D: {
+        break;
+      }  // case gdpbv100::MSG_STAR_TRI_A-D
+      default:
+        LOG(error) << "Message type " << std::hex << std::setw(2) << static_cast<uint16_t>(messageType)
+                   << " not included in Get4 unpacker.";
+    }  // switch( mess.getMessageType() )
+  }    // for (uint32_t uIdx = 0; uIdx < uNbMessages; uIdx ++)
+  fhHitsEvo->Fill(fdTsStartTime * 1e-9, ulNbHitsTs);
+
+  /// Fill histograms
+  FillHistograms();
+
+  return kTRUE;
+}
+// -------------------------------------------------------------------------
+Bool_t CbmMcbmSpillFindAlgo::CreateHistograms()
+{
+  std::string sFolder = "SpillFinder";
+
+  LOG(info) << "create Histos for T0 monitoring ";
+
+  /// Logarithmic bining
+  uint32_t iNbBinsLog = 0;
+  /// Parameters are NbDecadesLog, NbStepsDecade, NbSubStepsInStep
+  std::vector<double> dBinsLogVector = GenerateLogBinArray(4, 9, 1, iNbBinsLog);
+  double* dBinsLog                   = dBinsLogVector.data();
+  //   double * dBinsLog = GenerateLogBinArray( 4, 9, 1, iNbBinsLog );
+
+  /*******************************************************************/
+  fhHitsEvo =
+    new TH1I("hHitsEvo", "Hit count evo; Time [s]; Hits Count []", fuHistoryHistoSize * 50, 0., fuHistoryHistoSize);
+  fhHitsPerSpill       = new TH1I("hHitsPerSpill", "Hit count per spill; Spill; Hits Count []", 2000, 0., 2000);
+  fhSpillBreakDuration = new TH1I("hSpillBreakDuration", "Spill break duration; Spill; Duration [TS]", 2000, 0., 2000);
+  fhSpillDuration      = new TH1I("hSpillDuration", "Spill duration; Spill; Duration [TS]", 2000, 0., 2000);
+
+  /// Add pointers to the vector with all histo for access by steering class
+  AddHistoToVector(fhHitsEvo, sFolder);
+  AddHistoToVector(fhHitsPerSpill, sFolder);
+  AddHistoToVector(fhSpillBreakDuration, sFolder);
+  AddHistoToVector(fhSpillDuration, sFolder);
+
+  /*******************************************************************/
+  /// Cleanup array of log bins
+  //   delete dBinsLog;
+
+  /*******************************************************************/
+
+  /// Canvases
+  Double_t w = 10;
+  Double_t h = 10;
+
+  /*******************************************************************/
+  /*
+  /// Map of hits over T0 detector and same vs time in run
+  fcHitMaps = new TCanvas("cHitMaps", "Hit maps", w, h);
+  fcHitMaps->Divide(2);
+
+  fcHitMaps->cd(1);
+  gPad->SetGridx();
+  gPad->SetGridy();
+  gPad->SetLogy();
+  fhChannelMap->Draw();
+
+  fcHitMaps->cd(2);
+  gPad->SetGridx();
+  gPad->SetGridy();
+  gPad->SetLogz();
+  fhHitMapEvo->Draw("colz");
+
+  AddCanvasToVector(fcHitMaps, "canvases");
+*/
+  /*******************************************************************/
+
+  /*******************************************************************/
+
+  return kTRUE;
+}
+Bool_t CbmMcbmSpillFindAlgo::FillHistograms() { return kTRUE; }
+Bool_t CbmMcbmSpillFindAlgo::ResetHistograms(Bool_t bResetTime)
+{
+  fuCurrentSpillIdx = 0;
+  fhHitsEvo->Reset();
+  fhHitsPerSpill->Reset();
+  fhSpillBreakDuration->Reset();
+  fhSpillDuration->Reset();
+
+  if (kTRUE == bResetTime) {
+    /// Also reset the Start time for the evolution plots!
+    fdStartTime = -1.0;
+  }  // if( kTRUE == bResetTime )
+
+  return kTRUE;
+}
+// -------------------------------------------------------------------------
diff --git a/fles/mcbm2018/tasks/CbmMcbmSpillFindAlgo.h b/fles/mcbm2018/tasks/CbmMcbmSpillFindAlgo.h
new file mode 100644
index 0000000000000000000000000000000000000000..f056431e52ddc328b468bd59731dd8ef236eb718
--- /dev/null
+++ b/fles/mcbm2018/tasks/CbmMcbmSpillFindAlgo.h
@@ -0,0 +1,164 @@
+// -----------------------------------------------------------------------------
+// -----                                                                   -----
+// -----                  CbmMcbmSpillFindAlgo                         -----
+// -----               Created 10.02.2019 by P.-A. Loizeau                 -----
+// -----                                                                   -----
+// -----------------------------------------------------------------------------
+
+#ifndef CbmMcbmSpillFindAlgo_H
+#define CbmMcbmSpillFindAlgo_H
+
+#include "CbmStar2019Algo.h"
+
+// Data
+#include "CbmTofDigi.h"
+
+#include "gDpbMessv100.h"
+
+// CbmRoot
+
+// C++11
+#include <chrono>
+
+// C/C++
+#include <map>
+#include <vector>
+
+class CbmMcbm2018TofPar;
+/*
+class TCanvas;
+class THttpServer;
+*/
+class TH1;
+class TH2;
+class TProfile;
+
+class CbmMcbmSpillFindAlgo : public CbmStar2019Algo<CbmTofDigi> {
+public:
+  CbmMcbmSpillFindAlgo();
+  ~CbmMcbmSpillFindAlgo();
+
+  virtual Bool_t Init();
+  virtual void Reset();
+  virtual void Finish();
+
+  Bool_t InitContainers();
+  Bool_t ReInitContainers();
+  TList* GetParList();
+
+  Bool_t InitParameters();
+
+  Bool_t ProcessTs(const fles::Timeslice& ts);
+  Bool_t ProcessTs(const fles::Timeslice& ts, size_t /*component*/) { return ProcessTs(ts); }
+  Bool_t ProcessMs(const fles::Timeslice& ts, size_t uMsCompIdx, size_t uMsIdx);
+
+  void AddMsComponentToList(size_t component, UShort_t usDetectorId);
+
+  Bool_t CreateHistograms();
+  Bool_t FillHistograms();
+  Bool_t ResetHistograms(Bool_t bResetTime = kTRUE);
+
+  inline void SetMonitorMode(Bool_t bFlagIn = kTRUE) { fbMonitorMode = bFlagIn; }
+  inline void SetHistoryHistoSize(UInt_t inHistorySizeSec = 1800) { fuHistoryHistoSize = inHistorySizeSec; }
+  inline void SetPulserTotLimits(UInt_t uMin, UInt_t uMax)
+  {
+    fuMinTotPulser = uMin;
+    fuMaxTotPulser = uMax;
+  }
+  inline void SetSpillThreshold(UInt_t uCntLimit) { fuOffSpillCountLimit = uCntLimit; }
+  inline void SetSpillCheckIntervalSec(Double_t dInterval) { fdSpillCheckInterval = dInterval; }
+
+private:
+  /// Control flags
+  Bool_t fbMonitorMode                    = kFALSE;  //! Switch ON the filling of a minimal set of histograms
+  Bool_t fbDebugMonitorMode               = kFALSE;  //! Switch ON the filling of a additional set of histograms
+  std::vector<Bool_t> fvbMaskedComponents = {};
+
+  /// Settings from parameter file
+  CbmMcbm2018TofPar* fUnpackPar = nullptr;  //!
+    /// Readout chain dimensions and mapping
+  UInt_t fuNrOfGdpbs                       = 0;   //! Total number of GDPBs in the system
+  std::map<UInt_t, UInt_t> fGdpbIdIndexMap = {};  //! gDPB ID to index map
+  UInt_t fuNrOfFeePerGdpb                  = 0;   //! Number of FEBs per GDPB
+  UInt_t fuNrOfGet4PerFee                  = 0;   //! Number of GET4s per FEE
+  UInt_t fuNrOfChannelsPerGet4             = 0;   //! Number of channels in each GET4
+  UInt_t fuNrOfChannelsPerFee              = 0;   //! Number of channels in each FEE
+  UInt_t fuNrOfGet4                        = 0;   //! Total number of Get4 chips in the system
+  UInt_t fuNrOfGet4PerGdpb                 = 0;   //! Number of GET4s per GDPB
+  UInt_t fuNrOfChannelsPerGdpb             = 0;   //! Number of channels per GDPB
+
+  /// User settings: Data correction parameters
+  UInt_t fuMinTotPulser         = 90;
+  UInt_t fuMaxTotPulser         = 100;
+  UInt_t fuOffSpillCountLimit   = 100;
+  Double_t fdSpillCheckInterval = 0.5;
+
+  /// Constants
+  static const Int_t kiMaxNbFlibLinks   = 32;
+  static const UInt_t kuBytesPerMessage = 8;
+  static const UInt_t kuNbChanDiamond   = 8;
+
+  /// Running indices
+  /// TS/MS info
+  ULong64_t fulFirstTsIdx   = 9999999999999;  //! First TS index, forward point set ~30 years...
+  ULong64_t fulCurrentTsIdx = 0;
+  ULong64_t fulCurrentMsIdx = 0;
+  Double_t fdTsStartTime    = -1.0;  //! Time in ns of current TS from the index of the first MS first component
+  Double_t fdTsStopTimeCore =
+    -1.0;                    //! End Time in ns of current TS Core from the index of the first MS first component
+  Double_t fdMsTime = -1.0;  //! Start Time in ns of current MS from its index field in header
+  UInt_t fuMsIndex  = 0;     //! Index of current MS within the TS
+                             /// Current data properties
+  std::map<gdpbv100::MessageTypes, UInt_t> fmMsgCounter = {};
+  UInt_t fuCurrentEquipmentId = 0;   //! Current equipment ID, tells from which DPB the current MS is originating
+  UInt_t fuCurrDpbId          = 0;   //! Temp holder until Current equipment ID is properly filled in MS
+  UInt_t fuCurrDpbIdx         = 0;   //! Index of the DPB from which the MS currently unpacked is coming
+  Int_t fiRunStartDateTimeSec = -1;  //! Start of run time since "epoch" in s, for the plots with date as X axis
+  Int_t fiBinSizeDatePlots    = -1;  //! Bin size in s for the plots with date as X axis
+  UInt_t fuGet4Id =
+    0;  //! running number (0 to fuNrOfGet4PerGdpb) of the Get4 chip of a unique GDPB for current message
+  UInt_t fuGet4Nr = 0;  //! running number (0 to fuNrOfGet4) of the Get4 chip in the system for current message
+
+  /// Starting state book-keeping
+  Double_t fdStartTime     = -1.0;  //! Time of first valid hit (epoch available), used as reference for evolution plots
+  Double_t fdStartTimeMsSz = 0.0;   //! Time of first microslice, used as reference for evolution plots
+  std::chrono::steady_clock::time_point ftStartTimeUnix = std::chrono::steady_clock::
+    now();  //! Time of run Start from UNIX system, used as reference for long evolution plots against reception time
+
+  /// Spill detection
+  Bool_t fbSpillOn                          = kTRUE;
+  UInt_t fuCurrentSpillIdx                  = 0;
+  Double_t fdStartTimeSpill                 = -1.0;
+  Double_t fdLastSecondTime                 = -1.0;
+  UInt_t fuCountsLastInterval               = 0;
+  UInt_t fuCountsLastSpill                  = 0;
+  std::vector<ULong64_t> fvuSpillBreakBegTs = {};
+  std::vector<ULong64_t> fvuSpillBreakEndTs = {};
+  std::vector<ULong64_t> fvuSpillBreakMidTs = {};
+
+  /// Histograms related variables
+  UInt_t fuHistoryHistoSize = 3600; /** Size in seconds of the evolution histograms **/
+
+  /// Histograms
+  TH1* fhHitsEvo            = nullptr;
+  TH1* fhHitsPerSpill       = nullptr;
+  TH1* fhSpillBreakDuration = nullptr;
+  TH1* fhSpillDuration      = nullptr;
+
+  /// Canvases
+  /*
+  TCanvas* fcSummary            = nullptr;
+  TCanvas* fcHitMaps            = nullptr;
+  TCanvas* fcGenCntsPerMs       = nullptr;
+  TCanvas* fcSpillCounts        = nullptr;
+  TCanvas* fcSpillCountsHori    = nullptr;
+  TCanvas* fcSpillDpbCountsHori = nullptr;
+*/
+
+  CbmMcbmSpillFindAlgo(const CbmMcbmSpillFindAlgo&);
+  CbmMcbmSpillFindAlgo operator=(const CbmMcbmSpillFindAlgo&);
+
+  ClassDef(CbmMcbmSpillFindAlgo, 1)
+};
+
+#endif
diff --git a/fles/mcbm2018/tasks/CbmMcbmSpillFindTask.cxx b/fles/mcbm2018/tasks/CbmMcbmSpillFindTask.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..cd2548beb8da36dae8bd13f870da2f41847bd8e6
--- /dev/null
+++ b/fles/mcbm2018/tasks/CbmMcbmSpillFindTask.cxx
@@ -0,0 +1,216 @@
+// -----------------------------------------------------------------------------
+// -----                                                                   -----
+// -----                     CbmMcbmSpillFindTask                      -----
+// -----               Created 10.02.2019 by P.-A. Loizeau                 -----
+// -----                                                                   -----
+// -----------------------------------------------------------------------------
+
+#include "CbmMcbmSpillFindTask.h"
+
+#include "CbmMcbm2018TofPar.h"
+#include "CbmMcbmSpillFindAlgo.h"
+
+#include "FairLogger.h"
+#include "FairParGenericSet.h"
+#include "FairRootManager.h"
+#include "FairRun.h"
+#include "FairRunOnline.h"
+#include "FairRuntimeDb.h"
+
+#include "TCanvas.h"
+#include "THttpServer.h"
+#include "TList.h"
+#include "TROOT.h"
+#include "TString.h"
+#include <TFile.h>
+
+#include <chrono>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+
+#include <stdint.h>
+
+Bool_t bMcbmSpillFindResetHistos = kFALSE;
+
+CbmMcbmSpillFindTask::CbmMcbmSpillFindTask()
+  : CbmMcbmUnpack()
+  , fbMonitorMode(kTRUE)
+  , fbDebugMonitorMode(kFALSE)
+  , fuHistoryHistoSize(3600)
+  , fsHistoFileName("data/HistosMonitorT0.root")
+  , fuMinTotPulser(90)
+  , fuMaxTotPulser(100)
+  , fuOffSpillCountLimit(200)
+  , fulTsCounter(0)
+  , fMonitorAlgo(nullptr)
+{
+  fMonitorAlgo = new CbmMcbmSpillFindAlgo();
+}
+
+CbmMcbmSpillFindTask::~CbmMcbmSpillFindTask() { delete fMonitorAlgo; }
+
+Bool_t CbmMcbmSpillFindTask::Init()
+{
+  LOG(info) << "CbmMcbmSpillFindTask::Init";
+  LOG(info) << "Initializing mCBM T0 2019 Monitor";
+
+  return kTRUE;
+}
+
+void CbmMcbmSpillFindTask::SetParContainers()
+{
+  LOG(info) << "Setting parameter containers for " << GetName();
+
+  TList* parCList = fMonitorAlgo->GetParList();
+
+  for (Int_t iparC = 0; iparC < parCList->GetEntries(); ++iparC) {
+    FairParGenericSet* tempObj = (FairParGenericSet*) (parCList->At(iparC));
+    parCList->Remove(tempObj);
+
+    std::string sParamName {tempObj->GetName()};
+    FairParGenericSet* newObj =
+      dynamic_cast<FairParGenericSet*>(FairRun::Instance()->GetRuntimeDb()->getContainer(sParamName.data()));
+
+    if (nullptr == newObj) {
+      LOG(error) << "Failed to obtain parameter container " << sParamName << ", for parameter index " << iparC;
+      return;
+    }  // if( nullptr == newObj )
+
+    parCList->AddAt(newObj, iparC);
+    //      delete tempObj;
+  }  // for( Int_t iparC = 0; iparC < parCList->GetEntries(); ++iparC )
+}
+
+Bool_t CbmMcbmSpillFindTask::InitContainers()
+{
+  LOG(info) << "Init parameter containers for " << GetName();
+
+  /// Control flags
+  CbmMcbm2018TofPar* pUnpackPar =
+    dynamic_cast<CbmMcbm2018TofPar*>(FairRun::Instance()->GetRuntimeDb()->getContainer("CbmMcbm2018TofPar"));
+  if (nullptr == pUnpackPar) {
+    LOG(error) << "Failed to obtain parameter container CbmMcbm2018TofPar";
+    return kFALSE;
+  }  // if( nullptr == pUnpackPar )
+
+  Bool_t initOK = fMonitorAlgo->InitContainers();
+
+  /// Transfer parameter values set from calling macro
+  fMonitorAlgo->SetMonitorMode(fbMonitorMode);
+  fMonitorAlgo->SetHistoryHistoSize(fuHistoryHistoSize);
+  fMonitorAlgo->SetPulserTotLimits(fuMinTotPulser, fuMaxTotPulser);
+  fMonitorAlgo->SetSpillThreshold(fuOffSpillCountLimit);
+  fMonitorAlgo->SetSpillCheckIntervalSec(fdSpillCheckInterval);
+
+  /// Histos creation, obtain pointer on them and add them to the HTTP server
+  /// Trigger histo creation on all associated algos
+  initOK &= fMonitorAlgo->CreateHistograms();
+
+  /// Obtain vector of pointers on each histo from the algo (+ optionally desired folder)
+  std::vector<std::pair<TNamed*, std::string>> vHistos = fMonitorAlgo->GetHistoVector();
+  /// Obtain vector of pointers on each canvas from the algo (+ optionally desired folder)
+  std::vector<std::pair<TCanvas*, std::string>> vCanvases = fMonitorAlgo->GetCanvasVector();
+
+  /// Register the histos in the HTTP server
+  THttpServer* server = FairRunOnline::Instance()->GetHttpServer();
+  if (nullptr != server) {
+    for (UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto) {
+      //         LOG(info) << "Registering  " << vHistos[ uHisto ].first->GetName()
+      //                   << " in " << vHistos[ uHisto ].second.data();
+      server->Register(Form("/%s", vHistos[uHisto].second.data()), vHistos[uHisto].first);
+    }  // for( UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto )
+
+    for (UInt_t uCanv = 0; uCanv < vCanvases.size(); ++uCanv) {
+      //         LOG(info) << "Registering  " << vCanvases[ uCanv ].first->GetName()
+      //                   << " in " << vCanvases[ uCanv ].second.data();
+      server->Register(Form("/%s", vCanvases[uCanv].second.data()),
+                       gROOT->FindObject((vCanvases[uCanv].first)->GetName()));
+    }  //  for( UInt_t uCanv = 0; uCanv < vCanvases.size(); ++uCanv )
+
+    server->RegisterCommand("/Reset_MoniT0_Hist", "bMcbmSpillFindResetHistos=kTRUE");
+    server->Restrict("/Reset_MoniT0_Hist", "allow=admin");
+  }  // if( nullptr != server )
+
+  return initOK;
+}
+
+Bool_t CbmMcbmSpillFindTask::ReInitContainers()
+{
+  LOG(info) << "ReInit parameter containers for " << GetName();
+  Bool_t initOK = fMonitorAlgo->ReInitContainers();
+
+  return initOK;
+}
+
+void CbmMcbmSpillFindTask::AddMsComponentToList(size_t component, UShort_t usDetectorId)
+{
+  fMonitorAlgo->AddMsComponentToList(component, usDetectorId);
+}
+
+Bool_t CbmMcbmSpillFindTask::DoUnpack(const fles::Timeslice& ts, size_t /*component*/)
+{
+  if (fbMonitorMode && bMcbmSpillFindResetHistos) {
+    LOG(info) << "Reset T0 Monitor histos ";
+    fMonitorAlgo->ResetHistograms();
+    bMcbmSpillFindResetHistos = kFALSE;
+  }  // if( fbMonitorMode && bMcbmSpillFindResetHistos )
+
+  if (kFALSE == fMonitorAlgo->ProcessTs(ts)) {
+    LOG(error) << "Failed processing TS " << ts.index() << " in unpacker algorithm class";
+    return kTRUE;
+  }  // if( kFALSE == fMonitorAlgo->ProcessTs( ts ) )
+
+  /// Cleqr the digis vector in case it was filled
+  std::vector<CbmTofDigi> vDigi = fMonitorAlgo->GetVector();
+  fMonitorAlgo->ClearVector();
+
+  if (0 == fulTsCounter % 1000) LOG(info) << "Processed " << fulTsCounter << "TS";
+  fulTsCounter++;
+
+  return kTRUE;
+}
+
+void CbmMcbmSpillFindTask::Reset() {}
+
+void CbmMcbmSpillFindTask::Finish()
+{
+  fMonitorAlgo->Finish();
+
+  /// Obtain vector of pointers on each histo from the algo (+ optionally desired folder)
+  std::vector<std::pair<TNamed*, std::string>> vHistos = fMonitorAlgo->GetHistoVector();
+
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
+  TFile* histoFile = nullptr;
+
+  // open separate histo file in recreate mode
+  histoFile = new TFile(fsHistoFileName, "RECREATE");
+  histoFile->cd();
+
+  /// Save the histograms in a file
+  for (UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto) {
+    /// Make sure we end up in chosen folder
+    TString sFolder = vHistos[uHisto].second.data();
+    if (nullptr == gDirectory->Get(sFolder)) gDirectory->mkdir(sFolder);
+    gDirectory->cd(sFolder);
+
+    /// Write plot
+    vHistos[uHisto].first->Write();
+
+    histoFile->cd();
+  }  // for( UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto )
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
+
+  histoFile->Close();
+}
+
+void CbmMcbmSpillFindTask::SetIgnoreOverlapMs(Bool_t bFlagIn) { fMonitorAlgo->SetIgnoreOverlapMs(bFlagIn); }
+
+
+ClassImp(CbmMcbmSpillFindTask)
diff --git a/fles/mcbm2018/tasks/CbmMcbmSpillFindTask.h b/fles/mcbm2018/tasks/CbmMcbmSpillFindTask.h
new file mode 100644
index 0000000000000000000000000000000000000000..45d639883ecc8858b3f8e5a21c4693c5c3f3e47f
--- /dev/null
+++ b/fles/mcbm2018/tasks/CbmMcbmSpillFindTask.h
@@ -0,0 +1,77 @@
+// -----------------------------------------------------------------------------
+// -----                                                                   -----
+// -----                     CbmMcbmSpillFindTaskzz                      -----
+// -----               Created 10.02.2019 by P.-A. Loizeau                 -----
+// -----                                                                   -----
+// -----------------------------------------------------------------------------
+
+#ifndef CbmMcbmSpillFindTask_H
+#define CbmMcbmSpillFindTask_H
+
+#include "CbmMcbmSpillFindAlgo.h"
+#include "CbmMcbmUnpack.h"
+
+#include "Timeslice.hpp"
+
+#include "TString.h"
+
+class CbmMcbmSpillFindTask : public CbmMcbmUnpack {
+public:
+  CbmMcbmSpillFindTask();
+  CbmMcbmSpillFindTask(const CbmMcbmSpillFindTask&) = delete;
+  CbmMcbmSpillFindTask operator=(const CbmMcbmSpillFindTask&) = delete;
+
+  virtual ~CbmMcbmSpillFindTask();
+
+  virtual Bool_t Init();
+  virtual Bool_t DoUnpack(const fles::Timeslice& ts, size_t component);
+  virtual void Reset();
+
+  virtual void Finish();
+
+  void SetParContainers();
+
+  Bool_t InitContainers();
+
+  Bool_t ReInitContainers();
+
+  /// Temp until we change from CbmMcbmUnpack to something else
+  void AddMsComponentToList(size_t component, UShort_t usDetectorId);
+  void SetNbMsInTs(size_t /*uCoreMsNb*/, size_t /*uOverlapMsNb*/) {};
+
+  /// Algo settings setters
+  inline void SetMonitorMode(Bool_t bFlagIn = kTRUE) { fbMonitorMode = bFlagIn; }
+  void SetIgnoreOverlapMs(Bool_t bFlagIn = kTRUE);
+  inline void SetHistoryHistoSize(UInt_t inHistorySizeSec = 1800) { fuHistoryHistoSize = inHistorySizeSec; }
+  inline void SetHistoFilename(TString sNameIn) { fsHistoFileName = sNameIn; }
+  inline void SetPulserTotLimits(UInt_t uMin, UInt_t uMax)
+  {
+    fuMinTotPulser = uMin;
+    fuMaxTotPulser = uMax;
+  }
+  inline void SetSpillThreshold(UInt_t uCntLimit) { fuOffSpillCountLimit = uCntLimit; }
+  inline void SetSpillCheckIntervalSec(Double_t dInterval) { fdSpillCheckInterval = dInterval; }
+
+private:
+  /// Control flags
+  Bool_t fbMonitorMode;       //! Switch ON the filling of a minimal set of histograms
+  Bool_t fbDebugMonitorMode;  //! Switch ON the filling of a additional set of histograms
+
+  /// User settings parameters
+  UInt_t fuHistoryHistoSize;
+  TString fsHistoFileName;
+  UInt_t fuMinTotPulser;
+  UInt_t fuMaxTotPulser;
+  UInt_t fuOffSpillCountLimit;
+  Double_t fdSpillCheckInterval = 0.5;
+
+  /// Statistics & first TS rejection
+  uint64_t fulTsCounter;
+
+  /// Processing algo
+  CbmMcbmSpillFindAlgo* fMonitorAlgo;
+
+  ClassDef(CbmMcbmSpillFindTask, 1)
+};
+
+#endif
diff --git a/macro/beamtime/mcbm2020/CMakeLists.txt b/macro/beamtime/mcbm2020/CMakeLists.txt
index 7813b2ecf71f80207a1bf0c17c09035d87c39b7c..79b3b909bb58bbe73b42a051774220e1504d2748 100644
--- a/macro/beamtime/mcbm2020/CMakeLists.txt
+++ b/macro/beamtime/mcbm2020/CMakeLists.txt
@@ -25,6 +25,7 @@ If(DEFINED ENV{RAW_DATA_PATH} )
   GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/beamtime/mcbm2020/mcbm_build_and_reco.C ) # TW event building + Cluster Finding + Hit reconstruction, Event based
   GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/beamtime/mcbm2020/mcbm_event_reco.C )  # Digi dt event building + Cluster Finding + Hit reconstruction, Event based
   GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/beamtime/mcbm2020/mcbm_event_ana.C )   # TOF Track extension toward other detectors
+  GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/beamtime/mcbm2020/mcbm_tof_tracking.C ) # TOF Tracking, Event based
   GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/beamtime/mcbm2020/MonitorT0.C )        # CbmMcbm2018MonitorTaskT0 + CbmMcbm2018MonitorAlgoT0
   GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/beamtime/mcbm2020/MonitorSts.C )       # CbmMcbm2018MonitorSts.h
   GENERATE_ROOT_TEST_SCRIPT(${CBMROOT_SOURCE_DIR}/macro/beamtime/mcbm2020/MonitorMuch.C )      # CbmMcbm2018MonitorMuchLite.h
@@ -123,12 +124,30 @@ If(DEFINED ENV{RAW_DATA_PATH} )
       Set(fixture_mcbm_event_reco_${RUN} fixture_done_${testname})
       set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_mcbm_event_reco_${RUN}})
 
-      Set(testname mcbm_evt_win_ana_2020_${RUN})
-      Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/beamtime/mcbm2020/mcbm_event_ana.sh ${RUN} 1000 "kTRUE" )
+      Set(testname mcbm_track_evt_win_2020_${RUN})
+      Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/beamtime/mcbm2020/mcbm_tof_tracking.sh ${RUN} "kTRUE" )
       Set_Tests_Properties(${testname} PROPERTIES TIMEOUT "600")
       Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
       set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_mcbm_build_reco_${RUN}})
       set_tests_properties(${testname} PROPERTIES DEPENDS mcbm_build_reco_2020_${RUN})
+      Set(fixture_mcbm_track_evt_win_${RUN} fixture_done_${testname})
+      set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_mcbm_track_evt_win_${RUN}})
+
+      Set(testname mcbm_track_event_2020_${RUN})
+      Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/beamtime/mcbm2020/mcbm_tof_tracking.sh ${RUN} )
+      Set_Tests_Properties(${testname} PROPERTIES TIMEOUT "600")
+      Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
+      set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_mcbm_event_reco_${RUN}})
+      set_tests_properties(${testname} PROPERTIES DEPENDS mcbm_event_reco_2020_${RUN})
+      Set(fixture_mcbm_track_event_${RUN} fixture_done_${testname})
+      set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_mcbm_track_event_${RUN}})
+
+      Set(testname mcbm_evt_win_ana_2020_${RUN})
+      Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/beamtime/mcbm2020/mcbm_event_ana.sh ${RUN} 1000 "kTRUE" )
+      Set_Tests_Properties(${testname} PROPERTIES TIMEOUT "600")
+      Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
+      set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_mcbm_track_evt_win_${RUN}})
+      set_tests_properties(${testname} PROPERTIES DEPENDS mcbm_track_evt_win_2020_${RUN})
       Set(fixture_mcbm_evt_win_ana_${RUN} fixture_done_${testname})
       set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_mcbm_evt_win_ana_${RUN}})
 
@@ -136,8 +155,8 @@ If(DEFINED ENV{RAW_DATA_PATH} )
       Add_Test(${testname} ${CBMROOT_BINARY_DIR}/macro/beamtime/mcbm2020/mcbm_event_ana.sh ${RUN} )
       Set_Tests_Properties(${testname} PROPERTIES TIMEOUT "600")
       Set_Tests_Properties(${testname} PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed;All ok")
-      set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_mcbm_event_reco_${RUN}})
-      set_tests_properties(${testname} PROPERTIES DEPENDS mcbm_event_reco_2020_${RUN})
+      set_tests_properties(${testname} PROPERTIES FIXTURES_REQUIRED ${fixture_mcbm_track_event_${RUN}})
+      set_tests_properties(${testname} PROPERTIES DEPENDS mcbm_track_event_2020_${RUN})
       Set(fixture_mcbm_event_ana_${RUN} fixture_done_${testname})
       set_tests_properties(${testname} PROPERTIES FIXTURES_SETUP ${fixture_mcbm_event_ana_${RUN}})
 
diff --git a/macro/beamtime/mcbm2020/MonitorPsd.C b/macro/beamtime/mcbm2020/MonitorPsd.C
index 7d23cd339ef4218f610be8f2116eed1e64803abf..6b3d70f39b1e2070b1378bfb99243691ec3517b5 100644
--- a/macro/beamtime/mcbm2020/MonitorPsd.C
+++ b/macro/beamtime/mcbm2020/MonitorPsd.C
@@ -53,6 +53,9 @@ void MonitorPsd(TString inFile           = "",
   std::cout << std::endl;
   std::cout << ">>> MonitorPsd: Initialising..." << std::endl;
   CbmMcbm2018MonitorTaskPsd* monitor_psd = new CbmMcbm2018MonitorTaskPsd();
+  monitor_psd->SetMonitorChanMode(kFALSE);
+  monitor_psd->SetMonitorWfmMode(kFALSE);
+  monitor_psd->SetMonitorFitMode(kFALSE);
 
   monitor_psd->SetIgnoreOverlapMs();
   monitor_psd->SetHistoryHistoSize(3600);
diff --git a/macro/beamtime/mcbm2020/build_event_win.C b/macro/beamtime/mcbm2020/build_event_win.C
index 42dff9606cf5cb1478e0b460cab0be6ac32011da..fe5471eba0cfb86cec7bd7a701b243f99b938f6f 100644
--- a/macro/beamtime/mcbm2020/build_event_win.C
+++ b/macro/beamtime/mcbm2020/build_event_win.C
@@ -1,10 +1,41 @@
-void build_event_win(UInt_t uRunId  = 0,
-                     Int_t nEvents  = 0,
-                     TString outDir = "data/") {
-  TString fileName = Form("data/unp_mcbm_%03u.root", uRunId);
+
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t build_event_win(UInt_t uRunId        = 0,
+                       Int_t nTimeslices    = 0,
+                       TString sOutDir      = "./data",
+                       TString sInpDir      = "./data",
+                       Int_t iUnpFileIndex  = -1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
+
+  // -----   In- and output file names   ------------------------------------
+  /// Standardized RUN ID
+  TString sRunId = TString::Format("%03u", uRunId);
+  /// Initial pattern
+  TString inFile  = sInpDir + "/unp_mcbm_" + sRunId;
+  TString outFile = sOutDir + "/mcbm_events_win_" + sRunId;
+  /// Add index of splitting at unpacking level if needed
+  if (0 <= iUnpFileIndex) {
+    inFile += TString::Format("_%02u", iUnpFileIndex);
+    outFile += TString::Format("_%02u", iUnpFileIndex);
+  }  // if ( 0 <= iUnpFileIndex )
+  /// Add ROOT file suffix
+  inFile += ".root";
+  outFile += ".root";
+  // ------------------------------------------------------------------------
 
   if (uRunId < 692) return kFALSE;
 
+  /*
+  std::cout << sOutDir << std::endl << sInpDir << std::endl;
+  std::cout << inFile << std::endl
+            << outFile << std::endl;
+  std::cout << uRunId << " " << nTimeslices << std::endl;
+
+  return kTRUE;
+  */
 
   // ========================================================================
   //          Adjust this part according to your requirements
@@ -14,8 +45,8 @@ void build_event_win(UInt_t uRunId  = 0,
 
   // --- Set log output levels
   FairLogger::GetLogger();
-  //gLogger->SetLogScreenLevel("INFO");
-  gLogger->SetLogScreenLevel("DEBUG");
+  gLogger->SetLogScreenLevel("INFO");
+  //  gLogger->SetLogScreenLevel("DEBUG");
   gLogger->SetLogVerbosityLevel("MEDIUM");
 
   // MC file
@@ -32,11 +63,9 @@ void build_event_win(UInt_t uRunId  = 0,
   FairRunAna* fRun = new FairRunAna();
   fRun->SetEventHeaderPersistence(kFALSE);
 
-  FairFileSource* inputSource = new FairFileSource(fileName);
+  FairFileSource* inputSource = new FairFileSource(inFile);
   fRun->SetSource(inputSource);
 
-  TString runId                = TString::Format("%03u", uRunId);
-  TString outFile              = outDir + "/events_win_" + runId + ".root";
   FairRootFileSink* outputSink = new FairRootFileSink(outFile);
   fRun->SetSink(outputSink);
 
@@ -71,8 +100,8 @@ void build_event_win(UInt_t uRunId  = 0,
   /// Change the selection window limits for T0 as ref
   eventBuilder->SetTriggerWindow(ECbmModuleId::kSts, -50, 100);
   eventBuilder->SetTriggerWindow(ECbmModuleId::kMuch, -150, 50);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kTrd, -250, 100);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kTof, -150, 10);
+  eventBuilder->SetTriggerWindow(ECbmModuleId::kTrd, -50, 250);
+  eventBuilder->SetTriggerWindow(ECbmModuleId::kTof, -50, 50);
   eventBuilder->SetTriggerWindow(ECbmModuleId::kRich, -50, 50);
   eventBuilder->SetTriggerWindow(ECbmModuleId::kPsd, -50, 50);
   /// To get T0 Digis (seed + close digis) in the event
@@ -81,7 +110,7 @@ void build_event_win(UInt_t uRunId  = 0,
   /*
   /// Use TOF as reference
   eventBuilder->SetReferenceDetector( kEventBuilderDetTof );
-  eventBuilder->AddDetector( kEventBuilderDetT0 );
+  eventBuilder->AddDetector(kEventBuilderDetT0);
 
   /// Change the selection window limits for TOF as ref
   /// => Should always be after changes of detector lists!
@@ -114,9 +143,7 @@ void build_event_win(UInt_t uRunId  = 0,
   eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kPsd, -1);
 
 
-  if (0 < uRunId)
-    eventBuilder->SetOutFilename(
-      Form("%sHistosEvtWin_%03u.root", outDir.Data(), uRunId));
+  if (0 < uRunId) eventBuilder->SetOutFilename(Form("%s/HistosEvtWin_%03u.root", sOutDir.Data(), uRunId));
 
   fRun->AddTask(eventBuilder);
 
@@ -128,10 +155,11 @@ void build_event_win(UInt_t uRunId  = 0,
   //  rtdb->print();
 
   cout << "Starting run" << endl;
-  if (0 == nEvents) {
+  if (0 == nTimeslices) {
     fRun->Run(0, 0);  // run until end of input file
-  } else {
-    fRun->Run(0, nEvents);  // process  N Events
+  }
+  else {
+    fRun->Run(0, nTimeslices);  // process  N Timeslices
   }
   // ------------------------------------------------------------------------
 
@@ -164,4 +192,6 @@ void build_event_win(UInt_t uRunId  = 0,
 
   cout << " Test passed" << endl;
   cout << " All ok " << endl;
+
+  return kTRUE;
 }
diff --git a/macro/beamtime/mcbm2020/build_event_win_kronos.C b/macro/beamtime/mcbm2020/build_event_win_kronos.C
index b5d71e57289e562aea89569e9ae3f0131420dc19..7feca70a0eb410bf58f8df802d52f933652e81b8 100644
--- a/macro/beamtime/mcbm2020/build_event_win_kronos.C
+++ b/macro/beamtime/mcbm2020/build_event_win_kronos.C
@@ -1,8 +1,19 @@
-void build_event_win_kronos(UInt_t uRunIdx = 0,
-                            Int_t nEvents  = 0,
-                            TString outDir = "data/") {
+#include "build_event_win.C"
+
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t build_event_win_kronos(UInt_t uRunIdx = 28,
+                              Int_t nTimeslices = 0,
+                              TString sOutDir = "./data",
+                              TString sInpDir = "/lustre/cbm/users/ploizeau/mcbm2020/"
+                                                "unp_evt_data_7f229b3f_20201103",
+                              Int_t iUnpFileIndex = -1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
+
   UInt_t uRunId    = 0;
-  TString fileName = "data/unp_mcbm_0.root";
+
   if (99999 != uRunIdx) {
     std::vector<UInt_t> vuListRunId = {
       692, 698, 702, 704, 705, 706, 707,            //  7 =>  0 -  6
@@ -13,183 +24,23 @@ void build_event_win_kronos(UInt_t uRunIdx = 0,
       841, 846, 849,                                //  3 => 30 - 32
       850, 851, 852, 854, 855, 856, 857, 858, 859,  //  9 => 33 - 41
       860, 861, 862, 863, 864, 865, 866             //  7 => 42 - 48
-                                                    /*
- /// With runs < 1 min due to missmatch!
-             811, 812, 816, 817, 818, 819,                     //  6 => 14 - 19
-             820, 821, 822, 824, 826, 827, 828, 829,           //  8 => 20 - 27
-             830, 831, 836, 839,                               //  4 => 28 - 31
-             840, 841, 842, 844, 845, 846, 848, 849,           //  8 => 32 - 39
-             850, 851, 852, 854, 855, 856, 857, 858, 859,      //  9 => 40 - 48
-             860, 861, 862, 863, 864, 865, 866                 //  7 => 49 - 55
-*/
+
+      /*
+      /// With runs < 1 min due to missmatch!
+      811, 812, 816, 817, 818, 819,                  //  6 => 14 - 19
+      820, 821, 822, 824, 826, 827, 828, 829,        //  8 => 20 - 27
+      830, 831, 836, 839,                            //  4 => 28 - 31
+      840, 841, 842, 844, 845, 846, 848, 849,        //  8 => 32 - 39
+      850, 851, 852, 854, 855, 856, 857, 858, 859,   //  9 => 40 - 48
+      860, 861, 862, 863, 864, 865, 866              //  7 => 49 - 55
+      */
     };
     if (vuListRunId.size() <= uRunIdx) return kFALSE;
+
     uRunId = vuListRunId[uRunIdx];
-    //fileName = Form("data/unp_mcbm_%03u.root", uRunId);
-    fileName = Form("/lustre/cbm/users/ploizeau/mcbm2020/"
-                    "unp_evt_data_7f229b3f_20201103/unp_mcbm_%i.root",
-                    uRunId);
   }  // if( 99999 != uRunIdx )
 
   if (uRunId < 692 && 0 != uRunId) return kFALSE;
 
-
-  // ========================================================================
-  //          Adjust this part according to your requirements
-
-  // Verbosity level (0=quiet, 1=event level, 2=track level, 3=debug)
-  //  Int_t iVerbose = 1;
-
-  // --- Set log output levels
-  FairLogger::GetLogger();
-  gLogger->SetLogScreenLevel("INFO");
-  //  gLogger->SetLogScreenLevel("DEBUG");
-  gLogger->SetLogVerbosityLevel("MEDIUM");
-
-  // MC file
-
-  TString srcDir = gSystem->Getenv("VMCWORKDIR");
-
-  // -----   Timer   --------------------------------------------------------
-  TStopwatch timer;
-  timer.Start();
-  // ------------------------------------------------------------------------
-
-  // -----  Analysis run   --------------------------------------------------
-  //  FairRunOnline *fRun= new FairRunOnline();
-  FairRunAna* fRun = new FairRunAna();
-  fRun->SetEventHeaderPersistence(kFALSE);
-
-  FairFileSource* inputSource = new FairFileSource(fileName);
-  fRun->SetSource(inputSource);
-
-  TString runId                = TString::Format("%03u", uRunId);
-  TString outFile              = outDir + "/events_win_" + runId + ".root";
-  FairRootFileSink* outputSink = new FairRootFileSink(outFile);
-  fRun->SetSink(outputSink);
-
-  // Define output file for FairMonitor histograms
-  //  TString monitorFile{outFile};
-  //  monitorFile.ReplaceAll("qa","qa.monitor");
-  FairMonitor::GetMonitor()->EnableMonitor(kTRUE);
-  //  FairMonitor::GetMonitor()->EnableMonitor(kFALSE);
-  // ------------------------------------------------------------------------
-
-  //  CbmMcbm2019TimeWinEventBuilder* eventBuilder = new CbmMcbm2019TimeWinEventBuilder();
-  CbmMcbm2019TimeWinEventBuilderTask* eventBuilder =
-    new CbmMcbm2019TimeWinEventBuilderTask();
-
-  eventBuilder->SetFillHistos(kTRUE);
-
-  eventBuilder->SetEventOverlapMode(EOverlapMode::NoOverlap);
-  //  eventBuilder->SetEventOverlapMode(EOverlapMode::MergeOverlap);
-  //  eventBuilder->SetEventOverlapMode(EOverlapMode::AllowOverlap);
-
-  /*
- * Available Pre-defined detectors:
- * kEventBuilderDetSts
- * kEventBuilderDetMuch
- * kEventBuilderDetTrd
- * kEventBuilderDetTof
- * kEventBuilderDetRich
- * kEventBuilderDetPsd
- * kEventBuilderDetT0
- */
-
-  /// Change the selection window limits for T0 as ref
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kSts, -50, 100);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kMuch, -150, 50);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kTrd, -250, 100);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kTof, -150, 10);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kRich, -50, 50);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kPsd, -50, 50);
-  /// To get T0 Digis (seed + close digis) in the event
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kT0, -1, 10);
-
-  /*
-  /// Use TOF as reference
-  eventBuilder->SetReferenceDetector( kEventBuilderDetTof );
-  eventBuilder->AddDetector( kEventBuilderDetT0 );
-
-  /// Change the selection window limits for TOF as ref
-  /// => Should always be after changes of detector lists!
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kT0, -150, 0);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kSts, -50, 100);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kMuch, -50, 200);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kTrd, -50, 300);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kTof, 0, 60);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kRich, -100, 150);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kPsd, -200, 50);
-*/
-
-  /// Change the trigger requirements
-  /// => Should always be after changes of detector lists!
-  /// --- Minimum
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kT0, 1);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kSts, 0);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kMuch, 0);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kTrd, 0);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kTof, 10);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kRich, 0);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kPsd, 0);
-  /// --- Maximum  (-1 to disable cut)
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kT0, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kSts, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kMuch, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kTrd, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kTof, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kRich, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kPsd, -1);
-
-
-  if (0 < uRunId)
-    eventBuilder->SetOutFilename(
-      Form("%sHistosEvtWin_%03u.root", outDir.Data(), uRunId));
-
-  fRun->AddTask(eventBuilder);
-
-  // -----   Intialise and run   --------------------------------------------
-  fRun->Init();
-
-  //  rtdb->setOutput(parIo1);
-  //  rtdb->saveOutput();
-  //  rtdb->print();
-
-  cout << "Starting run" << endl;
-  if (0 == nEvents) {
-    fRun->Run(0, 0);  // run until end of input file
-  } else {
-    fRun->Run(0, nEvents);  // process  N Events
-  }
-  // ------------------------------------------------------------------------
-
-
-  // -----   Finish   -------------------------------------------------------
-  timer.Stop();
-  Double_t rtime = timer.RealTime();
-  Double_t ctime = timer.CpuTime();
-  cout << endl << endl;
-  cout << "Macro finished succesfully." << endl;
-  cout << "Real time " << rtime << " s, CPU time " << ctime << " s" << endl;
-  cout << endl;
-  // ------------------------------------------------------------------------
-
-  // Extract the maximal used memory an add is as Dart measurement
-  // This line is filtered by CTest and the value send to CDash
-  FairSystemInfo sysInfo;
-  Float_t maxMemory = sysInfo.GetMaxMemory();
-  cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
-  cout << maxMemory;
-  cout << "</DartMeasurement>" << endl;
-
-  Float_t cpuUsage = ctime / rtime;
-  cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
-  cout << cpuUsage;
-  cout << "</DartMeasurement>" << endl;
-
-  FairMonitor* tempMon = FairMonitor::GetMonitor();
-  tempMon->Print();
-
-  cout << " Test passed" << endl;
-  cout << " All ok " << endl;
+  return build_event_win(uRunId, nTimeslices, sOutDir, sInpDir, iUnpFileIndex);
 }
diff --git a/macro/beamtime/mcbm2020/find_spills.C b/macro/beamtime/mcbm2020/find_spills.C
new file mode 100644
index 0000000000000000000000000000000000000000..64d4b952b885fb7f2b00d950802f652019b9122d
--- /dev/null
+++ b/macro/beamtime/mcbm2020/find_spills.C
@@ -0,0 +1,109 @@
+/** @file MCBM spill detection with T0
+ ** @author Pierre-Alain Loizeau <p.-a.loizeau@gsi.de>
+ ** @date 16.02.2021
+ ** ROOT macro to read tsa files which have been produced in mCBM and use the T0 detector to
+ ** find the spill breaks beginning, middle and end TS index
+ */
+// In order to call later Finish, we make this global
+FairRunOnline* run = NULL;
+
+Bool_t find_spills(TString inFile = "", UInt_t uRunId = 0, TString sOutDir = "data", TString sHostname = "localhost",
+                   Int_t iServerHttpPort = 8080, Int_t iServerRefreshRate = 100)
+{
+  TString srcDir = gSystem->Getenv("VMCWORKDIR");
+
+  // --- Specify number of events to be produced.
+  // --- -1 means run until the end of the input file.
+  Int_t nEvents = -1;
+  // --- Specify output file name (this is just an example)
+  TString runId   = TString::Format("%u", uRunId);
+  TString parFile = "data/spill_finder_params_" + runId + ".root";
+
+  // --- Set log output levels
+  FairLogger::GetLogger();
+  gLogger->SetLogScreenLevel("INFO");
+  //gLogger->SetLogScreenLevel("DEBUG");
+  gLogger->SetLogVerbosityLevel("MEDIUM");
+
+  // --- Define parameter files
+  TList* parFileList = new TList();
+  TString paramDir   = srcDir + "/macro/beamtime/mcbm2020/";
+
+  TString paramFileTof       = paramDir + "mT0Par.par";
+  TObjString* parTofFileName = new TObjString(paramFileTof);
+  parFileList->Add(parTofFileName);
+
+  // --- Set debug level
+  gDebug = 0;
+
+  std::cout << std::endl;
+
+  // ========================================================================
+  // ========================================================================
+  std::cout << std::endl;
+  std::cout << ">>> SpillFinder: Initialising..." << std::endl;
+  CbmMcbmSpillFindTask* spill_finder_t0 = new CbmMcbmSpillFindTask();
+
+  spill_finder_t0->SetIgnoreOverlapMs();
+  if (0 < uRunId) spill_finder_t0->SetHistoFilename(Form("data/HistosSpillFinder_%03u.root", uRunId));
+  spill_finder_t0->SetPulserTotLimits(180, 210);    // for runs  >  86
+  spill_finder_t0->SetSpillCheckIntervalSec(0.05);  // ~every 4 TS
+  spill_finder_t0->SetSpillThreshold(40);           // ~10 hits per TS
+
+  // --- Source task
+  CbmMcbm2018Source* source = new CbmMcbm2018Source();
+
+  if ("" != inFile) { source->SetFileName(inFile); }  // if( "" != inFile )
+  else {
+    source->SetHostName(sHostname);
+  }  // else of if( "" != inFile )
+
+  // Use kHodo since there is no entry for T0 in the enum yet
+  source->AddUnpacker(spill_finder_t0, 0x90, ECbmModuleId::kHodo);  //gDPB T0
+
+  source->SetSubscriberHwm(1000);
+
+  // --- Run
+  run = new FairRunOnline(source);
+  run->ActivateHttpServer(iServerRefreshRate,
+                          iServerHttpPort);  // refresh each 100 events
+  /// To avoid the server sucking all Histos from gROOT when no output file is used
+  /// ===> Need to explicitely add the canvases to the server in the task!
+  run->GetHttpServer()->GetSniffer()->SetScanGlobalDir(kFALSE);
+  run->SetAutoFinish(kFALSE);
+
+
+  // -----   Runtime database   ---------------------------------------------
+  FairRuntimeDb* rtdb       = run->GetRuntimeDb();
+  FairParAsciiFileIo* parIn = new FairParAsciiFileIo();
+  parIn->open(parFileList, "in");
+  rtdb->setFirstInput(parIn);
+
+  run->Init();
+
+  // --- Start run
+  TStopwatch timer;
+  timer.Start();
+  std::cout << ">>> SpillFinder: Starting run..." << std::endl;
+  run->Run(-1, 0);  // process  full file(s)!
+
+  run->Finish();
+
+  timer.Stop();
+
+  std::cout << "Processed " << std::dec << source->GetTsCount() << " timeslices" << std::endl;
+
+  // --- End-of-run info
+  Double_t rtime = timer.RealTime();
+  Double_t ctime = timer.CpuTime();
+  std::cout << std::endl << std::endl;
+  std::cout << ">>> SpillFinder: Macro finished successfully." << std::endl;
+  std::cout << ">>> SpillFinder: Real time " << rtime << " s, CPU time " << ctime << " s" << std::endl;
+  std::cout << std::endl;
+
+  /// --- Screen output for automatic tests
+  std::cout << " Test passed" << std::endl;
+  std::cout << " All ok " << std::endl;
+
+  return kTRUE;
+}
diff --git a/macro/beamtime/mcbm2020/find_spills_kronos.C b/macro/beamtime/mcbm2020/find_spills_kronos.C
new file mode 100644
index 0000000000000000000000000000000000000000..f4ea5834fdbb533f80eb09603b43db5192b36a38
--- /dev/null
+++ b/macro/beamtime/mcbm2020/find_spills_kronos.C
@@ -0,0 +1,60 @@
+/** @file MCBM spill detection with T0, wrapper for lustre runs
+ ** @author Pierre-Alain Loizeau <p.-a.loizeau@gsi.de>
+ ** @date 16.02.2021
+ ** ROOT macro to read tsa files which have been produced in mCBM and use the T0 detector to
+ ** find the spill breaks beginning, middle and end TS index
+ ** This wrapper macro provides all lustre paths + easy [0; n] run index mapping
+ */
+#include "find_spills.C"
+
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t find_spills_kronos(UInt_t uRunIdx       = 28,
+                          TString sOutDir      = "data")
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
+
+  UInt_t uRunId = 0;
+  if (99999 != uRunIdx) {
+    std::vector<UInt_t> vuListRunId = {
+      692, 698, 702, 704, 705, 706, 707,            //  7 =>  0 -  6
+      744, 750, 759, 760, 761, 762, 799,            //  7 =>  7 - 13
+      811, 812, 816, 817, 819,                      //  5 => 14 - 18
+      820, 821, 822, 824, 826, 827, 828, 829,       //  8 => 19 - 26
+      830, 831, 836,                                //  3 => 27 - 29
+      841, 846, 849,                                //  3 => 30 - 32
+      850, 851, 852, 854, 855, 856, 857, 858, 859,  //  9 => 33 - 41
+      860, 861, 862, 863, 864, 865, 866             //  7 => 42 - 48
+                                                    /*
+ /// With runs < 1 min due to missmatch!
+             811, 812, 816, 817, 818, 819,                     //  6 => 14 - 19
+             820, 821, 822, 824, 826, 827, 828, 829,           //  8 => 20 - 27
+             830, 831, 836, 839,                               //  4 => 28 - 31
+             840, 841, 842, 844, 845, 846, 848, 849,           //  8 => 32 - 39
+             850, 851, 852, 854, 855, 856, 857, 858, 859,      //  9 => 40 - 48
+             860, 861, 862, 863, 864, 865, 866                 //  7 => 49 - 55
+*/
+    };
+    if (vuListRunId.size() <= uRunIdx) {
+      std::cout << "Run index is out of range, not doing anything" << std::endl;
+      return kFALSE;
+    }
+    uRunId = vuListRunId[uRunIdx];
+  }  // if( 99999 != uRunIdx )
+
+  if (uRunId < 692) return kFALSE;
+
+  TString inFile = Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn02_*.tsa;", uRunId);
+  inFile += Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn04_*.tsa;", uRunId);
+  inFile += Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn05_*.tsa;", uRunId);
+  inFile += Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn06_*.tsa;", uRunId);
+  inFile += Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn08_*.tsa;", uRunId);
+  inFile += Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn10_*.tsa;", uRunId);
+  inFile += Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn11_*.tsa;", uRunId);
+  inFile += Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn12_*.tsa;", uRunId);
+  inFile += Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn13_*.tsa;", uRunId);
+  inFile += Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn15_*.tsa", uRunId);
+
+  return find_spills(inFile, uRunId, sOutDir);
+}
diff --git a/macro/beamtime/mcbm2020/mcbm_build_and_reco.C b/macro/beamtime/mcbm2020/mcbm_build_and_reco.C
index 34ca01145f8bb3ef9f03d4c20d5738d2562051dd..2a70b2249b55e6d8d97a722a6955e3b282473ea0 100644
--- a/macro/beamtime/mcbm2020/mcbm_build_and_reco.C
+++ b/macro/beamtime/mcbm2020/mcbm_build_and_reco.C
@@ -6,11 +6,16 @@
 //
 // --------------------------------------------------------------------------
 
-
-void mcbm_build_and_reco(UInt_t uRunId     = 831,
-                         Int_t nTimeslices = 300,
-                         TString outDir    = "data/") {
-
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t mcbm_build_and_reco(UInt_t uRunId        = 831,
+                           Int_t nTimeslices    = 0,
+                           TString sInpDir      = "./data",
+                           TString sOutDir      = "./data",
+                           Int_t iUnpFileIndex  = -1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
 
   // ========================================================================
   //          Adjust this part according to your requirements
@@ -25,15 +30,47 @@ void mcbm_build_and_reco(UInt_t uRunId     = 831,
   TString myName   = "mcbm_reco";  // this macro's name for screen output
   TString srcDir   = gSystem->Getenv("VMCWORKDIR");  // top source directory
   TString paramDir = srcDir + "/macro/beamtime/mcbm2020/";
+  TString parDir   = srcDir + "/parameters";
   //    ------------------------------------------------------------------------
 
 
+  /// FIXME: Disable clang formatting around parameters initial value setting
+  /// due to problem with real file path length
+  /* clang-format off */
   // -----   In- and output file names   ------------------------------------
-  TString inFile     = Form("./data/unp_mcbm_%i.root", uRunId);
-  TString parFileIn  = Form("./data/unp_mcbm_params_%i.root", uRunId);
-  TString parFileOut = Form("./data/reco_mcbm_evt_win_params_%u.root", uRunId);
-  TString outFile    = Form("./data/reco_mcbm_evt_win_%u.root", uRunId);
+  /// Standardized RUN ID
+  TString sRunId     = TString::Format("%03u", uRunId);
+  /// Initial pattern
+  TString inFile     = sInpDir + "/unp_mcbm_" + sRunId;
+  TString parFileIn  = sInpDir + "/unp_mcbm_params_" + sRunId;
+  TString parFileOut = sOutDir + "/reco_mcbm_evt_win_params_" + sRunId;
+  TString outFile    = sOutDir + "/reco_mcbm_evt_win_" + sRunId;
+  /// Add index of splitting at unpacking level if needed
+  if ( 0 <= iUnpFileIndex ) {
+    inFile     += TString::Format( "_%02u", iUnpFileIndex );
+    // the input par file is not split during unpacking!
+    parFileOut += TString::Format( "_%02u", iUnpFileIndex );
+    outFile    += TString::Format( "_%02u", iUnpFileIndex );
+  }  // if ( 0 <= iUnpFileIndex )
+  /// Add ROOT file suffix
+  inFile     += ".root";
+  parFileIn  += ".root";
+  parFileOut += ".root";
+  outFile    += ".root";
   // ------------------------------------------------------------------------
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
+
+  /*
+  std::cout << sInpDir << std::endl << sOutDir << std::endl;
+  std::cout << inFile << std::endl
+            << parFileIn << std::endl
+            << parFileOut << std::endl
+            << outFile << std::endl;
+  std::cout << uRunId << " " << nTimeslices << std::endl;
+
+  return kTRUE;
+  */
 
   // --- Load the geometry setup ----
   // This is currently only required by the TRD (parameters)
@@ -45,7 +82,6 @@ void mcbm_build_and_reco(UInt_t uRunId     = 831,
   TList* parFileList = new TList();
   // ------------------------------------------------------------------------
 
-
   // -----   Timer   --------------------------------------------------------
   TStopwatch timer;
   timer.Start();
@@ -65,7 +101,7 @@ void mcbm_build_and_reco(UInt_t uRunId     = 831,
 
   // Define output file for FairMonitor histograms
   TString monitorFile {outFile};
-  monitorFile.ReplaceAll("rec", "rec.monitor");
+  monitorFile.ReplaceAll("reco", "reco.monitor");
   FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile);
   // ------------------------------------------------------------------------
 
@@ -97,8 +133,8 @@ void mcbm_build_and_reco(UInt_t uRunId     = 831,
  * kEventBuilderDetT0
  */
   /// Use T0 as reference
-  eventBuilder->SetReferenceDetector(kEventBuilderDetT0);
-  eventBuilder->AddDetector(kEventBuilderDetTof);
+  /// The default (hardcoded) settings are T0 as reference detector and
+  /// STS, MUCH, TRD, TOF, RICH and PSD as selected detectors
 
   /// Change the selection window limits for T0 as ref
   eventBuilder->SetTriggerWindow(ECbmModuleId::kSts, -50, 100);
@@ -146,9 +182,7 @@ void mcbm_build_and_reco(UInt_t uRunId     = 831,
   eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kPsd, -1);
 
 
-  if (0 < uRunId)
-    eventBuilder->SetOutFilename(
-      Form("%sHistosEvtWin_%03u.root", outDir.Data(), uRunId));
+  if (0 < uRunId) eventBuilder->SetOutFilename(Form("%sHistosEvtWin_%03u.root", sOutDir.Data(), uRunId));
 
   run->AddTask(eventBuilder);
   // ------------------------------------------------------------------------
@@ -199,8 +233,6 @@ void mcbm_build_and_reco(UInt_t uRunId     = 831,
 
   // -----   Local reconstruction in MUCH   ---------------------------------
   Int_t flag = 1;
-  TString parDir =
-    TString(gSystem->Getenv("VMCWORKDIR")) + TString("/parameters");
   TString muchDigiFile(
     parDir + "/much/much_v19c_mcbm_digi_sector.root");  // MUCH digi file
   CbmMuchFindHitsGem* muchFindHits =
@@ -250,7 +282,6 @@ void mcbm_build_and_reco(UInt_t uRunId     = 831,
 
 
   // -----   Local reconstruction in TOF   ----------------------------------
-  // ------------------------------------------------------------------------
   // TOF defaults
   Int_t calMode      = 93;
   Int_t calSel       = 1;
@@ -284,179 +315,8 @@ void mcbm_build_and_reco(UInt_t uRunId     = 831,
 
   run->AddTask(tofCluster);
   std::cout << "-I- Added task " << tofCluster->GetName() << std::endl;
+  // ------------------------------------------------------------------------
 
-  // -----   Track reconstruction   ------------------------------------------
-  Int_t iTrackMode = 2;
-  switch (iTrackMode) {
-    case 2: {
-      Int_t iGenCor      = 1;
-      Double_t dScalFac  = 1.;
-      Double_t dChi2Lim2 = 3.5;
-      TString cTrkFile =
-        parDir + "/tof/" + Form("%s_tofFindTracks.hst.root", cCalId.Data());
-      Int_t iTrackingSetup = 1;
-      Int_t iCalOpt        = 1;
-
-      CbmTofTrackFinder* tofTrackFinder = new CbmTofTrackFinderNN();
-      tofTrackFinder->SetMaxTofTimeDifference(0.2);  // in ns/cm
-      tofTrackFinder->SetTxLIM(0.3);                 // max slope dx/dz
-      tofTrackFinder->SetTyLIM(0.3);  // max dev from mean slope dy/dz
-      tofTrackFinder->SetTyMean(0.);  // mean slope dy/dz
-      CbmTofTrackFitter* tofTrackFitter = new CbmTofTrackFitterKF(0, 211);
-      TFitter* MyFit                    = new TFitter(1);  // initialize Minuit
-      tofTrackFinder->SetFitter(tofTrackFitter);
-
-      CbmTofFindTracks* tofFindTracks =
-        new CbmTofFindTracks("TOF Track Finder");
-      tofFindTracks->UseFinder(tofTrackFinder);
-      tofFindTracks->UseFitter(tofTrackFitter);
-      tofFindTracks->SetCalOpt(iCalOpt);
-      // 1 - update offsets, 2 - update walk, 0 - bypass
-      tofFindTracks->SetCorMode(
-        iGenCor);  // valid options: 0,1,2,3,4,5,6, 10 - 19
-      tofFindTracks->SetTtTarg(
-        0.065);  // target value for Mar2020 triple stack -> betapeak ~ 0.95
-      //tofFindTracks->SetTtTarg(0.041);  // target value for inverse velocity, > 0.033 ns/cm!
-      //tofFindTracks->SetTtTarg(0.035);  // target value for inverse velocity, > 0.033 ns/cm!
-      tofFindTracks->SetCalParFileName(
-        cTrkFile);  // Tracker parameter value file name
-      tofFindTracks->SetBeamCounter(5, 0, 0);  // default beam counter
-      tofFindTracks->SetStationMaxHMul(
-        30);  // Max Hit Multiplicity in any used station
-
-      tofFindTracks->SetT0MAX(dScalFac);  // in ns
-      tofFindTracks->SetSIGT(0.08);       // default in ns
-      tofFindTracks->SetSIGX(0.3);        // default in cm
-      tofFindTracks->SetSIGY(0.45);       // default in cm
-      tofFindTracks->SetSIGZ(0.05);       // default in cm
-      tofFindTracks->SetUseSigCalib(
-        kFALSE);  // ignore resolutions in CalPar file
-      tofTrackFinder->SetSIGLIM(dChi2Lim2
-                                * 2.);  // matching window in multiples of chi2
-      tofTrackFinder->SetChiMaxAccept(dChi2Lim2);  // max tracklet chi2
-
-      Int_t iMinNofHits   = -1;
-      Int_t iNStations    = 0;
-      Int_t iNReqStations = 3;
-      switch (iTrackingSetup) {
-        case 0:  // bypass mode
-          iMinNofHits = -1;
-          iNStations  = 1;
-          tofFindTracks->SetStation(0, 5, 0, 0);  // Diamond
-          break;
-
-        case 1:  // for calibration mode of full setup
-          iMinNofHits   = 3;
-          iNStations    = 28;
-          iNReqStations = 4;
-          tofFindTracks->SetStation(0, 5, 0, 0);
-          tofFindTracks->SetStation(1, 0, 2, 2);
-          tofFindTracks->SetStation(2, 0, 1, 2);
-          tofFindTracks->SetStation(3, 0, 0, 2);
-          tofFindTracks->SetStation(4, 0, 2, 1);
-          tofFindTracks->SetStation(5, 0, 1, 1);
-          tofFindTracks->SetStation(6, 0, 0, 1);
-          tofFindTracks->SetStation(7, 0, 2, 3);
-          tofFindTracks->SetStation(8, 0, 1, 3);
-          tofFindTracks->SetStation(9, 0, 0, 3);
-          tofFindTracks->SetStation(10, 0, 2, 0);
-          tofFindTracks->SetStation(11, 0, 1, 0);
-          tofFindTracks->SetStation(12, 0, 0, 0);
-          tofFindTracks->SetStation(13, 0, 2, 4);
-          tofFindTracks->SetStation(14, 0, 1, 4);
-          tofFindTracks->SetStation(15, 0, 0, 4);
-          tofFindTracks->SetStation(16, 0, 4, 0);
-          tofFindTracks->SetStation(17, 0, 3, 0);
-          tofFindTracks->SetStation(18, 0, 4, 1);
-          tofFindTracks->SetStation(19, 0, 3, 1);
-          tofFindTracks->SetStation(20, 0, 4, 2);
-          tofFindTracks->SetStation(21, 0, 3, 2);
-          tofFindTracks->SetStation(22, 0, 4, 3);
-          tofFindTracks->SetStation(23, 0, 3, 3);
-          tofFindTracks->SetStation(24, 0, 4, 4);
-          tofFindTracks->SetStation(25, 0, 3, 4);
-          tofFindTracks->SetStation(26, 9, 0, 0);
-          tofFindTracks->SetStation(27, 9, 0, 1);
-          break;
-
-        case 2:  // for geometry check mode of full setup
-          iMinNofHits   = 3;
-          iNStations    = 27;
-          iNReqStations = 4;
-          tofFindTracks->SetStation(0, 0, 2, 2);
-          tofFindTracks->SetStation(1, 0, 1, 2);
-          tofFindTracks->SetStation(2, 0, 0, 2);
-          tofFindTracks->SetStation(3, 0, 2, 1);
-          tofFindTracks->SetStation(4, 0, 1, 1);
-          tofFindTracks->SetStation(5, 0, 0, 1);
-          tofFindTracks->SetStation(6, 0, 2, 3);
-          tofFindTracks->SetStation(7, 0, 1, 3);
-          tofFindTracks->SetStation(8, 0, 0, 3);
-          tofFindTracks->SetStation(9, 0, 2, 0);
-          tofFindTracks->SetStation(10, 0, 1, 0);
-          tofFindTracks->SetStation(11, 0, 0, 0);
-          tofFindTracks->SetStation(12, 0, 2, 4);
-          tofFindTracks->SetStation(13, 0, 1, 4);
-          tofFindTracks->SetStation(14, 0, 0, 4);
-          tofFindTracks->SetStation(15, 0, 4, 0);
-          tofFindTracks->SetStation(16, 0, 3, 0);
-          tofFindTracks->SetStation(17, 0, 4, 1);
-          tofFindTracks->SetStation(18, 0, 3, 1);
-          tofFindTracks->SetStation(19, 0, 4, 2);
-          tofFindTracks->SetStation(20, 0, 3, 2);
-          tofFindTracks->SetStation(21, 0, 4, 3);
-          tofFindTracks->SetStation(22, 0, 3, 3);
-          tofFindTracks->SetStation(23, 0, 4, 4);
-          tofFindTracks->SetStation(24, 0, 3, 4);
-          tofFindTracks->SetStation(25, 9, 0, 0);
-          tofFindTracks->SetStation(26, 9, 0, 1);
-          break;
-
-        case 3:  // for reduced bias tracking of full setup
-          iMinNofHits   = 3;
-          iNStations    = 28;
-          iNReqStations = 4;
-          tofFindTracks->SetStation(0, 0, 2, 2);
-          tofFindTracks->SetStation(1, 0, 1, 2);
-          tofFindTracks->SetStation(2, 0, 0, 2);
-          tofFindTracks->SetStation(3, 0, 2, 1);
-          tofFindTracks->SetStation(4, 0, 1, 1);
-          tofFindTracks->SetStation(5, 0, 0, 1);
-          tofFindTracks->SetStation(6, 0, 2, 3);
-          tofFindTracks->SetStation(7, 0, 1, 3);
-          tofFindTracks->SetStation(8, 0, 0, 3);
-          tofFindTracks->SetStation(9, 0, 2, 0);
-          tofFindTracks->SetStation(10, 0, 1, 0);
-          tofFindTracks->SetStation(11, 0, 0, 0);
-          tofFindTracks->SetStation(12, 0, 2, 4);
-          tofFindTracks->SetStation(13, 0, 1, 4);
-          tofFindTracks->SetStation(14, 0, 0, 4);
-          tofFindTracks->SetStation(15, 0, 4, 0);
-          tofFindTracks->SetStation(16, 0, 3, 0);
-          tofFindTracks->SetStation(17, 0, 4, 1);
-          tofFindTracks->SetStation(18, 0, 3, 1);
-          tofFindTracks->SetStation(19, 0, 4, 2);
-          tofFindTracks->SetStation(20, 0, 3, 2);
-          tofFindTracks->SetStation(21, 0, 4, 3);
-          tofFindTracks->SetStation(22, 0, 3, 3);
-          tofFindTracks->SetStation(23, 0, 4, 4);
-          tofFindTracks->SetStation(24, 0, 3, 4);
-          tofFindTracks->SetStation(25, 9, 0, 0);
-          tofFindTracks->SetStation(26, 9, 0, 1);
-          tofFindTracks->SetStation(27, 5, 0, 0);
-          break;
-      }
-      tofFindTracks->SetMinNofHits(iMinNofHits);
-      tofFindTracks->SetNStations(iNStations);
-      tofFindTracks->SetNReqStations(iNReqStations);
-      //tofFindTracks->PrintSetup();
-      run->AddTask(tofFindTracks);
-    } break;
-    case 1: {
-    }
-    case 0:
-    default:;
-  }
 
   // -----   Local reconstruction of RICH Hits ------------------------------
   CbmRichMCbmHitProducer* hitProdRich = new CbmRichMCbmHitProducer();
@@ -493,8 +353,8 @@ void mcbm_build_and_reco(UInt_t uRunId     = 831,
 
   parIo2->open(parFileList, "in");
   rtdb->setSecondInput(parIo2);
-  parIo3->open(parFileOut.Data(), "RECREATE");
 
+  parIo3->open(parFileOut.Data(), "RECREATE");
 
   // ------------------------------------------------------------------------
 
@@ -554,4 +414,6 @@ void mcbm_build_and_reco(UInt_t uRunId     = 831,
   /// --- Screen output for automatic tests
   std::cout << " Test passed" << std::endl;
   std::cout << " All ok " << std::endl;
+
+  return kTRUE;
 }
diff --git a/macro/beamtime/mcbm2020/mcbm_build_and_reco_kronos.C b/macro/beamtime/mcbm2020/mcbm_build_and_reco_kronos.C
index fd8becba1052fbc63cd632e56e4b538fb874a8af..1f0748a5fa7a6d0ac5a9e129ba4ca031dd980acf 100644
--- a/macro/beamtime/mcbm2020/mcbm_build_and_reco_kronos.C
+++ b/macro/beamtime/mcbm2020/mcbm_build_and_reco_kronos.C
@@ -6,13 +6,22 @@
 //
 // --------------------------------------------------------------------------
 
+#include "mcbm_build_and_reco.C"
+
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t mcbm_build_and_reco_kronos(UInt_t uRunIdx    = 28,
+                                  Int_t nTimeslices = 0,
+                                  TString sInpDir = "/lustre/cbm/users/ploizeau/mcbm2020/"
+                                                    "unp_evt_data_7f229b3f_20201103",
+                                  TString sOutDir = "./data",
+                                  Int_t iUnpFileIndex = -1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
 
-void mcbm_build_and_reco_kronos(UInt_t uRunIdx    = 28,
-                                Int_t nTimeslices = 300,
-                                TString outDir    = "data/") {
   UInt_t uRunId     = 0;
-  TString inFile    = "./data/unp_mcbm_0.root";
-  TString parFileIn = "./data/unp_mcbm_params_0.root";
+
   if (99999 != uRunIdx) {
     std::vector<UInt_t> vuListRunId = {
       692, 698, 702, 704, 705, 706, 707,            //  7 =>  0 -  6
@@ -23,561 +32,23 @@ void mcbm_build_and_reco_kronos(UInt_t uRunIdx    = 28,
       841, 846, 849,                                //  3 => 30 - 32
       850, 851, 852, 854, 855, 856, 857, 858, 859,  //  9 => 33 - 41
       860, 861, 862, 863, 864, 865, 866             //  7 => 42 - 48
-                                                    /*
- /// With runs < 1 min due to missmatch!
-             811, 812, 816, 817, 818, 819,                     //  6 => 14 - 19
-             820, 821, 822, 824, 826, 827, 828, 829,           //  8 => 20 - 27
-             830, 831, 836, 839,                               //  4 => 28 - 31
-             840, 841, 842, 844, 845, 846, 848, 849,           //  8 => 32 - 39
-             850, 851, 852, 854, 855, 856, 857, 858, 859,      //  9 => 40 - 48
-             860, 861, 862, 863, 864, 865, 866                 //  7 => 49 - 55
-*/
+
+      /*
+      /// With runs < 1 min due to missmatch!
+      811, 812, 816, 817, 818, 819,                     //  6 => 14 - 19
+      820, 821, 822, 824, 826, 827, 828, 829,           //  8 => 20 - 27
+      830, 831, 836, 839,                               //  4 => 28 - 31
+      840, 841, 842, 844, 845, 846, 848, 849,           //  8 => 32 - 39
+      850, 851, 852, 854, 855, 856, 857, 858, 859,      //  9 => 40 - 48
+      860, 861, 862, 863, 864, 865, 866                 //  7 => 49 - 55
+      */
     };
     if (vuListRunId.size() <= uRunIdx) return kFALSE;
-    uRunId = vuListRunId[uRunIdx];
 
-    inFile    = Form("/lustre/cbm/users/ploizeau/mcbm2020/"
-                  "unp_evt_data_7f229b3f_20201103/unp_mcbm_%u.root",
-                  uRunId);
-    parFileIn = Form("/lustre/cbm/users/ploizeau/mcbm2020/"
-                     "unp_evt_data_7f229b3f_20201103/unp_mcbm_params_%u.root",
-                     uRunId);
+    uRunId = vuListRunId[uRunIdx];
   }  // if( 99999 != uRunIdx )
 
   if (uRunId < 692 && 0 != uRunId) return kFALSE;
 
-
-  // ========================================================================
-  //          Adjust this part according to your requirements
-
-  // --- Logger settings ----------------------------------------------------
-  TString logLevel     = "INFO";
-  TString logVerbosity = "LOW";
-  // ------------------------------------------------------------------------
-
-
-  // -----   Environment   --------------------------------------------------
-  TString myName   = "mcbm_reco";  // this macro's name for screen output
-  TString srcDir   = gSystem->Getenv("VMCWORKDIR");  // top source directory
-  TString paramDir = srcDir + "/macro/beamtime/mcbm2020/";
-  //    ------------------------------------------------------------------------
-
-
-  // -----   In- and output file names   ------------------------------------
-  TString parFileOut = Form("./data/reco_mcbm_evt_win_params_%u.root", uRunId);
-  TString outFile    = Form("./data/reco_mcbm_evt_win_%u.root", uRunId);
-  // ------------------------------------------------------------------------
-
-  // --- Load the geometry setup ----
-  // This is currently only required by the TRD (parameters)
-  std::string geoSetupTag = "mcbm_beam_2020_03";
-  TString geoFile =
-    paramDir + geoSetupTag.data() + ".geo.root";  // Created in sim. run
-  CbmSetup* geoSetup = CbmSetup::Instance();
-  geoSetup->LoadSetup(geoSetupTag.data());
-  TList* parFileList = new TList();
-  // ------------------------------------------------------------------------
-
-  // -----   Timer   --------------------------------------------------------
-  TStopwatch timer;
-  timer.Start();
-  // ------------------------------------------------------------------------
-
-
-  // -----   FairRunAna   ---------------------------------------------------
-  FairRunAna* run = new FairRunAna();
-  run->SetEventHeaderPersistence(kFALSE);
-
-  FairFileSource* inputSource = new FairFileSource(inFile);
-  run->SetSource(inputSource);
-
-  FairRootFileSink* outputSink = new FairRootFileSink(outFile);
-  run->SetSink(outputSink);
-  run->SetGeomFile(geoFile);
-
-  // Define output file for FairMonitor histograms
-  TString monitorFile {outFile};
-  monitorFile.ReplaceAll("rec", "rec.monitor");
-  FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile);
-  // ------------------------------------------------------------------------
-
-
-  // -----   Logger settings   ----------------------------------------------
-  FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data());
-  FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data());
-  // ------------------------------------------------------------------------
-
-  //-------- Event builder --------------------------------------------------
-  //  CbmMcbm2019TimeWinEventBuilder* eventBuilder = new CbmMcbm2019TimeWinEventBuilder();
-  CbmMcbm2019TimeWinEventBuilderTask* eventBuilder =
-    new CbmMcbm2019TimeWinEventBuilderTask();
-
-  eventBuilder->SetFillHistos(kTRUE);
-
-  eventBuilder->SetEventOverlapMode(EOverlapMode::NoOverlap);
-  //  eventBuilder->SetEventOverlapMode(EOverlapMode::MergeOverlap);
-  //  eventBuilder->SetEventOverlapMode(EOverlapMode::AllowOverlap);
-
-  /*
- * Available Pre-defined detectors:
- * kEventBuilderDetSts
- * kEventBuilderDetMuch
- * kEventBuilderDetTrd
- * kEventBuilderDetTof
- * kEventBuilderDetRich
- * kEventBuilderDetPsd
- * kEventBuilderDetT0
- */
-
-  /// Change the selection window limits for T0 as ref
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kSts, -50, 100);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kMuch, -150, 50);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kTrd, -250, 100);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kTof, -150, 10);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kRich, -50, 50);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kPsd, -50, 50);
-  /// To get T0 Digis (seed + close digis) in the event
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kT0, -1, 10);
-
-  /*
-  /// Use TOF as reference
-  eventBuilder->SetReferenceDetector( kEventBuilderDetTof );
-  eventBuilder->AddDetector( kEventBuilderDetT0 );
-
-  /// Change the selection window limits for TOF as ref
-  /// => Should always be after changes of detector lists!
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kT0, -150, 0);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kSts, -50, 100);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kMuch, -50, 200);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kTrd, -50, 300);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kTof, 0, 60);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kRich, -100, 150);
-  eventBuilder->SetTriggerWindow(ECbmModuleId::kPsd, -200, 50);
-*/
-
-  /// Change the trigger requirements
-  /// => Should always be after changes of detector lists!
-  /// --- Minimum
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kT0, 1);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kSts, 0);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kMuch, 0);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kTrd, 0);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kTof, 10);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kRich, 0);
-  eventBuilder->SetTriggerMinNumber(ECbmModuleId::kPsd, 0);
-  /// --- Maximum  (-1 to disable cut)
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kT0, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kSts, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kMuch, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kTrd, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kTof, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kRich, -1);
-  eventBuilder->SetTriggerMaxNumber(ECbmModuleId::kPsd, -1);
-
-
-  if (0 < uRunId)
-    eventBuilder->SetOutFilename(
-      Form("%sHistosEvtWin_%03u.root", outDir.Data(), uRunId));
-
-  run->AddTask(eventBuilder);
-  // ------------------------------------------------------------------------
-
-
-  // -----   Reconstruction tasks   -----------------------------------------
-
-  // -----   Local reconstruction in STS   ----------------------------------
-  CbmRecoSts* recoSts = new CbmRecoSts();
-  recoSts->SetMode(kCbmRecoEvent);
-
-  //recoSts->SetTimeCutDigisAbs( 20 );// cluster finder: time cut in ns
-  //recoSts->SetTimeCutClustersAbs(20.); // hit finder: time cut in ns
-
-  // ASIC params: #ADC channels, dyn. range, threshold, time resol., dead time,
-  // noise RMS, zero-threshold crossing rate
-  auto parAsic =
-    new CbmStsParAsic(32, 75000., 3000., 5., 800., 1000., 3.9789e-3);
-
-  // Module params: number of channels, number of channels per ASIC
-  auto parMod = new CbmStsParModule(2048, 128);
-  parMod->SetAllAsics(*parAsic);
-  recoSts->UseModulePar(parMod);
-
-  // Sensor params
-  auto sensorPar = new CbmStsParSensor(CbmStsSensorClass::kDssdStereo);
-  sensorPar->SetPar(0, 6.2092);  // Extension in x
-  sensorPar->SetPar(1, 6.2);     // Extension in y
-  sensorPar->SetPar(2, 0.03);    // Extension in z
-  sensorPar->SetPar(3, 5.9692);  // Active size in y
-  sensorPar->SetPar(4, 1024.);   // Number of strips front side
-  sensorPar->SetPar(5, 1024.);   // Number of strips back side
-  sensorPar->SetPar(6, 0.0058);  // Strip pitch front side
-  sensorPar->SetPar(7, 0.0058);  // Strip pitch back side
-  sensorPar->SetPar(8, 7.5);     // Stereo angle front side
-  sensorPar->SetPar(9, 0.0);     // Stereo angle back side
-  recoSts->UseSensorPar(sensorPar);
-
-  // Sensor conditions: full depletion voltage, bias voltage, temperature,
-  // coupling capacitance, inter-strip capacitance
-  auto sensorCond = new CbmStsParSensorCond(70., 140., 268., 17.5, 1.);
-  recoSts->UseSensorCond(sensorCond);
-
-  run->AddTask(recoSts);
-  std::cout << "-I- : Added task " << recoSts->GetName() << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Local reconstruction in MUCH   ---------------------------------
-  Int_t flag = 1;
-  TString parDir =
-    TString(gSystem->Getenv("VMCWORKDIR")) + TString("/parameters");
-  TString muchDigiFile(
-    parDir + "/much/much_v19c_mcbm_digi_sector.root");  // MUCH digi file
-  CbmMuchFindHitsGem* muchFindHits =
-    new CbmMuchFindHitsGem(muchDigiFile.Data(), flag);
-  muchFindHits->SetBeamTimeDigi(kTRUE);
-  run->AddTask(muchFindHits);
-  std::cout << "-I- : Added task " << muchFindHits->GetName() << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Local reconstruction in TRD   ----------------------------------
-  // Load parameters <- they are required by the hit producer.
-  // For now, it is enough to load the default ascii parameters
-  // if no root file is existing from the unpacking process.
-  TString geoTagTrd = "";
-  bool isActiveTrd =
-    (geoSetup->GetGeoTag(ECbmModuleId::kTrd, geoTagTrd)) ? true : false;
-  if (!isActiveTrd) {
-    LOG(warning) << Form(
-      "TRD - parameter loading - Trd not found in CbmSetup(%s) -> parameters "
-      "can not be loaded correctly!",
-      geoSetupTag.data());
-  } else {
-    TString paramFilesTrd(
-      Form("%s/parameters/trd/trd_%s", srcDir.Data(), geoTagTrd.Data()));
-    std::vector<std::string> paramFilesVecTrd;
-    CbmTrdParManager::GetParFileExtensions(&paramFilesVecTrd);
-    for (auto parIt : paramFilesVecTrd) {
-      parFileList->Add(
-        new TObjString(Form("%s.%s.par", paramFilesTrd.Data(), parIt.data())));
-    }
-  }
-  // -- end trd parameters
-  // -- beginn trd reco
-  Double_t triggerThreshold       = 0.5e-6;  // Default
-  CbmTrdClusterFinder* trdCluster = new CbmTrdClusterFinder();
-  trdCluster->SetNeighbourEnable(true, false);
-  trdCluster->SetMinimumChargeTH(triggerThreshold);
-  trdCluster->SetRowMerger(true);
-  run->AddTask(trdCluster);
-  std::cout << "-I- : Added task " << trdCluster->GetName() << std::endl;
-
-  CbmTrdHitProducer* trdHit = new CbmTrdHitProducer();
-  run->AddTask(trdHit);
-  std::cout << "-I- : Added task " << trdHit->GetName() << std::endl;
-  // ------------------------------------------------------------------------
-
-  // -----   Local reconstruction in TOF   ----------------------------------
-  // ------------------------------------------------------------------------
-  // TOF defaults
-  Int_t calMode      = 93;
-  Int_t calSel       = 1;
-  Int_t calSm        = 0;
-  Int_t RefSel       = 0;
-  Double_t dDeadtime = 50.;
-  Int_t iSel2        = 500;
-  TString TofGeoTag  = "v20f_mcbm";
-  TString cCalId     = "831.50.3.0";
-  Int_t iCalSet      = 12022500;  // calibration settings
-
-  TObjString* tofBdfFile =
-    new TObjString(parDir + "/tof/tof_" + TofGeoTag + ".digibdf.par");
-  parFileList->Add(tofBdfFile);
-  std::cout << "-I- Using parameter file " << tofBdfFile->GetString()
-            << std::endl;
-
-  CbmTofEventClusterizer* tofCluster =
-    new CbmTofEventClusterizer("TOF Event Clusterizer", 0, 1);
-  TString cFname = parDir + "/tof/"
-                   + Form("%s_set%09d_%02d_%01dtofClust.hst.root",
-                          cCalId.Data(),
-                          iCalSet,
-                          calMode,
-                          calSel);
-  tofCluster->SetCalParFileName(cFname);
-  tofCluster->SetCalMode(calMode);
-  tofCluster->SetCalSel(calSel);
-  tofCluster->PosYMaxScal(0.75);              //in % of 2*length
-  tofCluster->SetChannelDeadtime(dDeadtime);  // artificial deadtime in ns
-
-  run->AddTask(tofCluster);
-  std::cout << "-I- Added task " << tofCluster->GetName() << std::endl;
-
-  // -----   Track reconstruction   ------------------------------------------
-  Int_t iTrackMode = 2;
-  switch (iTrackMode) {
-    case 2: {
-      Int_t iGenCor      = 1;
-      Double_t dScalFac  = 1.;
-      Double_t dChi2Lim2 = 3.5;
-      TString cTrkFile =
-        parDir + "/tof/" + Form("%s_tofFindTracks.hst.root", cCalId.Data());
-      Int_t iTrackingSetup = 1;
-      Int_t iCalOpt        = 0;
-
-      CbmTofTrackFinder* tofTrackFinder = new CbmTofTrackFinderNN();
-      tofTrackFinder->SetMaxTofTimeDifference(0.2);  // in ns/cm
-      tofTrackFinder->SetTxLIM(0.3);                 // max slope dx/dz
-      tofTrackFinder->SetTyLIM(0.3);  // max dev from mean slope dy/dz
-      tofTrackFinder->SetTyMean(0.);  // mean slope dy/dz
-      CbmTofTrackFitter* tofTrackFitter = new CbmTofTrackFitterKF(0, 211);
-      TFitter* MyFit                    = new TFitter(1);  // initialize Minuit
-      tofTrackFinder->SetFitter(tofTrackFitter);
-
-      CbmTofFindTracks* tofFindTracks =
-        new CbmTofFindTracks("TOF Track Finder");
-      tofFindTracks->UseFinder(tofTrackFinder);
-      tofFindTracks->UseFitter(tofTrackFitter);
-      tofFindTracks->SetCalOpt(iCalOpt);
-      // 1 - update offsets, 2 - update walk, 0 - bypass
-      tofFindTracks->SetCorMode(
-        iGenCor);  // valid options: 0,1,2,3,4,5,6, 10 - 19
-      tofFindTracks->SetTtTarg(
-        0.065);  // target value for Mar2020 triple stack -> betapeak ~ 0.95
-      //tofFindTracks->SetTtTarg(0.041);  // target value for inverse velocity, > 0.033 ns/cm!
-      //tofFindTracks->SetTtTarg(0.035);  // target value for inverse velocity, > 0.033 ns/cm!
-      tofFindTracks->SetCalParFileName(
-        cTrkFile);  // Tracker parameter value file name
-      tofFindTracks->SetBeamCounter(5, 0, 0);  // default beam counter
-      tofFindTracks->SetStationMaxHMul(
-        30);  // Max Hit Multiplicity in any used station
-
-      tofFindTracks->SetT0MAX(dScalFac);  // in ns
-      tofFindTracks->SetSIGT(0.08);       // default in ns
-      tofFindTracks->SetSIGX(0.3);        // default in cm
-      tofFindTracks->SetSIGY(0.45);       // default in cm
-      tofFindTracks->SetSIGZ(0.05);       // default in cm
-      tofFindTracks->SetUseSigCalib(
-        kFALSE);  // ignore resolutions in CalPar file
-      tofTrackFinder->SetSIGLIM(dChi2Lim2
-                                * 2.);  // matching window in multiples of chi2
-      tofTrackFinder->SetChiMaxAccept(dChi2Lim2);  // max tracklet chi2
-
-      Int_t iMinNofHits   = -1;
-      Int_t iNStations    = 0;
-      Int_t iNReqStations = 3;
-      switch (iTrackingSetup) {
-        case 0:  // bypass mode
-          iMinNofHits = -1;
-          iNStations  = 1;
-          tofFindTracks->SetStation(0, 5, 0, 0);  // Diamond
-          break;
-
-        case 1:  // for calibration mode of full setup
-          iMinNofHits   = 3;
-          iNStations    = 28;
-          iNReqStations = 4;
-          tofFindTracks->SetStation(0, 5, 0, 0);
-          tofFindTracks->SetStation(1, 0, 2, 2);
-          tofFindTracks->SetStation(2, 0, 1, 2);
-          tofFindTracks->SetStation(3, 0, 0, 2);
-          tofFindTracks->SetStation(4, 0, 2, 1);
-          tofFindTracks->SetStation(5, 0, 1, 1);
-          tofFindTracks->SetStation(6, 0, 0, 1);
-          tofFindTracks->SetStation(7, 0, 2, 3);
-          tofFindTracks->SetStation(8, 0, 1, 3);
-          tofFindTracks->SetStation(9, 0, 0, 3);
-          tofFindTracks->SetStation(10, 0, 2, 0);
-          tofFindTracks->SetStation(11, 0, 1, 0);
-          tofFindTracks->SetStation(12, 0, 0, 0);
-          tofFindTracks->SetStation(13, 0, 2, 4);
-          tofFindTracks->SetStation(14, 0, 1, 4);
-          tofFindTracks->SetStation(15, 0, 0, 4);
-          tofFindTracks->SetStation(16, 0, 4, 0);
-          tofFindTracks->SetStation(17, 0, 3, 0);
-          tofFindTracks->SetStation(18, 0, 4, 1);
-          tofFindTracks->SetStation(19, 0, 3, 1);
-          tofFindTracks->SetStation(20, 0, 4, 2);
-          tofFindTracks->SetStation(21, 0, 3, 2);
-          tofFindTracks->SetStation(22, 0, 4, 3);
-          tofFindTracks->SetStation(23, 0, 3, 3);
-          tofFindTracks->SetStation(24, 0, 4, 4);
-          tofFindTracks->SetStation(25, 0, 3, 4);
-          tofFindTracks->SetStation(26, 9, 0, 0);
-          tofFindTracks->SetStation(27, 9, 0, 1);
-          break;
-
-        case 2:  // for geometry check mode of full setup
-          iMinNofHits   = 3;
-          iNStations    = 27;
-          iNReqStations = 4;
-          tofFindTracks->SetStation(0, 0, 2, 2);
-          tofFindTracks->SetStation(1, 0, 1, 2);
-          tofFindTracks->SetStation(2, 0, 0, 2);
-          tofFindTracks->SetStation(3, 0, 2, 1);
-          tofFindTracks->SetStation(4, 0, 1, 1);
-          tofFindTracks->SetStation(5, 0, 0, 1);
-          tofFindTracks->SetStation(6, 0, 2, 3);
-          tofFindTracks->SetStation(7, 0, 1, 3);
-          tofFindTracks->SetStation(8, 0, 0, 3);
-          tofFindTracks->SetStation(9, 0, 2, 0);
-          tofFindTracks->SetStation(10, 0, 1, 0);
-          tofFindTracks->SetStation(11, 0, 0, 0);
-          tofFindTracks->SetStation(12, 0, 2, 4);
-          tofFindTracks->SetStation(13, 0, 1, 4);
-          tofFindTracks->SetStation(14, 0, 0, 4);
-          tofFindTracks->SetStation(15, 0, 4, 0);
-          tofFindTracks->SetStation(16, 0, 3, 0);
-          tofFindTracks->SetStation(17, 0, 4, 1);
-          tofFindTracks->SetStation(18, 0, 3, 1);
-          tofFindTracks->SetStation(19, 0, 4, 2);
-          tofFindTracks->SetStation(20, 0, 3, 2);
-          tofFindTracks->SetStation(21, 0, 4, 3);
-          tofFindTracks->SetStation(22, 0, 3, 3);
-          tofFindTracks->SetStation(23, 0, 4, 4);
-          tofFindTracks->SetStation(24, 0, 3, 4);
-          tofFindTracks->SetStation(25, 9, 0, 0);
-          tofFindTracks->SetStation(26, 9, 0, 1);
-          break;
-
-        case 3:  // for reduced bias tracking of full setup
-          iMinNofHits   = 3;
-          iNStations    = 28;
-          iNReqStations = 4;
-          tofFindTracks->SetStation(0, 0, 2, 2);
-          tofFindTracks->SetStation(1, 0, 1, 2);
-          tofFindTracks->SetStation(2, 0, 0, 2);
-          tofFindTracks->SetStation(3, 0, 2, 1);
-          tofFindTracks->SetStation(4, 0, 1, 1);
-          tofFindTracks->SetStation(5, 0, 0, 1);
-          tofFindTracks->SetStation(6, 0, 2, 3);
-          tofFindTracks->SetStation(7, 0, 1, 3);
-          tofFindTracks->SetStation(8, 0, 0, 3);
-          tofFindTracks->SetStation(9, 0, 2, 0);
-          tofFindTracks->SetStation(10, 0, 1, 0);
-          tofFindTracks->SetStation(11, 0, 0, 0);
-          tofFindTracks->SetStation(12, 0, 2, 4);
-          tofFindTracks->SetStation(13, 0, 1, 4);
-          tofFindTracks->SetStation(14, 0, 0, 4);
-          tofFindTracks->SetStation(15, 0, 4, 0);
-          tofFindTracks->SetStation(16, 0, 3, 0);
-          tofFindTracks->SetStation(17, 0, 4, 1);
-          tofFindTracks->SetStation(18, 0, 3, 1);
-          tofFindTracks->SetStation(19, 0, 4, 2);
-          tofFindTracks->SetStation(20, 0, 3, 2);
-          tofFindTracks->SetStation(21, 0, 4, 3);
-          tofFindTracks->SetStation(22, 0, 3, 3);
-          tofFindTracks->SetStation(23, 0, 4, 4);
-          tofFindTracks->SetStation(24, 0, 3, 4);
-          tofFindTracks->SetStation(25, 9, 0, 0);
-          tofFindTracks->SetStation(26, 9, 0, 1);
-          tofFindTracks->SetStation(27, 5, 0, 0);
-          break;
-      }
-      tofFindTracks->SetMinNofHits(iMinNofHits);
-      tofFindTracks->SetNStations(iNStations);
-      tofFindTracks->SetNReqStations(iNReqStations);
-      //tofFindTracks->PrintSetup();
-      run->AddTask(tofFindTracks);
-    } break;
-    case 1: {
-    }
-    case 0:
-    default:;
-  }
-
-  // -----   Local reconstruction of RICH Hits ------------------------------
-  CbmRichMCbmHitProducer* hitProdRich = new CbmRichMCbmHitProducer();
-  hitProdRich->setToTLimits(23.7, 30.0);
-  hitProdRich->applyToTCut();
-  TString sRichMapFile =
-    srcDir + "/macro/rich/mcbm/beamtime/mRICH_Mapping_vert_20190318_elView.geo";
-  hitProdRich->SetMappingFile(sRichMapFile.Data());
-  run->AddTask(hitProdRich);
-  // ------------------------------------------------------------------------
-
-  // -----   Local reconstruction in RICh -> Finding of Rings ---------------
-  CbmRichReconstruction* richReco = new CbmRichReconstruction();
-  richReco->UseMCbmSetup();
-  run->AddTask(richReco);
-  // ------------------------------------------------------------------------
-
-
-  // -----  Psd hit producer   ----------------------------------------------
-  CbmPsdMCbmHitProducer* hitProdPsd = new CbmPsdMCbmHitProducer();
-  run->AddTask(hitProdPsd);
-  // ------------------------------------------------------------------------
-
-
-  // -----  Parameter database   --------------------------------------------
-  std::cout << std::endl << std::endl;
-  std::cout << "-I- " << myName << ": Set runtime DB" << std::endl;
-  FairRuntimeDb* rtdb        = run->GetRuntimeDb();
-  FairParRootFileIo* parIo1  = new FairParRootFileIo();
-  FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo();
-  FairParRootFileIo* parIo3  = new FairParRootFileIo();
-  parIo1->open(parFileIn.Data(), "READ");
-  rtdb->setFirstInput(parIo1);
-  parIo2->open(parFileList, "in");
-  rtdb->setSecondInput(parIo2);
-  parIo3->open(parFileOut.Data(), "RECREATE");
-
-  // ------------------------------------------------------------------------
-
-
-  // -----   Run initialisation   -------------------------------------------
-  std::cout << std::endl;
-  std::cout << "-I- " << myName << ": Initialise run" << std::endl;
-  run->Init();
-  rtdb->setOutput(parIo3);
-  rtdb->saveOutput();
-  rtdb->print();
-  // ------------------------------------------------------------------------
-
-
-  // -----   Start run   ----------------------------------------------------
-  std::cout << std::endl << std::endl;
-  std::cout << "-I- " << myName << ": Starting run" << std::endl;
-  run->Run(0, nTimeslices);
-  // ------------------------------------------------------------------------
-
-
-  // -----   Finish   -------------------------------------------------------
-  timer.Stop();
-  FairMonitor::GetMonitor()->Print();
-  Double_t rtime = timer.RealTime();
-  Double_t ctime = timer.CpuTime();
-  std::cout << std::endl << std::endl;
-  std::cout << "Macro finished successfully." << std::endl;
-  std::cout << "Output file is " << outFile << std::endl;
-  std::cout << "Parameter file is " << parFileOut << std::endl;
-  std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s"
-            << std::endl;
-  std::cout << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Resource monitoring   ------------------------------------------
-  // Extract the maximal used memory an add is as Dart measurement
-  // This line is filtered by CTest and the value send to CDash
-  FairSystemInfo sysInfo;
-  Float_t maxMemory = sysInfo.GetMaxMemory();
-  std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
-  std::cout << maxMemory;
-  std::cout << "</DartMeasurement>" << std::endl;
-
-  Float_t cpuUsage = ctime / rtime;
-  std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
-  std::cout << cpuUsage;
-  std::cout << "</DartMeasurement>" << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Function needed for CTest runtime dependency   -----------------
-  //  RemoveGeoManager();
-  // ------------------------------------------------------------------------
-
-  /// --- Screen output for automatic tests
-  std::cout << " Test passed" << std::endl;
-  std::cout << " All ok " << std::endl;
+  return mcbm_build_and_reco(uRunId, nTimeslices, sInpDir, sOutDir, iUnpFileIndex);
 }
diff --git a/macro/beamtime/mcbm2020/mcbm_event_ana.C b/macro/beamtime/mcbm2020/mcbm_event_ana.C
index 7399cefef4ff41acb112cdb2462cd82f6ae9bf8f..f7b1f19bb60e5cdaf195e7b3cc82d83feb0543fb 100644
--- a/macro/beamtime/mcbm2020/mcbm_event_ana.C
+++ b/macro/beamtime/mcbm2020/mcbm_event_ana.C
@@ -6,9 +6,17 @@
 //
 // --------------------------------------------------------------------------
 
-void mcbm_event_ana(Int_t runId       = 831,
-                    Int_t nTimeslices = 1000,
-                    Bool_t bUseEvtWin = kFALSE) {
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+void mcbm_event_ana(UInt_t uRunId         = 831,
+                    Int_t nTimeslices     = 1000,
+                    Bool_t bUseEvtWin     = kFALSE,
+                    TString sInpDir       = "./data",
+                    TString sOutDir       = "./data",
+                    Int_t iUnpFileIndex   = -1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
 
   // --- Logger settings ----------------------------------------------------
   TString logLevel     = "WARN";
@@ -23,14 +31,36 @@ void mcbm_event_ana(Int_t runId       = 831,
   // ------------------------------------------------------------------------
 
   // -----   In- and output file names   ------------------------------------
-  TString inFile = Form("./data/reco_mcbm_%03u.root", runId);
+  /// Standardized RUN ID
+  TString sRunId = TString::Format("%03u", uRunId);
+  /// Initial pattern
+  TString inFile     = sInpDir + "/reco_mcbm_event_" + sRunId;
+  TString trkFile    = sInpDir + "/tracking_mcbm_event_" + sRunId;
+  TString parFileIn  = sInpDir + "/unp_mcbm_params_" + sRunId;
+  TString parFileOut = sOutDir + "/mcbm_event_ana_params_" + sRunId;
+  TString geoFile    = paramDir + "mcbm_beam_2020_03.geo.root";
+  TString outFile    = sOutDir + "/mcbm_event_ana__" + sRunId;
+  /// Initial pattern if using event builder with time window
   if (bUseEvtWin) {
-    inFile = Form("./data/reco_mcbm_evt_win_%03u.root", runId);
-  }  // if (bUseEvtWin)
-  TString parFile = Form("./data/unp_mcbm_params_%i.root", runId);
-  TString geoFile = paramDir + "mcbm_beam_2020_03.geo.root";
-  TString outFile = Form("./data/ana_mcbm_%i.root", runId);
-
+    inFile     = sInpDir + "/reco_mcbm_evt_win_" + sRunId;
+    trkFile    = sInpDir + "/tracking_mcbm_evt_win_" + sRunId;
+    parFileOut = sOutDir + "/mcbm_event_ana_evt_win_params_" + sRunId;
+    outFile    = sOutDir + "/mcbm_event_ana_evt_win_" + sRunId;
+  }  // if( bUseEvtWin )
+  /// Add index of splitting at unpacking level if needed
+  if (0 <= iUnpFileIndex) {
+    inFile += TString::Format("_%02u", iUnpFileIndex);
+    trkFile += TString::Format("_%02u", iUnpFileIndex);
+    // the input par file is from unpacking and not split during it!
+    parFileOut += TString::Format("_%02u", iUnpFileIndex);
+    outFile += TString::Format("_%02u", iUnpFileIndex);
+  }  // if ( 0 <= iUnpFileIndex )
+  /// Add ROOT file suffix
+  inFile += ".root";
+  trkFile += ".root";
+  parFileIn += ".root";
+  parFileOut += ".root";
+  outFile += ".root";
   // ------------------------------------------------------------------------
 
   // -----   Parameter files as input to the runtime database   -------------
@@ -47,6 +77,7 @@ void mcbm_event_ana(Int_t runId       = 831,
   // -----   FairRunAna   ---------------------------------------------------
   FairRunAna* run             = new FairRunAna();
   FairFileSource* inputSource = new FairFileSource(inFile);
+  inputSource->AddFriend(trkFile);
   run->SetSource(inputSource);
 
   FairRootFileSink* outputSink = new FairRootFileSink(outFile);
@@ -396,10 +427,12 @@ void mcbm_event_ana(Int_t runId       = 831,
   FairRuntimeDb* rtdb        = run->GetRuntimeDb();
   FairParRootFileIo* parIo1  = new FairParRootFileIo();
   FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo();
-  parIo1->open(parFile.Data(), "UPDATE");
+  FairParRootFileIo* parIo3  = new FairParRootFileIo();
+  parIo1->open(parFileIn.Data(), "READ");
   parIo2->open(parFileList, "in");
   rtdb->setFirstInput(parIo1);
   rtdb->setSecondInput(parIo2);
+  parIo3->open(parFileOut.Data(), "RECREATE");
   // ------------------------------------------------------------------------
 
 
@@ -407,7 +440,7 @@ void mcbm_event_ana(Int_t runId       = 831,
   std::cout << std::endl;
   std::cout << "-I- " << myName << ": Initialise run" << std::endl;
   run->Init();
-  rtdb->setOutput(parIo1);
+  rtdb->setOutput(parIo3);
   rtdb->saveOutput();
   rtdb->print();
   // ------------------------------------------------------------------------
@@ -428,7 +461,7 @@ void mcbm_event_ana(Int_t runId       = 831,
   std::cout << std::endl << std::endl;
   std::cout << "Macro finished successfully." << std::endl;
   std::cout << "Output file is " << outFile << std::endl;
-  std::cout << "Parameter file is " << parFile << std::endl;
+  std::cout << "Parameter file is " << parFileOut << std::endl;
   std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s"
             << std::endl;
   std::cout << std::endl;
diff --git a/macro/beamtime/mcbm2020/mcbm_event_reco.C b/macro/beamtime/mcbm2020/mcbm_event_reco.C
index 4c5f4a77747a4f310c23c66928d7292ac6dfd453..1be681d0acb0eccd6383b8368d9dc1e0f09ded5d 100644
--- a/macro/beamtime/mcbm2020/mcbm_event_reco.C
+++ b/macro/beamtime/mcbm2020/mcbm_event_reco.C
@@ -6,10 +6,19 @@
 //
 // --------------------------------------------------------------------------
 
-void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = -1) {
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t mcbm_event_reco(UInt_t uRunId        = 831,
+                       Int_t nTimeslices    = 0,
+                       TString sInpDir      = "./data",
+                       TString sOutDir      = "./data",
+                       Int_t iUnpFileIndex  = -1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
 
   // --- Logger settings ----------------------------------------------------
-  TString logLevel     = "WARN";
+  TString logLevel     = "INFO";
   TString logVerbosity = "LOW";
   // ------------------------------------------------------------------------
 
@@ -21,12 +30,44 @@ void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = -1) {
   TString parDir   = srcDir + "/parameters";
   // ------------------------------------------------------------------------
 
-
+  /// FIXME: Disable clang formatting around parameters initial value setting
+  /// due to problem with real file path length
+  /* clang-format off */
   // -----   In- and output file names   ------------------------------------
-  TString inFile  = Form("./data/unp_mcbm_%i.root", runId);
-  TString parFile = Form("./data/unp_mcbm_params_%i.root", runId);
-  TString outFile = Form("./data/reco_mcbm_%i.root", runId);
+  /// Standardized RUN ID
+  TString sRunId     = TString::Format("%03u", uRunId);
+  /// Initial pattern
+  TString inFile     = sInpDir + "/unp_mcbm_" + sRunId;
+  TString parFileIn  = sInpDir + "/unp_mcbm_params_" + sRunId;
+  TString parFileOut = sOutDir + "/reco_mcbm_event_params_" + sRunId;
+  TString outFile    = sOutDir + "/reco_mcbm_event_" + sRunId;
+  /// Add index of splitting at unpacking level if needed
+  if ( 0 <= iUnpFileIndex ) {
+    inFile     += TString::Format( "_%02u", iUnpFileIndex );
+    // the input par file is not split during unpacking!
+    parFileOut += TString::Format( "_%02u", iUnpFileIndex );
+    outFile    += TString::Format( "_%02u", iUnpFileIndex );
+  }  // if ( 0 <= iUnpFileIndex )
+  /// Add ROOT file suffix
+  inFile     += ".root";
+  parFileIn  += ".root";
+  parFileOut += ".root";
+  outFile    += ".root";
   // ------------------------------------------------------------------------
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
+
+  /*
+  std::cout << sInpDir << std::endl << sOutDir << std::endl;
+  std::cout << inFile << std::endl
+            << parFileIn << std::endl
+            << parFileOut << std::endl
+            << outFile << std::endl;
+  std::cout << uRunId << " " << nTimeslices << std::endl;
+
+  return kTRUE;
+  */
+
   // --- Load the geometry setup ----
   // This is currently only required by the TRD (parameters)
   std::string geoSetupTag = "mcbm_beam_2020_03";
@@ -37,7 +78,6 @@ void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = -1) {
   TList* parFileList = new TList();
   // ------------------------------------------------------------------------
 
-
   // -----   Timer   --------------------------------------------------------
   TStopwatch timer;
   timer.Start();
@@ -55,7 +95,7 @@ void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = -1) {
 
   // Define output file for FairMonitor histograms
   TString monitorFile {outFile};
-  monitorFile.ReplaceAll("rec", "rec.monitor");
+  monitorFile.ReplaceAll("reco", "reco.monitor");
   FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile);
   // ------------------------------------------------------------------------
 
@@ -72,9 +112,9 @@ void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = -1) {
   eventBuilder->SetEventBuilderAlgo(EventBuilderAlgo::FixedTimeWindow);
   eventBuilder->SetFixedTimeWindow(200.);
   eventBuilder->SetTriggerMinNumberT0(1);
-  // eventBuilder->SetTriggerMinNumberTrd(1);
   //eventBuilder->SetTriggerMinNumberSts(0);
   eventBuilder->SetTriggerMinNumberMuch(1);
+  // eventBuilder->SetTriggerMinNumberTrd(1);
   eventBuilder->SetTriggerMinNumberTof(10);
   // eventBuilder->SetFillHistos(kTRUE);
   run->AddTask(eventBuilder);
@@ -175,7 +215,6 @@ void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = -1) {
 
 
   // -----   Local reconstruction in TOF   ----------------------------------
-  // ------------------------------------------------------------------------
   // TOF defaults
   Int_t calMode      = 93;
   Int_t calSel       = 1;
@@ -209,179 +248,8 @@ void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = -1) {
 
   run->AddTask(tofCluster);
   std::cout << "-I- Added task " << tofCluster->GetName() << std::endl;
+  // ------------------------------------------------------------------------
 
-  // -----   Track reconstruction   ------------------------------------------
-  Int_t iTrackMode = 2;
-  switch (iTrackMode) {
-    case 2: {
-      Int_t iGenCor      = 1;
-      Double_t dScalFac  = 1.;
-      Double_t dChi2Lim2 = 3.5;
-      TString cTrkFile =
-        parDir + "/tof/" + Form("%s_tofFindTracks.hst.root", cCalId.Data());
-      Int_t iTrackingSetup = 1;
-      Int_t iCalOpt        = 0;
-
-      CbmTofTrackFinder* tofTrackFinder = new CbmTofTrackFinderNN();
-      tofTrackFinder->SetMaxTofTimeDifference(0.2);  // in ns/cm
-      tofTrackFinder->SetTxLIM(0.3);                 // max slope dx/dz
-      tofTrackFinder->SetTyLIM(0.3);  // max dev from mean slope dy/dz
-      tofTrackFinder->SetTyMean(0.);  // mean slope dy/dz
-      CbmTofTrackFitter* tofTrackFitter = new CbmTofTrackFitterKF(0, 211);
-      TFitter* MyFit                    = new TFitter(1);  // initialize Minuit
-      tofTrackFinder->SetFitter(tofTrackFitter);
-
-      CbmTofFindTracks* tofFindTracks =
-        new CbmTofFindTracks("TOF Track Finder");
-      tofFindTracks->UseFinder(tofTrackFinder);
-      tofFindTracks->UseFitter(tofTrackFitter);
-      tofFindTracks->SetCalOpt(iCalOpt);
-      // 1 - update offsets, 2 - update walk, 0 - bypass
-      tofFindTracks->SetCorMode(
-        iGenCor);  // valid options: 0,1,2,3,4,5,6, 10 - 19
-      tofFindTracks->SetTtTarg(
-        0.065);  // target value for Mar2020 triple stack -> betapeak ~ 0.95
-      //tofFindTracks->SetTtTarg(0.041);  // target value for inverse velocity, > 0.033 ns/cm!
-      //tofFindTracks->SetTtTarg(0.035);  // target value for inverse velocity, > 0.033 ns/cm!
-      tofFindTracks->SetCalParFileName(
-        cTrkFile);  // Tracker parameter value file name
-      tofFindTracks->SetBeamCounter(5, 0, 0);  // default beam counter
-      tofFindTracks->SetStationMaxHMul(
-        30);  // Max Hit Multiplicity in any used station
-
-      tofFindTracks->SetT0MAX(dScalFac);  // in ns
-      tofFindTracks->SetSIGT(0.08);       // default in ns
-      tofFindTracks->SetSIGX(0.3);        // default in cm
-      tofFindTracks->SetSIGY(0.45);       // default in cm
-      tofFindTracks->SetSIGZ(0.05);       // default in cm
-      tofFindTracks->SetUseSigCalib(
-        kFALSE);  // ignore resolutions in CalPar file
-      tofTrackFinder->SetSIGLIM(dChi2Lim2
-                                * 2.);  // matching window in multiples of chi2
-      tofTrackFinder->SetChiMaxAccept(dChi2Lim2);  // max tracklet chi2
-
-      Int_t iMinNofHits   = -1;
-      Int_t iNStations    = 0;
-      Int_t iNReqStations = 3;
-      switch (iTrackingSetup) {
-        case 0:  // bypass mode
-          iMinNofHits = -1;
-          iNStations  = 1;
-          tofFindTracks->SetStation(0, 5, 0, 0);  // Diamond
-          break;
-
-        case 1:  // for calibration mode of full setup
-          iMinNofHits   = 3;
-          iNStations    = 28;
-          iNReqStations = 4;
-          tofFindTracks->SetStation(0, 5, 0, 0);
-          tofFindTracks->SetStation(1, 0, 2, 2);
-          tofFindTracks->SetStation(2, 0, 1, 2);
-          tofFindTracks->SetStation(3, 0, 0, 2);
-          tofFindTracks->SetStation(4, 0, 2, 1);
-          tofFindTracks->SetStation(5, 0, 1, 1);
-          tofFindTracks->SetStation(6, 0, 0, 1);
-          tofFindTracks->SetStation(7, 0, 2, 3);
-          tofFindTracks->SetStation(8, 0, 1, 3);
-          tofFindTracks->SetStation(9, 0, 0, 3);
-          tofFindTracks->SetStation(10, 0, 2, 0);
-          tofFindTracks->SetStation(11, 0, 1, 0);
-          tofFindTracks->SetStation(12, 0, 0, 0);
-          tofFindTracks->SetStation(13, 0, 2, 4);
-          tofFindTracks->SetStation(14, 0, 1, 4);
-          tofFindTracks->SetStation(15, 0, 0, 4);
-          tofFindTracks->SetStation(16, 0, 4, 0);
-          tofFindTracks->SetStation(17, 0, 3, 0);
-          tofFindTracks->SetStation(18, 0, 4, 1);
-          tofFindTracks->SetStation(19, 0, 3, 1);
-          tofFindTracks->SetStation(20, 0, 4, 2);
-          tofFindTracks->SetStation(21, 0, 3, 2);
-          tofFindTracks->SetStation(22, 0, 4, 3);
-          tofFindTracks->SetStation(23, 0, 3, 3);
-          tofFindTracks->SetStation(24, 0, 4, 4);
-          tofFindTracks->SetStation(25, 0, 3, 4);
-          tofFindTracks->SetStation(26, 9, 0, 0);
-          tofFindTracks->SetStation(27, 9, 0, 1);
-          break;
-
-        case 2:  // for geometry check mode of full setup
-          iMinNofHits   = 3;
-          iNStations    = 27;
-          iNReqStations = 4;
-          tofFindTracks->SetStation(0, 0, 2, 2);
-          tofFindTracks->SetStation(1, 0, 1, 2);
-          tofFindTracks->SetStation(2, 0, 0, 2);
-          tofFindTracks->SetStation(3, 0, 2, 1);
-          tofFindTracks->SetStation(4, 0, 1, 1);
-          tofFindTracks->SetStation(5, 0, 0, 1);
-          tofFindTracks->SetStation(6, 0, 2, 3);
-          tofFindTracks->SetStation(7, 0, 1, 3);
-          tofFindTracks->SetStation(8, 0, 0, 3);
-          tofFindTracks->SetStation(9, 0, 2, 0);
-          tofFindTracks->SetStation(10, 0, 1, 0);
-          tofFindTracks->SetStation(11, 0, 0, 0);
-          tofFindTracks->SetStation(12, 0, 2, 4);
-          tofFindTracks->SetStation(13, 0, 1, 4);
-          tofFindTracks->SetStation(14, 0, 0, 4);
-          tofFindTracks->SetStation(15, 0, 4, 0);
-          tofFindTracks->SetStation(16, 0, 3, 0);
-          tofFindTracks->SetStation(17, 0, 4, 1);
-          tofFindTracks->SetStation(18, 0, 3, 1);
-          tofFindTracks->SetStation(19, 0, 4, 2);
-          tofFindTracks->SetStation(20, 0, 3, 2);
-          tofFindTracks->SetStation(21, 0, 4, 3);
-          tofFindTracks->SetStation(22, 0, 3, 3);
-          tofFindTracks->SetStation(23, 0, 4, 4);
-          tofFindTracks->SetStation(24, 0, 3, 4);
-          tofFindTracks->SetStation(25, 9, 0, 0);
-          tofFindTracks->SetStation(26, 9, 0, 1);
-          break;
-
-        case 3:  // for reduced bias tracking of full setup
-          iMinNofHits   = 3;
-          iNStations    = 28;
-          iNReqStations = 4;
-          tofFindTracks->SetStation(0, 0, 2, 2);
-          tofFindTracks->SetStation(1, 0, 1, 2);
-          tofFindTracks->SetStation(2, 0, 0, 2);
-          tofFindTracks->SetStation(3, 0, 2, 1);
-          tofFindTracks->SetStation(4, 0, 1, 1);
-          tofFindTracks->SetStation(5, 0, 0, 1);
-          tofFindTracks->SetStation(6, 0, 2, 3);
-          tofFindTracks->SetStation(7, 0, 1, 3);
-          tofFindTracks->SetStation(8, 0, 0, 3);
-          tofFindTracks->SetStation(9, 0, 2, 0);
-          tofFindTracks->SetStation(10, 0, 1, 0);
-          tofFindTracks->SetStation(11, 0, 0, 0);
-          tofFindTracks->SetStation(12, 0, 2, 4);
-          tofFindTracks->SetStation(13, 0, 1, 4);
-          tofFindTracks->SetStation(14, 0, 0, 4);
-          tofFindTracks->SetStation(15, 0, 4, 0);
-          tofFindTracks->SetStation(16, 0, 3, 0);
-          tofFindTracks->SetStation(17, 0, 4, 1);
-          tofFindTracks->SetStation(18, 0, 3, 1);
-          tofFindTracks->SetStation(19, 0, 4, 2);
-          tofFindTracks->SetStation(20, 0, 3, 2);
-          tofFindTracks->SetStation(21, 0, 4, 3);
-          tofFindTracks->SetStation(22, 0, 3, 3);
-          tofFindTracks->SetStation(23, 0, 4, 4);
-          tofFindTracks->SetStation(24, 0, 3, 4);
-          tofFindTracks->SetStation(25, 9, 0, 0);
-          tofFindTracks->SetStation(26, 9, 0, 1);
-          tofFindTracks->SetStation(27, 5, 0, 0);
-          break;
-      }
-      tofFindTracks->SetMinNofHits(iMinNofHits);
-      tofFindTracks->SetNStations(iNStations);
-      tofFindTracks->SetNReqStations(iNReqStations);
-      //tofFindTracks->PrintSetup();
-      run->AddTask(tofFindTracks);
-    } break;
-    case 1: {
-    }
-    case 0:
-    default:;
-  }
 
   // -----   Local reconstruction of RICH Hits ------------------------------
   CbmRichMCbmHitProducer* hitProdRich = new CbmRichMCbmHitProducer();
@@ -412,11 +280,12 @@ void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = -1) {
   FairRuntimeDb* rtdb        = run->GetRuntimeDb();
   FairParRootFileIo* parIo1  = new FairParRootFileIo();
   FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo();
-  parIo1->open(parFile.Data(), "UPDATE");
-  parIo2->open(parFileList, "in");
+  FairParRootFileIo* parIo3  = new FairParRootFileIo();
+  parIo1->open(parFileIn.Data(), "READ");
   rtdb->setFirstInput(parIo1);
   parIo2->open(parFileList, "in");
   rtdb->setSecondInput(parIo2);
+  parIo3->open(parFileOut.Data(), "RECREATE");
   // ------------------------------------------------------------------------
 
 
@@ -424,7 +293,7 @@ void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = -1) {
   std::cout << std::endl;
   std::cout << "-I- " << myName << ": Initialise run" << std::endl;
   run->Init();
-  rtdb->setOutput(parIo1);
+  rtdb->setOutput(parIo3);
   rtdb->saveOutput();
   rtdb->print();
   // ------------------------------------------------------------------------
@@ -445,7 +314,7 @@ void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = -1) {
   std::cout << std::endl << std::endl;
   std::cout << "Macro finished successfully." << std::endl;
   std::cout << "Output file is " << outFile << std::endl;
-  std::cout << "Parameter file is " << parFile << std::endl;
+  std::cout << "Parameter file is " << parFileOut << std::endl;
   std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s"
             << std::endl;
   std::cout << std::endl;
@@ -475,4 +344,6 @@ void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = -1) {
   /// --- Screen output for automatic tests
   std::cout << " Test passed" << std::endl;
   std::cout << " All ok " << std::endl;
+
+  return kTRUE;
 }
diff --git a/macro/beamtime/mcbm2020/mcbm_event_reco_kronos.C b/macro/beamtime/mcbm2020/mcbm_event_reco_kronos.C
index b99fd0b0cc8fe6484b46d5c099bc4340da256a3a..03552c2ca0ba0641dbd5aa03879008af8ac30ab0 100644
--- a/macro/beamtime/mcbm2020/mcbm_event_reco_kronos.C
+++ b/macro/beamtime/mcbm2020/mcbm_event_reco_kronos.C
@@ -6,274 +6,49 @@
 //
 // --------------------------------------------------------------------------
 
-void mcbm_event_reco(Int_t runId = 831, Int_t nTimeslices = 300) {
-
-  // --- Logger settings ----------------------------------------------------
-  TString logLevel     = "INFO";
-  TString logVerbosity = "LOW";
-  // ------------------------------------------------------------------------
-
-
-  // -----   Environment   --------------------------------------------------
-  TString myName   = "mcbm_reco";  // this macro's name for screen output
-  TString srcDir   = gSystem->Getenv("VMCWORKDIR");  // top source directory
-  TString paramDir = srcDir + "/macro/beamtime/mcbm2020/";
-  // ------------------------------------------------------------------------
-
-
-  // -----   In- and output file names   ------------------------------------
-  TString inFile = Form("/lustre/cbm/users/ploizeau/mcbm2020/"
-                        "unp_evt_data_7f229b3f_20201103/unp_mcbm_%i.root",
-                        runId);
-  TString parFileIn =
-    Form("/lustre/cbm/users/ploizeau/mcbm2020/unp_evt_data_7f229b3f_20201103/"
-         "unp_mcbm_params_%i.root",
-         runId);
-  TString parFileOut = Form("./data/reco_mcbm_params_%i.root", runId);
-  TString outFile    = Form("./data/reco_mcbm_%i.root", runId);
-  // ------------------------------------------------------------------------
-
-  // --- Load the geometry setup ----
-  // This is currently only required by the TRD (parameters)
-  std::string geoSetupTag = "mcbm_beam_2020_03";
-  TString geoFile =
-    paramDir + geoSetupTag.data() + ".geo.root";  // Created in sim. run
-  CbmSetup* geoSetup = CbmSetup::Instance();
-  geoSetup->LoadSetup(geoSetupTag.data());
-  TList* parFileList = new TList();
-  // ------------------------------------------------------------------------
-
-  // -----   Timer   --------------------------------------------------------
-  TStopwatch timer;
-  timer.Start();
-  // ------------------------------------------------------------------------
-
-
-  // -----   FairRunAna   ---------------------------------------------------
-  FairRunAna* run             = new FairRunAna();
-  FairFileSource* inputSource = new FairFileSource(inFile);
-  run->SetSource(inputSource);
-
-  FairRootFileSink* outputSink = new FairRootFileSink(outFile);
-  run->SetSink(outputSink);
-  run->SetGeomFile(geoFile);
-
-  // Define output file for FairMonitor histograms
-  TString monitorFile {outFile};
-  monitorFile.ReplaceAll("rec", "rec.monitor");
-  FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile);
-  // ------------------------------------------------------------------------
-
-
-  // -----   Logger settings   ----------------------------------------------
-  FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data());
-  FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data());
-  // ------------------------------------------------------------------------
-
-  //--------------------event builder-------------------//
-  CbmMcbm2018EventBuilder* eventBuilder = new CbmMcbm2018EventBuilder();
-  // eventBuilder->SetEventBuilderAlgo(EventBuilderAlgo::MaximumTimeGap);
-  //eventBuilder->SetMaximumTimeGap(50.);
-  eventBuilder->SetEventBuilderAlgo(EventBuilderAlgo::FixedTimeWindow);
-  eventBuilder->SetFixedTimeWindow(200.);
-  eventBuilder->SetTriggerMinNumberT0(1);
-  //eventBuilder->SetTriggerMinNumberSts(0);
-  eventBuilder->SetTriggerMinNumberMuch(1);
-  eventBuilder->SetTriggerMinNumberTof(10);
-  run->AddTask(eventBuilder);
-  // ------------------------------------------------------------------------
-
-
-  // -----   Reconstruction tasks   -----------------------------------------
-
-  // -----   Local reconstruction in MUCH   ---------------------------------
-  Int_t flag = 1;
-  TString parDir =
-    TString(gSystem->Getenv("VMCWORKDIR")) + TString("/parameters");
-  TString muchDigiFile(
-    parDir + "/much/much_v19c_mcbm_digi_sector.root");  // MUCH digi file
-  CbmMuchFindHitsGem* muchFindHits =
-    new CbmMuchFindHitsGem(muchDigiFile.Data(), flag);
-  muchFindHits->SetBeamTimeDigi(kTRUE);
-  run->AddTask(muchFindHits);
-  std::cout << "-I- : Added task " << muchFindHits->GetName() << std::endl;
-  //-------------------------------------------------------------------------------
-
-
-  // -----   Local reconstruction in STS   ----------------------------------
-  CbmRecoSts* recoSts = new CbmRecoSts();
-  recoSts->SetMode(kCbmRecoEvent);
-
-  //recoSts->SetTimeCutDigisAbs( 20 );// cluster finder: time cut in ns
-  //recoSts->SetTimeCutClustersAbs(20.); // hit finder: time cut in ns
-
-  // ASIC params: #ADC channels, dyn. range, threshold, time resol., dead time,
-  // noise RMS, zero-threshold crossing rate
-  auto parAsic =
-    new CbmStsParAsic(32, 75000., 3000., 5., 800., 1000., 3.9789e-3);
-
-  // Module params: number of channels, number of channels per ASIC
-  auto parMod = new CbmStsParModule(2048, 128);
-  parMod->SetAllAsics(*parAsic);
-  recoSts->UseModulePar(parMod);
-
-  // Sensor params
-  auto sensorPar = new CbmStsParSensor(CbmStsSensorClass::kDssdStereo);
-  sensorPar->SetPar(0, 6.2092);  // Extension in x
-  sensorPar->SetPar(1, 6.2);     // Extension in y
-  sensorPar->SetPar(2, 0.03);    // Extension in z
-  sensorPar->SetPar(3, 5.9692);  // Active size in y
-  sensorPar->SetPar(4, 1024.);   // Number of strips front side
-  sensorPar->SetPar(5, 1024.);   // Number of strips back side
-  sensorPar->SetPar(6, 0.0058);  // Strip pitch front side
-  sensorPar->SetPar(7, 0.0058);  // Strip pitch back side
-  sensorPar->SetPar(8, 7.5);     // Stereo angle front side
-  sensorPar->SetPar(9, 0.0);     // Stereo angle back side
-  recoSts->UseSensorPar(sensorPar);
-
-  // Sensor conditions: full depletion voltage, bias voltage, temperature,
-  // coupling capacitance, inter-strip capacitance
-  auto sensorCond = new CbmStsParSensorCond(70., 140., 268., 17.5, 1.);
-  recoSts->UseSensorCond(sensorCond);
-
-  run->AddTask(recoSts);
-  std::cout << "-I- : Added task " << recoSts->GetName() << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Local reconstruction in TRD   ----------------------------------
-  // Load parameters <- they are required by the hit producer.
-  // For now, it is enough to load the default ascii parameters
-  // if no root file is existing from the unpacking process.
-  TString geoTagTrd = "";
-  bool isActiveTrd =
-    (geoSetup->GetGeoTag(ECbmModuleId::kTrd, geoTagTrd)) ? true : false;
-  if (!isActiveTrd) {
-    LOG(warning) << Form(
-      "TRD - parameter loading - Trd not found in CbmSetup(%s) -> parameters "
-      "can not be loaded correctly!",
-      geoSetupTag.data());
-  } else {
-    TString paramFilesTrd(
-      Form("%s/parameters/trd/trd_%s", srcDir.Data(), geoTagTrd.Data()));
-    std::vector<std::string> paramFilesVecTrd;
-    CbmTrdParManager::GetParFileExtensions(&paramFilesVecTrd);
-    for (auto parIt : paramFilesVecTrd) {
-      parFileList->Add(
-        new TObjString(Form("%s.%s.par", paramFilesTrd.Data(), parIt.data())));
-    }
-  }
-  // -- end trd parameters
-  // -- beginn trd reco
-  Double_t triggerThreshold       = 0.5e-6;  // Default
-  CbmTrdClusterFinder* trdCluster = new CbmTrdClusterFinder();
-  trdCluster->SetNeighbourEnable(true, false);
-  trdCluster->SetMinimumChargeTH(triggerThreshold);
-  trdCluster->SetRowMerger(true);
-  run->AddTask(trdCluster);
-  std::cout << "-I- : Added task " << trdCluster->GetName() << std::endl;
-
-  CbmTrdHitProducer* trdHit = new CbmTrdHitProducer();
-  run->AddTask(trdHit);
-  std::cout << "-I- : Added task " << trdHit->GetName() << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Local reconstruction in TOF   ----------------------------------
-  // ------------------------------------------------------------------------
-
-
-  // -----   Local reconstruction of RICH Hits ------------------------------
-  CbmRichMCbmHitProducer* hitProdRich = new CbmRichMCbmHitProducer();
-  hitProdRich->setToTLimits(23.7, 30.0);
-  hitProdRich->applyToTCut();
-  TString sRichMapFile =
-    srcDir + "/macro/rich/mcbm/beamtime/mRICH_Mapping_vert_20190318_elView.geo";
-  hitProdRich->SetMappingFile(sRichMapFile.Data());
-  run->AddTask(hitProdRich);
-  // ------------------------------------------------------------------------
-
-  // -----   Local reconstruction in RICh -> Finding of Rings ---------------
-  CbmRichReconstruction* richReco = new CbmRichReconstruction();
-  richReco->UseMCbmSetup();
-  run->AddTask(richReco);
-  // ------------------------------------------------------------------------
-
-
-  // -----  Psd hit producer   ----------------------------------------------
-  CbmPsdMCbmHitProducer* hitProdPsd = new CbmPsdMCbmHitProducer();
-  run->AddTask(hitProdPsd);
-  // ------------------------------------------------------------------------
-
-
-  // -----  Parameter database   --------------------------------------------
-  std::cout << std::endl << std::endl;
-  std::cout << "-I- " << myName << ": Set runtime DB" << std::endl;
-  FairRuntimeDb* rtdb        = run->GetRuntimeDb();
-  FairParRootFileIo* parIo1  = new FairParRootFileIo();
-  FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo();
-  FairParRootFileIo* parIo3  = new FairParRootFileIo();
-  parIo1->open(parFileIn.Data(), "READ");
-  rtdb->setFirstInput(parIo1);
-  parIo2->open(parFileList, "in");
-  rtdb->setSecondInput(parIo2);
-  parIo3->open(parFileOut.Data(), "RECREATE");
-  // ------------------------------------------------------------------------
-
-
-  // -----   Run initialisation   -------------------------------------------
-  std::cout << std::endl;
-  std::cout << "-I- " << myName << ": Initialise run" << std::endl;
-  run->Init();
-  rtdb->setOutput(parIo3);
-  rtdb->saveOutput();
-  rtdb->print();
-  // ------------------------------------------------------------------------
-
-
-  // -----   Start run   ----------------------------------------------------
-  std::cout << std::endl << std::endl;
-  std::cout << "-I- " << myName << ": Starting run" << std::endl;
-  run->Run(0, nTimeslices);
-  // ------------------------------------------------------------------------
-
-
-  // -----   Finish   -------------------------------------------------------
-  timer.Stop();
-  FairMonitor::GetMonitor()->Print();
-  Double_t rtime = timer.RealTime();
-  Double_t ctime = timer.CpuTime();
-  std::cout << std::endl << std::endl;
-  std::cout << "Macro finished successfully." << std::endl;
-  std::cout << "Output file is " << outFile << std::endl;
-  std::cout << "Parameter file is " << parFileOut << std::endl;
-  std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s"
-            << std::endl;
-  std::cout << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Resource monitoring   ------------------------------------------
-  // Extract the maximal used memory an add is as Dart measurement
-  // This line is filtered by CTest and the value send to CDash
-  FairSystemInfo sysInfo;
-  Float_t maxMemory = sysInfo.GetMaxMemory();
-  std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
-  std::cout << maxMemory;
-  std::cout << "</DartMeasurement>" << std::endl;
-
-  Float_t cpuUsage = ctime / rtime;
-  std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
-  std::cout << cpuUsage;
-  std::cout << "</DartMeasurement>" << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Function needed for CTest runtime dependency   -----------------
-  //  RemoveGeoManager();
-  // ------------------------------------------------------------------------
-
-  /// --- Screen output for automatic tests
-  std::cout << " Test passed" << std::endl;
-  std::cout << " All ok " << std::endl;
+#include "mcbm_event_reco.C"
+
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t mcbm_event_reco_kronos(UInt_t uRunIdx = 28,
+                              Int_t nTimeslices = 0,
+                              TString sInpDir = "/lustre/cbm/users/ploizeau/mcbm2020/"
+                                                "unp_evt_data_7f229b3f_20201103",
+                              TString sOutDir = "./data",
+                              Int_t iUnpFileIndex = -1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
+
+  UInt_t uRunId = 0;
+
+  if (99999 != uRunIdx) {
+    std::vector<UInt_t> vuListRunId = {
+      692, 698, 702, 704, 705, 706, 707,            //  7 =>  0 -  6
+      744, 750, 759, 760, 761, 762, 799,            //  7 =>  7 - 13
+      811, 812, 816, 817, 819,                      //  5 => 14 - 18
+      820, 821, 822, 824, 826, 827, 828, 829,       //  8 => 19 - 26
+      830, 831, 836,                                //  3 => 27 - 29
+      841, 846, 849,                                //  3 => 30 - 32
+      850, 851, 852, 854, 855, 856, 857, 858, 859,  //  9 => 33 - 41
+      860, 861, 862, 863, 864, 865, 866             //  7 => 42 - 48
+
+      /*
+      /// With runs < 1 min due to missmatch!
+      811, 812, 816, 817, 818, 819,                  //  6 => 14 - 19
+      820, 821, 822, 824, 826, 827, 828, 829,        //  8 => 20 - 27
+      830, 831, 836, 839,                            //  4 => 28 - 31
+      840, 841, 842, 844, 845, 846, 848, 849,        //  8 => 32 - 39
+      850, 851, 852, 854, 855, 856, 857, 858, 859,   //  9 => 40 - 48
+      860, 861, 862, 863, 864, 865, 866              //  7 => 49 - 55
+      */
+    };
+    if (vuListRunId.size() <= uRunIdx) return kFALSE;
+
+    uRunId = vuListRunId[uRunIdx];
+  }  // if( 99999 != uRunIdx )
+
+  if (uRunId < 692 && 0 != uRunId) return kFALSE;
+
+  return mcbm_event_reco(uRunId, nTimeslices, sInpDir, sOutDir, iUnpFileIndex);
 }
diff --git a/macro/beamtime/mcbm2020/mcbm_reco.C b/macro/beamtime/mcbm2020/mcbm_reco.C
index 9f8847891c250e7d57892e17bfb0a9ba5bc8df52..962f42d571a3b8bd7ff07b913ae124f498382f4e 100644
--- a/macro/beamtime/mcbm2020/mcbm_reco.C
+++ b/macro/beamtime/mcbm2020/mcbm_reco.C
@@ -5,8 +5,16 @@
 //
 // --------------------------------------------------------------------------
 
-
-void mcbm_reco(Int_t runId = 831, Int_t nTimeslices = 0) {
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t mcbm_reco(UInt_t uRunId        = 831,
+                 Int_t nTimeslices    = 0,
+                 TString sInpDir      = "./data",
+                 TString sOutDir      = "./data",
+                 Int_t iUnpFileIndex  = -1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
 
   // --- Logger settings ----------------------------------------------------
   TString logLevel     = "INFO";
@@ -23,11 +31,38 @@ void mcbm_reco(Int_t runId = 831, Int_t nTimeslices = 0) {
 
 
   // -----   In- and output file names   ------------------------------------
-  TString inFile  = Form("./data/unp_mcbm_%i.root", runId);
-  TString parFile = Form("./data/unp_mcbm_params_%i.root", runId);
-  TString outFile = Form("./data/reco_mcbm_%i.root", runId);
+  /// Standardized RUN ID
+  TString sRunId = TString::Format("%03u", uRunId);
+  /// Initial pattern
+  TString inFile     = sInpDir + "/unp_mcbm_" + sRunId;
+  TString parFileIn  = sInpDir + "/unp_mcbm_params_" + sRunId;
+  TString parFileOut = sOutDir + "/reco_mcbm_params_" + sRunId;
+  TString outFile    = sOutDir + "/reco_mcbm_" + sRunId;
+  /// Add index of splitting at unpacking level if needed
+  if (0 <= iUnpFileIndex) {
+    inFile += TString::Format("_%02u", iUnpFileIndex);
+    // the input par file is not split during unpacking!
+    parFileOut += TString::Format("_%02u", iUnpFileIndex);
+    outFile += TString::Format("_%02u", iUnpFileIndex);
+  }  // if ( 0 <= uUnpFileIndex )
+  /// Add ROOT file suffix
+  inFile += ".root";
+  parFileIn += ".root";
+  parFileOut += ".root";
+  outFile += ".root";
   // ------------------------------------------------------------------------
 
+  /*
+  std::cout << sInpDir << std::endl << sOutDir << std::endl;
+  std::cout << inFile << std::endl
+            << parFileIn << std::endl
+            << parFileOut << std::endl
+            << outFile << std::endl;
+  std::cout << uRunId << " " << nTimeslices << std::endl;
+
+  return kTRUE;
+  */
+
   // --- Load the geometry setup ----
   // This is currently only required by the TRD (parameters)
   std::string geoSetupTag = "mcbm_beam_2020_03";
@@ -55,7 +90,7 @@ void mcbm_reco(Int_t runId = 831, Int_t nTimeslices = 0) {
 
   // Define output file for FairMonitor histograms
   TString monitorFile {outFile};
-  monitorFile.ReplaceAll("rec", "rec.monitor");
+  monitorFile.ReplaceAll("reco", "reco.monitor");
   FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile);
   // ------------------------------------------------------------------------
 
@@ -222,11 +257,12 @@ void mcbm_reco(Int_t runId = 831, Int_t nTimeslices = 0) {
   FairRuntimeDb* rtdb        = run->GetRuntimeDb();
   FairParRootFileIo* parIo1  = new FairParRootFileIo();
   FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo();
-  parIo1->open(parFile.Data(), "UPDATE");
-  parIo2->open(parFileList, "in");
+  FairParRootFileIo* parIo3  = new FairParRootFileIo();
+  parIo1->open(parFileIn.Data(), "READ");
   rtdb->setFirstInput(parIo1);
   parIo2->open(parFileList, "in");
   rtdb->setSecondInput(parIo2);
+  parIo3->open(parFileOut.Data(), "RECREATE");
   // ------------------------------------------------------------------------
 
 
@@ -234,7 +270,7 @@ void mcbm_reco(Int_t runId = 831, Int_t nTimeslices = 0) {
   std::cout << std::endl;
   std::cout << "-I- " << myName << ": Initialise run" << std::endl;
   run->Init();
-  rtdb->setOutput(parIo1);
+  rtdb->setOutput(parIo3);
   rtdb->saveOutput();
   rtdb->print();
   // ------------------------------------------------------------------------
@@ -255,7 +291,7 @@ void mcbm_reco(Int_t runId = 831, Int_t nTimeslices = 0) {
   std::cout << std::endl << std::endl;
   std::cout << "Macro finished successfully." << std::endl;
   std::cout << "Output file is " << outFile << std::endl;
-  std::cout << "Parameter file is " << parFile << std::endl;
+  std::cout << "Parameter file is " << parFileOut << std::endl;
   std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s"
             << std::endl;
   std::cout << std::endl;
@@ -285,4 +321,6 @@ void mcbm_reco(Int_t runId = 831, Int_t nTimeslices = 0) {
   /// --- Screen output for automatic tests
   std::cout << " Test passed" << std::endl;
   std::cout << " All ok " << std::endl;
+
+  return kTRUE;
 }
diff --git a/macro/beamtime/mcbm2020/mcbm_reco_kronos.C b/macro/beamtime/mcbm2020/mcbm_reco_kronos.C
index 2df53707813399d5cfb12e9b62643f87004ea662..07ba9365377607e3daa460b1bbf1674f3d8f86ec 100644
--- a/macro/beamtime/mcbm2020/mcbm_reco_kronos.C
+++ b/macro/beamtime/mcbm2020/mcbm_reco_kronos.C
@@ -5,258 +5,49 @@
 //
 // --------------------------------------------------------------------------
 
-void mcbm_reco_kronos(Int_t runId = 831, Int_t nTimeslices = 0) {
-
-  // --- Logger settings ----------------------------------------------------
-  TString logLevel     = "INFO";
-  TString logVerbosity = "LOW";
-  // ------------------------------------------------------------------------
-
-
-  // -----   Environment   --------------------------------------------------
-  TString myName   = "mcbm_reco";  // this macro's name for screen output
-  TString srcDir   = gSystem->Getenv("VMCWORKDIR");  // top source directory
-  TString paramDir = srcDir + "/macro/beamtime/mcbm2020/";
-  //    ------------------------------------------------------------------------
-
-
-  // -----   In- and output file names   ------------------------------------
-  TString inFile = Form("/lustre/cbm/users/ploizeau/mcbm2020/"
-                        "unp_evt_data_7f229b3f_20201103/unp_mcbm_%i.root",
-                        runId);
-  TString parFileIn =
-    Form("/lustre/cbm/users/ploizeau/mcbm2020/unp_evt_data_7f229b3f_20201103/"
-         "unp_mcbm_params_%i.root",
-         runId);
-  TString parFileOut = Form("./data/reco_mcbm_params_%i.root", runId);
-  TString outFile    = Form("./data/reco_mcbm_%i.root", runId);
-  // ------------------------------------------------------------------------
-
-  // --- Load the geometry setup ----
-  // This is currently only required by the TRD (parameters)
-  std::string geoSetupTag = "mcbm_beam_2020_03";
-  TString geoFile =
-    paramDir + geoSetupTag.data() + ".geo.root";  // Created in sim. run
-  CbmSetup* geoSetup = CbmSetup::Instance();
-  geoSetup->LoadSetup(geoSetupTag.data());
-  TList* parFileList = new TList();
-  // ------------------------------------------------------------------------
-
-  // -----   Timer   --------------------------------------------------------
-  TStopwatch timer;
-  timer.Start();
-  // ------------------------------------------------------------------------
-
-
-  // -----   FairRunAna   ---------------------------------------------------
-  FairRunAna* run             = new FairRunAna();
-  FairFileSource* inputSource = new FairFileSource(inFile);
-  run->SetSource(inputSource);
-
-  FairRootFileSink* outputSink = new FairRootFileSink(outFile);
-  run->SetSink(outputSink);
-  run->SetGeomFile(geoFile);
-
-  // Define output file for FairMonitor histograms
-  TString monitorFile {outFile};
-  monitorFile.ReplaceAll("rec", "rec.monitor");
-  FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile);
-  // ------------------------------------------------------------------------
-
-
-  // -----   Logger settings   ----------------------------------------------
-  FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data());
-  FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data());
-  // ------------------------------------------------------------------------
-
-
-  // -----   Reconstruction tasks   -----------------------------------------
-
-  // -----   Local reconstruction in MUCH   ---------------------------------
-  Int_t flag = 1;
-  TString parDir =
-    TString(gSystem->Getenv("VMCWORKDIR")) + TString("/parameters");
-  TString muchDigiFile(
-    parDir + "/much/much_v19c_mcbm_digi_sector.root");  // MUCH digi file
-  CbmMuchFindHitsGem* muchFindHits =
-    new CbmMuchFindHitsGem(muchDigiFile.Data(), flag);
-  muchFindHits->SetBeamTimeDigi(kTRUE);
-  run->AddTask(muchFindHits);
-  std::cout << "-I- : Added task " << muchFindHits->GetName() << std::endl;
-  //--------------------------------------------------------
-
-  // -----   Local reconstruction in STS   ----------------------------------
-  CbmRecoSts* recoSts = new CbmRecoSts();
-
-  //recoSts->SetTimeCutDigisAbs( 20 );// cluster finder: time cut in ns
-  //recoSts->SetTimeCutClustersAbs(20.); // hit finder: time cut in ns
-
-  // ASIC params: #ADC channels, dyn. range, threshold, time resol., dead time,
-  // noise RMS, zero-threshold crossing rate
-  auto parAsic =
-    new CbmStsParAsic(32, 75000., 3000., 5., 800., 1000., 3.9789e-3);
-
-  // Module params: number of channels, number of channels per ASIC
-  auto parMod = new CbmStsParModule(2048, 128);
-  parMod->SetAllAsics(*parAsic);
-  recoSts->UseModulePar(parMod);
-
-  // Sensor params
-  auto sensorPar = new CbmStsParSensor(CbmStsSensorClass::kDssdStereo);
-  sensorPar->SetPar(0, 6.2092);  // Extension in x
-  sensorPar->SetPar(1, 6.2);     // Extension in y
-  sensorPar->SetPar(2, 0.03);    // Extension in z
-  sensorPar->SetPar(3, 5.9692);  // Active size in y
-  sensorPar->SetPar(4, 1024.);   // Number of strips front side
-  sensorPar->SetPar(5, 1024.);   // Number of strips back side
-  sensorPar->SetPar(6, 0.0058);  // Strip pitch front side
-  sensorPar->SetPar(7, 0.0058);  // Strip pitch back side
-  sensorPar->SetPar(8, 7.5);     // Stereo angle front side
-  sensorPar->SetPar(9, 0.0);     // Stereo angle back side
-  recoSts->UseSensorPar(sensorPar);
-
-  // Sensor conditions: full depletion voltage, bias voltage, temperature,
-  // coupling capacitance, inter-strip capacitance
-  auto sensorCond = new CbmStsParSensorCond(70., 140., 268., 17.5, 1.);
-  recoSts->UseSensorCond(sensorCond);
-
-  run->AddTask(recoSts);
-  std::cout << "-I- : Added task " << recoSts->GetName() << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Local reconstruction in TRD   ----------------------------------
-  // Load parameters <- they are required by the hit producer.
-  // For now, it is enough to load the default ascii parameters
-  // if no root file is existing from the unpacking process.
-  TString geoTagTrd = "";
-  bool isActiveTrd =
-    (geoSetup->GetGeoTag(ECbmModuleId::kTrd, geoTagTrd)) ? true : false;
-  if (!isActiveTrd) {
-    LOG(warning) << Form(
-      "TRD - parameter loading - Trd not found in CbmSetup(%s) -> parameters "
-      "can not be loaded correctly!",
-      geoSetupTag.data());
-  } else {
-    TString paramFilesTrd(
-      Form("%s/parameters/trd/trd_%s", srcDir.Data(), geoTagTrd.Data()));
-    std::vector<std::string> paramFilesVecTrd;
-    CbmTrdParManager::GetParFileExtensions(&paramFilesVecTrd);
-    for (auto parIt : paramFilesVecTrd) {
-      parFileList->Add(
-        new TObjString(Form("%s.%s.par", paramFilesTrd.Data(), parIt.data())));
-    }
-  }
-  // -- end trd parameters
-  Double_t triggerThreshold       = 0.5e-6;  // Default
-  CbmTrdClusterFinder* trdCluster = new CbmTrdClusterFinder();
-  trdCluster->SetNeighbourEnable(true, false);
-  trdCluster->SetMinimumChargeTH(triggerThreshold);
-  trdCluster->SetRowMerger(true);
-  run->AddTask(trdCluster);
-  std::cout << "-I- : Added task " << trdCluster->GetName() << std::endl;
-
-  CbmTrdHitProducer* trdHit = new CbmTrdHitProducer();
-  run->AddTask(trdHit);
-  std::cout << "-I- : Added task " << trdHit->GetName() << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Local reconstruction in TOF   ----------------------------------
-  // ------------------------------------------------------------------------
-
-
-  // -----   Local reconstruction of RICH Hits ------------------------------
-  CbmRichMCbmHitProducer* hitProdRich = new CbmRichMCbmHitProducer();
-  hitProdRich->setToTLimits(23.7, 30.0);
-  hitProdRich->applyToTCut();
-  TString sRichMapFile =
-    srcDir + "/macro/rich/mcbm/beamtime/mRICH_Mapping_vert_20190318_elView.geo";
-  hitProdRich->SetMappingFile(sRichMapFile.Data());
-  run->AddTask(hitProdRich);
-  // ------------------------------------------------------------------------
-
-  // -----   Local reconstruction in RICh -> Finding of Rings ---------------
-  CbmRichReconstruction* richReco = new CbmRichReconstruction();
-  richReco->UseMCbmSetup();
-  run->AddTask(richReco);
-  // ------------------------------------------------------------------------
-
-
-  // -----  Psd hit producer   ----------------------------------------------
-  CbmPsdMCbmHitProducer* hitProdPsd = new CbmPsdMCbmHitProducer();
-  run->AddTask(hitProdPsd);
-  // ------------------------------------------------------------------------
-
-
-  // -----  Parameter database   --------------------------------------------
-  std::cout << std::endl << std::endl;
-  std::cout << "-I- " << myName << ": Set runtime DB" << std::endl;
-  FairRuntimeDb* rtdb        = run->GetRuntimeDb();
-  FairParRootFileIo* parIo1  = new FairParRootFileIo();
-  FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo();
-  FairParRootFileIo* parIo3  = new FairParRootFileIo();
-  parIo1->open(parFileIn.Data(), "READ");
-  rtdb->setFirstInput(parIo1);
-  parIo2->open(parFileList, "in");
-  rtdb->setSecondInput(parIo2);
-  parIo3->open(parFileOut.Data(), "RECREATE");
-  // ------------------------------------------------------------------------
-
-
-  // -----   Run initialisation   -------------------------------------------
-  std::cout << std::endl;
-  std::cout << "-I- " << myName << ": Initialise run" << std::endl;
-  run->Init();
-  rtdb->setOutput(parIo3);
-  rtdb->saveOutput();
-  rtdb->print();
-  // ------------------------------------------------------------------------
-
-
-  // -----   Start run   ----------------------------------------------------
-  std::cout << std::endl << std::endl;
-  std::cout << "-I- " << myName << ": Starting run" << std::endl;
-  run->Run(0, nTimeslices);
-  // ------------------------------------------------------------------------
-
-
-  // -----   Finish   -------------------------------------------------------
-  timer.Stop();
-  FairMonitor::GetMonitor()->Print();
-  Double_t rtime = timer.RealTime();
-  Double_t ctime = timer.CpuTime();
-  std::cout << std::endl << std::endl;
-  std::cout << "Macro finished successfully." << std::endl;
-  std::cout << "Output file is " << outFile << std::endl;
-  std::cout << "Parameter file is " << parFileOut << std::endl;
-  std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s"
-            << std::endl;
-  std::cout << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Resource monitoring   ------------------------------------------
-  // Extract the maximal used memory an add is as Dart measurement
-  // This line is filtered by CTest and the value send to CDash
-  FairSystemInfo sysInfo;
-  Float_t maxMemory = sysInfo.GetMaxMemory();
-  std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
-  std::cout << maxMemory;
-  std::cout << "</DartMeasurement>" << std::endl;
-
-  Float_t cpuUsage = ctime / rtime;
-  std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
-  std::cout << cpuUsage;
-  std::cout << "</DartMeasurement>" << std::endl;
-  // ------------------------------------------------------------------------
-
-
-  // -----   Function needed for CTest runtime dependency   -----------------
-  //  RemoveGeoManager();
-  // ------------------------------------------------------------------------
-
-  /// --- Screen output for automatic tests
-  std::cout << " Test passed" << std::endl;
-  std::cout << " All ok " << std::endl;
+#include "mcbm_reco.C"
+
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t mcbm_reco_kronos(UInt_t uRunIdx    = 28,
+                        Int_t nTimeslices = 0,
+                        TString sInpDir = "/lustre/cbm/users/ploizeau/mcbm2020/"
+                                          "unp_evt_data_7f229b3f_20201103",
+                        TString sOutDir      = "./data",
+                        Int_t iUnpFileIndex = -1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
+
+  UInt_t uRunId = 0;
+
+  if (99999 != uRunIdx) {
+    std::vector<UInt_t> vuListRunId = {
+      692, 698, 702, 704, 705, 706, 707,            //  7 =>  0 -  6
+      744, 750, 759, 760, 761, 762, 799,            //  7 =>  7 - 13
+      811, 812, 816, 817, 819,                      //  5 => 14 - 18
+      820, 821, 822, 824, 826, 827, 828, 829,       //  8 => 19 - 26
+      830, 831, 836,                                //  3 => 27 - 29
+      841, 846, 849,                                //  3 => 30 - 32
+      850, 851, 852, 854, 855, 856, 857, 858, 859,  //  9 => 33 - 41
+      860, 861, 862, 863, 864, 865, 866             //  7 => 42 - 48
+
+      /*
+      /// With runs < 1 min due to missmatch!
+      811, 812, 816, 817, 818, 819,                  //  6 => 14 - 19
+      820, 821, 822, 824, 826, 827, 828, 829,        //  8 => 20 - 27
+      830, 831, 836, 839,                            //  4 => 28 - 31
+      840, 841, 842, 844, 845, 846, 848, 849,        //  8 => 32 - 39
+      850, 851, 852, 854, 855, 856, 857, 858, 859,   //  9 => 40 - 48
+      860, 861, 862, 863, 864, 865, 866              //  7 => 49 - 55
+      */
+    };
+    if (vuListRunId.size() <= uRunIdx) return kFALSE;
+
+    uRunId = vuListRunId[uRunIdx];
+  }  // if( 99999 != uRunIdx )
+
+  if (uRunId < 692 && 0 != uRunId) return kFALSE;
+
+  return mcbm_reco(uRunId, nTimeslices, sInpDir, sOutDir, iUnpFileIndex);
 }
diff --git a/macro/beamtime/mcbm2020/mcbm_tof_tracking.C b/macro/beamtime/mcbm2020/mcbm_tof_tracking.C
new file mode 100644
index 0000000000000000000000000000000000000000..436401a3853c0dd2991a4ca79ebc31aba2f4edda
--- /dev/null
+++ b/macro/beamtime/mcbm2020/mcbm_tof_tracking.C
@@ -0,0 +1,353 @@
+// --------------------------------------------------------------------------
+//
+// Macro for reconstruction "TOF tracks" in mcbm data (2020)
+// Runs on output of event-based combined hit reconstruction for all systems.
+//
+// --------------------------------------------------------------------------
+
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t mcbm_tof_tracking(UInt_t uRunId         = 831,
+                         Bool_t bEventWin      = kFALSE,
+                         Int_t iTrackMode      = 2,
+                         Int_t iCalOpt         = 0,
+                         Int_t nTimeslices     = 0,
+                         TString sInpDir       = "./data",
+                         TString sOutDir       = "./data",
+                         TString cCalId        = "831.50.3.0",
+                         Int_t iUnpFileIndex   = -1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
+
+  // --- Logger settings ----------------------------------------------------
+  TString logLevel     = "INFO";
+  TString logVerbosity = "LOW";
+  // ------------------------------------------------------------------------
+
+
+  // -----   Environment   --------------------------------------------------
+  TString myName   = "mcbm_tof_tracking";            // this macro's name for screen outp
+  TString srcDir   = gSystem->Getenv("VMCWORKDIR");  // top source directory
+  TString paramDir = srcDir + "/macro/beamtime/mcbm2020/";
+  TString parDir   = srcDir + "/parameters";
+  // ------------------------------------------------------------------------
+
+  /// FIXME: Disable clang formatting around parameters initial value setting
+  /// due to problem with real file path length
+  /* clang-format off */
+  // -----   In- and output file names   ------------------------------------
+  /// Standardized RUN ID
+  TString sRunId     = TString::Format("%03u", uRunId);
+  /// Initial pattern
+  TString inFile     = sInpDir + "/reco_mcbm_event_" + sRunId;
+  TString parFileIn  = sInpDir + "/reco_mcbm_event_params_" + sRunId;
+  TString parFileOut = sOutDir + "/tracking_mcbm_event_params_" + sRunId;
+  TString outFile    = sOutDir + "/tracking_mcbm_event_" + sRunId;
+  /// Initial pattern if using event builder with time window
+  if (bEventWin) {
+     inFile     = sInpDir + "/reco_mcbm_evt_win_" + sRunId;
+     parFileIn  = sInpDir + "/reco_mcbm_evt_win_params_" + sRunId;
+     parFileOut = sOutDir + "/tracking_mcbm_evt_win_params_" + sRunId;
+     outFile    = sOutDir + "/tracking_mcbm_evt_win_" + sRunId;
+  }  // if( bEventWin )
+  /// Add index of splitting at unpacking level if needed
+  if ( 0 <= iUnpFileIndex ) {
+    inFile     += TString::Format( "_%02u", iUnpFileIndex );
+    parFileIn  += TString::Format( "_%02u", iUnpFileIndex );
+    parFileOut += TString::Format( "_%02u", iUnpFileIndex );
+    outFile    += TString::Format( "_%02u", iUnpFileIndex );
+  }  // if ( 0 <= iUnpFileIndex )
+  /// Add ROOT file suffix
+  inFile     += ".root";
+  parFileIn  += ".root";
+  parFileOut += ".root";
+  outFile    += ".root";
+  // ------------------------------------------------------------------------
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
+
+  /*
+  std::cout << sInpDir << std::endl << sOutDir << std::endl;
+  std::cout << inFile << std::endl
+            << parFileIn << std::endl
+            << parFileOut << std::endl
+            << outFile << std::endl;
+  std::cout << uRunId << " " << nTimeslices << std::endl;
+
+  return kTRUE;
+  */
+
+  // --- Load the geometry setup ----
+  // This is currently only required by the TRD (parameters)
+  std::string geoSetupTag = "mcbm_beam_2020_03";
+  TString geoFile         = paramDir + geoSetupTag.data() + ".geo.root";  // Created in sim. run
+  CbmSetup* geoSetup      = CbmSetup::Instance();
+  geoSetup->LoadSetup(geoSetupTag.data());
+  TList* parFileList = new TList();
+  // ------------------------------------------------------------------------
+
+  // -----   Timer   --------------------------------------------------------
+  TStopwatch timer;
+  timer.Start();
+  // ------------------------------------------------------------------------
+
+
+  // -----   FairRunAna   ---------------------------------------------------
+  FairRunAna* run             = new FairRunAna();
+  FairFileSource* inputSource = new FairFileSource(inFile);
+  run->SetSource(inputSource);
+
+  FairRootFileSink* outputSink = new FairRootFileSink(outFile);
+  run->SetSink(outputSink);
+  run->SetGeomFile(geoFile);
+
+  // Define output file for FairMonitor histograms
+  TString monitorFile {outFile};
+  monitorFile.ReplaceAll("reco", "reco.monitor");
+  FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile);
+  // ------------------------------------------------------------------------
+
+
+  // -----   Logger settings   ----------------------------------------------
+  FairLogger::GetLogger()->SetLogScreenLevel(logLevel.Data());
+  FairLogger::GetLogger()->SetLogVerbosityLevel(logVerbosity.Data());
+  // ------------------------------------------------------------------------
+
+
+  // -----   Track reconstruction   ------------------------------------------
+  switch (iTrackMode) {
+    case 2: {
+      Int_t iGenCor        = 1;
+      Double_t dScalFac    = 1.;
+      Double_t dChi2Lim2   = 3.5;
+      TString cTrkFile     = parDir + "/tof/" + Form("%s_tofFindTracks.hst.root", cCalId.Data());
+      Int_t iTrackingSetup = 1;
+
+      CbmTofTrackFinder* tofTrackFinder = new CbmTofTrackFinderNN();
+      tofTrackFinder->SetMaxTofTimeDifference(0.2);  // in ns/cm
+      tofTrackFinder->SetTxLIM(0.3);                 // max slope dx/dz
+      tofTrackFinder->SetTyLIM(0.3);                 // max dev from mean slope dy/dz
+      tofTrackFinder->SetTyMean(0.);                 // mean slope dy/dz
+      CbmTofTrackFitter* tofTrackFitter = new CbmTofTrackFitterKF(0, 211);
+      TFitter* MyFit                    = new TFitter(1);  // initialize Minuit
+      tofTrackFinder->SetFitter(tofTrackFitter);
+
+      CbmTofFindTracks* tofFindTracks = new CbmTofFindTracks("TOF Track Finder");
+      tofFindTracks->UseFinder(tofTrackFinder);
+      tofFindTracks->UseFitter(tofTrackFitter);
+      tofFindTracks->SetCalOpt(iCalOpt);
+      // 1 - update offsets, 2 - update walk, 0 - bypass
+      tofFindTracks->SetCorMode(iGenCor);  // valid options: 0,1,2,3,4,5,6, 10 - 19
+      tofFindTracks->SetTtTarg(0.065);     // target value for Mar2020 triple stack -> betapeak ~ 0.95
+      //tofFindTracks->SetTtTarg(0.041);  // target value for inverse velocity, > 0.033 ns/cm!
+      //tofFindTracks->SetTtTarg(0.035);  // target value for inverse velocity, > 0.033 ns/cm!
+      tofFindTracks->SetCalParFileName(cTrkFile);  // Tracker parameter value file name
+      tofFindTracks->SetBeamCounter(5, 0, 0);      // default beam counter
+      tofFindTracks->SetStationMaxHMul(30);        // Max Hit Multiplicity in any used station
+
+      tofFindTracks->SetT0MAX(dScalFac);           // in ns
+      tofFindTracks->SetSIGT(0.08);                // default in ns
+      tofFindTracks->SetSIGX(0.3);                 // default in cm
+      tofFindTracks->SetSIGY(0.45);                // default in cm
+      tofFindTracks->SetSIGZ(0.05);                // default in cm
+      tofFindTracks->SetUseSigCalib(kFALSE);       // ignore resolutions in CalPar file
+      tofTrackFinder->SetSIGLIM(dChi2Lim2 * 2.);   // matching window in multiples of chi2
+      tofTrackFinder->SetChiMaxAccept(dChi2Lim2);  // max tracklet chi2
+
+      Int_t iMinNofHits   = -1;
+      Int_t iNStations    = 0;
+      Int_t iNReqStations = 3;
+      switch (iTrackingSetup) {
+        case 0:  // bypass mode
+          iMinNofHits = -1;
+          iNStations  = 1;
+          tofFindTracks->SetStation(0, 5, 0, 0);  // Diamond
+          break;
+
+        case 1:  // for calibration mode of full setup
+          iMinNofHits   = 3;
+          iNStations    = 28;
+          iNReqStations = 4;
+          tofFindTracks->SetStation(0, 5, 0, 0);
+          tofFindTracks->SetStation(1, 0, 2, 2);
+          tofFindTracks->SetStation(2, 0, 1, 2);
+          tofFindTracks->SetStation(3, 0, 0, 2);
+          tofFindTracks->SetStation(4, 0, 2, 1);
+          tofFindTracks->SetStation(5, 0, 1, 1);
+          tofFindTracks->SetStation(6, 0, 0, 1);
+          tofFindTracks->SetStation(7, 0, 2, 3);
+          tofFindTracks->SetStation(8, 0, 1, 3);
+          tofFindTracks->SetStation(9, 0, 0, 3);
+          tofFindTracks->SetStation(10, 0, 2, 0);
+          tofFindTracks->SetStation(11, 0, 1, 0);
+          tofFindTracks->SetStation(12, 0, 0, 0);
+          tofFindTracks->SetStation(13, 0, 2, 4);
+          tofFindTracks->SetStation(14, 0, 1, 4);
+          tofFindTracks->SetStation(15, 0, 0, 4);
+          tofFindTracks->SetStation(16, 0, 4, 0);
+          tofFindTracks->SetStation(17, 0, 3, 0);
+          tofFindTracks->SetStation(18, 0, 4, 1);
+          tofFindTracks->SetStation(19, 0, 3, 1);
+          tofFindTracks->SetStation(20, 0, 4, 2);
+          tofFindTracks->SetStation(21, 0, 3, 2);
+          tofFindTracks->SetStation(22, 0, 4, 3);
+          tofFindTracks->SetStation(23, 0, 3, 3);
+          tofFindTracks->SetStation(24, 0, 4, 4);
+          tofFindTracks->SetStation(25, 0, 3, 4);
+          tofFindTracks->SetStation(26, 9, 0, 0);
+          tofFindTracks->SetStation(27, 9, 0, 1);
+          break;
+
+        case 2:  // for geometry check mode of full setup
+          iMinNofHits   = 3;
+          iNStations    = 27;
+          iNReqStations = 4;
+          tofFindTracks->SetStation(0, 0, 2, 2);
+          tofFindTracks->SetStation(1, 0, 1, 2);
+          tofFindTracks->SetStation(2, 0, 0, 2);
+          tofFindTracks->SetStation(3, 0, 2, 1);
+          tofFindTracks->SetStation(4, 0, 1, 1);
+          tofFindTracks->SetStation(5, 0, 0, 1);
+          tofFindTracks->SetStation(6, 0, 2, 3);
+          tofFindTracks->SetStation(7, 0, 1, 3);
+          tofFindTracks->SetStation(8, 0, 0, 3);
+          tofFindTracks->SetStation(9, 0, 2, 0);
+          tofFindTracks->SetStation(10, 0, 1, 0);
+          tofFindTracks->SetStation(11, 0, 0, 0);
+          tofFindTracks->SetStation(12, 0, 2, 4);
+          tofFindTracks->SetStation(13, 0, 1, 4);
+          tofFindTracks->SetStation(14, 0, 0, 4);
+          tofFindTracks->SetStation(15, 0, 4, 0);
+          tofFindTracks->SetStation(16, 0, 3, 0);
+          tofFindTracks->SetStation(17, 0, 4, 1);
+          tofFindTracks->SetStation(18, 0, 3, 1);
+          tofFindTracks->SetStation(19, 0, 4, 2);
+          tofFindTracks->SetStation(20, 0, 3, 2);
+          tofFindTracks->SetStation(21, 0, 4, 3);
+          tofFindTracks->SetStation(22, 0, 3, 3);
+          tofFindTracks->SetStation(23, 0, 4, 4);
+          tofFindTracks->SetStation(24, 0, 3, 4);
+          tofFindTracks->SetStation(25, 9, 0, 0);
+          tofFindTracks->SetStation(26, 9, 0, 1);
+          break;
+
+        case 3:  // for reduced bias tracking of full setup
+          iMinNofHits   = 3;
+          iNStations    = 28;
+          iNReqStations = 4;
+          tofFindTracks->SetStation(0, 0, 2, 2);
+          tofFindTracks->SetStation(1, 0, 1, 2);
+          tofFindTracks->SetStation(2, 0, 0, 2);
+          tofFindTracks->SetStation(3, 0, 2, 1);
+          tofFindTracks->SetStation(4, 0, 1, 1);
+          tofFindTracks->SetStation(5, 0, 0, 1);
+          tofFindTracks->SetStation(6, 0, 2, 3);
+          tofFindTracks->SetStation(7, 0, 1, 3);
+          tofFindTracks->SetStation(8, 0, 0, 3);
+          tofFindTracks->SetStation(9, 0, 2, 0);
+          tofFindTracks->SetStation(10, 0, 1, 0);
+          tofFindTracks->SetStation(11, 0, 0, 0);
+          tofFindTracks->SetStation(12, 0, 2, 4);
+          tofFindTracks->SetStation(13, 0, 1, 4);
+          tofFindTracks->SetStation(14, 0, 0, 4);
+          tofFindTracks->SetStation(15, 0, 4, 0);
+          tofFindTracks->SetStation(16, 0, 3, 0);
+          tofFindTracks->SetStation(17, 0, 4, 1);
+          tofFindTracks->SetStation(18, 0, 3, 1);
+          tofFindTracks->SetStation(19, 0, 4, 2);
+          tofFindTracks->SetStation(20, 0, 3, 2);
+          tofFindTracks->SetStation(21, 0, 4, 3);
+          tofFindTracks->SetStation(22, 0, 3, 3);
+          tofFindTracks->SetStation(23, 0, 4, 4);
+          tofFindTracks->SetStation(24, 0, 3, 4);
+          tofFindTracks->SetStation(25, 9, 0, 0);
+          tofFindTracks->SetStation(26, 9, 0, 1);
+          tofFindTracks->SetStation(27, 5, 0, 0);
+          break;
+      }
+      tofFindTracks->SetMinNofHits(iMinNofHits);
+      tofFindTracks->SetNStations(iNStations);
+      tofFindTracks->SetNReqStations(iNReqStations);
+      //tofFindTracks->PrintSetup();
+      run->AddTask(tofFindTracks);
+    } break;
+    case 1: {
+    }
+    case 0:
+    default:;
+  }
+
+
+  // -----  Parameter database   --------------------------------------------
+  std::cout << std::endl << std::endl;
+  std::cout << "-I- " << myName << ": Set runtime DB" << std::endl;
+  FairRuntimeDb* rtdb        = run->GetRuntimeDb();
+  FairParRootFileIo* parIo1  = new FairParRootFileIo();
+  FairParAsciiFileIo* parIo2 = new FairParAsciiFileIo();
+  FairParRootFileIo* parIo3  = new FairParRootFileIo();
+  parIo1->open(parFileIn.Data(), "READ");
+  rtdb->setFirstInput(parIo1);
+  parIo2->open(parFileList, "in");
+  rtdb->setSecondInput(parIo2);
+  parIo3->open(parFileOut.Data(), "RECREATE");
+  // ------------------------------------------------------------------------
+
+
+  // -----   Run initialisation   -------------------------------------------
+  std::cout << std::endl;
+  std::cout << "-I- " << myName << ": Initialise run" << std::endl;
+  run->Init();
+  rtdb->setOutput(parIo3);
+  rtdb->saveOutput();
+  rtdb->print();
+  // ------------------------------------------------------------------------
+
+
+  // -----   Start run   ----------------------------------------------------
+  std::cout << std::endl << std::endl;
+  std::cout << "-I- " << myName << ": Starting run" << std::endl;
+  run->Run(0, nTimeslices);
+  // ------------------------------------------------------------------------
+
+
+  // -----   Finish   -------------------------------------------------------
+  timer.Stop();
+  FairMonitor::GetMonitor()->Print();
+  Double_t rtime = timer.RealTime();
+  Double_t ctime = timer.CpuTime();
+  std::cout << std::endl << std::endl;
+  std::cout << "Macro finished successfully." << std::endl;
+  std::cout << "Output file is " << outFile << std::endl;
+  std::cout << "Parameter file is " << parFileOut << std::endl;
+  std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s" << std::endl;
+  std::cout << std::endl;
+  // ------------------------------------------------------------------------
+
+
+  // -----   Resource monitoring   ------------------------------------------
+  // Extract the maximal used memory an add is as Dart measurement
+  // This line is filtered by CTest and the value send to CDash
+  FairSystemInfo sysInfo;
+  Float_t maxMemory = sysInfo.GetMaxMemory();
+  std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
+  std::cout << maxMemory;
+  std::cout << "</DartMeasurement>" << std::endl;
+
+  Float_t cpuUsage = ctime / rtime;
+  std::cout << "<DartMeasurement name=\"CpuLoad\" type=\"numeric/double\">";
+  std::cout << cpuUsage;
+  std::cout << "</DartMeasurement>" << std::endl;
+  // ------------------------------------------------------------------------
+
+
+  // -----   Function needed for CTest runtime dependency   -----------------
+  //  RemoveGeoManager();
+  // ------------------------------------------------------------------------
+
+  /// --- Screen output for automatic tests
+  std::cout << " Test passed" << std::endl;
+  std::cout << " All ok " << std::endl;
+
+  return kTRUE;
+}
diff --git a/macro/beamtime/mcbm2020/mcbm_tof_tracking_kronos.C b/macro/beamtime/mcbm2020/mcbm_tof_tracking_kronos.C
new file mode 100644
index 0000000000000000000000000000000000000000..846216de0d1487aa8a6d5cfbe6208dde1ddbc12d
--- /dev/null
+++ b/macro/beamtime/mcbm2020/mcbm_tof_tracking_kronos.C
@@ -0,0 +1,59 @@
+// --------------------------------------------------------------------------
+//
+// Macro for reconstruction "TOF tracks" in mcbm data (2020)
+// Runs on output of event-based combined hit reconstruction for all systems.
+// Wrapper setting the paths for analysis using the HPC farm's common files.
+//
+// --------------------------------------------------------------------------
+
+#include "mcbm_tof_tracking.C"
+
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t mcbm_tof_tracking_kronos(UInt_t uRunIdx = 28,
+                                Bool_t bEventWin  = kFALSE,
+                                Int_t iTrackMode  = 2,
+                                Int_t iCalOpt     = 0,
+                                Int_t nTimeslices = 0,
+                                TString sInpDir = "/lustre/cbm/users/ploizeau/mcbm2020/"
+                                                  "unp_evt_data_7f229b3f_20201103",
+                                TString sOutDir = "./data",
+                                TString cCalId        = "831.50.3.0",
+                                Int_t iUnpFileIndex  = -1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
+
+  UInt_t uRunId = 0;
+
+  if (99999 != uRunIdx) {
+    std::vector<UInt_t> vuListRunId = {
+      692, 698, 702, 704, 705, 706, 707,            //  7 =>  0 -  6
+      744, 750, 759, 760, 761, 762, 799,            //  7 =>  7 - 13
+      811, 812, 816, 817, 819,                      //  5 => 14 - 18
+      820, 821, 822, 824, 826, 827, 828, 829,       //  8 => 19 - 26
+      830, 831, 836,                                //  3 => 27 - 29
+      841, 846, 849,                                //  3 => 30 - 32
+      850, 851, 852, 854, 855, 856, 857, 858, 859,  //  9 => 33 - 41
+      860, 861, 862, 863, 864, 865, 866             //  7 => 42 - 48
+
+      /*
+      /// With runs < 1 min due to missmatch!
+      811, 812, 816, 817, 818, 819,                  //  6 => 14 - 19
+      820, 821, 822, 824, 826, 827, 828, 829,        //  8 => 20 - 27
+      830, 831, 836, 839,                            //  4 => 28 - 31
+      840, 841, 842, 844, 845, 846, 848, 849,        //  8 => 32 - 39
+      850, 851, 852, 854, 855, 856, 857, 858, 859,   //  9 => 40 - 48
+      860, 861, 862, 863, 864, 865, 866              //  7 => 49 - 55
+      */
+    };
+    if (vuListRunId.size() <= uRunIdx) return kFALSE;
+
+    uRunId = vuListRunId[uRunIdx];
+  }  // if( 99999 != uRunIdx )
+
+  if (uRunId < 692 && 0 != uRunId) return kFALSE;
+
+  return mcbm_tof_tracking(uRunId, bEventWin, iTrackMode, iCalOpt, nTimeslices, sInpDir, sOutDir, cCalId,
+                           iUnpFileIndex);
+}
diff --git a/macro/beamtime/mcbm2020/unpack_tsa_mcbm.C b/macro/beamtime/mcbm2020/unpack_tsa_mcbm.C
index 89caf6459762a0788387f0638b7ae6cd68fa2260..aadd7491abf2a89f7bc38401e94779aff29ef46a 100644
--- a/macro/beamtime/mcbm2020/unpack_tsa_mcbm.C
+++ b/macro/beamtime/mcbm2020/unpack_tsa_mcbm.C
@@ -10,20 +10,40 @@
 // In order to call later Finish, we make this global
 FairRunOnline* run = NULL;
 
-void unpack_tsa_mcbm(TString inFile  = "",
-                     UInt_t uRunId   = 0,
-                     UInt_t nrEvents = 0,
-                     TString outDir  = "data",
-                     TString inDir   = "") {
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t unpack_tsa_mcbm(TString inFile       = "",
+                       UInt_t uRunId        = 0,
+                       UInt_t uNbTimeslices = 0,
+                       TString sOutDir      = "data",
+                       Int_t iSpillIndex    = -1,
+                       Int_t iSpillnumber   = 3,
+                       UInt_t uSpillLimType = 1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
+
   TString srcDir = gSystem->Getenv("VMCWORKDIR");
 
-  // --- Specify number of events to be produced.
-  // --- -1 means run until the end of the input file.
-  Int_t nEvents = -1;
   // --- Specify output file name (this is just an example)
   TString runId   = TString::Format("%03u", uRunId);
-  TString outFile = outDir + "/unp_mcbm_" + runId + ".root";
-  TString parFile = outDir + "/unp_mcbm_params_" + runId + ".root";
+  TString outFile = sOutDir + "/unp_mcbm_" + runId;
+  TString parFile = sOutDir + "/unp_mcbm_params_" + runId;
+  if (0 <= iSpillIndex) {
+    outFile += TString::Format("_%02i", iSpillIndex);
+    parFile += TString::Format("_%02i", iSpillIndex);
+  }  // if( 0 <= iSpillIndex )
+  outFile += ".root";
+  parFile += ".root";
+
+  /*
+  std::cout << inFile << std::endl << sOutDir << std::endl;
+  std::cout << parFile << std::endl
+            << outFile << std::endl;
+  std::cout << uRunId << " " << uNbTimeslices << std::endl;
+
+  return kTRUE;
+  */
 
   // --- Set log output levels
   FairLogger::GetLogger();
@@ -573,6 +593,7 @@ void unpack_tsa_mcbm(TString inFile  = "",
   }  // switch( uRunId )
   /// FIXME: Re-enable clang formatting after parameters tuning
   /* clang-format on */
+
   // --- Source task
   CbmMcbm2018Source* source = new CbmMcbm2018Source();
   source->SetWriteOutputFlag(kTRUE);  // For writing TS metadata
@@ -588,14 +609,43 @@ void unpack_tsa_mcbm(TString inFile  = "",
   source->AddUnpacker(unpacker_rich, 0x30, ECbmModuleId::kRich);   // RICH trb
   source->AddUnpacker(unpacker_psd, 0x80, ECbmModuleId::kPsd);     // PSD
 
+  /// Select a pre-identified spills block through block index + block length (in spills)
+  /// Also select where we split the spills: beginning, middle or end of the spill break
+  source->UnpackSelectSpills(iSpillIndex * iSpillnumber, iSpillIndex * iSpillnumber + iSpillnumber - 1, uSpillLimType);
+  /// Disable clang formatting around vectors initialization by lists
+  /* clang-format off */
+  switch (uRunId) {
+    case 831: {
+      source->LoadTsListSpillBreakBegin(std::vector<ULong64_t>(
+        {    1,   933,  1941,  2949,  4349,  5357,  6365,  7373,  8773,  9781,
+         10789, 11801, 13197, 14209, 15217, 16225, 17625, 18633, 19645, 20653,
+         22053, 23061, 24069, 25077, 26473, 27481, 28493, 29501, 30897, 31905,
+         32913, 33921, 35321, 36329, 37337, 38345, 39745, 40753, 41761, 42769,
+         44169, 45177, 46185, 47193, 48593}));
+      source->LoadTsListSpillBreakMiddle(std::vector<ULong64_t>(
+        {  111,  1081,  2087,  3299,  4495,  5503,  6513,  7721,  8921,  9927,
+         10935, 12149, 13347, 14355, 15363, 16573, 17773, 18781, 19791, 21001,
+         22199, 23209, 24215, 25423, 26619, 27629, 28637, 29847, 31045, 32051,
+         33059, 34275, 35469, 36475, 37483, 38693, 39889, 40899, 41907, 43117,
+         44315, 45323, 46333, 47543, 48689}));
+      source->LoadTsListSpillBreakEnd(std::vector<ULong64_t>(
+        {  221, 1229,  2233,  3649,  4641,  5649,  6661,  8069,  9069,  10073,
+         11081, 12497, 13497, 14501, 15509, 16921, 17921, 18929, 19937, 21349,
+         22345, 23357, 24361, 25769, 26765, 27777, 28781, 30193, 31193, 32197,
+         33205, 34629, 35617, 36621, 37629, 39041, 40033, 41045, 42053, 43465,
+         44461, 45469, 46481, 47893, 48786}));
+      break;
+    }  // case 831
+  }    // switch (uRunId)
+  /// Re-enable clang formatting after vectors initialization by lists
+  /* clang-format on */
+
   // --- Event header
   FairEventHeader* event = new FairEventHeader();
   event->SetRunId(uRunId);
 
   // --- RootFileSink
-  // --- Open next outputfile after 4GB
   FairRootFileSink* sink = new FairRootFileSink(outFile);
-  //  sink->GetOutTree()->SetMaxTreeSize(4294967295LL);
 
   // --- Run
   run = new FairRunOnline(source);
@@ -620,10 +670,11 @@ void unpack_tsa_mcbm(TString inFile  = "",
   TStopwatch timer;
   timer.Start();
   std::cout << ">>> unpack_tsa_mcbm: Starting run..." << std::endl;
-  if (0 == nrEvents) {
-    run->Run(nEvents, 0);  // run until end of input file
-  } else {
-    run->Run(0, nrEvents);  // process  N Events
+  if (0 == uNbTimeslices) {
+    run->Run(-1, 0);  // run until end of input file
+  }
+  else {
+    run->Run(0, uNbTimeslices);  // process  N Timeslices
   }
   run->Finish();
 
@@ -645,4 +696,6 @@ void unpack_tsa_mcbm(TString inFile  = "",
   /// --- Screen output for automatic tests
   std::cout << " Test passed" << std::endl;
   std::cout << " All ok " << std::endl;
+
+  return kTRUE;
 }
diff --git a/macro/beamtime/mcbm2020/unpack_tsa_mcbm_kronos.C b/macro/beamtime/mcbm2020/unpack_tsa_mcbm_kronos.C
index 964fbfd048c2bc2b044a704152fa2df2a47d840c..0b5cc0988007b3f9ae6f2aa8ca5e7bd19f93722a 100644
--- a/macro/beamtime/mcbm2020/unpack_tsa_mcbm_kronos.C
+++ b/macro/beamtime/mcbm2020/unpack_tsa_mcbm_kronos.C
@@ -7,12 +7,20 @@
  ** Convert data into cbmroot format.
  ** Uses CbmMcbm2018Source as source task.
  */
-// In order to call later Finish, we make this global
-FairRunOnline* run = NULL;
+#include "unpack_tsa_mcbm.C"
+
+/// FIXME: Disable clang formatting to keep easy parameters overview
+/* clang-format off */
+Bool_t unpack_tsa_mcbm_kronos(UInt_t uRunIdx       = 28,
+                              UInt_t uNbTimeslices = 0,
+                              TString sOutDir      = "data",
+                              Int_t iSpillIndex    = -1,
+                              Int_t iSpillnumber   = 3,
+                              UInt_t uSpillLimType = 1)
+{
+  /// FIXME: Re-enable clang formatting after parameters initial values setting
+  /* clang-format on */
 
-void unpack_tsa_mcbm_kronos(UInt_t uRunIdx  = 99999,
-                            UInt_t nrEvents = 0,
-                            TString outDir  = "data") {
   UInt_t uRunId = 0;
   if (99999 != uRunIdx) {
     std::vector<UInt_t> vuListRunId = {
@@ -41,569 +49,7 @@ void unpack_tsa_mcbm_kronos(UInt_t uRunIdx  = 99999,
     uRunId = vuListRunId[uRunIdx];
   }  // if( 99999 != uRunIdx )
 
-  if (uRunId < 692 && 0 != uRunId) return kFALSE;
-
-  TString srcDir = gSystem->Getenv("VMCWORKDIR");
-
-  // --- Specify number of events to be produced.
-  // --- -1 means run until the end of the input file.
-  Int_t nEvents = -1;
-  // --- Specify output file name (this is just an example)
-  TString runId   = TString::Format("%03u", uRunId);
-  TString outFile = outDir + "/unp_mcbm_" + runId + ".root";
-  TString parFile = outDir + "/unp_mcbm_params_" + runId + ".root";
-
-  // --- Set log output levels
-  FairLogger::GetLogger();
-  gLogger->SetLogScreenLevel("INFO");
-  //gLogger->SetLogScreenLevel("DEBUG4");
-  gLogger->SetLogVerbosityLevel("MEDIUM");
-  //gLogger->SetLogVerbosityLevel("LOW");
-
-  // --- Define parameter files
-  TList* parFileList = new TList();
-  TString paramDir   = srcDir + "/macro/beamtime/mcbm2020/";
-
-  // --- Load the geometry setup ----
-  // This is currently only required by the TRD
-  std::string geoSetupTag = "mcbm_beam_2020_03";
-  CbmSetup* geoSetup      = CbmSetup::Instance();
-  geoSetup->LoadSetup(geoSetupTag.data());
-
-  TString paramFileSts       = paramDir + "mStsPar.par";
-  TObjString* parStsFileName = new TObjString(paramFileSts);
-  parFileList->Add(parStsFileName);
-
-  TString paramFileMuch       = paramDir + "mMuchPar.par";
-  TObjString* parMuchFileName = new TObjString(paramFileMuch);
-  parFileList->Add(parMuchFileName);
-
-  // ---- Trd ----
-  TString geoTagTrd = "";
-  bool isActiveTrd =
-    (geoSetup->GetGeoTag(ECbmModuleId::kTrd, geoTagTrd)) ? true : false;
-  if (!isActiveTrd) {
-    LOG(warning) << Form(
-      "TRD - parameter loading - Trd not found in CbmSetup(%s) -> parameters "
-      "can not be loaded correctly!",
-      geoSetupTag.data());
-  } else {
-    TString paramFilesTrd(
-      Form("%s/parameters/trd/trd_%s", srcDir.Data(), geoTagTrd.Data()));
-    std::vector<std::string> paramFilesVecTrd;
-    CbmTrdParManager::GetParFileExtensions(&paramFilesVecTrd);
-    for (auto parIt : paramFilesVecTrd) {
-      parFileList->Add(
-        new TObjString(Form("%s.%s.par", paramFilesTrd.Data(), parIt.data())));
-    }
-    // Add timeshift calibration, currently only available for run 831 others to come
-    if (uRunId == 831)
-      parFileList->Add(new TObjString(Form(
-        "%s/parameters/trd/mcbm2020_special/CbmMcbm2020TrdTshiftPar_run%d.par",
-        srcDir.Data(),
-        uRunId)));
-  }
-
-  TString paramFileTof = paramDir + "mTofPar.par";
-  if (uRunId >= 708 && uRunId < 754)
-    paramFileTof = paramDir + "mTofPar_2Stack.par";
-  else if (uRunId >= 754)
-    paramFileTof = paramDir + "mTofPar_3Stack.par";
-
-  TObjString* parTofFileName = new TObjString(paramFileTof);
-  parFileList->Add(parTofFileName);
-
-  TString paramFileRich = paramDir + "mRichPar.par";
-  if (uRunId > 698) paramFileRich = paramDir + "mRichPar_70.par";
-  TObjString* parRichFileName = new TObjString(paramFileRich);
-  parFileList->Add(parRichFileName);
-
-  TString paramFilePsd       = paramDir + "mPsdPar.par";
-  TObjString* parPsdFileName = new TObjString(paramFilePsd);
-  parFileList->Add(parPsdFileName);
-
-  // --- Set debug level
-  gDebug = 0;
-
-  std::cout << std::endl;
-  std::cout << ">>> unpack_tsa: output file is " << outFile << std::endl;
-
-  // ========================================================================
-  // ========================================================================
-  std::cout << std::endl;
-  std::cout << ">>> unpack_tsa: Initialising..." << std::endl;
-
-  CbmMcbm2018UnpackerTaskSts* unpacker_sts = new CbmMcbm2018UnpackerTaskSts();
-  CbmMcbm2018UnpackerTaskMuch* unpacker_much =
-    new CbmMcbm2018UnpackerTaskMuch();
-  CbmMcbm2018UnpackerTaskTrdR* unpacker_trdR =
-    new CbmMcbm2018UnpackerTaskTrdR();
-  CbmMcbm2018UnpackerTaskTof* unpacker_tof = new CbmMcbm2018UnpackerTaskTof();
-  CbmMcbm2018UnpackerTaskRich* unpacker_rich =
-    new CbmMcbm2018UnpackerTaskRich();
-  CbmMcbm2018UnpackerTaskPsd* unpacker_psd = new CbmMcbm2018UnpackerTaskPsd();
-
-  /*
- * Do not generate plots by default
-  unpacker_sts ->SetMonitorMode();
-  unpacker_much->SetMonitorMode();
-  unpacker_trdR->SetMonitorMode(); // Assume histo server present, not like other unpackers
-  unpacker_tof ->SetMonitorMode();
-  unpacker_rich->SetMonitorMode();
-  unpacker_psd->SetMonitorMode();
-*/
-
-  unpacker_sts->SetIgnoreOverlapMs();
-  unpacker_much->SetIgnoreOverlapMs();
-  //  unpacker_trdR ->SetIgnoreOverlapMs(); /// Default is kTRUE
-  unpacker_tof->SetIgnoreOverlapMs();
-  unpacker_rich->SetIgnoreOverlapMs();
-  unpacker_psd->SetIgnoreOverlapMs();
-
-  /// Starting from first run on Tuesday 28/04/2020, STS uses bin sorter FW
-  if (692 <= uRunId) unpacker_sts->SetBinningFwFlag(kTRUE);
-  /// Starting from first run on Monday 04/05/2020, MUCH uses bin sorter FW
-  if (811 <= uRunId) unpacker_much->SetBinningFwFlag(kTRUE);
-
-  /// FIXME: Disable clang formatting for parameters tuning for now
-  /* clang-format off */
-  //  unpacker_sts ->SetAdcCut( 3 );
-  unpacker_sts ->MaskNoisyChannel(1,768 ,  true );
-  unpacker_sts ->MaskNoisyChannel(1,894 ,  true );
-  unpacker_sts ->MaskNoisyChannel(1,896 ,  true );
-
-  unpacker_sts ->MaskNoisyChannel(2,930 ,  true );
-  unpacker_sts ->MaskNoisyChannel(2,926 ,  true );
-  unpacker_sts ->MaskNoisyChannel(2,892 ,  true );
-
-  unpacker_sts ->MaskNoisyChannel(3,770 ,  true );
-
-  unpacker_tof->SetSeparateArrayT0();
-
-  // ------------------------------ //
-  // Enable Asic type for MUCH data.
-  // fFlag = 0 ==> Asic type 2.0 (20) ---> December 2018 and March 2019 Data
-  // fFlag = 1 ==> Asic type 2.1 (21) ---> December 2019 Data
-  // This is to correct the channel fliping problem in smx 2.1 chip
-  Int_t fFlag = 1;
-  unpacker_much->EnableAsicType(fFlag);
-  // ------------------------------ //
-
-  /// General System offsets (= offsets between sub-systems)
-  unpacker_sts->SetTimeOffsetNs(-936);   // Run 811-866
-  unpacker_much->SetTimeOffsetNs(-885);  // Run 811-866
-  unpacker_trdR->SetTimeOffsetNs(0);     // Run 811-866
-  unpacker_tof->SetTimeOffsetNs(30);     // Run 811-866
-  unpacker_rich->SetTimeOffsetNs(-310);  // Run 811-866
-  unpacker_psd->SetTimeOffsetNs(-225);   // Run 811-866
-// ----------- ASIC by ASIC STS ----------------
-  // the first 8 Unused
-  unpacker_sts ->SetTimeOffsetNsAsic(  0,       0.0  ); // Unused
-  unpacker_sts ->SetTimeOffsetNsAsic(  1,       0.0  ); // Unused
-  unpacker_sts ->SetTimeOffsetNsAsic(  2,       0.0  ); // Unused
-  unpacker_sts ->SetTimeOffsetNsAsic(  3,       0.0  ); // Unused
-  unpacker_sts ->SetTimeOffsetNsAsic(  4,       0.0  ); // Unused
-  unpacker_sts ->SetTimeOffsetNsAsic(  5,       0.0  ); // Unused
-  unpacker_sts ->SetTimeOffsetNsAsic(  6,       0.0  ); // Unused
-  unpacker_sts ->SetTimeOffsetNsAsic(  7,       0.0  ); // Unused
-  //
-  unpacker_sts ->SetTimeOffsetNsAsic(8,  -0.360078  );
-  unpacker_sts ->SetTimeOffsetNsAsic(9,  2.73976    );
-  unpacker_sts ->SetTimeOffsetNsAsic(10,  -0.507079  );
-  unpacker_sts ->SetTimeOffsetNsAsic(11,  1.74695    );
-  unpacker_sts ->SetTimeOffsetNsAsic(12,  -0.909864  );
-  unpacker_sts ->SetTimeOffsetNsAsic(13,  -0.255514  );
-  unpacker_sts ->SetTimeOffsetNsAsic(14,  1.44034    );
-  unpacker_sts ->SetTimeOffsetNsAsic(15,  2.64009    );
-  // this side: revert order 23->16
-  unpacker_sts ->SetTimeOffsetNsAsic(23,  -0.442762  );
-  unpacker_sts ->SetTimeOffsetNsAsic(22,  1.76543    );
-  unpacker_sts ->SetTimeOffsetNsAsic(21, -0.94728   );
-  unpacker_sts ->SetTimeOffsetNsAsic(20, -2.18516   );
-  unpacker_sts ->SetTimeOffsetNsAsic(19, -0.68254   );
-  unpacker_sts ->SetTimeOffsetNsAsic(18, -2.32241   );
-  unpacker_sts ->SetTimeOffsetNsAsic(17, -1.53483   );
-  unpacker_sts ->SetTimeOffsetNsAsic(16, -2.12455   );
-  //
-  unpacker_sts ->SetTimeOffsetNsAsic(24, -0.41084   );
-  unpacker_sts ->SetTimeOffsetNsAsic(25, 0.230455   );
-  unpacker_sts ->SetTimeOffsetNsAsic(26, -0.206921  );
-  unpacker_sts ->SetTimeOffsetNsAsic(27, 0.0913657  );
-  unpacker_sts ->SetTimeOffsetNsAsic(28, -0.17252   );
-  unpacker_sts ->SetTimeOffsetNsAsic(29, -0.32990   );
-  unpacker_sts ->SetTimeOffsetNsAsic(30, 1.43535    );
-  unpacker_sts ->SetTimeOffsetNsAsic(31, -0.155741  );
-  // this side: revert order 39->32
-  unpacker_sts ->SetTimeOffsetNsAsic(39, 1.53865    );
-  unpacker_sts ->SetTimeOffsetNsAsic(38, 3.6318     );
-  unpacker_sts ->SetTimeOffsetNsAsic(37, 1.3153     );
-  unpacker_sts ->SetTimeOffsetNsAsic(36, -1.90278   );
-  unpacker_sts ->SetTimeOffsetNsAsic(35, 2.00051    );
-  unpacker_sts ->SetTimeOffsetNsAsic(34, -2.85656   );
-  unpacker_sts ->SetTimeOffsetNsAsic(33, 1.28834    );
-  unpacker_sts ->SetTimeOffsetNsAsic(32, 0.657113   );
-
-  switch (uRunId) {
-    case 707: {
-      /// General System offsets (= offsets between sub-systems)
-      //unpacker_sts ->SetTimeOffsetNs( -1750 ); // Run 707
-      //unpacker_much->SetTimeOffsetNs( -1750 ); // Run 707
-
-      /// ASIC specific offsets (= offsets inside sub-system)
-      unpacker_much->SetTimeOffsetNsAsic(0, 0.0);      // Run 707, DPB 0 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(1, 0.0);      // Run 707, DPB 0 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(2, 0.0);      // Run 707, DPB 0 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(3, 0.0);      // Run 707, DPB 0 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(4, 0.0);      // Run 707, DPB 0 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(5, 0.0);      // Run 707, DPB 0 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(6, 0.0);      // Run 707, DPB 1 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(7, 0.0);      // Run 707, DPB 1 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(8, 0.0);      // Run 707, DPB 1 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(9, 0.0);      // Run 707, DPB 1 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(10, 0.0);     // Run 707, DPB 1 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(11, 0.0);     // Run 707, DPB 1 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(12, 0.0);     // Run 707, DPB 2 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(13, 0.0);     // Run 707, DPB 2 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(14, 0.0);     // Run 707, DPB 2 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(15, 0.0);     // Run 707, DPB 2 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(16, 0.0);     // Run 707, DPB 2 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(17, 0.0);     // Run 707, DPB 2 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(18, 9590.0);  // Run 707, DPB 3 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(19, 9590.0);  // Run 707, DPB 3 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(20, 9630.0);  // Run 707, DPB 3 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(21, 9590.0);  // Run 707, DPB 3 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(22, 0.0);     // Run 707, DPB 3 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(23, 0.0);     // Run 707, DPB 3 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(24, 0.0);     // Run 707, DPB 4 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(25, 0.0);     // Run 707, DPB 4 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(26, 0.0);     // Run 707, DPB 4 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(27, 0.0);     // Run 707, DPB 4 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(28, 0.0);     // Run 707, DPB 4 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(29, 0.0);     // Run 707, DPB 4 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(30, 0.0);     // Run 707, DPB 5 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(31, 0.0);     // Run 707, DPB 5 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(32, 7170.0);  // Run 707, DPB 5 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(33, 7170.0);  // Run 707, DPB 5 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(34, 0.0);     // Run 707, DPB 5 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(35, 0.0);     // Run 707, DPB 5 ASIC 5
-      break;
-    }  // 707
-    case 750: {
-      /// General System offsets (= offsets between sub-systems)
-      //unpacker_sts ->SetTimeOffsetNs( -1750 ); // Run 750
-      //unpacker_much->SetTimeOffsetNs( -1750 ); // Run 750
-
-      /// ASIC specific offsets (= offsets inside sub-system)
-      unpacker_much->SetTimeOffsetNsAsic(0, 0.0);      // Run 750, DPB 0 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(1, 0.0);      // Run 750, DPB 0 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(2, 0.0);      // Run 750, DPB 0 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(3, 0.0);      // Run 750, DPB 0 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(4, 0.0);      // Run 750, DPB 0 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(5, 0.0);      // Run 750, DPB 0 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(6, 0.0);      // Run 750, DPB 1 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(7, 0.0);      // Run 750, DPB 1 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(8, 0.0);      // Run 750, DPB 1 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(9, 0.0);      // Run 750, DPB 1 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(10, 0.0);     // Run 750, DPB 1 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(11, 0.0);     // Run 750, DPB 1 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(12, 0.0);     // Run 750, DPB 2 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(13, 0.0);     // Run 750, DPB 2 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(14, 0.0);     // Run 750, DPB 2 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(15, 0.0);     // Run 750, DPB 2 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(16, 0.0);     // Run 750, DPB 2 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(17, 0.0);     // Run 750, DPB 2 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(18, 6400.0);  // Run 750, DPB 3 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(19, 6400.0);  // Run 750, DPB 3 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(20, 6400.0);  // Run 750, DPB 3 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(21, 6400.0);  // Run 750, DPB 3 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(22, 0.0);     // Run 750, DPB 3 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(23, 0.0);     // Run 750, DPB 3 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(24, 0.0);     // Run 750, DPB 4 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(25, 0.0);     // Run 750, DPB 4 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(26, 0.0);     // Run 750, DPB 4 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(27, 0.0);     // Run 750, DPB 4 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(28, 0.0);     // Run 750, DPB 4 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(29, 0.0);     // Run 750, DPB 4 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(30, 0.0);     // Run 750, DPB 5 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(31, 0.0);     // Run 750, DPB 5 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(32, 3170.0);  // Run 750, DPB 5 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(33, 3170.0);  // Run 750, DPB 5 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(34, 0.0);     // Run 750, DPB 5 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(35, 0.0);     // Run 750, DPB 5 ASIC 5
-      break;
-    }  // 750
-    case 759: {
-      /// General System offsets (= offsets between sub-systems)
-      //unpacker_sts ->SetTimeOffsetNs( -1759 ); // Run 759
-      //unpacker_much->SetTimeOffsetNs( -1759 ); // Run 759
-      unpacker_trdR->SetTimeOffsetNs(190);  // Run 759
-
-      /// ASIC specific offsets (= offsets inside sub-system)
-      unpacker_much->SetTimeOffsetNsAsic(0, 0.0);      // Run 759, DPB 0 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(1, 0.0);      // Run 759, DPB 0 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(2, 0.0);      // Run 759, DPB 0 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(3, 0.0);      // Run 759, DPB 0 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(4, 0.0);      // Run 759, DPB 0 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(5, 0.0);      // Run 759, DPB 0 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(6, 0.0);      // Run 759, DPB 1 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(7, 0.0);      // Run 759, DPB 1 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(8, 0.0);      // Run 759, DPB 1 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(9, 0.0);      // Run 759, DPB 1 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(10, 0.0);     // Run 759, DPB 1 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(11, 0.0);     // Run 759, DPB 1 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(12, 0.0);     // Run 759, DPB 2 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(13, 0.0);     // Run 759, DPB 2 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(14, 0.0);     // Run 759, DPB 2 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(15, 0.0);     // Run 759, DPB 2 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(16, 0.0);     // Run 759, DPB 2 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(17, 0.0);     // Run 759, DPB 2 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(18, 3200.0);  // Run 759, DPB 3 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(19, 3200.0);  // Run 759, DPB 3 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(20, 3200.0);  // Run 759, DPB 3 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(21, 3200.0);  // Run 759, DPB 3 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(22, 0.0);     // Run 759, DPB 3 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(23, 0.0);     // Run 759, DPB 3 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(24, 3200.0);  // Run 759, DPB 4 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(25, 3200.0);  // Run 759, DPB 4 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(26, 3200.0);  // Run 759, DPB 4 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(27, 0.0);     // Run 759, DPB 4 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(28, 0.0);     // Run 759, DPB 4 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(29, 0.0);     // Run 759, DPB 4 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(30, 0.0);     // Run 759, DPB 5 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(31, 0.0);     // Run 759, DPB 5 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(32, -30.0);   // Run 759, DPB 5 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(33, -30.0);   // Run 759, DPB 5 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(34, 0.0);     // Run 759, DPB 5 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(35, 0.0);     // Run 759, DPB 5 ASIC 5
-      break;
-    }  // 759
-    case 760: {
-      /// General System offsets (= offsets between sub-systems)
-      //unpacker_sts ->SetTimeOffsetNs( -1760 ); // Run 760
-      //unpacker_much->SetTimeOffsetNs( -1760 ); // Run 760
-      unpacker_trdR->SetTimeOffsetNs(-75);  // Run 760
-
-      /// ASIC specific offsets (= offsets inside sub-system)
-      unpacker_much->SetTimeOffsetNsAsic(0, 0.0);      // Run 760, DPB 0 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(1, 0.0);      // Run 760, DPB 0 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(2, 0.0);      // Run 760, DPB 0 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(3, 0.0);      // Run 760, DPB 0 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(4, 0.0);      // Run 760, DPB 0 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(5, 0.0);      // Run 760, DPB 0 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(6, 0.0);      // Run 760, DPB 1 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(7, 0.0);      // Run 760, DPB 1 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(8, 0.0);      // Run 760, DPB 1 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(9, 0.0);      // Run 760, DPB 1 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(10, 0.0);     // Run 760, DPB 1 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(11, 0.0);     // Run 760, DPB 1 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(12, 0.0);     // Run 760, DPB 2 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(13, 0.0);     // Run 760, DPB 2 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(14, 0.0);     // Run 760, DPB 2 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(15, 0.0);     // Run 760, DPB 2 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(16, 0.0);     // Run 760, DPB 2 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(17, 0.0);     // Run 760, DPB 2 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(18, 0.0);     // Run 760, DPB 3 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(19, 0.0);     // Run 760, DPB 3 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(20, 0.0);     // Run 760, DPB 3 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(21, 0.0);     // Run 760, DPB 3 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(22, 0.0);     // Run 760, DPB 3 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(23, 0.0);     // Run 760, DPB 3 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(24, 3160.0);  // Run 760, DPB 4 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(25, 3160.0);  // Run 760, DPB 4 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(26, 3160.0);  // Run 760, DPB 4 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(27, 0.0);     // Run 760, DPB 4 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(28, 0.0);     // Run 760, DPB 4 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(29, 0.0);     // Run 760, DPB 4 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(30, 0.0);     // Run 760, DPB 5 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(31, 0.0);     // Run 760, DPB 5 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(32, -30.0);   // Run 760, DPB 5 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(33, -30.0);   // Run 760, DPB 5 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(34, 0.0);     // Run 760, DPB 5 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(35, 0.0);     // Run 760, DPB 5 ASIC 5
-      break;
-    }  // 760
-    case 761: {
-      /// General System offsets (= offsets between sub-systems)
-      //unpacker_sts ->SetTimeOffsetNs( -1761 ); // Run 761
-      //unpacker_much->SetTimeOffsetNs( -1761 ); // Run 761
-      unpacker_trdR->SetTimeOffsetNs(90);  // Run 761
-
-      /// ASIC specific offsets (= offsets inside sub-system)
-      unpacker_much->SetTimeOffsetNsAsic(0, 0.0);      // Run 761, DPB 0 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(1, 0.0);      // Run 761, DPB 0 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(2, 0.0);      // Run 761, DPB 0 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(3, 0.0);      // Run 761, DPB 0 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(4, 0.0);      // Run 761, DPB 0 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(5, 0.0);      // Run 761, DPB 0 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(6, 0.0);      // Run 761, DPB 1 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(7, 0.0);      // Run 761, DPB 1 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(8, 0.0);      // Run 761, DPB 1 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(9, 0.0);      // Run 761, DPB 1 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(10, 0.0);     // Run 761, DPB 1 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(11, 0.0);     // Run 761, DPB 1 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(12, 0.0);     // Run 761, DPB 2 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(13, 0.0);     // Run 761, DPB 2 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(14, 0.0);     // Run 761, DPB 2 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(15, 0.0);     // Run 761, DPB 2 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(16, 0.0);     // Run 761, DPB 2 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(17, 0.0);     // Run 761, DPB 2 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(18, 3200.0);  // Run 761, DPB 3 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(19, 3200.0);  // Run 761, DPB 3 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(20, 3200.0);  // Run 761, DPB 3 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(21, 3200.0);  // Run 761, DPB 3 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(22, 0.0);     // Run 761, DPB 3 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(23, 0.0);     // Run 761, DPB 3 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(24, 6360.0);  // Run 761, DPB 4 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(25, 6360.0);  // Run 761, DPB 4 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(26, 6360.0);  // Run 761, DPB 4 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(27, 0.0);     // Run 761, DPB 4 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(28, 0.0);     // Run 761, DPB 4 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(29, 0.0);     // Run 761, DPB 4 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(30, 0.0);     // Run 761, DPB 5 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(31, 0.0);     // Run 761, DPB 5 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(32, 6360.0);  // Run 761, DPB 5 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(33, 6360.0);  // Run 761, DPB 5 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(34, 0.0);     // Run 761, DPB 5 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(35, 0.0);     // Run 761, DPB 5 ASIC 5
-      break;
-    }  // 761
-    case 762: {
-      /// General System offsets (= offsets between sub-systems)
-      //unpacker_sts ->SetTimeOffsetNs( -1762 ); // Run 762
-      //unpacker_much->SetTimeOffsetNs( -1762 ); // Run 762
-      unpacker_trdR->SetTimeOffsetNs(60);  // Run 762
-
-      /// ASIC specific offsets (= offsets inside sub-system)
-      unpacker_much->SetTimeOffsetNsAsic(0, 0.0);      // Run 762, DPB 0 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(1, 0.0);      // Run 762, DPB 0 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(2, 0.0);      // Run 762, DPB 0 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(3, 0.0);      // Run 762, DPB 0 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(4, 0.0);      // Run 762, DPB 0 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(5, 0.0);      // Run 762, DPB 0 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(6, 0.0);      // Run 762, DPB 1 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(7, 0.0);      // Run 762, DPB 1 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(8, 0.0);      // Run 762, DPB 1 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(9, 0.0);      // Run 762, DPB 1 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(10, 0.0);     // Run 762, DPB 1 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(11, 0.0);     // Run 762, DPB 1 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(12, 0.0);     // Run 762, DPB 2 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(13, 0.0);     // Run 762, DPB 2 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(14, 0.0);     // Run 762, DPB 2 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(15, 0.0);     // Run 762, DPB 2 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(16, 0.0);     // Run 762, DPB 2 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(17, 0.0);     // Run 762, DPB 2 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(18, 4800.0);  // Run 762, DPB 3 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(19, 4800.0);  // Run 762, DPB 3 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(20, 4800.0);  // Run 762, DPB 3 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(21, 4800.0);  // Run 762, DPB 3 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(22, 0.0);     // Run 762, DPB 3 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(23, 0.0);     // Run 762, DPB 3 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(24, 9550.0);  // Run 762, DPB 4 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(25, 9550.0);  // Run 762, DPB 4 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(26, 9550.0);  // Run 762, DPB 4 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(27, 0.0);     // Run 762, DPB 4 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(28, 0.0);     // Run 762, DPB 4 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(29, 0.0);     // Run 762, DPB 4 ASIC 5
-      unpacker_much->SetTimeOffsetNsAsic(30, 0.0);     // Run 762, DPB 5 ASIC 0
-      unpacker_much->SetTimeOffsetNsAsic(31, 0.0);     // Run 762, DPB 5 ASIC 1
-      unpacker_much->SetTimeOffsetNsAsic(32, -30.0);   // Run 762, DPB 5 ASIC 2
-      unpacker_much->SetTimeOffsetNsAsic(33, -30.0);   // Run 762, DPB 5 ASIC 3
-      unpacker_much->SetTimeOffsetNsAsic(34, 0.0);     // Run 762, DPB 5 ASIC 4
-      unpacker_much->SetTimeOffsetNsAsic(35, 0.0);     // Run 762, DPB 5 ASIC 5
-      break;
-    }  // 762
-    case 811: {
-      unpacker_trdR->SetTimeOffsetNs(84.38);
-      break;
-    }  // 811
-    case 812: {
-      unpacker_trdR->SetTimeOffsetNs(165.62);
-      break;
-    }  // 812
-    case 816: {
-      unpacker_trdR->SetTimeOffsetNs(-9.38);
-      break;
-    }  // 816
-    case 819: {
-      unpacker_trdR->SetTimeOffsetNs(-140.62);
-      break;
-    }  // 819
-    case 820: {
-      unpacker_trdR->SetTimeOffsetNs(109.38);
-      break;
-    }  // 820
-    case 821: {
-      unpacker_trdR->SetTimeOffsetNs(-65.62);
-      break;
-    }  // 821
-    case 822: {
-      unpacker_trdR->SetTimeOffsetNs(59.38);
-      break;
-    }  // 822
-    case 824: {
-      unpacker_trdR->SetTimeOffsetNs(-165.62);
-      break;
-    }  // 824
-    case 826: {
-      unpacker_trdR->SetTimeOffsetNs(59.38);
-      break;
-    }  // 826
-    case 827: {
-      unpacker_trdR->SetTimeOffsetNs(-15.62);
-      break;
-    }  // 827
-    case 828: {
-      unpacker_trdR->SetTimeOffsetNs(-109.38);
-      break;
-    }  // 828
-    case 830: {
-      unpacker_trdR->SetTimeOffsetNs(15.62);
-      break;
-    }  // 830
-    case 831: {
-      //         unpacker_trdR->SetTimeOffsetNs(   70.00 );
-      unpacker_trdR->SetTimeOffsetNs(-25.00);
-
-      std::cout << "MUCH: Feb by feb time offset correction......" << std::endl;
-      UInt_t uRun, uNx;
-      Double_t offset;
-      ifstream infile_off(paramDir + "/parameters/time_offset_much.txt");
-      if (!infile_off) {
-        std::cout << "can not open time offset MUCH parameter List" << std::endl;
-        return kFALSE;
-      } // if (!infile_off)
-      while (!infile_off.eof())  {
-        infile_off >> uRun >> uNx >> offset;
-        if(uRun != 831) continue;
-        unpacker_much->SetTimeOffsetNsAsic(uNx, offset);
-      } // while (!infile_off.eof())
-      infile_off.close();
-      std::cout << "masking noisy channels......" << std::endl;
-      UInt_t uChan = 0;
-      ifstream infile_noise(paramDir + "parameters/much_noisy_channel_list.txt");
-      if (!infile_noise) {
-        std::cout << "can not open MUCH noisy channel List" << std::endl;
-        return kFALSE;
-      } // if (!infile_noise)
-      while (!infile_noise.eof())  {
-        infile_noise >> uRun >> uNx >> uChan;
-        if(uRun != 831) continue;
-        unpacker_much->MaskNoisyChannel(uNx, uChan, kTRUE );
-      } // while (!infile_noise.eof())
-      infile_noise.close();
-      break;
-    }  // 831
-    case 836: {
-      unpacker_trdR->SetTimeOffsetNs(-40.62);
-      break;
-    }  // 836
-    default: break;
-  }  // switch( uRunId )
-  /// FIXME: Re-enable clang formatting after parameters tuning
-  /* clang-format on */
-  // --- Source task
-  CbmMcbm2018Source* source = new CbmMcbm2018Source();
-  source->SetWriteOutputFlag(kTRUE);  // For writing TS metadata
+  if (uRunId < 692) return kFALSE;
 
   TString inFile =
     Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn02_*.tsa;", uRunId);
@@ -626,72 +72,5 @@ void unpack_tsa_mcbm_kronos(UInt_t uRunIdx  = 99999,
   inFile +=
     Form("/lustre/cbm/users/ploizeau/mcbm2020/data/%3u_pn15_*.tsa", uRunId);
 
-  source->SetFileName(inFile);
-
-  source->AddUnpacker(unpacker_sts, 0x10, ECbmModuleId::kSts);    // STS xyter
-  source->AddUnpacker(unpacker_much, 0x50, ECbmModuleId::kMuch);  // MUCH xyter
-  if (isActiveTrd)
-    source->AddUnpacker(unpacker_trdR, 0x40, ECbmModuleId::kTrd);  // Trd
-  source->AddUnpacker(unpacker_tof, 0x60, ECbmModuleId::kTof);     // gDPB TOF
-  source->AddUnpacker(unpacker_tof, 0x90, ECbmModuleId::kTof);     // gDPB T0
-  source->AddUnpacker(unpacker_rich, 0x30, ECbmModuleId::kRich);   // RICH trb
-  source->AddUnpacker(unpacker_psd, 0x80, ECbmModuleId::kPsd);     // PSD
-
-  // --- Event header
-  FairEventHeader* event = new FairEventHeader();
-  event->SetRunId(uRunId);
-
-  // --- RootFileSink
-  // --- Open next outputfile after 4GB
-  FairRootFileSink* sink = new FairRootFileSink(outFile);
-  //  sink->GetOutTree()->SetMaxTreeSize(4294967295LL);
-
-  // --- Run
-  run = new FairRunOnline(source);
-  run->SetSink(sink);
-  run->SetEventHeader(event);
-  run->SetAutoFinish(kFALSE);
-
-
-  // -----   Runtime database   ---------------------------------------------
-  FairRuntimeDb* rtdb       = run->GetRuntimeDb();
-  Bool_t kParameterMerged   = kTRUE;
-  FairParRootFileIo* parOut = new FairParRootFileIo(kParameterMerged);
-  FairParAsciiFileIo* parIn = new FairParAsciiFileIo();
-  parOut->open(parFile.Data());
-  parIn->open(parFileList, "in");
-  rtdb->setFirstInput(parIn);
-  rtdb->setOutput(parOut);
-
-  run->Init();
-
-  // --- Start run
-  TStopwatch timer;
-  timer.Start();
-  std::cout << ">>> unpack_tsa_mcbm: Starting run..." << std::endl;
-  if (0 == nrEvents) {
-    run->Run(nEvents, 0);  // run until end of input file
-  } else {
-    run->Run(0, nrEvents);  // process  N Events
-  }
-  run->Finish();
-
-  timer.Stop();
-
-  std::cout << "Processed " << std::dec << source->GetTsCount() << " timeslices"
-            << std::endl;
-
-  // --- End-of-run info
-  Double_t rtime = timer.RealTime();
-  Double_t ctime = timer.CpuTime();
-  std::cout << std::endl << std::endl;
-  std::cout << ">>> unpack_tsa_mcbm: Macro finished successfully." << std::endl;
-  std::cout << ">>> unpack_tsa_mcbm: Output file is " << outFile << std::endl;
-  std::cout << ">>> unpack_tsa_mcbm: Real time " << rtime << " s, CPU time "
-            << ctime << " s" << std::endl;
-  std::cout << std::endl;
-
-  /// --- Screen output for automatic tests
-  std::cout << " Test passed" << std::endl;
-  std::cout << " All ok " << std::endl;
+  return unpack_tsa_mcbm(inFile, uRunId, uNbTimeslices, sOutDir, iSpillIndex, iSpillnumber, uSpillLimType);
 }
diff --git a/macro/run/run_reco.C b/macro/run/run_reco.C
index 7afd3921cc6dd13b1fb005164b66fa94fc88cf29..5fb13de91be96a717f5f458905d685d236b2343e 100644
--- a/macro/run/run_reco.C
+++ b/macro/run/run_reco.C
@@ -30,6 +30,7 @@
 #include "CbmTofSimpClusterizer.h"
 #include "CbmTrdClusterFinder.h"
 #include "CbmTrdHitProducer.h"
+
 #include <FairFileSource.h>
 #include <FairMonitor.h>
 #include <FairParAsciiFileIo.h>
@@ -37,6 +38,7 @@
 #include <FairRunAna.h>
 #include <FairRuntimeDb.h>
 #include <FairSystemInfo.h>
+
 #include <TStopwatch.h>
 #endif
 
@@ -61,7 +63,8 @@
  ** employed and reconstruction will be time-based. The option "Ideal"
  ** selects the ideal raw event builder, which associates digis to events
  ** based on the MC truth. The option "Real" selects a real raw event builder
- ** (not yet available).
+ ** (latest version, for older versions use "Real2018" or "Real2019").
+ ** 
  **
  ** The file names must be specified without extensions. The convention is
  ** that the raw (input) file is [input].raw.root. The output file
@@ -74,13 +77,9 @@
  ** from the ROOT prompt without user intervention.
  **
  **/
-void run_reco(TString input        = "",
-              Int_t nTimeSlices    = -1,
-              Int_t firstTimeSlice = 0,
-              TString output       = "",
-              TString sEvBuildRaw  = "",
-              TString setup        = "sis100_electron",
-              TString paramFile    = "") {
+void run_reco(TString input = "", Int_t nTimeSlices = -1, Int_t firstTimeSlice = 0, TString output = "",
+              TString sEvBuildRaw = "", TString setup = "sis100_electron", TString paramFile = "")
+{
 
   // ========================================================================
   //          Adjust this part according to your requirements
@@ -92,7 +91,7 @@ void run_reco(TString input        = "",
 
 
   // -----   Environment   --------------------------------------------------
-  TString myName = "run_reco";  // this macro's name for screen output
+  TString myName = "run_reco";                     // this macro's name for screen output
   TString srcDir = gSystem->Getenv("VMCWORKDIR");  // top source directory
   // ------------------------------------------------------------------------
 
@@ -145,21 +144,17 @@ void run_reco(TString input        = "",
     const Char_t* npar[4] = {"asic", "digi", "gas", "gain"};
     TObjString* trdParFile(NULL);
     for (Int_t i(0); i < 4; i++) {
-      trdParFile = new TObjString(srcDir + "/parameters/trd/trd_" + geoTag + "."
-                                  + npar[i] + ".par");
+      trdParFile = new TObjString(srcDir + "/parameters/trd/trd_" + geoTag + "." + npar[i] + ".par");
       parFileList->Add(trdParFile);
-      std::cout << "-I- " << myName << ": Using parameter file "
-                << trdParFile->GetString() << std::endl;
+      std::cout << "-I- " << myName << ": Using parameter file " << trdParFile->GetString() << std::endl;
     }
   }
 
   // - TOF digitisation parameters
   if (CbmSetup::Instance()->GetGeoTag(ECbmModuleId::kTof, geoTag)) {
-    TObjString* tofBdfFile =
-      new TObjString(srcDir + "/parameters/tof/tof_" + geoTag + ".digibdf.par");
+    TObjString* tofBdfFile = new TObjString(srcDir + "/parameters/tof/tof_" + geoTag + ".digibdf.par");
     parFileList->Add(tofBdfFile);
-    std::cout << "-I- " << myName << ": Using parameter file "
-              << tofBdfFile->GetString() << std::endl;
+    std::cout << "-I- " << myName << ": Using parameter file " << tofBdfFile->GetString() << std::endl;
   }
   // ------------------------------------------------------------------------
 
@@ -194,36 +189,26 @@ void run_reco(TString input        = "",
     if (sEvBuildRaw.EqualTo("Ideal", TString::ECaseCompare::kIgnoreCase)) {
       FairTask* evBuildRaw = new CbmBuildEventsIdeal();
       run->AddTask(evBuildRaw);
-      std::cout << "-I- " << myName << ": Added task " << evBuildRaw->GetName()
-                << std::endl;
+      std::cout << "-I- " << myName << ": Added task " << evBuildRaw->GetName() << std::endl;
       eventBased = kTRUE;
     }  //? Ideal raw event building
-    else if (sEvBuildRaw.EqualTo("Real", TString::ECaseCompare::kIgnoreCase)) {
-      // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
-      /// to use 2018 version, uncomment this section and comment the next one
-      /*
+    else if (sEvBuildRaw.EqualTo("Real2018", TString::ECaseCompare::kIgnoreCase)) {
       CbmMcbm2018EventBuilder* evBuildRaw = new CbmMcbm2018EventBuilder();
 
-      evBuildRaw->SetFixedTimeWindow(5500.);
-      evBuildRaw->SetTriggerMinNumberSts(50);
+      evBuildRaw->SetFixedTimeWindow(500.);
+      evBuildRaw->SetTriggerMinNumberSts(1000);
 
-      if (!useSts) {
-        std::cerr << "-E- " << myName << ": Sts must be present for raw event "
-                  << "building using ``Real'' option. Terminating macro."
-                  << std::endl;
-         return;
-      }
-      */
-      // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
+      evBuildRaw->SetUseBaseMuchDigi(kTRUE);
 
-      // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
-      /// to use 2018 version, uncomment this section and comment the prev. one
-      CbmMcbm2019TimeWinEventBuilderTask* evBuildRaw =
-        new CbmMcbm2019TimeWinEventBuilderTask();
-      evBuildRaw->SetTsParameters(0.0, 1.e7, 0.0);
+      run->AddTask(evBuildRaw);
+      std::cout << "-I- " << myName << ": Added task " << evBuildRaw->GetName() << std::endl;
+      eventBased = kTRUE;
+    }
+    else if (sEvBuildRaw.EqualTo("Real2019", TString::ECaseCompare::kIgnoreCase)) {
+      CbmMcbm2019TimeWinEventBuilderTask* evBuildRaw = new CbmMcbm2019TimeWinEventBuilderTask();
 
-      // Use CbmMuchDigi instead of CbmMuchBeamtimeDigi
-      evBuildRaw->ChangeMuchBeamtimeDigiFlag(kFALSE);
+      //Choose between NoOverlap, MergeOverlap, AllowOverlap
+      evBuildRaw->SetEventOverlapMode(EOverlapMode::AllowOverlap);
 
       // Remove detectors where digis not found
       if (!useRich) evBuildRaw->RemoveDetector(kEventBuilderDetRich);
@@ -231,49 +216,85 @@ void run_reco(TString input        = "",
       if (!usePsd) evBuildRaw->RemoveDetector(kEventBuilderDetPsd);
       if (!useTof) evBuildRaw->RemoveDetector(kEventBuilderDetTof);
       if (!useTrd) evBuildRaw->RemoveDetector(kEventBuilderDetTrd);
-
-      // Remove STS as it will be our reference
-      evBuildRaw->RemoveDetector(kEventBuilderDetSts);
-
+      if (!useSts) {
+        std::cerr << "-E- " << myName << ": Sts must be present for raw event "
+                  << "building using ``Real2019'' option. Terminating macro." << std::endl;
+        return;
+      }
       // Set STS as reference detector
       evBuildRaw->SetReferenceDetector(kEventBuilderDetSts);
+      evBuildRaw->SetTsParameters(0.0, 1.e7, 0.0);
+
+      // Use CbmMuchDigi instead of CbmMuchBeamtimeDigi
+      evBuildRaw->ChangeMuchBeamtimeDigiFlag(kFALSE);
+
+      evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kSts, 1000);
+      evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kSts, -1);
+      evBuildRaw->SetTriggerWindow(ECbmModuleId::kSts, -500, 500);
+
+      run->AddTask(evBuildRaw);
+      std::cout << "-I- " << myName << ": Added task " << evBuildRaw->GetName() << std::endl;
+      eventBased = kTRUE;
+    }
+    else if (sEvBuildRaw.EqualTo("Real", TString::ECaseCompare::kIgnoreCase)) {
+      CbmTaskBuildRawEvents* evBuildRaw = new CbmTaskBuildRawEvents();
 
       //Choose between NoOverlap, MergeOverlap, AllowOverlap
-      evBuildRaw->SetEventOverlapMode(EOverlapMode::AllowOverlap);
+      evBuildRaw->SetEventOverlapMode(EOverlapModeRaw::AllowOverlap);
+
+      // Remove detectors where digis not found
+      if (!useRich) evBuildRaw->RemoveDetector(kRawEventBuilderDetRich);
+      if (!useMuch) evBuildRaw->RemoveDetector(kRawEventBuilderDetMuch);
+      if (!usePsd) evBuildRaw->RemoveDetector(kRawEventBuilderDetPsd);
+      if (!useTof) evBuildRaw->RemoveDetector(kRawEventBuilderDetTof);
+      if (!useTrd) evBuildRaw->RemoveDetector(kRawEventBuilderDetTrd);
+      if (!useSts) {
+        std::cerr << "-E- " << myName << ": Sts must be present for raw event "
+                  << "building using ``Real2019'' option. Terminating macro." << std::endl;
+        return;
+      }
+      // Set STS as reference detector
+      evBuildRaw->SetReferenceDetector(kRawEventBuilderDetSts);
+      evBuildRaw->SetTsParameters(0.0, 1.e7, 0.0);
 
-      evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kSts, 10);
+      // Use CbmMuchDigi instead of CbmMuchBeamtimeDigi
+      evBuildRaw->ChangeMuchBeamtimeDigiFlag(kFALSE);
+
+      evBuildRaw->SetTriggerMinNumber(ECbmModuleId::kSts, 1000);
       evBuildRaw->SetTriggerMaxNumber(ECbmModuleId::kSts, -1);
-      evBuildRaw->SetTriggerWindow(ECbmModuleId::kSts, -5500, 5500);
-      // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //
+      evBuildRaw->SetTriggerWindow(ECbmModuleId::kSts, -500, 500);
 
       run->AddTask(evBuildRaw);
-      std::cout << "-I- " << myName << ": Added task " << evBuildRaw->GetName()
-                << std::endl;
+      std::cout << "-I- " << myName << ": Added task " << evBuildRaw->GetName() << std::endl;
       eventBased = kTRUE;
     }  //? Real raw event building
     else {
       std::cerr << "-E- " << myName << ": Unknown option " << sEvBuildRaw
-                << " for raw event building! Terminating macro execution."
-                << std::endl;
+                << " for raw event building! Terminating macro execution." << std::endl;
       return;
     }
   }  //? event-based reco
   // ------------------------------------------------------------------------
 
+  // ----------- QA for raw event builder -----------------------------------
+  if (eventBased) {
+    CbmBuildEventsQA* evBuildQA = new CbmBuildEventsQA();
+    run->AddTask(evBuildQA);
+  }
+  // ------------------------------------------------------------------------
+
 
   // -----   Local reconstruction in MVD   ----------------------------------
   if (useMvd) {
 
-    CbmMvdClusterfinder* mvdCluster =
-      new CbmMvdClusterfinder("MVD Cluster Finder", 0, 0);
+    CbmMvdClusterfinder* mvdCluster = new CbmMvdClusterfinder("MVD Cluster Finder", 0, 0);
     run->AddTask(mvdCluster);
     std::cout << "-I- : Added task " << mvdCluster->GetName() << std::endl;
 
     CbmMvdHitfinder* mvdHit = new CbmMvdHitfinder("MVD Hit Finder", 0, 0);
     mvdHit->UseClusterfinder(kTRUE);
     run->AddTask(mvdHit);
-    std::cout << "-I- " << myName << ": Added task " << mvdHit->GetName()
-              << std::endl;
+    std::cout << "-I- " << myName << ": Added task " << mvdHit->GetName() << std::endl;
   }
   // ------------------------------------------------------------------------
 
@@ -283,8 +304,7 @@ void run_reco(TString input        = "",
     CbmRecoSts* stsReco = new CbmRecoSts(kCbmRecoTimeslice);
     if (eventBased) stsReco->SetMode(kCbmRecoEvent);
     run->AddTask(stsReco);
-    std::cout << "-I- " << myName << ": Added task " << stsReco->GetName()
-              << std::endl;
+    std::cout << "-I- " << myName << ": Added task " << stsReco->GetName() << std::endl;
   }
   // ------------------------------------------------------------------------
 
@@ -293,8 +313,7 @@ void run_reco(TString input        = "",
   if (useRich) {
     CbmRichHitProducer* richHitProd = new CbmRichHitProducer();
     run->AddTask(richHitProd);
-    std::cout << "-I- " << myName << ": Added task " << richHitProd->GetName()
-              << std::endl;
+    std::cout << "-I- " << myName << ": Added task " << richHitProd->GetName() << std::endl;
   }
   // ------------------------------------------------------------------------
 
@@ -313,8 +332,8 @@ void run_reco(TString input        = "",
     // --- Hit finder for GEMs
     FairTask* muchReco = new CbmMuchFindHitsGem(parFile.Data(), muchFlag);
     run->AddTask(muchReco);
-    std::cout << "-I- " << myName << ": Added task " << muchReco->GetName()
-              << " with parameter file " << parFile << std::endl;
+    std::cout << "-I- " << myName << ": Added task " << muchReco->GetName() << " with parameter file " << parFile
+              << std::endl;
   }
   // ------------------------------------------------------------------------
 
@@ -324,34 +343,29 @@ void run_reco(TString input        = "",
 
     Double_t triggerThreshold       = 0.5e-6;  // SIS100
     CbmTrdClusterFinder* trdCluster = new CbmTrdClusterFinder();
-    if (eventBased)
-      trdCluster->SetTimeBased(kFALSE);
+    if (eventBased) trdCluster->SetTimeBased(kFALSE);
     else
       trdCluster->SetTimeBased(kTRUE);
     trdCluster->SetNeighbourEnable(true, false);
     trdCluster->SetMinimumChargeTH(triggerThreshold);
     trdCluster->SetRowMerger(true);
     run->AddTask(trdCluster);
-    std::cout << "-I- " << myName << ": Added task " << trdCluster->GetName()
-              << std::endl;
+    std::cout << "-I- " << myName << ": Added task " << trdCluster->GetName() << std::endl;
 
     CbmTrdHitProducer* trdHit = new CbmTrdHitProducer();
     run->AddTask(trdHit);
-    std::cout << "-I- " << myName << ": Added task " << trdHit->GetName()
-              << std::endl;
+    std::cout << "-I- " << myName << ": Added task " << trdHit->GetName() << std::endl;
   }
   // ------------------------------------------------------------------------
 
 
   // -----   Local reconstruction in TOF   ----------------------------------
   if (useTof) {
-    CbmTofSimpClusterizer* tofCluster =
-      new CbmTofSimpClusterizer("TOF Simple Clusterizer", 0);
+    CbmTofSimpClusterizer* tofCluster = new CbmTofSimpClusterizer("TOF Simple Clusterizer", 0);
     tofCluster->SetOutputBranchPersistent("TofHit", kTRUE);
     tofCluster->SetOutputBranchPersistent("TofDigiMatch", kTRUE);
     run->AddTask(tofCluster);
-    std::cout << "-I- " << myName << ": Added task " << tofCluster->GetName()
-              << std::endl;
+    std::cout << "-I- " << myName << ": Added task " << tofCluster->GetName() << std::endl;
   }
   // ------------------------------------------------------------------------
 
@@ -360,8 +374,7 @@ void run_reco(TString input        = "",
   if (usePsd) {
     CbmPsdHitProducer* psdHit = new CbmPsdHitProducer();
     run->AddTask(psdHit);
-    std::cout << "-I- " << myName << ": Added task " << psdHit->GetName()
-              << std::endl;
+    std::cout << "-I- " << myName << ": Added task " << psdHit->GetName() << std::endl;
   }
   // ------------------------------------------------------------------------
 
@@ -388,21 +401,18 @@ void run_reco(TString input        = "",
       l1->SetStsMaterialBudgetFileName(parFile.Data());
     }
     run->AddTask(l1);
-    std::cout << "-I- " << myName << ": Added task " << l1->GetName()
-              << std::endl;
+    std::cout << "-I- " << myName << ": Added task " << l1->GetName() << std::endl;
 
     CbmStsTrackFinder* stsTrackFinder = new CbmL1StsTrackFinder();
     if (eventBased) {
-      FairTask* stsFindTracks =
-        new CbmStsFindTracksEvents(stsTrackFinder, useMvd);
+      FairTask* stsFindTracks = new CbmStsFindTracksEvents(stsTrackFinder, useMvd);
       run->AddTask(stsFindTracks);
-      std::cout << "-I- " << myName << ": Added task "
-                << stsFindTracks->GetName() << std::endl;
-    } else {
+      std::cout << "-I- " << myName << ": Added task " << stsFindTracks->GetName() << std::endl;
+    }
+    else {
       FairTask* stsFindTracks = new CbmStsFindTracks(0, stsTrackFinder, useMvd);
       run->AddTask(stsFindTracks);
-      std::cout << "-I- " << myName << ": Added task "
-                << stsFindTracks->GetName() << std::endl;
+      std::cout << "-I- " << myName << ": Added task " << stsFindTracks->GetName() << std::endl;
     }
   }
   // ------------------------------------------------------------------------
@@ -420,8 +430,7 @@ void run_reco(TString input        = "",
     CbmPrimaryVertexFinder* pvFinder = new CbmPVFinderKF();
     CbmFindPrimaryVertex* findVertex = new CbmFindPrimaryVertex(pvFinder);
     run->AddTask(findVertex);
-    std::cout << "-I- " << myName << ": Added task " << findVertex->GetName()
-              << std::endl;
+    std::cout << "-I- " << myName << ": Added task " << findVertex->GetName() << std::endl;
     // ----------------------------------------------------------------------
 
 
@@ -504,8 +513,7 @@ void run_reco(TString input        = "",
   std::cout << "Macro finished successfully." << std::endl;
   std::cout << "Output file is    " << outFile << std::endl;
   std::cout << "Parameter file is " << parFile << std::endl;
-  std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s"
-            << std::endl;
+  std::cout << "Real time " << rtime << " s, CPU time " << ctime << " s" << std::endl;
   FairSystemInfo sysInfo;
   Float_t maxMemory = sysInfo.GetMaxMemory();
   std::cout << "<DartMeasurement name=\"MaxMemory\" type=\"numeric/double\">";
diff --git a/reco/detectors/much/CbmMuchFindHitsGem.cxx b/reco/detectors/much/CbmMuchFindHitsGem.cxx
index a7dc2d83d9882a6144770c18f500d684cb9886ae..9a18f06417eca8d1a00c988e5dfa5c78032acec1 100644
--- a/reco/detectors/much/CbmMuchFindHitsGem.cxx
+++ b/reco/detectors/much/CbmMuchFindHitsGem.cxx
@@ -1,6 +1,6 @@
 /*
  * CbmMuchFindHitsGem.cxx
- * 
+ *
  * Modified on 08/08/2019 : Hit reconstruction in Event (in time slice) and Time slice mode
  * Default is time slice (kCbmTimeSlice) and it will run in event mode (kCbmEvent) if find event branch in the tree
  * @authors Vikas Singhal and Ajit Kumar
@@ -78,13 +78,13 @@ InitStatus CbmMuchFindHitsGem::Init() {
 
   // fDigis will not be used now. Just for checking. Need to remove
   /*fDigis     = (TClonesArray*) ioman->GetObject("MuchDigi");
-  if (! fDigis) 
-    fDigis     = (TClonesArray*) ioman->GetObject("MuchBeamTimeDigi"); 
-  if (! fDigis) 
-    fDigis     = (TClonesArray*) ioman->GetObject("CbmMuchBeamTimeDigi"); 
-  if (! fDigis) 
-    fDigis     = (TClonesArray*) ioman->GetObject("CbmMuchDigi"); 
-  if (! fDigis) 
+  if (! fDigis)
+    fDigis     = (TClonesArray*) ioman->GetObject("MuchBeamTimeDigi");
+  if (! fDigis)
+    fDigis     = (TClonesArray*) ioman->GetObject("CbmMuchBeamTimeDigi");
+  if (! fDigis)
+    fDigis     = (TClonesArray*) ioman->GetObject("CbmMuchDigi");
+  if (! fDigis)
     LOG(info) << "MuchFindHitsGem: No MuchDigi or MuchBeamTimeDigi or CbmMuchDigi or CbmMuchBeamTimeDigi exist";
     */
 
@@ -117,12 +117,18 @@ InitStatus CbmMuchFindHitsGem::Init() {
                   IsOutputBranchPersistent("MuchPixelHit"));
 
   // Initialize GeoScheme
-  TFile* oldfile      = gFile;
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
   TFile* file         = new TFile(fDigiFile);
   TObjArray* stations = (TObjArray*) file->Get("stations");
   file->Close();
   file->Delete();
-  gFile = oldfile;
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
+
   fGeoScheme->Init(stations, fFlag);
   return kSUCCESS;
 }
diff --git a/reco/detectors/much/CbmMuchHitProducerIdeal.cxx b/reco/detectors/much/CbmMuchHitProducerIdeal.cxx
index f719cb34e723d3646d872aeadb126978a36c1b2a..f6182355c939c536a26e185b4532e12dcc19e150 100644
--- a/reco/detectors/much/CbmMuchHitProducerIdeal.cxx
+++ b/reco/detectors/much/CbmMuchHitProducerIdeal.cxx
@@ -45,12 +45,18 @@ InitStatus CbmMuchHitProducerIdeal::Init() {
 
   // Initialize GeoScheme
   fGeoScheme          = CbmMuchGeoScheme::Instance();
-  TFile* oldfile      = gFile;
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
   TFile* file         = new TFile(fDigiFile);
   TObjArray* stations = (TObjArray*) file->Get("stations");
   file->Close();
   file->Delete();
-  gFile = oldfile;
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
+
   fGeoScheme->Init(stations, fId);
   return kSUCCESS;
 }
diff --git a/reco/detectors/much/qa/CbmMuchHitFinderQa.cxx b/reco/detectors/much/qa/CbmMuchHitFinderQa.cxx
index 6b397aaeb3af9cda75e6f03f3c2557fec23aad76..ebe7f849178069732888a1f28531e665292624ee 100644
--- a/reco/detectors/much/qa/CbmMuchHitFinderQa.cxx
+++ b/reco/detectors/much/qa/CbmMuchHitFinderQa.cxx
@@ -138,7 +138,16 @@ InitStatus CbmMuchHitFinderQa::Init() {
   // Reading Much Digis from CbmMuchDigiManager which are stored as vector
   fDigiManager = CbmDigiManager::Instance();
 
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
+
   TFile* f            = new TFile(fGeoFileName, "R");
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
+
   TObjArray* stations = (TObjArray*) f->Get("stations");
   fGeoScheme->Init(stations, fFlag);
 
diff --git a/reco/detectors/sts/CbmStsAlgoFindHits.cxx b/reco/detectors/sts/CbmStsAlgoFindHits.cxx
index 3863eb23fe3b8225a9d111fbfb7fc705b7b61c17..fa88a5fd03013656f2b51dcf91ae5b38ed9655d1 100644
--- a/reco/detectors/sts/CbmStsAlgoFindHits.cxx
+++ b/reco/detectors/sts/CbmStsAlgoFindHits.cxx
@@ -116,7 +116,7 @@ Long64_t CbmStsAlgoFindHits::Exec(const vector<CbmStsCluster>& clustersF,
   fHits->clear();
   fTanStereoF = TMath::Tan(fStereoF * TMath::DegToRad());
   fTanStereoB = TMath::Tan(fStereoB * TMath::DegToRad());
-  fErrorFac   = 1. / (fTanStereoB - fTanStereoF) / (fTanStereoB - fTanStereoB);
+  fErrorFac   = 1. / (fTanStereoB - fTanStereoF) / (fTanStereoB - fTanStereoF);
   fDx         = Double_t(fNofStrips) * fPitch;
 
   // Determine the maximum cluster time errors
diff --git a/reco/eventbuilder/CMakeLists.txt b/reco/eventbuilder/CMakeLists.txt
index 11025c2ece4220ab4d95ed49d827b8968e4faeac..17f0aaa1af6f661c70b2b23a2d3d5318f393d875 100644
--- a/reco/eventbuilder/CMakeLists.txt
+++ b/reco/eventbuilder/CMakeLists.txt
@@ -41,6 +41,7 @@ ${CBMROOT_SOURCE_DIR}/rich
 ${CBMROOT_SOURCE_DIR}/tof/TofMC
 ${CBMROOT_SOURCE_DIR}/psd
 ${CBMROOT_SOURCE_DIR}/field
+${CBMROOT_SOURCE_DIR}/core/data/raw
 
 )
 
@@ -66,6 +67,8 @@ link_directories( ${LINK_DIRECTORIES})
 
 set(SRCS
 
+digis/CbmAlgoBuildRawEvents.cxx
+digis/CbmTaskBuildRawEvents.cxx
 digis/CbmBuildEventsIdeal.cxx
 digis/CbmBuildEventsIdealNew.cxx
 digis/CbmBuildEventsQA.cxx
diff --git a/reco/eventbuilder/CbmEventBuilderLinkDef.h b/reco/eventbuilder/CbmEventBuilderLinkDef.h
index a62bc57b8e07f1bd803cabbf4c565f597fe6b9d7..1f6d5431ab5e6535572681af5dc6a41f3f47b566 100644
--- a/reco/eventbuilder/CbmEventBuilderLinkDef.h
+++ b/reco/eventbuilder/CbmEventBuilderLinkDef.h
@@ -4,13 +4,14 @@
 #pragma link off all classes;
 #pragma link off all functions;
 
-
+#pragma link C++ class CbmAlgoBuildRawEvents + ;
+#pragma link C++ class CbmTaskBuildRawEvents + ;
 #pragma link C++ class CbmBuildEventsFromTracksIdeal + ;
 #pragma link C++ class CbmBuildEventsFromTracksReal + ;
 #pragma link C++ class CbmEventBuilderQA + ;
 #pragma link C++ class CbmBuildEventsIdeal + ;
 #pragma link C++ class CbmBuildEventsIdealNew + ;
-#pragma link C++ class CbmBuildEventsQA+;
+#pragma link C++ class CbmBuildEventsQA + ;
 #pragma link C++ class CbmBuildEventsSimple + ;
 //#pragma link C++ class CbmEvBuildSource+;
 
diff --git a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f748a36cca443651e389726d879a1f0a96c9fd04
--- /dev/null
+++ b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.cxx
@@ -0,0 +1,934 @@
+/********************************************************************************
+ *    Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH    *
+ *                                                                              *
+ *              This software is distributed under the terms of the             *
+ *              GNU Lesser General Public Licence (LGPL) version 3,             *
+ *                  copied verbatim in the file "LICENSE"                       *
+ ********************************************************************************/
+#include "CbmAlgoBuildRawEvents.h"
+
+/// CBM headers
+#include "CbmEvent.h"
+#include "CbmMuchBeamTimeDigi.h"
+#include "CbmMuchDigi.h"
+#include "CbmPsdDigi.h"
+#include "CbmRichDigi.h"
+#include "CbmStsDigi.h"
+#include "CbmTofDigi.h"
+#include "CbmTrdDigi.h"
+
+#include "TimesliceMetaData.h"
+
+/// FAIRROOT headers
+#include "FairLogger.h"
+#include "FairRootManager.h"
+#include "FairRunOnline.h"
+
+/// FAIRSOFT headers (geant, boost, ...)
+#include "TCanvas.h"
+#include "TClonesArray.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "THttpServer.h"
+
+template<>
+void CbmAlgoBuildRawEvents::LoopOnSeeds<Double_t>();
+
+Bool_t CbmAlgoBuildRawEvents::InitAlgo()
+{
+  LOG(info) << "CbmAlgoBuildRawEvents::InitAlgo => Starting sequence";
+
+  // Get a handle from the IO manager
+  FairRootManager* ioman = FairRootManager::Instance();
+
+  /// Check if reference detector is set and seed data are available,
+  /// otherwise look for explicit seed times
+  if (fRefDet.detId == ECbmModuleId::kNotExist) {
+    if (fSeedTimes == nullptr) {
+      LOG(fatal) << "No reference detector set and no seed times supplied, stopping there!";
+    }
+  }
+  else {
+    if (fSeedTimes != nullptr) {
+      LOG(fatal) << "Cannot have explicit seed times and reference detector, stopping there!";
+    }
+    if (kFALSE == CheckDataAvailable(fRefDet)) {
+      LOG(fatal) << "Reference detector set but no digi input found, stopping there!";
+    }
+  }
+
+  /// Check if data for detectors in selection list are available
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    if (kFALSE == CheckDataAvailable(*det)) {
+      LOG(fatal) << "No digi input for one of selection detector, stopping there!";
+    }
+  }
+
+  /// Access the TS metadata to know TS start time if needed
+  if (fdTsStartTime < 0 || fdTsLength < 0 || fdTsOverLength < 0) {
+    fTimeSliceMetaDataArray = dynamic_cast<TClonesArray*>(ioman->GetObject("TimesliceMetaData"));
+    if (!fTimeSliceMetaDataArray) {
+      LOG(fatal) << "No TS metadata input found"
+                 << " => Please check in the unpacking macro if the following line was "
+                    "present!"
+                 << std::endl
+                 << "source->SetWriteOutputFlag(kTRUE);  // For writing TS metadata";
+    }
+  }
+
+  if (fbFillHistos) { CreateHistograms(); }
+  LOG(info) << "CbmAlgoBuildRawEvents::InitAlgo => Done";
+  return kTRUE;
+}
+
+void CbmAlgoBuildRawEvents::Finish() { LOG(info) << "Total errors: " << fuErrors; }
+
+void CbmAlgoBuildRawEvents::ClearEventVector()
+{
+  /// Need to delete the object the pointer points to first
+  int counter = 0;
+  for (CbmEvent* event : fEventVector) {
+    LOG(debug) << "Event " << counter << " has " << event->GetNofData() << " digis";
+    delete event;
+    counter++;
+  }
+  fEventVector.clear();
+}
+
+void CbmAlgoBuildRawEvents::ProcessTs()
+{
+  LOG_IF(info, fuNrTs % 1000 == 0) << "Begin of TS " << fuNrTs;
+  InitTs();
+  InitSeedWindow();
+  BuildEvents();
+
+  /// Store last event with trigger if not done by other seed
+  if (nullptr != fCurrentEvent) {
+    /// TODO: store start time of current event ?
+    //        fCurrentEvent->SetStartTime( fPrevTime ); // Replace Seed time with time of first digi in event?
+    fCurrentEvent->SetEndTime(fdPrevEvtEndTime);
+    fEventVector.push_back(fCurrentEvent);
+    fuCurEv++;
+
+    /// Prevent building over TS edge
+    fCurrentEvent = nullptr;
+  }
+
+  LOG(debug) << "Found " << fEventVector.size() << " triggered events";
+  if (fbFillHistos) { FillHistos(); }
+  fuNrTs++;
+}
+
+void CbmAlgoBuildRawEvents::InitTs()
+{
+  /// Reset TS based variables (analysis per TS = no building over the border)
+
+  /// Reference detector
+  if (fRefDet.detId != ECbmModuleId::kNotExist) {
+    fRefDet.fuStartIndex = 0;
+    fRefDet.fuEndIndex   = 0;
+  }
+  /// Loop on detectors in selection list
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    (*det).fuStartIndex = 0;
+    (*det).fuEndIndex   = 0;
+  }
+}
+
+void CbmAlgoBuildRawEvents::InitSeedWindow()
+{
+  /// Access the TS metadata if needed to know TS start time and overlap size
+  Double_t dTsStartTime  = fdTsStartTime;
+  Double_t dOverlapStart = fdTsStartTime + fdTsLength;
+  Double_t dOverlapSize  = fdTsOverLength;
+
+  if (fdTsStartTime < 0 || fdTsLength < 0 || fdTsOverLength < 0) {
+    pTsMetaData = dynamic_cast<TimesliceMetaData*>(fTimeSliceMetaDataArray->At(0));
+    if (nullptr == pTsMetaData)
+      LOG(fatal) << Form("CbmAlgoBuildRawEvents::LoopOnSeeds => "
+                         "No TS metadata found for TS %6u.",
+                         fuNrTs);
+    dTsStartTime  = pTsMetaData->GetStartTime();
+    dOverlapStart = pTsMetaData->GetOverlapStartTime();
+    dOverlapSize  = pTsMetaData->GetOverlapDuration();
+  }
+
+  /// Print warning in first TS if time window borders out of potential overlap
+  if ((0.0 < fdEarliestTimeWinBeg && dOverlapSize < fdLatestTimeWinEnd) || (dOverlapSize < fdWidestTimeWinRange)) {
+    LOG(warning) << "CbmAlgoBuildRawEvents::LoopOnSeeds => "
+                 << Form("Event window not fitting in TS overlap, risk of "
+                         "incomplete events: %f %f %f %f",
+                         fdEarliestTimeWinBeg, fdLatestTimeWinEnd, fdWidestTimeWinRange, dOverlapSize);
+  }  // if end of event window does not fit in overlap for a seed at edge of TS core
+
+  /// Define an acceptance window for the seeds in order to use the overlap
+  /// part of the TS to avoid incomplete events
+  if (fbIgnoreTsOverlap) {
+    fdSeedWindowBeg = dTsStartTime;
+    fdSeedWindowEnd = dOverlapStart;
+  }
+  else {
+    fdSeedWindowBeg = dTsStartTime + (0.0 < fdEarliestTimeWinBeg ? 0.0 : -fdEarliestTimeWinBeg);
+    fdSeedWindowEnd = dOverlapStart + (0.0 < fdEarliestTimeWinBeg ? 0.0 : -fdEarliestTimeWinBeg);
+  }
+}
+
+void CbmAlgoBuildRawEvents::BuildEvents()
+{
+  /// Call LoopOnSeed with proper template argument
+  switch (fRefDet.detId) {
+    case ECbmModuleId::kSts: {
+      LoopOnSeeds<CbmStsDigi>();
+      break;
+    }
+    case ECbmModuleId::kMuch: {
+      if (fbUseMuchBeamtimeDigi) { LoopOnSeeds<CbmMuchBeamTimeDigi>(); }
+      else {
+        LoopOnSeeds<CbmMuchDigi>();
+      }
+      break;
+    }
+    case ECbmModuleId::kTrd: {
+      LoopOnSeeds<CbmTrdDigi>();
+      break;
+    }
+    case ECbmModuleId::kTof: {
+      LoopOnSeeds<CbmTofDigi>();
+      break;
+    }
+    case ECbmModuleId::kRich: {
+      LoopOnSeeds<CbmRichDigi>();
+      break;
+    }
+    case ECbmModuleId::kPsd: {
+      LoopOnSeeds<CbmPsdDigi>();
+      break;
+    }
+    case ECbmModuleId::kT0: {
+      LoopOnSeeds<CbmTofDigi>();
+      break;
+    }
+    case ECbmModuleId::kNotExist: {  //explicit seed times
+      LoopOnSeeds<Double_t>();
+      break;
+    }
+    default: {
+      LOG(fatal) << "CbmAlgoBuildRawEvents::BuildEvents => "
+                 << "Trying to search event seeds with unsupported det: " << fRefDet.sName;
+      break;
+    }
+  }
+}
+
+template<>
+void CbmAlgoBuildRawEvents::LoopOnSeeds<Double_t>()
+{
+  if (ECbmModuleId::kNotExist == fRefDet.detId) {
+    const UInt_t uNbSeeds = fSeedTimes->size();
+    /// Loop on size of vector
+    for (UInt_t uSeed = 0; uSeed < uNbSeeds; ++uSeed) {
+      LOG(debug) << Form("Checking seed %6u / %6u", uSeed, uNbSeeds);
+      Double_t dTime = fSeedTimes->at(uSeed);
+
+      /// Check if seed in acceptance window (is this needed here?)
+      if (dTime < fdSeedWindowBeg) { continue; }
+      else if (fdSeedWindowEnd < dTime) {
+        break;
+      }
+      /// Check Seed and build event if needed
+      CheckSeed(dTime, uSeed);
+    }
+  }
+  else {
+    LOG(fatal) << "Trying to read explicit seeds while reference detector is set.";
+  }
+}
+
+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);
+    }
+  }
+  else {
+    const UInt_t uNbRefDigis = GetNofDigis(fRefDet.detId);
+    /// 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);
+      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);
+    }
+  }
+}
+
+Double_t CbmAlgoBuildRawEvents::GetSeedTimeWinRange()
+{
+  if (ECbmModuleId::kNotExist != fRefDet.detId) { return fRefDet.GetTimeWinRange(); }
+  else {
+    return fdSeedTimeWinEnd - fdSeedTimeWinBeg;
+  }
+}
+
+void CbmAlgoBuildRawEvents::CheckSeed(Double_t dSeedTime, UInt_t uSeedDigiIdx)
+{
+  /// If previous event valid and event overlap not allowed, check if we are in overlap
+  /// and react accordingly
+  if (nullptr != fCurrentEvent
+      && (EOverlapModeRaw::AllowOverlap != fOverMode || dSeedTime - fdPrevEvtTime < GetSeedTimeWinRange())
+      && dSeedTime - fdPrevEvtTime < fdWidestTimeWinRange) {
+    /// Within overlap range
+    switch (fOverMode) {
+      case EOverlapModeRaw::NoOverlap: {
+        /// No overlap allowed => reject
+        LOG(debug1) << "Reject seed due to overlap";
+        return;
+        break;
+      }
+      case EOverlapModeRaw::MergeOverlap: {
+        /// Merge overlap mode => do nothing and go on filling current event
+        break;
+      }
+      case EOverlapModeRaw::AllowOverlap: {
+        /// In allow overlap mode => reject only if reference det is in overlap
+        /// to avoid cloning events due to single seed cluster
+        LOG(debug1) << "Reject seed because part of cluster of previous one";
+        return;
+        break;
+      }
+    }
+  }  // if( prev Event exists and mode forbiden overlap present )
+  else {
+    /// Out of overlap range or in overlap allowed mode
+    /// => store previous event if not empty and create new one
+    if (nullptr != fCurrentEvent) {
+      /// TODO: store start time of current event ?
+      //        fCurrentEvent->SetStartTime( fPrevTime ); // Replace Seed time with time of first digi in event?
+      fCurrentEvent->SetEndTime(fdPrevEvtEndTime);
+      fEventVector.push_back(fCurrentEvent);
+      fuCurEv++;
+    }
+    fCurrentEvent = new CbmEvent(fuCurEv, dSeedTime, 0.);
+  }  // else of if( prev Event exists and mode forbiden overlap present )
+
+  if (fRefDet.detId != ECbmModuleId::kNotExist) {
+    /// If window open for reference detector, search for other reference Digis matching it
+    /// Otherwise only add the current seed
+    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);
+    }
+    else {
+      AddDigiToEvent(fRefDet, uSeedDigiIdx);
+    }
+  }
+
+  /// Search for matches for each detector in selection list
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    SearchMatches(dSeedTime, *det);
+  }
+
+  CheckTriggerCondition(dSeedTime);
+}
+
+void CbmAlgoBuildRawEvents::SearchMatches(Double_t dSeedTime, RawEventBuilderDetector& detMatch)
+{
+  switch (detMatch.detId) {
+    case ECbmModuleId::kSts: {
+      SearchMatches<CbmStsDigi>(dSeedTime, detMatch);
+      break;
+    }
+    case ECbmModuleId::kMuch: {
+      if (fbUseMuchBeamtimeDigi) { SearchMatches<CbmMuchBeamTimeDigi>(dSeedTime, detMatch); }
+      else {
+        SearchMatches<CbmMuchDigi>(dSeedTime, detMatch);
+      }
+      break;
+    }
+    case ECbmModuleId::kTrd: {
+      SearchMatches<CbmTrdDigi>(dSeedTime, detMatch);
+      break;
+    }
+    case ECbmModuleId::kTof: {
+      SearchMatches<CbmTofDigi>(dSeedTime, detMatch);
+      break;
+    }
+    case ECbmModuleId::kRich: {
+      SearchMatches<CbmRichDigi>(dSeedTime, detMatch);
+      break;
+    }
+    case ECbmModuleId::kPsd: {
+      SearchMatches<CbmPsdDigi>(dSeedTime, detMatch);
+      break;
+    }
+    case ECbmModuleId::kT0: {
+      SearchMatches<CbmTofDigi>(dSeedTime, detMatch);
+      break;
+    }
+    default: {
+      LOG(fatal) << "CbmAlgoBuildRawEvents::LoopOnSeeds => "
+                 << "Trying to search matches with unsupported det: " << detMatch.sName << std::endl
+                 << "You may want to add support for it in the method.";
+      break;
+    }
+  }
+}
+
+template<class DigiCheck>
+void CbmAlgoBuildRawEvents::SearchMatches(Double_t dSeedTime, RawEventBuilderDetector& detMatch)
+{
+  /// This algo relies on time sorted vectors for the selected detectors
+  UInt_t uLocalIndexStart = detMatch.fuStartIndex;
+  UInt_t uLocalIndexEnd   = detMatch.fuStartIndex;
+
+  /// Check the Digis until out of window
+  if (ECbmModuleId::kT0 == 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 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 {
+    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);
+      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;
+      }
+      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;
+  }
+
+  /// Update the StartIndex and EndIndex for the next event seed
+  detMatch.fuStartIndex = uLocalIndexStart;
+  detMatch.fuEndIndex   = uLocalIndexEnd;
+}
+
+void CbmAlgoBuildRawEvents::AddDigiToEvent(RawEventBuilderDetector& det, Int_t _entry)
+{
+  fCurrentEvent->AddData(det.dataType, _entry);
+}
+
+void CbmAlgoBuildRawEvents::CheckTriggerCondition(Double_t dSeedTime)
+{
+  /// Check if event is filling trigger conditions and clear it if not
+  if (HasTrigger(fCurrentEvent)) {
+    fdPrevEvtTime = dSeedTime;
+
+    /// In case of NoOverlap or MergeOverlap, we can and should start checking the next window
+    /// from end of current window in order to save CPU and avoid duplicating
+    if (EOverlapModeRaw::NoOverlap == fOverMode || EOverlapModeRaw::MergeOverlap == fOverMode) {
+      /// Update reference detector
+      if (fRefDet.detId != ECbmModuleId::kNotExist) { fRefDet.fuStartIndex = fRefDet.fuEndIndex; }
+      /// Loop on selection detectors
+      for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+        (*det).fuStartIndex = (*det).fuEndIndex;
+      }
+    }
+  }
+  else {
+    LOG(debug1) << "Reject seed due to Trigger requirements";
+    delete fCurrentEvent;
+    fCurrentEvent = nullptr;  /// delete does NOT set a pointer to nullptr...
+  }
+}
+
+Bool_t CbmAlgoBuildRawEvents::HasTrigger(CbmEvent* event)
+{
+  /// Check first reference detector
+  if (fRefDet.detId != ECbmModuleId::kNotExist) {
+    if (kFALSE == CheckTriggerConditions(event, fRefDet)) { return kFALSE; }
+  }
+  /// Loop on selection detectors
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    if (kFALSE == CheckTriggerConditions(event, *det)) return kFALSE;
+  }
+  /// All Ok, trigger is there
+  return kTRUE;
+}
+
+Bool_t CbmAlgoBuildRawEvents::CheckTriggerConditions(CbmEvent* event, RawEventBuilderDetector& det)
+{
+  /// Check if both Trigger conditions disabled for this detector
+  if (0 == det.fuTriggerMinDigis && det.fiTriggerMaxDigis < 0) { return kTRUE; }
+
+  /// Check if detector present
+  if (!CheckDataAvailable(det.detId)) {
+    LOG(warning) << "Event does not have digis storage for " << det.sName
+                 << " while the following trigger min/max are defined: " << det.fuTriggerMinDigis << " "
+                 << det.fiTriggerMaxDigis;
+    return kFALSE;
+  }
+
+  /// Check trigger rejection by minimal number or absence
+  const Int_t iNbDigis = event->GetNofData(det.dataType);
+  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;
+    return kFALSE;
+  }
+
+  /// Check trigger rejection by maximal number
+  else if (0 < det.fiTriggerMaxDigis && det.fiTriggerMaxDigis < iNbDigis) {
+    LOG(debug2) << "Event Has too many digis: " << iNbDigis << " vs " << det.fiTriggerMaxDigis << " for " << det.sName;
+    return kFALSE;
+  }
+  else {
+    return kTRUE;
+  }
+}
+
+//----------------------------------------------------------------------
+
+Bool_t CbmAlgoBuildRawEvents::CheckDataAvailable(RawEventBuilderDetector& det)
+{
+  if (!CheckDataAvailable(det.detId)) {
+    LOG(info) << "No " << det.sName << " digi input found.";
+    return kFALSE;
+  }
+  return kTRUE;
+}
+
+bool CbmAlgoBuildRawEvents::CheckDataAvailable(ECbmModuleId detId)
+{
+  switch (detId) {
+    case ECbmModuleId::kSts: {
+      return fStsDigis != nullptr;
+    }
+    case ECbmModuleId::kMuch: {
+      if (fbUseMuchBeamtimeDigi) { return fMuchBeamTimeDigis != nullptr; }
+      else {
+        return fMuchDigis != nullptr;
+      }
+    }
+    case ECbmModuleId::kTrd: {
+      return fTrdDigis != nullptr;
+    }
+    case ECbmModuleId::kTof: {
+      return fTofDigis != nullptr;
+    }
+    case ECbmModuleId::kRich: {
+      return fRichDigis != nullptr;
+    }
+    case ECbmModuleId::kPsd: {
+      return fPsdDigis != nullptr;
+    }
+    case ECbmModuleId::kT0: {
+      return fT0DigiVec != nullptr;
+    }
+    default: {
+      LOG(fatal) << "CbmAlgoBuildRawEvents::CheckDataAvailable => "
+                 << "Unsupported detector.";
+      return -1;
+    }
+  }
+}
+
+UInt_t CbmAlgoBuildRawEvents::GetNofDigis(ECbmModuleId detId)
+{
+  switch (detId) {
+    case ECbmModuleId::kSts: {
+      return fStsDigis->size();
+    }
+    case ECbmModuleId::kMuch: {
+      if (fbUseMuchBeamtimeDigi) { return fMuchBeamTimeDigis->size(); }
+      else {
+        return fMuchDigis->size();
+      }
+    }
+    case ECbmModuleId::kTrd: {
+      return fTrdDigis->size();
+    }
+    case ECbmModuleId::kTof: {
+      return fTofDigis->size();
+    }
+    case ECbmModuleId::kRich: {
+      return fRichDigis->size();
+    }
+    case ECbmModuleId::kPsd: {
+      return fPsdDigis->size();
+    }
+    case ECbmModuleId::kT0: {
+      return fT0DigiVec->size();  //what to do here? Not in digi manager.
+    }
+    default: {
+      LOG(fatal) << "CbmAlgoBuildRawEvents::GetNofDigis => "
+                 << "Trying to get digi number with unsupported detector.";
+      return -1;
+    }
+  }
+}
+
+template<>
+const CbmStsDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi)
+{
+  return &((*fStsDigis)[uDigi]);
+}
+template<>
+const CbmMuchBeamTimeDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi)
+{
+  return &((*fMuchBeamTimeDigis)[uDigi]);
+}
+template<>
+const CbmMuchDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi)
+{
+  return &((*fMuchDigis)[uDigi]);
+}
+template<>
+const CbmTrdDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi)
+{
+  return &((*fTrdDigis)[uDigi]);
+}
+template<>
+const CbmTofDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi)
+{
+  return &((*fTofDigis)[uDigi]);
+}
+template<>
+const CbmRichDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi)
+{
+  return &((*fRichDigis)[uDigi]);
+}
+template<>
+const CbmPsdDigi* CbmAlgoBuildRawEvents::GetDigi(UInt_t uDigi)
+{
+  return &((*fPsdDigis)[uDigi]);
+}
+
+//----------------------------------------------------------------------
+void CbmAlgoBuildRawEvents::CreateHistograms()
+{
+  fhEventTime = new TH1F("hEventTime", "seed time of the events; Seed time [s]; Events", 60000, 0, 600);
+  fhEventDt =
+    new TH1F("fhEventDt", "interval in seed time of consecutive events; Seed time [s]; Events", 2100, -100.5, 1999.5);
+  fhEventSize        = new TH1F("hEventSize", "nb of all  digis in the event; Nb Digis []; Events []", 10000, 0, 10000);
+  fhNbDigiPerEvtTime = new TH2I("hNbDigiPerEvtTime",
+                                "nb of all  digis per event vs seed time of the events; Seed time "
+                                "[s]; Nb Digis []; Events []",
+                                600, 0, 600, 1000, 0, 10000);
+
+  /// Loop on selection detectors
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    /// In case name not provided, do not create the histo to avoid name conflicts!
+    if ("Invalid" == (*det).sName) {
+      fvhNbDigiPerEvtTimeDet.push_back(nullptr);
+      continue;
+    }
+
+    fvhNbDigiPerEvtTimeDet.push_back(new TH2I(Form("hNbDigiPerEvtTime%s", (*det).sName.data()),
+                                              Form("nb of %s digis per event vs seed time of the events; Seed time "
+                                                   "[s]; Nb Digis []; Events []",
+                                                   (*det).sName.data()),
+                                              600, 0, 600, 4000, 0, 4000));
+  }
+
+  AddHistoToVector(fhEventTime, "evtbuild");
+  AddHistoToVector(fhEventDt, "evtbuild");
+  AddHistoToVector(fhEventSize, "evtbuild");
+  AddHistoToVector(fhNbDigiPerEvtTime, "evtbuild");
+  for (std::vector<TH2*>::iterator itHist = fvhNbDigiPerEvtTimeDet.begin(); itHist != fvhNbDigiPerEvtTimeDet.end();
+       ++itHist) {
+    if (nullptr != (*itHist)) { AddHistoToVector((*itHist), "evtbuild"); }
+  }
+}
+
+void CbmAlgoBuildRawEvents::FillHistos()
+{
+  Double_t dPreEvtTime = -1.0;
+  for (CbmEvent* evt : fEventVector) {
+    fhEventTime->Fill(evt->GetStartTime() * 1e-9);
+    if (0.0 <= dPreEvtTime) { fhEventDt->Fill(evt->GetStartTime() - dPreEvtTime); }
+    fhEventSize->Fill(evt->GetNofData());
+    fhNbDigiPerEvtTime->Fill(evt->GetStartTime() * 1e-9, evt->GetNofData());
+
+    /// Loop on selection detectors
+    for (UInt_t uDetIdx = 0; uDetIdx < fvDets.size(); ++uDetIdx) {
+      if (nullptr == fvhNbDigiPerEvtTimeDet[uDetIdx]) continue;
+      fvhNbDigiPerEvtTimeDet[uDetIdx]->Fill(evt->GetStartTime() * 1e-9, evt->GetNofData(fvDets[uDetIdx].dataType));
+    }
+    dPreEvtTime = evt->GetStartTime();
+  }
+}
+
+void CbmAlgoBuildRawEvents::ResetHistograms(Bool_t /*bResetTime*/)
+{
+  fhEventTime->Reset();
+  fhEventDt->Reset();
+  fhEventSize->Reset();
+
+  fhNbDigiPerEvtTime->Reset();
+  /// Loop on histograms
+  for (std::vector<TH2*>::iterator itHist = fvhNbDigiPerEvtTimeDet.begin(); itHist != fvhNbDigiPerEvtTimeDet.end();
+       ++itHist) {
+    (*itHist)->Reset();
+  }
+  /*
+   if( kTRUE == bResetTime )
+   {
+      /// Also reset the Start time for the evolution plots!
+      fdStartTime = -1.0;
+   } 
+   */
+}
+
+void CbmAlgoBuildRawEvents::SetReferenceDetector(ECbmModuleId refDet, ECbmDataType dataTypeIn, std::string sNameIn,
+                                                 UInt_t uTriggerMinDigisIn, Int_t iTriggerMaxDigisIn,
+                                                 Double_t fdTimeWinBegIn, Double_t fdTimeWinEndIn)
+{
+  /// FIXME: Deprecated method to be removed later. For now create temp object.
+  SetReferenceDetector(RawEventBuilderDetector(refDet, dataTypeIn, sNameIn, uTriggerMinDigisIn, iTriggerMaxDigisIn,
+                                               fdTimeWinBegIn, fdTimeWinEndIn));
+}
+void CbmAlgoBuildRawEvents::AddDetector(ECbmModuleId selDet, ECbmDataType dataTypeIn, std::string sNameIn,
+                                        UInt_t uTriggerMinDigisIn, Int_t iTriggerMaxDigisIn, Double_t fdTimeWinBegIn,
+                                        Double_t fdTimeWinEndIn)
+{
+  /// FIXME: Deprecated method to be removed later. For now create temp object.
+  AddDetector(RawEventBuilderDetector(selDet, dataTypeIn, sNameIn, uTriggerMinDigisIn, iTriggerMaxDigisIn,
+                                      fdTimeWinBegIn, fdTimeWinEndIn));
+}
+
+void CbmAlgoBuildRawEvents::SetReferenceDetector(RawEventBuilderDetector refDetIn)
+{
+  /// Loop on selection detectors
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    if ((*det) == refDetIn) {
+      LOG(warning) << "CbmAlgoBuildRawEvents::SetReferenceDetector => "
+                      "Reference detector already in selection detector list!"
+                   << refDetIn.sName;
+      LOG(warning) << "                                                         => "
+                      "It will be automatically removed from selection detector list!";
+      LOG(warning) << "                                                         => "
+                      "Please also remember to update the selection windows to store "
+                      "clusters!";
+      RemoveDetector(refDetIn);
+    }
+  }
+
+  if (fRefDet == refDetIn) {
+    LOG(warning) << "CbmAlgoBuildRawEvents::SetReferenceDetector => "
+                    "Doing nothing, identical reference detector already in use";
+  }
+  else {
+    LOG(info) << "CbmAlgoBuildRawEvents::SetReferenceDetector => "
+              << "Replacing " << fRefDet.sName << " with " << refDetIn.sName << " as reference detector";
+    LOG(warning) << "                                                         => "
+                    "You may want to use AddDetector after this command to add in "
+                    "selection "
+                 << refDetIn.sName;
+    LOG(warning) << "                                                         => "
+                    "Please also remember to update the selection windows!";
+  }
+  fRefDet = refDetIn;
+
+  /// Update the variables storing the earliest and latest time window boundaries
+  UpdateTimeWinBoundariesExtrema();
+  /// Update the variable storing the size if widest time window for overlap detection
+  UpdateWidestTimeWinRange();
+}
+
+void CbmAlgoBuildRawEvents::AddDetector(RawEventBuilderDetector selDet)
+{
+  if (fRefDet == selDet) {
+    LOG(fatal) << "CbmAlgoBuildRawEvents::AddDetector => Cannot "
+                  "add the reference detector as selection detector!"
+               << std::endl
+               << "=> Maybe first change the reference detector with "
+                  "SetReferenceDetector?";
+  }
+
+  /// Loop on selection detectors
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    if ((*det) == selDet) {
+      LOG(warning) << "CbmAlgoBuildRawEvents::AddDetector => "
+                      "Doing nothing, selection detector already in list!"
+                   << selDet.sName;
+      return;
+    }
+  }
+  fvDets.push_back(selDet);
+
+  /// Update the variables storing the earliest and latest time window boundaries
+  UpdateTimeWinBoundariesExtrema();
+  /// Update the variable storing the size if widest time window for overlap detection
+  UpdateWidestTimeWinRange();
+}
+
+void CbmAlgoBuildRawEvents::RemoveDetector(RawEventBuilderDetector selDet)
+{
+  /// Loop on selection detectors
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    if ((*det) == selDet) {
+      fvDets.erase(det);
+      return;
+    }
+  }
+  LOG(warning) << "CbmAlgoBuildRawEvents::RemoveDetector => Doing "
+                  "nothing, selection detector not in list!"
+               << selDet.sName;
+}
+
+void CbmAlgoBuildRawEvents::SetTriggerMinNumber(ECbmModuleId selDet, UInt_t uVal)
+{
+  /// Check first if reference detector
+  if (fRefDet.detId == selDet) {
+    fRefDet.fuTriggerMinDigis = uVal;
+    LOG(debug) << "Set Trigger min limit for " << fRefDet.sName << " to " << uVal;
+    return;
+  }
+
+  /// Loop on selection detectors
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    if ((*det).detId == selDet) {
+      (*det).fuTriggerMinDigis = uVal;
+      LOG(debug) << "Set Trigger min limit for " << (*det).sName << " to " << uVal;
+      return;
+    }
+  }
+  LOG(warning) << "CbmAlgoBuildRawEvents::SetTriggerMinNumber => "
+                  "Doing nothing, detector neither reference nor in selection list!"
+               << selDet;
+}
+
+void CbmAlgoBuildRawEvents::SetTriggerMaxNumber(ECbmModuleId selDet, Int_t iVal)
+{
+  /// Check first if reference detector
+  if (fRefDet.detId == selDet) {
+    fRefDet.fiTriggerMaxDigis = iVal;
+    LOG(debug) << "Set Trigger min limit for " << fRefDet.sName << " to " << iVal;
+    return;
+  }
+
+  /// Loop on selection detectors
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    if ((*det).detId == selDet) {
+      (*det).fiTriggerMaxDigis = iVal;
+      LOG(debug) << "Set Trigger min limit for " << (*det).sName << " to " << iVal;
+      return;
+    }
+  }
+  LOG(warning) << "CbmAlgoBuildRawEvents::SetTriggerMaxNumber => "
+                  "Doing nothing, detector neither reference nor in selection list!"
+               << selDet;
+}
+
+void CbmAlgoBuildRawEvents::SetTriggerWindow(ECbmModuleId selDet, Double_t dWinBeg, Double_t dWinEnd)
+{
+  /// Check if valid time window: end strictly after beginning
+  if (dWinEnd <= dWinBeg) {
+    LOG(fatal) << "CbmAlgoBuildRawEvents::SetTriggerWindow => "
+                  "Invalid time window: [ "
+               << dWinBeg << ", " << dWinEnd << " ]";
+  }
+
+  Bool_t bFound = kFALSE;
+  /// Check first if reference detector
+  if (fRefDet.detId == selDet) {
+    fRefDet.fdTimeWinBeg = dWinBeg;
+    fRefDet.fdTimeWinEnd = dWinEnd;
+    bFound               = kTRUE;
+  }
+
+  /// Loop on selection detectors
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    if ((*det).detId == selDet) {
+      (*det).fdTimeWinBeg = dWinBeg;
+      (*det).fdTimeWinEnd = dWinEnd;
+      bFound              = kTRUE;
+    }
+  }
+
+  if (kFALSE == bFound) {
+    LOG(warning) << "CbmAlgoBuildRawEvents::SetTriggerWindow => "
+                    "Doing nothing, detector neither reference nor in selection list!"
+                 << selDet;
+  }
+
+  /// Update the variables storing the earliest and latest time window boundaries
+  UpdateTimeWinBoundariesExtrema();
+  /// Update the variable storing the size if widest time window for overlap detection
+  UpdateWidestTimeWinRange();
+}
+
+void CbmAlgoBuildRawEvents::UpdateTimeWinBoundariesExtrema()
+{
+  /// Initialize with reference detector or explicit times
+  if (fRefDet.detId != ECbmModuleId::kNotExist) {
+    fdEarliestTimeWinBeg = fRefDet.fdTimeWinBeg;
+    fdLatestTimeWinEnd   = fRefDet.fdTimeWinEnd;
+  }
+  else {
+    fdEarliestTimeWinBeg = fdSeedTimeWinBeg;
+    fdLatestTimeWinEnd   = fdSeedTimeWinEnd;
+  }
+
+  /// Loop on selection detectors
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    fdEarliestTimeWinBeg = std::min(fdEarliestTimeWinBeg, (*det).fdTimeWinBeg);
+    fdLatestTimeWinEnd   = std::max(fdLatestTimeWinEnd, (*det).fdTimeWinEnd);
+  }
+}
+
+void CbmAlgoBuildRawEvents::UpdateWidestTimeWinRange()
+{
+  /// Initialize with reference detector
+  fdWidestTimeWinRange = GetSeedTimeWinRange();
+
+  /// Loop on selection detectors
+  for (std::vector<RawEventBuilderDetector>::iterator det = fvDets.begin(); det != fvDets.end(); ++det) {
+    fdWidestTimeWinRange = std::max(fdWidestTimeWinRange, (*det).fdTimeWinEnd - (*det).fdTimeWinBeg);
+  }
+}
+
+ClassImp(CbmAlgoBuildRawEvents)
diff --git a/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ab53eb48c0b14da8ccbf946512c28c81826f2c7
--- /dev/null
+++ b/reco/eventbuilder/digis/CbmAlgoBuildRawEvents.h
@@ -0,0 +1,322 @@
+/********************************************************************************
+ *    Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH    *
+ *                                                                              *
+ *              This software is distributed under the terms of the             *
+ *              GNU Lesser General Public Licence (LGPL) version 3,             *
+ *                  copied verbatim in the file "LICENSE"                       *
+ ********************************************************************************/
+#ifndef CBMALGOBUILDRAWEVENTS_H
+#define CBMALGOBUILDRAWEVENTS_H
+
+/// CBM headers
+#include "CbmMuchBeamTimeDigi.h"
+#include "CbmMuchDigi.h"
+#include "CbmPsdDigi.h"
+#include "CbmRichDigi.h"
+#include "CbmStsDigi.h"
+#include "CbmTofDigi.h"
+#include "CbmTrdDigi.h"
+
+/// FAIRROOT headers
+#include "FairTask.h"
+
+/// FAIRSOFT headers (geant, boost, ...)
+
+/// C/C++ headers
+#include <tuple>
+
+#include <boost/any.hpp>
+
+#include <array>
+#include <map>
+#include <set>
+#include <vector>
+
+class TimesliceMetaData;
+class CbmEvent;
+class TClonesArray;
+class TH1;
+class TH2;
+class TNamed;
+class TCanvas;
+
+enum class EOverlapModeRaw
+{
+  NoOverlap,
+  MergeOverlap,
+  AllowOverlap
+};
+
+class RawEventBuilderDetector {
+public:
+  RawEventBuilderDetector() = default;
+
+  RawEventBuilderDetector(ECbmModuleId detIdIn, ECbmDataType dataTypeIn, std::string sNameIn)
+    : detId {detIdIn}
+    , dataType {dataTypeIn}
+    , sName {sNameIn}
+  {
+  }
+
+  RawEventBuilderDetector(ECbmModuleId detIdIn, ECbmDataType dataTypeIn, std::string sNameIn, UInt_t uTriggerMinDigisIn,
+                          Int_t iTriggerMaxDigisIn, Double_t fdTimeWinBegIn, Double_t fdTimeWinEndIn)
+    : RawEventBuilderDetector(detIdIn, dataTypeIn, sNameIn)
+  {
+    fuTriggerMinDigis = uTriggerMinDigisIn;
+    fiTriggerMaxDigis = iTriggerMaxDigisIn;
+    fdTimeWinBeg      = fdTimeWinBegIn;
+    fdTimeWinEnd      = fdTimeWinEndIn;
+  }
+
+  bool operator==(const RawEventBuilderDetector& other) const { return (other.detId == this->detId); }
+  bool operator!=(const RawEventBuilderDetector& other) const { return (other.detId != this->detId); }
+
+  Double_t GetTimeWinRange() { return fdTimeWinEnd - fdTimeWinBeg; }
+
+  /// Settings
+  ECbmModuleId detId    = ECbmModuleId::kNotExist;
+  ECbmDataType dataType = ECbmDataType::kUnknown;
+  std::string sName     = "Invalid";
+  /// Minimum number of T0 digis needed to generate a trigger, 0 means don't use for trigger generation
+  UInt_t fuTriggerMinDigis = 0;
+  /// Maximum number of digis per detector to generate an event, -1 means no cut, 0 means anti-coinc trigger
+  Int_t fiTriggerMaxDigis = -1;
+  /// Selection Window
+  Double_t fdTimeWinBeg = -100;
+  Double_t fdTimeWinEnd = 100;
+  /// Book-keeping variables
+  UInt_t fuStartIndex = 0;
+  UInt_t fuEndIndex   = 0;
+};
+
+/// Pre-defined detector types
+static const RawEventBuilderDetector kRawEventBuilderDetSts =
+  RawEventBuilderDetector(ECbmModuleId::kSts, ECbmDataType::kStsDigi, "Sts");
+static const RawEventBuilderDetector kRawEventBuilderDetMuch =
+  RawEventBuilderDetector(ECbmModuleId::kMuch, ECbmDataType::kMuchDigi, "Much");
+static const RawEventBuilderDetector kRawEventBuilderDetTrd =
+  RawEventBuilderDetector(ECbmModuleId::kTrd, ECbmDataType::kTrdDigi, "Trd");
+static const RawEventBuilderDetector kRawEventBuilderDetTof =
+  RawEventBuilderDetector(ECbmModuleId::kTof, ECbmDataType::kTofDigi, "Tof");
+static const RawEventBuilderDetector kRawEventBuilderDetRich =
+  RawEventBuilderDetector(ECbmModuleId::kRich, ECbmDataType::kRichDigi, "Rich");
+static const RawEventBuilderDetector kRawEventBuilderDetPsd =
+  RawEventBuilderDetector(ECbmModuleId::kPsd, ECbmDataType::kPsdDigi, "Psd");
+static const RawEventBuilderDetector kRawEventBuilderDetT0 =
+  RawEventBuilderDetector(ECbmModuleId::kT0, ECbmDataType::kT0Digi, "T0");
+static const RawEventBuilderDetector kRawEventBuilderDetUndef = RawEventBuilderDetector();
+
+
+class CbmAlgoBuildRawEvents {
+public:
+  /** Default constructor **/
+  CbmAlgoBuildRawEvents() = default;
+
+  CbmAlgoBuildRawEvents(const CbmAlgoBuildRawEvents&) = delete;
+  CbmAlgoBuildRawEvents operator=(const CbmAlgoBuildRawEvents&) = delete;
+
+  /** Destructor **/
+  ~CbmAlgoBuildRawEvents() {};
+
+  /** Initiliazation at the beginning of a run **/
+  Bool_t InitAlgo();
+
+  /** Executed for each TS. **/
+  void ProcessTs();
+
+  /** Finish called at the end of the run **/
+  void Finish();
+
+  void SetFillHistos(Bool_t var) { fbFillHistos = var; }
+  void ResetHistograms(Bool_t bResetTime = kTRUE);
+
+  void SetReferenceDetector(ECbmModuleId refDet, ECbmDataType dataTypeIn, std::string sNameIn,
+                            UInt_t uTriggerMinDigisIn = 0, Int_t iTriggerMaxDigisIn = -1,
+                            Double_t fdTimeWinBegIn = -100, Double_t fdTimeWinEndIn = 100);
+  void AddDetector(ECbmModuleId selDet, ECbmDataType dataTypeIn, std::string sNameIn, UInt_t uTriggerMinDigisIn = 0,
+                   Int_t iTriggerMaxDigisIn = -1, Double_t fdTimeWinBegIn = -100, Double_t fdTimeWinEndIn = 100);
+
+  void SetReferenceDetector(RawEventBuilderDetector refDetIn);
+  void AddDetector(RawEventBuilderDetector selDet);
+  void RemoveDetector(RawEventBuilderDetector selDet);
+
+  void SetTriggerMinNumber(ECbmModuleId selDet, UInt_t uVal);
+  void SetTriggerMaxNumber(ECbmModuleId selDet, Int_t iVal);
+  void SetTriggerWindow(ECbmModuleId selDet, Double_t dWinBeg, Double_t dWinEnd);
+
+  void SetTsParameters(Double_t dTsStartTime, Double_t dTsLength, Double_t dTsOverLength)
+  {
+    fdTsStartTime  = dTsStartTime;
+    fdTsLength     = dTsLength;
+    fdTsOverLength = dTsOverLength;
+  }
+
+  void SetSeedTimeWindow(Double_t timeWinBeg, Double_t timeWinEnd)
+  {
+    fdSeedTimeWinBeg = timeWinBeg;
+    fdSeedTimeWinEnd = timeWinEnd;
+    UpdateTimeWinBoundariesExtrema();
+    UpdateWidestTimeWinRange();
+  }
+
+  /// Control flags
+  void SetEventOverlapMode(EOverlapModeRaw mode) { fOverMode = mode; }
+  void SetIgnoreTsOverlap(Bool_t bFlagIn = kTRUE) { fbIgnoreTsOverlap = bFlagIn; }
+
+  void ChangeMuchBeamtimeDigiFlag(Bool_t bFlagIn = kFALSE) { fbUseMuchBeamtimeDigi = bFlagIn; }
+
+  /// For monitor algos
+  void AddHistoToVector(TNamed* pointer, std::string sFolder = "")
+  {
+    fvpAllHistoPointers.push_back(std::pair<TNamed*, std::string>(pointer, sFolder));
+  }
+  std::vector<std::pair<TNamed*, std::string>> GetHistoVector() { return fvpAllHistoPointers; }
+  void AddCanvasToVector(TCanvas* pointer, std::string sFolder = "")
+  {
+    fvpAllCanvasPointers.push_back(std::pair<TCanvas*, std::string>(pointer, sFolder));
+  }
+  std::vector<std::pair<TCanvas*, std::string>> GetCanvasVector() { return fvpAllCanvasPointers; }
+
+  /// Set digi containers
+  void SetT0Digis(const std::vector<CbmTofDigi>* T0DigiVec) { fT0DigiVec = T0DigiVec; }
+  void SetStsDigis(std::vector<CbmStsDigi>* StsDigis) { fStsDigis = StsDigis; }
+  void SetMuchDigis(std::vector<CbmMuchDigi>* MuchDigis) { fMuchDigis = MuchDigis; }
+  void SetTrdDigis(std::vector<CbmTrdDigi>* TrdDigis) { fTrdDigis = TrdDigis; }
+  void SetTofDigis(std::vector<CbmTofDigi>* TofDigis) { fTofDigis = TofDigis; }
+  void SetRichDigis(std::vector<CbmRichDigi>* RichDigis) { fRichDigis = RichDigis; }
+  void SetPsdDigis(std::vector<CbmPsdDigi>* PsdDigis) { fPsdDigis = PsdDigis; }
+  void SetMuchBeamTimeDigis(std::vector<CbmMuchBeamTimeDigi>* MuchBeamTimeDigis)
+  {
+    fMuchBeamTimeDigis = MuchBeamTimeDigis;
+  }
+
+  void SetSeedTimes(std::vector<Double_t>* SeedTimes) { fSeedTimes = SeedTimes; }
+
+  /// Data output access
+  std::vector<CbmEvent*>& GetEventVector() { return fEventVector; }
+  void ClearEventVector();
+
+private:
+  /// Internal methods
+  Bool_t CheckDataAvailable(RawEventBuilderDetector& det);
+  void InitTs();
+  void InitSeedWindow();
+  void BuildEvents();
+
+  void CreateHistograms();
+  void FillHistos();
+
+  template<class DigiSeed>
+  void LoopOnSeeds();
+
+  void CheckSeed(Double_t dSeedTime, UInt_t uSeedDigiIdx);
+  void CheckTriggerCondition(Double_t dSeedTime);
+
+  template<class DigiCheck>
+  void SearchMatches(Double_t dSeedTime, RawEventBuilderDetector& detMatch);
+  void SearchMatches(Double_t dSeedTime, RawEventBuilderDetector& detMatch);
+  void AddDigiToEvent(RawEventBuilderDetector& det, Int_t uIdx);
+  Bool_t HasTrigger(CbmEvent*);
+  Bool_t CheckTriggerConditions(CbmEvent* event, RawEventBuilderDetector& det);
+
+  void UpdateTimeWinBoundariesExtrema();
+  void UpdateWidestTimeWinRange();
+
+  /// Constants
+  static constexpr Double_t kdDefaultTimeWinBeg = -100.0;
+  static constexpr Double_t kdDefaultTimeWinEnd = 100.0;
+
+  /// User parameters
+  /// Control flags
+  Bool_t fbIgnoreTsOverlap = kFALSE;     //! Ignore data in Overlap part of the TS
+  Bool_t fbFillHistos {kTRUE};           //! Switch ON/OFF filling of histograms
+  Bool_t fbUseMuchBeamtimeDigi = kTRUE;  //! Switch between MUCH digi classes
+    /// Event building mode and detectors selection
+  EOverlapModeRaw fOverMode {EOverlapModeRaw::AllowOverlap};
+
+  RawEventBuilderDetector fRefDet             = RawEventBuilderDetector(ECbmModuleId::kT0, ECbmDataType::kT0Digi, "T0");
+  std::vector<RawEventBuilderDetector> fvDets = {
+    RawEventBuilderDetector(ECbmModuleId::kSts, ECbmDataType::kStsDigi, "kSts"),
+    RawEventBuilderDetector(ECbmModuleId::kMuch, ECbmDataType::kMuchDigi, "kMuch"),
+    RawEventBuilderDetector(ECbmModuleId::kTrd, ECbmDataType::kTrdDigi, "kTrd"),
+    RawEventBuilderDetector(ECbmModuleId::kTof, ECbmDataType::kTofDigi, "kTof"),
+    RawEventBuilderDetector(ECbmModuleId::kRich, ECbmDataType::kRichDigi, "kRich"),
+    RawEventBuilderDetector(ECbmModuleId::kPsd, ECbmDataType::kPsdDigi, "kPsd")};
+
+  Double_t fdEarliestTimeWinBeg = kdDefaultTimeWinBeg;
+  Double_t fdLatestTimeWinEnd   = kdDefaultTimeWinEnd;
+  Double_t fdWidestTimeWinRange = kdDefaultTimeWinEnd - kdDefaultTimeWinBeg;
+  ///Seed window
+  Double_t fdSeedWindowBeg = 0;
+  Double_t fdSeedWindowEnd = 0;
+
+  Double_t fdTsStartTime  = -1;
+  Double_t fdTsLength     = -1;
+  Double_t fdTsOverLength = -1;
+
+  /// Data input
+  /// FIXME: usage of CbmDigiManager in FairMq context?!?
+  ///        => Maybe by registering vector (or vector reference) to ioman in Device?
+  //CbmDigiManager* fDigiMan                  = nullptr;  //!
+  TClonesArray* fTimeSliceMetaDataArray = nullptr;  //!
+  const TimesliceMetaData* pTsMetaData  = nullptr;
+
+  const std::vector<CbmTofDigi>* fT0DigiVec                  = nullptr;
+  const std::vector<CbmMuchDigi>* fMuchDigis                 = nullptr;
+  const std::vector<CbmMuchBeamTimeDigi>* fMuchBeamTimeDigis = nullptr;
+  const std::vector<CbmStsDigi>* fStsDigis                   = nullptr;
+  const std::vector<CbmTrdDigi>* fTrdDigis                   = nullptr;
+  const std::vector<CbmTofDigi>* fTofDigis                   = nullptr;
+  const std::vector<CbmRichDigi>* fRichDigis                 = nullptr;
+  const std::vector<CbmPsdDigi>* fPsdDigis                   = nullptr;
+
+  // If explicit seed times are supplied.
+  const std::vector<Double_t>* fSeedTimes = nullptr;
+  Double_t fdSeedTimeWinBeg               = -100.0;
+  Double_t fdSeedTimeWinEnd               = 100.0;
+
+  bool CheckDataAvailable(ECbmModuleId detId);
+  UInt_t GetNofDigis(ECbmModuleId detId);
+  template<class Digi>
+  const Digi* GetDigi(UInt_t uDigi);
+
+  Double_t GetSeedTimeWinRange();
+
+  /// Data ouptut
+  CbmEvent* fCurrentEvent             = nullptr;  //! pointer to the event which is currently build
+  std::vector<CbmEvent*> fEventVector = {};       //! vector with all created events
+
+  /// Monitoring histograms
+  /// => Pointers should be filled with TH1*, TH2*, TProfile*, ...
+  /// ==> To check if object N is of type T, use "T ObjectPointer = dynamic_cast<T>( fvpAllHistoPointers[N].first );" and check for nullptr
+  /// ==> To get back the original class name use "fvpAllHistoPointers[N].first->ClassName()" which returns a const char * (e.g. "TH1I")
+  /// ===> Usage example with feeding a THttpServer:
+  /// ===> #include "TH2.h"
+  /// ===> std::string sClassName = vHistos[ uHisto ].first.ClassName();
+  /// ===> if( !strncmp( sClassName, "TH1", 3 ) )
+  /// ===>    server->Register( vHistos[ uHisto ].second.data(), dynamic_cast< TH1 * >(vHistos[ uHisto ].first) );
+  /// ===> else if( !strncmp( sClassName, "TH2", 3 ) )
+  /// ===>    server->Register( vHistos[ uHisto ].second.data(), dynamic_cast< TH2 * >(vHistos[ uHisto ].first) );
+  std::vector<std::pair<TNamed*, std::string>>
+    fvpAllHistoPointers;  //! Vector of pointers to histograms + optional folder name
+  std::vector<std::pair<TCanvas*, std::string>>
+    fvpAllCanvasPointers;  //! Vector of pointers to canvases + optional folder name
+
+  TH1* fhEventTime        = nullptr;  //! histogram with the seed time of the events
+  TH1* fhEventDt          = nullptr;  //! histogram with the interval in seed time of consecutive events
+  TH1* fhEventSize        = nullptr;  //! histogram with the nb of all  digis in the event
+  TH2* fhNbDigiPerEvtTime = nullptr;  //! histogram with the nb of all  digis per event vs seed time of the events
+  std::vector<TH2*> fvhNbDigiPerEvtTimeDet =
+    {};  //! histograms with the nb of digis in each detector per event vs seed time of the events
+
+  /// Internal state variables
+  UInt_t fuCurEv            = 0;   //! Event Counter
+  UInt_t fuErrors           = 0;   //! Error Counter
+  UInt_t fuNrTs             = 0;   //! Timeslice Counter
+  Double_t fdPrevEvtTime    = 0.;  //! Save previous time information
+  Double_t fdPrevEvtEndTime = 0.;  //! Save previous event last digi time information
+
+  ClassDefNV(CbmAlgoBuildRawEvents, 1);
+};
+
+#endif  // CBMALGOBUILDRAWEVENTS_H
diff --git a/reco/eventbuilder/digis/CbmBuildEventsQA.cxx b/reco/eventbuilder/digis/CbmBuildEventsQA.cxx
index 03158ba3ab8a7db0a4e903a9bcc9e27d939cc0ca..fe1ebea8f1ed7761411a264496705c92cc8c628c 100644
--- a/reco/eventbuilder/digis/CbmBuildEventsQA.cxx
+++ b/reco/eventbuilder/digis/CbmBuildEventsQA.cxx
@@ -5,14 +5,19 @@
 
 #include "CbmBuildEventsQA.h"
 
+#include "CbmDigiManager.h"
 #include "CbmEvent.h"
 #include "CbmLink.h"
 #include "CbmMatch.h"
+#include "CbmModuleList.h"
 #include "CbmStsDigi.h"
+
 #include "FairLogger.h"
 #include "FairRootManager.h"
+
 #include "TClonesArray.h"
 #include "TStopwatch.h"
+
 #include <cassert>
 #include <iomanip>
 #include <iostream>
@@ -22,12 +27,7 @@ using namespace std;
 
 
 // =====   Constructor   =====================================================
-CbmBuildEventsQA::CbmBuildEventsQA()
-  : FairTask("BuildEventsQA")
-  , fStsDigis(NULL)
-  , fStsDigiMatches(nullptr)
-  , fEvents(NULL)
-  , fNofEntries(0) {}
+CbmBuildEventsQA::CbmBuildEventsQA() : FairTask("BuildEventsQA"), fEvents(NULL), fNofEntries(0) {}
 // ===========================================================================
 
 
@@ -36,136 +36,210 @@ CbmBuildEventsQA::~CbmBuildEventsQA() {}
 // ===========================================================================
 
 
+// =====   Task initialisation   =============================================
+InitStatus CbmBuildEventsQA::Init()
+{
+
+  // --- Get FairRootManager instance
+  FairRootManager* ioman = FairRootManager::Instance();
+  assert(ioman);
+
+  // --- Get input array (CbmEvent)
+  fEvents = dynamic_cast<TClonesArray*>(ioman->GetObject("CbmEvent"));
+  if (nullptr == fEvents) {
+    LOG(fatal) << "CbmBuildEventsQA::Init"
+               << "No CbmEvent TClonesArray found!";
+  }
+
+  // --- DigiManager instance
+  fDigiMan = CbmDigiManager::Instance();
+  fDigiMan->Init();
+
+  // --- Check input data
+  for (ECbmModuleId system = ECbmModuleId::kMvd; system < ECbmModuleId::kNofSystems; ++system) {
+    if (fDigiMan->IsMatchPresent(system)) {
+      LOG(info) << GetName() << ": Found match branch for " << CbmModuleList::GetModuleNameCaps(system);
+      fSystems.push_back(system);
+    }
+  }
+  if (fSystems.empty()) {
+    LOG(fatal) << GetName() << ": No match branch found!";
+    return kFATAL;
+  }
+
+  return kSUCCESS;
+}
+// ===========================================================================
+
+
 // =====   Task execution   ==================================================
-void CbmBuildEventsQA::Exec(Option_t*) {
+void CbmBuildEventsQA::Exec(Option_t*)
+{
 
   // --- Time and counters
   TStopwatch timer;
   timer.Start();
-  Int_t nMCEvents = 0;
 
   // --- Event loop
   Int_t nEvents = fEvents->GetEntriesFast();
   for (Int_t iEvent = 0; iEvent < nEvents; iEvent++) {
+    //LOG(info) << "iEvent = " << iEvent << " , nEvents = " << nEvents;
     CbmEvent* event = (CbmEvent*) fEvents->At(iEvent);
 
     // --- Match event to MC
     MatchEvent(event);
+    if (event->GetMatch()->GetNofLinks() < 1) {
+      LOG(warning) << "No links in this event match object, skipping the event";
+      continue;
+    }  // if (-1 == event->GetMatch()->GetNofLinks())
     Int_t mcEventNr = event->GetMatch()->GetMatchedLink().GetEntry();
-    LOG(info) << GetName() << ": Event " << event->GetNumber()
-              << ", data objects : " << event->GetNofData()
-              << ", links: " << event->GetMatch()->GetNofLinks()
-              << ", matched MC event number " << mcEventNr;
-
-    // --- Counters
-    Int_t nDigis        = event->GetNofData(ECbmDataType::kStsDigi);
-    Int_t nDigiCorrect  = 0;
-    Int_t nLinks        = 0;
-    Int_t nLinksCorrect = 0;
-    nMCEvents += event->GetMatch()->GetNofLinks();
-
-    // --- Loop over STS digis
-    for (Int_t iDigi = 0; iDigi < nDigis; iDigi++) {
-      UInt_t index        = event->GetIndex(ECbmDataType::kStsDigi, iDigi);
-      CbmStsDigi* digi    = (CbmStsDigi*) fStsDigis->At(index);
-      CbmMatch* digiMatch = (CbmMatch*) fStsDigiMatches->At(index);
-      assert(digi);
-      assert(digiMatch);
-
-      // --- Check MC event of digi match
-      if (digiMatch->GetMatchedLink().GetEntry() == mcEventNr) nDigiCorrect++;
-
-      for (Int_t iLink = 0; iLink < digiMatch->GetNofLinks(); iLink++) {
-        Int_t entry = digiMatch->GetLink(iLink).GetEntry();
-        nLinks++;
-        if (entry == mcEventNr) nLinksCorrect++;
-      }  //# links in digi
-
-    }  //# digis
-
-
-    // --- QA output
-    LOG(info) << GetName() << ": correct digis " << nDigiCorrect << " / "
-              << nDigis << " = "
-              << 100. * Double_t(nDigiCorrect) / Double_t(nDigis)
-              << " %, correct digi links " << nLinksCorrect << " / " << nLinks
-              << " = " << 100. * Double_t(nLinksCorrect) / Double_t(nLinks)
-              << " % ";
-
-  }  //# events
-
+    LOG(info) << GetName() << ": Event " << event->GetNumber() << ", digis in event: " << event->GetNofData()
+              << ", links to MC events: " << event->GetMatch()->GetNofLinks() << ", matched MC event number "
+              << mcEventNr;
+
+    // --- Loop over all detector systems
+    for (ECbmModuleId& system : fSystems) {
+
+      // --- Skip system if no data branch or no match match present
+      if (!fDigiMan->IsPresent(system)) continue;
+      if (!fDigiMan->IsMatchPresent(system)) continue;
+
+      // --- Counters
+      Int_t nDigis        = event->GetNofData(GetDigiType(system));
+      Int_t nDigiCorrect  = 0;
+      Int_t nLinks        = 0;
+      Int_t nLinksCorrect = 0;
+
+      // --- Loop over digis in event
+      for (Int_t iDigi = 0; iDigi < nDigis; iDigi++) {
+        UInt_t index = event->GetIndex(GetDigiType(system), iDigi);
+
+        const CbmMatch* digiMatch = fDigiMan->GetMatch(system, index);
+        assert(digiMatch);
+
+        // --- Check MC event of digi match
+        if (digiMatch->GetNofLinks()) {
+          if (digiMatch->GetMatchedLink().GetEntry() == mcEventNr) nDigiCorrect++;
+        }
+
+        for (Int_t iLink = 0; iLink < digiMatch->GetNofLinks(); iLink++) {
+          Int_t entry = digiMatch->GetLink(iLink).GetEntry();
+          nLinks++;
+          if (entry == mcEventNr) nLinksCorrect++;
+        }  //# links in digi
+      }    //# digis
+
+      // --- Counters
+      Int_t totDigis      = fDigiMan->GetNofDigis(system);
+      Int_t totEventDigis = 0;
+
+      // --- Loop over all digis for the current system
+      for (Int_t iDigi = 0; iDigi < totDigis; iDigi++) {
+
+        // --- Get the event number through the match object
+        const CbmMatch* match = fDigiMan->GetMatch(system, iDigi);
+        assert(match);
+        Int_t mcEvent = -1;
+
+        if (match->GetNofLinks()) { mcEvent = match->GetMatchedLink().GetEntry(); }
+        //digi belongs to current event
+        if (mcEvent == mcEventNr) totEventDigis++;
+      }
+
+      // --- QA output
+      if (0 < nDigis) {
+        LOG(info) << GetName() << ": Detector " << CbmModuleList::GetModuleNameCaps(system);
+        LOG(info) << "Correct digis " << nDigiCorrect << " / " << nDigis << " = "
+                  << 100. * Double_t(nDigiCorrect) / Double_t(nDigis) << " %";
+        LOG(info) << "Correct digi links " << nLinksCorrect << " / " << nLinks << " = "
+                  << 100. * Double_t(nLinksCorrect) / Double_t(nLinks) << " % ";
+        LOG(info) << "Digi percentage found " << nDigiCorrect << " / " << totEventDigis << " = "
+                  << 100. * Double_t(nDigiCorrect) / Double_t(totEventDigis) << " % ";
+      }
+      else {
+        LOG(info) << GetName() << ": Detector " << CbmModuleList::GetModuleNameCaps(system)
+                  << ", no digis in this event";
+
+      }  // else of if( 0 < nDigis )
+    }    // systems
+  }      //# events
 
   // Timer and counters
   fNofEntries++;
   timer.Stop();
 
   // --- Execution log
-  LOG(info) << "+ " << setw(20) << GetName() << ": Entry " << setw(6) << right
-            << fNofEntries << ", real time " << fixed << setprecision(6)
-            << timer.RealTime() << " s, events: " << fEvents->GetEntriesFast()
-            << ", MC events: " << nMCEvents;
-}
-// ===========================================================================
-
-
-// =====   Task initialisation   =============================================
-InitStatus CbmBuildEventsQA::Init() {
-
-  // --- Get FairRootManager instance
-  FairRootManager* ioman = FairRootManager::Instance();
-  assert(ioman);
-
-  // --- Get input array (CbmEvent)
-  fEvents = dynamic_cast<TClonesArray*>(ioman->GetObject("CbmEvent"));
-  if (nullptr == fEvents) {
-    LOG(fatal) << "CbmBuildEventsQA::Init"
-               << "No CbmEvent TClonesArray found!";
-  }
-
-
-  // --- Get input array (CbmStsDigi)
-  fStsDigis = (TClonesArray*) ioman->GetObject("StsDigi");
-  assert(fStsDigis);
-
-  return kSUCCESS;
+  LOG(info) << "+ " << setw(20) << GetName() << ": Entry " << setw(6) << right << fNofEntries << ", real time " << fixed
+            << setprecision(6) << timer.RealTime() << " s, events: " << fEvents->GetEntriesFast();
 }
 // ===========================================================================
 
 
 // =====   Match event   =====================================================
-void CbmBuildEventsQA::MatchEvent(CbmEvent* event) {
-
-  // TODO: This functionality should later be moved to the class
-  // CbmMatchRecoToMC
+void CbmBuildEventsQA::MatchEvent(CbmEvent* event)
+{
 
   // --- Get event match object. If present, will be cleared first. If not,
   // --- it will be created.
   CbmMatch* match = event->GetMatch();
   if (!match) {
+    LOG(info) << "No match data found in event. Creating new.";
     match = new CbmMatch();
     event->SetMatch(match);
-  }  //? event has no match
-
-  // --- Loop over digis
-  for (Int_t iDigi = 0; iDigi < event->GetNofData(ECbmDataType::kStsDigi);
-       iDigi++) {
-    Int_t index         = event->GetIndex(ECbmDataType::kStsDigi, iDigi);
-    CbmStsDigi* digi    = (CbmStsDigi*) fStsDigis->At(index);
-    CbmMatch* digiMatch = (CbmMatch*) fStsDigiMatches->At(index);
-    assert(digi);
-    assert(digiMatch);
-
-    // --- Update event match with digi links
-    // --- N.b.: The member "index" of CbmLink has here no meaning, since
-    // --- there is only one MC event per tree entry.
-    for (Int_t iLink = 0; iLink < digiMatch->GetNofLinks(); iLink++) {
-      Int_t file      = digiMatch->GetLink(iLink).GetFile();
-      Int_t entry     = digiMatch->GetLink(iLink).GetEntry();
-      Double_t weight = digiMatch->GetLink(iLink).GetWeight();
-      match->AddLink(weight, 0, entry, file);
-    }  //# links in digi
-
-  }  //#digis
+  }
+  else {
+    LOG(info) << "Match data found in event. Clearing.";
+    match->ClearLinks();
+  }
+  //  LOG(info) << GetName() << ": Event " << event->GetNumber()
+  //              << ", STS digis : " << event->GetNofData(ECbmDataType::kStsDigi);
+
+  // --- Loop over all detector systems
+  for (ECbmModuleId& system : fSystems) {
+
+    //Skip if reference detectors are set and current system isn't one
+    if (!fRefDetectors.empty()
+        && std::find(fRefDetectors.begin(), fRefDetectors.end(), system) == fRefDetectors.end()) {
+      continue;
+    }
+
+    // --- Loop over digis in event
+    Int_t iNbDigis = event->GetNofData(GetDigiType(system));
+    for (Int_t iDigi = 0; iDigi < iNbDigis; iDigi++) {
+      Int_t index               = event->GetIndex(GetDigiType(system), iDigi);
+      const CbmMatch* digiMatch = fDigiMan->GetMatch(system, index);
+      assert(digiMatch);
+
+      // --- Update event match with digi links
+      // --- N.b.: The member "index" of CbmLink has here no meaning, since
+      // --- there is only one MC event per tree entry.
+      for (Int_t iLink = 0; iLink < digiMatch->GetNofLinks(); iLink++) {
+        Int_t file      = digiMatch->GetLink(iLink).GetFile();
+        Int_t entry     = digiMatch->GetLink(iLink).GetEntry();
+        Double_t weight = digiMatch->GetLink(iLink).GetWeight();
+        //     LOG(info) << "Adding link (weight, entry, file): " << weight << " "
+        //		<< entry << " " << file;
+        match->AddLink(weight, 0, entry, file);
+      }  //# links in digi
+    }    //#digis
+  }
+}
+// ===========================================================================
+
+
+// =====  Get digi type  =====================================================
+ECbmDataType CbmBuildEventsQA::GetDigiType(ECbmModuleId system)
+{
+  switch (system) {
+    case ECbmModuleId::kMvd: return ECbmDataType::kMvdDigi;
+    case ECbmModuleId::kSts: return ECbmDataType::kStsDigi;
+    case ECbmModuleId::kRich: return ECbmDataType::kRichDigi;
+    case ECbmModuleId::kMuch: return ECbmDataType::kMuchDigi;
+    case ECbmModuleId::kTrd: return ECbmDataType::kTrdDigi;
+    case ECbmModuleId::kTof: return ECbmDataType::kTofDigi;
+    case ECbmModuleId::kPsd: return ECbmDataType::kPsdDigi;
+    default: return ECbmDataType::kUnknown;
+  }
 }
 // ===========================================================================
 
diff --git a/reco/eventbuilder/digis/CbmBuildEventsQA.h b/reco/eventbuilder/digis/CbmBuildEventsQA.h
index cf0a8a3295bc1873a6d1534bc26768457e967d21..33c20d02b12ddf64c70205b65574c949731674b9 100644
--- a/reco/eventbuilder/digis/CbmBuildEventsQA.h
+++ b/reco/eventbuilder/digis/CbmBuildEventsQA.h
@@ -5,10 +5,12 @@
 #ifndef CBMBUILDEVENTSQA_H_
 #define CBMBUILDEVENTSQA_H 1
 
+#include "CbmDefs.h"
 
 #include <FairTask.h>
 
 class TClonesArray;
+class CbmDigiManager;
 class CbmEvent;
 
 /** @class CbmStsBuildEventsQA
@@ -33,12 +35,14 @@ public:
   /** Task execution **/
   virtual void Exec(Option_t* opt);
 
+  /** Add a reference detector **/
+  void AddRefDetector(ECbmModuleId RefDetector) { fRefDetectors.push_back(RefDetector); }
 
 private:
-  TClonesArray* fStsDigis;        ///< Input array (class CbmStsDigi)
-  TClonesArray* fStsDigiMatches;  ///< Input array (class CbmMatch)
-  TClonesArray* fEvents;          ///< Input array (class CbmEvent)
-  Int_t fNofEntries;              ///< Number of processed entries
+  CbmDigiManager* fDigiMan = nullptr;     //!
+  std::vector<ECbmModuleId> fSystems {};  //  List of detector systems
+  TClonesArray* fEvents;                  ///< Input array (class CbmEvent)
+  Int_t fNofEntries = 0;                  ///< Number of processed entries
 
   /** Task initialisation **/
   virtual InitStatus Init();
@@ -49,6 +53,10 @@ private:
 		 **/
   void MatchEvent(CbmEvent* event);
 
+  ECbmDataType GetDigiType(ECbmModuleId system);
+
+  std::vector<ECbmModuleId> fRefDetectors;  //  Detectors used for MC matching
+
   CbmBuildEventsQA(const CbmBuildEventsQA&);
   CbmBuildEventsQA& operator=(const CbmBuildEventsQA&);
 
diff --git a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2d3888b9b1488691fade1b2e0f0d80b39d14d70c
--- /dev/null
+++ b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.cxx
@@ -0,0 +1,412 @@
+/********************************************************************************
+ *    Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH    *
+ *                                                                              *
+ *              This software is distributed under the terms of the             *
+ *              GNU Lesser General Public Licence (LGPL) version 3,             *
+ *                  copied verbatim in the file "LICENSE"                       *
+ ********************************************************************************/
+#include "CbmTaskBuildRawEvents.h"
+
+#include "CbmDigiManager.h"
+#include "CbmEvent.h"
+
+#include "FairLogger.h"
+#include "FairRootManager.h"
+#include "FairRunOnline.h"
+
+#include "TClonesArray.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "THttpServer.h"
+#include <TFile.h>
+
+#include <iomanip>
+
+CbmTaskBuildRawEvents::CbmTaskBuildRawEvents() : FairTask("CbmTaskBuildRawEvents")
+{
+  /// Create Algo. To be made generic/switchable when more event building algo are available!
+  fpAlgo = new CbmAlgoBuildRawEvents();
+}
+
+CbmTaskBuildRawEvents::~CbmTaskBuildRawEvents() {}
+
+void CbmTaskBuildRawEvents::SetParContainers() {}
+
+void CbmTaskBuildRawEvents::SetSeedTimeFiller(RawEventBuilderDetector seedDet)
+{
+  if (fSeedTimeDetList.size() > 0) { LOG(fatal) << "Cannot use seed detector list and single instance together."; }
+
+  fSeedTimeDet = seedDet;
+  if (fSeedTimeDet != kRawEventBuilderDetUndef) {
+    if (fSeedTimes == nullptr) { fSeedTimes = new std::vector<Double_t>; }
+  }
+  else {
+    if (fSeedTimes != nullptr) {
+      fSeedTimes->clear();
+      delete fSeedTimes;
+      fSeedTimes = nullptr;
+    }
+  }
+  fpAlgo->SetSeedTimes(fSeedTimes);
+}
+
+void CbmTaskBuildRawEvents::AddSeedTimeFillerToList(RawEventBuilderDetector seedDet)
+{
+  if (fSeedTimeDet != kRawEventBuilderDetUndef) {
+    LOG(fatal) << "Cannot use seed detector list and single instance together.";
+  }
+  if (fSeedTimes == nullptr) { fSeedTimes = new std::vector<Double_t>; }
+
+  fSeedTimeDetList.push_back(seedDet);
+  fpAlgo->SetSeedTimes(fSeedTimes);
+}
+
+InitStatus CbmTaskBuildRawEvents::Init()
+{
+  /// Get a handle from the IO manager
+  FairRootManager* ioman = FairRootManager::Instance();
+
+  //T0 not included in digi manager.
+  fT0Digis = ioman->InitObjectAs<std::vector<CbmTofDigi> const*>("T0Digi");
+  if (!fT0Digis) { LOG(info) << "No T0 digi input."; }
+  else {
+    LOG(info) << "T0 digi input.";
+    fpAlgo->SetT0Digis(fT0Digis);
+  }
+
+  // Get a pointer to the previous already existing data level
+  fDigiMan = CbmDigiManager::Instance();
+  if (fbUseMuchBeamtimeDigi) { fDigiMan->UseMuchBeamTimeDigi(); }
+  fDigiMan->Init();
+
+  //Init STS digis
+  if (!fDigiMan->IsPresent(ECbmModuleId::kSts)) { LOG(info) << "No STS digi input."; }
+  else {
+    LOG(info) << "STS digi input.";
+    fStsDigis = new std::vector<CbmStsDigi>;
+    fpAlgo->SetStsDigis(fStsDigis);
+  }
+
+  //Init MUCH digis
+  if (!fDigiMan->IsPresent(ECbmModuleId::kMuch)) { LOG(info) << "No MUCH digi input."; }
+  else {
+    LOG(info) << "MUCH digi input.";
+    if (fbUseMuchBeamtimeDigi) {
+      fMuchBeamTimeDigis = new std::vector<CbmMuchBeamTimeDigi>;
+      fpAlgo->SetMuchBeamTimeDigis(fMuchBeamTimeDigis);
+    }
+    else {
+      fMuchDigis = new std::vector<CbmMuchDigi>;
+      fpAlgo->SetMuchDigis(fMuchDigis);
+    }
+  }
+
+  //Init TRD digis
+  if (!fDigiMan->IsPresent(ECbmModuleId::kTrd)) { LOG(info) << "No TRD digi input."; }
+  else {
+    LOG(info) << "TRD digi input.";
+    fTrdDigis = new std::vector<CbmTrdDigi>;
+    fpAlgo->SetTrdDigis(fTrdDigis);
+  }
+
+  //Init TOF digis
+  if (!fDigiMan->IsPresent(ECbmModuleId::kTof)) { LOG(info) << "No TOF digi input."; }
+  else {
+    LOG(info) << "TOF digi input.";
+    fTofDigis = new std::vector<CbmTofDigi>;
+    fpAlgo->SetTofDigis(fTofDigis);
+  }
+
+  //Init RICH digis
+  if (!fDigiMan->IsPresent(ECbmModuleId::kRich)) { LOG(info) << "No RICH digi input."; }
+  else {
+    LOG(info) << "RICH digi input.";
+    fRichDigis = new std::vector<CbmRichDigi>;
+    fpAlgo->SetRichDigis(fRichDigis);
+  }
+
+  //Init PSD digis
+  if (!fDigiMan->IsPresent(ECbmModuleId::kPsd)) { LOG(info) << "No PSD digi input."; }
+  else {
+    LOG(info) << "PSD digi input.";
+    fPsdDigis = new std::vector<CbmPsdDigi>;
+    fpAlgo->SetPsdDigis(fPsdDigis);
+  }
+
+  /// 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";
+
+  /// Call Algo Init method
+  if (kTRUE == fpAlgo->InitAlgo()) return kSUCCESS;
+  else
+    return kFATAL;
+}
+
+
+InitStatus CbmTaskBuildRawEvents::ReInit() { return kSUCCESS; }
+
+void CbmTaskBuildRawEvents::Exec(Option_t* /*option*/)
+{
+  LOG(debug2) << "CbmTaskBuildRawEvents::Exec => Starting sequence";
+  //Warning: Int_t must be used for the loop counters instead of UInt_t,
+  //as the digi manager can return -1, which would be casted to +1
+  //during comparison, leading to an error.
+
+  if (fSeedTimeDet != kRawEventBuilderDetUndef && fSeedTimeDetList.size() > 0) {
+    LOG(fatal) << "Cannot use seed detector list and single instance together.";
+  }
+
+  //Reset explicit seed times if set
+  if (fSeedTimeDet != kRawEventBuilderDetUndef || fSeedTimeDetList.size() > 0) { fSeedTimes->clear(); }
+
+  //Read STS digis
+  if (fDigiMan->IsPresent(ECbmModuleId::kSts)) {
+    fStsDigis->clear();
+    for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kSts); i++) {
+      const CbmStsDigi* Digi = fDigiMan->Get<CbmStsDigi>(i);
+      fStsDigis->push_back(*Digi);
+      if (fSeedTimeDet.detId == ECbmModuleId::kSts) { fSeedTimes->push_back(Digi->GetTime()); }
+    }
+    LOG(debug) << "Read: " << fStsDigis->size() << " STS digis.";
+    LOG(debug) << "In DigiManager: " << fDigiMan->GetNofDigis(ECbmModuleId::kSts) << " STS digis.";
+  }
+
+  //Read MUCH digis
+  if (fDigiMan->IsPresent(ECbmModuleId::kMuch)) {
+    if (fbUseMuchBeamtimeDigi) {
+      fMuchBeamTimeDigis->clear();
+      for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kMuch); i++) {
+        const CbmMuchBeamTimeDigi* Digi = fDigiMan->Get<CbmMuchBeamTimeDigi>(i);
+        fMuchBeamTimeDigis->push_back(*Digi);
+        if (fSeedTimeDet.detId == ECbmModuleId::kMuch) { fSeedTimes->push_back(Digi->GetTime()); }
+      }
+      LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kMuch) << " MUCH digis.";
+      LOG(debug) << "In DigiManager: " << fMuchBeamTimeDigis->size() << " MUCH digis.";
+    }
+    else {
+      fMuchDigis->clear();
+      for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kMuch); i++) {
+        const CbmMuchDigi* Digi = fDigiMan->Get<CbmMuchDigi>(i);
+        fMuchDigis->push_back(*Digi);
+        if (fSeedTimeDet.detId == ECbmModuleId::kMuch) { fSeedTimes->push_back(Digi->GetTime()); }
+      }
+      LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kMuch) << " MUCH digis.";
+      LOG(debug) << "In DigiManager: " << fMuchDigis->size() << " MUCH digis.";
+    }
+  }
+
+  //Read TRD digis
+  if (fDigiMan->IsPresent(ECbmModuleId::kTrd)) {
+    fTrdDigis->clear();
+    for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kTrd); i++) {
+      const CbmTrdDigi* Digi = fDigiMan->Get<CbmTrdDigi>(i);
+      fTrdDigis->push_back(*Digi);
+      if (fSeedTimeDet.detId == ECbmModuleId::kTrd) { fSeedTimes->push_back(Digi->GetTime()); }
+    }
+    LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kTrd) << " TRD digis.";
+    LOG(debug) << "In DigiManager: " << fTrdDigis->size() << " TRD digis.";
+  }
+
+  //Read TOF digis
+  if (fDigiMan->IsPresent(ECbmModuleId::kTof)) {
+    fTofDigis->clear();
+    for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kTof); i++) {
+      const CbmTofDigi* Digi = fDigiMan->Get<CbmTofDigi>(i);
+      fTofDigis->push_back(*Digi);
+      if (fSeedTimeDet.detId == ECbmModuleId::kTof) { fSeedTimes->push_back(Digi->GetTime()); }
+    }
+    LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kTof) << " TOF digis.";
+    LOG(debug) << "In DigiManager: " << fTofDigis->size() << " TOF digis.";
+  }
+
+  //Read RICH digis
+  if (fDigiMan->IsPresent(ECbmModuleId::kRich)) {
+    fRichDigis->clear();
+    for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kRich); i++) {
+      const CbmRichDigi* Digi = fDigiMan->Get<CbmRichDigi>(i);
+      fRichDigis->push_back(*Digi);
+      if (fSeedTimeDet.detId == ECbmModuleId::kRich) { fSeedTimes->push_back(Digi->GetTime()); }
+    }
+    LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kRich) << " RICH digis.";
+    LOG(debug) << "In DigiManager: " << fRichDigis->size() << " RICH digis.";
+  }
+
+  //Read PSD digis
+  if (fDigiMan->IsPresent(ECbmModuleId::kPsd)) {
+    fPsdDigis->clear();
+    for (Int_t i = 0; i < fDigiMan->GetNofDigis(ECbmModuleId::kPsd); i++) {
+      const CbmPsdDigi* Digi = fDigiMan->Get<CbmPsdDigi>(i);
+      fPsdDigis->push_back(*Digi);
+      if (fSeedTimeDet.detId == ECbmModuleId::kPsd) { fSeedTimes->push_back(Digi->GetTime()); }
+    }
+    LOG(debug) << "Read: " << fDigiMan->GetNofDigis(ECbmModuleId::kPsd) << " PSD digis.";
+    LOG(debug) << "In DigiManager: " << fPsdDigis->size() << " PSD digis.";
+  }
+
+  if (fSeedTimeDetList.size() > 0) { FillSeedTimesFromDetList(); }
+  //DumpSeedTimesFromDetList();
+
+  /// Call Algo ProcessTs method
+  fpAlgo->ProcessTs();
+
+  /// Save the resulting vector of events in TClonesArray
+  FillOutput();
+  LOG(debug2) << "CbmTaskBuildRawEvents::Exec => Done";
+}
+
+void CbmTaskBuildRawEvents::FillSeedTimesFromDetList()
+{
+  std::map<ECbmModuleId, UInt_t> DigiNumbers;
+  std::map<ECbmModuleId, UInt_t> DigiCounters;
+  fSeedTimes->clear();
+
+  for (RawEventBuilderDetector& system : fSeedTimeDetList) {
+    DigiNumbers[system.detId]  = GetNofDigis(system.detId);
+    DigiCounters[system.detId] = 0;
+  }
+
+  do {
+    ECbmModuleId nextAddedSystem;
+    Double_t earliestTime = -1;
+
+    for (RawEventBuilderDetector& system : fSeedTimeDetList) {
+      if (DigiCounters[system.detId] < DigiNumbers[system.detId]) {
+        Double_t thisTime = GetDigiTime(system.detId, DigiCounters[system.detId]);
+        if (thisTime < earliestTime || earliestTime == -1) {
+          nextAddedSystem = system.detId;
+          earliestTime    = thisTime;
+        }
+      }
+    }
+    if (earliestTime != -1) {
+      fSeedTimes->push_back(earliestTime);
+      DigiCounters[nextAddedSystem]++;
+    }
+    else {
+      break;
+    }
+  } while (true);
+}
+
+void CbmTaskBuildRawEvents::DumpSeedTimesFromDetList()
+{
+  std::ofstream timesUnsorted("digiTimesUnsorted.dat", std::ofstream::out);
+  timesUnsorted << std::setprecision(16);
+
+  for (RawEventBuilderDetector& system : fSeedTimeDetList) {
+    for (UInt_t i = 0; i < GetNofDigis(system.detId); i++) {
+      timesUnsorted << GetDigiTime(system.detId, i) << std::endl;
+    }
+  }
+  timesUnsorted.close();
+  LOG(info) << "Completed write of unsorted digi list.";
+
+  std::ofstream timesSorted("digiTimesSorted.dat", std::ofstream::out);
+  timesSorted << std::setprecision(16);
+
+  for (UInt_t i = 0; i < fSeedTimes->size(); i++) {
+    timesSorted << fSeedTimes->at(i) << std::endl;
+  }
+  timesSorted.close();
+  LOG(info) << "Completed DumpSeedTimesFromDetList(). Closing.";
+  exit(0);  //terminate as this method should only be used for diagnostics
+}
+
+Double_t CbmTaskBuildRawEvents::GetDigiTime(ECbmModuleId _system, UInt_t _entry)
+{
+  switch (_system) {
+    case ECbmModuleId::kMuch:
+      if (fbUseMuchBeamtimeDigi) { return (fMuchBeamTimeDigis->at(_entry)).GetTime(); }
+      else {
+        return (fMuchDigis->at(_entry)).GetTime();
+      }
+    case ECbmModuleId::kSts: return (fStsDigis->at(_entry)).GetTime();
+    case ECbmModuleId::kTrd: return (fTrdDigis->at(_entry)).GetTime();
+    case ECbmModuleId::kTof: return (fTofDigis->at(_entry)).GetTime();
+    case ECbmModuleId::kRich: return (fRichDigis->at(_entry)).GetTime();
+    case ECbmModuleId::kPsd: return (fPsdDigis->at(_entry)).GetTime();
+    case ECbmModuleId::kHodo: return (fT0Digis->at(_entry)).GetTime();
+    default: break;
+  }
+  return -1;
+}
+
+UInt_t CbmTaskBuildRawEvents::GetNofDigis(ECbmModuleId _system)
+{
+  switch (_system) {
+    case ECbmModuleId::kMuch:
+      if (fbUseMuchBeamtimeDigi) { return fMuchBeamTimeDigis->size(); }
+      else {
+        return fMuchDigis->size();
+      }
+    case ECbmModuleId::kSts: return fStsDigis->size();
+    case ECbmModuleId::kTrd: return fTrdDigis->size();
+    case ECbmModuleId::kTof: return fTofDigis->size();
+    case ECbmModuleId::kRich: return fRichDigis->size();
+    case ECbmModuleId::kPsd: return fPsdDigis->size();
+    case ECbmModuleId::kHodo: return fT0Digis->size();
+    default: break;
+  }
+  return 0;
+}
+
+void CbmTaskBuildRawEvents::Finish()
+{
+  /// Call Algo finish method
+  fpAlgo->Finish();
+  if (fbFillHistos) { SaveHistos(); }
+}
+
+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();
+  }
+  /// Clear event vector after usage
+  fpAlgo->ClearEventVector();
+}
+
+void CbmTaskBuildRawEvents::SaveHistos()
+{
+  /// Obtain vector of pointers on each histo from the algo (+ optionally desired folder)
+  std::vector<std::pair<TNamed*, std::string>> vHistos = fpAlgo->GetHistoVector();
+
+  /// (Re-)Create ROOT file to store the histos
+  TDirectory* oldDir = NULL;
+  TFile* histoFile   = NULL;
+  /// Store current directory position to allow restore later
+  oldDir = gDirectory;
+  /// open separate histo file in recreate mode
+  histoFile = new TFile(fsOutFileName, "RECREATE");
+  histoFile->cd();
+
+  /// Save all plots and create folders if needed
+  for (UInt_t uHisto = 0; uHisto < vHistos.size(); ++uHisto) {
+    /// Make sure we end up in chosen folder
+    const TString sFolder = vHistos[uHisto].second.data();
+    if (nullptr == gDirectory->Get(sFolder)) gDirectory->mkdir(sFolder);
+    gDirectory->cd(sFolder);
+
+    /// Write plot
+    vHistos[uHisto].first->Write();
+    histoFile->cd();
+  }
+
+  /// Restore original directory position
+  oldDir->cd();
+  histoFile->Close();
+}
+
+
+ClassImp(CbmTaskBuildRawEvents)
diff --git a/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h
new file mode 100644
index 0000000000000000000000000000000000000000..c896aa3a8e581faf5c412d4f07fd25562c0d94ab
--- /dev/null
+++ b/reco/eventbuilder/digis/CbmTaskBuildRawEvents.h
@@ -0,0 +1,159 @@
+/********************************************************************************
+ *    Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH    *
+ *                                                                              *
+ *              This software is distributed under the terms of the             *
+ *              GNU Lesser General Public Licence (LGPL) version 3,             *
+ *                  copied verbatim in the file "LICENSE"                       *
+ ********************************************************************************/
+#ifndef CBMTASKBUILDRAWEVENTS_H
+#define CBMTASKBUILDRAWEVENTS_H
+
+/// FAIRROOT headers
+#include "FairTask.h"
+
+/// FAIRSOFT headers (geant, boost, ...)
+
+/// C/C++ headers
+#include "CbmAlgoBuildRawEvents.h"
+#include "CbmMuchBeamTimeDigi.h"
+#include "CbmMuchDigi.h"
+#include "CbmPsdDigi.h"
+#include "CbmRichDigi.h"
+#include "CbmStsDigi.h"
+#include "CbmTofDigi.h"
+#include "CbmTrdDigi.h"
+
+#include <tuple>
+
+#include <array>
+#include <map>
+#include <set>
+#include <vector>
+
+class CbmDigiManager;
+class RawEventBuilderDetector;
+class TClonesArray;
+
+enum class EOverlapModeRaw;
+
+class CbmTaskBuildRawEvents : public FairTask {
+public:
+  /** Default constructor **/
+  CbmTaskBuildRawEvents();
+
+  CbmTaskBuildRawEvents(const CbmTaskBuildRawEvents&) = delete;
+  CbmTaskBuildRawEvents operator=(const CbmTaskBuildRawEvents&) = delete;
+
+  /** Constructor with parameters (Optional) **/
+  //  CbmTaskBuildRawEvents(Int_t verbose);
+
+  /** Destructor **/
+  ~CbmTaskBuildRawEvents();
+
+  /** Initiliazation of task at the beginning of a run **/
+  virtual InitStatus Init();
+
+  /** ReInitiliazation of task when the runID changes **/
+  virtual InitStatus ReInit();
+
+  /** Executed for each event. **/
+  virtual void Exec(Option_t*);
+
+  /** Load the parameter container from the runtime database **/
+  virtual void SetParContainers();
+
+  /** Finish task called at the end of the run **/
+  virtual void Finish();
+
+  /** Setters **/
+  void SetOutFilename(TString sNameIn) { fsOutFileName = sNameIn; }
+
+  void SetFillHistos(Bool_t bFlag = kTRUE)
+  {
+    fbFillHistos = bFlag;
+    if (nullptr != fpAlgo) fpAlgo->SetFillHistos(fbFillHistos);
+  }
+  void SetReferenceDetector(RawEventBuilderDetector refDet)
+  {
+    if (nullptr != fpAlgo) fpAlgo->SetReferenceDetector(refDet);
+  }
+  void AddDetector(RawEventBuilderDetector selDet)
+  {
+    if (nullptr != fpAlgo) fpAlgo->AddDetector(selDet);
+  }
+  void RemoveDetector(RawEventBuilderDetector selDet)
+  {
+    if (nullptr != fpAlgo) fpAlgo->RemoveDetector(selDet);
+  }
+  void SetTriggerMinNumber(ECbmModuleId selDet, UInt_t uVal)
+  {
+    if (nullptr != fpAlgo) fpAlgo->SetTriggerMinNumber(selDet, uVal);
+  }
+  void SetTriggerMaxNumber(ECbmModuleId selDet, Int_t iVal)
+  {
+    if (nullptr != fpAlgo) fpAlgo->SetTriggerMaxNumber(selDet, iVal);
+  }
+  void SetTriggerWindow(ECbmModuleId det, Double_t dWinBeg, Double_t dWinEnd)
+  {
+    if (nullptr != fpAlgo) fpAlgo->SetTriggerWindow(det, dWinBeg, dWinEnd);
+  }
+  void SetTsParameters(Double_t dTsStartTime, Double_t dTsLength, Double_t dTsOverLength)
+  {
+    if (nullptr != fpAlgo) fpAlgo->SetTsParameters(dTsStartTime, dTsLength, dTsOverLength);
+  }
+  void SetEventOverlapMode(EOverlapModeRaw mode)
+  {
+    if (nullptr != fpAlgo) fpAlgo->SetEventOverlapMode(mode);
+  }
+  void SetIgnoreTsOverlap(Bool_t bFlagIn)
+  {
+    if (nullptr != fpAlgo) fpAlgo->SetIgnoreTsOverlap(bFlagIn);
+  }
+  void ChangeMuchBeamtimeDigiFlag(Bool_t bFlagIn = kFALSE)
+  {
+    if (nullptr != fpAlgo) fpAlgo->ChangeMuchBeamtimeDigiFlag(bFlagIn);
+    fbUseMuchBeamtimeDigi = bFlagIn;
+  }
+  void SetSeedTimeFiller(RawEventBuilderDetector seedDet);
+  void AddSeedTimeFillerToList(RawEventBuilderDetector seedDet);
+  void DumpSeedTimesFromDetList();
+  void SetSeedTimeWindow(Double_t beg, Double_t end) { fpAlgo->SetSeedTimeWindow(beg, end); }
+
+private:
+  void FillOutput();
+  void SaveHistos();
+
+  Bool_t fbUseMuchBeamtimeDigi = kTRUE;  //! Switch between MUCH digi classes
+
+  CbmDigiManager* fDigiMan                             = nullptr;
+  const std::vector<CbmTofDigi>* fT0Digis              = nullptr;
+  std::vector<CbmMuchDigi>* fMuchDigis                 = nullptr;
+  std::vector<CbmMuchBeamTimeDigi>* fMuchBeamTimeDigis = nullptr;
+  std::vector<CbmStsDigi>* fStsDigis                   = nullptr;
+  std::vector<CbmTrdDigi>* fTrdDigis                   = nullptr;
+  std::vector<CbmTofDigi>* fTofDigis                   = nullptr;
+  std::vector<CbmRichDigi>* fRichDigis                 = nullptr;
+  std::vector<CbmPsdDigi>* fPsdDigis                   = nullptr;
+  std::vector<Double_t>* fSeedTimes                    = nullptr;
+
+  std::vector<RawEventBuilderDetector> fSeedTimeDetList;            //if multiple are desired
+  RawEventBuilderDetector fSeedTimeDet = kRawEventBuilderDetUndef;  //single seed det
+
+  Double_t GetDigiTime(ECbmModuleId _system, UInt_t _entry);
+  UInt_t GetNofDigis(ECbmModuleId _system);
+
+  void FillSeedTimesFromDetList();
+
+  CbmAlgoBuildRawEvents* fpAlgo = nullptr;
+
+  TClonesArray* fEvents = nullptr;  //! output container of CbmEvents
+
+  Bool_t fbFillHistos {kTRUE};  //! Switch ON/OFF filling of histograms
+
+  /** Name of the histogram output file **/
+  TString fsOutFileName {"data/HistosEvtWin.root"};
+
+  ClassDef(CbmTaskBuildRawEvents, 1);
+};
+
+#endif  // CBMTASKBUILDRAWEVENTS_H
diff --git a/reco/qa/CbmRecoQa.cxx b/reco/qa/CbmRecoQa.cxx
index d403b5c0f93701e1d73745cdb6d69a0032fd24ea..f535ff91b94a30e6b139c98b36d392026bfa3f6d 100644
--- a/reco/qa/CbmRecoQa.cxx
+++ b/reco/qa/CbmRecoQa.cxx
@@ -181,6 +181,9 @@ void CbmRecoQa::FinishEvent() {
 // --- Finish Task
 // Save Data in File
 void CbmRecoQa::FinishTask() {
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
 
   std::string filename = outname + ".qa.hists.root";
   pullresfile          = new TFile(filename.c_str(), "Recreate");
@@ -196,6 +199,12 @@ void CbmRecoQa::FinishTask() {
     }
     gDirectory->cd("..");
   }
+
+  pullresfile->Close();
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
 }
 
 // --- Write Data in Historgrams, depending on detectorw
diff --git a/scripts/check-apply-format-changes.sh b/scripts/check-apply-format-changes.sh
index 12f8a017e9096fd4557a55462043a2620f33a892..31f7e7aec86324039d8f6b2fd4a86b46ed02568f 100755
--- a/scripts/check-apply-format-changes.sh
+++ b/scripts/check-apply-format-changes.sh
@@ -39,12 +39,12 @@ case $1 in
   check)
     echo "Checking if there are format changes required"
     git fetch $UPSTREAM
-    $GIT_CLANG_FORMAT_BIN --commit $BASE_COMMIT --diff $CHANGED_FILES --extensions h,hpp,c,C,cpp,cxx,tpl
+    $GIT_CLANG_FORMAT_BIN --binary $CLANG_FORMAT_BIN --commit $BASE_COMMIT --diff $CHANGED_FILES --extensions h,hpp,c,C,cpp,cxx,tpl
     ;;
 
   apply)
     echo "Applying required format changes"
-    $GIT_CLANG_FORMAT_BIN --verbose --commit $BASE_COMMIT $CHANGED_FILES --extensions h,hpp,c,C,cpp,cxx,tpl
+    $GIT_CLANG_FORMAT_BIN --binary $CLANG_FORMAT_BIN --verbose --commit $BASE_COMMIT $CHANGED_FILES --extensions h,hpp,c,C,cpp,cxx,tpl
     git status
     echo "Next step: git add "$CHANGED_FILES
     echo 'Then     : git commit -m"Apply clang-format"'
diff --git a/sim/detectors/much/CbmMuchDigitizeGem.cxx b/sim/detectors/much/CbmMuchDigitizeGem.cxx
index 419df13c141c2d0c99e4cd810d98815e3184321b..dd38dc25e4ec163b2a5b6aecc041b6450fd0231c 100644
--- a/sim/detectors/much/CbmMuchDigitizeGem.cxx
+++ b/sim/detectors/much/CbmMuchDigitizeGem.cxx
@@ -2,8 +2,8 @@
  *@author Vikas Singhal <vikas@vecc.gov.in>
  *@since 15.01.2020
  *@version 4.0
- *@description: Using std::vector for digi and match containers. 
- *@author Ekata Nandy (ekata@vecc.gov.in) 
+ *@description: Using std::vector for digi and match containers.
+ *@author Ekata Nandy (ekata@vecc.gov.in)
  *@since 21.06.19 : RPC digitization parameters(for 3rd and 4th MUCH station) now have been implemented along with GEM param// eters (1st and 2nd station) @author Ekata Nandy (ekata@vecc.gov.in)
  *@description: ADC channels number is 32.GEM & RPC has different charge threshold value and dynamic range, so SetAdc has been changed acc// ordingly. ADC value starts from 1 to 32. ADC 0 has been excluded as it gives wrong x, y, t. @author Ekata Nandy
  *@author Vikas Singhal <vikas@vecc.gov.in>
@@ -378,7 +378,9 @@ InitStatus CbmMuchDigitizeGem::Init() {
 
 
   // Initialize GeoScheme
-  TFile* oldfile = gFile;
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
   TFile* file    = new TFile(fDigiFile);
   if (!file->IsOpen())
     LOG(fatal) << fName << ": parameter file " << fDigiFile
@@ -386,7 +388,9 @@ InitStatus CbmMuchDigitizeGem::Init() {
   TObjArray* stations = (TObjArray*) file->Get("stations");
   file->Close();
   file->Delete();
-  gFile = oldfile;
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
   fGeoScheme->Init(stations, fFlag);
 
 
@@ -808,11 +812,18 @@ void CbmMuchDigitizeGem::Finish() {
   LOG(info) << "=====================================";
 
   /*
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
   TFile *f1 =new TFile ("pri_el_info.root","RECREATE");
   hPriElAfterDriftpathgem->Write();
   hPriElAfterDriftpathrpc->Write();
   hadcGEM->Write();
   hadcRPC->Write();
+  f1->Close();
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
   */
   //if (fDaq)	ReadAndRegister(-1.);
 }
diff --git a/sim/transport/generators/CMakeLists.txt b/sim/transport/generators/CMakeLists.txt
index 556e0de5d1977668a544324565ae217d5705e84d..14b472370000e9e45757d8da8eaa64e94a3b5f00 100644
--- a/sim/transport/generators/CMakeLists.txt
+++ b/sim/transport/generators/CMakeLists.txt
@@ -30,6 +30,7 @@ pluto/PValues.cxx
 # ----  Include directories -------------------------------
 set(INCLUDE_DIRECTORIES
 ${CBMDATA_DIR}
+${CBMBASE_DIR}/utils
 ${CBMROOT_SOURCE_DIR}/sim
 ${CBMROOT_SOURCE_DIR}/sim/transport
 ${CBMROOT_SOURCE_DIR}/sim/transport/base
diff --git a/sim/transport/generators/CbmPlutoGenerator.cxx b/sim/transport/generators/CbmPlutoGenerator.cxx
index e110b5f93f48d7e174d64063766bcd4dd7e4fec1..476ad6442d49f59bed68ee6dd72894d9f3604ec3 100644
--- a/sim/transport/generators/CbmPlutoGenerator.cxx
+++ b/sim/transport/generators/CbmPlutoGenerator.cxx
@@ -4,13 +4,12 @@
 // -------------------------------------------------------------------------
 #include "CbmPlutoGenerator.h"
 
+#include "CbmFileUtils.h"
+
 #include "FairLogger.h"
 #include "FairPrimaryGenerator.h"  // for FairPrimaryGenerator
 
-#include "PDataBase.h"    // for PDataBase
-#include "PParticle.h"    // for PParticle
-#include "PStaticData.h"  // for PStaticData
-
+#include "TArchiveFile.h"    // for TArchiveFile
 #include "TChain.h"          // for TChain
 #include "TClonesArray.h"    // for TClonesArray
 #include "TDatabasePDG.h"    // for TDatabasePDG
@@ -18,7 +17,12 @@
 #include "TLorentzVector.h"  // for TLorentzVector
 #include "TTree.h"           // for TTree
 #include "TVector3.h"        // for TVector3
-#include <iosfwd>            // for ostream
+
+#include <iosfwd>  // for ostream
+
+#include "PDataBase.h"    // for PDataBase
+#include "PParticle.h"    // for PParticle
+#include "PStaticData.h"  // for PStaticData
 
 //#include <stddef.h>                     // for NULL
 #include <iostream>  // for operator<<, basic_ostream, etc
@@ -47,10 +51,15 @@ CbmPlutoGenerator::CbmPlutoGenerator(const Char_t* fileName)
   , fParticles(new TClonesArray("PParticle", 100))
   , fPDGmanual(0) {
   fInputChain = new TChain("data");
-  CheckFileExist(fileName);
 
-  fInputChain->Add(fileName);
-  fInputChain->SetBranchAddress("Particles", &fParticles);
+  if (Cbm::File::IsRootFile(fileName)) {
+    fInputChain->Add(fileName);
+    fInputChain->SetBranchAddress("Particles", &fParticles);
+    LOG(info) << "CbmPlutoGenerator: Add file " << fileName << " to input chain";
+  }
+  else {
+    LOG(fatal) << "Problem opening file " << fileName;
+  }
 }
 // ------------------------------------------------------------------------
 
@@ -65,10 +74,16 @@ CbmPlutoGenerator::CbmPlutoGenerator(std::vector<std::string> fileNames)
   , fParticles(new TClonesArray("PParticle", 100))
   , fPDGmanual(0) {
   fInputChain = new TChain("data");
-  for (auto& name : fileNames) {
-    CheckFileExist(name);
-    fInputChain->Add(name.c_str());
+  for (const auto& name : fileNames) {
+    if (Cbm::File::IsRootFile(name)) {
+      fInputChain->Add(name.c_str());
+      LOG(info) << "CbmPlutoGenerator: Add file " << name << " to input chain";
+    }
+    else {
+      LOG(fatal) << "Problem opening file " << name;
+    }
   }
+
   fInputChain->SetBranchAddress("Particles", &fParticles);
 }
 
@@ -178,14 +193,4 @@ void CbmPlutoGenerator::CloseInput() {
 }
 // ------------------------------------------------------------------------
 
-void CbmPlutoGenerator::CheckFileExist(std::string filename) {
-  struct stat buffer;
-  if (stat(filename.c_str(), &buffer) == 0) {
-    LOG(info) << "CbmPlutoGenerator: Add file " << filename
-              << " to input chain";
-  } else {
-    LOG(fatal) << "Input File " << filename << " not found";
-  }
-}
-
 ClassImp(CbmPlutoGenerator)
diff --git a/sim/transport/generators/CbmPlutoGenerator.h b/sim/transport/generators/CbmPlutoGenerator.h
index db1424da9d4ed739d6008e2afce5f5d7ea28aea9..d5f6a7cd8e4594c2d4e324b3a0d472f8a858d992 100644
--- a/sim/transport/generators/CbmPlutoGenerator.h
+++ b/sim/transport/generators/CbmPlutoGenerator.h
@@ -77,9 +77,6 @@ private:
      ** input file properly. Called from destructor and from ReadEvent. **/
   void CloseInput();
 
-  /** Check if file exists. Break fatal when it doesn't exist **/
-  void CheckFileExist(std::string filename);
-
   ClassDef(CbmPlutoGenerator, 4);
 };
 
diff --git a/sim/transport/generators/CbmUnigenGenerator.cxx b/sim/transport/generators/CbmUnigenGenerator.cxx
index c9719e51e5d63d350da4e749b776fe12fc4d29de..56e686a5166f9b40707dbeff6fd4badf385b2197 100644
--- a/sim/transport/generators/CbmUnigenGenerator.cxx
+++ b/sim/transport/generators/CbmUnigenGenerator.cxx
@@ -158,9 +158,17 @@ Bool_t CbmUnigenGenerator::Init() {
   }
   LOG(INFO) << GetName() << ": Mode " << ss.str();
 
+  /// Save old global file and folder pointer to avoid messing with FairRoot
+  TFile* oldFile     = gFile;
+  TDirectory* oldDir = gDirectory;
 
   // --- Try to open file
   fFile = new TFile(fFileName, "READ");
+
+  /// Restore old global file and folder pointer to avoid messing with FairRoot
+  gFile      = oldFile;
+  gDirectory = oldDir;
+
   if (!fFile->IsOpen()) {
     LOG(error) << GetName() << ": Could not open input file " << fFileName;
     return kFALSE;
diff --git a/sim/transport/steer/CMakeLists.txt b/sim/transport/steer/CMakeLists.txt
index 253c1a2907170d0741b16d6967fe02b58cd2b98a..375b40e617e1003f3a1220ccc95de52cf75db82a 100644
--- a/sim/transport/steer/CMakeLists.txt
+++ b/sim/transport/steer/CMakeLists.txt
@@ -33,7 +33,7 @@ ${CBMROOT_SOURCE_DIR}/sim/transport/generators
 ${CBMROOT_SOURCE_DIR}/sim/transport/steer
 ${CBMROOT_SOURCE_DIR}/sim/transport/geosetup
 ${CBMDATA_DIR}
-${CBMROOT_SOURCE_DIR}/generators/unigen
+${CBMBASE_DIR}/utils
 )
 
 set(SYSTEM_INCLUDE_DIRECTORIES
diff --git a/sim/transport/steer/CbmTransport.cxx b/sim/transport/steer/CbmTransport.cxx
index e56866d543a125d7a6eda7a6a047a483f8015624..c79d77955a8bce1d620d92bba44ab471358b90a3 100644
--- a/sim/transport/steer/CbmTransport.cxx
+++ b/sim/transport/steer/CbmTransport.cxx
@@ -5,6 +5,27 @@
 
 #include "CbmTransport.h"
 
+#include "CbmBeamProfile.h"
+#include "CbmEventGenerator.h"
+#include "CbmFieldMap.h"
+#include "CbmFieldPar.h"
+#include "CbmFileUtils.h"
+#include "CbmGeant3Settings.h"
+#include "CbmGeant4Settings.h"
+#include "CbmPlutoGenerator.h"
+#include "CbmSetup.h"
+#include "CbmStack.h"
+#include "CbmTarget.h"
+#include "CbmUnigenGenerator.h"
+
+#include "FairLogger.h"
+#include "FairMonitor.h"
+#include "FairParRootFileIo.h"
+#include "FairRunSim.h"
+#include "FairRuntimeDb.h"
+#include "FairSystemInfo.h"
+#include "FairUrqmdGenerator.h"
+
 #include "TDatabasePDG.h"
 #include "TG4RunConfiguration.h"
 #include "TGeant3.h"
@@ -18,34 +39,15 @@
 #include "TSystem.h"
 #include "TVector3.h"
 #include "TVirtualMC.h"
-#include <array>
+
 #include <boost/filesystem.hpp>
+
+#include <array>
 #include <cassert>
 #include <iostream>
 #include <sstream>
 #include <string>
 
-#include "FairLogger.h"
-#include "FairMonitor.h"
-#include "FairParRootFileIo.h"
-#include "FairRunSim.h"
-#include "FairRuntimeDb.h"
-#include "FairSystemInfo.h"
-#include "FairUrqmdGenerator.h"
-
-#include "CbmBeamProfile.h"
-#include "CbmEventGenerator.h"
-#include "CbmFieldMap.h"
-#include "CbmFieldPar.h"
-#include "CbmPlutoGenerator.h"
-#include "CbmSetup.h"
-#include "CbmStack.h"
-#include "CbmTarget.h"
-#include "CbmUnigenGenerator.h"
-
-#include "CbmGeant3Settings.h"
-#include "CbmGeant4Settings.h"
-
 using std::stringstream;
 
 
@@ -104,9 +106,17 @@ void CbmTransport::AddInput(const char* fileName, ECbmGenerator genType) {
 
   FairGenerator* generator = NULL;
 
-  if (gSystem->AccessPathName(fileName)) {
-    LOG(fatal) << GetName() << ": Input file " << fileName << " not found!";
-    return;
+  if (genType == kUrqmd) {
+    if (gSystem->AccessPathName(fileName)) {
+      LOG(fatal) << GetName() << ": Input file " << fileName << " not found!";
+      return;
+    }
+  }
+  else {
+    if (!Cbm::File::IsRootFile(fileName)) {
+      LOG(fatal) << GetName() << ": Input file " << fileName << " not found!";
+      return;
+    }
   }
 
   switch (genType) {