From 024a19d91230dbcdcb8f51ca95f19567cef74d02 Mon Sep 17 00:00:00 2001
From: "s.zharko@gsi.de" <s.zharko@gsi.de>
Date: Tue, 28 May 2024 16:39:00 +0200
Subject: [PATCH] Offline QA: specific configuration of the QA task

The commit introduces the possibility of the specific QA task configuration withing the QA-config yaml file.
In the yaml-file, the configuration should be defined under qa/<task name>/specific node. On the task side
the configuration is represented with a plain structure (Config), which can be defined using the function
std::optional<Config> CbmQaTask::ReadSpecificConfig<Config>() in the task initialization function (for
expample see the CbmCaInputQaBase class implementation).

The specific configuration feature is optional and can rely on the default-initialized Config structure, so the "specific" branch
of the QA-configuration file is not mandatory.
---
 core/qa/CbmQaIO.h                             | 19 ++++-
 macro/mcbm/mcbm_qa.C                          | 17 +---
 macro/qa/configs/qa_tasks_config_mcbm.yaml    |  6 ++
 ...ks_config_mcbm_beam_2022_05_23_nickel.yaml | 29 +++++++
 macro/run/run_qa.C                            | 22 ++---
 reco/L1/qa/CbmCaInputQaBase.cxx               | 17 ++--
 reco/L1/qa/CbmCaInputQaBase.h                 | 83 +++++++++----------
 reco/L1/qa/CbmCaInputQaMuch.cxx               | 12 ---
 reco/L1/qa/CbmCaInputQaMvd.cxx                | 12 ---
 reco/L1/qa/CbmCaInputQaSts.cxx                | 12 ---
 reco/L1/qa/CbmCaInputQaTof.cxx                | 12 ---
 reco/L1/qa/CbmCaInputQaTrd.cxx                | 12 ---
 reco/qa/CMakeLists.txt                        |  2 +
 13 files changed, 112 insertions(+), 143 deletions(-)

diff --git a/core/qa/CbmQaIO.h b/core/qa/CbmQaIO.h
index 146df13b95..274fd67191 100644
--- a/core/qa/CbmQaIO.h
+++ b/core/qa/CbmQaIO.h
@@ -26,8 +26,11 @@
 #include "TProfile3D.h"
 #include "TROOT.h"
 #include "TString.h"
+#include "yaml/Property.h"
+#include "yaml/Yaml.h"
 
 #include <limits>
+#include <optional>
 #include <type_traits>
 #include <vector>
 
