diff --git a/core/qa/CbmQaCmpDrawer.cxx b/core/qa/CbmQaCmpDrawer.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1e117bf50e616b61901e58f2bc4ce0078468a7e5
--- /dev/null
+++ b/core/qa/CbmQaCmpDrawer.cxx
@@ -0,0 +1,18 @@
+/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// @file   CbmQaCmpDrawer.cxx
+/// @brief  Class for a canvas with a comparison of multiple graphs or histograms (implementation)
+/// @since  22.04.2023
+/// @author Sergei Zharko <s.zharko@gsi.de>
+
+#include "CbmQaCmpDrawer.h"
+
+#include "TH1F.h"
+#include "TProfile.h"
+
+templateClassImp(CbmQaCmpDrawer);
+
+template class CbmQaCmpDrawer<TH1F>;
+template class CbmQaCmpDrawer<TProfile>;
diff --git a/core/qa/CbmQaCmpDrawer.h b/core/qa/CbmQaCmpDrawer.h
new file mode 100644
index 0000000000000000000000000000000000000000..d25fce7180f375cd9e8d313472655050be58d392
--- /dev/null
+++ b/core/qa/CbmQaCmpDrawer.h
@@ -0,0 +1,178 @@
+/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// @file   CbmQaCmpDrawer.h
+/// @brief  Class for a canvas with a comparison of multiple graphs or histograms (header)
+/// @since  21.04.2023
+/// @author Sergei Zharko <s.zharko@gsi.de>
+
+#ifndef CbmQaCmpDrawer_h
+#define CbmQaCmpDrawer_h 1
+
+#include "Logger.h"
+
+#include "TH1.h"
+#include "TH2.h"
+#include "TH3.h"
+#include "TLegend.h"
+#include "TPad.h"
+
+#include <algorithm>
+#include <limits>
+#include <type_traits>
+#include <vector>
+
+/// @brief  Class to draw a comparison of objects on the provided canvas or pad
+/// @tparam Obj Type of underlying objects (TH1D, TGraph, TProfile, ...)
+///
+template<class Obj>
+class CbmQaCmpDrawer {
+public:
+  /// @brief Default constructor
+  CbmQaCmpDrawer();
+
+  /// @brief Destructor
+  ~CbmQaCmpDrawer() = default;
+
+  /// @brief Copy constructor
+  CbmQaCmpDrawer(const CbmQaCmpDrawer&) = delete;
+
+  /// @brief Move constructor
+  CbmQaCmpDrawer(CbmQaCmpDrawer&&) = delete;
+
+  /// @brief Copy assignment operator
+  CbmQaCmpDrawer& operator=(const CbmQaCmpDrawer&) = delete;
+
+  /// @brief Move assignment operator
+  CbmQaCmpDrawer& operator=(CbmQaCmpDrawer&&) = delete;
+
+  /// @brief Clears the set of objects
+  void Clear();
+
+  /// @brief Registers an object to draw
+  /// @param pObj  Pointer to object
+  /// @param title Title of object (appears in the legend).
+  void RegisterObject(const Obj* pObj, const char* title = nullptr);
+
+  /// @brief Draw objects
+  /// @param opt  Drawing option:
+  ///             TODO: Specify options
+  void Draw(Option_t* opt) const;
+
+  /// @brief Sets minimum of the histogram/graph
+  /// @param min  Minimum
+  ///
+  /// If the minimum is not set with this function, it will be set to 0 or the minimal value of the objects
+  void SetMinimum(double min) { fMinimum = min; }
+
+  /// @brief Sets maximum of the histogram/graph
+  /// @param max  Maximum
+  ///
+  /// If the maximum is not set with this function, it will be set to the maximum value of the objects, multiplied
+  /// by the value (1. + kIndentFromMax), which is 1.1 by default
+  void SetMaximum(double max) { fMaximum = max; }
+
+private:
+  // Some constant expressions (TODO: move to a separate header)
+  static constexpr double kLegEntryHight = 0.06;  ///< Hight of one legend entry in Y axis
+  static constexpr double kLegEntryWidth = 0.35;  ///< Width of the legend
+  static constexpr double kLegRightBound = 0.99;  ///< Right bound of the legend
+  static constexpr double kLegTopBound   = 0.90;  ///< Top bound of the legend
+  static constexpr double kLegTextSize   = 0.04;  ///< Text size of the legend entries
+  static constexpr double kIndentFromMax = 0.1;   ///< Indent from the maximum (percentage from (max - min))
+
+  double fMinimum = std::numeric_limits<double>::signaling_NaN();
+  double fMaximum = std::numeric_limits<double>::signaling_NaN();
+
+  std::vector<Obj*> fvpObjects;        ///< Set of objects to be drawn
+  std::vector<TString> fvsLegEntries;  ///< Entries to legend
+};
+
+
+// ****************************
+// **     Implementation     **
+// ****************************
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<class Obj>
+CbmQaCmpDrawer<Obj>::CbmQaCmpDrawer()
+{
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<class Obj>
+void CbmQaCmpDrawer<Obj>::Clear()
+{
+  fvpObjects.clear();
+  fvsLegEntries.clear();
+  fMinimum = std::numeric_limits<double>::signaling_NaN();
+  fMaximum = std::numeric_limits<double>::signaling_NaN();
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<class Obj>
+void CbmQaCmpDrawer<Obj>::RegisterObject(const Obj* pObj, const char* title)
+{
+  if (!pObj) {
+    LOG(info) << "CbmQaCmpDrawer: attempt to register a nullptr (" << title << "), ignored";
+    return;
+  }
+
+  // Add entry to objects array
+  auto* pObjClone = static_cast<Obj*>(pObj->Clone());
+  fvpObjects.push_back(pObjClone);
+
+  // Add entry to legend
+  TString legEntryName = title ? title : pObj->GetTitle();
+  fvsLegEntries.push_back(legEntryName);
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<class Obj>
+void CbmQaCmpDrawer<Obj>::Draw(Option_t* /*opt*/) const
+{
+  // TH1, TProfile
+  if constexpr (std::is_base_of_v<TH1, Obj> && !std::is_base_of_v<TH2, Obj> && !std::is_base_of_v<TH3, Obj>) {
+    // Maximum and minimum
+    double maxY = fMaximum;
+    if (std::isnan(maxY)) {
+      auto HistMax = [](const Obj* lhs, const Obj* rhs) { return lhs->GetMaximum() < rhs->GetMaximum(); };
+      maxY         = (*std::max_element(fvpObjects.cbegin(), fvpObjects.cend(), HistMax))->GetMaximum();
+      maxY *= (1. + kIndentFromMax);
+    }
+    double minY = fMinimum;
+    if (std::isnan(minY)) {
+      auto HistMin = [](const Obj* lhs, const Obj* rhs) { return lhs->GetMinimum() < rhs->GetMinimum(); };
+      minY         = (*std::min_element(fvpObjects.cbegin(), fvpObjects.cend(), HistMin))->GetMaximum();
+      minY         = (minY < 0.) ? minY : 0.;
+    }
+
+    // Draw a stack of histograms
+    for (auto it = fvpObjects.begin(); it != fvpObjects.end(); ++it) {
+      (*it)->SetStats(false);
+      (*it)->SetMinimum(minY);
+      (*it)->SetMaximum(maxY);
+      (*it)->Draw(it == fvpObjects.begin() ? "" : "same");
+    }
+  }
+
+  // Draw legend
+  double legX0 = kLegRightBound - kLegEntryWidth;
+  double legX1 = kLegRightBound;
+  double legY0 = kLegTopBound - kLegEntryHight * fvpObjects.size();
+  double legY1 = kLegTopBound;
+
+  auto* pLeg = new TLegend(legX0, legY0, legX1, legY1);
+  pLeg->SetTextSize(kLegTextSize);
+  for (int iObj = 0; iObj < (int) fvpObjects.size(); ++iObj) {
+    pLeg->AddEntry(fvpObjects[iObj], fvsLegEntries[iObj], "lp");
+  }
+  pLeg->Draw();
+}
+
+#endif  // CbmQaCmpDrawer_h
diff --git a/core/qa/CbmQaIO.cxx b/core/qa/CbmQaIO.cxx
index da8aac99a56f3f19332f48d434d65f1990ab8e04..f414c3f2b802755e8ca7fd48b0a9753b5668e191 100644
--- a/core/qa/CbmQaIO.cxx
+++ b/core/qa/CbmQaIO.cxx
@@ -34,3 +34,11 @@ CbmQaIO::~CbmQaIO()
     fpFolderRoot = nullptr;
   }
 }
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void CbmQaIO::SetHistoProperties(TH1* pHist)
+{
+  pHist->SetStats(true);
+  pHist->Sumw2();
+}
diff --git a/core/qa/CbmQaIO.h b/core/qa/CbmQaIO.h
index b6ea8acdb5ff9b2778bd06d45d38774c7ca0b3f2..424ca1c3ffd870f9bc0da71fe985d37d0192fc9f 100644
--- a/core/qa/CbmQaIO.h
+++ b/core/qa/CbmQaIO.h
@@ -87,6 +87,10 @@ public:
   CbmQaTable* MakeTable(const char* name, Args... args);
 
 protected:
+  /// @brief Applies properties on the histogram created with MakeHisto funciton
+  /// @param pHist  Pointer to histogram
+  virtual void SetHistoProperties(TH1* /*pHits*/);
+
   TString fsRootFolderName = "";  ///< Name of root folder
   TString fsPrefix         = "";  ///< Unique prefix for all writeable root
 
@@ -172,8 +176,7 @@ T* CbmQaIO::MakeHisto(const char* nameBase, Args... args)
   }
 
   T* pHist = new T(name, args...);
