From 9d659403717018d330b77942e520ddce5e9e3ca1 Mon Sep 17 00:00:00 2001
From: "s.zharko@gsi.de" <s.zharko@gsi.de>
Date: Tue, 12 Mar 2024 23:13:57 +0100
Subject: [PATCH] ca: Timers update and monitor serialization

---
 algo/ca/TrackingChain.cxx                     | 34 ++++++---
 algo/ca/TrackingChain.h                       |  2 +
 algo/ca/TrackingChainConfig.h                 | 13 +++-
 algo/ca/core/tracking/CaTrackFinder.cxx       | 20 +++--
 algo/ca/core/tracking/CaTrackFinderWindow.cxx | 18 +++--
 algo/ca/core/utils/CaEnumArray.h              | 11 +++
 algo/ca/core/utils/CaMonitor.h                | 16 ++++
 algo/ca/core/utils/CaMonitorData.h            | 10 +++
 algo/ca/core/utils/CaTimer.h                  | 14 ++++
 algo/ca/core/utils/CaTrackingMonitor.h        | 74 ++++++++++++-------
 algo/global/Reco.cxx                          |  4 +-
 reco/L1/L1LinkDef.h                           |  1 +
 12 files changed, 159 insertions(+), 58 deletions(-)

diff --git a/algo/ca/TrackingChain.cxx b/algo/ca/TrackingChain.cxx
index 4136c65fcd..17bfefa3ff 100644
--- a/algo/ca/TrackingChain.cxx
+++ b/algo/ca/TrackingChain.cxx
@@ -13,10 +13,11 @@
 #include "CaHit.h"
 #include "CaInitManager.h"
 #include "CaParameters.h"
-#include "TrackingChainConfig.h"
 #include "tof/Config.h"
 #include "yaml/Yaml.h"
 
+#include <boost/archive/text_oarchive.hpp>
+
 #include <fstream>
 #include <unordered_map>
 
@@ -49,10 +50,10 @@ TrackingChain::TrackingChain(std::shared_ptr<HistogramSender> histoSender)
 void TrackingChain::Init()
 {
   // ------ Read tracking chain parameters from the config
-  auto config = yaml::ReadFromFile<TrackingChainConfig>(Opts().ParamsDir() / "CaConfig.yaml");
+  fConfig = yaml::ReadFromFile<TrackingChainConfig>(Opts().ParamsDir() / "CaConfig.yaml");
 
   // ------ Read parameters from binary
-  auto paramFile = Opts().ParamsDir() / config.fsParName;
+  auto paramFile = Opts().ParamsDir() / fConfig.fsParName;
   L_(info) << "Tracking Chain: reading CA parameters file " << GNb << paramFile.string() << CL << '\n';
   auto manager = InitManager{};
   manager.ReadParametersObject(paramFile.string());
@@ -61,7 +62,7 @@ void TrackingChain::Init()
 
   // ------ Initialize CA framework
   fCaMonitor.Reset();
-  fCaFramework.SetNofThreads(config.fNofThreads);
+  fCaFramework.SetNofThreads(fConfig.fNofThreads);
   fCaFramework.Init(ca::Framework::TrackingMode::kMcbm);
   fCaFramework.ReceiveParameters(std::move(parameters));
 
@@ -100,7 +101,16 @@ TrackingChain::Output_t TrackingChain::Run(Input_t recoResults)
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-void TrackingChain::Finalize() { L_(info) << fCaMonitor.ToString(); }
+void TrackingChain::Finalize()
+{
+  L_(info) << fCaMonitor.ToString();
+  if (fConfig.fbStoreMonitor) {
+    auto fileName = "./" + fConfig.fsMoniOutName;
+    std::ofstream ofs(fileName);
+    boost::archive::text_oarchive oa(ofs);
+    oa << fCaMonitor;
+  }
+}
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
@@ -155,8 +165,6 @@ TrackingChain::Output_t TrackingChain::PrepareOutput()
            << fCaMonitorData.GetCounterValue(ca::ECounter::RecoTofHit) << " tof hits; the FindTracks routine ran "
            << fCaMonitorData.GetTimer(ca::ETimer::FindTracks).GetTotal() << " s";
 
-  fCaMonitor.AddMonitorData(fCaMonitorData);
-  output.monitorData = fCaMonitorData;
 
   // QA
   if (fInputQa.IsSenderDefined()) {
@@ -167,12 +175,16 @@ TrackingChain::Output_t TrackingChain::PrepareOutput()
   }
 
   if (fOutputQa.IsSenderDefined()) {
-    fOutputQa.RegisterInputData(&fCaFramework.GetInputData());
-    fOutputQa.RegisterTracks(&output.tracks);
-    fOutputQa.RegisterRecoHitIndices(&fCaFramework.fRecoHits);
-    fOutputQa.Exec();
+    fCaMonitorData.StartTimer(ca::ETimer::OutputQa);
+    fQaBuilder.RegisterInputData(&fCaFramework.GetInputData());
+    fQaBuilder.RegisterTracks(&output.tracks);
+    fQaBuilder.RegisterRecoHitIndices(&fCaFramework.fRecoHits);
+    fQaBuilder.Build();
+    fCaMonitorData.StopTimer(ca::ETimer::OutputQa);
   }
 
+  fCaMonitor.AddMonitorData(fCaMonitorData);
+  output.monitorData = fCaMonitorData;
 
   return output;
 }
