diff --git a/core/qa/CbmQaIO.cxx b/core/qa/CbmQaIO.cxx
index 00f9ce99cef13294e9c5d0a418c857d87e5dcff3..e5ba4c24cb4d6365fafc300c49f3bc71e72dc4fb 100644
--- a/core/qa/CbmQaIO.cxx
+++ b/core/qa/CbmQaIO.cxx
@@ -27,6 +27,17 @@ CbmQaIO::~CbmQaIO() {}
 //
 void CbmQaIO::SetHistoProperties(TH1* pHist) { pHist->SetStats(true); }
 
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void CbmQaIO::SetCanvasProperties(TCanvas* pCanv)
+{
+  constexpr double left   = 0.15;
+  constexpr double bottom = 0.15;
+  constexpr double right  = 0.10;
+  constexpr double top    = 0.10;
+  pCanv->SetMargin(left, right, bottom, top);
+}
+
 // ---------------------------------------------------------------------------------------------------------------------
 //
 void CbmQaIO::SetConfigName(const char* path)
@@ -53,7 +64,7 @@ void CbmQaIO::WriteToFile(TFile* pOutFile) const
 {
   LOG(info) << "CbmQaIO: Writing objects in file \033[1;31m" << pOutFile->GetName() << "\033[0m";
   pOutFile->cd();
-  for (const auto& [pObject, sPath] : (*fpvObjList)) {
+  for (auto& [pObject, sPath] : (*fpvObjList)) {
     if (!pOutFile->GetDirectory(sPath)) { pOutFile->mkdir(sPath); }
     pOutFile->cd(sPath);
     if (pObject) { pObject->Write(); }
diff --git a/core/qa/CbmQaIO.h b/core/qa/CbmQaIO.h
index a1003ea50f71579ac8e133f03bad09fa2f834535..d466756d39ff0704653c4192ee318d07a001f0de 100644
--- a/core/qa/CbmQaIO.h
+++ b/core/qa/CbmQaIO.h
@@ -70,71 +70,37 @@ public:
   /// @brief Move assignment operator
   CbmQaIO& operator=(CbmQaIO&&) = delete;
 
-  /// Set storing mode
-  void SetStoringMode(EStoringMode val) { fStoringMode = val; }
 
-  /// @brief Sets a common root path to the objects in the output file
-  /// @param path  A path to the object
-  void SetRootFolderName(TString path) { fsRootFolderName = path; }
-
-  /// @brief Creates a ROOT object
-  /// @param name    Name of the object including the path
-  /// @param args... Arguments passed to the object constructor
-  template<typename T, typename... Args>
-  T* MakeQaObject(TString name, Args... args);
   /// @brief Gets config name
   const char* GetConfigName() const { return fsConfigName.Data(); }
 
-  /// @brief Creates, initializes and registers a canvas
-  /// @tparam  T     Type of the canvas: TCanvas or CbmQaCanvas (\note T should not be a pointer)
-  /// @param   name  Name of canvas
-  /// @param   args  The rest of the arguments, which will be passed to the canvas constructor
-  template<typename T, typename... Args>
-  T* MakeCanvas(TString name, Args... args);
-
-  /// @brief Creates, initializes and registers an efficiency
-  /// @tparam  T     Type of the canvas: either TProfile, TProfile1D or TEfficiency (\note T should not be a pointer)
-  /// @param   name  Name of canvas
-  /// @param   args  The rest of the arguments, which will be passed to the efficiency constructor
-  template<typename T, typename... Args>
-  T* MakeEfficiency(TString name, Args... args);
-
-  /// @brief Creates, initializes and registers a histogram
-  /// @tparam  T     Type of the histogram (\note T should not be a pointer)
-  /// @param   name  Name of histogram
-  /// @param   args  The rest of the arguments, which will be passed to the histogram constructor
-  template<typename T, typename... Args>
-  T* MakeHisto(TString name, Args... args);
-
-  /// @brief Creates histogram, using properties defined with a tag in config
-  /// @param nameBase  Name of the histogram
-  /// @param args      The rest of the arguments, which will be passed to the histogram constructor
+  /// @brief Creates a QA (ROOT) object, using properties defined with a tag in config
+  /// @tparam T       Type of the object
+  /// @param sName    Name of the object
+  /// @param sTitle   Title of the object
+  /// @param args...  The rest of the arguments, which will be passed to the histogram constructor
   /// @note Tag is defined after the last ';' symbol in the nameBase string
   /// @example
-  ///    nambeBase = "/foo/bar/hit_xy_occupancy_station0;xy_station0" will be decayed into:
-  ///    1) subdirectory /foo/bar
-  ///    2) name of histogram "catrd_hit_xy_occupancy_station0"
+  ///    nambeBase = "/stations/station0/xy_occupancy;xy_station0" will be decayed into:
+  ///    1) subdirectory "stations/station0"
+  ///    2) name of histogram "catrd_hit_xy_occupancy"
   ///    3) tag for configuration file "xy_station0"
   /// If configuration file or tag are not defined, default parameters will be used
   template<typename T, typename... Args>
-  T* MakeHistoConfig(const char* nameBase, const char* title, Args... args);
-
-  /// @brief Creates, initializes and registers a table
-  /// @param  name  Name of the table
-  /// @param  args  The rest of the arguments, which will be passed to the table constructor
-  template<typename... Args>
-  CbmQaTable* MakeTable(TString name, Args... args);
+  T* MakeQaObject(TString sName, TString sTitle, Args... args);
 
   /// @brief Creates a ROOT object
-  /// @param name    Name of the object
-  /// @param args... Arguments passed to the object constructor
-  template<typename T, typename... Args>
-  T* MakeObject(const char* name, Args... args);
-
   /// @brief Sets config name
   /// @param name  A path to the config
   void SetConfigName(const char* path);
 
+  /// @brief Sets a common root path to the objects in the output file
+  /// @param path  A path to the object
+  void SetRootFolderName(const TString& path) { fsRootFolderName = path.Strip(TString::kBoth, '/'); }
+
+  /// @brief Set storing mode
+  void SetStoringMode(EStoringMode mode) { fStoringMode = mode; }
+
 protected:
   /// @brief Function to check, if a property is defined
   /// @param property  A property to be tested
@@ -143,9 +109,13 @@ protected:
   template<typename T>
   void CheckProperty(T&& property, const char* name) const;
 
-  /// @brief Applies properties on the histogram created with MakeHisto funciton
-  /// @param pHist  Pointer to histogram
-  virtual void SetHistoProperties(TH1* /*pHits*/);
+  /// @brief Applies properties on the histogram created with the MakeQaObject function
+  /// @param pHist  Pointer to the histogram
+  virtual void SetHistoProperties(TH1* pHist);
+
+  /// @brief Applies properties on the canvas created with the MakeQaObject funciton
+  /// @param pCanv  Pointer to the canvas
+  virtual void SetCanvasProperties(TCanvas* pCanv);
 
   /// @brief Writes objects into file
   /// @param pOutFile Pointer to output ROOT file
@@ -160,6 +130,13 @@ protected:
   std::shared_ptr<ObjList_t> fpvObjList = nullptr;                ///< List of registered ROOT objects
 
   YAML::Node fConfigNode {};  ///< Configuration node
+
+private:
+  /// @brief Creates and registers a ROOT object
+  /// @param name  A name of the ROOT object, which can contain a sub-directory
+  /// @param args  Other arguments, passed to the ROOT object constructor
+  template<typename T, typename... Args>
+  T* ConstructAndRegisterQaObject(TString name, Args... args);
 };
 
 
@@ -184,186 +161,153 @@ void CbmQaIO::CheckProperty(T&& property, const char* name) const
 // ---------------------------------------------------------------------------------------------------------------------
 //
 template<typename T, typename... Args>
-T* CbmQaIO::MakeQaObject(TString sObjName, Args... args)
+T* CbmQaIO::ConstructAndRegisterQaObject(TString sName, Args... args)
 {
-  // Resolve directory name and object name
-  auto iLastSlashPos = static_cast<int>(sObjName.Last('/'));
-  TString sDirName   = sObjName(0, iLastSlashPos);
-  sObjName           = sObjName(iLastSlashPos + 1, sObjName.Length() - iLastSlashPos);
-
-  // Add unique prefix to the object name
-  sObjName = fsPrefix + sObjName;
+  if constexpr (std::is_base_of_v<CbmQaTable, T>) { static_assert(sizeof...(Args) == 3); }
 
-  // Check, if an object with the same name already exists
-  // TODO: check if this makes sense and doesn't crash the memory
-  //if (gROOT->FindObject(sObjName)) {
-  //  LOG(warn) << fsRootFolderName << ": A previously created object \"" << sObjName << "\" will be deleted";
-  //  auto* pObj = static_cast<T*>(gROOT->FindObject(sObjName));
-  //  delete pObj;
-  //}
+  // Resolve directory name and object name
+  auto iLastSlashPos = static_cast<int>(sName.Last('/'));
+  TString sDirectory = TString(sName(0, iLastSlashPos)).Strip(TString::kBoth, '/');
+  sName              = sName(iLastSlashPos + 1, sName.Length() - iLastSlashPos);
 
   // Create a new object
-  T* pObj = new T(sObjName, args...);
-
-  // specific stuff for different kind of objects
+  T* pObj = new T(sName.Data(), args...);
 
-  TH1* pH1 = dynamic_cast<TH1*>(pObj);
-
-  if (pH1) {               // any kind of histogram
-    pH1->SetDirectory(0);  // don't let ROOT own the histogram. The user should take care on deleting it.
-    SetHistoProperties(pH1);
+  // Take object ownership from ROOT and apply user-defined properties
+  if constexpr (std::is_base_of_v<TH1, T>) {  // histograms
+    pObj->SetDirectory(0);
+    SetHistoProperties(pObj);
   }
-
-  TString sPrefix = "";
-  if (EStoringMode::kSUBDIR == fStoringMode) {
-    if (dynamic_cast<CbmQaTable*>(pObj) || dynamic_cast<CbmQaCanvas*>(pObj)) { sPrefix = "summary/"; }
+  else if constexpr (std::is_base_of_v<TCanvas, T>) {  // canvases
+    auto* pListOfCanvases = gROOT->GetListOfCanvases();
+    if (-1 != pListOfCanvases->IndexOf(pObj)) { pListOfCanvases->Remove(pObj); }
+    SetCanvasProperties(pObj);
   }
 
-  // Add parent directory to the folder
-  if (fsRootFolderName.Length() != 0) { sDirName = fsRootFolderName + "/" + sPrefix + sDirName; }
+  // Define a "summary" subdirectory of canvases and tables
+  if constexpr (std::is_base_of_v<CbmQaTable, T> || std::is_base_of_v<TCanvas, T>) {
+    if (EStoringMode::kSUBDIR == fStoringMode) { sDirectory = TString("summary/") + sDirectory; }
+  }
 
-  // Register the object into an object list
-  fpvObjList->push_back(std::make_pair(static_cast<TObject*>(pObj), sDirName));
-  return pObj;
-}
+  // Add parent directory
+  if (fsRootFolderName.Length() != 0) { sDirectory = fsRootFolderName + "/" + sDirectory; }
 
+  // Register the object in the list
+  fpvObjList->push_back(std::make_pair(static_cast<TObject*>(pObj), sDirectory));
 
-// ---------------------------------------------------------------------------------------------------------------------
-//
-template<typename T, typename... Args>
-T* CbmQaIO::MakeCanvas(TString nameBase, Args... args)
-{
-  return MakeQaObject<T>(nameBase, args...);
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
-template<typename T, typename... Args>
-T* CbmQaIO::MakeEfficiency(TString nameBase, Args... args)
-{
-  return MakeQaObject<T>(nameBase, args...);
+  return pObj;
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
 template<typename T, typename... Args>
-T* CbmQaIO::MakeHisto(TString nameBase, Args... args) 
+T* CbmQaIO::MakeQaObject(TString sName, TString sTitle, Args... args)
 {
-  return CbmQaIO::MakeQaObject<T>(nameBase, args...);
-}
-
+  if constexpr (std::is_base_of_v<CbmQaTable, T>) { static_assert(sizeof...(Args) == 2); }
 
-T* CbmQaIO::MakeHistoConfig(const char* nameBase, const char* title, Args... args)
-{
-  TString sObjName = nameBase;
-  auto iLastSepPos = static_cast<int>(sObjName.Last(';'));
-  TString sTagName = sObjName(iLastSepPos + 1, sObjName.Length() - iLastSepPos);
-  sObjName         = sObjName(0, iLastSepPos);
+  // Resolve configuration tag, if any
+  auto iLastSepPos = static_cast<int>(sName.Last(';'));
+  TString sTagName = sName(iLastSepPos + 1, sName.Length() - iLastSepPos);
+  if (iLastSepPos != -1) { sName = sName(0, iLastSepPos); }
 
   bool bUseConfig = false;
   // Check, if parameters are provided for this tag
   if (fConfigNode) {
-    if (fConfigNode["histograms"]) {
-      if (fConfigNode["histograms"][sTagName.Data()]) { bUseConfig = true; }
+    if constexpr (std::is_base_of_v<TH1, T>) {
+      if (fConfigNode["histograms"]) {
+        if (fConfigNode["histograms"][sTagName.Data()]) { bUseConfig = true; }
+      }
+    }
+    else if constexpr (std::is_base_of_v<TCanvas, T>) {
+      if (fConfigNode["canvases"]) {
+        if (fConfigNode["canvases"][sTagName.Data()]) { bUseConfig = true; }
+      }
     }
   }
 
+  const char* title = sTitle.Data();
   if (bUseConfig) {
-    const auto& tagNode = fConfigNode["histograms"][sTagName.Data()];
-
-    int nBinsX                   = -1;
-    double minX                  = std::numeric_limits<double>::signaling_NaN();
-    double maxX                  = std::numeric_limits<double>::signaling_NaN();
-    [[maybe_unused]] int nBinsY  = -1;
-    [[maybe_unused]] double minY = std::numeric_limits<double>::signaling_NaN();
-    [[maybe_unused]] double maxY = std::numeric_limits<double>::signaling_NaN();
-    [[maybe_unused]] int nBinsZ  = -1;
-    [[maybe_unused]] double minZ = std::numeric_limits<double>::signaling_NaN();
-    [[maybe_unused]] double maxZ = std::numeric_limits<double>::signaling_NaN();
-
-    if (tagNode["x"]) {
-      nBinsX = tagNode["x"]["nbins"].as<int>();
-      minX   = tagNode["x"]["min"].as<double>();
-      maxX   = tagNode["x"]["max"].as<double>();
-    }
-    if (tagNode["y"]) {
-      nBinsY = tagNode["y"]["nbins"].as<int>();
-      minY   = tagNode["y"]["min"].as<double>();
-      maxY   = tagNode["y"]["max"].as<double>();
-    }
-    if (tagNode["z"]) {
-      nBinsZ = tagNode["z"]["nbins"].as<int>();
-      minZ   = tagNode["z"]["min"].as<double>();
-      maxZ   = tagNode["z"]["max"].as<double>();
-    }
-
-    if constexpr (std::is_base_of_v<TProfile2D, T>) {
-      CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
-      CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
-      CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
-      CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
-      CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
-      CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
-      CheckProperty(minZ, Form("qa/histograms/%s/z/min", sTagName.Data()));
-      CheckProperty(maxZ, Form("qa/histograms/%s/z/max", sTagName.Data()));
-      return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, nBinsY, minY, maxY, minZ, maxZ);
-    }
-    else if constexpr (std::is_base_of_v<TProfile, T>) {
-      CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
-      CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
-      CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
-      CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
-      CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
-      return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, minY, maxY);
-    }
-    else if constexpr (std::is_base_of_v<TH3, T>) {
-      CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
-      CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
-      CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
-      CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
-      CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
-      CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
-      CheckProperty(nBinsZ, Form("qa/histograms/%s/z/nbins", sTagName.Data()));
-      CheckProperty(minZ, Form("qa/histograms/%s/z/min", sTagName.Data()));
-      CheckProperty(maxZ, Form("qa/histograms/%s/z/max", sTagName.Data()));
-      return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, nBinsY, minY, maxY, nBinsZ, minZ, maxZ);
-    }
-    else if constexpr (std::is_base_of_v<TH2, T>) {
-      CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
-      CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
-      CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
-      CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
-      CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
-      CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
-      return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, nBinsY, minY, maxY);
-    }
-    else if constexpr (std::is_base_of_v<TH1, T>) {
-      CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
-      CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
-      CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
-      return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX);
+    if constexpr (std::is_base_of_v<TH1, T>) {
+      const auto& tagNode = fConfigNode["histograms"][sTagName.Data()];
+
+      [[maybe_unused]] int nBinsX  = -1;
+      [[maybe_unused]] double minX = std::numeric_limits<double>::signaling_NaN();
+      [[maybe_unused]] double maxX = std::numeric_limits<double>::signaling_NaN();
+      [[maybe_unused]] int nBinsY  = -1;
+      [[maybe_unused]] double minY = std::numeric_limits<double>::signaling_NaN();
+      [[maybe_unused]] double maxY = std::numeric_limits<double>::signaling_NaN();
+      [[maybe_unused]] int nBinsZ  = -1;
+      [[maybe_unused]] double minZ = std::numeric_limits<double>::signaling_NaN();
+      [[maybe_unused]] double maxZ = std::numeric_limits<double>::signaling_NaN();
+
+      if (const auto& axisNode = tagNode["x"]) {
+        nBinsX = axisNode["nbins"].as<int>();
+        minX   = axisNode["min"].as<double>();
+        maxX   = axisNode["max"].as<double>();
+      }
+      if (const auto& axisNode = tagNode["y"]) {
+        nBinsY = axisNode["nbins"].as<int>();
+        minY   = axisNode["min"].as<double>();
+        maxY   = axisNode["max"].as<double>();
+      }
+      if (const auto& axisNode = tagNode["z"]) {
+        nBinsZ = axisNode["nbins"].as<int>();
+        minZ   = axisNode["min"].as<double>();
+        maxZ   = axisNode["max"].as<double>();
+      }
+
+      if constexpr (std::is_base_of_v<CbmQaTable, T>) { return ConstructAndRegisterQaObject<T>(sName, title, args...); }
+      else if constexpr (std::is_base_of_v<TProfile2D, T>) {
+        CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
+        CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
+        CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
+        CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
+        CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
+        CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
+        CheckProperty(minZ, Form("qa/histograms/%s/z/min", sTagName.Data()));
+        CheckProperty(maxZ, Form("qa/histograms/%s/z/max", sTagName.Data()));
+        return ConstructAndRegisterQaObject<T>(sName, title, nBinsX, minX, maxX, nBinsY, minY, maxY, minZ, maxZ);
+      }
+      else if constexpr (std::is_base_of_v<TProfile, T>) {
+        CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
+        CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
+        CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
+        CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
+        CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
+        return ConstructAndRegisterQaObject<T>(sName, title, nBinsX, minX, maxX, minY, maxY);
+      }
+      else if constexpr (std::is_base_of_v<TH3, T>) {
+        CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
+        CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
+        CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
+        CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
+        CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
+        CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
+        CheckProperty(nBinsZ, Form("qa/histograms/%s/z/nbins", sTagName.Data()));
+        CheckProperty(minZ, Form("qa/histograms/%s/z/min", sTagName.Data()));
+        CheckProperty(maxZ, Form("qa/histograms/%s/z/max", sTagName.Data()));
+        return ConstructAndRegisterQaObject<T>(sName, title, nBinsX, minX, maxX, nBinsY, minY, maxY, nBinsZ, minZ,
+                                               maxZ);
+      }
+      else if constexpr (std::is_base_of_v<TH2, T>) {
+        CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
+        CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
+        CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
+        CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
+        CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
+        CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
+        return ConstructAndRegisterQaObject<T>(sName, title, nBinsX, minX, maxX, nBinsY, minY, maxY);
+      }
+      else if constexpr (std::is_base_of_v<TH1, T>) {
+        CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
+        CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
+        CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
+        return ConstructAndRegisterQaObject<T>(sName, title, nBinsX, minX, maxX);
+      }
     }
   }
-  else {
-    return MakeHisto<T>(sObjName.Data(), title, args...);
-  }
-}
-
-// ---------------------------------------------------------------------------------------------------------------------
-//
-template<typename T, typename... Args>
-T* CbmQaIO::MakeObject(const char* name, Args... args)
-{
-  return MakeQaObject<T>(nameBase, args...);
-}
 
-// ---------------------------------------------------------------------------------------------------------------------
-//
-template<typename... Args>
-CbmQaTable* CbmQaIO::MakeTable(TString nameBase, Args... args)
-{
-  return MakeQaObject<CbmQaTable>(nameBase, args...);
+  return ConstructAndRegisterQaObject<T>(sName, title, args...);
 }
 
-
 #endif  // CbmQaIO_h
diff --git a/core/qa/CbmQaIO.h.orig b/core/qa/CbmQaIO.h.orig
new file mode 100644
index 0000000000000000000000000000000000000000..6bd4475159ade4a9293de3dbb1cd81ebb8559a66
--- /dev/null
+++ b/core/qa/CbmQaIO.h.orig
@@ -0,0 +1,380 @@
+/* Copyright (C) 2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// @file   CbmQaIO.h
+/// @brief  Module for ROOT objects IO interface (header)
+/// @author S.Zharko <s.zharko@gsi.de>
+/// @since   29.03.2023
+
+#ifndef CbmQaIO_h
+#define CbmQaIO_h 1
+
+#include "CbmQaCanvas.h"
+#include "CbmQaEff.h"
+#include "CbmQaTable.h"
+
+#include "Logger.h"
+
+#include "TCanvas.h"
+#include "TEfficiency.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "TH3.h"
+#include "TObject.h"
+#include "TParameter.h"
+#include "TProfile.h"
+#include "TProfile2D.h"
+#include "TProfile3D.h"
+#include "TROOT.h"
+#include "TString.h"
+
+#include <limits>
+#include <type_traits>
+#include <vector>
+
+<<<<<<< HEAD
+=======
+#include <yaml-cpp/yaml.h>
+>>>>>>> QA: Added posibility of configuring histogram binning in CbmQaTask; Clean-up of CbmCaInputQaTrd
+
+class TFile;
+
+/// @brief  ROOT object IO interface for QA
+///
+/// The class provides interface to write ROOT object into resulted files
+class CbmQaIO {
+public:
+  using ObjList_t = std::vector<std::pair<TObject*, TString>>;
+
+  enum class EStoringMode
+  {
+    kSAMEDIR,  ///< Objects of different type will be stored to root directory
+    kSUBDIR    ///< Objects of different type will be stored in different subdirectories like histograms/ canvases/
+  };
+
+  /// @brief Constructor
+  /// @param prefixName    Name of the unique prefix
+  /// @param pObjList      List of already created objects
+  CbmQaIO(TString prefixName, std::shared_ptr<ObjList_t> pObjList = nullptr);
+
+  /// @brief Destructor
+  virtual ~CbmQaIO();
+
+  /// @brief Copy constructor
+  CbmQaIO(const CbmQaIO&) = delete;
+
+  /// @brief Move constructor
+  CbmQaIO(CbmQaIO&&) = delete;
+
+  /// @brief Copy assignment operator
+  CbmQaIO& operator=(const CbmQaIO&) = delete;
+
+  /// @brief Move assignment operator
+  CbmQaIO& operator=(CbmQaIO&&) = delete;
+
+<<<<<<< HEAD
+  /// Set storing mode
+  void SetStoringMode(EStoringMode val) { fStoringMode = val; }
+
+  /// @brief Sets a common root path to the objects in the output file
+  /// @param path  A path to the object
+  void SetRootFolderName(TString path) { fsRootFolderName = path; }
+
+  /// @brief Creates a ROOT object
+  /// @param name    Name of the object including the path
+  /// @param args... Arguments passed to the object constructor
+  template<typename T, typename... Args>
+  T* MakeQaObject(TString name, Args... args);
+=======
+  /// @brief Gets config name
+  const char* GetConfigName() const { return fsConfigName.Data(); }
+>>>>>>> QA: Added posibility of configuring histogram binning in CbmQaTask; Clean-up of CbmCaInputQaTrd
+
+  /// @brief Creates, initializes and registers a canvas
+  /// @tparam  T     Type of the canvas: TCanvas or CbmQaCanvas (\note T should not be a pointer)
+  /// @param   name  Name of canvas
+  /// @param   args  The rest of the arguments, which will be passed to the canvas constructor
+  template<typename T, typename... Args>
+  T* MakeCanvas(TString name, Args... args);
+
+  /// @brief Creates, initializes and registers an efficiency
+  /// @tparam  T     Type of the canvas: either TProfile, TProfile1D or TEfficiency (\note T should not be a pointer)
+  /// @param   name  Name of canvas
+  /// @param   args  The rest of the arguments, which will be passed to the efficiency constructor
+  template<typename T, typename... Args>
+  T* MakeEfficiency(TString name, Args... args);
+
+  /// @brief Creates, initializes and registers a histogram
+  /// @tparam  T     Type of the histogram (\note T should not be a pointer)
+  /// @param   name  Name of histogram
+  /// @param   args  The rest of the arguments, which will be passed to the histogram constructor
+  template<typename T, typename... Args>
+  T* MakeHisto(TString name, Args... args);
+
+  /// @brief Creates histogram, using properties defined with a tag in config
+  /// @param nameBase  Name of the histogram
+  /// @param args      The rest of the arguments, which will be passed to the histogram constructor
+  /// @note Tag is defined after the last ';' symbol in the nameBase string
+  /// @example
+  ///    nambeBase = "/foo/bar/hit_xy_occupancy_station0;xy_station0" will be decayed into:
+  ///    1) subdirectory /foo/bar
+  ///    2) name of histogram "catrd_hit_xy_occupancy_station0"
+  ///    3) tag for configuration file "xy_station0"
+  /// If configuration file or tag are not defined, default parameters will be used
+  template<typename T, typename... Args>
+  T* MakeHistoConfig(const char* nameBase, const char* title, Args... args);
+
+  /// @brief Creates, initializes and registers a table
+  /// @param  name  Name of the table
+  /// @param  args  The rest of the arguments, which will be passed to the table constructor
+  template<typename... Args>
+  CbmQaTable* MakeTable(TString name, Args... args);
+
+<<<<<<< HEAD
+=======
+  /// @brief Creates a ROOT object
+  /// @param name    Name of the object
+  /// @param args... Arguments passed to the object constructor
+  template<typename T, typename... Args>
+  T* MakeObject(const char* name, Args... args);
+
+  /// @brief Sets config name
+  /// @param name  A path to the config
+  void SetConfigName(const char* path);
+
+  /// @brief Sets a common root path to the objects in the output file
+  /// @param path  A path to the object
+  void SetRootFolderName(const char* path) { fsRootFolderName = path; }
+>>>>>>> QA: Added posibility of configuring histogram binning in CbmQaTask; Clean-up of CbmCaInputQaTrd
+
+protected:
+  /// @brief Function to check, if a property is defined
+  /// @param property  A property to be tested
+  /// @param name      A name of property (used for logging)
+  /// @note  Throws an exception, if property is undefined
+  template<typename T>
+  void CheckProperty(T&& property, const char* name) const;
+
+  /// @brief Applies properties on the histogram created with MakeHisto funciton
+  /// @param pHist  Pointer to histogram
+  virtual void SetHistoProperties(TH1* /*pHits*/);
+
+  /// @brief Writes objects into file
+  /// @param pOutFile Pointer to output ROOT file
+  void WriteToFile(TFile* pOutFile) const;
+
+
+  TString fsRootFolderName = "";  ///< Name of root folder
+  TString fsConfigName     = "";  ///< Name of configuration file
+  TString fsPrefix         = "";  ///< Unique prefix for all writeable root
+
+  EStoringMode fStoringMode             = EStoringMode::kSUBDIR;  ///< Objects storing mode
+  std::shared_ptr<ObjList_t> fpvObjList = nullptr;                ///< List of registered ROOT objects
+
+  YAML::Node fConfigNode {};  ///< Configuration node
+};
+
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<typename T>
+void CbmQaIO::CheckProperty(T&& property, const char* name) const
+{
+  bool bPropertyUndefined = false;
+  if constexpr (std::is_signed_v<T>) { bPropertyUndefined = property < 0; }
+  else if constexpr (std::is_floating_point_v<T>) {
+    bPropertyUndefined = std::isnan(property);
+  }
+
+  if (bPropertyUndefined) {
+    std::stringstream msg;
+    msg << "Property " << name << " is undefined in the configuration file";
+    throw std::runtime_error(msg.str());
+  }
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<typename T, typename... Args>
+T* CbmQaIO::MakeQaObject(TString sObjName, Args... args)
+{
+  // Resolve directory name and object name
+  auto iLastSlashPos = static_cast<int>(sObjName.Last('/'));
+  TString sDirName   = sObjName(0, iLastSlashPos);
+  sObjName           = sObjName(iLastSlashPos + 1, sObjName.Length() - iLastSlashPos);
+
+  // Add unique prefix to the object name
+  sObjName = fsPrefix + sObjName;
+
+  // Check, if an object with the same name already exists
+  // TODO: check if this makes sense and doesn't crash the memory
+  //if (gROOT->FindObject(sObjName)) {
+  //  LOG(warn) << fsRootFolderName << ": A previously created object \"" << sObjName << "\" will be deleted";
+  //  auto* pObj = static_cast<T*>(gROOT->FindObject(sObjName));
+  //  delete pObj;
+  //}
+
+  // Create a new object
+  T* pObj = new T(sObjName, args...);
+
+  // specific stuff for different kind of objects
+
+  TH1* pH1 = dynamic_cast<TH1*>(pObj);
+
+  if (pH1) {               // any kind of histogram
+    pH1->SetDirectory(0);  // don't let ROOT own the histogram. The user should take care on deleting it.
+    SetHistoProperties(pH1);
+  }
+
+  TString sPrefix = "";
+  if (EStoringMode::kSUBDIR == fStoringMode) {
+    if (dynamic_cast<CbmQaTable*>(pObj) || dynamic_cast<CbmQaCanvas*>(pObj)) { sPrefix = "summary/"; }
+  }
+
+  // Add parent directory to the folder
+  if (fsRootFolderName.Length() != 0) { sDirName = fsRootFolderName + "/" + sPrefix + sDirName; }
+
+  // Register the object into an object list
+  fpvObjList->push_back(std::make_pair(static_cast<TObject*>(pObj), sDirName));
+  return pObj;
+}
+
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<typename T, typename... Args>
+T* CbmQaIO::MakeCanvas(TString nameBase, Args... args)
+{
+  return MakeQaObject<T>(nameBase, args...);
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<typename T, typename... Args>
+T* CbmQaIO::MakeEfficiency(TString nameBase, Args... args)
+{
+  return MakeQaObject<T>(nameBase, args...);
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<typename T, typename... Args>
+<<<<<<< HEAD
+T* CbmQaIO::MakeHisto(TString nameBase, Args... args)
+=======
+T* CbmQaIO::MakeHistoConfig(const char* nameBase, const char* title, Args... args)
+{
+  TString sObjName = nameBase;
+  auto iLastSepPos = static_cast<int>(sObjName.Last(';'));
+  TString sTagName = sObjName(iLastSepPos + 1, sObjName.Length() - iLastSepPos);
+  sObjName         = sObjName(0, iLastSepPos);
+
+  bool bUseConfig = false;
+  // Check, if parameters are provided for this tag
+  if (fConfigNode) {
+    if (fConfigNode["histograms"]) {
+      if (fConfigNode["histograms"][sTagName.Data()]) { bUseConfig = true; }
+    }
+  }
+
+  if (bUseConfig) {
+    const auto& tagNode = fConfigNode["histograms"][sTagName.Data()];
+
+    int nBinsX                   = -1;
+    double minX                  = std::numeric_limits<double>::signaling_NaN();
+    double maxX                  = std::numeric_limits<double>::signaling_NaN();
+    [[maybe_unused]] int nBinsY  = -1;
+    [[maybe_unused]] double minY = std::numeric_limits<double>::signaling_NaN();
+    [[maybe_unused]] double maxY = std::numeric_limits<double>::signaling_NaN();
+    [[maybe_unused]] int nBinsZ  = -1;
+    [[maybe_unused]] double minZ = std::numeric_limits<double>::signaling_NaN();
+    [[maybe_unused]] double maxZ = std::numeric_limits<double>::signaling_NaN();
+
+    if (tagNode["x"]) {
+      nBinsX = tagNode["x"]["nbins"].as<int>();
+      minX   = tagNode["x"]["min"].as<double>();
+      maxX   = tagNode["x"]["max"].as<double>();
+    }
+    if (tagNode["y"]) {
+      nBinsY = tagNode["y"]["nbins"].as<int>();
+      minY   = tagNode["y"]["min"].as<double>();
+      maxY   = tagNode["y"]["max"].as<double>();
+    }
+    if (tagNode["z"]) {
+      nBinsZ = tagNode["z"]["nbins"].as<int>();
+      minZ   = tagNode["z"]["min"].as<double>();
+      maxZ   = tagNode["z"]["max"].as<double>();
+    }
+
+    if constexpr (std::is_base_of_v<TProfile2D, T>) {
+      CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
+      CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
+      CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
+      CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
+      CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
+      CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
+      CheckProperty(minZ, Form("qa/histograms/%s/z/min", sTagName.Data()));
+      CheckProperty(maxZ, Form("qa/histograms/%s/z/max", sTagName.Data()));
+      return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, nBinsY, minY, maxY, minZ, maxZ);
+    }
+    else if constexpr (std::is_base_of_v<TProfile, T>) {
+      CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
+      CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
+      CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
+      CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
+      CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
+      return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, minY, maxY);
+    }
+    else if constexpr (std::is_base_of_v<TH3, T>) {
+      CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
+      CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
+      CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
+      CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
+      CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
+      CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
+      CheckProperty(nBinsZ, Form("qa/histograms/%s/z/nbins", sTagName.Data()));
+      CheckProperty(minZ, Form("qa/histograms/%s/z/min", sTagName.Data()));
+      CheckProperty(maxZ, Form("qa/histograms/%s/z/max", sTagName.Data()));
+      return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, nBinsY, minY, maxY, nBinsZ, minZ, maxZ);
+    }
+    else if constexpr (std::is_base_of_v<TH2, T>) {
+      CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
+      CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
+      CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
+      CheckProperty(nBinsY, Form("qa/histograms/%s/y/nbins", sTagName.Data()));
+      CheckProperty(minY, Form("qa/histograms/%s/y/min", sTagName.Data()));
+      CheckProperty(maxY, Form("qa/histograms/%s/y/max", sTagName.Data()));
+      return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX, nBinsY, minY, maxY);
+    }
+    else if constexpr (std::is_base_of_v<TH1, T>) {
+      CheckProperty(nBinsX, Form("qa/histograms/%s/x/nbins", sTagName.Data()));
+      CheckProperty(minX, Form("qa/histograms/%s/x/min", sTagName.Data()));
+      CheckProperty(maxX, Form("qa/histograms/%s/x/max", sTagName.Data()));
+      return MakeHisto<T>(sObjName.Data(), title, nBinsX, minX, maxX);
+    }
+  }
+  else {
+    return MakeHisto<T>(sObjName.Data(), title, args...);
+  }
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<typename T, typename... Args>
+T* CbmQaIO::MakeObject(const char* name, Args... args)
+>>>>>>> QA: Added posibility of configuring histogram binning in CbmQaTask; Clean-up of CbmCaInputQaTrd
+{
+  return MakeQaObject<T>(nameBase, args...);
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+template<typename... Args>
+CbmQaTable* CbmQaIO::MakeTable(TString nameBase, Args... args)
+{
+  return MakeQaObject<CbmQaTable>(nameBase, args...);
+}
+
+
+#endif  // CbmQaIO_h
diff --git a/core/qa/CbmQaTask.cxx b/core/qa/CbmQaTask.cxx
index f2b3ffbd4f2e115d7b9e95e62144f2731ea664e1..4d086e35440085335831bae8dc38970fb7f22b2f 100644
--- a/core/qa/CbmQaTask.cxx
+++ b/core/qa/CbmQaTask.cxx
@@ -27,7 +27,7 @@ ClassImp(CbmQaTask);
 //
 CbmQaTask::CbmQaTask(const char* name, const char* prefix, int verbose, bool isMCUsed)
   : FairTask(name, verbose)
-  , CbmQaIO(prefix)
+  , CbmQaIO(name)
   , fbUseMC(isMCUsed)
 {
   CbmQaIO::SetRootFolderName(name);
diff --git a/macro/qa/configs/CMakeLists.txt b/macro/qa/configs/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..bb215f639a320e6f4bf06492fc0f30d35660f4ab
--- /dev/null
+++ b/macro/qa/configs/CMakeLists.txt
@@ -0,0 +1,4 @@
+Install(FILES objects.yaml
+              qa_tasks_config_mcbm.yaml
+              DESTINATION share/cbmroot/macro/qa/configs
+       )
diff --git a/macro/qa/configs/objects.yaml b/macro/qa/configs/objects.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fe4d1e6aa700dcea692a74f56a5449503e5ad6fb
--- /dev/null
+++ b/macro/qa/configs/objects.yaml
@@ -0,0 +1,16 @@
+##################################################
+#                                                #
+#  File-object map for the QA-Checker framework  #
+#                                                #
+##################################################
+
+
+checker:
+  files:
+    - name: "%v/%d_qa.qa.root"
+      label: qa
+      objects:
+        - CbmCaInputQaSts/efficiencies/casts_reco_eff_vs_r_st0
+        - CbmCaInputQaSts/efficiencies/casts_reco_eff_vs_xy_st0
+        - CbmCaInputQaSts/histograms/casts_pull_t_st2
+        - CbmCaInputQaSts/histograms/casts_res_x_vs_x_st2        
diff --git a/reco/L1/qa/CbmCaInputQaMuch.cxx b/reco/L1/qa/CbmCaInputQaMuch.cxx
index 7e2a1d651ec4a1b69943b49dd0cfd6fecc787a2b..50bbac4394d41d07b7f47099eb8e0d905f539d2b 100644
--- a/reco/L1/qa/CbmCaInputQaMuch.cxx
+++ b/reco/L1/qa/CbmCaInputQaMuch.cxx
@@ -126,7 +126,7 @@ bool CbmCaInputQaMuch::Check()
     LOG(info) << "-- Hit efficiency integrated over hit distance from station center";
     LOG(info) << "\tintegration range: [" << fEffRange[0] << ", " << fEffRange[1] << "] cm";
 
-    auto* pEffTable = MakeTable("eff_table", "Efficiency table", nSt, 2);
+    auto* pEffTable = MakeQaObject<CbmQaTable>("eff_table", "Efficiency table", nSt, 2);
     pEffTable->SetNamesOfCols({"Station ID", "Efficiency"});
     pEffTable->SetColWidth(20);
 
@@ -159,7 +159,8 @@ bool CbmCaInputQaMuch::Check()
       return result;
     };
 
-    auto* pResidualsTable = MakeTable("residuals_mean", "Residual mean values in different stations", nSt, 4);
+    auto* pResidualsTable =
+      MakeQaObject<CbmQaTable>("residuals_mean", "Residual mean values in different stations", nSt, 4);
     pResidualsTable->SetNamesOfCols({"Station ID", "Residual(x) [cm]", "Residual(y) [cm]", "Residual(t) [ns]"});
     pResidualsTable->SetColWidth(20);
 
@@ -202,7 +203,7 @@ bool CbmCaInputQaMuch::Check()
       return fit.GetParameter(2);
     };
 
-    auto* pPullsTable = MakeTable("pulls_rms", "Pulls std. dev. values in different stations", nSt, 4);
+    auto* pPullsTable = MakeQaObject<CbmQaTable>("pulls_rms", "Pulls std. dev. values in different stations", nSt, 4);
     pPullsTable->SetNamesOfCols({"Station ID", "Pull(x) sigm", "Pull(y) sigm", "Pull(z) sigm"});
     pPullsTable->SetColWidth(20);
 
@@ -581,7 +582,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
   // ** Hit occupancies
 
   // ** Occupancy in XY plane
-  auto* pc_hit_ypos_vs_xpos = MakeCanvas<CbmQaCanvas>("hit_ypos_vs_xpos", "", 1600, 800);
+  auto* pc_hit_ypos_vs_xpos = MakeQaObject<CbmQaCanvas>("hit_ypos_vs_xpos", "", 1600, 800);
   pc_hit_ypos_vs_xpos->Divide2D(nSt);
   for (int iSt = 0; iSt < nSt; ++iSt) {
     pc_hit_ypos_vs_xpos->cd(iSt + 1);
@@ -618,7 +619,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
   }
 
   // ----- Occupancy projections
-  auto* pc_hit_xpos = MakeCanvas<CbmQaCanvas>("hit_xpos", "", 1400, 800);
+  auto* pc_hit_xpos = MakeQaObject<CbmQaCanvas>("hit_xpos", "", 1400, 800);
   pc_hit_xpos->Divide2D(nSt);
   for (int iSt = 0; iSt < nSt; ++iSt) {
     pc_hit_xpos->cd(iSt + 1);
@@ -626,7 +627,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
     phProj->DrawCopy();
   }
 
-  auto* pc_hit_ypos = MakeCanvas<CbmQaCanvas>("hit_ypos", "", 1400, 800);
+  auto* pc_hit_ypos = MakeQaObject<CbmQaCanvas>("hit_ypos", "", 1400, 800);
   pc_hit_ypos->Divide2D(nSt);
   for (int iSt = 0; iSt < nSt; ++iSt) {
     pc_hit_ypos->cd(iSt + 1);
@@ -636,7 +637,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
 
 
   // ** Occupancy in XZ plane
-  MakeCanvas<CbmQaCanvas>("hit_xpos_vs_zpos", "", 600, 400);
+  MakeQaObject<CbmQaCanvas>("hit_xpos_vs_zpos", "", 600, 400);
   fvph_hit_xpos_vs_zpos[nSt]->DrawCopy("colz", "");
   for (int iSt = 0; iSt < nSt; ++iSt) {
     // Station positions in detector IFS
@@ -654,7 +655,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
   }
 
   // ** Occupancy in YZ plane
-  MakeCanvas<CbmQaCanvas>("hit_ypos_vs_zpos", "", 600, 400);
+  MakeQaObject<CbmQaCanvas>("hit_ypos_vs_zpos", "", 600, 400);
   fvph_hit_ypos_vs_zpos[nSt]->DrawCopy("colz", "");
   for (int iSt = 0; iSt < nSt; ++iSt) {
     // Station positions in detector IFS
@@ -680,7 +681,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
     // ** Point occupancies
 
     // ** Occupancy in XY plane
-    auto* pc_point_ypos_vs_xpos = MakeCanvas<CbmQaCanvas>("point_ypos_vs_xpos", "", 1600, 800);
+    auto* pc_point_ypos_vs_xpos = MakeQaObject<CbmQaCanvas>("point_ypos_vs_xpos", "", 1600, 800);
     pc_point_ypos_vs_xpos->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_point_ypos_vs_xpos->cd(iSt + 1);
@@ -716,7 +717,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
     }
 
     // ** Occupancy in XZ plane
-    MakeCanvas<CbmQaCanvas>("point_xpos_vs_zpos", "", 600, 400);
+    MakeQaObject<CbmQaCanvas>("point_xpos_vs_zpos", "", 600, 400);
     fvph_point_xpos_vs_zpos[nSt]->SetStats(false);
     fvph_point_xpos_vs_zpos[nSt]->DrawCopy("colz", "");
     for (int iSt = 0; iSt < nSt; ++iSt) {
@@ -735,7 +736,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
     }
 
     // ** Occupancy in YZ plane
-    MakeCanvas<CbmQaCanvas>("point_ypos_vs_zpos", "", 600, 400);
+    MakeQaObject<CbmQaCanvas>("point_ypos_vs_zpos", "", 600, 400);
     fvph_point_ypos_vs_zpos[nSt]->SetStats(false);
     fvph_point_ypos_vs_zpos[nSt]->DrawCopy("colz", "");
     for (int iSt = 0; iSt < nSt; ++iSt) {
@@ -757,7 +758,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
     // ** Residuals
 
     // x-coordinate
-    auto* pc_res_x = MakeCanvas<CbmQaCanvas>("res_x", "Residuals for x coordinate", 1600, 800);
+    auto* pc_res_x = MakeQaObject<CbmQaCanvas>("res_x", "Residuals for x coordinate", 1600, 800);
     pc_res_x->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_res_x->cd(iSt + 1);
@@ -765,7 +766,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
     }
 
     // y-coordinate
-    auto* pc_res_y = MakeCanvas<CbmQaCanvas>("res_y", "Residuals for y coordinate", 1600, 800);
+    auto* pc_res_y = MakeQaObject<CbmQaCanvas>("res_y", "Residuals for y coordinate", 1600, 800);
     pc_res_y->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_res_y->cd(iSt + 1);
@@ -773,7 +774,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
     }
 
     // time
-    auto* pc_res_t = MakeCanvas<CbmQaCanvas>("res_t", "Residuals for time", 1600, 800);
+    auto* pc_res_t = MakeQaObject<CbmQaCanvas>("res_t", "Residuals for time", 1600, 800);
     pc_res_t->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_res_t->cd(iSt + 1);
@@ -785,7 +786,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
     // ** Pulls
 
     // x-coordinate
-    auto* pc_pull_x = MakeCanvas<CbmQaCanvas>("pull_x", "Pulls for x coordinate", 1600, 800);
+    auto* pc_pull_x = MakeQaObject<CbmQaCanvas>("pull_x", "Pulls for x coordinate", 1600, 800);
     pc_pull_x->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_pull_x->cd(iSt + 1);
@@ -793,7 +794,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
     }
 
     // y-coordinate