@@ -116,8 +119,20 @@ class CbmQaIO {
   template<typename T>
   void CheckProperty(T&& property, const char* name) const;
 
-  /// \brief Compares the selected objects with default, if the default file is provided
-
+  /// \brief Reads the specific configuration structure from the YAML node
+  /// \tparam Config  Type of the configuration class
+  ///
+  /// The function is to be called in the user-defined class method InitDataBranches
+  template<class Config>
+  std::optional<Config> ReadSpecificConfig() const
+  {
+    std::optional<Config> res = std::nullopt;
+    const auto& node          = fConfigNode["specific"];
+    if (node) {
+      res = std::make_optional(cbm::algo::yaml::Read<Config>(node));
+    }
+    return res;
+  }
 
   /// \brief Applies properties on the histogram created with the MakeQaObject function
   /// \param pHist  Pointer to the histogram
diff --git a/macro/mcbm/mcbm_qa.C b/macro/mcbm/mcbm_qa.C
index 703931640d..2bbe5bd9ce 100644
--- a/macro/mcbm/mcbm_qa.C
+++ b/macro/mcbm/mcbm_qa.C
@@ -270,9 +270,7 @@ void mcbm_qa(Int_t nEvents = 0,
   // ----- STS QA -----------------------------------------------------------
   if (bUseSts) {
     // CA Input QA
-    auto* pCaInputSts = new CbmCaInputQaSts(verbose, bUseMC);
-    pCaInputSts->SetEfficiencyThrsh(0.5, 0, 100);
-    qaManager->AddTask(pCaInputSts);
+    qaManager->AddTask(new CbmCaInputQaSts(verbose, bUseMC));
   }
   // ------------------------------------------------------------------------
 
@@ -288,28 +286,21 @@ void mcbm_qa(Int_t nEvents = 0,
     run->AddTask(muchHitFinderQa);
 
     // CA Input QA
-    auto* pCaInputMuch = new CbmCaInputQaMuch(verbose, bUseMC);
-    pCaInputMuch->SetEfficiencyThrsh(0.5, 0, 100);
-    qaManager->AddTask(pCaInputMuch);
+    qaManager->AddTask(new CbmCaInputQaMuch(verbose, bUseMC));
   }
   // ------------------------------------------------------------------------
 
   // ----- TRD QA -----------------------------------------------------------
   if (bUseTrd) {
     // CA Input QA
-    auto* pCaInputTrd = new CbmCaInputQaTrd(verbose, bUseMC);
-    pCaInputTrd->SetEfficiencyThrsh(0.5, 0, 100);
-    pCaInputTrd->SetPullMeanDeviationThrsh(0.3);
-    qaManager->AddTask(pCaInputTrd);
+    qaManager->AddTask(new CbmCaInputQaTrd(verbose, bUseMC));
   }
   // ------------------------------------------------------------------------
 
   // ----- TOF QA -----------------------------------------------------------
   if (bUseTof) {
     // CA Input QA
-    auto* pCaInputTof = new CbmCaInputQaTof(verbose, bUseMC);
-    pCaInputTof->SetEfficiencyThrsh(0.5, 0, 100);
-    qaManager->AddTask(pCaInputTof);
+    qaManager->AddTask(new CbmCaInputQaTof(verbose, bUseMC));
   }
   // ------------------------------------------------------------------------
 
diff --git a/macro/qa/configs/qa_tasks_config_mcbm.yaml b/macro/qa/configs/qa_tasks_config_mcbm.yaml
index 01cac78248..6db450accb 100644
--- a/macro/qa/configs/qa_tasks_config_mcbm.yaml
+++ b/macro/qa/configs/qa_tasks_config_mcbm.yaml
@@ -18,6 +18,12 @@ qa:
       pull_t_station_%d: true
       pull_station_%_pull_x: false
   CbmCaInputQaSts:
+    # Specific configuration, provided in the Config structure of the QA-task
+    specific:
+      PullMeanThrsh: 0.2
+      PullWidthThrsh: 2.0
+      EffThrsh: 0.4
+      MaxDiffZStHit: 1.0
     check_list:
       station_position_ordering: true
       station_position_hit_delta_z: false
diff --git a/macro/qa/configs/qa_tasks_config_mcbm_beam_2022_05_23_nickel.yaml b/macro/qa/configs/qa_tasks_config_mcbm_beam_2022_05_23_nickel.yaml
index dbe5a60995..3ab97fa2ed 100644
--- a/macro/qa/configs/qa_tasks_config_mcbm_beam_2022_05_23_nickel.yaml
+++ b/macro/qa/configs/qa_tasks_config_mcbm_beam_2022_05_23_nickel.yaml
@@ -8,6 +8,9 @@
 ## @author Sergei Zharko <s.zharko@gsi.de>
 
 qa:
+  #
+  #  CA INPUT QA: MVD
+  #
   CbmCaInputQaMvd:
     check_list:
       station_position_ordering: true
@@ -17,7 +20,20 @@ qa:
       pull_y_station_%d: true
       pull_t_station_%d: true
       pull_station_%_pull_x: false
+  #
+  #  CA INPUT QA: STS
+  #
   CbmCaInputQaSts:
+    # Specific configuration, provided in the Config structure of the QA-task
+    specific:
+      McTrackCuts:
+        MinMom: 0.1 # [GeV/c]
+        MaxTheta: 60. # [grad]
+        IsPrimary: true
+      PullMeanThrsh: 0.2
+      PullWidthThrsh: 2.0
+      EffThrsh: 0.5
+      MaxDiffZStHit: 1.0
     check_list:
       station_position_ordering: true
       station_position_hit_delta_z: false
@@ -38,6 +54,9 @@ qa:
         ratio: { use: 0, min: 0.5, max: 1.5 }
         chi2Test: {use: 1, chi2_ndf_max: 10., stat_opt: "UU" }
         canvas: {comp: true, ratio: false, diff: true}
+  #
+  #  CA INPUT QA: MuCh
+  #
   CbmCaInputQaMuch:
     check_list:
       station_position_ordering: true
@@ -50,6 +69,9 @@ qa:
       pull_t_station_%d: true
       pull_t_station_1: false
       pull_t_station_3: false
+  #
+  #  CA INPUT QA: TRD
+  #
   CbmCaInputQaTrd:
     histograms:
       #xy_station0: 
@@ -70,6 +92,9 @@ qa:
       pull_x_station_%d: true
       pull_y_station_%d: true
       pull_t_station_%d: true
+  #
+  #  CA INPUT QA: TOF
+  #
   CbmCaInputQaTof:
     check_list:
       station_position_ordering: true
@@ -80,6 +105,9 @@ qa:
       pull_t_station_%d: false
       pull_t_station_3: false
   CbmCaOutputQa:
+    specific:
+      testA: 42
+      testB: "hello"
     check_histograms:
       - name: "all/eff_pMC"
         point_to_point: { use: 1 }
@@ -96,5 +124,6 @@ qa:
         ratio: { use: 0, min: 0.5, max: 1.5 }
         chi2Test: {use: 1, chi2_ndf_max: 10., stat_opt: "UU" }
         canvas: {comp: true, ratio: true, diff: true}
+  CbmRecoQa:
 
 ...
diff --git a/macro/run/run_qa.C b/macro/run/run_qa.C
index 69d2fd2b6f..ad0442d387 100644
--- a/macro/run/run_qa.C
+++ b/macro/run/run_qa.C
@@ -242,10 +242,7 @@ void run_qa(TString dataTraColl,
     CbmMuchHitFinderQa* muchHitFinderQa = new CbmMuchHitFinderQa();
     muchHitFinderQa->SetGeoFileName(muchParFile);
     qaManager->AddTask(muchHitFinderQa);
-
-    auto* pCaInputQaMuch = new CbmCaInputQaMuch(verbose, bUseMC);
-    pCaInputQaMuch->SetEfficiencyThrsh(0.5, 0, 100);
-    qaManager->AddTask(pCaInputQaMuch);
+    qaManager->AddTask(new CbmCaInputQaMuch(verbose, bUseMC));
   }
 
   // ----- TRD QA  ---------------------------------
@@ -262,37 +259,30 @@ void run_qa(TString dataTraColl,
     }
     qaManager->AddTask(trdHitProducerQa);
     qaManager->AddTask(new CbmTrdCalibTracker());
-    auto* pCaInputQaTrd = new CbmCaInputQaTrd(verbose, bUseMC);
-    pCaInputQaTrd->SetEfficiencyThrsh(0.5, 0, 100);
-    qaManager->AddTask(pCaInputQaTrd);
+    qaManager->AddTask(new CbmCaInputQaTrd(verbose, bUseMC));
   }
   // ------------------------------------------------------------------------
 
   // ----- TOF QA  ----------------------------------------------------------
   if (bUseTof) {
-    auto* pCaInputQaTof = new CbmCaInputQaTof(verbose, bUseMC);
-    pCaInputQaTof->SetEfficiencyThrsh(0.5, 0, 100);
-    qaManager->AddTask(pCaInputQaTof);
+    qaManager->AddTask(new CbmCaInputQaTof(verbose, bUseMC));
   }
   // ------------------------------------------------------------------------
 
   // ----- MVD QA  ----------------------------------------------------------
   if (bUseMvd && !sEvBuildRaw.EqualTo("Real", TString::ECaseCompare::kIgnoreCase)) {
-    auto* pCaInputQaMvd = new CbmCaInputQaMvd(verbose, bUseMC);
-    qaManager->AddTask(pCaInputQaMvd);
+    qaManager->AddTask(new CbmCaInputQaMvd(verbose, bUseMC));
   }
   // ------------------------------------------------------------------------
 
   // ----- STS QA  ----------------------------------------------------------
   if (bUseSts) {
-    auto* pCaInputQaSts = new CbmCaInputQaSts(verbose, bUseMC);
-    qaManager->AddTask(pCaInputQaSts);
+    qaManager->AddTask(new CbmCaInputQaSts(verbose, bUseMC));
   }
   // ------------------------------------------------------------------------
 
   // ----- Event builder QA  ---------------------------------
-  CbmBuildEventsQa* evBuildQA = new CbmBuildEventsQa();
-  qaManager->AddTask(evBuildQA);
+  qaManager->AddTask(new CbmBuildEventsQa());
   // ------------------------------------------------------------------------
 
   // ----- Tracking QA ------------------------------------------------------
diff --git a/reco/L1/qa/CbmCaInputQaBase.cxx b/reco/L1/qa/CbmCaInputQaBase.cxx
index 65605d9dd4..916f819586 100644
--- a/reco/L1/qa/CbmCaInputQaBase.cxx
+++ b/reco/L1/qa/CbmCaInputQaBase.cxx
@@ -140,8 +140,8 @@ void CbmCaInputQaBase<DetID>::Check()
         res = false;
         continue;
       }