diff --git a/algo/ca/TrackingChain.h b/algo/ca/TrackingChain.h
index ec6bf2644d..9adc9528da 100644
--- a/algo/ca/TrackingChain.h
+++ b/algo/ca/TrackingChain.h
@@ -20,6 +20,7 @@
 #include "PartitionedSpan.h"
 #include "RecoResults.h"
 #include "SubChain.h"
+#include "TrackingChainConfig.h"
 #include "TrackingDefs.h"
 #include "sts/Hit.h"
 #include "tof/Hit.h"
@@ -109,6 +110,7 @@ namespace cbm::algo
     // ************************
     // **  Auxilary variables
 
+    TrackingChainConfig fConfig;        ///< Tracking config
     ca::HitKeyIndex_t fNofHitKeys = 0;  ///< Current number of hit keys (aux)
 
     /// \brief External indices of used hits
diff --git a/algo/ca/TrackingChainConfig.h b/algo/ca/TrackingChainConfig.h
index a6844f09b8..3f57a3a852 100644
--- a/algo/ca/TrackingChainConfig.h
+++ b/algo/ca/TrackingChainConfig.h
@@ -19,10 +19,15 @@ namespace cbm::algo
   /// \struct TrackingChainConfig
   /// \brief Configuration reader for the TrackingChain class
   struct TrackingChainConfig {
-    int fNofThreads;        ///< Number of threads for tracking
-    std::string fsParName;  ///< Tracking parameter file name
+    std::string fsParName;      ///< Tracking parameter file name
+    std::string fsMoniOutName;  ///< Monitor output file name
+    int fNofThreads;            ///< Number of threads for tracking
+    bool fbStoreMonitor;        ///< Stores monitor snapshot
 
-    CBM_YAML_PROPERTIES(yaml::Property(&TrackingChainConfig::fNofThreads, "NofThreads", "Number of threads"),
-                      yaml::Property(&TrackingChainConfig::fsParName, "ParName", "CA parameters input"));
+    CBM_YAML_PROPERTIES(
+                      yaml::Property(&TrackingChainConfig::fsParName, "ParName", "CA parameters input"),
+                      yaml::Property(&TrackingChainConfig::fsMoniOutName, "MoniOutName", "Monitor output"),
+                      yaml::Property(&TrackingChainConfig::fNofThreads, "NofThreads", "Number of threads"),
+                      yaml::Property(&TrackingChainConfig::fbStoreMonitor, "StoreMonitor", "If store monitor"));
   };
 }  // namespace cbm::algo
diff --git a/algo/ca/core/tracking/CaTrackFinder.cxx b/algo/ca/core/tracking/CaTrackFinder.cxx
index a18dec3502..b40cef2c67 100644
--- a/algo/ca/core/tracking/CaTrackFinder.cxx
+++ b/algo/ca/core/tracking/CaTrackFinder.cxx
@@ -55,6 +55,8 @@ void TrackFinder::FindTracks()
 
   auto timerStart = std::chrono::high_resolution_clock::now();
 