-  pHist->SetStats(kTRUE);
-  pHist->Sumw2();
+  SetHistoProperties(pHist);
 
   // Register histogram in the folder
   if (fStoringMode == EStoringMode::kSUBDIR) {
diff --git a/reco/L1/CbmL1Track.h b/reco/L1/CbmL1Track.h
index d89fd5cedcebee8da48387dc1b07a1f90b60ec27..bad57d9da3990d770c9103b6f3e7adc3aa486388 100644
--- a/reco/L1/CbmL1Track.h
+++ b/reco/L1/CbmL1Track.h
@@ -64,6 +64,9 @@ public:
   /// Gets Chi-square of track fit model
   double GetChiSq() const { return chi2; }
 
+  /// @brief Gets pseudo-rapidity
+  double GetEta() const { return -std::log(std::tan(GetTheta() * 0.5)); }
+
   /// @brief Gets first hit index
   int GetFirstHitIndex() const { return Hits.front(); }
 
diff --git a/reco/L1/catools/CaToolsMCTrack.h b/reco/L1/catools/CaToolsMCTrack.h
index 3c474af8012bc113f4e3895f6ecc9a74839bac05..a9ab5286ee5d1e0944a3c0a17aeb3d069cb00872 100644
--- a/reco/L1/catools/CaToolsMCTrack.h
+++ b/reco/L1/catools/CaToolsMCTrack.h
@@ -92,6 +92,9 @@ namespace ca::tools
     /// Gets kinetic energy [GeV]
     double GetEkin() const { return GetE() - fMass; }
 
+    /// Gets pseudo-rapidity
+    double GetEta() const { return -std::log(std::tan(GetTheta() * 0.5)); }
+
     /// Gets index of MC event containing this track in external data structures
     int GetEventId() const { return fLinkKey.fEvent; }
 
diff --git a/reco/L1/qa/CbmCaOutputQa.cxx b/reco/L1/qa/CbmCaOutputQa.cxx
index af42719b282bd283fc7439ba8e4557612913fd5a..220f69a16710728e92f3cc5f3914b207504db16a 100644
--- a/reco/L1/qa/CbmCaOutputQa.cxx
+++ b/reco/L1/qa/CbmCaOutputQa.cxx
@@ -9,9 +9,14 @@
 
 #include "CbmCaOutputQa.h"
 
+#include "CbmQaCanvas.h"
+
 #include "FairRootManager.h"
 #include "Logger.h"
 
+#include "THStack.h"
+#include "TPad.h"
+
 #include "L1InitManager.h"
 
 using ca::tools::Debugger;
@@ -27,20 +32,38 @@ OutputQa::OutputQa(int verbose, bool isMCUsed) : CbmQaTask("CbmCaOutputQa", "cao
   AddTrackType(ETrackType::kGhost);
   AddTrackType(ETrackType::kPrim);
   AddTrackType(ETrackType::kSec);
+  AddTrackType(ETrackType::kPrimE);
+  AddTrackType(ETrackType::kPrimPI);
+  AddTrackType(ETrackType::kPrimK);
+  AddTrackType(ETrackType::kPrimMU);
+  AddTrackType(ETrackType::kPrimPPBAR);
+  AddTrackType(ETrackType::kSecE);
+  AddTrackType(ETrackType::kSecPI);
+  AddTrackType(ETrackType::kSecK);
+  AddTrackType(ETrackType::kSecMU);
+  AddTrackType(ETrackType::kSecPPBAR);
+
   AddTrackType(ETrackType::kPrimPIP);
   AddTrackType(ETrackType::kPrimPIM);
   AddTrackType(ETrackType::kSecPIP);
   AddTrackType(ETrackType::kSecPIM);
-  AddTrackType(ETrackType::kPrimMUP);
-  AddTrackType(ETrackType::kPrimMUM);
-  AddTrackType(ETrackType::kSecMUP);
-  AddTrackType(ETrackType::kSecMUM);
+  AddTrackType(ETrackType::kPrimKP);
+  AddTrackType(ETrackType::kPrimKM);
+  AddTrackType(ETrackType::kSecKP);
+  AddTrackType(ETrackType::kSecKM);
+  AddTrackType(ETrackType::kPrimP);
+  AddTrackType(ETrackType::kPrimPBAR);
+  AddTrackType(ETrackType::kSecP);
+  AddTrackType(ETrackType::kSecPBAR);
 
   //AddTrackType(ETrackType::kAllE);
   //AddTrackType(ETrackType::kAllMU);
   //AddTrackType(ETrackType::kAllPI);
   //AddTrackType(ETrackType::kAllK);
   //AddTrackType(ETrackType::kAllPPBAR);
+
+  // Init track type histograms drawing attributes
+  InitDrawingAttributes();
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -75,7 +98,7 @@ void OutputQa::FillHistograms()
         if (fvpTrackHistograms[iType]->IsMCUsed()) { fvpTrackHistograms[iType]->FillMCTracks(); }
       }  // if track type ID filled
     }    // track type ID