-    auto* pc_pull_y = MakeCanvas<CbmQaCanvas>("pull_y", "Pulls for y coordinate", 1600, 800);
+    auto* pc_pull_y = MakeQaObject<CbmQaCanvas>("pull_y", "Pulls for y coordinate", 1600, 800);
     pc_pull_y->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_pull_y->cd(iSt + 1);
@@ -801,7 +802,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
     }
 
     // time
-    auto* pc_pull_t = MakeCanvas<CbmQaCanvas>("pull_t", "Pulls for time", 1600, 800);
+    auto* pc_pull_t = MakeQaObject<CbmQaCanvas>("pull_t", "Pulls for time", 1600, 800);
     pc_pull_t->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_pull_t->cd(iSt + 1);
@@ -813,7 +814,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
     // ** Hit reconstruction efficiencies
 
     auto* pc_reco_eff_vs_r =
-      MakeCanvas<CbmQaCanvas>("reco_eff_vs_r", "Hit efficiencies wrt distance from center", 1600, 800);
+      MakeQaObject<CbmQaCanvas>("reco_eff_vs_r", "Hit efficiencies wrt distance from center", 1600, 800);
     pc_reco_eff_vs_r->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_reco_eff_vs_r->cd(iSt + 1);
@@ -821,7 +822,7 @@ InitStatus CbmCaInputQaMuch::InitCanvases()
       fvpe_reco_eff_vs_r[iSt]->DrawCopy("AP", "");
     }
 