+  frAlgo.fMonitorData.StartTimer(ETimer::PrepareDataStreams);
+
   // ----- Reset data arrays -------------------------------------------------------------------------------------------
   size_t nHitsExpected   = 2 * frAlgo.fInputData.GetNhits();
   size_t nTracksExpected = 2 * frAlgo.fInputData.GetNhits() / frAlgo.GetParameters().GetNstationsActive();
@@ -215,6 +217,7 @@ void TrackFinder::FindTracks()
     LOG(info) << "Thread: " << iThread << " from " << fvWindowStartThread[iThread] / 1.e6 << " ms  to "
               << fvWindowEndThread[iThread] / 1.e6 << " ms";
   }
+  frAlgo.fMonitorData.StopTimer(ETimer::PrepareDataStreams);
 
   // Save tracks
   frAlgo.fRecoTracks.clear();
@@ -275,6 +278,8 @@ void TrackFinder::FindTracks()
 void TrackFinder::FindTracksThread(int iThread)
 {
   LOG(info) << "---- CA: searching for tracks on thread " << iThread;
+  frAlgo.fMonitorData.StartTimer(ETimer::FindTracksThread);
+
   const int nDataStreams    = frAlgo.fInputData.GetNdataStreams();
   bool areUntouchedDataLeft = true;  // is the whole TS processed
   std::vector<HitIndex_t> sliceFirstHit(nDataStreams, 0);
@@ -321,8 +326,7 @@ void TrackFinder::FindTracksThread(int iThread)
 
     int statNwindowHits = 0;
 
-    Timer tHitInit;
-    tHitInit.Start();
+    frAlgo.fMonitorData.StartTimer(ETimer::PrepareHitsWindow);
     for (int iStream = 0; iStream < nDataStreams; ++iStream) {
       for (ca::HitIndex_t caHitId = sliceFirstHit[iStream]; caHitId < sliceLastHit[iStream]; ++caHitId) {
         const CaHitTimeInfo& info = frAlgo.fHitTimeInfo[caHitId];
@@ -352,7 +356,7 @@ void TrackFinder::FindTracksThread(int iThread)
       }
     }
     fvStatNhitsProcessed[iThread] += statNwindowHits;
-    tHitInit.Stop();
+    frAlgo.fMonitorData.StopTimer(ETimer::PrepareHitsWindow);
 
     // print the LOG for every 10 ms of data processed
     {
@@ -383,12 +387,9 @@ void TrackFinder::FindTracksThread(int iThread)
       }
     }
 
-    Timer tTracking;
-    tTracking.Start();
-    frAlgo.fMonitorData.StartTimer(ETimer::TrackFinder);
+    frAlgo.fMonitorData.StartTimer(ETimer::TrackFinderWindow);
     frAlgo.fvTrackFinderWindow[iThread].CaTrackFinderSlice();
-    frAlgo.fMonitorData.StopTimer(ETimer::TrackFinder);
-    tTracking.Stop();
+    frAlgo.fMonitorData.StopTimer(ETimer::TrackFinderWindow);
 
     // save reconstructed tracks with no hits in the overlap region
     //if (fvWindowStartThread[iThread] > 13.23e6 && fvWindowStartThread[iThread] < 13.26e6) {
@@ -397,6 +398,7 @@ void TrackFinder::FindTracksThread(int iThread)
     // we do it in a simple way by extending the tsStartNew
     // TODO: only add those hits from the region before tsStartNew that belong to the not stored tracks
 
+    frAlgo.fMonitorData.StartTimer(ETimer::StoreTracksWindow);
     int trackFirstHit = 0;
     for (const auto& track : frAlgo.fvWData[iThread].RecoTracks()) {
       bool isTrackCompletelyInOverlap = true;
@@ -439,6 +441,7 @@ void TrackFinder::FindTracksThread(int iThread)
       }
       trackFirstHit += track.fNofHits;
     }  // sub-timeslice tracks