-  }
+  }      // kEXPTRACKFILL = true
   else {
     for (size_t iTrkReco = 0; iTrkReco < fvRecoTracks.size(); ++iTrkReco) {
       const auto& recoTrk = fvRecoTracks[iTrkReco];
@@ -83,12 +106,12 @@ void OutputQa::FillHistograms()
       // Reject tracks, which do not contain hits
       if (recoTrk.GetNofHits() < 1) { continue; }
 
-      if (fvbTrackTypeOn[ETrackType::kAll]) { fvpTrackHistograms[ETrackType::kAll]->FillRecoTrack(iTrkReco); }
+      FillRecoTrack(ETrackType::kAll, iTrkReco);
 
       if (IsMCUsed()) {
-        if (fvbTrackTypeOn[ETrackType::kGhost] && recoTrk.IsGhost()) {
-          fvpTrackHistograms[ETrackType::kGhost]->FillRecoTrack(iTrkReco);
-        }
+        // NOTE: The ghost status of track is now defined by its purity, thus it can still contain MC information
+        if (recoTrk.IsGhost()) { FillRecoTrack(ETrackType::kGhost, iTrkReco); }
+
         int iTrkMC = recoTrk.GetMatchedMCTrackIndex();
         if (iTrkMC > -1) {
           const auto& mcTrk = fMCData.GetTrack(iTrkMC);
@@ -98,33 +121,7 @@ void OutputQa::FillHistograms()
           // Cut tracks, which did not leave hits in tracker
           if (mcTrk.GetNofHits() == 0) { continue; }
 
-          if (isPrimary) {
-            if (fvbTrackTypeOn[ETrackType::kPrim]) { fvpTrackHistograms[ETrackType::kPrim]->FillRecoTrack(iTrkReco); }
-
-            if (fvbTrackTypeOn[ETrackType::kPrimPI] && std::abs(pdg) == 211) {
-              fvpTrackHistograms[ETrackType::kPrimPI]->FillRecoTrack(iTrkReco);
-            }
-
-            if (fvbTrackTypeOn[ETrackType::kPrimPIP] && pdg == +211) {
-              fvpTrackHistograms[ETrackType::kPrimPIP]->FillRecoTrack(iTrkReco);
-            }
-
-            if (fvbTrackTypeOn[ETrackType::kPrimPIM] && pdg == -211) {
-              fvpTrackHistograms[ETrackType::kPrimPIM]->FillRecoTrack(iTrkReco);
-            }
-
-            if (fvbTrackTypeOn[ETrackType::kPrimMU] && std::abs(pdg) == 13) {
-              fvpTrackHistograms[ETrackType::kPrimMU]->FillRecoTrack(iTrkReco);
-            }
-
-            if (fvbTrackTypeOn[ETrackType::kPrimMUP] && pdg == +13) {
-              fvpTrackHistograms[ETrackType::kPrimMUP]->FillRecoTrack(iTrkReco);
-            }
-
-            if (fvbTrackTypeOn[ETrackType::kPrimMUM] && pdg == -13) {
-              fvpTrackHistograms[ETrackType::kPrimMUM]->FillRecoTrack(iTrkReco);
-            }
-          }
+          if (isPrimary) { FillRecoTrack(ETrackType::kPrim, iTrkReco); }
           else {
             if (fvbTrackTypeOn[ETrackType::kSec]) { fvpTrackHistograms[ETrackType::kSec]->FillRecoTrack(iTrkReco); }
 
@@ -152,6 +149,65 @@ void OutputQa::FillHistograms()
               fvpTrackHistograms[ETrackType::kSecMUM]->FillRecoTrack(iTrkReco);
             }
           }
+
+          // Track distributions for different particle species
+          switch (std::abs(pdg)) {
+            case 211:  // pion
+              FillRecoTrack(ETrackType::kAllPI, iTrkReco);
+              if (isPrimary) {
+                FillRecoTrack(ETrackType::kPrimPI, iTrkReco);
+                FillRecoTrack((pdg > 0) ? ETrackType::kPrimPIP : ETrackType::kPrimPIM, iTrkReco);
+              }
+              else {
+                FillRecoTrack(ETrackType::kSecPI, iTrkReco);
+                FillRecoTrack((pdg > 0) ? ETrackType::kSecPIP : ETrackType::kSecPIM, iTrkReco);
+              }
+              break;
+            case 2212:  // proton
+              FillRecoTrack(ETrackType::kAllPPBAR, iTrkReco);
+              if (isPrimary) {
+                FillRecoTrack(ETrackType::kPrimPPBAR, iTrkReco);
+                FillRecoTrack((pdg > 0) ? ETrackType::kPrimP : ETrackType::kPrimPBAR, iTrkReco);
+              }
+              else {
+                FillRecoTrack(ETrackType::kSecPPBAR, iTrkReco);
+                FillRecoTrack((pdg > 0) ? ETrackType::kSecP : ETrackType::kSecPBAR, iTrkReco);
+              }
+              break;
+            case 321:  // kaon
+              FillRecoTrack(ETrackType::kAllK, iTrkReco);
+              if (isPrimary) {
+                FillRecoTrack(ETrackType::kPrimK, iTrkReco);
+                FillRecoTrack((pdg > 0) ? ETrackType::kPrimKP : ETrackType::kPrimKM, iTrkReco);
+              }
+              else {
+                FillRecoTrack(ETrackType::kSecK, iTrkReco);
+                FillRecoTrack((pdg > 0) ? ETrackType::kSecKP : ETrackType::kSecKM, iTrkReco);
+              }
+              break;
+            case 11:  // electron
+              FillRecoTrack(ETrackType::kAllE, iTrkReco);
+              if (isPrimary) {
+                FillRecoTrack(ETrackType::kPrimE, iTrkReco);
+                FillRecoTrack((pdg < 0) ? ETrackType::kPrimEP : ETrackType::kPrimEM, iTrkReco);
+              }
+              else {
+                FillRecoTrack(ETrackType::kSecE, iTrkReco);
+                FillRecoTrack((pdg < 0) ? ETrackType::kSecEP : ETrackType::kSecEM, iTrkReco);
+              }
+              break;
+            case 13:  // muon
+              FillRecoTrack(ETrackType::kAllMU, iTrkReco);
+              if (isPrimary) {
+                FillRecoTrack(ETrackType::kPrimMU, iTrkReco);
+                FillRecoTrack((pdg > 0) ? ETrackType::kPrimMUP : ETrackType::kPrimMUM, iTrkReco);
+              }
+              else {
+                FillRecoTrack(ETrackType::kSecMU, iTrkReco);
+                FillRecoTrack((pdg > 0) ? ETrackType::kSecMUP : ETrackType::kSecMUM, iTrkReco);
+              }
+              break;
+          }  // switch abs(pdg): end
         }
       }
     }  // loop over recoTrk: end
@@ -161,86 +217,176 @@ void OutputQa::FillHistograms()
     // ** Fill distributions of MC-tracks **
     // *************************************
     if (IsMCUsed()) {
-
-
       for (int iTrkMC = 0; iTrkMC < fMCData.GetNofTracks(); ++iTrkMC) {
         const auto& mcTrk = fMCData.GetTrack(iTrkMC);
 
         // Cut tracks, which did not leave hits in tracker
         if (mcTrk.GetNofHits() == 0) { continue; }
 
-        // Fill different track categories
-        if (fvbTrackTypeOn[ETrackType::kAll]) { fvpTrackHistograms[ETrackType::kAll]->FillMCTrack(iTrkMC); }
-
         int pdg        = mcTrk.GetPdgCode();
         bool isPrimary = mcTrk.IsPrimary();
 
-        if (isPrimary) {
-          if (fvbTrackTypeOn[ETrackType::kPrim]) { fvpTrackHistograms[ETrackType::kPrim]->FillMCTrack(iTrkMC); }
+        // Fill different track categories
+        FillMCTrack(ETrackType::kAll, iTrkMC);
+        if (isPrimary) { FillMCTrack(ETrackType::kPrim, iTrkMC); }
+        else {
+          FillMCTrack(ETrackType::kSec, iTrkMC);
+        }
 
-          if (fvbTrackTypeOn[ETrackType::kPrimPI] && std::abs(pdg) == 211) {
-            fvpTrackHistograms[ETrackType::kPrimPI]->FillMCTrack(iTrkMC);
-          }
+        // Track distributions for different particle species
+        switch (std::abs(pdg)) {
+          case 211:  // pion
+            FillMCTrack(ETrackType::kAllPI, iTrkMC);
+            if (isPrimary) {
+              FillMCTrack(ETrackType::kPrimPI, iTrkMC);
+              FillMCTrack((pdg > 0) ? ETrackType::kPrimPIP : ETrackType::kPrimPIM, iTrkMC);
+            }
+            else {
+              FillMCTrack(ETrackType::kSecPI, iTrkMC);
+              FillMCTrack((pdg > 0) ? ETrackType::kSecPIP : ETrackType::kSecPIM, iTrkMC);
+            }
+            break;
+          case 2212:  // proton
+            FillMCTrack(ETrackType::kAllPPBAR, iTrkMC);
+            if (isPrimary) {
+              FillMCTrack(ETrackType::kPrimPPBAR, iTrkMC);
+              FillMCTrack((pdg > 0) ? ETrackType::kPrimP : ETrackType::kPrimPBAR, iTrkMC);
+            }
+            else {
+              FillMCTrack(ETrackType::kSecPPBAR, iTrkMC);
+              FillMCTrack((pdg > 0) ? ETrackType::kSecP : ETrackType::kSecPBAR, iTrkMC);
+            }
+            break;
+          case 321:  // kaon
+            FillMCTrack(ETrackType::kAllK, iTrkMC);
+            if (isPrimary) {
+              FillMCTrack(ETrackType::kPrimK, iTrkMC);
+              FillMCTrack((pdg > 0) ? ETrackType::kPrimKP : ETrackType::kPrimKM, iTrkMC);
+            }
+            else {
+              FillMCTrack(ETrackType::kSecK, iTrkMC);
+              FillMCTrack((pdg > 0) ? ETrackType::kSecKP : ETrackType::kSecKM, iTrkMC);
+            }
+            break;
+          case 11:  // electron
+            FillMCTrack(ETrackType::kAllE, iTrkMC);
+            if (isPrimary) {
+              FillMCTrack(ETrackType::kPrimE, iTrkMC);
+              FillMCTrack((pdg < 0) ? ETrackType::kPrimEP : ETrackType::kPrimEM, iTrkMC);
+            }
+            else {
+              FillMCTrack(ETrackType::kSecE, iTrkMC);
+              FillMCTrack((pdg < 0) ? ETrackType::kSecEP : ETrackType::kSecEM, iTrkMC);
+            }
+            break;
+          case 13:  // muon
+            FillMCTrack(ETrackType::kAllMU, iTrkMC);
+            if (isPrimary) {
+              FillMCTrack(ETrackType::kPrimMU, iTrkMC);
+              FillMCTrack((pdg > 0) ? ETrackType::kPrimMUP : ETrackType::kPrimMUM, iTrkMC);
+            }
+            else {
+              FillMCTrack(ETrackType::kSecMU, iTrkMC);
+              FillMCTrack((pdg > 0) ? ETrackType::kSecMUP : ETrackType::kSecMUM, iTrkMC);
+            }
+            break;
+        }  // switch abs(pdg): end
+      }    // iTrkMC
+    }      // IsMCUsed()
+  }        // kEXPTRACKFILL = false
+}
 