-    auto* pc_reco_eff_vs_xy = MakeCanvas<CbmQaCanvas>("reco_eff_vs_xy", "Hit efficiencies wrt x and y", 1600, 800);
+    auto* pc_reco_eff_vs_xy = MakeQaObject<CbmQaCanvas>("reco_eff_vs_xy", "Hit efficiencies wrt x and y", 1600, 800);
     pc_reco_eff_vs_xy->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_reco_eff_vs_xy->cd(iSt + 1);
@@ -858,34 +859,36 @@ InitStatus CbmCaInputQaMuch::InitHistograms()
     // Hit occupancy
     sN                         = (TString) "hit_ypos_vs_xpos" + nsuff;
     sT                         = (TString) "Hit occupancy in xy-Plane" + tsuff + ";x_{hit} [cm];y_{hit} [cm]";
-    fvph_hit_ypos_vs_xpos[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, kRHitX[0], kRHitX[1], kNbins, kRHitY[0], kRHitY[1]);
+    fvph_hit_ypos_vs_xpos[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, kRHitX[0], kRHitX[1], kNbins, kRHitY[0], kRHitY[1]);
 
     sN                         = (TString) "hit_xpos_vs_zpos" + nsuff;
     sT                         = (TString) "Hit occupancy in xz-Plane" + tsuff + ";z_{hit} [cm];x_{hit} [cm]";
-    fvph_hit_xpos_vs_zpos[iSt] = MakeHisto<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitX[0], kRHitX[1]);
+    fvph_hit_xpos_vs_zpos[iSt] =
+      MakeQaObject<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitX[0], kRHitX[1]);
 
     sN                         = (TString) "hit_ypos_vs_zpos" + nsuff;
     sT                         = (TString) "Hit occupancy in yz-plane" + tsuff + ";z_{hit} [cm];y_{hit} [cm]";
-    fvph_hit_ypos_vs_zpos[iSt] = MakeHisto<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitY[0], kRHitY[1]);
+    fvph_hit_ypos_vs_zpos[iSt] =
+      MakeQaObject<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitY[0], kRHitY[1]);
 
     // Hit errors
     sN               = (TString) "hit_dx" + nsuff;
     sT               = (TString) "Hit position error along x-axis" + tsuff + ";dx_{hit} [cm]";