-      int iBinMin = fvph_hit_station_delta_z[iSt]->FindBin(-fMaxDiffZStHit);
-      int iBinMax = fvph_hit_station_delta_z[iSt]->FindBin(+fMaxDiffZStHit);
+      int iBinMin = fvph_hit_station_delta_z[iSt]->FindBin(-fConfig.fMaxDiffZStHit);
+      int iBinMax = fvph_hit_station_delta_z[iSt]->FindBin(+fConfig.fMaxDiffZStHit);
 
       if (fvph_hit_station_delta_z[iSt]->Integral(iBinMin, iBinMax) < nHits) {
         LOG_IF(error, fVerbose > 0) << fName << ": station " << iSt << " has mismatches in hit z-positions";
@@ -173,7 +173,7 @@ void CbmCaInputQaBase<DetID>::Check()
         auto eff = fvph_reco_eff[iSt]->GetMean();
         pEffTable->SetRowName(iSt, Form("station %d", iSt));
         pEffTable->SetCell(iSt, 0, eff);
-        bool res = CheckRange("Hit finder efficiency in station " + std::to_string(iSt), eff, fEffThrsh, 1.000);
+        bool res = CheckRange("Hit finder efficiency in station " + std::to_string(iSt), eff, fConfig.fEffThrsh, 1.000);
         StoreCheckResult(Form("hit_efficiency_station_%d", iSt), res);
       }
       LOG(info) << '\n' << pEffTable->ToString(3);