-          if (fvbTrackTypeOn[ETrackType::kPrimPIP] && pdg == +211) {
-            fvpTrackHistograms[ETrackType::kPrimPIP]->FillMCTrack(iTrkMC);
-          }
+// ---------------------------------------------------------------------------------------------------------------------
+//
+InitStatus OutputQa::InitCanvases()
+{
+  /// Set of track types to compare
+  std::vector<ETrackType> vCmpTypesGeneral = {kAll, kPrim, kSec};
+  std::vector<ETrackType> vCmpTypesPrim    = {kPrim, kPrimE, kPrimMU, kPrimPI, kPrimK, kPrimPPBAR};
+  std::vector<ETrackType> vCmpTypesSec     = {kSec, kSecE, kSecMU, kSecPI, kSecK, kSecPPBAR};
+  std::vector<ETrackType> vCmpTypesPions   = {kAllPI, kPrimPIP, kPrimPIM, kSecPIP, kSecPIM};
+  std::vector<ETrackType> vCmpTypesKaons   = {kAllK, kPrimKP, kPrimKM, kSecKP, kSecKM};
+  std::vector<ETrackType> vCmpTypesProtons = {kAllPPBAR, kPrimP, kPrimPBAR, kSecP, kSecPBAR};
+
+  /// @brief Function to draw generic canvas of histogram comparison
+  auto DrawTrackDistributions = [&](CbmQaCanvas* pCanv, std::function<TH1F*(ETrackType)> Hist) {
+    pCanv->Divide2D(6);
+    pCanv->cd(1);
+    gPad->SetLogy();
+    DrawSetOf<TH1F>(vCmpTypesGeneral, Hist);
+    pCanv->cd(2);
+    gPad->SetLogy();
+    DrawSetOf<TH1F>(vCmpTypesPrim, Hist);
+    pCanv->cd(3);
+    gPad->SetLogy();
+    DrawSetOf<TH1F>(vCmpTypesSec, Hist);
+    pCanv->cd(4);
+    gPad->SetLogy();
+    DrawSetOf<TH1F>(vCmpTypesPions, Hist);
+    pCanv->cd(5);
+    gPad->SetLogy();
+    DrawSetOf<TH1F>(vCmpTypesKaons, Hist);
+    pCanv->cd(6);
+    gPad->SetLogy();
+    DrawSetOf<TH1F>(vCmpTypesProtons, Hist);
+  };
 
-          if (fvbTrackTypeOn[ETrackType::kPrimPIM] && pdg == -211) {
-            fvpTrackHistograms[ETrackType::kPrimPIM]->FillMCTrack(iTrkMC);
-          }
+  /// @brief Function to draw generic canvas of efficiencies comparison
+  auto DrawTrackEfficiens = [&](CbmQaCanvas* pCanv, std::function<TProfile*(ETrackType)> Prof) {
+    pCanv->Divide2D(3);
+    pCanv->cd(1);
+    DrawSetOf<TProfile>(vCmpTypesGeneral, Prof);
+    pCanv->cd(2);
+    DrawSetOf<TProfile>(vCmpTypesPrim, Prof);
+    pCanv->cd(3);
+    DrawSetOf<TProfile>(vCmpTypesSec, Prof);
+  };
 
-          if (fvbTrackTypeOn[ETrackType::kPrimMU] && std::abs(pdg) == 13) {
-            fvpTrackHistograms[ETrackType::kPrimMU]->FillMCTrack(iTrkMC);
-          }
 
-          if (fvbTrackTypeOn[ETrackType::kPrimMUP] && pdg == +13) {
-            fvpTrackHistograms[ETrackType::kPrimMUP]->FillMCTrack(iTrkMC);
-          }
+  if (IsMCUsed()) {
+    // **  Reconstructed track distributions  **
+    // Reconstructed pseudorapidity
+    auto* pc_reco_eta =
+      MakeCanvas<CbmQaCanvas>("reco_eta", "Reconstructed track pseudorapidity", kCXSIZEPX * 3, kCYSIZEPX * 2);
+    DrawTrackDistributions(pc_reco_eta, [&](ETrackType t) -> TH1F* { return fvpTrackHistograms[t]->fph_reco_eta; });
 
-          if (fvbTrackTypeOn[ETrackType::kPrimMUM] && pdg == -13) {
-            fvpTrackHistograms[ETrackType::kPrimMUM]->FillMCTrack(iTrkMC);
-          }
-        }
-        else {
-          if (fvbTrackTypeOn[ETrackType::kSec]) { fvpTrackHistograms[ETrackType::kSec]->FillMCTrack(iTrkMC); }
+    // MC pseudorapidity
+    auto* pc_reco_etaMC =
+      MakeCanvas<CbmQaCanvas>("reco_etaMC", "Reconstructed track MC pseudorapidity", kCXSIZEPX * 3, kCYSIZEPX * 2);
+    DrawTrackDistributions(pc_reco_etaMC, [&](ETrackType t) -> TH1F* { return fvpTrackHistograms[t]->fph_reco_etaMC; });
 
-          if (fvbTrackTypeOn[ETrackType::kSecPIP] && std::abs(pdg) == 211) {
-            fvpTrackHistograms[ETrackType::kSecPIP]->FillMCTrack(iTrkMC);
-          }
+    // MC momentum
+    auto* pc_reco_pMC =
+      MakeCanvas<CbmQaCanvas>("reco_pMC", "Reconstructed track MC momentum", kCXSIZEPX * 3, kCYSIZEPX * 2);
+    DrawTrackDistributions(pc_reco_pMC, [&](ETrackType t) -> TH1F* { return fvpTrackHistograms[t]->fph_reco_pMC; });
 
-          if (fvbTrackTypeOn[ETrackType::kSecPIP] && pdg == +211) {
-            fvpTrackHistograms[ETrackType::kPrimPIP]->FillMCTrack(iTrkMC);
-          }
+    // MC rapidity
+    auto* pc_reco_yMC =
+      MakeCanvas<CbmQaCanvas>("reco_yMC", "Reconstructed track MC rapidity", kCXSIZEPX * 3, kCYSIZEPX * 2);
+    DrawTrackDistributions(pc_reco_yMC, [&](ETrackType t) -> TH1F* { return fvpTrackHistograms[t]->fph_reco_yMC; });
 
-          if (fvbTrackTypeOn[ETrackType::kSecPIM] && pdg == -211) {
-            fvpTrackHistograms[ETrackType::kPrimPIM]->FillMCTrack(iTrkMC);
-          }
+    // **  MC track distributions  **
 
-          if (fvbTrackTypeOn[ETrackType::kSecMU] && std::abs(pdg) == 13) {
-            fvpTrackHistograms[ETrackType::kSecMU]->FillMCTrack(iTrkMC);
-          }
+    // MC momentum
+    auto* pc_mc_pMC =
+      MakeCanvas<CbmQaCanvas>("mc_pMC", "MC reconstructable track MC momentum", kCXSIZEPX * 3, kCYSIZEPX * 2);
+    DrawTrackDistributions(pc_mc_pMC, [&](ETrackType t) -> TH1F* { return fvpTrackHistograms[t]->fph_mc_pMC; });
 
-          if (fvbTrackTypeOn[ETrackType::kSecMUP] && pdg == +13) {
-            fvpTrackHistograms[ETrackType::kSecMUP]->FillMCTrack(iTrkMC);
-          }
+    // MC rapidity
+    auto* pc_mc_yMC =
+      MakeCanvas<CbmQaCanvas>("mc_yMC", "MC reconstructable track MC rapidity", kCXSIZEPX * 3, kCYSIZEPX * 2);
+    DrawTrackDistributions(pc_mc_yMC, [&](ETrackType t) -> TH1F* { return fvpTrackHistograms[t]->fph_mc_yMC; });
 
-          if (fvbTrackTypeOn[ETrackType::kSecMUM] && pdg == -13) {
-            fvpTrackHistograms[ETrackType::kSecMUM]->FillMCTrack(iTrkMC);
-          }
-        }
-      }
-    }
-  }
-}
 
-// ---------------------------------------------------------------------------------------------------------------------
-//
-InitStatus OutputQa::InitCanvases()
-{
-  // ***************************
-  // **  Track distributions
+    // **  Efficiencies  **
+
+    // MC momentum
+    auto* pc_eff_pMC = MakeCanvas<CbmQaCanvas>("eff_pMC", "Tracking Eff. vs. MC momentum", kCXSIZEPX * 3, kCYSIZEPX);
+    DrawTrackEfficiens(pc_eff_pMC, [&](ETrackType t) -> TProfile* { return fvpTrackHistograms[t]->fph_eff_pMC; });
 
+    auto* pc_eff_yMC = MakeCanvas<CbmQaCanvas>("eff_yMC", "Tracking Eff. vs. MC rapidity", kCXSIZEPX * 3, kCYSIZEPX);
+    DrawTrackEfficiens(pc_eff_yMC, [&](ETrackType t) -> TProfile* { return fvpTrackHistograms[t]->fph_eff_yMC; });
+  }
 
   return kSUCCESS;
 }