-    fvph_hit_dx[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRHitDx[0], kRHitDx[1]);
+    fvph_hit_dx[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRHitDx[0], kRHitDx[1]);
 
     sN               = (TString) "hit_dy" + nsuff;
     sT               = (TString) "Hit position error along y-axis" + tsuff + ";dy_{hit} [cm]";
-    fvph_hit_dy[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRHitDy[0], kRHitDy[1]);
+    fvph_hit_dy[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRHitDy[0], kRHitDy[1]);
 
     sN               = (TString) "hit_dt" + nsuff;
     sT               = (TString) "Hit time error" + tsuff + ";dt_{hit} [ns]";
-    fvph_hit_dt[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRHitDt[0], kRHitDt[1]);
+    fvph_hit_dt[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRHitDt[0], kRHitDt[1]);
 
     if (iSt == nSt) { continue; }  // Following histograms are defined only for separate station
 
     sN = (TString) "hit_station_delta_z" + nsuff;
     sT = (TString) "Different between hit and station z-positions" + tsuff + ";z_{hit} - z_{st} [cm]";
-    fvph_hit_station_delta_z[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, -5., 5);
+    fvph_hit_station_delta_z[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, -5., 5);
 
   }  // loop over station index: end
 
@@ -920,85 +923,85 @@ InitStatus CbmCaInputQaMuch::InitHistograms()
 
       sN                         = (TString) "n_points_per_hit" + nsuff;
       sT                         = (TString) "Number of points per hit" + tsuff + ";N_{point}/hit";
-      fvph_n_points_per_hit[iSt] = MakeHisto<TH1F>(sN, sT, 10, -0.5, 9.5);
+      fvph_n_points_per_hit[iSt] = MakeQaObject<TH1F>(sN, sT, 10, -0.5, 9.5);
 
       // Point occupancy
       sN = (TString) "point_ypos_vs_xpos" + nsuff;
       sT = (TString) "Point occupancy in XY plane" + tsuff + ";x_{MC} [cm];y_{MC} [cm]";
       fvph_point_ypos_vs_xpos[iSt] =
-        MakeHisto<TH2F>(sN, sT, kNbins, kRHitX[0], kRHitX[1], kNbins, kRHitY[0], kRHitY[1]);
+        MakeQaObject<TH2F>(sN, sT, kNbins, kRHitX[0], kRHitX[1], kNbins, kRHitY[0], kRHitY[1]);
 
       sN = (TString) "point_xpos_vs_zpos" + nsuff;
       sT = (TString) "Point Occupancy in XZ plane" + tsuff + ";z_{MC} [cm];x_{MC} [cm]";
       fvph_point_xpos_vs_zpos[iSt] =
-        MakeHisto<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitX[0], kRHitX[1]);
+        MakeQaObject<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitX[0], kRHitX[1]);
 
       sN = (TString) "point_ypos_vs_zpos" + nsuff;
       sT = (TString) "Point Occupancy in YZ Plane" + tsuff + ";z_{MC} [cm];y_{MC} [cm]";
       fvph_point_ypos_vs_zpos[iSt] =
-        MakeHisto<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitY[0], kRHitY[1]);
+        MakeQaObject<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitY[0], kRHitY[1]);
 
       // Difference between MC input z and hit z coordinates
       sN = (TString) "point_hit_delta_z" + nsuff;
       sT = (TString) "Distance between point and hit along z axis" + tsuff + ";z_{reco} - z_{MC} [cm]";
-      fvph_point_hit_delta_z[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, -0.04, 0.04);
+      fvph_point_hit_delta_z[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, -0.04, 0.04);
 
       sN              = (TString) "res_x" + nsuff;
       sT              = (TString) "Residuals for x-coordinate" + tsuff + ";x_{reco} - x_{MC} [cm]";
-      fvph_res_x[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRResX[0], kRResX[1]);
+      fvph_res_x[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRResX[0], kRResX[1]);
 
       sN              = (TString) "res_y" + nsuff;
       sT              = (TString) "Residuals for y-coordinate" + tsuff + ";y_{reco} - y_{MC} [cm]";
-      fvph_res_y[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRResY[0], kRResY[1]);
+      fvph_res_y[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRResY[0], kRResY[1]);
 
       sN              = (TString) "res_t" + nsuff;
       sT              = (TString) "Residuals for time" + tsuff + ";t_{reco} - t_{MC} [ns]";
-      fvph_res_t[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRResT[0], kRResT[1]);
+      fvph_res_t[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRResT[0], kRResT[1]);
 
       sN               = (TString) "pull_x" + nsuff;
       sT               = (TString) "Pulls for x-coordinate" + tsuff + ";(x_{reco} - x_{MC}) / #sigma_{x}^{reco}";
-      fvph_pull_x[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRPullX[0], kRPullX[1]);
+      fvph_pull_x[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRPullX[0], kRPullX[1]);
 
       sN               = (TString) "pull_y" + nsuff;
       sT               = (TString) "Pulls for y-coordinate" + tsuff + ";(y_{reco} - y_{MC}) / #sigma_{y}^{reco}";
-      fvph_pull_y[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRPullY[0], kRPullY[1]);
+      fvph_pull_y[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRPullY[0], kRPullY[1]);
 
       sN               = (TString) "pull_t" + nsuff;
       sT               = (TString) "Pulls for time" + tsuff + ";(t_{reco} - t_{MC}) / #sigma_{t}^{reco}";
-      fvph_pull_t[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRPullT[0], kRPullT[1]);
+      fvph_pull_t[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRPullT[0], kRPullT[1]);
 
       sN                   = (TString) "res_x_vs_x" + nsuff;
       sT                   = (TString) "Residuals for x-coordinate" + tsuff + ";x_{reco} [cm];x_{reco} - x_{MC} [cm]";
-      fvph_res_x_vs_x[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResX[0], kRResX[1]);
+      fvph_res_x_vs_x[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResX[0], kRResX[1]);
 
       sN                   = (TString) "res_y_vs_y" + nsuff;
       sT                   = (TString) "Residuals for y-coordinate" + tsuff + ";y_{reco} [cm];y_{reco} - y_{MC} [cm]";
-      fvph_res_y_vs_y[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResY[0], kRResY[1]);
+      fvph_res_y_vs_y[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResY[0], kRResY[1]);
 
       sN                   = (TString) "res_t_vs_t" + nsuff;
       sT                   = (TString) "Residuals for time" + tsuff + "t_{reco} [ns];t_{reco} - t_{MC} [ns]";
-      fvph_res_t_vs_t[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResT[0], kRResT[1]);
+      fvph_res_t_vs_t[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResT[0], kRResT[1]);
 
       sN = (TString) "pull_x_vs_x" + nsuff;
       sT = (TString) "Pulls for x-coordinate" + tsuff + "x_{reco} [cm];(x_{reco} - x_{MC}) / #sigma_{x}^{reco}";
-      fvph_pull_x_vs_x[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullX[0], kRPullX[1]);
+      fvph_pull_x_vs_x[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullX[0], kRPullX[1]);
 
       sN = (TString) "pull_y_vs_y" + nsuff;
       sT = (TString) "Pulls for y-coordinate" + tsuff + ";y_{reco} [cm];(y_{reco} - y_{MC}) / #sigma_{y}^{reco}";
-      fvph_pull_y_vs_y[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullY[0], kRPullY[1]);
+      fvph_pull_y_vs_y[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullY[0], kRPullY[1]);
 
       sN = (TString) "pull_t_vs_t" + nsuff;
       sT = (TString) "Pulls for time" + tsuff + ";t_{reco} [ns];(t_{reco} - t_{MC}) / #sigma_{t}^{reco}";
-      fvph_pull_t_vs_t[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullT[0], kRPullT[1]);
+      fvph_pull_t_vs_t[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullT[0], kRPullT[1]);
 
 
       sN                       = (TString) "reco_eff_vs_xy" + nsuff;
       sT                       = (TString) "Hit rec. efficiency" + tsuff + ";x_{MC} [cm];y_{MC} [cm];#epsilon";
-      fvpe_reco_eff_vs_xy[iSt] = MakeEfficiency<CbmQaEff>(sN, sT, 100, -50, 50, 100, -50, 50);
+      fvpe_reco_eff_vs_xy[iSt] = MakeQaObject<CbmQaEff>(sN, sT, 100, -50, 50, 100, -50, 50);
 
       sN                      = (TString) "reco_eff_vs_r" + nsuff;
       sT                      = (TString) "Hit rec. efficiency" + tsuff + ";r_{MC} [cm];#epsilon";
-      fvpe_reco_eff_vs_r[iSt] = MakeEfficiency<CbmQaEff>(sN, sT, 100, 0, 100);
+      fvpe_reco_eff_vs_r[iSt] = MakeQaObject<CbmQaEff>(sN, sT, 100, 0, 100);
     }
   }
   return kSUCCESS;
diff --git a/reco/L1/qa/CbmCaInputQaSts.cxx b/reco/L1/qa/CbmCaInputQaSts.cxx
index 67268bbb26ec175d7a6007b5da19dfd24fc8272a..e0aa7dfea7df6332a89360ca509a24463d8909eb 100644
--- a/reco/L1/qa/CbmCaInputQaSts.cxx
+++ b/reco/L1/qa/CbmCaInputQaSts.cxx
@@ -15,7 +15,6 @@
 #include "CbmMCTrack.h"
 #include "CbmMatch.h"
 #include "CbmQaCanvas.h"
-#include "CbmQaEff.h"
 #include "CbmQaTable.h"
 #include "CbmQaUtil.h"
 #include "CbmStsCluster.h"
@@ -36,6 +35,8 @@
 #include "TH1F.h"
 #include "TH2F.h"
 #include "TMath.h"
+#include "TProfile.h"
+#include "TProfile2D.h"
 #include "TStyle.h"
 
 #include <algorithm>
@@ -137,7 +138,7 @@ bool CbmCaInputQaSts::Check()
     pEffTable->SetColWidth(20);
 
     for (int iSt = 0; iSt < nSt; ++iSt) {
-      auto [eff, effEL, effEU] = fvpe_reco_eff_vs_r[iSt]->GetTotalEfficiency();
+      auto eff = fvpe_reco_eff_vs_r[iSt]->GetMean(2);
       pEffTable->SetCell(iSt, 0, iSt);
       pEffTable->SetCell(iSt, 1, eff);
       res = CheckRange("Hit finder efficiency in station " + std::to_string(iSt), eff, fEffThrsh, 1.000);
@@ -545,11 +546,11 @@ void CbmCaInputQaSts::FillHistograms()
         // Conditions under which point is accounted as reconstructed: point
         bool ifPointHasHits = (vNofHitsPerPoint[iE][iP] > 0);
 
-        fvpe_reco_eff_vs_xy[iSt]->Fill(ifPointHasHits, xMC, yMC);
-        fvpe_reco_eff_vs_xy[nSt]->Fill(ifPointHasHits, xMC, yMC);
+        fvpe_reco_eff_vs_xy[iSt]->Fill(xMC, yMC, ifPointHasHits);
+        fvpe_reco_eff_vs_xy[nSt]->Fill(xMC, yMC, ifPointHasHits);
 
-        fvpe_reco_eff_vs_r[iSt]->Fill(ifPointHasHits, rMC);
-        fvpe_reco_eff_vs_r[nSt]->Fill(ifPointHasHits, rMC);
+        fvpe_reco_eff_vs_r[iSt]->Fill(rMC, ifPointHasHits);
+        fvpe_reco_eff_vs_r[nSt]->Fill(rMC, ifPointHasHits);
 
       }  // loop over MC-points: end
     }    // loop over MC-events: end
@@ -1144,11 +1145,11 @@ InitStatus CbmCaInputQaSts::InitHistograms()
 
       sN                       = (TString) "reco_eff_vs_xy" + nsuff;
       sT                       = (TString) "Hit rec. efficiency" + tsuff + ";x_{MC} [cm];y_{MC} [cm];#epsilon";
-      fvpe_reco_eff_vs_xy[iSt] = MakeQaObject<CbmQaEff>(sN, sT, 100, -50, 50, 100, -50, 50);
+      fvpe_reco_eff_vs_xy[iSt] = MakeQaObject<TProfile2D>(sN, sT, 100, -50, 50, 100, -50, 50);
 
       sN                      = (TString) "reco_eff_vs_r" + nsuff;
       sT                      = (TString) "Hit rec. efficiency" + tsuff + ";r_{MC} [cm];#epsilon";
-      fvpe_reco_eff_vs_r[iSt] = MakeQaObject<CbmQaEff>(sN, sT, 100, 0, 100);
+      fvpe_reco_eff_vs_r[iSt] = MakeQaObject<TProfile>(sN, sT, 100, 0, 100);
     }  // stations
 
     for (int idig = 0; idig <= fkMaxDigisInClusterForPulls; idig++) {
diff --git a/reco/L1/qa/CbmCaInputQaSts.h b/reco/L1/qa/CbmCaInputQaSts.h
index d8c670aa3570d6065ff3b544a914cc25b06d1477..7d5fb730d64f08257848010b728d249f10d9dd37 100644
--- a/reco/L1/qa/CbmCaInputQaSts.h
+++ b/reco/L1/qa/CbmCaInputQaSts.h
@@ -31,7 +31,8 @@ class CbmStsTrackingInterface;
 class TClonesArray;
 class TH1F;
 class TH2F;
-class CbmQaEff;
+class TProfile;
+class TProfile2D;
 
 /// A QA-task class, which provides assurance of MuCh hits and geometry
 class CbmCaInputQaSts : public CbmQaTask, public CbmCaInputQaBase {
@@ -168,8 +169,8 @@ private:
   std::vector<TH2F*> fvph_pull_t_vs_t;  ///< pull for t coordinate in different stations
 
   // Hit efficiencies
-  std::vector<CbmQaEff*> fvpe_reco_eff_vs_xy;  ///< Efficiency of hit reconstruction vs. x and y coordinates of MC
-  std::vector<CbmQaEff*> fvpe_reco_eff_vs_r;   ///< Efficiency of hit reconstruction vs. distance from center
+  std::vector<TProfile2D*> fvpe_reco_eff_vs_xy;  ///< Efficiency of hit reconstruction vs. x and y coordinates of MC
+  std::vector<TProfile*> fvpe_reco_eff_vs_r;     ///< Efficiency of hit reconstruction vs. distance from center
 };
 
 #endif  // CbmCaInputQaSts_h
diff --git a/reco/L1/qa/CbmCaInputQaTof.cxx b/reco/L1/qa/CbmCaInputQaTof.cxx
index e8903f8e8b8a33cdebc9492cb016cbca01c97e6d..ca329d6a13a6c5cab3488ed84057b5a5bd9326e5 100644
--- a/reco/L1/qa/CbmCaInputQaTof.cxx
+++ b/reco/L1/qa/CbmCaInputQaTof.cxx
@@ -129,7 +129,7 @@ bool CbmCaInputQaTof::Check()
     LOG(info) << "-- Hit efficiency integrated over hit distance from station center";
     LOG(info) << "\tintegration range: [" << fEffRange[0] << ", " << fEffRange[1] << "] cm";
 
-    auto* pEffTable = MakeTable("eff_table", "Efficiency table", nSt, 2);
+    auto* pEffTable = MakeQaObject<CbmQaTable>("eff_table", "Efficiency table", nSt, 2);
     pEffTable->SetNamesOfCols({"Station ID", "Efficiency"});
     pEffTable->SetColWidth(20);
 
@@ -162,7 +162,8 @@ bool CbmCaInputQaTof::Check()
       return result;
     };
 
-    auto* pResidualsTable = MakeTable("residuals_mean", "Residual mean values in different stations", nSt, 4);
+    auto* pResidualsTable =
+      MakeQaObject<CbmQaTable>("residuals_mean", "Residual mean values in different stations", nSt, 4);
     pResidualsTable->SetNamesOfCols({"Station ID", "Residual(x) [cm]", "Residual(y) [cm]", "Residual(t) [ns]"});
     pResidualsTable->SetColWidth(20);
 
@@ -205,7 +206,7 @@ bool CbmCaInputQaTof::Check()
       return fit.GetParameter(2);
     };
 