+    frAlgo.fMonitorData.StopTimer(ETimer::StoreTracksWindow);
 
     if (fvWindowStartThread[iThread] > fvWindowEndThread[iThread]) {
       break;
@@ -447,6 +450,7 @@ void TrackFinder::FindTracksThread(int iThread)
       fvWindowStartThread[iThread] -= 5;  // do 5 ns margin
     }
   }
+  frAlgo.fMonitorData.StopTimer(ETimer::FindTracksThread);
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
diff --git a/algo/ca/core/tracking/CaTrackFinderWindow.cxx b/algo/ca/core/tracking/CaTrackFinderWindow.cxx
index a1886d9bfd..d73d7de5fa 100644
--- a/algo/ca/core/tracking/CaTrackFinderWindow.cxx
+++ b/algo/ca/core/tracking/CaTrackFinderWindow.cxx
@@ -309,7 +309,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
 
     ///   stage for triplets creation
 
-    frAlgo.fMonitorData.StartTimer(ETimer::TripletConstruction);
+    frAlgo.fMonitorData.StartTimer(ETimer::TripletConstructionWindow);
 
     ca::TripletConstructor constructor(frAlgo, frWData);
 
@@ -339,10 +339,10 @@ void TrackFinderWindow::CaTrackFinderSlice()
       }
     }  // istal
 
-    frAlgo.fMonitorData.StopTimer(ETimer::TripletConstruction);
+    frAlgo.fMonitorData.StopTimer(ETimer::TripletConstructionWindow);
 
     // search for neighbouring triplets
-    frAlgo.fMonitorData.StartTimer(ETimer::NeighboringTripletSearch);
+    frAlgo.fMonitorData.StartTimer(ETimer::NeighboringTripletSearchWindow);
 
     for (int istal = frAlgo.GetParameters().GetNstationsActive() - 2; istal >= iStFirst; istal--) {
       // start with downstream chambers
@@ -391,7 +391,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
       frAlgo.fMonitorData.IncrementCounter(ECounter::Triplet, fvTriplets[istal].size());
 
     }  // istal
-    frAlgo.fMonitorData.StopTimer(ETimer::NeighboringTripletSearch);
+    frAlgo.fMonitorData.StopTimer(ETimer::NeighboringTripletSearchWindow);
 
 
     ///====================================================================
@@ -671,16 +671,18 @@ void TrackFinderWindow::CaTrackFinderSlice()
   }  // ---- Loop over Track Finder iterations: END -----------------------------------------------------------//
 
   // Fit tracks
-  frAlgo.fMonitorData.StartTimer(ETimer::TrackFitter);
+  frAlgo.fMonitorData.StartTimer(ETimer::TrackFitterWindow);
   fTrackFitter.FitCaTracks();
-  frAlgo.fMonitorData.StopTimer(ETimer::TrackFitter);
+  frAlgo.fMonitorData.StopTimer(ETimer::TrackFitterWindow);
 
   // Merge clones
+  frAlgo.fMonitorData.StartTimer(ETimer::CloneMergerWindow);
   fCloneMerger.Exec(frWData.RecoTracks(), frWData.RecoHitIndices());
+  frAlgo.fMonitorData.StopTimer(ETimer::CloneMergerWindow);
 
-  frAlgo.fMonitorData.StartTimer(ETimer::TrackFitter);
+  frAlgo.fMonitorData.StartTimer(ETimer::TrackFitterWindow);
   fTrackFitter.FitCaTracks();
-  frAlgo.fMonitorData.StopTimer(ETimer::TrackFitter);
+  frAlgo.fMonitorData.StopTimer(ETimer::TrackFitterWindow);
 }
 
 
diff --git a/algo/ca/core/utils/CaEnumArray.h b/algo/ca/core/utils/CaEnumArray.h
index 82e685a849..a51e090ab2 100644
--- a/algo/ca/core/utils/CaEnumArray.h
+++ b/algo/ca/core/utils/CaEnumArray.h
@@ -9,6 +9,9 @@
 
 #pragma once  // include this header only once per compilation unit
 