@@ -313,15 +459,16 @@ InitStatus OutputQa::InitDataBranches()
 //
 InitStatus OutputQa::InitHistograms()
 {
-  auto RegisterTrackQa = [&](const char* typeName, ETrackType type, bool bSuppressMC = false) {
+  auto RegisterTrackQa = [&](const char* typeName, const char* title, ETrackType type, bool bSuppressMC = false) {
     if (!fvbTrackTypeOn[type]) { return; }
     bool bUseMC              = IsMCUsed() && !bSuppressMC;
     fvpTrackHistograms[type] = std::make_unique<TrackTypeQa>(typeName, fsPrefix.Data(), bUseMC, fpFolderRoot);
+    fvpTrackHistograms[type]->SetTitle(title);
     fvpTrackHistograms[type]->RegisterParameters(fpParameters);
     fvpTrackHistograms[type]->RegisterRecoHits(fvHits);
     fvpTrackHistograms[type]->RegisterRecoTracks(fvRecoTracks);
     fvpTrackHistograms[type]->RegisterMCData(fMCData);
-
+    fvpTrackHistograms[type]->SetDrawAtt(fvTrackDrawAtts[type].fColor, fvTrackDrawAtts[type].fMarker);
     if constexpr (kEXPTRACKFILL) {
       // Define track cuts
       switch (type) {
@@ -487,6 +634,7 @@ InitStatus OutputQa::InitHistograms()
           fvpTrackHistograms[type]->SetMCTrackCut(
             [](const MCTrack& t) -> bool { return !t.IsPrimary() && t.GetPdgCode() == -2212; });
           break;
+        case kEND: break;
       }
     }
 
@@ -497,46 +645,46 @@ InitStatus OutputQa::InitHistograms()
     LOG(info) << i << ' ' << fvpTrackHistograms[i].get() << ' ' << fvbTrackTypeOn[i];
   }
 
-  RegisterTrackQa("all", ETrackType::kAll);
+  RegisterTrackQa("all", "all", ETrackType::kAll);
   if (IsMCUsed()) {
-    RegisterTrackQa("ghost", ETrackType::kGhost, /*suppress MC*/ true);
-    RegisterTrackQa("prim", ETrackType::kPrim);
-    RegisterTrackQa("sec", ETrackType::kSec);
-    RegisterTrackQa("all_pi", ETrackType::kAllPI);
-    RegisterTrackQa("prim_pi", ETrackType::kPrimPI);
-    RegisterTrackQa("prim_pip", ETrackType::kPrimPIP);
-    RegisterTrackQa("prim_pim", ETrackType::kPrimPIM);
-    RegisterTrackQa("sec_pi", ETrackType::kSecPI);
-    RegisterTrackQa("sec_pip", ETrackType::kSecPIP);
-    RegisterTrackQa("sec_pim", ETrackType::kSecPIM);
-    RegisterTrackQa("all_e", ETrackType::kAllE);
-    RegisterTrackQa("prim_e", ETrackType::kPrimE);
-    RegisterTrackQa("prim_ep", ETrackType::kPrimEP);
-    RegisterTrackQa("prim_em", ETrackType::kPrimEM);
-    RegisterTrackQa("sec_e", ETrackType::kSecE);
-    RegisterTrackQa("sec_ep", ETrackType::kSecEP);
-    RegisterTrackQa("sec_em", ETrackType::kSecEM);
-    RegisterTrackQa("all_mu", ETrackType::kAllMU);
-    RegisterTrackQa("prim_mu", ETrackType::kPrimMU);
-    RegisterTrackQa("prim_mup", ETrackType::kPrimMUP);
-    RegisterTrackQa("prim_mum", ETrackType::kPrimMUM);
-    RegisterTrackQa("sec_mu", ETrackType::kSecMU);
-    RegisterTrackQa("sec_mup", ETrackType::kSecMUP);
-    RegisterTrackQa("sec_mum", ETrackType::kSecMUM);
-    RegisterTrackQa("all_k", ETrackType::kAllK);
-    RegisterTrackQa("prim_k", ETrackType::kPrimK);
-    RegisterTrackQa("prim_kp", ETrackType::kPrimKP);
-    RegisterTrackQa("prim_km", ETrackType::kPrimKM);
-    RegisterTrackQa("sec_k", ETrackType::kSecK);
-    RegisterTrackQa("sec_kp", ETrackType::kSecKP);
-    RegisterTrackQa("sec_km", ETrackType::kSecKM);
-    RegisterTrackQa("all_ppbar", ETrackType::kAllPPBAR);
-    RegisterTrackQa("prim_ppbar", ETrackType::kPrimPPBAR);
-    RegisterTrackQa("prim_p", ETrackType::kPrimP);
-    RegisterTrackQa("prim_pbar", ETrackType::kPrimPBAR);
-    RegisterTrackQa("sec_ppbar", ETrackType::kSecPPBAR);
-    RegisterTrackQa("sec_p", ETrackType::kSecP);
-    RegisterTrackQa("sec_pbar", ETrackType::kSecPBAR);
+    RegisterTrackQa("ghost", "ghost", ETrackType::kGhost, true);
+    RegisterTrackQa("prim", "primary", ETrackType::kPrim);
+    RegisterTrackQa("sec", "secondary", ETrackType::kSec);
+    RegisterTrackQa("all_pi", "all #pi^{#pm}", ETrackType::kAllPI);
+    RegisterTrackQa("prim_pi", "primary #pi^{#pm}", ETrackType::kPrimPI);
+    RegisterTrackQa("prim_pip", "primary #pi^{#plus}", ETrackType::kPrimPIP);
+    RegisterTrackQa("prim_pim", "primary #pi^{#minus}", ETrackType::kPrimPIM);
+    RegisterTrackQa("sec_pi", "secondary #pi^{#pm}", ETrackType::kSecPI);
+    RegisterTrackQa("sec_pip", "secondary #pi^{#plus}", ETrackType::kSecPIP);
+    RegisterTrackQa("sec_pim", "secondary #pi^{#minus}", ETrackType::kSecPIM);
+    RegisterTrackQa("all_e", "all e^{#pm}", ETrackType::kAllE);
+    RegisterTrackQa("prim_e", "primary e^{#pm}", ETrackType::kPrimE);
+    RegisterTrackQa("prim_ep", "primary e^{#plus}", ETrackType::kPrimEP);
+    RegisterTrackQa("prim_em", "primary e^{#minus}", ETrackType::kPrimEM);
+    RegisterTrackQa("sec_e", "secondary e^{#pm}", ETrackType::kSecE);
+    RegisterTrackQa("sec_ep", "secondary e^{#plus}", ETrackType::kSecEP);
+    RegisterTrackQa("sec_em", "secondary e^{#minus}", ETrackType::kSecEM);
+    RegisterTrackQa("all_mu", "all #mu^{#pm}", ETrackType::kAllMU);
+    RegisterTrackQa("prim_mu", "primary #mu^{#pm}", ETrackType::kPrimMU);
+    RegisterTrackQa("prim_mup", "primary #mu^{#plus}", ETrackType::kPrimMUP);
+    RegisterTrackQa("prim_mum", "primary #mu^{#minus}", ETrackType::kPrimMUM);
+    RegisterTrackQa("sec_mu", "secondary #mu^{#pm}", ETrackType::kSecMU);
+    RegisterTrackQa("sec_mup", "secondary #mu^{#plus}", ETrackType::kSecMUP);
+    RegisterTrackQa("sec_mum", "secondary #mu^{#minus}", ETrackType::kSecMUM);
+    RegisterTrackQa("all_k", "all K^{#pm}", ETrackType::kAllK);
+    RegisterTrackQa("prim_k", "primary K^{#pm}", ETrackType::kPrimK);
+    RegisterTrackQa("prim_kp", "primary K^{#plus}", ETrackType::kPrimKP);
+    RegisterTrackQa("prim_km", "primary K^{#minus}", ETrackType::kPrimKM);
+    RegisterTrackQa("sec_k", "secondary K^{#pm}", ETrackType::kSecK);
+    RegisterTrackQa("sec_kp", "secondary K^{#plus}", ETrackType::kSecKP);
+    RegisterTrackQa("sec_km", "secondary K^{#minus}", ETrackType::kSecKM);
+    RegisterTrackQa("all_ppbar", "all p/#bar{p}", ETrackType::kAllPPBAR);
+    RegisterTrackQa("prim_ppbar", "primary p/#bar{p}", ETrackType::kPrimPPBAR);
+    RegisterTrackQa("prim_p", "primary p", ETrackType::kPrimP);
+    RegisterTrackQa("prim_pbar", "primary #bar{p}", ETrackType::kPrimPBAR);
+    RegisterTrackQa("sec_ppbar", "secondary p/#bar{p}", ETrackType::kSecPPBAR);
+    RegisterTrackQa("sec_p", "secondary p", ETrackType::kSecP);
+    RegisterTrackQa("sec_pbar", "secondary #bar{p}", ETrackType::kSecPBAR);
   }
 
   return kSUCCESS;
@@ -582,3 +730,53 @@ void OutputQa::ReadParameters(const char* filename)
 
   LOG(info) << fpParameters->ToString(0);
 }
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void OutputQa::InitDrawingAttributes()
+{
+  fvTrackDrawAtts[ETrackType::kAll]   = {1, 20};
+  fvTrackDrawAtts[ETrackType::kGhost] = {kGray, 20};
+  fvTrackDrawAtts[ETrackType::kPrim]  = {kGray + 3, 21};
+  fvTrackDrawAtts[ETrackType::kSec]   = {kGray + 2, 25};
+
+  fvTrackDrawAtts[ETrackType::kAllPI]   = {kRed - 4, 20};
+  fvTrackDrawAtts[ETrackType::kPrimPI]  = {kRed - 2, 21};
+  fvTrackDrawAtts[ETrackType::kPrimPIP] = {kRed - 1, 22};
+  fvTrackDrawAtts[ETrackType::kPrimPIM] = {kRed - 3, 23};
+  fvTrackDrawAtts[ETrackType::kSecPI]   = {kRed - 8, 25};
+  fvTrackDrawAtts[ETrackType::kSecPIP]  = {kRed - 6, 26};
+  fvTrackDrawAtts[ETrackType::kSecPIM]  = {kRed - 10, 32};
+
+  fvTrackDrawAtts[ETrackType::kAllK]   = {kBlue - 4, 20};
+  fvTrackDrawAtts[ETrackType::kPrimK]  = {kBlue - 2, 21};
+  fvTrackDrawAtts[ETrackType::kPrimKP] = {kBlue - 1, 22};
+  fvTrackDrawAtts[ETrackType::kPrimKM] = {kBlue - 3, 23};
+  fvTrackDrawAtts[ETrackType::kSecK]   = {kBlue - 8, 25};
+  fvTrackDrawAtts[ETrackType::kSecKP]  = {kBlue - 6, 26};
+  fvTrackDrawAtts[ETrackType::kSecKM]  = {kBlue - 10, 32};
+
+  fvTrackDrawAtts[ETrackType::kAllPPBAR]  = {kGreen - 4, 20};
+  fvTrackDrawAtts[ETrackType::kPrimPPBAR] = {kGreen - 2, 21};
+  fvTrackDrawAtts[ETrackType::kPrimP]     = {kGreen - 1, 22};
+  fvTrackDrawAtts[ETrackType::kPrimPBAR]  = {kGreen - 3, 23};
+  fvTrackDrawAtts[ETrackType::kSecPPBAR]  = {kGreen - 8, 25};
+  fvTrackDrawAtts[ETrackType::kSecP]      = {kGreen - 6, 26};
+  fvTrackDrawAtts[ETrackType::kSecPBAR]   = {kGreen - 10, 32};
+
+  fvTrackDrawAtts[ETrackType::kAllE]   = {kCyan - 4, 20};
+  fvTrackDrawAtts[ETrackType::kPrimE]  = {kCyan - 2, 21};
+  fvTrackDrawAtts[ETrackType::kPrimEP] = {kCyan - 1, 22};
+  fvTrackDrawAtts[ETrackType::kPrimEM] = {kCyan - 3, 23};
+  fvTrackDrawAtts[ETrackType::kSecE]   = {kCyan - 8, 25};
+  fvTrackDrawAtts[ETrackType::kSecEP]  = {kCyan - 6, 26};
+  fvTrackDrawAtts[ETrackType::kSecEM]  = {kCyan - 10, 32};
+
+  fvTrackDrawAtts[ETrackType::kAllMU]   = {kMagenta - 4, 20};
+  fvTrackDrawAtts[ETrackType::kPrimMU]  = {kMagenta - 2, 21};
+  fvTrackDrawAtts[ETrackType::kPrimMUP] = {kMagenta - 1, 22};
+  fvTrackDrawAtts[ETrackType::kPrimMUM] = {kMagenta - 3, 23};
+  fvTrackDrawAtts[ETrackType::kSecMU]   = {kMagenta - 8, 25};
+  fvTrackDrawAtts[ETrackType::kSecMUP]  = {kMagenta - 6, 26};
+  fvTrackDrawAtts[ETrackType::kSecMUM]  = {kMagenta - 10, 32};
+}
diff --git a/reco/L1/qa/CbmCaOutputQa.h b/reco/L1/qa/CbmCaOutputQa.h
index 2cac1f21bc4c6d637c0dc8a918714d852c74eccb..95e84669861249594c74741a0c917a89a2bbeda1 100644
--- a/reco/L1/qa/CbmCaOutputQa.h
+++ b/reco/L1/qa/CbmCaOutputQa.h
@@ -15,6 +15,7 @@
 #include "CbmCaTrackTypeQa.h"
 #include "CbmL1DetectorID.h"
 #include "CbmL1Hit.h"
+#include "CbmQaCmpDrawer.h"
 #include "CbmQaTask.h"
 
 #include <array>
@@ -96,6 +97,16 @@ namespace cbm::ca
     // 3) Experimental approach runs in ~10% slower, then the standard
     static constexpr bool kEXPTRACKFILL = false;
 
+    /// Array for track type properties
+    template<typename T>
+    using TTypeArr_t = std::array<T, ETrackType::kEND>;
+
+    /// @brief Structure to keep drawing attributes of histograms
+    struct DrawAtt {
+      Color_t fColor  = 1;  ///< Marker and line color
+      Style_t fMarker = 1;  ///< Marker style
+    };
+
   public:
     /// @brief  Constructor from parameters
     /// @param  verbose   Verbosity level
@@ -185,6 +196,33 @@ namespace cbm::ca
     void FillTrackTypeHistograms();
 
   private:
+    /// @brief Fills reconstructed track by its index
+    /// @param type      Track type
+    /// @param iTrkReco  Index of reconstructed track
+    [[gnu::always_inline]] void FillRecoTrack(ETrackType type, int iTrkReco)
+    {
+      if (fvbTrackTypeOn[type]) { fvpTrackHistograms[type]->FillRecoTrack(iTrkReco); }
+    }
+
+    /// @brief Fills MC track by its index
+    /// @param type      Track type
+    /// @param iTrkReco  Index of MC track
+    [[gnu::always_inline]] void FillMCTrack(ETrackType type, int iTrkMC)
+    {
+      if (fvbTrackTypeOn[type]) { fvpTrackHistograms[type]->FillMCTrack(iTrkMC); }
+    }
+
+    /// @brief Utility function to draw a generic comparison of histograms from different track types
+    /// @tparam TObj    Type of ROOT object
+    /// @param  vTypes  Vector of types to draw
+    /// @param  GetObj  Function, returning an object of a given type
+    template<class TObj>
+    void DrawSetOf(const std::vector<ETrackType>& vTypes, std::function<TObj*(ETrackType)> GetObj);
+
+
+    /// @brief Defines drawing attributes for histograms of different track types
+    void InitDrawingAttributes();
+
     // Flags for detector subsystems being used
     bool fbUseMvd  = false;  ///< is MVD used
     bool fbUseSts  = false;  ///< is STS used
@@ -212,11 +250,36 @@ namespace cbm::ca
     // **  List of histograms **
     // *************************
 
-    /// Histograms of different track types
-    std::array<std::unique_ptr<TrackTypeQa>, ETrackType::kEND> fvpTrackHistograms;
-    std::array<bool, ETrackType::kEND> fvbTrackTypeOn = {0};  ///< Track type is on
+    TTypeArr_t<std::unique_ptr<TrackTypeQa>> fvpTrackHistograms;  ///< Histogrammers for different track types
+    TTypeArr_t<bool> fvbTrackTypeOn = {0};                        ///< Usage flag for different track types
+    TTypeArr_t<DrawAtt> fvTrackDrawAtts;                          ///< Drawing attributes for track types
+
+    // ************************************
+    // ** Drawing options and properties **
+    // ************************************
+
+    static constexpr int kCXSIZEPX = 600;  ///< Canvas size along x-axis [px]
+    static constexpr int kCYSIZEPX = 600;  ///< Canvas size along y-axis [px]
   };
 }  // namespace cbm::ca
 
 