-    auto* pPullsTable = MakeTable("pulls_rms", "Pulls std. dev. values in different stations", nSt, 4);
+    auto* pPullsTable = MakeQaObject<CbmQaTable>("pulls_rms", "Pulls std. dev. values in different stations", nSt, 4);
     pPullsTable->SetNamesOfCols({"Station ID", "Pull(x) sigm", "Pull(y) sigm", "Pull(z) sigm"});
     pPullsTable->SetColWidth(20);
 
@@ -671,7 +672,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
   // ** Hit occupancies
 
   // ** Occupancy in XY plane
-  auto* pc_hit_ypos_vs_xpos = MakeCanvas<CbmQaCanvas>("hit_ypos_vs_xpos", "", 1600, 800);
+  auto* pc_hit_ypos_vs_xpos = MakeQaObject<CbmQaCanvas>("hit_ypos_vs_xpos", "", 1600, 800);
   pc_hit_ypos_vs_xpos->Divide2D(nSt);
   for (int iSt = 0; iSt < nSt; ++iSt) {
     pc_hit_ypos_vs_xpos->cd(iSt + 1);
@@ -708,7 +709,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
   }
 
   // ----- Occupancy projections
-  auto* pc_hit_xpos = MakeCanvas<CbmQaCanvas>("hit_xpos", "", 1400, 800);
+  auto* pc_hit_xpos = MakeQaObject<CbmQaCanvas>("hit_xpos", "", 1400, 800);
   pc_hit_xpos->Divide2D(nSt);
   for (int iSt = 0; iSt < nSt; ++iSt) {
     pc_hit_xpos->cd(iSt + 1);
@@ -716,7 +717,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
     phProj->DrawCopy();
   }
 
-  auto* pc_hit_ypos = MakeCanvas<CbmQaCanvas>("hit_ypos", "", 1400, 800);
+  auto* pc_hit_ypos = MakeQaObject<CbmQaCanvas>("hit_ypos", "", 1400, 800);
   pc_hit_ypos->Divide2D(nSt);
   for (int iSt = 0; iSt < nSt; ++iSt) {
     pc_hit_ypos->cd(iSt + 1);
@@ -726,7 +727,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
 
 
   // ** Occupancy in XZ plane
-  MakeCanvas<CbmQaCanvas>("hit_xpos_vs_zpos", "", 600, 400);
+  MakeQaObject<CbmQaCanvas>("hit_xpos_vs_zpos", "", 600, 400);
   fvph_hit_xpos_vs_zpos[nSt]->DrawCopy("colz", "");
   for (int iSt = 0; iSt < nSt; ++iSt) {
     // Station positions in detector IFS
@@ -744,7 +745,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
   }
 
   // ** Occupancy in YZ plane
-  MakeCanvas<CbmQaCanvas>("hit_ypos_vs_zpos", "", 600, 400);
+  MakeQaObject<CbmQaCanvas>("hit_ypos_vs_zpos", "", 600, 400);
   fvph_hit_ypos_vs_zpos[nSt]->DrawCopy("colz", "");
   for (int iSt = 0; iSt < nSt; ++iSt) {
     // Station positions in detector IFS
@@ -770,7 +771,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
     // ** Point occupancies
 
     // ** Occupancy in XY plane
-    auto* pc_point_ypos_vs_xpos = MakeCanvas<CbmQaCanvas>("point_ypos_vs_xpos", "", 1600, 800);
+    auto* pc_point_ypos_vs_xpos = MakeQaObject<CbmQaCanvas>("point_ypos_vs_xpos", "", 1600, 800);
     pc_point_ypos_vs_xpos->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_point_ypos_vs_xpos->cd(iSt + 1);
@@ -806,7 +807,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
     }
 
     // ** Occupancy in XZ plane
-    MakeCanvas<CbmQaCanvas>("point_xpos_vs_zpos", "", 600, 400);
+    MakeQaObject<CbmQaCanvas>("point_xpos_vs_zpos", "", 600, 400);
     fvph_point_xpos_vs_zpos[nSt]->SetStats(false);
     fvph_point_xpos_vs_zpos[nSt]->DrawCopy("colz", "");
     for (int iSt = 0; iSt < nSt; ++iSt) {
@@ -825,7 +826,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
     }
 
     // ** Occupancy in YZ plane
-    MakeCanvas<CbmQaCanvas>("point_ypos_vs_zpos", "", 600, 400);
+    MakeQaObject<CbmQaCanvas>("point_ypos_vs_zpos", "", 600, 400);
     fvph_point_ypos_vs_zpos[nSt]->SetStats(false);
     fvph_point_ypos_vs_zpos[nSt]->DrawCopy("colz", "");
     for (int iSt = 0; iSt < nSt; ++iSt) {
@@ -847,7 +848,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
     // ** Residuals
 
     // x-coordinate
-    auto* pc_res_x = MakeCanvas<CbmQaCanvas>("res_x", "Residuals for x coordinate", 1600, 800);
+    auto* pc_res_x = MakeQaObject<CbmQaCanvas>("res_x", "Residuals for x coordinate", 1600, 800);
     pc_res_x->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_res_x->cd(iSt + 1);
@@ -855,7 +856,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
     }
 
     // y-coordinate
-    auto* pc_res_y = MakeCanvas<CbmQaCanvas>("res_y", "Residuals for y coordinate", 1600, 800);
+    auto* pc_res_y = MakeQaObject<CbmQaCanvas>("res_y", "Residuals for y coordinate", 1600, 800);
     pc_res_y->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_res_y->cd(iSt + 1);
@@ -863,7 +864,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
     }
 
     // time
-    auto* pc_res_t = MakeCanvas<CbmQaCanvas>("res_t", "Residuals for time", 1600, 800);
+    auto* pc_res_t = MakeQaObject<CbmQaCanvas>("res_t", "Residuals for time", 1600, 800);
     pc_res_t->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_res_t->cd(iSt + 1);
@@ -875,7 +876,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
     // ** Pulls
 
     // x-coordinate
-    auto* pc_pull_x = MakeCanvas<CbmQaCanvas>("pull_x", "Pulls for x coordinate", 1600, 800);
+    auto* pc_pull_x = MakeQaObject<CbmQaCanvas>("pull_x", "Pulls for x coordinate", 1600, 800);
     pc_pull_x->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_pull_x->cd(iSt + 1);
@@ -883,7 +884,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
     }
 
     // y-coordinate
-    auto* pc_pull_y = MakeCanvas<CbmQaCanvas>("pull_y", "Pulls for y coordinate", 1600, 800);
+    auto* pc_pull_y = MakeQaObject<CbmQaCanvas>("pull_y", "Pulls for y coordinate", 1600, 800);
     pc_pull_y->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_pull_y->cd(iSt + 1);
@@ -891,7 +892,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
     }
 
     // time
-    auto* pc_pull_t = MakeCanvas<CbmQaCanvas>("pull_t", "Pulls for time", 1600, 800);
+    auto* pc_pull_t = MakeQaObject<CbmQaCanvas>("pull_t", "Pulls for time", 1600, 800);
     pc_pull_t->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_pull_t->cd(iSt + 1);
@@ -903,7 +904,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
     // ** Hit reconstruction efficiencies
 
     auto* pc_reco_eff_vs_r =
-      MakeCanvas<CbmQaCanvas>("reco_eff_vs_r", "Hit efficiencies wrt distance from center", 1600, 800);
+      MakeQaObject<CbmQaCanvas>("reco_eff_vs_r", "Hit efficiencies wrt distance from center", 1600, 800);
     pc_reco_eff_vs_r->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_reco_eff_vs_r->cd(iSt + 1);
@@ -911,7 +912,7 @@ InitStatus CbmCaInputQaTof::InitCanvases()
       fvpe_reco_eff_vs_r[iSt]->DrawCopy("AP", "");
     }
 
-    auto* pc_reco_eff_vs_xy = MakeCanvas<CbmQaCanvas>("reco_eff_vs_xy", "Hit efficiencies wrt x and y", 1600, 800);
+    auto* pc_reco_eff_vs_xy = MakeQaObject<CbmQaCanvas>("reco_eff_vs_xy", "Hit efficiencies wrt x and y", 1600, 800);
     pc_reco_eff_vs_xy->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_reco_eff_vs_xy->cd(iSt + 1);
@@ -948,34 +949,36 @@ InitStatus CbmCaInputQaTof::InitHistograms()
     // Hit occupancy
     sN                         = (TString) "hit_ypos_vs_xpos" + nsuff;
     sT                         = (TString) "Hit occupancy in xy-Plane" + tsuff + ";x_{hit} [cm];y_{hit} [cm]";
-    fvph_hit_ypos_vs_xpos[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, kRHitX[0], kRHitX[1], kNbins, kRHitY[0], kRHitY[1]);
+    fvph_hit_ypos_vs_xpos[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, kRHitX[0], kRHitX[1], kNbins, kRHitY[0], kRHitY[1]);
 
     sN                         = (TString) "hit_xpos_vs_zpos" + nsuff;
     sT                         = (TString) "Hit occupancy in xz-Plane" + tsuff + ";z_{hit} [cm];x_{hit} [cm]";
-    fvph_hit_xpos_vs_zpos[iSt] = MakeHisto<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitX[0], kRHitX[1]);
+    fvph_hit_xpos_vs_zpos[iSt] =
+      MakeQaObject<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitX[0], kRHitX[1]);
 
     sN                         = (TString) "hit_ypos_vs_zpos" + nsuff;
     sT                         = (TString) "Hit occupancy in yz-plane" + tsuff + ";z_{hit} [cm];y_{hit} [cm]";
-    fvph_hit_ypos_vs_zpos[iSt] = MakeHisto<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitY[0], kRHitY[1]);
+    fvph_hit_ypos_vs_zpos[iSt] =
+      MakeQaObject<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitY[0], kRHitY[1]);
 
     // Hit errors
     sN               = (TString) "hit_dx" + nsuff;
     sT               = (TString) "Hit position error along x-axis" + tsuff + ";dx_{hit} [cm]";
-    fvph_hit_dx[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRHitDx[0], kRHitDx[1]);
+    fvph_hit_dx[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRHitDx[0], kRHitDx[1]);
 
     sN               = (TString) "hit_dy" + nsuff;
     sT               = (TString) "Hit position error along y-axis" + tsuff + ";dy_{hit} [cm]";
-    fvph_hit_dy[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRHitDy[0], kRHitDy[1]);
+    fvph_hit_dy[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRHitDy[0], kRHitDy[1]);
 
     sN               = (TString) "hit_dt" + nsuff;
     sT               = (TString) "Hit time error" + tsuff + ";dt_{hit} [ns]";
-    fvph_hit_dt[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRHitDt[0], kRHitDt[1]);
+    fvph_hit_dt[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRHitDt[0], kRHitDt[1]);
 
     if (iSt == nSt) { continue; }  // Following histograms are defined only for separate station
 
     sN = (TString) "hit_station_delta_z" + nsuff;
     sT = (TString) "Different between hit and station z-positions" + tsuff + ";z_{hit} - z_{st} [cm]";
-    fvph_hit_station_delta_z[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, -5., 5);
+    fvph_hit_station_delta_z[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, -5., 5);
 
   }  // loop over station index: end
 
@@ -1010,85 +1013,85 @@ InitStatus CbmCaInputQaTof::InitHistograms()
 
       sN                         = (TString) "n_points_per_hit" + nsuff;
       sT                         = (TString) "Number of points per hit" + tsuff + ";N_{point}/hit";
-      fvph_n_points_per_hit[iSt] = MakeHisto<TH1F>(sN, sT, 10, -0.5, 9.5);
+      fvph_n_points_per_hit[iSt] = MakeQaObject<TH1F>(sN, sT, 10, -0.5, 9.5);
 
       // Point occupancy
       sN = (TString) "point_ypos_vs_xpos" + nsuff;
       sT = (TString) "Point occupancy in XY plane" + tsuff + ";x_{MC} [cm];y_{MC} [cm]";
       fvph_point_ypos_vs_xpos[iSt] =
-        MakeHisto<TH2F>(sN, sT, kNbins, kRHitX[0], kRHitX[1], kNbins, kRHitY[0], kRHitY[1]);
+        MakeQaObject<TH2F>(sN, sT, kNbins, kRHitX[0], kRHitX[1], kNbins, kRHitY[0], kRHitY[1]);
 
       sN = (TString) "point_xpos_vs_zpos" + nsuff;
       sT = (TString) "Point Occupancy in XZ plane" + tsuff + ";z_{MC} [cm];x_{MC} [cm]";
       fvph_point_xpos_vs_zpos[iSt] =
-        MakeHisto<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitX[0], kRHitX[1]);
+        MakeQaObject<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitX[0], kRHitX[1]);
 
       sN = (TString) "point_ypos_vs_zpos" + nsuff;
       sT = (TString) "Point Occupancy in YZ Plane" + tsuff + ";z_{MC} [cm];y_{MC} [cm]";
       fvph_point_ypos_vs_zpos[iSt] =
-        MakeHisto<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitY[0], kRHitY[1]);
+        MakeQaObject<TH2F>(sN, sT, kNbinsZ, kRHitZ[0], kRHitZ[1], kNbins, kRHitY[0], kRHitY[1]);
 
       // Difference between MC input z and hit z coordinates
       sN = (TString) "point_hit_delta_z" + nsuff;
       sT = (TString) "Distance between point and hit along z axis" + tsuff + ";z_{reco} - z_{MC} [cm]";
-      fvph_point_hit_delta_z[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, -0.04, 0.04);
+      fvph_point_hit_delta_z[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, -0.04, 0.04);
 
       sN              = (TString) "res_x" + nsuff;
       sT              = (TString) "Residuals for x-coordinate" + tsuff + ";x_{reco} - x_{MC} [cm]";
-      fvph_res_x[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRResX[0], kRResX[1]);
+      fvph_res_x[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRResX[0], kRResX[1]);
 
       sN              = (TString) "res_y" + nsuff;
       sT              = (TString) "Residuals for y-coordinate" + tsuff + ";y_{reco} - y_{MC} [cm]";
-      fvph_res_y[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRResY[0], kRResY[1]);
+      fvph_res_y[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRResY[0], kRResY[1]);
 
       sN              = (TString) "res_t" + nsuff;
       sT              = (TString) "Residuals for time" + tsuff + ";t_{reco} - t_{MC} [ns]";
-      fvph_res_t[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRResT[0], kRResT[1]);
+      fvph_res_t[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRResT[0], kRResT[1]);
 
       sN               = (TString) "pull_x" + nsuff;
       sT               = (TString) "Pulls for x-coordinate" + tsuff + ";(x_{reco} - x_{MC}) / #sigma_{x}^{reco}";
-      fvph_pull_x[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRPullX[0], kRPullX[1]);
+      fvph_pull_x[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRPullX[0], kRPullX[1]);
 
       sN               = (TString) "pull_y" + nsuff;
       sT               = (TString) "Pulls for y-coordinate" + tsuff + ";(y_{reco} - y_{MC}) / #sigma_{y}^{reco}";
-      fvph_pull_y[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRPullY[0], kRPullY[1]);
+      fvph_pull_y[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRPullY[0], kRPullY[1]);
 
       sN               = (TString) "pull_t" + nsuff;
       sT               = (TString) "Pulls for time" + tsuff + ";(t_{reco} - t_{MC}) / #sigma_{t}^{reco}";
-      fvph_pull_t[iSt] = MakeHisto<TH1F>(sN, sT, kNbins, kRPullT[0], kRPullT[1]);
+      fvph_pull_t[iSt] = MakeQaObject<TH1F>(sN, sT, kNbins, kRPullT[0], kRPullT[1]);
 
       sN                   = (TString) "res_x_vs_x" + nsuff;
       sT                   = (TString) "Residuals for x-coordinate" + tsuff + ";x_{reco} [cm];x_{reco} - x_{MC} [cm]";
-      fvph_res_x_vs_x[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResX[0], kRResX[1]);
+      fvph_res_x_vs_x[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResX[0], kRResX[1]);
 
       sN                   = (TString) "res_y_vs_y" + nsuff;
       sT                   = (TString) "Residuals for y-coordinate" + tsuff + ";y_{reco} [cm];y_{reco} - y_{MC} [cm]";
-      fvph_res_y_vs_y[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResY[0], kRResY[1]);
+      fvph_res_y_vs_y[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResY[0], kRResY[1]);
 
       sN                   = (TString) "res_t_vs_t" + nsuff;
       sT                   = (TString) "Residuals for time" + tsuff + "t_{reco} [ns];t_{reco} - t_{MC} [ns]";