+#include <boost/serialization/array.hpp>
+#include <boost/serialization/base_object.hpp>
+
 #include <array>
 
 namespace cbm::algo::ca
@@ -55,5 +58,13 @@ namespace cbm::algo::ca
 
     /// \brief Convertion operator to the base array class
     operator Arr&() const { return *this; }
+
+   private:
+    friend class boost::serialization::access;
+    template<typename Archive>
+    void serialize(Archive& ar, const unsigned int /*version*/)
+    {
+      ar& boost::serialization::base_object<Arr>(*this);
+    }
   };
 }  // namespace cbm::algo::ca
diff --git a/algo/ca/core/utils/CaMonitor.h b/algo/ca/core/utils/CaMonitor.h
index bb972bb7f1..79dde7560b 100644
--- a/algo/ca/core/utils/CaMonitor.h
+++ b/algo/ca/core/utils/CaMonitor.h
@@ -12,6 +12,10 @@
 #include "CaEnumArray.h"
 #include "CaMonitorData.h"
 
+#include <boost/serialization/access.hpp>
+#include <boost/serialization/string.hpp>
+#include <boost/serialization/vector.hpp>
+
 #include <algorithm>
 #include <iomanip>
 #include <sstream>
@@ -19,6 +23,7 @@
 #include <string_view>
 #include <vector>
 
+
 namespace cbm::algo::ca
 {
   /// \class  Monitor
@@ -128,6 +133,17 @@ namespace cbm::algo::ca
     /// \brief Prints counters summary to string
     std::string ToString() const;
 
+    friend class boost::serialization::access;
+    template<typename Archive>
+    void serialize(Archive& ar, const unsigned int /*version*/)
+    {
+      ar& fMonitorData;
+      ar& faTimerNames;
+      ar& faCounterNames;
+      ar& fvCounterRatioKeys;
+      ar& fsName;
+    }
+
    private:
     MonitorData<ECounterKey, ETimerKey> fMonitorData;  ///< Monitor data
     TimerArray<std::string> faTimerNames{};            ///< Array of timer names
diff --git a/algo/ca/core/utils/CaMonitorData.h b/algo/ca/core/utils/CaMonitorData.h
index d744acfb1c..9a17298009 100644
--- a/algo/ca/core/utils/CaMonitorData.h
+++ b/algo/ca/core/utils/CaMonitorData.h
@@ -12,6 +12,8 @@
 #include "CaEnumArray.h"
 #include "CaTimer.h"
 
+#include <boost/serialization/access.hpp>
+
 #include <algorithm>
 
 namespace cbm::algo::ca
@@ -88,6 +90,14 @@ namespace cbm::algo::ca
     void StopTimer(ETimerKey key) { faTimers[key].Stop(); }
 
    private:
+    friend class boost::serialization::access;
+    template<typename Archive>
+    void serialize(Archive& ar, const unsigned int /*version*/)
+    {
+      ar& faTimers;
+      ar& faCounters;
+    }
+
     TimerArray<Timer> faTimers{};    ///< Array of timers
     CounterArray<int> faCounters{};  ///< Array of counters
   };
diff --git a/algo/ca/core/utils/CaTimer.h b/algo/ca/core/utils/CaTimer.h
index 90b519164e..37f7d059e9 100644
--- a/algo/ca/core/utils/CaTimer.h
+++ b/algo/ca/core/utils/CaTimer.h
@@ -9,6 +9,8 @@
 
 #pragma once
 
+#include <boost/serialization/serialization.hpp>
+
 #include <chrono>
 #include <cstdint>
 #include <limits>
@@ -82,6 +84,18 @@ namespace cbm::algo::ca
     void Stop();
 
    private:
+    friend class boost::serialization::access;
+    template<typename Archive>
+    void serialize(Archive& ar, const unsigned int /*version*/)
+    {
+      ar& fMin;
+      ar& fMax;
+      ar& fTotal;
+      ar& fNofCalls;
+      ar& fMinCallIndex;
+      ar& fMaxCallIndex;
+    }
+
     TimePoint fStart     = TimePoint();
     DurationCount fMin   = std::numeric_limits<DurationCount>::max();  ///< Minimal time period
     DurationCount fMax   = std::numeric_limits<DurationCount>::min();  ///< Maximal time period
