From e78ea917df7315407fe8d5aa1f0ecfae0acc172e Mon Sep 17 00:00:00 2001
From: Frederic Julian Linz <f.linz@gsi.de>
Date: Mon, 18 Dec 2023 14:43:14 +0000
Subject: [PATCH] Updates to offline reco and at converter binaries

This MR introduced minor updates to the cbmreco_offline and cbm_atconverter binary:
- colored log ouput
- forward declaration of classes in header files
- new function to get cbmsim tree from file
- use consistently "firstTs" and "numTS" to set start event and number of processed events, respectively -STS track matching
---
 .../analysis_tree_converter/app/Application.h |  6 ++--
 .../config/ATConfig_event_ideal.yaml          |  2 ++
 .../config/ATConfig_timeslice.yaml            |  2 ++
 .../analysis_tree_converter/steer/Config.cxx  | 20 +++++++-----
 .../analysis_tree_converter/steer/Config.h    |  3 ++
 .../analysis_tree_converter/steer/Run.cxx     | 21 ++++++++-----
 .../analysis_tree_converter/steer/Run.h       |  3 +-
 .../steer/TaskFactory.cxx                     | 11 +++++++
 .../steer/TaskFactory.h                       |  6 ++--
 macro/run/CMakeLists.txt                      | 20 ++++++------
 reco/offline/app/Application.cxx              |  5 ++-
 reco/offline/app/Application.h                |  3 +-
 reco/offline/app/ProgramOptions.cxx           | 16 +++++-----
 reco/offline/app/ProgramOptions.h             | 22 ++++++-------
 .../config/RecoConfig_event_ideal.yaml        |  3 ++
 .../offline/config/RecoConfig_event_real.yaml |  3 ++
 reco/offline/config/RecoConfig_timeslice.yaml |  3 ++
 reco/offline/steer/Config.cxx                 |  6 ++++
 reco/offline/steer/Config.h                   |  3 ++
 reco/offline/steer/Run.cxx                    | 31 +++++++++++--------
 reco/offline/steer/Run.h                      | 17 +++++-----
 21 files changed, 128 insertions(+), 78 deletions(-)

diff --git a/analysis/common/analysis_tree_converter/app/Application.h b/analysis/common/analysis_tree_converter/app/Application.h
index bd762dd7fa..d125f22428 100644
--- a/analysis/common/analysis_tree_converter/app/Application.h
+++ b/analysis/common/analysis_tree_converter/app/Application.h
@@ -40,9 +40,9 @@ namespace cbm::atconverter
   private:
     const std::string& OutputFile() const;
     const std::string& TraFile() const;
-    const std::string& rawFile() const;
-    const std::string& ParamFile() const;
-    const std::string& recoFile() const;
+    const std::string& RawFile() const;
+    const std::string& ParFile() const;
+    const std::string& RecoFile() const;
     const std::string& SetupTag() const;
     const std::string& ConfigFile() const;
 
diff --git a/analysis/common/analysis_tree_converter/config/ATConfig_event_ideal.yaml b/analysis/common/analysis_tree_converter/config/ATConfig_event_ideal.yaml
index e1a0779f72..81c7c95250 100644
--- a/analysis/common/analysis_tree_converter/config/ATConfig_event_ideal.yaml
+++ b/analysis/common/analysis_tree_converter/config/ATConfig_event_ideal.yaml
@@ -1,12 +1,14 @@
 global:
   log_level: INFO
   log_verbose: LOW
+  log_color: true
   mode: event
   nTimeslices: -1
   firstTimeslice: 0
   timeslicelength: 1.e5
   collisionSystem: "Au+Au"
   beamMomentum: 12.
+  trackMatching: true
 fsdhits:
   gtrackmatch_minChi2: -1
   gtrackmatch_maxChi2: 10000
diff --git a/analysis/common/analysis_tree_converter/config/ATConfig_timeslice.yaml b/analysis/common/analysis_tree_converter/config/ATConfig_timeslice.yaml
index a447f5817a..5a659f91b5 100644
--- a/analysis/common/analysis_tree_converter/config/ATConfig_timeslice.yaml
+++ b/analysis/common/analysis_tree_converter/config/ATConfig_timeslice.yaml
@@ -1,12 +1,14 @@
 global:
   log_level: INFO
   log_verbose: LOW
+  log_color: true
   mode: timeslice
   nTimeslices: -1
   firstTimeslice: 0
   timeslicelength: 1.e5
   collisionSystem: "Au+Au"
   beamMomentum: 12.
+  trackMatching: true
 fsdhits:
   gtrackmatch_minChi2: -1
   gtrackmatch_maxChi2: 10000