-      fvph_res_t_vs_t[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResT[0], kRResT[1]);
+      fvph_res_t_vs_t[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRResT[0], kRResT[1]);
 
       sN = (TString) "pull_x_vs_x" + nsuff;
       sT = (TString) "Pulls for x-coordinate" + tsuff + "x_{reco} [cm];(x_{reco} - x_{MC}) / #sigma_{x}^{reco}";
-      fvph_pull_x_vs_x[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullX[0], kRPullX[1]);
+      fvph_pull_x_vs_x[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullX[0], kRPullX[1]);
 
       sN = (TString) "pull_y_vs_y" + nsuff;
       sT = (TString) "Pulls for y-coordinate" + tsuff + ";y_{reco} [cm];(y_{reco} - y_{MC}) / #sigma_{y}^{reco}";
-      fvph_pull_y_vs_y[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullY[0], kRPullY[1]);
+      fvph_pull_y_vs_y[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullY[0], kRPullY[1]);
 
       sN = (TString) "pull_t_vs_t" + nsuff;
       sT = (TString) "Pulls for time" + tsuff + ";t_{reco} [ns];(t_{reco} - t_{MC}) / #sigma_{t}^{reco}";
-      fvph_pull_t_vs_t[iSt] = MakeHisto<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullT[0], kRPullT[1]);
+      fvph_pull_t_vs_t[iSt] = MakeQaObject<TH2F>(sN, sT, kNbins, 0, 0, kNbins, kRPullT[0], kRPullT[1]);
 
 
       sN                       = (TString) "reco_eff_vs_xy" + nsuff;
       sT                       = (TString) "Hit rec. efficiency" + tsuff + ";x_{MC} [cm];y_{MC} [cm];#epsilon";
-      fvpe_reco_eff_vs_xy[iSt] = MakeEfficiency<CbmQaEff>(sN, sT, 100, -50, 50, 100, -50, 50);
+      fvpe_reco_eff_vs_xy[iSt] = MakeQaObject<CbmQaEff>(sN, sT, 100, -50, 50, 100, -50, 50);
 
       sN                      = (TString) "reco_eff_vs_r" + nsuff;
       sT                      = (TString) "Hit rec. efficiency" + tsuff + ";r_{MC} [cm];#epsilon";
-      fvpe_reco_eff_vs_r[iSt] = MakeEfficiency<CbmQaEff>(sN, sT, 100, 0, 100);
+      fvpe_reco_eff_vs_r[iSt] = MakeQaObject<CbmQaEff>(sN, sT, 100, 0, 100);
     }
   }
   return kSUCCESS;
diff --git a/reco/L1/qa/CbmCaInputQaTrd.cxx b/reco/L1/qa/CbmCaInputQaTrd.cxx
index e3a3a142dafab30272a67a0d6526feba421c41cb..a5883c47fc441a6ab60462cd6ef83b55bf8ef7ee 100644
--- a/reco/L1/qa/CbmCaInputQaTrd.cxx
+++ b/reco/L1/qa/CbmCaInputQaTrd.cxx
@@ -125,7 +125,7 @@ bool CbmCaInputQaTrd::Check()
     LOG(info) << "-- Hit efficiency integrated over hit distance from station center";
     LOG(info) << "\tintegration range: [" << fEffRange[0] << ", " << fEffRange[1] << "] cm";
 
-    auto* pEffTable = MakeTable("eff_table", "Efficiency table", nSt, 2);
+    auto* pEffTable = MakeQaObject<CbmQaTable>("eff_table", "Efficiency table", nSt, 2);
     pEffTable->SetNamesOfCols({"Station ID", "Efficiency"});
     pEffTable->SetColWidth(20);
 
@@ -158,7 +158,8 @@ bool CbmCaInputQaTrd::Check()
       return result;
     };
 
-    auto* pResidualsTable = MakeTable("residuals_mean", "Residual mean values in different stations", nSt, 4);
+    auto* pResidualsTable =
+      MakeQaObject<CbmQaTable>("residuals_mean", "Residual mean values in different stations", nSt, 4);
     pResidualsTable->SetNamesOfCols({"Station ID", "Residual(x) [cm]", "Residual(y) [cm]", "Residual(t) [ns]"});
     pResidualsTable->SetColWidth(20);
 
@@ -201,7 +202,7 @@ bool CbmCaInputQaTrd::Check()
       return fit.GetParameter(2);
     };
 
-    auto* pPullsTable = MakeTable("pulls_rms", "Pulls std. dev. values in different stations", nSt, 4);
+    auto* pPullsTable = MakeQaObject<CbmQaTable>("pulls_rms", "Pulls std. dev. values in different stations", nSt, 4);
     pPullsTable->SetNamesOfCols({"Station ID", "Pull(x) sigm", "Pull(y) sigm", "Pull(z) sigm"});
     pPullsTable->SetColWidth(20);
 
@@ -547,7 +548,7 @@ InitStatus CbmCaInputQaTrd::InitCanvases()
   // ** Hit occupancies
 
   // ** Occupancy in XY plane
-  auto* pc_hit_ypos_vs_xpos = MakeCanvas<CbmQaCanvas>("hit_ypos_vs_xpos", "", 1600, 800);
+  auto* pc_hit_ypos_vs_xpos = MakeQaObject<CbmQaCanvas>("hit_ypos_vs_xpos", "", 1600, 800);
   pc_hit_ypos_vs_xpos->Divide2D(nSt);
   for (int iSt = 0; iSt < nSt; ++iSt) {
     pc_hit_ypos_vs_xpos->cd(iSt + 1);
@@ -584,7 +585,7 @@ InitStatus CbmCaInputQaTrd::InitCanvases()
   }
 
   // ----- Occupancy projections
-  auto* pc_hit_xpos = MakeCanvas<CbmQaCanvas>("hit_xpos", "", 1400, 800);
+  auto* pc_hit_xpos = MakeQaObject<CbmQaCanvas>("hit_xpos", "", 1400, 800);
   pc_hit_xpos->Divide2D(nSt);
   for (int iSt = 0; iSt < nSt; ++iSt) {
     pc_hit_xpos->cd(iSt + 1);
@@ -592,7 +593,7 @@ InitStatus CbmCaInputQaTrd::InitCanvases()
     phProj->DrawCopy();
   }
 
-  auto* pc_hit_ypos = MakeCanvas<CbmQaCanvas>("hit_ypos", "", 1400, 800);
+  auto* pc_hit_ypos = MakeQaObject<CbmQaCanvas>("hit_ypos", "", 1400, 800);
   pc_hit_ypos->Divide2D(nSt);
   for (int iSt = 0; iSt < nSt; ++iSt) {
     pc_hit_ypos->cd(iSt + 1);
@@ -609,7 +610,7 @@ InitStatus CbmCaInputQaTrd::InitCanvases()
     // ** Point occupancies
 
     // ** Occupancy in XY plane
-    auto* pc_point_ypos_vs_xpos = MakeCanvas<CbmQaCanvas>("point_ypos_vs_xpos", "", 1600, 800);
+    auto* pc_point_ypos_vs_xpos = MakeQaObject<CbmQaCanvas>("point_ypos_vs_xpos", "", 1600, 800);
     pc_point_ypos_vs_xpos->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_point_ypos_vs_xpos->cd(iSt + 1);
@@ -648,7 +649,7 @@ InitStatus CbmCaInputQaTrd::InitCanvases()
     // ** Residuals
 
     // x-coordinate
-    auto* pc_res_x = MakeCanvas<CbmQaCanvas>("res_x", "Residuals for x coordinate", 1600, 800);
+    auto* pc_res_x = MakeQaObject<CbmQaCanvas>("res_x", "Residuals for x coordinate", 1600, 800);
     pc_res_x->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_res_x->cd(iSt + 1);
@@ -656,7 +657,7 @@ InitStatus CbmCaInputQaTrd::InitCanvases()
     }
 
     // y-coordinate
-    auto* pc_res_y = MakeCanvas<CbmQaCanvas>("res_y", "Residuals for y coordinate", 1600, 800);
+    auto* pc_res_y = MakeQaObject<CbmQaCanvas>("res_y", "Residuals for y coordinate", 1600, 800);
     pc_res_y->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_res_y->cd(iSt + 1);
@@ -664,7 +665,7 @@ InitStatus CbmCaInputQaTrd::InitCanvases()
     }
 
     // time
-    auto* pc_res_t = MakeCanvas<CbmQaCanvas>("res_t", "Residuals for time", 1600, 800);
+    auto* pc_res_t = MakeQaObject<CbmQaCanvas>("res_t", "Residuals for time", 1600, 800);
     pc_res_t->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_res_t->cd(iSt + 1);
@@ -676,7 +677,7 @@ InitStatus CbmCaInputQaTrd::InitCanvases()
     // ** Pulls
 
     // x-coordinate
-    auto* pc_pull_x = MakeCanvas<CbmQaCanvas>("pull_x", "Pulls for x coordinate", 1600, 800);
+    auto* pc_pull_x = MakeQaObject<CbmQaCanvas>("pull_x", "Pulls for x coordinate", 1600, 800);
     pc_pull_x->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_pull_x->cd(iSt + 1);
@@ -684,7 +685,7 @@ InitStatus CbmCaInputQaTrd::InitCanvases()
     }
 
     // y-coordinate
-    auto* pc_pull_y = MakeCanvas<CbmQaCanvas>("pull_y", "Pulls for y coordinate", 1600, 800);
+    auto* pc_pull_y = MakeQaObject<CbmQaCanvas>("pull_y", "Pulls for y coordinate", 1600, 800);
     pc_pull_y->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_pull_y->cd(iSt + 1);
@@ -692,7 +693,7 @@ InitStatus CbmCaInputQaTrd::InitCanvases()
     }
 
     // time
-    auto* pc_pull_t = MakeCanvas<CbmQaCanvas>("pull_t", "Pulls for time", 1600, 800);
+    auto* pc_pull_t = MakeQaObject<CbmQaCanvas>("pull_t", "Pulls for time", 1600, 800);
     pc_pull_t->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_pull_t->cd(iSt + 1);
@@ -704,14 +705,14 @@ InitStatus CbmCaInputQaTrd::InitCanvases()
     // ** Hit reconstruction efficiencies
 
     auto* pc_reco_eff_vs_r =
-      MakeCanvas<CbmQaCanvas>("reco_eff_vs_r", "Hit efficiencies wrt distance from center", 1600, 800);
+      MakeQaObject<CbmQaCanvas>("reco_eff_vs_r", "Hit efficiencies wrt distance from center", 1600, 800);
     pc_reco_eff_vs_r->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_reco_eff_vs_r->cd(iSt + 1);
       fvpe_reco_eff_vs_r[iSt]->DrawCopy("AP", "");
     }
 
-    auto* pc_reco_eff_vs_xy = MakeCanvas<CbmQaCanvas>("reco_eff_vs_xy", "Hit efficiencies wrt x and y", 1600, 800);
+    auto* pc_reco_eff_vs_xy = MakeQaObject<CbmQaCanvas>("reco_eff_vs_xy", "Hit efficiencies wrt x and y", 1600, 800);
     pc_reco_eff_vs_xy->Divide2D(nSt);
     for (int iSt = 0; iSt < nSt; ++iSt) {
       pc_reco_eff_vs_xy->cd(iSt + 1);
@@ -780,113 +781,113 @@ InitStatus CbmCaInputQaTrd::InitHistograms()
     // Hit occupancy
     sN                         = npref + "hit_ypos_vs_xpos" + nsuff + ";" + xyBinningTag;
     sT                         = (TString) "Hit occupancy in xy-Plane" + tsuff + ";x_{hit} [cm];y_{hit} [cm]";
-    fvph_hit_ypos_vs_xpos[iSt] = MakeHistoConfig<TH2F>(sN, sT, nBinsX, -xMax, xMax, nBinsY, -yMax, yMax);
+    fvph_hit_ypos_vs_xpos[iSt] = MakeQaObject<TH2F>(sN, sT, nBinsX, -xMax, xMax, nBinsY, -yMax, yMax);
 
     sN                         = npref + "hit_xpos_vs_zpos" + nsuff;
     sT                         = (TString) "Hit occupancy in xz-Plane" + tsuff + ";z_{hit} [cm];x_{hit} [cm]";
-    fvph_hit_xpos_vs_zpos[iSt] = MakeHisto<TH2F>(sN, sT, fNbinsZ, fvRHitZ[0], fvRHitZ[1], nBinsX, -xMax, xMax);
+    fvph_hit_xpos_vs_zpos[iSt] = MakeQaObject<TH2F>(sN, sT, fNbinsZ, fvRHitZ[0], fvRHitZ[1], nBinsX, -xMax, xMax);
 
     sN                         = npref + "hit_ypos_vs_zpos" + nsuff;
     sT                         = (TString) "Hit occupancy in yz-plane" + tsuff + ";z_{hit} [cm];y_{hit} [cm]";
-    fvph_hit_ypos_vs_zpos[iSt] = MakeHisto<TH2F>(sN, sT, fNbinsZ, fvRHitZ[0], fvRHitZ[1], nBinsY, -yMax, yMax);
+    fvph_hit_ypos_vs_zpos[iSt] = MakeQaObject<TH2F>(sN, sT, fNbinsZ, fvRHitZ[0], fvRHitZ[1], nBinsY, -yMax, yMax);
 
     // Hit errors
     sN               = npref + "hit_dx" + nsuff;
     sT               = (TString) "Hit position error along x-axis" + tsuff + ";dx_{hit} [cm]";
-    fvph_hit_dx[iSt] = MakeHisto<TH1F>(sN, sT, fNbins, fvRHitDx[0], fvRHitDx[1]);
+    fvph_hit_dx[iSt] = MakeQaObject<TH1F>(sN, sT, fNbins, fvRHitDx[0], fvRHitDx[1]);
 
     sN               = npref + "hit_dy" + nsuff;
     sT               = (TString) "Hit position error along y-axis" + tsuff + ";dy_{hit} [cm]";
-    fvph_hit_dy[iSt] = MakeHisto<TH1F>(sN, sT, fNbins, fvRHitDy[0], fvRHitDy[1]);
+    fvph_hit_dy[iSt] = MakeQaObject<TH1F>(sN, sT, fNbins, fvRHitDy[0], fvRHitDy[1]);
 
     sN               = npref + "hit_dt" + nsuff;
     sT               = (TString) "Hit time error" + tsuff + ";dt_{hit} [ns]";
-    fvph_hit_dt[iSt] = MakeHisto<TH1F>(sN, sT, fNbins, fvRHitDt[0], fvRHitDt[1]);
+    fvph_hit_dt[iSt] = MakeQaObject<TH1F>(sN, sT, fNbins, fvRHitDt[0], fvRHitDt[1]);
 
     sN = npref + "hit_station_delta_z" + nsuff;
     sT = (TString) "Different between hit and station z-positions" + tsuff + ";z_{hit} - z_{st} [cm]";
-    fvph_hit_station_delta_z[iSt] = MakeHisto<TH1F>(sN, sT, fNbins, -5., 5);
+    fvph_hit_station_delta_z[iSt] = MakeQaObject<TH1F>(sN, sT, fNbins, -5., 5);
 
     // ----- Initialize histograms, which are use MC-information
     if (IsMCUsed()) {
       sN                         = npref + "n_points_per_hit" + nsuff;
       sT                         = (TString) "Number of points per hit" + tsuff + ";N_{point}/hit";
-      fvph_n_points_per_hit[iSt] = MakeHisto<TH1F>(sN, sT, 10, -0.5, 9.5);
+      fvph_n_points_per_hit[iSt] = MakeQaObject<TH1F>(sN, sT, 10, -0.5, 9.5);
 
       // Point occupancy
       sN                           = npref + "point_ypos_vs_xpos" + nsuff + ";" + xyBinningTag;
       sT = (TString) "Point occupancy in XY plane" + tsuff + ";x_{MC} [cm];y_{MC} [cm]";
-      fvph_point_ypos_vs_xpos[iSt] = MakeHistoConfig<TH2F>(sN, sT, nBinsX, -xMax, xMax, nBinsY, -yMax, yMax);
+      fvph_point_ypos_vs_xpos[iSt] = MakeQaObject<TH2F>(sN, sT, nBinsX, -xMax, xMax, nBinsY, -yMax, yMax);
 
       sN                           = npref + "point_xpos_vs_zpos" + nsuff;
       sT = (TString) "Point Occupancy in XZ plane" + tsuff + ";z_{MC} [cm];x_{MC} [cm]";
-      fvph_point_xpos_vs_zpos[iSt] = MakeHisto<TH2F>(sN, sT, fNbinsZ, fvRHitZ[0], fvRHitZ[1], nBinsX, -xMax, xMax);
+      fvph_point_xpos_vs_zpos[iSt] = MakeQaObject<TH2F>(sN, sT, fNbinsZ, fvRHitZ[0], fvRHitZ[1], nBinsX, -xMax, xMax);
 
       sN                           = npref + "point_ypos_vs_zpos" + nsuff;
       sT = (TString) "Point Occupancy in YZ Plane" + tsuff + ";z_{MC} [cm];y_{MC} [cm]";
-      fvph_point_ypos_vs_zpos[iSt] = MakeHisto<TH2F>(sN, sT, fNbinsZ, fvRHitZ[0], fvRHitZ[1], nBinsY, -yMax, yMax);
+      fvph_point_ypos_vs_zpos[iSt] = MakeQaObject<TH2F>(sN, sT, fNbinsZ, fvRHitZ[0], fvRHitZ[1], nBinsY, -yMax, yMax);
 
       // Difference between MC input z and hit z coordinates
       sN = npref + "point_hit_delta_z" + nsuff;
       sT = (TString) "Distance between point and hit along z axis" + tsuff + ";z_{reco} - z_{MC} [cm]";
-      fvph_point_hit_delta_z[iSt] = MakeHisto<TH1F>(sN, sT, fNbins, -0.04, 0.04);
+      fvph_point_hit_delta_z[iSt] = MakeQaObject<TH1F>(sN, sT, fNbins, -0.04, 0.04);
 
       sN              = npref + "res_x" + nsuff;
       sT              = (TString) "Residuals for x-coordinate" + tsuff + ";x_{reco} - x_{MC} [cm]";
-      fvph_res_x[iSt] = MakeHisto<TH1F>(sN, sT, fNbins, fvRResX[0], fvRResX[1]);
+      fvph_res_x[iSt] = MakeQaObject<TH1F>(sN, sT, fNbins, fvRResX[0], fvRResX[1]);
 
       sN              = npref + "res_y" + nsuff;
       sT              = (TString) "Residuals for y-coordinate" + tsuff + ";y_{reco} - y_{MC} [cm]";
-      fvph_res_y[iSt] = MakeHisto<TH1F>(sN, sT, fNbins, fvRResY[0], fvRResY[1]);
+      fvph_res_y[iSt] = MakeQaObject<TH1F>(sN, sT, fNbins, fvRResY[0], fvRResY[1]);
 
       sN              = npref + "res_t" + nsuff;
       sT              = (TString) "Residuals for time" + tsuff + ";t_{reco} - t_{MC} [ns]";
-      fvph_res_t[iSt] = MakeHisto<TH1F>(sN, sT, fNbins, fvRResT[0], fvRResT[1]);
+      fvph_res_t[iSt] = MakeQaObject<TH1F>(sN, sT, fNbins, fvRResT[0], fvRResT[1]);
 
       sN               = npref + "pull_x" + nsuff;
       sT               = (TString) "Pulls for x-coordinate" + tsuff + ";(x_{reco} - x_{MC}) / #sigma_{x}^{reco}";
-      fvph_pull_x[iSt] = MakeHisto<TH1F>(sN, sT, fNbins, fvRPullX[0], fvRPullX[1]);
+      fvph_pull_x[iSt] = MakeQaObject<TH1F>(sN, sT, fNbins, fvRPullX[0], fvRPullX[1]);
 
       sN               = npref + "pull_y" + nsuff;
       sT               = (TString) "Pulls for y-coordinate" + tsuff + ";(y_{reco} - y_{MC}) / #sigma_{y}^{reco}";
-      fvph_pull_y[iSt] = MakeHisto<TH1F>(sN, sT, fNbins, fvRPullY[0], fvRPullY[1]);
+      fvph_pull_y[iSt] = MakeQaObject<TH1F>(sN, sT, fNbins, fvRPullY[0], fvRPullY[1]);
 
       sN               = npref + "pull_t" + nsuff;
       sT               = (TString) "Pulls for time" + tsuff + ";(t_{reco} - t_{MC}) / #sigma_{t}^{reco}";
-      fvph_pull_t[iSt] = MakeHisto<TH1F>(sN, sT, fNbins, fvRPullT[0], fvRPullT[1]);
+      fvph_pull_t[iSt] = MakeQaObject<TH1F>(sN, sT, fNbins, fvRPullT[0], fvRPullT[1]);
 
       sN                   = npref + "res_x_vs_x" + nsuff;
       sT                   = (TString) "Residuals for x-coordinate" + tsuff + ";x_{reco} [cm];x_{reco} - x_{MC} [cm]";
-      fvph_res_x_vs_x[iSt] = MakeHisto<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRResX[0], fvRResX[1]);
+      fvph_res_x_vs_x[iSt] = MakeQaObject<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRResX[0], fvRResX[1]);
 
       sN                   = npref + "res_y_vs_y" + nsuff;
       sT                   = (TString) "Residuals for y-coordinate" + tsuff + ";y_{reco} [cm];y_{reco} - y_{MC} [cm]";
