diff --git a/algo/ca/TrackingChain.cxx b/algo/ca/TrackingChain.cxx
index e5533656fdbecb74698764942bb6441e194c270b..a16a285ef205c7e51df9dd23289d0b6c58ba087c 100644
--- a/algo/ca/TrackingChain.cxx
+++ b/algo/ca/TrackingChain.cxx
@@ -174,7 +174,6 @@ void TrackingChain::ReadHits(PartitionedSpan<const ca::HitTypes_t::at<DetID>> hi
 
   xpu::t_add_bytes(hits.NElements() * sizeof(Hit_t));  // Assumes call from Run, for existence of timer!
 
-  ca::HitKeyIndex_t firstHitKey = fNofHitKeys;
   int64_t dataStreamDet         = static_cast<int64_t>(DetID) << 60;  // detector part of the data stream
   int64_t dataStream            = 0;
   for (size_t iPartition = 0; iPartition < hits.NPartitions(); ++iPartition, ++dataStream) {
@@ -201,6 +200,7 @@ void TrackingChain::ReadHits(PartitionedSpan<const ca::HitTypes_t::at<DetID>> hi
     }
     double lastTime = -1e9;
     double prevTime = -1;
+    ca::HitKeyIndex_t firstHitKey = fNofHitKeys;
     for (size_t iPartHit = 0; iPartHit < vHits.size(); ++iPartHit) {
       const auto& hit = vHits[iPartHit];
       int iHitExt     = iOffset + iPartHit;
@@ -209,6 +209,7 @@ void TrackingChain::ReadHits(PartitionedSpan<const ca::HitTypes_t::at<DetID>> hi
       if constexpr (IsSts) {
         caHit.SetFrontKey(firstHitKey + hit.fFrontClusterId);
         caHit.SetBackKey(firstHitKey + hit.fBackClusterId);
+        //L_(info) << ", hit="  << iHitExt << ", f=" << hit.fFrontClusterId << ", b=" << hit.fBackClusterId;
       }
       else {
         caHit.SetFrontKey(firstHitKey + iHitExt);
diff --git a/algo/ca/core/CMakeLists.txt b/algo/ca/core/CMakeLists.txt
index 566fbed38071a4db66aa23f6268d27ff8193e949..90a19d9f5276d5dd97f5d8a885243ce57f29aaf1 100644
--- a/algo/ca/core/CMakeLists.txt
+++ b/algo/ca/core/CMakeLists.txt
@@ -19,6 +19,7 @@ set(SRCS
   ${CMAKE_CURRENT_SOURCE_DIR}/data/CaMeasurementXy.cxx
   ${CMAKE_CURRENT_SOURCE_DIR}/data/CaMeasurementTime.cxx
   ${CMAKE_CURRENT_SOURCE_DIR}/data/CaWindowData.cxx
+  ${CMAKE_CURRENT_SOURCE_DIR}/data/CaTimesliceHeader.cxx
   ${CMAKE_CURRENT_SOURCE_DIR}/pars/CaConfigReader.cxx
   ${CMAKE_CURRENT_SOURCE_DIR}/pars/CaField.cxx
   ${CMAKE_CURRENT_SOURCE_DIR}/pars/CaInitManager.cxx
@@ -93,6 +94,7 @@ install(
     data/CaTriplet.h
     data/CaBranch.h
     data/CaWindowData.h
+    data/CaTimesliceHeader.h
     pars/CaConstants.h
     pars/CaField.h
     pars/CaInitManager.h
diff --git a/algo/ca/core/data/CaHit.h b/algo/ca/core/data/CaHit.h
index b013a13da058695b54f4b75b7349207c6233578c..fb0551ee784616df3f315d783dd3fd857b05314e 100644
--- a/algo/ca/core/data/CaHit.h
+++ b/algo/ca/core/data/CaHit.h
@@ -16,6 +16,13 @@
 
 namespace cbm::algo::ca
 {
+  struct CaHitTimeInfo {
+    fscal fEventTimeMin{-std::numeric_limits<fscal>::max() / 2.};
+    fscal fEventTimeMax{std::numeric_limits<fscal>::max() / 2.};
+    fscal fMaxTimeBeforeHit{0.};  //< max event time for hits [0 .. hit] in the station hit array
+    fscal fMinTimeAfterHit{0.};   //< min event time for hits [hit ... ] in the station hit array
+  };
+
   // FIXME: Move typedefs to another header (potential problems with dependencies)
   using HitIndex_t    = unsigned int;  ///< Index of ca::Hit
   using HitKeyIndex_t = unsigned int;  ///< Index of the hit key (e.g. front / back cluster id for STS)
diff --git a/algo/ca/core/data/CaTimesliceHeader.cxx b/algo/ca/core/data/CaTimesliceHeader.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f0e543305168616814ca2a3abade895777e8c0e1
--- /dev/null
+++ b/algo/ca/core/data/CaTimesliceHeader.cxx
@@ -0,0 +1,25 @@
+/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   CaTimesliceHeader.cxx
+/// \brief  A structure to keep all the common information on the timeslice coming from tracking (implementation)
+/// \since  15.02.2024
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#pragma once
+
+#include "CaTimesliceHeader.h"
+
+#include <sstream>
+
+using cbm::algo::ca::TimesliceHeader;
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+std::string TimesliceHeader::ToString() const
+{
+  std::stringstream msg;
+  msg << "TimesliceHeader: start = " << fStart << " [ns], end = " << fEnd << " [ns]";
+  return msg.str();
+}
diff --git a/algo/ca/core/data/CaTimesliceHeader.h b/algo/ca/core/data/CaTimesliceHeader.h
new file mode 100644
index 0000000000000000000000000000000000000000..7fc20004f69ae26d41daf723de0c3c49ef7f0611
--- /dev/null
+++ b/algo/ca/core/data/CaTimesliceHeader.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   CaTimesliceHeader.h
+/// \brief  A structure to keep all the common information on the timeslice coming from tracking
+/// \since  15.02.2024
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#pragma once
+
+#include <string>
+
+namespace cbm::algo::ca
+{
+  /// \class TimesliceHeader
+  /// \brief Structure for keeping the current information on the timeslice
+  class TimesliceHeader {
+   public:
+    /// \brief Accesses the end of timeslice [ns]
+    float& End() { return fEnd; }
+    float End() const { return fEnd; }
+
+    /// \brief Accesses the start of timeslice [ns]
+    float& Start() { return fStart; }
+    float Start() const { return fStart; }
+
+    /// \brief String representation of the contents
+    std::string ToString() const;
+
+    /// \brief Converts time from ns to tau
+    float ConvToTau(float time) const { return (time - fStart) / (fEnd - fStart); }
+
+    /// \brief Converts time from tau to ns
+    float ConvToNs(float tau) const { return fStart + tau * (fEnd - fStart); }
+
+   private:
+    float fStart;  ///< Start of timeslice
+    float fEnd;    ///< End of timeslice
+  };
+}  // namespace cbm::algo::ca
diff --git a/algo/ca/core/data/CaWindowData.h b/algo/ca/core/data/CaWindowData.h
index 67269e9533f11712885b8ec3d3ffcf026bf56c0a..b599ae6a03da1658eed297236b0208e01f3c5712 100644
--- a/algo/ca/core/data/CaWindowData.h
+++ b/algo/ca/core/data/CaWindowData.h
@@ -192,9 +192,6 @@ namespace cbm::algo::ca
     /// \brief Sample of reconstructed hit indices
     Vector<HitIndex_t> fvRecoHitIndices{"WindowData::fvRecoHitIndices"};
 
-    /// \brief Sample of track candidates
-    Vector<Track> fvTrackCandidates{"WindowData::fvTrackCandidates"};
-
     /// \brief Map of hit indices from the time window to the time slice
     std::array<Vector<HitIndex_t>, kMaxNofStations> fvTsHitIndices{"WindowData::fvFullDSHitIndex"};
 
diff --git a/algo/ca/core/tracking/CaFramework.h b/algo/ca/core/tracking/CaFramework.h
index 74b85031a249962b7dc88a1ea7d273ce42b559c8..40943de475ca7acab36411dd0e4684b0ca12f1b6 100644
--- a/algo/ca/core/tracking/CaFramework.h
+++ b/algo/ca/core/tracking/CaFramework.h
@@ -16,9 +16,9 @@
 #include "CaParameters.h"
 #include "CaStation.h"
 #include "CaTimer.h"
+#include "CaTimesliceHeader.h"
 #include "CaTrack.h"
 #include "CaTrackExtender.h"
-#include "CaTrackExtraInfo.h"
 #include "CaTrackFinder.h"
 #include "CaTrackFinderWindow.h"
 #include "CaTrackFitter.h"
@@ -59,12 +59,6 @@ namespace cbm::algo::ca
   using CaMaterialArray_t = std::array<ca::MaterialMap, constants::size::MaxNstations>;
   using Tindex            = int;  // TODO: Replace with ca::HitIndex_t, if suitable
 
-  struct CaHitTimeInfo {
-    fscal fEventTimeMin{-std::numeric_limits<fscal>::max() / 2.};
-    fscal fEventTimeMax{std::numeric_limits<fscal>::max() / 2.};
-    fscal fMaxTimeBeforeHit{0.};  //< max event time for hits [0 .. hit] in the station hit array
-    fscal fMinTimeAfterHit{0.};   //< min event time for hits [hit ... ] in the station hit array
-  };
 
   /// Main class of CA track finder algorithm
   ///
@@ -167,6 +161,8 @@ namespace cbm::algo::ca
     /// \return particle mass squared
     float GetDefaultParticleMass2() const { return fDefaultMass * fDefaultMass; }
 
+    /// \brief Gets timeslice header
+    const TimesliceHeader& GetTsHeader() const { return fTsHeader; }
 
     /*********************************************************************************************/ /**
    *                             ------  FUNCTIONAL PART ------
@@ -200,21 +196,22 @@ namespace cbm::algo::ca
 
     // const CbmL1MCTrack* GetMcTrackForWindowHit(int iHit) const;
 
+    /// \brief Sets number of threads
     void SetNofThtreads(int nThreads)
     {
       fNofThreads = nThreads;
+      assert(nThreads > 0);
       LOG(info) << "ca::Framework: number of threads is set to " << fNofThreads;
     }
 
+    /// \brief Gets number of threads
     int GetNofThreads() const { return fNofThreads; }
 
-    bool IfCollectTrackExtraInfo() const { return fbCollectTrackExtraInfo; }
-
    private:
     int fNstationsBeforePipe{0};                    ///< number of stations before pipe (MVD stations in CBM)
     int fNfieldStations{0};                         ///< number of stations in the field region
     float fDefaultMass{constants::phys::MuonMass};  ///< mass of the propagated particle [GeV/c2]
-
+    TimesliceHeader fTsHeader;                      ///< current timeslice header
 
     // ***************************
     // ** Member variables list **
@@ -223,11 +220,9 @@ namespace cbm::algo::ca
     Parameters<fvec> fParameters;  ///< Object of Framework parameters class
     InputData fInputData;          ///< Tracking input data
 
-    bool fbCollectTrackExtraInfo = true;  ///< Flag, if to fill the additional track info structure
-
     TrackingMonitorData fMonitorData{};  ///< Tracking monitor data (statistics per call)
 
-    int fNofThreads = 10;  ///< Number of threads to execute the track-finder
+    int fNofThreads = 1;  ///< Number of threads to execute the track-finder
 
    public:
     Vector<CaHitTimeInfo> fHitTimeInfo;
@@ -242,7 +237,6 @@ namespace cbm::algo::ca
     double fCaRecoTime{0.};  // time of the track finder + fitter
 
     Vector<Track> fRecoTracks{"Framework::fRecoTracks"};       ///< reconstructed tracks
-    Vector<TrackExtraInfo> fRecoTrackExtraInfo{"Framework::fRecoTrackExtraInfo"};  ///< Extra info on tracks
     Vector<ca::HitIndex_t> fRecoHits{"Framework::fRecoHits"};  ///< packed hits of reconstructed tracks
 
     fvec EventTime{0.f};
diff --git a/algo/ca/core/tracking/CaTrackFinder.cxx b/algo/ca/core/tracking/CaTrackFinder.cxx
index 96bc482b184e26a3a1fb912d4f68091775a2b1a1..a18dec3502e4d7a9e9ca4d94f2c01437ff50a1ff 100644
--- a/algo/ca/core/tracking/CaTrackFinder.cxx
+++ b/algo/ca/core/tracking/CaTrackFinder.cxx
@@ -62,10 +62,6 @@ void TrackFinder::FindTracks()
   for (int iThread = 0; iThread < frAlgo.GetNofThreads(); ++iThread) {
     fvRecoTracks[iThread].clear();
     fvRecoTracks[iThread].reserve(nTracksExpected / frAlgo.GetNofThreads());
-    if (frAlgo.IfCollectTrackExtraInfo()) {
-      fvRecoTrackExtraInfo[iThread].clear();
-      fvRecoTrackExtraInfo[iThread].reserve(nTracksExpected / frAlgo.GetNofThreads());
-    }
     fvRecoHitIndices[iThread].clear();
     fvRecoHitIndices[iThread].reserve(nHitsExpected / frAlgo.GetNofThreads());
     frAlgo.fvTrackFinderWindow[iThread].InitTimeslice();
@@ -213,6 +209,9 @@ void TrackFinder::FindTracks()
   for (int iThread = 0; iThread < frAlgo.GetNofThreads(); ++iThread) {
     fvWindowStartThread[iThread] = fStatTsStart + iThread * threadDuration;
     fvWindowEndThread[iThread]   = fvWindowStartThread[iThread] + threadDuration;
+    if (iThread > 0) {
+      fvWindowStartThread[iThread] += 200;
+    }
     LOG(info) << "Thread: " << iThread << " from " << fvWindowStartThread[iThread] / 1.e6 << " ms  to "
               << fvWindowEndThread[iThread] / 1.e6 << " ms";
   }
@@ -261,6 +260,11 @@ void TrackFinder::FindTracks()
     statNwindowsTotal += fvStatNwindows[iThread];
   }
 
+  // Filling TS headear
+  auto& tsHeader   = frAlgo.fTsHeader;
+  tsHeader.Start() = fStatTsStart;
+  tsHeader.End()   = fStatTsEnd;
+
   LOG(info) << "CA tracker: time slice finished. Reconstructed " << frAlgo.fRecoTracks.size() << " tracks with "
             << frAlgo.fRecoHits.size() << " hits. Processed " << statNhitsProcessedTotal << " hits in "
             << statNwindowsTotal << " time windows. Reco time " << frAlgo.fCaRecoTime / 1.e9 << " s";
@@ -274,26 +278,29 @@ void TrackFinder::FindTracksThread(int iThread)
   const int nDataStreams    = frAlgo.fInputData.GetNdataStreams();
   bool areUntouchedDataLeft = true;  // is the whole TS processed
   std::vector<HitIndex_t> sliceFirstHit(nDataStreams, 0);
+  std::vector<HitIndex_t> sliceLastHit(nDataStreams, 0);
   auto& wData = frAlgo.fvWData[iThread];
 
   // Define first hit, skip all the hits, which are before the first window
   for (int iStream = 0; iStream < nDataStreams; ++iStream) {
     sliceFirstHit[iStream] = frAlgo.fInputData.GetStreamStartIndex(iStream);
-    HitIndex_t caLstId     = frAlgo.fInputData.GetStreamStopIndex(iStream);
-    HitIndex_t caFstId     = sliceFirstHit[iStream];
-    for (HitIndex_t caHitId = caFstId; caHitId < caLstId; ++caHitId) {
+    sliceLastHit[iStream]  = frAlgo.fInputData.GetStreamStopIndex(iStream);
+    for (HitIndex_t caHitId = sliceFirstHit[iStream]; caHitId < sliceLastHit[iStream]; ++caHitId) {
       CaHitTimeInfo& info = frAlgo.fHitTimeInfo[caHitId];
       const ca::Hit& h    = frAlgo.fInputData.GetHit(caHitId);
       if (wData.IsHitKeyUsed(h.FrontKey()) || wData.IsHitKeyUsed(h.BackKey())) {
         continue;
       }
       if (info.fMaxTimeBeforeHit < fvWindowStartThread[iThread]) {
-        // this hit and all hits before are before the overlap
         sliceFirstHit[iStream] = caHitId + 1;
       }
+      if (info.fMinTimeAfterHit > fvWindowEndThread[iThread]) {
+        sliceLastHit[iStream] = caHitId;
+      }
     }
   }
 
+
   fvStatNwindows[iThread]       = 0;
   fvStatNhitsProcessed[iThread] = 0;
 
@@ -316,14 +323,10 @@ void TrackFinder::FindTracksThread(int iThread)
 
     Timer tHitInit;
     tHitInit.Start();
-    int nLoops1 = 0;
-    int nLoops2 = 0;
     for (int iStream = 0; iStream < nDataStreams; ++iStream) {
-      for (ca::HitIndex_t caHitId = sliceFirstHit[iStream]; caHitId < frAlgo.fInputData.GetStreamStopIndex(iStream);
-           ++caHitId) {
-        nLoops1++;
-        CaHitTimeInfo& info = frAlgo.fHitTimeInfo[caHitId];
-        const ca::Hit& h    = frAlgo.fInputData.GetHit(caHitId);
+      for (ca::HitIndex_t caHitId = sliceFirstHit[iStream]; caHitId < sliceLastHit[iStream]; ++caHitId) {
+        const CaHitTimeInfo& info = frAlgo.fHitTimeInfo[caHitId];
+        const ca::Hit& h          = frAlgo.fInputData.GetHit(caHitId);
         if (wData.IsHitKeyUsed(h.FrontKey()) || wData.IsHitKeyUsed(h.BackKey())) {
           // the hit is already reconstructed
           continue;
@@ -344,10 +347,8 @@ void TrackFinder::FindTracksThread(int iThread)
               // this hit and all hits before are before the overlap
               sliceFirstHit[iStream] = caHitId + 1;
             }
-            //LOG(warning) << "event time " << ((float) info.fEventTimeMax )<< " " << h.ToString();
           }
         }  // else the hit has been alread processed in previous sub-slices
-        nLoops2++;
       }
     }
     fvStatNhitsProcessed[iThread] += statNwindowHits;
@@ -427,14 +428,6 @@ void TrackFinder::FindTracksThread(int iThread)
       }
       else {  // save the track
         fvRecoTracks[iThread].push_back(track);
-        if (frAlgo.IfCollectTrackExtraInfo()) {
-          auto trkInfo       = TrackExtraInfo();
-          trkInfo.fTimeStart = (track.fParFirst.GetTime() - fStatTsStart) / (fStatTsEnd - fStatTsStart);
-          trkInfo.fTimeEnd   = (track.fParLast.GetTime() - fStatTsStart) / (fStatTsEnd - fStatTsStart);
-          trkInfo.fThreadId  = iThread;
-          fvRecoTrackExtraInfo[iThread].push_back(trkInfo);
-        }
-
         // mark the track hits as used
         for (int i = 0; i < track.fNofHits; i++) {
           int caHitId                      = frAlgo.fvWData[iThread].RecoHitIndex(trackFirstHit + i);
@@ -475,18 +468,9 @@ void TrackFinder::Init()
   fvRecoHitIndices.clear();
   fvRecoHitIndices.resize(frAlgo.GetNofThreads());
 
-  if (frAlgo.IfCollectTrackExtraInfo()) {
-    fvRecoTrackExtraInfo.clear();
-    fvRecoTrackExtraInfo.resize(frAlgo.GetNofThreads());
-  }
-
   for (int iThread = 0; iThread < frAlgo.GetNofThreads(); ++iThread) {
     fvRecoTracks[iThread].SetName(std::string("TrackFinder::fvRecoTracks_") + std::to_string(iThread));
     fvRecoHitIndices[iThread].SetName(std::string("TrackFinder::fvRecoHitIndices_") + std::to_string(iThread));
-    if (frAlgo.IfCollectTrackExtraInfo()) {
-      fvRecoTrackExtraInfo[iThread].SetName(std::string("TrackFinder::fvRecoTrackExtraInfo_")
-                                            + std::to_string(iThread));
-    }
   }
 
   fWindowLength = (ca::Framework::TrackingMode::kMcbm == frAlgo.fTrackingMode) ? 500 : 10000;
diff --git a/algo/ca/core/tracking/CaTrackFinder.h b/algo/ca/core/tracking/CaTrackFinder.h
index 107f81a3355a6322dc592a016720aa0cb7ef2e73..f6f7c5a99752e23d651023af34d8ce817c6748c2 100644
--- a/algo/ca/core/tracking/CaTrackFinder.h
+++ b/algo/ca/core/tracking/CaTrackFinder.h
@@ -51,6 +51,9 @@ namespace cbm::algo::ca
     void FindTracksThread(int iThread);
     void Init();
 
+    const auto& GetRecoTracksContainer(int iThread) const { return fvRecoTracks[iThread]; }
+    const auto& GetRecoHitIndicesContainer(int iThread) const { return fvRecoHitIndices[iThread]; }
+
    private:
     // -------------------------------
     // Private methods
@@ -70,9 +73,8 @@ namespace cbm::algo::ca
     std::vector<int> fvStatNwindows;
     std::vector<int> fvStatNhitsProcessed;
 
-    std::vector<Vector<Track>> fvRecoTracks;                   ///< reconstructed tracks
-    std::vector<Vector<TrackExtraInfo>> fvRecoTrackExtraInfo;  ///< Extra info on tracks
-    std::vector<Vector<ca::HitIndex_t>> fvRecoHitIndices;      ///< packed hits of reconstructed tracks
+    std::vector<Vector<Track>> fvRecoTracks;           ///< reconstructed tracks
+    std::vector<Vector<HitIndex_t>> fvRecoHitIndices;  ///< packed hits of reconstructed tracks
 
     float fWindowLength  = 0.;
     float fWindowOverlap = 15.;  // ns
diff --git a/algo/ca/core/tracking/CaTrackFinderWindow.cxx b/algo/ca/core/tracking/CaTrackFinderWindow.cxx
index 646185bc5945c6950b87503ae124738a88d046d5..a1886d9bfd4b8fbb1f45eaa06569fff8f37fe1c1 100644
--- a/algo/ca/core/tracking/CaTrackFinderWindow.cxx
+++ b/algo/ca/core/tracking/CaTrackFinderWindow.cxx
@@ -427,6 +427,7 @@ void TrackFinderWindow::CaTrackFinderSlice()
 
 
       fvTrackCandidates.clear();
+      fvTrackCandidates.reserve(frWData.Hits().size() / 10);
 
       for (const auto& h : frWData.Hits()) {
         fvHitKeyToTrack[h.FrontKey()] = -1;
diff --git a/algo/ca/qa/CaQaBuilder.cxx b/algo/ca/qa/CaQaBuilder.cxx
index a319fd510f9e7eee27296542b8a1c0ee7d3d1196..5a690e7fc776c92d1e8abbceda8ab961554b454f 100644
--- a/algo/ca/qa/CaQaBuilder.cxx
+++ b/algo/ca/qa/CaQaBuilder.cxx
@@ -1,4 +1,4 @@
-/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+/* Copyright (C) 2023-2024 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Sergei Zharko [committer] */
 
@@ -28,6 +28,8 @@ using cbm::algo::ca::qa::Builder;
 //
 void Builder::Init()
 {
+  using fmt::format;
+
   if (!fpSender.get()) {
     return;
   }
@@ -38,23 +40,23 @@ void Builder::Init()
   std::array<std::string, knTrkParPoints> vsPointName = {"first", "last"};
   for (int i = 0; i < knTrkParPoints; ++i) {
     {
-      auto sName      = fmt::format("track_{}_theta", vsPointName[i]);
-      auto sTitl      = fmt::format("#theta at {} hit; #theta", vsPointName[i]);
+      auto sName      = format("track_{}_theta", vsPointName[i]);
+      auto sTitl      = format("#theta at {} hit; #theta", vsPointName[i]);
       fvphTrkTheta[i] = fQaData.MakeObj<Histo1D>(62, 0., 90., sName, sTitl);
     }
     {
-      auto sName    = fmt::format("track_{}_phi", vsPointName[i]);
-      auto sTitl    = fmt::format("#phi at {} hit; #phi", vsPointName[i]);
+      auto sName    = format("track_{}_phi", vsPointName[i]);
+      auto sTitl    = format("#phi at {} hit; #phi", vsPointName[i]);
       fvphTrkPhi[i] = fQaData.MakeObj<Histo1D>(62, -180., 180., sName, sTitl);
     }
     {
-      auto sName        = fmt::format("track_{}_chi2_ndf", vsPointName[i]);
-      auto sTitl        = fmt::format("#chi^{{2}}/NDF at {} hit; #chi^{{2}}/NDF", vsPointName[i]);
+      auto sName        = format("track_{}_chi2_ndf", vsPointName[i]);
+      auto sTitl        = format("#chi^{{2}}/NDF at {} hit; #chi^{{2}}/NDF", vsPointName[i]);
       fvphTrkChi2Ndf[i] = fQaData.MakeObj<Histo1D>(100, 0., 20., sName, sTitl);
     }
     {
-      auto sName    = fmt::format("track_{}_hit_station", vsPointName[i]);
-      auto sTitl    = fmt::format("Station of {} hit;ID_{{sta}}", vsPointName[i]);
+      auto sName    = format("track_{}_hit_station", vsPointName[i]);
+      auto sTitl    = format("Station of {} hit;ID_{{sta}}", vsPointName[i]);
       fvphHitSta[i] = fQaData.MakeObj<Histo1D>(100, -.5, 10.5, sName, sTitl);
     }
   }
@@ -125,26 +127,29 @@ void Builder::Build()
   }
 
   // Fill track histograms
-  int trkFirstHit = 0;  // Index of hit in fpvRecoHits
-  for (auto& track : (*fpvTracks)) {
-    int nHits = track.fNofHits;
-    // Indices of hits in fpInputData->GetHits()
-    int iFstHit = (*fpvRecoHits)[trkFirstHit];
-    int iLstHit = (*fpvRecoHits)[trkFirstHit + nHits - 1];
-
-    // Distributions in different track points
-    for (int ip = 0; ip < knTrkParPoints; ++ip) {
-      int iHit           = (ip == 0 ? iFstHit : iLstHit);
-      const auto& trkPar = (ip == 0 ? track.fParFirst : track.fParLast);
-      const auto& hit    = fpInputData->GetHit(iHit);
-      fvphTrkTheta[ip]->Add(trkPar.GetTheta() * 180. / Pi);
-      fvphTrkPhi[ip]->Add(trkPar.GetPhi() * 180. / Pi);
-      fvphTrkChi2Ndf[ip]->Add(trkPar.GetChiSq() / trkPar.GetNdf());
-      fvphHitSta[ip]->Add(hit.Station());
+  {
+    int trkFirstHit = 0;  // Index of hit in fpvRecoHits
+    for (auto trkIt = fpvTracks->begin(); trkIt != fpvTracks->end(); ++trkIt) {
+      auto& track = *trkIt;
+      int nHits   = track.fNofHits;
+      // Indices of hits in fpInputData->GetHits()
+      int iFstHit = (*fpvRecoHits)[trkFirstHit];
+      int iLstHit = (*fpvRecoHits)[trkFirstHit + nHits - 1];
+
+      // Distributions in different track points
+      for (int ip = 0; ip < knTrkParPoints; ++ip) {
+        int iHit           = (ip == 0 ? iFstHit : iLstHit);
+        const auto& trkPar = (ip == 0 ? track.fParFirst : track.fParLast);
+        const auto& hit    = fpInputData->GetHit(iHit);
+        fvphTrkTheta[ip]->Add(trkPar.GetTheta() * 180. / Pi);
+        fvphTrkPhi[ip]->Add(trkPar.GetPhi() * 180. / Pi);
+        fvphTrkChi2Ndf[ip]->Add(trkPar.GetChiSq() / trkPar.GetNdf());
+        fvphHitSta[ip]->Add(hit.Station());
+      }
+      // Other distributions
+      fphTrkNofHits->Add(nHits);
+      trkFirstHit += nHits;
     }
-    // Other distributions
-    fphTrkNofHits->Add(nHits);
-    trkFirstHit += nHits;
   }
 
   fQaData.Send(fpSender);
diff --git a/algo/ca/qa/CaQaBuilder.h b/algo/ca/qa/CaQaBuilder.h
index f9a6748f953c37066da641ef9a6dd5b031de7cb1..ff3293acdbbf5c2f5587d7532322f4beaae45f9a 100644
--- a/algo/ca/qa/CaQaBuilder.h
+++ b/algo/ca/qa/CaQaBuilder.h
@@ -10,7 +10,7 @@
 #pragma once
 
 #include "CaHit.h"  // for HitIndex_t
-#include "CaQaBuilder.h"
+#include "CaTimesliceHeader.h"
 #include "CaVector.h"
 #include "QaData.h"
 
@@ -84,14 +84,13 @@ namespace cbm::algo::ca::qa
     /// \note  Call per run
     void RegisterParameters(const Parameters<fvec>* pParameters) { fpParameters = pParameters; }
 
-
    private:
     QaData fQaData{"CaQa"};  ///< QA data
 
     std::shared_ptr<HistogramSender> fpSender = nullptr;  ///< Histogram sender
     const Parameters<fvec>* fpParameters      = nullptr;  ///< Pointer to tracking parameters
-    const Vector<Track>* fpvTracks            = nullptr;  ///< Pointer to tracks vector
     const InputData* fpInputData              = nullptr;  ///< Pointer to input data
+    const Vector<Track>* fpvTracks            = nullptr;  ///< Pointer to tracks vector
     const Vector<HitIndex_t>* fpvRecoHits     = nullptr;  ///< Pointer to reco hit indices
 
     // ----- List of the histograms ------------------------------------------------------------------------------------
diff --git a/algo/qa/CanvasConfig.cxx b/algo/qa/CanvasConfig.cxx
index 449eba144c4b56f87d38740ed3151748f9f71a0b..bfbb99c2f282468095454d3c93316c22e84756b1 100644
--- a/algo/qa/CanvasConfig.cxx
+++ b/algo/qa/CanvasConfig.cxx
@@ -9,6 +9,7 @@
 
 #include "CanvasConfig.h"
 
+#include <log.hpp>
 #include <sstream>
 
 using cbm::algo::CanvasConfig;
@@ -49,8 +50,15 @@ std::string CanvasConfig::ToString() const
 
   std::stringstream cfg;
   cfg << fsName << ';' << fsTitle << ';' << fNofPadsX << ';' << fNofPadsY;
-  for (const auto& padCfg : fvsPadConfigs) {
-    cfg << ';' << padCfg;
+  if (fvsPadConfigs.empty()) {
+    L_(warning) << "CanvasConfig::ToString(): creating a config message for an empty pad";
+    auto pad = PadConfig();
+    cfg << ';' << pad.ToString();
+  }
+  else {
+    for (const auto& padCfg : fvsPadConfigs) {
+      cfg << ';' << padCfg;
+    }
   }
   return cfg.str();
 }
diff --git a/algo/qa/PadConfig.cxx b/algo/qa/PadConfig.cxx
index 5743b665a6a6c63e741944642b61a2c1dbb2425b..4b9d1a0394e6fbd4005f91410daca602c85fabe8 100644
--- a/algo/qa/PadConfig.cxx
+++ b/algo/qa/PadConfig.cxx
@@ -9,6 +9,7 @@
 
 #include "PadConfig.h"
 
+#include <log.hpp>
 #include <sstream>
 
 using cbm::algo::PadConfig;
@@ -37,7 +38,8 @@ std::string PadConfig::ToString() const
   std::stringstream cfg;
   cfg << fbGridX << ',' << fbGridY << ',' << fbLogX << ',' << fbLogY << ',' << fbLogZ;
   if (fvObjectList.empty()) {
-    cfg << ',';
+    L_(warning) << "PadConfig::ToString(): creating a config message for an empty pad";
+    cfg << ",(nullptr,nullptr)";
   }
   else {
     for (const auto& [name, opt] : fvObjectList) {
diff --git a/macro/run/run_qa.C b/macro/run/run_qa.C
index 47bfa43c0d62a14a0bbe38780bf0435917f29577..2f85dd770057b367745da4d32d42d532d79d9321 100644
--- a/macro/run/run_qa.C
+++ b/macro/run/run_qa.C
@@ -207,7 +207,7 @@ void run_qa(TString dataTraColl,
   FairMonitor::GetMonitor()->EnableMonitor(kTRUE, monitorFile);
 
   auto* qaManager = new CbmQaManager(verbose);
-  qaManager->SetConfigName(qaConfig);
+  //qaManager->SetConfigName(qaConfig);
   if (!sBenchmark.IsNull()) {
     qaManager->OpenBenchmarkInput(sBenchmark);
     qaManager->OpenBenchmarkOutput(benchmarkOut);