+// **********************
+// **  Implementation  **
+// **********************
+
+template<class TObj>
+void cbm::ca::OutputQa::DrawSetOf(const std::vector<ETrackType>& vTypes, std::function<TObj*(ETrackType)> GetObj)
+{
+  CbmQaCmpDrawer<TObj> drawer;
+  for (auto type : vTypes) {
+    if (!fvbTrackTypeOn[type] || !fvpTrackHistograms[type]->IsMCUsed()) { continue; }
+    drawer.RegisterObject(GetObj(type), fvpTrackHistograms[type]->GetTitle());
+  }
+  if constexpr (std::is_same_v<TH1F, TObj>) { drawer.SetMinimum(1.e-1); }
+  drawer.Draw("");
+  drawer.Clear();
+}
+
+
 #endif  // CbmCaOutputQa_h
diff --git a/reco/L1/qa/CbmCaTrackFitQa.h b/reco/L1/qa/CbmCaTrackFitQa.h
index 4f2ce84f430f9d51264d80d1b84b6212a337570f..7211c325f86cfc579a7b7b22c7e37f507d3567cc 100644
--- a/reco/L1/qa/CbmCaTrackFitQa.h
+++ b/reco/L1/qa/CbmCaTrackFitQa.h
@@ -129,11 +129,11 @@ namespace cbm::ca
     double fUpRESVI = +2.;     ///< Upper boundary, residual of inverse speed [1/c]
 
     int fBinsPULLX   = 200;   ///< Number of bins, pull of x
