diff --git a/macro/run/CMakeLists.txt b/macro/run/CMakeLists.txt
index 12bc7acfa170c6daf8cfc1cdd78274801791a206..5e3dec30610e0c0f42b4a708aadfcfecd27608c0 100644
--- a/macro/run/CMakeLists.txt
+++ b/macro/run/CMakeLists.txt
@@ -245,7 +245,7 @@ foreach(setup IN LISTS cbm_setup)
 
   # --- Test run_reco_offline_ts_eb_ideal
   # --- Event-by-event reconstruction from time-based simulation, with binary cbmreco_offline
-  # --- Real raw event builder
+  # --- Ideal raw event builder
   set(testname run_${sname}_reco_offline_ts_eb_ideal)
   set(binary ${CBMROOT_BINARY_DIR}/bin/cbmreco_offline.sh)
   set(rawfilename data/${sname}_ts.raw.root)
@@ -302,11 +302,12 @@ foreach(setup IN LISTS cbm_setup)
   add_test(${testname} ${MACRODIR}/run_qa.sh
     \"data/${sname}_coll\" \"data/${sname}_ts\"  \"data/${sname}_ts_eb_real\"
     \"data/${sname}_coll\" \"data/${sname}_qa\" \"${setup}\" -1
-    \"data/${sname}_sign\" \"data/${sname}_beam\" \"qa_config.cbm.yaml\")
+    \"data/${sname}_sign\" \"data/${sname}_beam\" \"qa_config.cbm.yaml\" \"Real\")
   set_tests_properties(${testname} PROPERTIES
     TIMEOUT ${timeOutTime}
+    FAIL_REGULAR_EXPRESSION "QA checks failed"
     FAIL_REGULAR_EXPRESSION "segmentation violation"
-    PASS_REGULAR_EXPRESSION "Macro finished successfully"
+    PASS_REGULAR_EXPRESSION "QA checks passed;Macro finished successfully"
     FIXTURES_REQUIRED "fixt_tra_coll_${setup};fixt_digi_ts_${setup};fixt_reco_ts_eb_real_${setup}"
     FIXTURES_SETUP fixt_qa_${setup}
     RESOURCE_LOCK collParDb_${setup}
diff --git a/macro/run/run_qa.C b/macro/run/run_qa.C
index befadd502f9d0b6666fe559f7978b3deefd220e1..a34d1526904911c82ac164b565f72243aac832cd 100644
--- a/macro/run/run_qa.C
+++ b/macro/run/run_qa.C
@@ -236,7 +236,7 @@ void run_qa(TString dataTraColl,
     qaManager->AddTask(matchTask);
   }
   // ----- MUCH QA  ---------------------------------
-  if (CbmSetup::Instance()->IsActive(ECbmModuleId::kMuch)) {
+  if (bUseMuch) {
     qaManager->AddTask(new CbmMuchTransportQa());
     qaManager->AddTask(new CbmMuchDigitizerQa());
     CbmMuchHitFinderQa* muchHitFinderQa = new CbmMuchHitFinderQa();
@@ -249,7 +249,7 @@ void run_qa(TString dataTraColl,
   }
 
   // ----- TRD QA  ---------------------------------
-  if (CbmSetup::Instance()->IsActive(ECbmModuleId::kTrd)) {
+  if (bUseTrd) {
     qaManager->AddTask(new CbmTrdMCQa());
     //run->AddTask(new CbmTrdHitRateQa());  //opens lots of windows
     //run->AddTask(new CbmTrdDigitizerPRFQa()); //works put currently doesn't do anything
@@ -269,15 +269,22 @@ void run_qa(TString dataTraColl,
   // ------------------------------------------------------------------------
 
   // ----- TOF QA  ----------------------------------------------------------
-  if (CbmSetup::Instance()->IsActive(ECbmModuleId::kTof)) {
+  if (bUseTof) {
     auto* pCaInputQaTof = new CbmCaInputQaTof(verbose, bUseMC);
     pCaInputQaTof->SetEfficiencyThrsh(0.5, 0, 100);
     qaManager->AddTask(pCaInputQaTof);
   }
   // ------------------------------------------------------------------------
 
+  // ----- MVD QA  ----------------------------------------------------------
+  if (bUseMvd && !sEvBuildRaw.EqualTo("Real", TString::ECaseCompare::kIgnoreCase)) {
+    auto* pCaInputQaMvd = new CbmCaInputQaMvd(verbose, bUseMC);
+    qaManager->AddTask(pCaInputQaMvd);
+  }
+  // ------------------------------------------------------------------------
+
   // ----- STS QA  ----------------------------------------------------------
-  if (CbmSetup::Instance()->IsActive(ECbmModuleId::kSts)) {
+  if (bUseSts) {
     auto* pCaInputQaSts = new CbmCaInputQaSts(verbose, bUseMC);
     qaManager->AddTask(pCaInputQaSts);
   }
@@ -291,7 +298,7 @@ void run_qa(TString dataTraColl,
   // ----- Tracking QA ------------------------------------------------------
   // KF is currently needed to access magnetic field. In future we will
   // delegate track fit routines to CbmKF as well.
-  qaManager->AddTask(new CbmKF());
+  qaManager->AddTask(new CbmKF());  // TODO: Needed?
 
   TString caParFile = recFile;
   caParFile.ReplaceAll(".root", ".L1Parameters.dat");
@@ -300,7 +307,11 @@ void run_qa(TString dataTraColl,
   pCaOutputQa->SetProcessFullTs(!bEventBasedReco);
   pCaOutputQa->SetStsTrackingMode();
   pCaOutputQa->ReadParameters(caParFile.Data());
-  pCaOutputQa->SetUseMvd(bUseMvd);
+  if (configName.Length() != 0) {
+    pCaOutputQa->SetConfigName(configName);
+  }
+  // TODO: Provide detector selection interface from the L1Parameters
+  pCaOutputQa->SetUseMvd(!(sEvBuildRaw.EqualTo("Real", TString::ECaseCompare::kIgnoreCase)) ? bUseMvd : false);
   pCaOutputQa->SetUseSts(bUseSts);
   //pCaOutputQa->SetUseMuch(bUseMuch);
   //pCaOutputQa->SetUseTrd(bUseTrd);
diff --git a/reco/L1/qa/CbmCaInputQaBase.cxx b/reco/L1/qa/CbmCaInputQaBase.cxx
index 470172749c3066dc4f20c9a9641af3af984b597a..a6802c860a444768354988cb4d0d732134fec509 100644
--- a/reco/L1/qa/CbmCaInputQaBase.cxx
+++ b/reco/L1/qa/CbmCaInputQaBase.cxx
@@ -234,6 +234,9 @@ void CbmCaInputQaBase<DetID>::Check()
       LOG(info) << '\n' << pPullsTable->ToString(3);
     }
   }  // McUsed
+
+  // Print out monitor
+  LOG(info) << fMonitor.ToString();
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -335,6 +338,9 @@ void CbmCaInputQaBase<DetID>::FillHistograms()
       }  // Skip Bmon hits
     }
 
+    fMonitor.IncrementCounter(EMonitorKey::kHit);
+    fMonitor.IncrementCounter(EMonitorKey::kHitAccepted);
+
     // *************************
     // ** Reconstructed hit QA
 
@@ -608,16 +614,20 @@ void CbmCaInputQaBase<DetID>::FillHistograms()
       for (int iP = 0; iP < nPoints; ++iP) {
         fHitQaData.Reset();
         fHitQaData.SetPointID(iP, iEvent, iFile);
+        fMonitor.IncrementCounter(EMonitorKey::kMcPoint);
 
         const auto* pMCPoint = dynamic_cast<const Point_t*>(fpMCPoints->Get(iFile, iEvent, iP));
         LOG_IF(fatal, !pMCPoint) << fName << ": MC point does not exist for iFile = " << iFile
                                  << ", iEvent = " << iEvent << ", iP = " << iP;
 
         int address = pMCPoint->GetDetectorID();
-        int iSt     = fpDetInterface->GetTrackingStationIndex(address);
-        LOG_IF(fatal, iSt < 0 || iSt >= nSt)
-          << fName << ": MC point for FEI = " << iFile << ", " << iEvent << ", " << iP << " and address " << address
-          << " has wrong station index: iSt = " << iSt;
+        int iSt     = fpDetInterface->GetTrackingStationIndex(pMCPoint);
+        if (iSt < 0 || iSt >= nSt) {
+          LOG(error) << fName << ": MC point for FEI = " << iFile << ", " << iEvent << ", " << iP << " and address "
+                     << address << " has wrong station index: iSt = " << iSt;
+          fMonitor.IncrementCounter(EMonitorKey::kMcPointWrongStation);
+          continue;
+        }
 
         // NOTE: SZh 04.09.2023: Methods GetX(), GetY(), GetZ() for MVD, STS, MUCH, TRD and TOF always return
         //                       positions of track at entrance to the active volume.
@@ -773,6 +783,14 @@ InitStatus CbmCaInputQaBase<DetID>::InitDataBranches()
     }
   }
 
+  // Init monitor
+  fMonitor.SetName(Form("Monitor for %s", fName.Data()));
+  fMonitor.SetCounterName(EMonitorKey::kEvent, "N events");
+  fMonitor.SetCounterName(EMonitorKey::kHit, "N hits total");
+  fMonitor.SetCounterName(EMonitorKey::kHitAccepted, "N hits accepted");
+  fMonitor.SetCounterName(EMonitorKey::kMcPoint, "N MC points total");
+  fMonitor.SetCounterName(EMonitorKey::kMcPointWrongStation, "N MC points total");
+  fMonitor.SetRatioKeys({EMonitorKey::kEvent});
 
   return kSUCCESS;
 }
diff --git a/reco/L1/qa/CbmCaInputQaBase.h b/reco/L1/qa/CbmCaInputQaBase.h
index c91a030e32a7ab6867f8768ac464a7f4bc36a364..9f70ed3fcf9d9729559fc91abfbab79aed541140 100644
--- a/reco/L1/qa/CbmCaInputQaBase.h
+++ b/reco/L1/qa/CbmCaInputQaBase.h
@@ -10,10 +10,12 @@
 
 #pragma once
 
+#include "CaMonitor.h"
 #include "CbmCaHitQaData.h"
 #include "CbmCaInputQaBase.h"
 #include "CbmL1DetectorID.h"
 #include "CbmMCDataManager.h"
+#include "CbmPixelHit.h"
 #include "CbmQaTask.h"
 #include "TMath.h"
 
@@ -40,6 +42,7 @@ class TProfile2D;
 namespace
 {
   using cbm::algo::ca::EDetectorID;
+  using cbm::algo::ca::Monitor;
 }
 
 /// A QA-task class, which provides assurance of MuCh hits and geometry
@@ -143,6 +146,9 @@ class CbmCaInputQaBase : public CbmQaTask {
   /// @return true when selected
   bool IsTrackSelected(const CbmMCTrack* track, const Point_t* point) const;
 
+  /// @brief Checks, if the hit is acceptable (has reasonable parameters)
+  bool IsHitAcceptable(const CbmPixelHit* pHit) const;
+
   /// @struct ResidualFitResult
   /// @brief  Stores fit residuals result
   struct ResidualFitResult {
@@ -151,6 +157,20 @@ class CbmCaInputQaBase : public CbmQaTask {
     double hi   = 0;  ///< higher limit for the mean
   };
 
+  /// @enum EMonitorKey
+  /// @brief QA monitor counters
+  enum class EMonitorKey
+  {
+    kEvent,
+    kHit,
+    kHitAccepted,
+    kMcPoint,
+    kMcPointWrongStation,
+    kEND
+  };
+
+  cbm::algo::ca::Monitor<EMonitorKey> fMonitor{};
+
   // ******************
   // **  Parameters  **
   // ******************
diff --git a/reco/L1/qa/CbmCaInputQaMvd.cxx b/reco/L1/qa/CbmCaInputQaMvd.cxx
index a8016b3c7a74fb548977f3888c4c8f7a12328333..bbf8e2ecafd5a551a74cb6e85a2010d1ed09d938 100644
--- a/reco/L1/qa/CbmCaInputQaMvd.cxx
+++ b/reco/L1/qa/CbmCaInputQaMvd.cxx
@@ -34,17 +34,17 @@ void CbmCaInputQaMvd::DefineParameters()
     range[1] = max;
   };
   // Hit errors
-  SetRange(fRHitDx, 0.0000, 5.00);  // [cm]
-  SetRange(fRHitDy, 0.0000, 5.00);  // [cm]
-  SetRange(fRHitDu, 0.0000, 5.00);  // [cm]
-  SetRange(fRHitDv, 0.0000, 5.00);  // [cm]
-  SetRange(fRHitDt, 0.0000, 0.15);  // [ns]
+  SetRange(fRHitDx, -0.005, 0.005);  // [cm]
+  SetRange(fRHitDy, -0.005, 0.005);  // [cm]
+  SetRange(fRHitDu, -0.005, 0.005);  // [cm]
+  SetRange(fRHitDv, -0.005, 0.005);  // [cm]
+  SetRange(fRHitDt, -10., 10.);      // [ns]
   // Residuals
-  SetRange(fRResX, -2.00, 2.00);
-  SetRange(fRResY, -4.00, 4.00);
-  SetRange(fRResU, -2.00, 2.00);
-  SetRange(fRResV, -4.00, 4.00);
-  SetRange(fRResT, -0.50, 0.50);
+  SetRange(fRResX, -0.004, 0.004);
+  SetRange(fRResY, -0.004, 0.004);
+  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]