@@ -721,6 +721,11 @@ void CbmCaInputQaBase<DetID>::FillHistograms()
 template<ca::EDetectorID DetID>
 InitStatus CbmCaInputQaBase<DetID>::InitDataBranches()
 {
+  // Config initialization
+  fConfig = ReadSpecificConfig<CbmCaInputQaBase<DetID>::Config>().value_or(Config{});
+
+  LOG(info) << "\n!!\n!!\n!! TEST: " << fConfig.fEffThrsh << "\n!!\n!!\n!!";
+
   LOG_IF(fatal, !fpDetInterface) << "\033[1;31m" << fName << ": tracking detector interface is undefined\033[0m";
 
   // FairRootManager
@@ -1497,7 +1502,7 @@ bool CbmCaInputQaBase<DetID>::IsTrackSelected(const CbmMCTrack* track, const Poi
 {
   assert(point);
 
-  if (fTrackSelectionPrimary && track->GetMotherId() >= 0) {
+  if (fConfig.fMcTrackCuts.fbPrimary && track->GetMotherId() >= 0) {
     return false;
   }
 
@@ -1520,11 +1525,11 @@ bool CbmCaInputQaBase<DetID>::IsTrackSelected(const CbmMCTrack* track, const Poi
     return false;
   }
 
-  if (p < fTrackSelectionMomentum) {
+  if (p < fConfig.fMcTrackCuts.fMinMom) {
     return false;
   }
 
-  if (TMath::ATan2(sqrt(px * px + py * py), pz) * TMath::RadToDeg() > fTrackSelectionAngle) {
+  if (TMath::ATan2(sqrt(px * px + py * py), pz) * TMath::RadToDeg() > fConfig.fMcTrackCuts.fMaxTheta) {
     return false;
   }
 
diff --git a/reco/L1/qa/CbmCaInputQaBase.h b/reco/L1/qa/CbmCaInputQaBase.h
index 610571c0d6..bf13aba102 100644
--- a/reco/L1/qa/CbmCaInputQaBase.h
+++ b/reco/L1/qa/CbmCaInputQaBase.h
@@ -43,6 +43,7 @@ namespace
 {
   using cbm::algo::ca::EDetectorID;
   using cbm::algo::ca::Monitor;
+  using cbm::algo::yaml::Property;
 }
 
 /// A QA-task class, which provides assurance of MuCh hits and geometry
@@ -52,6 +53,40 @@ class CbmCaInputQaBase : public CbmQaTask {
   using Point_t = cbm::ca::PointTypes_t::at<DetID>;  ///< Point type for detector ID
   using Hit_t   = cbm::ca::HitTypes_t::at<DetID>;    ///< Hit type for detector ID
 
+  /// \struct Config
+  /// \brief  Specific configuration for the QA-task
+  struct Config {
+    /// \struct McTrackCut
+    /// \brief  MC track selection criteria
+    struct McTrackCuts {
+      double fMinMom   = 0.1;   ///< Track momentum on the exit of the station [GeV/c]
+      double fMaxTheta = 60.;   ///< Track theta on the exit of the station [grad]
+      bool fbPrimary   = true;  ///< Must the track come from the primary vertex
+      /* clang-format off */
+      CBM_YAML_PROPERTIES(
+        Property(&McTrackCuts::fMinMom, "MinMom", "Minimal momentum at the exit of the station [GeV/c]"),
+        Property(&McTrackCuts::fMaxTheta, "MaxTheta", "Maximal theta at the exit of the station [grad]"),
+        Property(&McTrackCuts::fbPrimary, "IsPrimary", "Is track primary")
+      );
+      /* clang-format on */
+    };
+
+    McTrackCuts fMcTrackCuts;      ///< MC-track selection cuts
+    double fPullMeanThrsh  = 0.1;  ///< Maximum allowed deviation of pull mean from zero
+    double fPullWidthThrsh = 2.0;  ///< Maximum allowed deviation of pull width from unity
+    double fEffThrsh       = 0.5;  ///< Threshold for hit efficiency in the selected range
+    double fMaxDiffZStHit  = 1.0;  ///< Maximum allowed difference between z-position of hit and station [cm]
+    /* clang-format off */
+    CBM_YAML_PROPERTIES(
+      Property(&Config::fMcTrackCuts, "McTrackCuts", "MC track cuts"),
+      Property(&Config::fPullMeanThrsh, "PullMeanThrsh", "Pull mean threshold"),
+      Property(&Config::fPullWidthThrsh, "PullWidthThrsh", "Pull width threshold"),
+      Property(&Config::fEffThrsh, "EffThrsh", "Efficiency threshold"),
+      Property(&Config::fMaxDiffZStHit, "MaxDiffZStHit", "Max difference between station and hit z")
+    );
+    /* clang-format on */
+  };
+
  public:
   /// @brief Constructor from parameters
   /// @param  name      Name of the task
@@ -62,40 +97,6 @@ class CbmCaInputQaBase : public CbmQaTask {
   /// @brief Destructor
   virtual ~CbmCaInputQaBase() = default;
 
-
-  /// @brief Sets maximum allowed deviation of pull distribution mean from 0
-  /// @param devThrsh  Deviation threshold (- devThrsh, + devThrsh)
-  void SetPullMeanDeviationThrsh(double devThrsh) { fPullMeanThrsh = devThrsh; }
-
-  /// @brief Sets maximum allowed deviation of pull distribution width from unity
-  /// @param devThrsh  Deviation threshold (1 - devThrsh, 1 + devThrsh)
-  void SetPullWidthDeviationThrsh(double devThrsh) { fPullWidthThrsh = devThrsh; }
-
-  /// @brief Sets maximum allowed deviation of residual mean from zero (-devThrsh * rms, +devThrsh * rms)
-  /// @param devThrsh  Deviation threshold in sigmas of residual distribution
-  void SetResidualMeanDeviationThrsh(double devThrsh) { fResMeanThrsh = devThrsh; }
-
-  /// @brief Sets hit efficiency analysis parameters: efficiency fit range
-  /// @param thrsh    Threshold for efficiency in a given range
-  /// @param loRange  Lower bound of the integration range
-  /// @param upRange  Upper limit of the integration range
-  void SetEfficiencyThrsh(double thrsh, double loRange, double upRange)
-  {
-    LOG(info) << "Call: SetEfficiencyThrsh";
-    fEffThrsh    = thrsh;
-    fEffRange[0] = loRange;
-    fEffRange[1] = upRange;
-    LOG(info) << fEffRange[0] << ' ' << fEffRange[1];
-  }
-
-  /// @brief Sets maximum allowed difference between z-position of hit and station
-  /// @param  dz  Difference between station and hit position z components [cm]
-  void SetMaxDiffZStationHit(double dz) { fMaxDiffZStHit = dz; }
-
-  /// @brief Sets lower momentum threshold
-  /// @param mom Minimum absolute value of momentum
-  void SetMinMomentum(double mom) { fMinMomentum = mom; }
-
  protected:
   // ********************************************
   // ** Virtual method override from CbmQaTask **
@@ -133,7 +134,7 @@ class CbmCaInputQaBase : public CbmQaTask {
   /// @return  False, if variable exits the range
   bool CheckRangePull(TH1* h)
   {
-    return CbmQaTask::CheckRange(h, fPullMeanThrsh, 1. - fPullWidthThrsh, 1. + fPullWidthThrsh);
+    return CbmQaTask::CheckRange(h, fConfig.fPullMeanThrsh, 1. - fConfig.fPullWidthThrsh, 1. + fConfig.fPullWidthThrsh);
   }
 
   /// @brief Returns a pointer to current hit QA data object
@@ -179,19 +180,9 @@ class CbmCaInputQaBase : public CbmQaTask {
 
   //TODO: remove check of residuals
   // ----- QA constants (thresholds, ranges etc.)
-  double fResMeanThrsh   = kNAN;  ///< Maximum allowed deviation of residual mean from zero [sigma]
-  double fPullMeanThrsh  = kNAN;  ///< Maximum allowed deviation of pull mean from zero
-  double fPullWidthThrsh = kNAN;  ///< Maximum allowed deviation of pull width from unity
-  double fEffThrsh       = kNAN;  ///< Threshold for hit efficiency in the selected range
-  double fMaxDiffZStHit  = kNAN;  ///< Maximum allowed difference between z-position of hit and station [cm]
-  double fMinMomentum    = kNAN;  ///< Minimum momentum of particle [GeV/c]
-
-  std::array<double, 2> fEffRange = {kNAN, kNAN};  ///< Range for hit efficiency approximation
+  Config fConfig;  ///< Task specific configuration parameters
 
   // ----- Track selection for efficiencies and pulls
-  bool fTrackSelectionPrimary    = true;  ///< must the track come from the primary vertex
-  double fTrackSelectionMomentum = kNAN;  ///< track momentum GeV when it exits the tracking station
-  double fTrackSelectionAngle    = kNAN;  ///< track incl. angle [grad] when it exits the station
 
   // ----- Histogram binning parameters
   int fNbins  = 200;  ///< General number of bins
diff --git a/reco/L1/qa/CbmCaInputQaMuch.cxx b/reco/L1/qa/CbmCaInputQaMuch.cxx
index a7a6e7dcbe..799d256a83 100644
--- a/reco/L1/qa/CbmCaInputQaMuch.cxx
+++ b/reco/L1/qa/CbmCaInputQaMuch.cxx
@@ -46,18 +46,6 @@ void CbmCaInputQaMuch::DefineParameters()
   SetRange(fRResV, -4.00, 4.00);
   SetRange(fRResT, -5.00, 5.00);
   SetRange(fRangeDzHitPoint, -50., 50.);
-  // QA result selection criteria
-  SetRange(fEffRange, 10.0, 30.0);  ///< Range for hit efficiency approximation
-  fResMeanThrsh   = 0.50;           ///< Maximum allowed deviation of residual mean from zero [sigma]
-  fPullMeanThrsh  = 0.10;           ///< Maximum allowed deviation of pull mean from zero
-  fPullWidthThrsh = 2.00;           ///< Maximum allowed deviation of pull width from unity
-  fEffThrsh       = 0.50;           ///< Threshold for hit efficiency in the selected range
-  fMaxDiffZStHit  = 1.00;           ///< Maximum allowed difference between z-position of hit and station [cm]
-  fMinMomentum    = 0.05;           ///< Minimum momentum of particle [GeV/c]
-  // Track selection criteria
-  fTrackSelectionPrimary  = true;  ///< must the track come from the primary vertex
-  fTrackSelectionMomentum = 0.1;   ///< track momentum GeV when it exits the tracking station
-  fTrackSelectionAngle    = 60.;   ///< track incl. angle [grad] when it exits the station
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
diff --git a/reco/L1/qa/CbmCaInputQaMvd.cxx b/reco/L1/qa/CbmCaInputQaMvd.cxx
index bbf8e2ecaf..f54dcf53ae 100644
--- a/reco/L1/qa/CbmCaInputQaMvd.cxx
+++ b/reco/L1/qa/CbmCaInputQaMvd.cxx
@@ -45,18 +45,6 @@ void CbmCaInputQaMvd::DefineParameters()
   SetRange(fRResU, -0.004, 0.004);
   SetRange(fRResV, -0.004, 0.004);
   SetRange(fRResT, -5.0, 5.0);
-  // QA result selection criteria
-  SetRange(fEffRange, 10.0, 30.0);  ///< Range for hit efficiency approximation
-  fResMeanThrsh   = 0.50;           ///< Maximum allowed deviation of residual mean from zero [sigma]
-  fPullMeanThrsh  = 0.10;           ///< Maximum allowed deviation of pull mean from zero
-  fPullWidthThrsh = 2.00;           ///< Maximum allowed deviation of pull width from unity
-  fEffThrsh       = 0.50;           ///< Threshold for hit efficiency in the selected range
-  fMaxDiffZStHit  = 1.00;           ///< Maximum allowed difference between z-position of hit and station [cm]
-  fMinMomentum    = 0.05;           ///< Minimum momentum of particle [GeV/c]
-  // Track selection criteria
-  fTrackSelectionPrimary  = true;  ///< must the track come from the primary vertex
-  fTrackSelectionMomentum = 0.1;   ///< track momentum GeV when it exits the tracking station
-  fTrackSelectionAngle    = 60.;   ///< track incl. angle [grad] when it exits the station
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
diff --git a/reco/L1/qa/CbmCaInputQaSts.cxx b/reco/L1/qa/CbmCaInputQaSts.cxx
index 4dd3738fd5..e3f30e87c0 100644
--- a/reco/L1/qa/CbmCaInputQaSts.cxx
+++ b/reco/L1/qa/CbmCaInputQaSts.cxx
@@ -100,18 +100,6 @@ void CbmCaInputQaSts::DefineParameters()
   SetRange(fRResU, -0.02, 0.02);
   SetRange(fRResV, -0.02, 0.02);
   SetRange(fRResT, -25.0, 25.0);
-  // QA result selection criteria
-  SetRange(fEffRange, 0.0, 100.0);  ///< Range for hit efficiency approximation
-  fResMeanThrsh   = 0.50;           ///< Maximum allowed deviation of residual mean from zero [sigma]
-  fPullMeanThrsh  = 0.10;           ///< Maximum allowed deviation of pull mean from zero
-  fPullWidthThrsh = 2.00;           ///< Maximum allowed deviation of pull width from unity
-  fEffThrsh       = 0.50;           ///< Threshold for hit efficiency in the selected range
-  fMaxDiffZStHit  = 1.00;           ///< Maximum allowed difference between z-position of hit and station [cm]
-  fMinMomentum    = 0.05;           ///< Minimum momentum of particle [GeV/c]
-  // Track selection criteria
-  fTrackSelectionPrimary  = true;  ///< must the track come from the primary vertex
-  fTrackSelectionMomentum = 0.1;   ///< track momentum GeV when it exits the tracking station
-  fTrackSelectionAngle    = 60.;   ///< track incl. angle [grad] when it exits the station
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
diff --git a/reco/L1/qa/CbmCaInputQaTof.cxx b/reco/L1/qa/CbmCaInputQaTof.cxx
index 497e0d6f25..5df6df416c 100644
--- a/reco/L1/qa/CbmCaInputQaTof.cxx
+++ b/reco/L1/qa/CbmCaInputQaTof.cxx
@@ -74,18 +74,6 @@ void CbmCaInputQaTof::DefineParameters()
   SetRange(fRResU, -2.00, 2.00);
   SetRange(fRResV, -4.00, 4.00);
   SetRange(fRResT, -0.50, 0.50);
-  // QA result selection criteria
-  SetRange(fEffRange, 10.0, 30.0);  ///< Range for hit efficiency approximation
-  fResMeanThrsh   = 0.50;           ///< Maximum allowed deviation of residual mean from zero [sigma]
-  fPullMeanThrsh  = 0.10;           ///< Maximum allowed deviation of pull mean from zero
-  fPullWidthThrsh = 2.00;           ///< Maximum allowed deviation of pull width from unity
-  fEffThrsh       = 0.50;           ///< Threshold for hit efficiency in the selected range
-  fMaxDiffZStHit  = 1.00;           ///< Maximum allowed difference between z-position of hit and station [cm]
-  fMinMomentum    = 0.05;           ///< Minimum momentum of particle [GeV/c]
-  // Track selection criteria
-  fTrackSelectionPrimary  = true;  ///< must the track come from the primary vertex
-  fTrackSelectionMomentum = 0.1;   ///< track momentum GeV when it exits the tracking station
-  fTrackSelectionAngle    = 60.;   ///< track incl. angle [grad] when it exits the station
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
diff --git a/reco/L1/qa/CbmCaInputQaTrd.cxx b/reco/L1/qa/CbmCaInputQaTrd.cxx
index 57b3952d7e..4331295c3c 100644
--- a/reco/L1/qa/CbmCaInputQaTrd.cxx
+++ b/reco/L1/qa/CbmCaInputQaTrd.cxx
@@ -45,18 +45,6 @@ void CbmCaInputQaTrd::DefineParameters()
   SetRange(fRResU, -2.00, 2.00);
   SetRange(fRResV, -10.00, 10.00);
   SetRange(fRResT, -200.0, 200.0);
-  // QA result selection criteria
-  SetRange(fEffRange, 10.0, 30.0);  ///< Range for hit efficiency approximation
-  fResMeanThrsh   = 0.50;           ///< Maximum allowed deviation of residual mean from zero [sigma]
-  fPullMeanThrsh  = 0.10;           ///< Maximum allowed deviation of pull mean from zero
-  fPullWidthThrsh = 2.00;           ///< Maximum allowed deviation of pull width from unity
-  fEffThrsh       = 0.50;           ///< Threshold for hit efficiency in the selected range
-  fMaxDiffZStHit  = 1.00;           ///< Maximum allowed difference between z-position of hit and station [cm]
-  fMinMomentum    = 0.05;           ///< Minimum momentum of particle [GeV/c]
-  // Track selection criteria
-  fTrackSelectionPrimary  = true;  ///< must the track come from the primary vertex
-  fTrackSelectionMomentum = 0.1;   ///< track momentum GeV when it exits the tracking station
-  fTrackSelectionAngle    = 60.;   ///< track incl. angle [grad] when it exits the station
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
diff --git a/reco/qa/CMakeLists.txt b/reco/qa/CMakeLists.txt
index 85ce9991ce..be3074d80b 100644
--- a/reco/qa/CMakeLists.txt
+++ b/reco/qa/CMakeLists.txt
@@ -7,11 +7,13 @@ set(SRCS
   CbmRecoQa.cxx
   CbmTrackingTrdQa.cxx
   CbmRecoQaTask.cxx
+  CbmRecoModuleQa.cxx
   )
 
 set(LIBRARY_NAME CbmRecoQa)
 set(LINKDEF  RecoQaLinkDef.h)
 set(PUBLIC_DEPENDENCIES
+  Algo
   CbmBase
   CbmData
   FairRoot::Base
-- 
GitLab