diff --git a/analysis/common/analysis_tree_converter/steer/Config.cxx b/analysis/common/analysis_tree_converter/steer/Config.cxx
index 6105e46600..bbe6be1b9a 100644
--- a/analysis/common/analysis_tree_converter/steer/Config.cxx
+++ b/analysis/common/analysis_tree_converter/steer/Config.cxx
@@ -30,14 +30,16 @@ namespace cbm::atconverter
     YAML::Node settings = YAML::LoadFile(fileName);
 
     // --- Global settings
-    f_glb_logLevel   = settings["global"]["log_level"].as<string>();
-    f_glb_logVerbose = settings["global"]["log_verbose"].as<string>();
-    f_glb_mode       = ToCbmRecoMode(settings["global"]["mode"].as<string>());
-    f_glb_numTs      = settings["global"]["nTimeslices"].as<int>();
-    f_glb_firstTs    = settings["global"]["firstTimeslice"].as<int>();
-    f_glb_tslength   = settings["global"]["timeslicelength"].as<float>();
-    f_glb_system     = settings["global"]["collisionSystem"].as<string>();
-    f_glb_beamMom    = settings["global"]["beamMomentum"].as<float>();
+    f_glb_logLevel      = settings["global"]["log_level"].as<string>();
+    f_glb_logVerbose    = settings["global"]["log_verbose"].as<string>();
+    f_glb_logColor      = settings["global"]["log_color"].as<string>();
+    f_glb_mode          = ToCbmRecoMode(settings["global"]["mode"].as<string>());
+    f_glb_numTs         = settings["global"]["nTimeslices"].as<int>();
+    f_glb_firstTs       = settings["global"]["firstTimeslice"].as<int>();
+    f_glb_tslength      = settings["global"]["timeslicelength"].as<float>();
+    f_glb_system        = settings["global"]["collisionSystem"].as<string>();
+    f_glb_beamMom       = settings["global"]["beamMomentum"].as<float>();
+    f_glb_trackMatching = settings["global"]["trackMatching"].as<bool>();
 
     // --- Fsd hits converter settings
     f_fsd_minChi2match = settings["fsdhits"]["gtrackmatch_minChi2"].as<double>();
@@ -80,12 +82,14 @@ namespace cbm::atconverter
     // --- Global settings
     settings["global"]["log_level"]       = f_glb_logLevel;
     settings["global"]["log_verbose"]     = f_glb_logVerbose;
+    settings["global"]["log_color"]       = f_glb_logColor;
     settings["global"]["mode"]            = ToString(f_glb_mode);
     settings["global"]["nTimeslices"]     = f_glb_numTs;
     settings["global"]["firstTimeslice"]  = f_glb_firstTs;
     settings["global"]["timeslicelength"] = f_glb_tslength;
     settings["global"]["collisionSystem"] = f_glb_system;
     settings["global"]["beamMomentum"]    = f_glb_beamMom;
+    settings["global"]["trackMatching"]   = f_glb_trackMatching;
 
     // --- Fsd hits converter settings
     settings["fsdhits"]["gtrackmatch_minChi2"] = f_fsd_minChi2match;
diff --git a/analysis/common/analysis_tree_converter/steer/Config.h b/analysis/common/analysis_tree_converter/steer/Config.h
index ad9d32c7cd..1a2c0814db 100644
--- a/analysis/common/analysis_tree_converter/steer/Config.h
+++ b/analysis/common/analysis_tree_converter/steer/Config.h
@@ -84,6 +84,7 @@ namespace cbm::atconverter
     // --- Global settings
     std::string f_glb_logLevel   = "INFO";
     std::string f_glb_logVerbose = "LOW";
+    std::string f_glb_logColor   = "true";
     ECbmRecoMode f_glb_mode      = ECbmRecoMode::Undefined;
     int f_glb_numTs              = -1;
     int f_glb_firstTs            = 0;
@@ -92,6 +93,8 @@ namespace cbm::atconverter
     std::string f_glb_system = "";
     float f_glb_beamMom      = 12.;
 
+    bool f_glb_trackMatching = true;
+
     // --- Event builder
     ECbmEvbuildType f_evbuild_type = ECbmEvbuildType::Undefined;
 