diff --git a/algo/ca/core/utils/CaTrackingMonitor.h b/algo/ca/core/utils/CaTrackingMonitor.h
index c14b4c26b4..0981f0e019 100644
--- a/algo/ca/core/utils/CaTrackingMonitor.h
+++ b/algo/ca/core/utils/CaTrackingMonitor.h
@@ -11,6 +11,8 @@
 
 #include "CaMonitor.h"
 
+#include <boost/serialization/base_object.hpp>
+
 namespace cbm::algo::ca
 {
   /// \enum  ECounter
@@ -44,10 +46,17 @@ namespace cbm::algo::ca
     //Tracking,
     PrepareInput,
     FindTracks,
-    TrackFinder,
-    TrackFitter,
-    TripletConstruction,
-    NeighboringTripletSearch,
+    PrepareDataStreams,
+    FindTracksThread,
+    PrepareHitsWindow,
+    TrackFinderWindow,
+    TrackFitterWindow,
+    CloneMergerWindow,
+    StoreTracksWindow,
+    TripletConstructionWindow,
+    NeighboringTripletSearchWindow,
+    //InputQa,
+    OutputQa,
     kEND
   };
 
@@ -60,30 +69,45 @@ namespace cbm::algo::ca
     /// \brief Default constructor
     TrackingMonitor() : Monitor<ECounter, ETimer>("CA Framework Monitor")
     {
-      SetCounterName(ECounter::TrackingCall, "full routine calls");
-      SetCounterName(ECounter::RecoTrack, "reco tracks");
-      SetCounterName(ECounter::RecoHit, "reco hits");
+      SetCounterName(ECounter::TrackingCall, "full_routine_calls");
+      SetCounterName(ECounter::RecoTrack, "reco_tracks");
+      SetCounterName(ECounter::RecoHit, "reco_hits");
       SetCounterName(ECounter::Triplet, "triplets");
-      SetCounterName(ECounter::RecoHitUsed, "used reco hits");
+      SetCounterName(ECounter::RecoHitUsed, "used_reco_hits");
       SetCounterName(ECounter::SubTS, "sub-timeslices");
-      SetCounterName(ECounter::RecoMvdHit, "MVD hits in tracks");
-      SetCounterName(ECounter::RecoStsHit, "STS hits in tracks");
-      SetCounterName(ECounter::RecoMuchHit, "MUCH hits in tracks");
-      SetCounterName(ECounter::RecoTrdHit, "TRD hits in tracks");
-      SetCounterName(ECounter::RecoTofHit, "TOF hits in tracks");
-      SetCounterName(ECounter::UndefinedMvdHit, "undefined MVD hits");
-      SetCounterName(ECounter::UndefinedStsHit, "undefined STS hits");
-      SetCounterName(ECounter::UndefinedMuchHit, "undefined MuCh hits");
-      SetCounterName(ECounter::UndefinedTrdHit, "undefined TRD hits");
-      SetCounterName(ECounter::UndefinedTofHit, "undefined TOF hits");
-      //SetTimerName(ETimer::Tracking, "full tracking");
-      SetTimerName(ETimer::PrepareInput, "input data initialization");
-      SetTimerName(ETimer::FindTracks, "find tracks procedure");
-      SetTimerName(ETimer::TrackFinder, "track finder");
-      SetTimerName(ETimer::TrackFitter, "track fitter");
-      SetTimerName(ETimer::TripletConstruction, "triplet construction");
-      SetTimerName(ETimer::NeighboringTripletSearch, "neighboring triplet search");
+      SetCounterName(ECounter::RecoMvdHit, "MVD_hits_in_tracks");
+      SetCounterName(ECounter::RecoStsHit, "STS_hits_in_tracks");
+      SetCounterName(ECounter::RecoMuchHit, "MUCH_hits_in_tracks");
+      SetCounterName(ECounter::RecoTrdHit, "TRD_hits_in_tracks");
+      SetCounterName(ECounter::RecoTofHit, "TOF_hits_in_tracks");
+      SetCounterName(ECounter::UndefinedMvdHit, "undefined_MVD_hits");
+      SetCounterName(ECounter::UndefinedStsHit, "undefined_STS_hits");
+      SetCounterName(ECounter::UndefinedMuchHit, "undefined_MuCh_hits");
+      SetCounterName(ECounter::UndefinedTrdHit, "undefined_TRD_hits");
+      SetCounterName(ECounter::UndefinedTofHit, "undefined_TOF_hits");
+      //SetTimerName(ETimer::Tracking, "full_tracking");
+      SetTimerName(ETimer::PrepareInput, "input_data_initialization");
+      SetTimerName(ETimer::FindTracks, "find_tracks_procedure");
+      SetTimerName(ETimer::PrepareDataStreams, "data_streams_preparation");
+      SetTimerName(ETimer::FindTracksThread, "find_tracks_on_thread");
+      SetTimerName(ETimer::PrepareHitsWindow, "hit_preparation_in_window");
+      SetTimerName(ETimer::TrackFinderWindow, "track_finder_in_window");
+      SetTimerName(ETimer::TrackFitterWindow, "track_fitter_in_window");
+      SetTimerName(ETimer::CloneMergerWindow, "clone_merger_in_window");
+      SetTimerName(ETimer::TripletConstructionWindow, "triplet_construction_in_window");
+      SetTimerName(ETimer::NeighboringTripletSearchWindow, "neighboring_triplets_w.");
+      SetTimerName(ETimer::StoreTracksWindow, "tracks_storing_in_window");
+      SetTimerName(ETimer::OutputQa, "output_QA");
       SetRatioKeys({ECounter::TrackingCall, ECounter::SubTS, ECounter::RecoTrack});
     }