-      fvph_res_y_vs_y[iSt] = MakeHisto<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRResY[0], fvRResY[1]);
+      fvph_res_y_vs_y[iSt] = MakeQaObject<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRResY[0], fvRResY[1]);
 
       sN                   = npref + "res_t_vs_t" + nsuff;
       sT                   = (TString) "Residuals for time" + tsuff + "t_{reco} [ns];t_{reco} - t_{MC} [ns]";
-      fvph_res_t_vs_t[iSt] = MakeHisto<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRResT[0], fvRResT[1]);
+      fvph_res_t_vs_t[iSt] = MakeQaObject<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRResT[0], fvRResT[1]);
 
       sN = npref + "pull_x_vs_x" + nsuff;
       sT = (TString) "Pulls for x-coordinate" + tsuff + "x_{reco} [cm];(x_{reco} - x_{MC}) / #sigma_{x}^{reco}";
-      fvph_pull_x_vs_x[iSt] = MakeHisto<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRPullX[0], fvRPullX[1]);
+      fvph_pull_x_vs_x[iSt] = MakeQaObject<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRPullX[0], fvRPullX[1]);
 
       sN = npref + "pull_y_vs_y" + nsuff;
       sT = (TString) "Pulls for y-coordinate" + tsuff + ";y_{reco} [cm];(y_{reco} - y_{MC}) / #sigma_{y}^{reco}";
-      fvph_pull_y_vs_y[iSt] = MakeHisto<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRPullY[0], fvRPullY[1]);
+      fvph_pull_y_vs_y[iSt] = MakeQaObject<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRPullY[0], fvRPullY[1]);
 
       sN                    = npref + "pull_t_vs_t" + nsuff;
       sT = (TString) "Pulls for time" + tsuff + ";t_{reco} [ns];(t_{reco} - t_{MC}) / #sigma_{t}^{reco}";
-      fvph_pull_t_vs_t[iSt] = MakeHisto<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRPullT[0], fvRPullT[1]);
+      fvph_pull_t_vs_t[iSt] = MakeQaObject<TH2F>(sN, sT, fNbins, 0, 0, fNbins, fvRPullT[0], fvRPullT[1]);
 
       sN                       = npref + "reco_eff_vs_xy" + nsuff + ";" + xyBinningTag;
       sT                       = (TString) "Hit rec. efficiency" + tsuff + ";x_{MC} [cm];y_{MC} [cm];#epsilon";
       fvpe_reco_eff_vs_xy[iSt] =
-        MakeHistoConfig<TProfile2D>(sN, sT, fNbins, fvRHitX[0], fvRHitX[1], fNbins, fvRHitY[0], fvRHitY[1]);
+        MakeQaObject<TProfile2D>(sN, sT, fNbins, fvRHitX[0], fvRHitX[1], fNbins, fvRHitY[0], fvRHitY[1]);
 
       sN                      = npref + "reco_eff_vs_r" + nsuff;
       sT                      = (TString) "Hit rec. efficiency" + tsuff + ";r_{MC} [cm];#epsilon";
-      fvpe_reco_eff_vs_r[iSt] = MakeHisto<TProfile>(sN, sT, 100, 0, 100, 0., 1.);
+      fvpe_reco_eff_vs_r[iSt] = MakeQaObject<TProfile>(sN, sT, 100, 0, 100, 0., 1.);
     }
   }
   return kSUCCESS;
diff --git a/reco/L1/qa/CbmCaOutputQa.cxx b/reco/L1/qa/CbmCaOutputQa.cxx
index 4547ea539c2206afe1f856d1814c06f2d2b94ea2..3a9fc87e546ef8f1cc6ad940981a5234483fcf94 100644
--- a/reco/L1/qa/CbmCaOutputQa.cxx
+++ b/reco/L1/qa/CbmCaOutputQa.cxx
@@ -342,61 +342,61 @@ InitStatus OutputQa::InitCanvases()
     // **  Reconstructed track distributions  **
     // Reconstructed pseudorapidity
     auto* pc_reco_eta =
-      MakeCanvas<CbmQaCanvas>("reco_eta", "Reconstructed track pseudorapidity", kCXSIZEPX * 3, kCYSIZEPX * 2);
+      MakeQaObject<CbmQaCanvas>("reco_eta", "Reconstructed track pseudorapidity", kCXSIZEPX * 3, kCYSIZEPX * 2);
     DrawTrackDistributions(pc_reco_eta, [&](ETrackType t) -> TH1F* { return fvpTrackHistograms[t]->fph_reco_eta; });
 
     // MC pseudorapidity
     auto* pc_reco_etaMC =
-      MakeCanvas<CbmQaCanvas>("reco_etaMC", "Reconstructed track MC pseudorapidity", kCXSIZEPX * 3, kCYSIZEPX * 2);
+      MakeQaObject<CbmQaCanvas>("reco_etaMC", "Reconstructed track MC pseudorapidity", kCXSIZEPX * 3, kCYSIZEPX * 2);
     DrawTrackDistributions(pc_reco_etaMC, [&](ETrackType t) -> TH1F* { return fvpTrackHistograms[t]->fph_reco_etaMC; });
 
     // MC momentum
     auto* pc_reco_pMC =
-      MakeCanvas<CbmQaCanvas>("reco_pMC", "Reconstructed track MC momentum", kCXSIZEPX * 3, kCYSIZEPX * 2);
+      MakeQaObject<CbmQaCanvas>("reco_pMC", "Reconstructed track MC momentum", kCXSIZEPX * 3, kCYSIZEPX * 2);
     DrawTrackDistributions(pc_reco_pMC, [&](ETrackType t) -> TH1F* { return fvpTrackHistograms[t]->fph_reco_pMC; });
 
     // MC rapidity
     auto* pc_reco_yMC =
-      MakeCanvas<CbmQaCanvas>("reco_yMC", "Reconstructed track MC rapidity", kCXSIZEPX * 3, kCYSIZEPX * 2);
+      MakeQaObject<CbmQaCanvas>("reco_yMC", "Reconstructed track MC rapidity", kCXSIZEPX * 3, kCYSIZEPX * 2);
     DrawTrackDistributions(pc_reco_yMC, [&](ETrackType t) -> TH1F* { return fvpTrackHistograms[t]->fph_reco_yMC; });
 
     // **  MC track distributions  **
 
     // MC momentum
     auto* pc_mc_pMC =
-      MakeCanvas<CbmQaCanvas>("mc_pMC", "MC reconstructable track MC momentum", kCXSIZEPX * 3, kCYSIZEPX * 2);
+      MakeQaObject<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; });
 
     // MC rapidity
     auto* pc_mc_yMC =
-      MakeCanvas<CbmQaCanvas>("mc_yMC", "MC reconstructable track MC rapidity", kCXSIZEPX * 3, kCYSIZEPX * 2);
+      MakeQaObject<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; });
 
     // MC rapidity vs. MC momentum
     // auto* pc_mc_pMC_yMC =
-    MakeCanvas<CbmQaCanvas>("mc_pMC_yMC", "MC track MC mom. vs. rapidity ", kCXSIZEPX * 3, kCYSIZEPX * 2);
+    MakeQaObject<CbmQaCanvas>("mc_pMC_yMC", "MC track MC mom. vs. rapidity ", kCXSIZEPX * 3, kCYSIZEPX * 2);
     DrawSetOf<TH2F>(vCmpTypesGeneral, [&](ETrackType t) -> TH2F* { return fvpTrackHistograms[t]->fph_reco_pMC_yMC; });
 
     // **  Efficiencies  **
 
     // MC momentum
-    auto* pc_eff_pMC = MakeCanvas<CbmQaCanvas>("eff_pMC", "Tracking Eff. vs. MC momentum", kCXSIZEPX * 3, kCYSIZEPX);
+    auto* pc_eff_pMC = MakeQaObject<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);
+    auto* pc_eff_yMC = MakeQaObject<CbmQaCanvas>("eff_yMC", "Tracking Eff. vs. MC rapidity", kCXSIZEPX * 3, kCYSIZEPX);
     DrawTrackEfficiens(pc_eff_yMC, [&](ETrackType t) -> TProfile* { return fvpTrackHistograms[t]->fph_eff_yMC; });
 
     auto* pc_eff_thetaMC =
-      MakeCanvas<CbmQaCanvas>("eff_thetaMC", "Tracking Eff. vs. MC polar angle", kCXSIZEPX * 3, kCYSIZEPX);
+      MakeQaObject<CbmQaCanvas>("eff_thetaMC", "Tracking Eff. vs. MC polar angle", kCXSIZEPX * 3, kCYSIZEPX);
     DrawTrackEfficiens(pc_eff_thetaMC,
                        [&](ETrackType t) -> TProfile* { return fvpTrackHistograms[t]->fph_eff_thetaMC; });
 
     auto* pc_eff_phiMC =
-      MakeCanvas<CbmQaCanvas>("eff_phiMC", "Tracking Eff. vs. MC azimuthal angle", kCXSIZEPX * 3, kCYSIZEPX);
+      MakeQaObject<CbmQaCanvas>("eff_phiMC", "Tracking Eff. vs. MC azimuthal angle", kCXSIZEPX * 3, kCYSIZEPX);
     DrawTrackEfficiens(pc_eff_phiMC, [&](ETrackType t) -> TProfile* { return fvpTrackHistograms[t]->fph_eff_phiMC; });
 
     auto* pc_eff_etaMC =
-      MakeCanvas<CbmQaCanvas>("eff_etaMC", "Tracking Eff. vs. MC pseudorapidity", kCXSIZEPX * 3, kCYSIZEPX);
+      MakeQaObject<CbmQaCanvas>("eff_etaMC", "Tracking Eff. vs. MC pseudorapidity", kCXSIZEPX * 3, kCYSIZEPX);
     DrawTrackEfficiens(pc_eff_etaMC, [&](ETrackType t) -> TProfile* { return fvpTrackHistograms[t]->fph_eff_etaMC; });
 
 