-    double fLoPULLX  = -1.;   ///< Lower boundary, pull of x [cm]
-    double fUpPULLX  = +1.;   ///< Upper boundary, pull of x [cm]
+    double fLoPULLX  = -4.;   ///< Lower boundary, pull of x [cm]
+    double fUpPULLX  = +4.;   ///< Upper boundary, pull of x [cm]
     int fBinsPULLY   = 200;   ///< Number of bins, pull of y
-    double fLoPULLY  = -1.;   ///< Lower boundary, pull of y [cm]
-    double fUpPULLY  = +1.;   ///< Upper boundary, pull of y [cm]
+    double fLoPULLY  = -4.;   ///< Lower boundary, pull of y [cm]
+    double fUpPULLY  = +4.;   ///< Upper boundary, pull of y [cm]
     int fBinsPULLTX  = 200;   ///< Number of bins, pull of slope along x-axis
     double fLoPULLTX = -4.;   ///< Lower boundary, pull of slope along x-axis
     double fUpPULLTX = +4.;   ///< Upper boundary, pull of slope along x-axis
diff --git a/reco/L1/qa/CbmCaTrackTypeQa.cxx b/reco/L1/qa/CbmCaTrackTypeQa.cxx
index 77a329d086ea4634bb07e57baf92a1d53199f387..8e2514d3dc89bc5ba84f7104f7fdc5270c21179d 100644
--- a/reco/L1/qa/CbmCaTrackTypeQa.cxx
+++ b/reco/L1/qa/CbmCaTrackTypeQa.cxx
@@ -48,41 +48,47 @@ void TrackTypeQa::Init()
   fph_reco_tx    = MakeHisto<TH1F>("reco_tx", "", kBinsTX, kLoTX, kUpTX);
   fph_reco_ty    = MakeHisto<TH1F>("reco_ty", "", kBinsTY, kLoTY, kUpTY);
   fph_reco_fhitR = MakeHisto<TH1F>("reco_fhitR", "", kBinsFHITR, kLoFHITR, kUpFHITR);
-  fph_reco_nhits = MakeHisto<TH1F>("reco_nhits", "", kBinsNHITS, kLoNHITS, kUpNHITS);
   // TODO: ...
 