diff --git a/analysis/common/analysis_tree_converter/steer/Run.cxx b/analysis/common/analysis_tree_converter/steer/Run.cxx
index 70a5aeac6b..9da68a6f0c 100644
--- a/analysis/common/analysis_tree_converter/steer/Run.cxx
+++ b/analysis/common/analysis_tree_converter/steer/Run.cxx
@@ -83,7 +83,7 @@ namespace cbm::atconverter
   {
     TFile* inFile = source->GetInFile();
     if (!inFile) throw std::runtime_error("No input file");
-    TTree* inTree = dynamic_cast<TTree*>(inFile->Get("cbmsim"));
+    auto* inTree = inFile->Get<TTree>("cbmsim");
     if (!inTree) throw std::runtime_error("No input tree");
 
     for (ECbmModuleId detector = ECbmModuleId::kMvd; detector != ECbmModuleId::kNofSystems; ++detector)
@@ -99,6 +99,7 @@ namespace cbm::atconverter
     TaskFactory fact(this);
 
     fact.RegisterMCDataManager(fTra);
+    if (fConfig.f_glb_trackMatching) fact.RegisterTrackMatching();
     fact.RegisterCaTracking();
     fact.RegisterTrdPid();
     fact.RegisterConverterManager(fOutput);
@@ -126,6 +127,11 @@ namespace cbm::atconverter
     // --- Run info
     fRun.SetGenerateRunInfo(true);
 
+    // --- Logger settings
+    FairLogger::GetLogger()->SetLogScreenLevel(fConfig.f_glb_logLevel.data());
+    FairLogger::GetLogger()->SetLogVerbosityLevel(fConfig.f_glb_logVerbose.data());
+    FairLogger::GetLogger()->SetColoredLog(fConfig.f_glb_logColor.data());
+
     // --- Check input, output and parameter files
     if (CheckFile(fOutput.Data()) && !fOverwrite) throw std::runtime_error("Output file already exists");
     if (!CheckFile(fTra.Data())) throw std::runtime_error("Transport file does not exist");
@@ -182,13 +188,12 @@ namespace cbm::atconverter
     FairMonitor::GetMonitor()->Print();
     std::cout << std::endl << std::endl;
     LOG(info) << GetName() << ": Execution successful";
-    LOG(info) << GetName() << ": Reconstruction file was   " << fReco;
-    LOG(info) << GetName() << ": Transport file file is    " << fTra;
-    ;
-    LOG(info) << GetName() << ": Parameter file is         " << fPar;
-    LOG(info) << GetName() << ": Digitization file file is " << fRaw;
-    LOG(info) << GetName() << ": Output file is            " << fOutput;
-    LOG(info) << GetName() << ": Execution time: Init      " << timeInit << " s, Exec " << timeExec << "s";
+    LOG(info) << GetName() << ": Transport file was      " << fTra;
+    LOG(info) << GetName() << ": Digitization file was   " << fRaw;
+    LOG(info) << GetName() << ": Parameter file was      " << fPar;
+    LOG(info) << GetName() << ": Reconstruction file was " << fReco;
+    LOG(info) << GetName() << ": Output file is          " << fOutput;
+    LOG(info) << GetName() << ": Execution time: Init    " << timeInit << " s, Exec " << timeExec << "s";
   }
   // --------------------------------------------------------------------------
 
diff --git a/analysis/common/analysis_tree_converter/steer/Run.h b/analysis/common/analysis_tree_converter/steer/Run.h
index 2c5b10b9df..08ec6f0faa 100644
--- a/analysis/common/analysis_tree_converter/steer/Run.h
+++ b/analysis/common/analysis_tree_converter/steer/Run.h
@@ -17,12 +17,13 @@
 
 #include <TNamed.h>
 #include <TString.h>
-#include <TTree.h>
 
 #include <string>
 
 class CbmSetup;
 class FairTask;
+class FairFileSource;
+class TTree;
 
 namespace cbm::atconverter
 {
diff --git a/analysis/common/analysis_tree_converter/steer/TaskFactory.cxx b/analysis/common/analysis_tree_converter/steer/TaskFactory.cxx
index 519a8f933b..373e99b45f 100644
--- a/analysis/common/analysis_tree_converter/steer/TaskFactory.cxx
+++ b/analysis/common/analysis_tree_converter/steer/TaskFactory.cxx
@@ -16,6 +16,7 @@
 #include "CbmL1.h"
 #include "CbmMCDataManager.h"
 #include "CbmMatchEvents.h"
+#include "CbmMatchRecoToMC.h"
 #include "CbmPsdModulesConverter.h"
 #include "CbmRecEventHeaderConverter.h"
 #include "CbmRichRingsConverter.h"
@@ -115,6 +116,16 @@ namespace cbm::atconverter
   // --------------------------------------------------------------------------
 
 
+  // -----   STS track matching   ---------------------------------------------
+  void TaskFactory::RegisterTrackMatching()
+  {
+    assert(fRun);
+
+    auto* matchTask = new CbmMatchRecoToMC();
+    fRun->AddTask(matchTask);
+  }
+  // --------------------------------------------------------------------------
+
   // -----   TID PID   --------------------------------------------------------
   void TaskFactory::RegisterTrdPid()
   {
diff --git a/analysis/common/analysis_tree_converter/steer/TaskFactory.h b/analysis/common/analysis_tree_converter/steer/TaskFactory.h
index bdc2ec3181..876637cbcd 100644
--- a/analysis/common/analysis_tree_converter/steer/TaskFactory.h
+++ b/analysis/common/analysis_tree_converter/steer/TaskFactory.h
@@ -38,12 +38,12 @@ namespace cbm::atconverter
      **/
     void RegisterConverterManager(const TString& outputFile);
 
-    void RegisterCaTracking();  /// CA track finding
-    void RegisterTrdPid();      /// PID with TRD
+    void RegisterCaTracking();     /// CA track finding
+    void RegisterTrackMatching();  /// STS track matching
+    void RegisterTrdPid();         /// PID with TRD
 
    private:  //members
     Run* fRun        = nullptr;
-    //bool hitMatching = false;
   };
 
 }  // namespace cbm::atconverter