+
+   private:
+    friend class boost::serialization::access;
+    template<typename Archive>
+    void serialize(Archive& ar, const unsigned int /*version*/)
+    {
+      ar& boost::serialization::base_object<Monitor<ECounter, ETimer>>(*this);
+    }
   };
+
 }  // namespace cbm::algo::ca
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index fb0f5c461d..7605cc9c90 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -463,8 +463,8 @@ void Reco::QueueTrackingMetrics(const ca::TrackingMonitorData& monitor)
 
   GetMonitor().QueueMetric("cbmreco", {{"hostname", fles::system::current_hostname()}, {"child", Opts().ChildId()}},
                            {{"caRecoTimeTotal", monitor.GetTimer(ca::ETimer::FindTracks).GetTotalMs()},
-                            {"caTrackFinderTime", monitor.GetTimer(ca::ETimer::TrackFinder).GetTotalMs()},
-                            {"caTrackFitterTime", monitor.GetTimer(ca::ETimer::TrackFitter).GetTotalMs()},
+                            {"caTrackFinderTime", monitor.GetTimer(ca::ETimer::TrackFinderWindow).GetTotalMs()},
+                            {"caTrackFitterTime", monitor.GetTimer(ca::ETimer::TrackFitterWindow).GetTotalMs()},
                             {"caNofRecoTracks", monitor.GetCounterValue(ca::ECounter::RecoTrack)},
                             {"caNofRecoHitsTotal", monitor.GetCounterValue(ca::ECounter::RecoHit)},
                             {"caNofRecoHitsUsed", monitor.GetCounterValue(ca::ECounter::RecoHitUsed)},
diff --git a/reco/L1/L1LinkDef.h b/reco/L1/L1LinkDef.h
index 84bd9fd6de..17d90b2a46 100644
--- a/reco/L1/L1LinkDef.h
+++ b/reco/L1/L1LinkDef.h
@@ -10,6 +10,7 @@
 #pragma link off all classes;
 #pragma link off all functions;
 
+#pragma link C++ class cbm::algo::ca::TrackingMonitor - ;
 #pragma link C++ class CbmTrackingDetectorInterfaceInit + ;
 #pragma link C++ class CbmL1 + ;
 #pragma link C++ class CbmL1StsTrackFinder + ;
-- 
GitLab