@@ -555,7 +555,7 @@ bool OutputQa::Check()
 {
   // Create summary table
   int nRows = std::count_if(fvbTrackTypeOn.begin(), fvbTrackTypeOn.end(), [](const auto& f) { return f == true; });
-  CbmQaTable* aTable                = MakeTable("summary_table", "Tracking summary table", nRows + 1, 9);
+  CbmQaTable* aTable = MakeQaObject<CbmQaTable>("summary_table", "Tracking summary table", nRows + 1, 9);
   int iRow                          = 0;
   std::vector<std::string> colNames = {"Efficiency", "Killed", "Length",   "Fakes",     "Clones",
                                        "Reco/Evt",   "MC/Evt", "Nst(hit)", "Nst(point)"};
diff --git a/reco/L1/qa/CbmCaTrackFitQa.cxx b/reco/L1/qa/CbmCaTrackFitQa.cxx
index 35b51d194858617b55adf48fee2034b5244c5dfe..ba6655a205b8319ec3e2492ae945d924035eb3f8 100644
--- a/reco/L1/qa/CbmCaTrackFitQa.cxx
+++ b/reco/L1/qa/CbmCaTrackFitQa.cxx
@@ -44,7 +44,7 @@ TrackFitQa::TrackFitQa(const char* pointTag, const char* prefix, std::shared_ptr
 //
 CbmQaCanvas* TrackFitQa::CreateResidualPlot()
 {
-  auto* pCanv = MakeCanvas<CbmQaCanvas>("canv_residuals", " residuals", kCXSIZEPX * 4, kCYSIZEPX * 2);
+  auto* pCanv = MakeQaObject<CbmQaCanvas>("canv_residuals", " residuals", kCXSIZEPX * 4, kCYSIZEPX * 2);
   pCanv->Divide2D(7);
 
 
@@ -62,7 +62,7 @@ CbmQaCanvas* TrackFitQa::CreateResidualPlot()
 //
 CbmQaCanvas* TrackFitQa::CreatePullPlot()
 {
-  auto* pCanv = MakeCanvas<CbmQaCanvas>(fsPrefix + "_canv_pulls", " pulls", kCXSIZEPX * 4, kCYSIZEPX * 2);
+  auto* pCanv = MakeQaObject<CbmQaCanvas>(fsPrefix + "_canv_pulls", " pulls", kCXSIZEPX * 4, kCYSIZEPX * 2);
   pCanv->Divide2D(7);
 
   for (int iType = static_cast<int>(ETrackParType::kBEGIN); iType < static_cast<int>(ETrackParType::kEND); ++iType) {
@@ -89,13 +89,13 @@ void TrackFitQa::Init()
   auto CreateResidualHisto = [&](ETrackParType t, const char* name, const char* title) {
     if (fvbParIgnored[t]) { return; }
     TString sPrefix  = (fsTitle.Length() > 0) ? fsTitle + " point residual for " : "residual for ";
-    fvphResiduals[t] = MakeHisto<TH1F>(name, sPrefix + title, fvRBins[t], fvRLo[t], fvRUp[t]);
+    fvphResiduals[t] = MakeQaObject<TH1F>(name, sPrefix + title, fvRBins[t], fvRLo[t], fvRUp[t]);
   };
 
   auto CreatePullHisto = [&](ETrackParType t, const char* name, const char* title) {
     if (fvbParIgnored[t]) { return; }
     TString sPrefix = (fsTitle.Length() > 0) ? fsTitle + " point pull for " : "pull for ";
-    fvphPulls[t]    = MakeHisto<TH1F>(name, sPrefix + title, fvPBins[t], fvPLo[t], fvPUp[t]);
+    fvphPulls[t]    = MakeQaObject<TH1F>(name, sPrefix + title, fvPBins[t], fvPLo[t], fvPUp[t]);
   };
 
   CreateResidualHisto(ETrackParType::kX, "res_x", "x-coordinate;x^{reco} - x^{MC} [cm]");
@@ -115,9 +115,9 @@ void TrackFitQa::Init()
   CreatePullHisto(ETrackParType::kVI, "pull_vi", "inverse speed;(v^{-1}_{reco} - v^{-1}_{MC})/#sigma_{v^{-1}}");
 
   // FIXME: Replace hardcoded parameters with variables
-  fph_res_p_pMC         = MakeHisto<TProfile>("res_p_vs_pMC", "", 100, 0.0, 10.0, -2., 2.);
-  fph_res_phi_phiMC     = MakeHisto<TProfile>("res_phi_vs_phiMC", "", 100, -3.2, 3.2, -2., 2.);
-  fph_res_theta_thetaMC = MakeHisto<TProfile>("res_theta_vs_phiMC", "", 100, 0., 3.2, -2., 2.);
+  fph_res_p_pMC         = MakeQaObject<TProfile>("res_p_vs_pMC", "", 100, 0.0, 10.0, -2., 2.);
+  fph_res_phi_phiMC     = MakeQaObject<TProfile>("res_phi_vs_phiMC", "", 100, -3.2, 3.2, -2., 2.);
+  fph_res_theta_thetaMC = MakeQaObject<TProfile>("res_theta_vs_phiMC", "", 100, 0., 3.2, -2., 2.);
 
   // Set histogram titles
   TString sPrefix = (fsTitle.Length() > 0) ? fsTitle + " point " : "";
diff --git a/reco/L1/qa/CbmCaTrackTypeQa.cxx b/reco/L1/qa/CbmCaTrackTypeQa.cxx
index 295b18de6806aab4a879ef7da14f744fd59458f7..2aad2a6c143b6920d3a6341e464c09795fc42be4 100644
--- a/reco/L1/qa/CbmCaTrackTypeQa.cxx
+++ b/reco/L1/qa/CbmCaTrackTypeQa.cxx
@@ -40,16 +40,17 @@ void TrackTypeQa::Init()
   //
   // ** Distributions of reconstructed tracks vs. reconstructed quantities **
   //
-  fph_reco_p     = MakeHisto<TH1F>("reco_p", "", kBinsP, kLoP, kUpP);
-  fph_reco_pt    = MakeHisto<TH1F>("reco_pt", "", kBinsPT, kLoPT, kUpPT);
-  fph_reco_eta   = MakeHisto<TH1F>("reco_eta", "", kBinsETA, kLoETA, kUpETA);
-  fph_reco_phi   = MakeHisto<TH1F>("reco_phi", "", kBinsPHI, kLoPHI, kUpPHI);
-  fph_reco_theta = MakeHisto<TH1F>("reco_theta", "", kBinsTHETA, kLoTHETA, kUpTHETA);
-  fph_reco_theta_phi = MakeHisto<TH2F>("reco_theta_phi", "", kBinsPHI, kLoPHI, kUpPHI, kBinsTHETA, kLoTHETA, kUpTHETA);
-  fph_reco_tx    = MakeHisto<TH1F>("reco_tx", "", kBinsTX, kLoTX, kUpTX);
-  fph_reco_ty    = MakeHisto<TH1F>("reco_ty", "", kBinsTY, kLoTY, kUpTY);
-  fph_reco_ty_tx     = MakeHisto<TH2F>("reco_ty_tx", "", kBinsTX, kLoTX, kUpTX, kBinsTY, kLoTY, kUpTY);
-  fph_reco_fhitR = MakeHisto<TH1F>("reco_fhitR", "", kBinsFHITR, kLoFHITR, kUpFHITR);
+  fph_reco_p     = MakeQaObject<TH1F>("reco_p", "", kBinsP, kLoP, kUpP);
+  fph_reco_pt    = MakeQaObject<TH1F>("reco_pt", "", kBinsPT, kLoPT, kUpPT);
+  fph_reco_eta   = MakeQaObject<TH1F>("reco_eta", "", kBinsETA, kLoETA, kUpETA);
+  fph_reco_phi   = MakeQaObject<TH1F>("reco_phi", "", kBinsPHI, kLoPHI, kUpPHI);
+  fph_reco_theta = MakeQaObject<TH1F>("reco_theta", "", kBinsTHETA, kLoTHETA, kUpTHETA);
+  fph_reco_theta_phi =
+    MakeQaObject<TH2F>("reco_theta_phi", "", kBinsPHI, kLoPHI, kUpPHI, kBinsTHETA, kLoTHETA, kUpTHETA);
+  fph_reco_tx    = MakeQaObject<TH1F>("reco_tx", "", kBinsTX, kLoTX, kUpTX);
+  fph_reco_ty    = MakeQaObject<TH1F>("reco_ty", "", kBinsTY, kLoTY, kUpTY);
+  fph_reco_ty_tx = MakeQaObject<TH2F>("reco_ty_tx", "", kBinsTX, kLoTX, kUpTX, kBinsTY, kLoTY, kUpTY);
+  fph_reco_fhitR = MakeQaObject<TH1F>("reco_fhitR", "", kBinsFHITR, kLoFHITR, kUpFHITR);
   // TODO: ...
 
   fph_reco_p->SetTitle("Total momentum of reconstructed track;p^{reco} [GeV/c];Counts");
@@ -70,13 +71,13 @@ void TrackTypeQa::Init()
     //
     // ** 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     = MakeQaObject<TH1F>("reco_pMC", "", kBinsP, kLoP, kUpP);
+    fph_reco_etaMC   = MakeQaObject<TH1F>("reco_etaMC", "", kBinsETA, kLoETA, kUpETA);
+    fph_reco_yMC     = MakeQaObject<TH1F>("reco_yMC", "", kBinsY, kLoY, kUpY);
+    fph_reco_pMC_yMC = MakeQaObject<TH2F>("reco_pMC_yMC", "", kBinsY, kLoY, kUpY, kBinsP, kLoP, kUpP);
+    fph_reco_phiMC   = MakeQaObject<TH1F>("reco_phiMC", "", kBinsPHI, kLoPHI, kUpPHI);
+    fph_reco_thetaMC = MakeQaObject<TH1F>("reco_thetaMC", "", kBinsTHETA, kLoTHETA, kUpTHETA);
+    fph_reco_nhits   = MakeQaObject<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");
@@ -87,15 +88,15 @@ void TrackTypeQa::Init()
     fph_reco_nhits->SetTitle("Hit number of reconstructed tracks;N^{MC}_{hits};Counts");
 
 
-    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_txMC      = MakeHisto<TH1F>("mc_txMC", "", kBinsTX, kLoTX, kUpTX);
-    fph_mc_tyMC      = MakeHisto<TH1F>("mc_tyMC", "", kBinsTY, kLoTY, kUpTY);
-    fph_mc_tyMC_txMC = MakeHisto<TH2F>("mc_tyMC_txMC", "", kBinsTX, kLoTX, kUpTX, kBinsTY, kLoTY, kUpTY);
+    fph_mc_pMC       = MakeQaObject<TH1F>("mc_pMC", "", kBinsP, kLoP, kUpP);
+    fph_mc_etaMC     = MakeQaObject<TH1F>("mc_etaMC", "", kBinsETA, kLoETA, kUpETA);
+    fph_mc_yMC       = MakeQaObject<TH1F>("mc_yMC", "", kBinsY, kLoY, kUpY);
+    fph_mc_pMC_yMC   = MakeQaObject<TH2F>("mc_pMC_yMC", "", kBinsY, kLoY, kUpY, kBinsP, kLoP, kUpP);
+    fph_mc_txMC      = MakeQaObject<TH1F>("mc_txMC", "", kBinsTX, kLoTX, kUpTX);
+    fph_mc_tyMC      = MakeQaObject<TH1F>("mc_tyMC", "", kBinsTY, kLoTY, kUpTY);
+    fph_mc_tyMC_txMC = MakeQaObject<TH2F>("mc_tyMC_txMC", "", kBinsTX, kLoTX, kUpTX, kBinsTY, kLoTY, kUpTY);
     fph_mc_thetaMC_phiMC =
-      MakeHisto<TH2F>("mc_thetaMC_phiMC", "", kBinsPHI, kLoPHI, kUpPHI, kBinsTHETA, kLoTHETA, kUpTHETA);
+      MakeQaObject<TH2F>("mc_thetaMC_phiMC", "", kBinsPHI, kLoPHI, kUpPHI, kBinsTHETA, kLoTHETA, kUpTHETA);
 
     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");
@@ -109,24 +110,24 @@ void TrackTypeQa::Init()
     //
     // ** Efficiencies **
     //
-    fph_eff_int     = MakeHisto<TProfile>("eff_int", "", 1, -0.5, 0.5, 0., 1.);
-    fph_eff_pMC     = MakeHisto<TProfile>("eff_pMC", "", kBinsP, kLoP, kUpP, 0., 1.);
-    fph_eff_yMC     = MakeHisto<TProfile>("eff_yMC", "", kBinsY, kLoY, kUpY, 0., 1.);
-    fph_eff_ptMC    = MakeHisto<TProfile>("eff_ptMC", "", kBinsPT, kLoPT, kUpPT, 0., 1.);
-    fph_eff_thetaMC = MakeHisto<TProfile>("eff_thetaMC", "", kBinsTHETA, kLoTHETA, kUpTHETA, 0., 1.);
-    fph_eff_etaMC   = MakeHisto<TProfile>("eff_etaMC", "", kBinsTHETA, kLoTHETA, kUpTHETA, 0., 1.);
-    fph_eff_phiMC   = MakeHisto<TProfile>("eff_phiMC", "", kBinsPHI, kLoPHI, kUpPHI, 0., 1.);
-    fph_eff_nhitsMC = MakeHisto<TProfile>("eff_nhitsMC", "", kBinsNHITS, kLoNHITS, kUpNHITS, 0., 1.);
-    fph_eff_txMC    = MakeHisto<TProfile>("eff_txMC", "", kBinsTX, kLoTX, kUpTX, 0., 1.);
-    fph_eff_tyMC    = MakeHisto<TProfile>("eff_tyMC", "", kBinsTY, kLoTY, kUpTX, 0., 1.);
-
-    fph_rate_reco   = MakeHisto<TProfile>("rate_reco", "", 1, -0.5, 0.5, 0., 1.);
-    fph_rate_killed = MakeHisto<TProfile>("rate_killed", "", 1, -0.5, 0.5, 0., 1.);
-    fph_rate_clones = MakeHisto<TProfile>("rate_clones", "", 1, -0.5, 0.5, 0., 1.);
+    fph_eff_int     = MakeQaObject<TProfile>("eff_int", "", 1, -0.5, 0.5, 0., 1.);
+    fph_eff_pMC     = MakeQaObject<TProfile>("eff_pMC", "", kBinsP, kLoP, kUpP, 0., 1.);
+    fph_eff_yMC     = MakeQaObject<TProfile>("eff_yMC", "", kBinsY, kLoY, kUpY, 0., 1.);
+    fph_eff_ptMC    = MakeQaObject<TProfile>("eff_ptMC", "", kBinsPT, kLoPT, kUpPT, 0., 1.);
+    fph_eff_thetaMC = MakeQaObject<TProfile>("eff_thetaMC", "", kBinsTHETA, kLoTHETA, kUpTHETA, 0., 1.);
+    fph_eff_etaMC   = MakeQaObject<TProfile>("eff_etaMC", "", kBinsTHETA, kLoTHETA, kUpTHETA, 0., 1.);
+    fph_eff_phiMC   = MakeQaObject<TProfile>("eff_phiMC", "", kBinsPHI, kLoPHI, kUpPHI, 0., 1.);
+    fph_eff_nhitsMC = MakeQaObject<TProfile>("eff_nhitsMC", "", kBinsNHITS, kLoNHITS, kUpNHITS, 0., 1.);
+    fph_eff_txMC    = MakeQaObject<TProfile>("eff_txMC", "", kBinsTX, kLoTX, kUpTX, 0., 1.);
+    fph_eff_tyMC    = MakeQaObject<TProfile>("eff_tyMC", "", kBinsTY, kLoTY, kUpTX, 0., 1.);
+
+    fph_rate_reco   = MakeQaObject<TProfile>("rate_reco", "", 1, -0.5, 0.5, 0., 1.);
+    fph_rate_killed = MakeQaObject<TProfile>("rate_killed", "", 1, -0.5, 0.5, 0., 1.);
+    fph_rate_clones = MakeQaObject<TProfile>("rate_clones", "", 1, -0.5, 0.5, 0., 1.);
 
     double nStations   = fpParameters->GetNstationsActive();
-    fph_stations_hit   = MakeHisto<TProfile>("rate_stations_hit", "", 1, -0.5, 0.5, 0., nStations);
-    fph_stations_point = MakeHisto<TProfile>("rate_stations_point", "", 1, -0.5, 0.5, 0., nStations);
+    fph_stations_hit   = MakeQaObject<TProfile>("rate_stations_hit", "", 1, -0.5, 0.5, 0., nStations);
+    fph_stations_point = MakeQaObject<TProfile>("rate_stations_point", "", 1, -0.5, 0.5, 0., nStations);
 
     fCounterMC     = 0;
     fCounterClones = 0;
@@ -144,9 +145,9 @@ void TrackTypeQa::Init()
     fph_eff_txMC->SetTitle("Efficiency vs. MC slope along x-axis;t_{x}^{MC};#epsilon_{CA}");
     fph_eff_tyMC->SetTitle("Efficiency vs. MC slope along y-axis;t_{y}^{MC};#epsilon_{CA}");
 
-    fph_eff_pMC_yMC = MakeHisto<TProfile2D>("eff_pMC_yMC", "", kBinsY, kLoY, kUpY, kBinsP, kLoP, kUpP, 0., 1.);
+    fph_eff_pMC_yMC = MakeQaObject<TProfile2D>("eff_pMC_yMC", "", kBinsY, kLoY, kUpY, kBinsP, kLoP, kUpP, 0., 1.);
     fph_eff_thetaMC_phiMC =
-      MakeHisto<TProfile2D>("eff_theta_phi", "", kBinsPHI, kLoPHI, kUpPHI, kBinsTHETA, kLoTHETA, kUpTHETA, 0., 1.);
+      MakeQaObject<TProfile2D>("eff_theta_phi", "", kBinsPHI, kLoPHI, kUpPHI, kBinsTHETA, kLoTHETA, kUpTHETA, 0., 1.);
 
     fph_eff_pMC_yMC->SetTitle("Efficiency vs. MC total momentum and MC rapidity;y^{MC};#epsilon_{CA};p^{MC} [GeV/c]");
     fph_eff_thetaMC_phiMC->SetTitle(