diff --git a/macro/run/CMakeLists.txt b/macro/run/CMakeLists.txt
index e80f3b9dbe..12bc7acfa1 100644
--- a/macro/run/CMakeLists.txt
+++ b/macro/run/CMakeLists.txt
@@ -180,11 +180,11 @@ foreach(setup IN LISTS cbm_setup)
   # --- Ideal raw event builder
   set(testname run_${sname}_reco_offline_ev_ideal)
   set(binary ${CBMROOT_BINARY_DIR}/bin/cbmreco_offline.sh)
-  set(inputname data/${sname}_ev.raw.root)
+  set(rawfilename data/${sname}_ev.raw.root)
   set(parfilename data/${sname}_coll.par.root)
   set(outputname data/${sname}_offline_ev_ideal.reco.root)
   set(configname ${CBMROOT_SOURCE_DIR}/reco/offline/config/RecoConfig_event_ideal.yaml)
-  set(cl_options -i ${inputname} -o ${outputname} -p ${parfilename} -c ${configname} -s ${setup} -w)
+  set(cl_options -d ${rawfilename} -o ${outputname} -p ${parfilename} -c ${configname} -s ${setup} -w)
   add_test(NAME ${testname} COMMAND ${binary} ${cl_options})
   set_tests_properties(${testname} PROPERTIES
     TIMEOUT ${timeOutTime}
@@ -214,11 +214,11 @@ foreach(setup IN LISTS cbm_setup)
   # --- Real raw event builder
   set(testname run_${sname}_reco_offline_ev_real)
   set(binary ${CBMROOT_BINARY_DIR}/bin/cbmreco_offline.sh)
-  set(inputname data/${sname}_ev.raw.root)
+  set(rawfilename data/${sname}_ev.raw.root)
   set(parfilename data/${sname}_coll.par.root)
   set(outputname data/${sname}_offline_ev_real.reco.root)
   set(configname ${CBMROOT_SOURCE_DIR}/reco/offline/config/RecoConfig_event_real.yaml)
-  set(cl_options -i ${inputname} -o ${outputname} -p ${parfilename} -c ${configname} -s ${setup} -w)
+  set(cl_options -d ${rawfilename} -o ${outputname} -p ${parfilename} -c ${configname} -s ${setup} -w)
   add_test(NAME ${testname} COMMAND ${binary} ${cl_options})
   set_tests_properties(${testname} PROPERTIES
     TIMEOUT ${timeOutTime}
@@ -248,11 +248,11 @@ foreach(setup IN LISTS cbm_setup)
   # --- Real raw event builder
   set(testname run_${sname}_reco_offline_ts_eb_ideal)
   set(binary ${CBMROOT_BINARY_DIR}/bin/cbmreco_offline.sh)
-  set(inputname data/${sname}_ts.raw.root)
+  set(rawfilename data/${sname}_ts.raw.root)
   set(parfilename data/${sname}_coll.par.root)
   set(outputname data/${sname}_offline_ts_eb_ideal.reco.root)
   set(configname ${CBMROOT_SOURCE_DIR}/reco/offline/config/RecoConfig_event_ideal.yaml)
-  set(cl_options -i ${inputname} -o ${outputname} -p ${parfilename} -c ${configname} -s ${setup} -w)
+  set(cl_options -d ${rawfilename} -o ${outputname} -p ${parfilename} -c ${configname} -s ${setup} -w)
   add_test(NAME ${testname} COMMAND ${binary} ${cl_options})
   set_tests_properties(${testname} PROPERTIES
     TIMEOUT ${timeOutTime}
@@ -282,11 +282,11 @@ foreach(setup IN LISTS cbm_setup)
   # --- Real raw event builder
   set(testname run_${sname}_reco_offline_ts_eb_real)
   set(binary ${CBMROOT_BINARY_DIR}/bin/cbmreco_offline.sh)
-  set(inputname data/${sname}_ts.raw.root)
+  set(rawfilename data/${sname}_ts.raw.root)
   set(parfilename data/${sname}_coll.par.root)
   set(outputname data/${sname}_offline_ts_eb_real.reco.root)
   set(configname ${CBMROOT_SOURCE_DIR}/reco/offline/config/RecoConfig_event_real.yaml)
-  set(cl_options -i ${inputname} -o ${outputname} -p ${parfilename} -c ${configname} -s ${setup} -w)
+  set(cl_options -d ${rawfilename} -o ${outputname} -p ${parfilename} -c ${configname} -s ${setup} -w)
   add_test(NAME ${testname} COMMAND ${binary} ${cl_options})
   set_tests_properties(${testname} PROPERTIES
     TIMEOUT ${timeOutTime}
@@ -331,11 +331,11 @@ foreach(setup IN LISTS cbm_setup)
   # --- Time-based reconstruction from time-based simulation, with binary cbmreco_offline
   set(testname run_${sname}_reco_offline_ts_tb)
   set(binary ${CBMROOT_BINARY_DIR}/bin/cbmreco_offline.sh)
-  set(inputname data/${sname}_ts.raw.root)
+  set(rawfilename data/${sname}_ts.raw.root)
   set(parfilename data/${sname}_coll.par.root)
   set(outputname data/${sname}_offline_ts_tb.reco.root)
   set(configname ${CBMROOT_SOURCE_DIR}/reco/offline/config/RecoConfig_timeslice.yaml)
-  set(cl_options -i ${inputname} -o ${outputname} -p ${parfilename} -c ${configname} -s ${setup} -w)
+  set(cl_options -d ${rawfilename} -o ${outputname} -p ${parfilename} -c ${configname} -s ${setup} -w)
   add_test(NAME ${testname} COMMAND ${binary} ${cl_options})
   set_tests_properties(${testname} PROPERTIES
     TIMEOUT ${timeOutTime}
diff --git a/reco/offline/app/Application.cxx b/reco/offline/app/Application.cxx
index cc31543a13..2cccaf6e58 100644
--- a/reco/offline/app/Application.cxx
+++ b/reco/offline/app/Application.cxx
@@ -26,11 +26,10 @@ namespace cbm::reco::offline
   {
 
     // --- Use program options
-    fRun.SetInput(fOpt.InputFile().c_str());
     fRun.SetOutput(fOpt.OutputFile().c_str());
-    fRun.SetParams(fOpt.ParamFile().c_str());
+    fRun.SetRawFile(fOpt.RawFile().c_str());
+    fRun.SetParFile(fOpt.ParFile().c_str());
     fRun.SetGeoSetupTag(fOpt.SetupTag().c_str());
-    fRun.SetNumTs(fOpt.MaxNumTs());
     if (fOpt.Overwrite()) fRun.AllowOverwrite();
 
     // --- Read configuration from YAML file
diff --git a/reco/offline/app/Application.h b/reco/offline/app/Application.h
index 650a74327d..44ee4b630b 100644
--- a/reco/offline/app/Application.h
+++ b/reco/offline/app/Application.h
@@ -39,7 +39,8 @@ namespace cbm::reco::offline
 
   private:
     const std::string& OutputFile() const;
-    const std::string& ParamFile() const;
+    const std::string& RawFile() const;
+    const std::string& ParFile() const;
     const std::string& SetupTag() const;
     const std::string& ConfigFile() const;
 
diff --git a/reco/offline/app/ProgramOptions.cxx b/reco/offline/app/ProgramOptions.cxx
index 1b9740bd8d..2e8fd5b4bb 100644
--- a/reco/offline/app/ProgramOptions.cxx
+++ b/reco/offline/app/ProgramOptions.cxx
@@ -39,18 +39,16 @@ namespace cbm::reco::offline
     defconfig.append(DEFAULT_CONFIG);
     po::options_description config("Configuration");
     auto config_add = config.add_options();
-    config_add("input,i", po::value<string>(&fInput)->value_name("<file name>"),
-               "name of the input ROOT file containing digi data");
     config_add("output,o", po::value<string>(&fOutput)->value_name("<file name>"),
                "name of the output ROOT file with reconstructed data");
-    config_add("params,p", po::value<string>(&fParam)->value_name("<file name>"),
+    config_add("digitization,d", po::value<string>(&fRaw)->value_name("<file name>"),
+               "name of the raw ROOT file containing digi data");
+    config_add("parameter,p", po::value<string>(&fPar)->value_name("<file name>"),
                "name of a parameter ROOT file (FairRuntimeDb format)");
     config_add("config,c", po::value<string>(&fConfig)->value_name("<file name>")->default_value(defconfig),
                "name of a YAML file describing the configuration of reconstruction");
     config_add("setup,s", po::value<string>(&fSetup)->value_name("<tag>")->default_value(DEFAULT_SETUP),
                "geometry setup tag");
-    config_add("max-timeslice-number,n", po::value<int32_t>(&fMaxNumTs)->value_name("<n>")->default_value(INT32_MAX),
-               "maximum number of timeslices to process (default: all in input file)");
     config_add("overwrite,w", po::bool_switch(&fOverwrite)->default_value(false),
                "allow to overwite an existing output file");
 
@@ -70,9 +68,13 @@ namespace cbm::reco::offline
     }
 
     // --- Catch mandatory parameters not being specified
-    if (vars.count("input") == 0u) { throw std::runtime_error("no input file name specified"); }
     if (vars.count("output") == 0u) { throw std::runtime_error("no output file name specified"); }
-    if (vars.count("params") == 0u) { throw std::runtime_error("no parameter file name specified"); }
+    if (vars.count("digitization") == 0u) {
+      throw std::runtime_error("no digitization (raw) file name specified");
+    }
+    if (vars.count("parameter") == 0u) {
+      throw std::runtime_error("no parameter file name specified");
+    }
   }
   // --------------------------------------------------------------------------
 
diff --git a/reco/offline/app/ProgramOptions.h b/reco/offline/app/ProgramOptions.h
index cb5bdbda5d..814112dbc3 100644
--- a/reco/offline/app/ProgramOptions.h
+++ b/reco/offline/app/ProgramOptions.h
@@ -41,8 +41,8 @@ namespace cbm::reco::offline
     /** @brief Destructor **/
     ~ProgramOptions() = default;
 
-    /** @brief Get input file name **/
-    [[nodiscard]] const std::string& InputFile() const { return fInput; }
+    /** @brief Get digitization (raw) file name **/
+    [[nodiscard]] const std::string& RawFile() const { return fRaw; }
 
     /** @brief Get output file name (.root format) **/
     [[nodiscard]] const std::string& OutputFile() const { return fOutput; }
@@ -54,14 +54,11 @@ namespace cbm::reco::offline
     [[nodiscard]] bool Overwrite() const { return fOverwrite; }
 
     /** @brief Get parameter file name **/
-    [[nodiscard]] const std::string& ParamFile() const { return fParam; }
+    [[nodiscard]] const std::string& ParFile() const { return fPar; }
 
     /** @brief Get geometry setup tag **/
     [[nodiscard]] const std::string& SetupTag() const { return fSetup; }
 
-    /** @brief Get maximum number of timeslices to process **/
-    [[nodiscard]] int32_t MaxNumTs() const { return fMaxNumTs; }
-
 
   private:
     /** @brief Parse command line arguments using boost program_options **/
@@ -69,13 +66,12 @@ namespace cbm::reco::offline
 
 
   private:                            // members
-    std::string fInput  = "";         ///< Input file name (ROOT format)
-    std::string fOutput = "";         ///< Output file name (ROOT format)
-    std::string fParam  = "";         ///< Parameter file name (ROOT format)
-    std::string fConfig = "";         ///< Configuration file name (YAML format)
-    std::string fSetup  = "";         ///< Geometry setup tag
-    int32_t fMaxNumTs   = INT32_MAX;  ///< Maximum number of timeslices to process
-    bool fOverwrite     = false;      ///< Enable overwriting of existing output file
+   std::string fRaw    = "";          ///< Input raw (digi) file name (ROOT format)
+   std::string fOutput = "";          ///< Output file name (ROOT format)
+   std::string fPar    = "";          ///< Parameter file name (ROOT format)
+   std::string fConfig = "";          ///< Configuration file name (YAML format)
+   std::string fSetup  = "";          ///< Geometry setup tag
+   bool fOverwrite     = false;       ///< Enable overwriting of existing output file
   };
 
 }  // namespace cbm::reco::offline
diff --git a/reco/offline/config/RecoConfig_event_ideal.yaml b/reco/offline/config/RecoConfig_event_ideal.yaml
index 28c0cd9378..1857bd9b9b 100644
--- a/reco/offline/config/RecoConfig_event_ideal.yaml
+++ b/reco/offline/config/RecoConfig_event_ideal.yaml
@@ -1,7 +1,10 @@
 global:
   log_level: INFO
   log_verbose: LOW
+  log_color: true
   mode: event
+  nTimeslices: -1
+  firstTimeslice: 0
 evbuild:
   type: ideal
   overlap: allow
diff --git a/reco/offline/config/RecoConfig_event_real.yaml b/reco/offline/config/RecoConfig_event_real.yaml
index b98ef71727..044320dedf 100644
--- a/reco/offline/config/RecoConfig_event_real.yaml
+++ b/reco/offline/config/RecoConfig_event_real.yaml
@@ -1,7 +1,10 @@
 global:
   log_level: INFO
   log_verbose: LOW
+  log_color: true
   mode: event
+  nTimeslices: -1
+  firstTimeslice: 0
 evbuild:
   type: real
   overlap: allow
diff --git a/reco/offline/config/RecoConfig_timeslice.yaml b/reco/offline/config/RecoConfig_timeslice.yaml
index 890a9751f5..210511b774 100644
--- a/reco/offline/config/RecoConfig_timeslice.yaml
+++ b/reco/offline/config/RecoConfig_timeslice.yaml
@@ -1,7 +1,10 @@
 global:
   log_level: INFO
   log_verbose: LOW
+  log_color: true
   mode: timeslice
+  nTimeslices: -1
+  firstTimeslice: 0
 evbuild:
   type: ideal
   overlap: allow
diff --git a/reco/offline/steer/Config.cxx b/reco/offline/steer/Config.cxx
index 82aa9cc6b4..f8e603c122 100644
--- a/reco/offline/steer/Config.cxx
+++ b/reco/offline/steer/Config.cxx
@@ -32,7 +32,10 @@ namespace cbm::reco::offline
     // --- Global settings
     f_glb_logLevel   = settings["global"]["log_level"].as<string>();
     f_glb_logVerbose = settings["global"]["log_verbose"].as<string>();
+    f_glb_logColor   = settings["global"]["log_color"].as<string>();
     f_glb_mode       = ToCbmRecoMode(settings["global"]["mode"].as<string>());
+    f_glb_numTs      = settings["global"]["nTimeslices"].as<Int_t>();
+    f_glb_firstTs    = settings["global"]["firstTimeslice"].as<Int_t>();
 
     // --- Event builder
     f_evbuild_type       = ToCbmEvbuildType(settings["evbuild"]["type"].as<string>());
@@ -146,7 +149,10 @@ namespace cbm::reco::offline
     // --- Global settings
     settings["global"]["log_level"]   = f_glb_logLevel;
     settings["global"]["log_verbose"] = f_glb_logVerbose;
+    settings["global"]["log_color"]      = f_glb_logColor;
     settings["global"]["mode"]        = ToString(f_glb_mode);
+    settings["global"]["nTimeslices"]    = f_glb_numTs;
+    settings["global"]["firstTimeslice"] = f_glb_firstTs;
 
     // --- Event builder
     settings["evbuild"]["type"]            = ToString(f_evbuild_type);
diff --git a/reco/offline/steer/Config.h b/reco/offline/steer/Config.h
index a013033884..0b6e13dcd5 100644
--- a/reco/offline/steer/Config.h
+++ b/reco/offline/steer/Config.h
@@ -89,7 +89,10 @@ namespace cbm::reco::offline
     // --- Global settings
     std::string f_glb_logLevel   = "INFO";
     std::string f_glb_logVerbose = "LOW";
+    std::string f_glb_logColor   = "true";
     ECbmRecoMode f_glb_mode      = ECbmRecoMode::Undefined;
+    Int_t f_glb_numTs            = -1;
+    Int_t f_glb_firstTs          = 0;
 
     // --- Event builder
     ECbmEvbuildType f_evbuild_type      = ECbmEvbuildType::Undefined;
diff --git a/reco/offline/steer/Run.cxx b/reco/offline/steer/Run.cxx
index 94d12c10bd..3ba8147ca4 100644
--- a/reco/offline/steer/Run.cxx
+++ b/reco/offline/steer/Run.cxx
@@ -84,7 +84,7 @@ namespace cbm::reco::offline
 
     TFile* inFile = source->GetInFile();
     if (!inFile) throw std::runtime_error("No input file");
-    TTree* inTree = dynamic_cast<TTree*>(inFile->Get("cbmsim"));
+    auto* inTree = inFile->Get<TTree>("cbmsim");
     if (!inTree) throw std::runtime_error("No input tree");
 
     for (ECbmModuleId detector = ECbmModuleId::kMvd; detector != ECbmModuleId::kNofSystems; ++detector)
@@ -141,10 +141,10 @@ namespace cbm::reco::offline
   {
 
     // --- Mirror options and configuration
-    LOG(info) << GetName() << ": Input file is     " << fInput;
-    LOG(info) << GetName() << ": Parameter file is " << fParams;
-    LOG(info) << GetName() << ": Output file is    " << fOutput;
-    LOG(info) << GetName() << ": Geometry setup is " << fSetupTag;
+    LOG(info) << GetName() << ": Output file is       " << fOutput;
+    LOG(info) << GetName() << ": Digitization file is " << fRaw;
+    LOG(info) << GetName() << ": Parameter file is    " << fPar;
+    LOG(info) << GetName() << ": Geometry setup is    " << fSetupTag;
     LOG(info) << "Configuration: \n" << fConfig.ToString();
 
     // --- Timer
@@ -154,13 +154,18 @@ namespace cbm::reco::offline
     // --- Run info
     fRun.SetGenerateRunInfo(true);
 
+    // --- Logger settings
+    FairLogger::GetLogger()->SetLogScreenLevel(fConfig.f_glb_logLevel.data());
+    FairLogger::GetLogger()->SetLogVerbosityLevel(fConfig.f_glb_logVerbose.data());
+    FairLogger::GetLogger()->SetColoredLog(fConfig.f_glb_logColor.data());
+
     // --- Check input, output and parameter files
-    if (!CheckFile(fInput.Data())) throw std::runtime_error("Input file does not exist");
-    if (!CheckFile(fParams.Data())) throw std::runtime_error("Parameter file does not exist");
+    if (!CheckFile(fRaw.Data())) throw std::runtime_error("Digitization (raw) file does not exist");
+    if (!CheckFile(fPar.Data())) throw std::runtime_error("Parameter file does not exist");
     if (CheckFile(fOutput.Data()) && !fOverwrite) throw std::runtime_error("Output file already exists");
 
     // --- Input and output
-    FairFileSource* source = new FairFileSource(fInput);
+    FairFileSource* source = new FairFileSource(fRaw);
     fRun.SetSource(source);
     fRun.SetSink(new FairRootFileSink(fOutput));
 
@@ -182,7 +187,7 @@ namespace cbm::reco::offline
     LOG(info) << GetName() << ": Set runtime DB...";
     FairRuntimeDb* rtdb       = fRun.GetRuntimeDb();
     FairParRootFileIo* parIo1 = new FairParRootFileIo();
-    parIo1->open(fParams.Data(), "UPDATE");
+    parIo1->open(fPar.Data(), "UPDATE");
     rtdb->setFirstInput(parIo1);
 
     // --- Initialisation
@@ -200,7 +205,7 @@ namespace cbm::reco::offline
     // --- Execute run
     std::cout << std::endl << std::endl;
     LOG(info) << GetName() << ": Starting run" << std::endl;
-    fRun.Run(fNumTs, 0);
+    fRun.Run(fConfig.f_glb_firstTs, fConfig.f_glb_numTs);
 
     // --- Finish
     timer.Stop();
@@ -208,9 +213,9 @@ namespace cbm::reco::offline
     FairMonitor::GetMonitor()->Print();
     std::cout << std::endl << std::endl;
     LOG(info) << GetName() << ": Execution successful";
-    LOG(info) << GetName() << ": Input file was    " << fInput;
-    LOG(info) << GetName() << ": Parameter file is " << fParams;
-    LOG(info) << GetName() << ": Output file is    " << fOutput;
+    LOG(info) << GetName() << ": Digitization file was " << fRaw;
+    LOG(info) << GetName() << ": Parameter file was    " << fPar;
+    LOG(info) << GetName() << ": Output file is        " << fOutput;
     LOG(info) << GetName() << ": Execution time: Init " << timeInit << " s, Exec " << timeExec << "s";
   }
   // --------------------------------------------------------------------------
diff --git a/reco/offline/steer/Run.h b/reco/offline/steer/Run.h
index 6c819ad499..0e8387df43 100644
--- a/reco/offline/steer/Run.h
+++ b/reco/offline/steer/Run.h
@@ -15,7 +15,6 @@
 #include <FairRunAna.h>
 
 #include <TNamed.h>
-#include <TTree.h>
 
 #include <string>
 
@@ -24,6 +23,8 @@
 class TGeoManager;
 class CbmSetup;
 class FairTask;
+class FairFileSource;
+class TTree;
 
 namespace cbm::reco::offline
 {
@@ -83,10 +84,10 @@ namespace cbm::reco::offline
     void SetGeoSetupTag(const char* tag) { fSetupTag = tag; }
 
 
-    /** @brief Set input file name
-     ** @param fileName  Input file name
+    /** @brief Set digitization (raw) file name
+     ** @param fileName  Digi (raw) file name
      **/
-    void SetInput(const char* fileName) { fInput = fileName; }
+    void SetRawFile(const char* fileName) { fRaw = fileName; }
 
 
     /** @brief Set number of timeslices to process
@@ -104,10 +105,10 @@ namespace cbm::reco::offline
     /** @brief Set parameter file name
      ** @param fileName  Parameter file name
      **/
-    void SetParams(const char* fileName) { fParams = fileName; }
+    void SetParFile(const char* fileName) { fPar = fileName; }
 
 
-  private:
+   private:
     /** @brief Copy constructor forbidden **/
     Run(const Run&) = delete;
 
@@ -140,9 +141,9 @@ namespace cbm::reco::offline
 
   private:
     FairRunAna fRun {};
-    TString fInput    = "";
-    TString fParams   = "";
     TString fOutput   = "";
+    TString fRaw      = "";
+    TString fPar      = "";
     TString fSetupTag = "";
     CbmSetup* fSetup  = nullptr;
     size_t fNumTs     = 0;
-- 
GitLab