-  fph_reco_p->SetTitle("Total momentum of reconstructed track;p^{reco} [GeV/c]");
-  fph_reco_pt->SetTitle("Transverse momentum of reconstructed track;p_{T}^{reco} [GeV/c]");
-  fph_reco_phi->SetTitle("Azimuthal angle of reconstructed track;#phi^{reco} [rad]");
-  fph_reco_theta->SetTitle("Polar angle of reconstructed track;#theta^{reco} [rad]");
-  fph_reco_tx->SetTitle("Slope along x-axis of reconstructed tracks;t_{x}^{reco}");
-  fph_reco_ty->SetTitle("Slope along y-axis of reconstructed tracks;t_{y}^{reco}");
-  fph_reco_fhitR->SetTitle("Distance of the first hit from z-axis for reconstructed tracks");
-  fph_reco_nhits->SetTitle("Hit number of reconstructed tracks");
+  fph_reco_p->SetTitle("Total momentum of reconstructed track;p^{reco} [GeV/c];Counts");
+  fph_reco_pt->SetTitle("Transverse momentum of reconstructed track;p_{T}^{reco} [GeV/c];Counts");
+  fph_reco_phi->SetTitle("Azimuthal angle of reconstructed track;#phi^{reco} [rad];Counts");
+  fph_reco_eta->SetTitle("Pseudorapidity of reconstructed track;#eta^{reco};Counts");
+  fph_reco_theta->SetTitle("Polar angle of reconstructed track;#theta^{reco} [rad];Counts");
+  fph_reco_tx->SetTitle("Slope along x-axis of reconstructed tracks;t_{x}^{reco};Counts");
+  fph_reco_ty->SetTitle("Slope along y-axis of reconstructed tracks;t_{y}^{reco};Counts");
+  fph_reco_fhitR->SetTitle("Distance of the first hit from z-axis for reconstructed tracks;R^{reco} [cm];Counts");
 
   if (fbUseMC) {
     //
     // ** Distributions of reconstructed tracks vs. MC quantities **
     //
     fph_reco_pMC     = MakeHisto<TH1F>("reco_pMC", "", kBinsP, kLoP, kUpP);
+    fph_reco_etaMC   = MakeHisto<TH1F>("reco_etaMC", "", kBinsETA, kLoETA, kUpETA);
     fph_reco_yMC     = MakeHisto<TH1F>("reco_yMC", "", kBinsY, kLoY, kUpY);
     fph_reco_pMC_yMC = MakeHisto<TH2F>("reco_pMC_yMC", "", kBinsY, kLoY, kUpY, kBinsP, kLoP, kUpP);
     fph_reco_phiMC   = MakeHisto<TH1F>("reco_phiMC", "", kBinsPHI, kLoPHI, kUpPHI);
     fph_reco_thetaMC = MakeHisto<TH1F>("reco_thetaMC", "", kBinsTHETA, kLoTHETA, kUpTHETA);
+    fph_reco_nhits   = MakeHisto<TH1F>("reco_nhits", "", kBinsNHITS, kLoNHITS, kUpNHITS);
+
+    fph_reco_pMC->SetTitle("MC total momentum of reconstructed track;p^{MC} [GeV/c];Counts");
+    fph_reco_yMC->SetTitle("MC rapidity of reconstructed track;y^{MC};Counts");
+    fph_reco_etaMC->SetTitle("MC pseudorapidity of reconstructed track;#eta^{MC};Counts");
+    fph_reco_pMC_yMC->SetTitle("Transverse momentum of reconstructed track;y^{MC};p_{T}^{MC} [GeV/c];Counts");
+    fph_reco_phiMC->SetTitle("Azimuthal angle of reconstructed track;#phi^{MC} [rad];Counts");
+    fph_reco_thetaMC->SetTitle("Polar angle of reconstructed track;#theta^{MC} [rad];Counts");
+    fph_reco_nhits->SetTitle("Hit number of reconstructed tracks;N^{MC}_{hits};Counts");
 
-    fph_reco_pMC->SetTitle("MC total momentum of reconstructed track;p^{MC} [GeV/c]");
-    fph_reco_yMC->SetTitle("MC rapidity of reconstructed track;y^{MC}");
-    fph_reco_pMC_yMC->SetTitle("Transverse momentum of reconstructed track;y^{MC};p_{T}^{MC} [GeV/c]");
-    fph_reco_phiMC->SetTitle("Azimuthal angle of reconstructed track;#phi^{MC} [rad]");
-    fph_reco_thetaMC->SetTitle("Polar angle of reconstructed track;#theta^{MC} [rad]");
 
     fph_mc_pMC     = MakeHisto<TH1F>("mc_pMC", "", kBinsP, kLoP, kUpP);
+    fph_mc_etaMC   = MakeHisto<TH1F>("mc_etaMC", "", kBinsETA, kLoETA, kUpETA);
     fph_mc_yMC     = MakeHisto<TH1F>("mc_yMC", "", kBinsY, kLoY, kUpY);
     fph_mc_pMC_yMC = MakeHisto<TH2F>("mc_pMC_yMC", "", kBinsY, kLoY, kUpY, kBinsP, kLoP, kUpP);
 
-    fph_mc_pMC->SetTitle("MC total momentum of MC tracks;p^{MC} [GeV/c]");
-    fph_mc_yMC->SetTitle("MC rapidity of MC tracks;y^{MC}");
-    fph_mc_pMC_yMC->SetTitle("MC total momentum vs. MC rapidity of MC tracks;y^{MC};p^{MC} [GeV/c]");
+    fph_mc_pMC->SetTitle("MC total momentum of MC tracks;p^{MC} [GeV/c];Counts");
+    fph_mc_yMC->SetTitle("MC rapidity of MC tracks;y^{MC};Counts");
+    fph_mc_etaMC->SetTitle("MC pseudorapidity of MC track;#eta^{MC};Counts");
+    fph_mc_pMC_yMC->SetTitle("MC total momentum vs. MC rapidity of MC tracks;y^{MC};p^{MC} [GeV/c];Counts");
 
     //
     // ** Efficiencies **
@@ -119,6 +125,10 @@ void TrackTypeQa::Init()
 
     fpFitQaLastHit = std::make_unique<TrackFitQa>("lst_hit", fsPrefix, fpFolderRoot);
     fpFitQaLastHit->SetTitle("Last hit");
+    fpFitQaLastHit->fLoRESX = -0.4;
+    fpFitQaLastHit->fUpRESX = +0.4;
+    fpFitQaLastHit->fLoRESY = -0.8;
+    fpFitQaLastHit->fUpRESY = +0.8;
     fpFitQaLastHit->Init();
 
     fpFitQaVertex = std::make_unique<TrackFitQa>("vertex", fsPrefix, fpFolderRoot);
@@ -134,6 +144,7 @@ void TrackTypeQa::FillRecoTrack(int iTrkReco, double weight)
   const auto& recoTrack = (*fpvRecoTracks)[iTrkReco];
   fph_reco_p->Fill(recoTrack.GetP(), weight);
   fph_reco_pt->Fill(recoTrack.GetPt(), weight);
+  fph_reco_eta->Fill(recoTrack.GetEta(), weight);
   fph_reco_phi->Fill(recoTrack.GetPhi(), weight);
   fph_reco_theta->Fill(recoTrack.GetTheta(), weight);
   fph_reco_tx->Fill(recoTrack.GetTx(), weight);
@@ -144,6 +155,7 @@ void TrackTypeQa::FillRecoTrack(int iTrkReco, double weight)
       /// TODO: fill mass hypothesis into CbmL1Track
       const auto& mcTrack = fpMCData->GetTrack(iTrkMC);
       fph_reco_pMC->Fill(mcTrack.GetP(), weight);
+      fph_reco_etaMC->Fill(mcTrack.GetEta(), weight);
       fph_reco_yMC->Fill(mcTrack.GetRapidity(), weight);
       fph_reco_pMC_yMC->Fill(mcTrack.GetRapidity(), mcTrack.GetP(), weight);
 
@@ -219,6 +231,7 @@ void TrackTypeQa::FillMCTrack(int iTrkMC, double weight)
 
   // ** Distributions **
   fph_mc_pMC->Fill(mcTrack.GetP(), weight);
+  fph_mc_etaMC->Fill(mcTrack.GetEta(), weight);
   fph_mc_yMC->Fill(mcTrack.GetRapidity(), weight);
   fph_mc_pMC_yMC->Fill(mcTrack.GetRapidity(), mcTrack.GetP(), weight);
 
@@ -247,7 +260,8 @@ void TrackTypeQa::FillMCTracks()
     const auto& mcTrk = fpMCData->GetTrack(iTrkMC);
 
     // Cut tracks, which did not leave hits in tracker
-    if (mcTrk.GetNofHits() == 0) { continue; }
+    //if (mcTrk.GetNofHits() == 0) { continue; }
+    if (!mcTrk.IsReconstructable()) { continue; }
 
     // Cut tracks, which do not pass the applied cut
     if (!fMCTrackCut(mcTrk)) { continue; }
@@ -259,3 +273,27 @@ void TrackTypeQa::FillMCTracks()
     this->FillMCTrack(iTrkMC);
   }
 }
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void TrackTypeQa::SetDrawAtt(Color_t markerCol, Style_t markerSty, Color_t lineCol, Style_t lineSty)
+{
+  fMarkerColor = markerCol;
+  fMarkerStyle = markerSty;
+  fLineColor   = (lineCol > -1) ? lineCol : markerCol;
+  fLineStyle   = lineSty;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void TrackTypeQa::SetHistoProperties(TH1* pHist)
+{
+  pHist->SetStats(true);
+  pHist->Sumw2();
+  if (!pHist->InheritsFrom("TH2") && !pHist->InheritsFrom("TH3")) {
+    pHist->SetMarkerStyle(fMarkerStyle);
+    pHist->SetLineStyle(fLineStyle);
+  }
+  pHist->SetMarkerColor(fMarkerColor);
+  pHist->SetLineColor(fLineColor);
+}
diff --git a/reco/L1/qa/CbmCaTrackTypeQa.h b/reco/L1/qa/CbmCaTrackTypeQa.h
index 73d284fcd74c8d0def7c4fff747495589f5f175c..a933122d45019ee65952b31d38f54e9009551d8a 100644
--- a/reco/L1/qa/CbmCaTrackTypeQa.h
+++ b/reco/L1/qa/CbmCaTrackTypeQa.h
@@ -39,7 +39,7 @@ namespace cbm::ca
   ///
   /// The class provides set of histograms, counters, and efficiencies for monitoring tracks of a particular type
   /// (reco_fast_long, mc_pi, reco_ghost)
-  class TrackTypeQa : public CbmQaIO {
+  class TrackTypeQa : virtual public CbmQaIO {
   public:
     /// @brief Constructor
     /// @param typeName   Name of tracks type (used as a prefix for histogram)
@@ -65,7 +65,7 @@ namespace cbm::ca
     TrackTypeQa& operator=(TrackTypeQa&&) = delete;
 
     /// @brief Gets title of track group
-    const char* GetTitle() const { return fsTitle; }
+    const char* GetTitle() const { return fsTitle.Data(); }
 
     /// @brief Initializes histograms
     void Init();
@@ -111,6 +111,13 @@ namespace cbm::ca
     /// @param pParameters  A shared pointer to the parameters object
     void RegisterParameters(std::shared_ptr<L1Parameters>& pParameters) { fpParameters = pParameters; }
 
+    /// @brief Sets drawing attributes for histograms
+    /// @param markerCol  Marker color
+    /// @param markerSty  Marker style
+    /// @param lineCol    Line color (-1: the same color as marker)
+    /// @param lineSty    Line style
+    void SetDrawAtt(Color_t markerCol = 1, Style_t markerSty = 20, Color_t lineCol = -1, Style_t lineSty = 1);
+
     /// @brief Sets title, which is to be reflected on legends and titles
     /// @param title  Title of track type
     void SetTitle(const char* title) { fsTitle = title; }
@@ -195,6 +202,11 @@ namespace cbm::ca
     // TODO: Provide integrated efficiencies
 
   private:
+    /// @brief Overrided virtual function of the CbmQaIO class, defines properties of the histograms
+    /// @param pHist Pointer to a histogram, which properties are to be set
+    virtual void SetHistoProperties(TH1* pHist);
+
+
     bool fbUseMC    = false;  ///< Flag: true - MC information is used
     TString fsTitle = "";     ///< Title of the track category
 
@@ -217,9 +229,9 @@ namespace cbm::ca
     // **************************
 
     // ** Binning **
-    static constexpr int kBinsP      = 150;   ///< Number of bins, total momentum
+    static constexpr int kBinsP      = 100;   ///< Number of bins, total momentum
     static constexpr double kLoP     = 0.;    ///< Lower boundary, total momentum [GeV/c]
-    static constexpr double kUpP     = 15.;   ///< Upper boundary, total momentum [GeV/c]
+    static constexpr double kUpP     = 10.;   ///< Upper boundary, total momentum [GeV/c]
     static constexpr int kBinsPT     = 100;   ///< Number of bins, transverse momentum
     static constexpr double kLoPT    = 0.;    ///< Lower boundary, transverse momentum [GeV/c]
     static constexpr double kUpPT    = 10.;   ///< Upper boundary, transverse momentum [GeV/c]
@@ -247,6 +259,12 @@ namespace cbm::ca
     static constexpr int kBinsFHITR  = 50;    ///< Number of bins, transverse distance of the 1st hit from z-axis
     static constexpr double kLoFHITR = 0.;    ///< Lower boundary, transverse distance of the 1st hit from z-axis [cm]
     static constexpr double kUpFHITR = 150.;  ///< Upper boundary, transverse distance of the 1st hit from z-axis [cm]
+
+    // ** Drawing attributes **
+    Color_t fMarkerColor = 1;   ///< Marker color
+    Style_t fMarkerStyle = 20;  ///< Marker style
+    Color_t fLineColor   = 1;   ///< Line color
+    Style_t fLineStyle   = 1;   ///< Line style
   };
 }  // namespace cbm::ca