diff --git a/algo/CMakeLists.txt b/algo/CMakeLists.txt
index 82f767e3bf236841a09e069d45d99814b5d0f8cf..5eff2e5606eb1168612012299dcf42894acace4f 100644
--- a/algo/CMakeLists.txt
+++ b/algo/CMakeLists.txt
@@ -159,6 +159,9 @@ set(SRCS
   qa/QaManager.cxx
   qa/hitfind/BmonHitfindQa.cxx
   qa/hitfind/BmonHitfindQaParameters.cxx
+  qa/trigger/V0TriggerQa.cxx
+  qa/hitfind/TofHitfindQa.cxx
+  qa/hitfind/TofHitfindQaParameters.cxx
   qa/unpack/StsDigiQa.cxx
   ca/TrackingSetup.cxx
   ca/TrackingChain.cxx
@@ -200,6 +203,7 @@ target_include_directories(Algo
          ${CMAKE_CURRENT_SOURCE_DIR}/qa
          ${CMAKE_CURRENT_SOURCE_DIR}/qa/unpack
          ${CMAKE_CURRENT_SOURCE_DIR}/qa/hitfind
+         ${CMAKE_CURRENT_SOURCE_DIR}/qa/trigger
          ${CMAKE_CURRENT_SOURCE_DIR}/kf
          ${CMAKE_CURRENT_SOURCE_DIR}/kf/core
          ${CMAKE_CURRENT_SOURCE_DIR}/kf/core/utils
@@ -275,6 +279,8 @@ if (NOT CBM_ONLINE_STANDALONE)
            ${CMAKE_CURRENT_SOURCE_DIR}/detectors
            ${CMAKE_CURRENT_SOURCE_DIR}/qa
            ${CMAKE_CURRENT_SOURCE_DIR}/qa/unpack
+           ${CMAKE_CURRENT_SOURCE_DIR}/qa/hitfind
+           ${CMAKE_CURRENT_SOURCE_DIR}/qa/trigger
            ${CMAKE_CURRENT_SOURCE_DIR}/kf
            ${CMAKE_CURRENT_SOURCE_DIR}/kf/core
            ${CMAKE_CURRENT_SOURCE_DIR}/kf/core/utils
diff --git a/algo/base/Definitions.h b/algo/base/Definitions.h
index b1ff4c9ccc8e804a33a67fe0ab40d81d74dd616e..c9cac7a917126b96499a3c8ede8824f1ee9bb5ca 100644
--- a/algo/base/Definitions.h
+++ b/algo/base/Definitions.h
@@ -79,6 +79,7 @@ namespace cbm::algo
     RecoFsd,
     Tracking,
     V0Finder,
+    V0Trigger,
   };
 
 }  // namespace cbm::algo
@@ -150,7 +151,8 @@ CBM_ENUM_DICT(cbm::algo::QaStep,
   {"RecoTof", cbm::algo::QaStep::RecoTof},
   {"RecoFsd", cbm::algo::QaStep::RecoFsd},
   {"Tracking", cbm::algo::QaStep::Tracking},
-  {"V0Finder", cbm::algo::QaStep::V0Finder}
+  {"V0Finder", cbm::algo::QaStep::V0Finder},
+  {"V0Trigger", cbm::algo::QaStep::V0Trigger}
 );
 
 #endif
diff --git a/algo/ca/qa/CaQa.cxx b/algo/ca/qa/CaQa.cxx
index 8d081862c78d399aca6ec01d0dda38e432517185..b921d16813e9bae3f93e871810e3ea04c4272400 100644
--- a/algo/ca/qa/CaQa.cxx
+++ b/algo/ca/qa/CaQa.cxx
@@ -216,6 +216,11 @@ void Qa::Init()
       auto sTitl      = "First vs. last station index;ID^{last}_{station};ID^{first}_{station}";
       fphTrkFstLstSta = MakeObj<H2D>(sName, sTitl, nBins, xMin, xMax, nBins, xMin, xMax);
     }
+    {
+      auto sName     = format("{}_track_origin", GetTaskName());
+      auto sTitl     = "Track origin;x [cm];y [cm]";
+      fphTrkOriginXY = MakeObj<H2D>(sName, sTitl, kOriginB, kOriginL, kOriginU, kOriginB, kOriginL, kOriginU);
+    }
     fphTrkNofHits = MakeObj<H1D>("n_hits", "Number of hits;N_{hit}", nBins, xMin, xMax);
   }
 
@@ -231,7 +236,7 @@ void Qa::Init()
           auto titl = format("{} hit occupancy in different stations in XY plane", setNm);
           auto canv = CanvasConfig(name, titl);
           for (int iSt = 0; iSt < nSt; ++iSt) {
-            auto pad = PadConfig();
+            auto pad = PadConfig(false, false, false, false, true);
             pad.RegisterHistogram(fvphHitOccupXY[iSt][hitSet], "colz");
             canv.AddPadConfig(pad);
           }
@@ -294,6 +299,11 @@ void Qa::Init()
         pad.RegisterHistogram(fphTrkFstLstSta, "colz");
         canv.AddPadConfig(pad);
       }
+      {
+        auto pad = PadConfig(true, true, false, false, false);
+        pad.RegisterHistogram(fphTrkOriginXY, "colz");
+        canv.AddPadConfig(pad);
+      }
       AddCanvasConfig(canv);
     }
   }
@@ -371,6 +381,7 @@ void Qa::Exec()
       // Other distributions
       fphTrkFstLstSta->Fill(fpInputData->GetHit(iLstHit).Station(), fpInputData->GetHit(iFstHit).Station());
       fphTrkNofHits->Fill(nHits);
+      fphTrkOriginXY->Fill(track.fParPV.X(), track.fParPV.Y());
       trkFirstHit += nHits;
     }
   }
diff --git a/algo/ca/qa/CaQa.h b/algo/ca/qa/CaQa.h
index 1c42b60562f19c5adf5274c045971fe9bda330bf..ae3658a64971a9d98609d61b5ae28e3d61ab185d 100644
--- a/algo/ca/qa/CaQa.h
+++ b/algo/ca/qa/CaQa.h
@@ -117,6 +117,9 @@ namespace cbm::algo::ca
     static constexpr int knTrkParPoints = 2;      ///< Number of track points to build par distributions
     static constexpr int knStaMax       = 16;     ///< Max number of stations (histogram binning)
     static constexpr bool kDebug        = false;  ///< Additional histograms
+    static constexpr int kOriginB       = 100;    ///< Track X(Y) at origin: n bins
+    static constexpr double kOriginL    = -10.;   ///< Track X(Y) at origin: lower bound [cm]
+    static constexpr double kOriginU    = +10.;   ///< Track X(Y) at origin: upper bound [cm]
 
     double fMinHitTime = std::numeric_limits<double>::max();
     double fMaxHitTime = std::numeric_limits<double>::lowest();
@@ -145,6 +148,7 @@ namespace cbm::algo::ca
     std::array<qa::H1D*, knTrkParPoints> fvphTrkChi2Ndf  = {{0}};  ///< hist: chi2/NDF at first/last hit
     std::array<qa::H2D*, knTrkParPoints> fvphTrkPhiTheta = {{0}};  ///< hist: theta vs. phi at first/last hit
 
+    qa::H2D* fphTrkOriginXY  = nullptr;  ///< hist: origin of tracks in x-y plane [cm]
     qa::H2D* fphTrkFstLstSta = nullptr;  ///< hist: fst vs lst station index
     qa::H1D* fphTrkNofHits   = nullptr;  ///< hist: number of hits in track
   };
diff --git a/algo/detectors/tof/ReadoutConfig.cxx b/algo/detectors/tof/ReadoutConfig.cxx
index 33238820100e333a7709b3d3d131b0b1beea308c..36310a9d4b3ea667023d853026ae6f64652d76f7 100644
--- a/algo/detectors/tof/ReadoutConfig.cxx
+++ b/algo/detectors/tof/ReadoutConfig.cxx
@@ -417,7 +417,7 @@ namespace cbm::algo::tof
       fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(iModuleId, 7 - iRpc, 0, 0, iModuleType);
       uCh++;
     }
-    uCh += (24 + 2 * 32);
+    uCh += (24 + 4 * 32);
     L_(debug) << " Map end ceramics  box  at GBTX  -  uCh = " << uCh;
   }
 
@@ -557,7 +557,7 @@ namespace cbm::algo::tof
         int iSideMap        = -1;
         int iStrMap         = -1;
         int iRpcMap         = -1;
-        const int ConOff[8] = {0, 2, 4, 6, 7, 1, 3, 5};  // Get4 after Gbtx
+        const int ConOff[8] = {0, 2, 4, 6, 7, 1, 3, 5};  //Get4 after Gbtx
         for (int32_t iFeet = 0; iFeet < 5; iFeet++) {
           for (int32_t iStr = 0; iStr < 32; iStr++) {
             switch (iFeet) {
@@ -592,6 +592,49 @@ namespace cbm::algo::tof
           }
         }
       }
+      else if (crob.rpcSide == 5) {
+        int iSideMap        = -1;
+        int iStrMap         = -1;
+        int iRpcMap         = -1;
+        const int ConOff[8] = {0, 2, 4, 6, 7, 1, 3, 5};  // Get4 after Gbtx
+        for (int32_t iFeet = 0; iFeet < 5; iFeet++) {
+          for (int32_t iStr = 0; iStr < 32; iStr++) {
+            switch (iFeet) {
+              case 0: iSideMap = -1; break;
+              case 1:
+                iRpcMap  = 0;
+                iStrMap  = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
+                iStrMap  = 31 - iStrMap;
+                iSideMap = 1;
+                break;
+              case 2:
+                iRpcMap  = 0;
+                iStrMap  = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
+                iStrMap  = 31 - iStrMap;
+                iSideMap = 0;
+                break;
+              case 3:
+                iRpcMap  = 1;
+                iStrMap  = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
+                iStrMap  = 31 - iStrMap;
+                iSideMap = 0;
+                break;
+              case 4:
+                iRpcMap  = 1;
+                iStrMap  = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
+                iStrMap  = 31 - iStrMap;
+                iSideMap = 1;
+                break;
+            }
+            if (iSideMap > -1)
+              fviRpcChUId[uCh] =
+                CbmTofAddress::GetUniqueAddress(crob.moduleId, iRpcMap, iStrMap, iSideMap, crob.rpcType);
+            else
+              fviRpcChUId[uCh] = 0;
+            uCh++;
+          }
+        }
+      }
     }
   }
 
@@ -645,7 +688,11 @@ namespace cbm::algo::tof
           case 4:  // HD cosmic 2019, Buc2018, v18o
             iRpcMap = 1 - iRpcMap;
             break;
-          case 5:  // HD cosmic 2020, Buc2018, v20a
+          case 5:  // Buc2025, mCBM
+            iRpcMap  = 1 - iRpcMap;
+            iSideMap = 1 - iSideMap;
+            break;
+          case 55:  // HD cosmic 2020, Buc2018, v20a
             iStrMap = 31 - iStr;
             break;
           case 6:  //BUC special
diff --git a/algo/detectors/tof/ReadoutConfig.h b/algo/detectors/tof/ReadoutConfig.h
index 07c91d72927aa86428f56030964c58effeebbef5..6b9ac632faef7de47e026881348a91e3ef750fd0 100644
--- a/algo/detectors/tof/ReadoutConfig.h
+++ b/algo/detectors/tof/ReadoutConfig.h
@@ -69,7 +69,8 @@ namespace cbm::algo::tof
     i32 NCrobsPerComponent() const { return nCrobPerComponent; }
 
     bool CheckBmonComp(uint32_t uCompId) const { return ((uCompId & 0xFFF0) == 0xABF0); }
-    bool CheckInnerComp(uint32_t uCompId) const { return ((uCompId & 0xFFF0) == 0xBBC0); }
+    //bool CheckInnerComp(uint32_t uCompId) const { return ((uCompId & 0xFFF0) == 0xBBC0); }
+    bool CheckInnerComp(uint32_t uCompId) const { return ((uCompId & 0xFF00) == 0xBB00); }
   };
 
 
diff --git a/algo/evbuild/EventbuildChain.h b/algo/evbuild/EventbuildChain.h
index ed6be01c66f7bb36b25d3f1582b9084272171971..32ae1e649c1228b17c49bc59226e2e66f7033f75 100644
--- a/algo/evbuild/EventbuildChain.h
+++ b/algo/evbuild/EventbuildChain.h
@@ -64,6 +64,11 @@ namespace cbm::algo::evbuild
     /** @brief Registers tracking setup **/
     void RegisterTrackingSetup(std::shared_ptr<TrackingSetup> pSetup) { fSelector.RegisterTrackingSetup(pSetup); }
 
+    /** @brief Sets V0 trigger QA
+     ** @param pQa  Qa module
+     **/
+    void SetV0TriggerQa(std::shared_ptr<V0TriggerQa> pQa) { fV0Trigger.SetQa(pQa); }
+
    private:                                              // members
     Config fConfig;                                      ///< Global configuration
     ECbmModuleId fTriggerDet = ECbmModuleId::kNotExist;  ///< Trigger detector
diff --git a/algo/evselector/DigiEventSelector.cxx b/algo/evselector/DigiEventSelector.cxx
index bae8b3e2cf4be404206848facf74f594f0ea2c14..4411689bfb468fa88af8bbb41233b3152c9eb5bc 100644
--- a/algo/evselector/DigiEventSelector.cxx
+++ b/algo/evselector/DigiEventSelector.cxx
@@ -44,6 +44,30 @@ namespace cbm::algo::evbuild
       }
     }
 
+    // --- Test masked channels (if any)
+    for (auto& entry : fConfig.fMaskedChannels) {
+      size_t nDigisAccepted = 0;
+      auto det              = entry.first;
+      auto itMinNumDigis    = fConfig.fMinNumDigis.find(det);
+      if (itMinNumDigis != fConfig.fMinNumDigis.end() && itMinNumDigis->second > 0) {
+        switch (det) {
+          case ECbmModuleId::kBmon:
+            for (const auto& digi : event.fBmon) {
+              if (entry.second.find(digi.GetAddress()) == entry.second.end()) {
+                ++nDigisAccepted;
+              }
+            }
+            break;
+          default:
+            // This was met in the first block of the function
+            break;
+        }
+        if (nDigisAccepted < itMinNumDigis->second) {
+          return false;
+        }
+      }
+    }
+
     return true;
   }
   // --------------------------------------------------------------------------
diff --git a/algo/evselector/DigiEventSelectorConfig.cxx b/algo/evselector/DigiEventSelectorConfig.cxx
index 647f7c0dfbb3acca86c180639167d2134eed1560..43399c74f0c7af2d827bedb8d8deffdf313ff17f 100644
--- a/algo/evselector/DigiEventSelectorConfig.cxx
+++ b/algo/evselector/DigiEventSelectorConfig.cxx
@@ -1,11 +1,12 @@
-/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+/* Copyright (C) 2022-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Shreya Roy. Pierre-Alain Loizeau, Volker Friese [committer], Dominik Smith */
+   Authors: Shreya Roy. Pierre-Alain Loizeau, Volker Friese [committer], Dominik Smith, Sergei Zharko */
 
 #include "DigiEventSelectorConfig.h"
 
 #include "AlgoFairloggerCompat.h"
 
+#include <iomanip>
 
 namespace cbm::algo::evbuild
 {
@@ -34,6 +35,19 @@ namespace cbm::algo::evbuild
           L_(warning) << "DigiEventSelectorConfig: Ignoring minimum 0 for layers in " << ::ToString(det);
       }
     }
+    if (auto maskedChannels = config["maskedChannels"]) {
+      for (YAML::const_iterator it = maskedChannels.begin(); it != maskedChannels.end(); ++it) {
+        auto det   = ToCbmModuleIdCaseInsensitive(it->first.as<std::string>());
+        auto value = it->second.as<std::vector<uint32_t>>();
+        if (value.size() > 0) {
+          fMaskedChannels[det] = std::unordered_set<uint32_t>(value.begin(), value.end());
+          L_(info) << "Masking following " << ToString(det) << " channels from event selecting: ";
+          for (auto address : fMaskedChannels[det]) {
+            L_(info) << " - 0x" << std::hex << std::setw(8) << std::setfill('0') << address << std::dec;
+          }
+        }
+      }
+    }
   }
   // --------------------------------------------------------------------------
 
@@ -50,6 +64,7 @@ namespace cbm::algo::evbuild
       auto det                 = ToString(entry.first);
       result["minLayers"][det] = entry.second;
     }
+    // FIXME: implement masked channels storage
     return result;
   }
   // --------------------------------------------------------------------------
diff --git a/algo/evselector/DigiEventSelectorConfig.h b/algo/evselector/DigiEventSelectorConfig.h
index 43276c739ddc21ceaf1bbd4767ad9ef0baf1e136..fa97bdcc13ac1475324f341217e1bc8a7300fcb7 100644
--- a/algo/evselector/DigiEventSelectorConfig.h
+++ b/algo/evselector/DigiEventSelectorConfig.h
@@ -1,6 +1,6 @@
-/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+/* Copyright (C) 2022-2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
    SPDX-License-Identifier: GPL-3.0-only
-   Authors: Shreya Roy. Pierre-Alain Loizeau, Volker Friese [committer], Dominik Smith */
+   Authors: Shreya Roy. Pierre-Alain Loizeau, Volker Friese [committer], Dominik Smith, Sergei Zharko */
 
 #ifndef CBM_ALGO_EVBUILD_DIGIEVENTSELECTORCONFIG_H
 #define CBM_ALGO_EVBUILD_DIGIEVENTSELECTORCONFIG_H 1
@@ -9,6 +9,7 @@
 
 #include <cstdint>
 #include <map>
+#include <unordered_set>
 
 #include <yaml-cpp/yaml.h>
 
@@ -45,10 +46,12 @@ namespace cbm::algo::evbuild
     /** @brief Save to YAML **/
     YAML::Node ToYaml() const;
 
-
    private:
     std::map<ECbmModuleId, size_t> fMinNumDigis;   ///< Key: detector, value: minimal number of digis
     std::map<ECbmModuleId, size_t> fMinNumLayers;  ///< Key: detector, value: Minimal number of layers
+
+    /** @brief A map of masked digi addresses, which should not participate in the event building **/
+    std::map<ECbmModuleId, std::unordered_set<uint32_t>> fMaskedChannels;
   };
 
 
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 0f192df1b6c68934269a1eea7e5561b73dd6aa5d..79784707ea990ca10e78cc88ec1b83c2512481e5 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -26,6 +26,7 @@
 #include "much/Unpack.h"
 #include "qa/QaManager.h"
 #include "qa/hitfind/BmonHitfindQa.h"
+#include "qa/hitfind/TofHitfindQa.h"
 #include "rich/Unpack.h"
 #include "sts/ChannelMaskSet.h"
 #include "sts/HitfinderChain.h"
@@ -192,6 +193,12 @@ void Reco::Init(const Options& opts)
     evbuild::Config config(YAML::LoadFile(configFile.string()));
     fEventBuild =
       std::make_unique<evbuild::EventbuildChain>(config, (Opts().Has(QaStep::EventBuilding) ? fSender : nullptr));
+    if (fQaManager != nullptr && Opts().Has(QaStep::V0Trigger)) {
+      // FIXME: Replace with a common function SetTriggerQa(fQaManager)
+      auto pTriggerQa = std::make_shared<evbuild::V0TriggerQa>(fQaManager);
+      pTriggerQa->Init();
+      fEventBuild->SetV0TriggerQa(pTriggerQa);
+    }
     fEventBuild->RegisterTrackingSetup(pTrackingSetup);
   }
 
@@ -215,6 +222,12 @@ void Reco::Init(const Options& opts)
 
     auto hitfindSetup = yaml::ReadFromFile<tof::HitfindSetup>(opts.ParamsDir() / parFiles.tof.hitfinder);
     fTofHitFinder     = std::make_unique<tof::Hitfind>(hitfindSetup);
+
+    if (fQaManager != nullptr && Opts().Has(QaStep::RecoTof)) {
+      fTofHitFinderQa = std::make_unique<tof::HitfindQa>(fQaManager, "TofHitfind");
+      fTofHitFinderQa->InitParameters(hitfindSetup);
+      fTofHitFinderQa->Init();
+    }
   }
 
   if (Opts().Has(fles::Subsystem::TRD) && Opts().Has(Step::LocalReco)) {
@@ -365,6 +378,10 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
         L_(error) << "TOF Digis with unknown RPCs: " << nUnknownRPC;
       }
       auto [hits, hitmonitor, digiindices] = (*fTofHitFinder)(caldigis);
+      if (fTofHitFinderQa != nullptr) {
+        fTofHitFinderQa->RegisterHits(&hits);
+        fTofHitFinderQa->Exec();
+      }
       recoData.tofHits                     = std::move(hits);
       QueueTofCalibMetrics(calmonitor);
       QueueTofRecoMetrics(hitmonitor);
diff --git a/algo/global/Reco.h b/algo/global/Reco.h
index 35cb5c34626c8dc84ba994478e83a305522cfd98..e5a8412151d8e05a4cd1b5ee68d71d8ee6f47ebc 100644
--- a/algo/global/Reco.h
+++ b/algo/global/Reco.h
@@ -60,6 +60,7 @@ namespace cbm::algo
     class Calibrate;
     struct CalibrateMonitorData;
     class Hitfind;
+    class HitfindQa;
     struct HitfindMonitorData;
   }
 
@@ -175,6 +176,7 @@ namespace cbm::algo
     std::unique_ptr<tof::Unpack> fTofUnpack;
     std::unique_ptr<tof::Calibrate> fTofCalibrator;
     std::unique_ptr<tof::Hitfind> fTofHitFinder;
+    std::unique_ptr<tof::HitfindQa> fTofHitFinderQa;
 
     // TRD
     std::unique_ptr<trd::Unpack> fTrdUnpack;
diff --git a/algo/kfp/KfpV0Finder.cxx b/algo/kfp/KfpV0Finder.cxx
index c95965bc847347caccc52b1bcf23a0eaeda8fd92..820078945d3ffd25eb18256e3077899c35d47432 100644
--- a/algo/kfp/KfpV0Finder.cxx
+++ b/algo/kfp/KfpV0Finder.cxx
@@ -80,7 +80,7 @@ void V0Finder::AssignPid(ParticleInfo& particleInfo)
     // primary
     //particleInfo.fPdg = fPrimaryAssignedPdg;
     particleInfo.fPdg = kUndefPdg;
-    fEventMonitor.IncrementCounter(ECounter::TracksWoPid);
+    fEventMonitor.IncrementCounter(ECounter::PrimaryDca);
   }
 }
 
diff --git a/algo/kfp/KfpV0FinderMonitor.h b/algo/kfp/KfpV0FinderMonitor.h
index d60d5b135478e2e6d379a26b69e8755d9b2bd96b..3f3b68ef6af1b548eb85cbb8c771caac3a93f51e 100644
--- a/algo/kfp/KfpV0FinderMonitor.h
+++ b/algo/kfp/KfpV0FinderMonitor.h
@@ -28,6 +28,7 @@ namespace cbm::algo::kfp
     TracksWUnphysicalBeta,      ///< Tracks with beta > 1
     PionsDca,                   ///< Number of raw pion-candidates
     ProtonsDca,                 ///< Number of raw proton-candidates
+    PrimaryDca,                 ///< Number of raw proton-candidates
     Pions,                      ///< Number of pion-candidates
     Protons,                    ///< Number of proton-candidates
     EventsTotal,                ///< Total number of events
@@ -76,6 +77,7 @@ namespace cbm::algo::kfp
       SetCounterName(ECounter::TracksWUnphysicalBeta, "tracks w/ beta > 1");
       SetCounterName(ECounter::PionsDca, "raw pion candidates");
       SetCounterName(ECounter::ProtonsDca, "raw proton candidates");
+      SetCounterName(ECounter::PrimaryDca, "number of primary particles");
       SetCounterName(ECounter::Pions, "pion candidates");
       SetCounterName(ECounter::Protons, "proton candidates");
       SetCounterName(ECounter::EventsTotal, "all events");
diff --git a/algo/kfp/KfpV0FinderQa.cxx b/algo/kfp/KfpV0FinderQa.cxx
index ffc903e2a2dcc2c12efa06b4bda11db6db29ffb9..703f067f93cf0b2a81c440817a55d9feac6fe7ea 100644
--- a/algo/kfp/KfpV0FinderQa.cxx
+++ b/algo/kfp/KfpV0FinderQa.cxx
@@ -57,7 +57,8 @@ void V0FinderQa::Exec(const RecoResults& recoEvent, const V0Finder& v0Finder)
       const auto& particleInfo{v0Finder.GetParticleInfo()[iTrk]};
       const auto& trkParFst{(v0Finder.GetTrackAssignedParams()[iTrk]).first};
       bool bPdgDefined = (particleInfo.fPdg != V0Finder::kUndefPdg);
-      fvphDcaAll->Fill(bPdgDefined ? particleInfo.fDca : -999);
+      // All particles with defined DCA (primaries + secondary pions and protons)
+      fvphDcaAll->Fill(std::isnan(particleInfo.fDca) ? -999 : particleInfo.fDca);
       fvphBetaAll->Fill(particleInfo.fBeta);
       if (bPdgDefined) {
         if (particleInfo.fPdg == -211) {
@@ -75,15 +76,15 @@ void V0FinderQa::Exec(const RecoResults& recoEvent, const V0Finder& v0Finder)
     for (uint32_t iTrk = 0; iTrk < tracks.size(); ++iTrk) {
       const auto& particleInfo{v0Finder.GetParticleInfo()[iTrk]};
       bool bPdgDefined = (particleInfo.fPdg != V0Finder::kUndefPdg);
-      fvphDcaAll->Fill(bPdgDefined ? particleInfo.fDca : -999);
-      fvphBetaAll->Fill(-999);
+      fvphDcaAll->Fill(std::isnan(particleInfo.fDca) ? -999 : particleInfo.fDca);
+      fvphBetaAll->Fill(-9999);
       if (bPdgDefined) {
         if (particleInfo.fPdg == -211) {
-          fvphBetaPion->Fill(-999);
-          fvphMomPion->Fill(-999);
+          fvphBetaPion->Fill(-9999);
+          fvphMomPion->Fill(-9999);
         }
         else if (particleInfo.fPdg == 2212) {
-          fvphBetaProton->Fill(-999);
+          fvphBetaProton->Fill(-9999);
         }
       }
     }
diff --git a/algo/qa/Histogram.h b/algo/qa/Histogram.h
index 1b70f3b0588b3eaba2b3617ecc8333957e3d8a39..44040934a422adb09a9b536714610548f30afabc 100644
--- a/algo/qa/Histogram.h
+++ b/algo/qa/Histogram.h
@@ -55,7 +55,8 @@ namespace cbm::algo::qa
   enum class EHistFlag : uint8_t
   {
     StoreVsTsId    = 0b00000001,  ///< Store the histogram vs timeslice index
-    OmitIntegrated = 0b00000010   ///< Omits storing integrated histogram
+    OmitIntegrated = 0b00000010,  ///< Omits storing integrated histogram
+    SetMinimum     = 0b00000100   ///< Sets minimum to the histogram
   };
 
   /// \class  HistogramMetadata
diff --git a/algo/qa/QaTaskHeader.h b/algo/qa/QaTaskHeader.h
index ceb03e5ad457c9b6ceecb1145c7a5f4c15f262b9..e910a6a103d62dbcee2e17722b9ac4d0a9f924b7 100644
--- a/algo/qa/QaTaskHeader.h
+++ b/algo/qa/QaTaskHeader.h
@@ -51,7 +51,7 @@ namespace cbm::algo::qa
     ///
     /// The task can be inactive, if a nullptr qa::Manager was passed to the constructor. If it is the case,
     /// the fpData instance is not defined, and no actions on the task should be performed
-    bool IsActive() const { return static_cast<bool>(fpData != nullptr); }
+    bool IsActive() const { return fpData.get(); }
 
     /// \brief Gets name of the task
     const std::string& GetTaskName() { return fsName; }
diff --git a/algo/qa/hitfind/TofHitfindQa.cxx b/algo/qa/hitfind/TofHitfindQa.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c037dc676457bd599e552e7c3e972ca523c9b4e8
--- /dev/null
+++ b/algo/qa/hitfind/TofHitfindQa.cxx
@@ -0,0 +1,110 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   TofHitfindQa.cxx
+/// \brief  A TOF hitfinder QA (implementation)
+/// \since  04.03.2025
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#include "qa/hitfind/TofHitfindQa.h"
+
+#include "CbmTofAddress.h"
+#include "qa/Histogram.h"
+#include "tof/Hit.h"
+
+#include <fmt/format.h>
+
+using cbm::algo::tof::HitfindQa;
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void HitfindQa::Init()
+try {
+  using fmt::format;
+  using qa::CanvasConfig;
+  using qa::PadConfig;
+  if (!IsActive()) {
+    return;
+  }
+
+  size_t nRpcs = fParameters.rpcs.size();
+  if (nRpcs < 1) {
+    throw std::runtime_error("parameters were not initialized. Please, provide the configuration using the function "
+                             "HitfindQa::InitParameters(hitSetup)");
+  }
+
+  // Histogram initialization
+  fvphRpcHitOccupX.resize(nRpcs, nullptr);
+  fvphRpcHitOccupY.resize(nRpcs, nullptr);
+  fvphRpcHitOccupCh.resize(nRpcs, nullptr);
+
+  auto cOccupX  = CanvasConfig(format("{}/tof_rpc_occup_x", GetTaskName()), "RPC hit occupancy vs. X", 1, 1);
+  auto cOccupY  = CanvasConfig(format("{}/tof_rpc_occup_y", GetTaskName()), "RPC hit occupancy vs. Y", 1, 1);
+  auto cOccupCh = CanvasConfig(format("{}/tof_rpc_occup_ch", GetTaskName()), "RPC hit occupancy vs. channel", 1, 1);
+  for (size_t iRpc = 0; iRpc < nRpcs; ++iRpc) {
+    const auto& rpcPar = fParameters.rpcs[iRpc];
+    int nCh            = rpcPar.chAddresses.size();
+    auto sDN           = format("{:#010x}", rpcPar.address);  // diamond suffix
+    auto sDT           = CbmTofAddress::ToString(rpcPar.address);
+
+    // Histograms initialisation
+    fvphRpcHitOccupX[iRpc]  = MakeObj<qa::H1D>(format("tof_hit_occup_x_{}", sDN), format("RPC {};x [cm];counts", sDT),
+                                              kHitOccupB, kHitOccupL, kHitOccupU);
+    fvphRpcHitOccupY[iRpc]  = MakeObj<qa::H1D>(format("tof_hit_occup_y_{}", sDN), format("RPC {};y [cm];counts", sDT),
+                                              kHitOccupB, kHitOccupL, kHitOccupU);
+    fvphRpcHitOccupCh[iRpc] = MakeObj<qa::H1D>(format("tof_hit_occup_chan_{}", sDN),
+                                               format("RPC {};channel;counts", sDT), nCh, -0.5, nCh - 0.5);
+
+    {
+      auto pad = PadConfig(fvphRpcHitOccupX[iRpc], "hist");
+      pad.SetLog(false, true, false);
+      cOccupX.AddPadConfig(pad);
+    }
+    {
+      auto pad = PadConfig(fvphRpcHitOccupY[iRpc], "hist");
+      pad.SetLog(false, true, false);
+      cOccupY.AddPadConfig(pad);
+    }
+    {
+      auto pad = PadConfig(fvphRpcHitOccupCh[iRpc], "hist");
+      pad.SetLog(false, true, false);
+      cOccupCh.AddPadConfig(pad);
+    }
+  }
+
+  AddCanvasConfig(cOccupX);
+  AddCanvasConfig(cOccupY);
+  AddCanvasConfig(cOccupCh);
+}
+catch (const std::exception& err) {
+  L_(fatal) << "tof::HitfindQa: initialization failed. Reason: " << err.what();
+  throw std::runtime_error("tof::HitfindQa initialization failure");
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void HitfindQa::Exec()
+{
+  if (!IsActive()) {
+    return;
+  }
+
+  // Fill hit distributions
+  const auto& hits = fpHits->Data();
+  for (size_t iH = 0; iH < hits.size(); ++iH) {
+    const auto& hit     = hits[iH];
+    int32_t hitAddress  = hit.address;
+    int32_t iCh         = CbmTofAddress::GetChannelId(hitAddress);
+    uint32_t rpcAddress = CbmTofAddress::GetModFullId(hitAddress);
+    auto itAddress      = fParameters.lookupMap.find(rpcAddress);
+    if (itAddress == fParameters.lookupMap.end()) {
+      L_(error) << "tof::HitfindQa: unknown RPC address " << CbmTofAddress::ToString(rpcAddress);
+      continue;
+    }
+    uint32_t iRpc = itAddress->second;
+    fvphRpcHitOccupX[iRpc]->Fill(hit.X());
+    fvphRpcHitOccupY[iRpc]->Fill(hit.Y());
+    fvphRpcHitOccupCh[iRpc]->Fill(iCh);
+  }
+}
diff --git a/algo/qa/hitfind/TofHitfindQa.h b/algo/qa/hitfind/TofHitfindQa.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c630b0b2a72a1943e94df84c95c9b33041e4d16
--- /dev/null
+++ b/algo/qa/hitfind/TofHitfindQa.h
@@ -0,0 +1,91 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   TofHitfindQa.h
+/// \brief  A TOF hitfinder QA
+/// \since  04.03.2025
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+
+#pragma once
+
+#include "PODVector.h"
+#include "PartitionedVector.h"
+#include "qa/QaTaskHeader.h"
+#include "qa/hitfind/TofHitfindQaParameters.h"
+
+namespace cbm::algo
+{
+  namespace qa
+  {
+    class H1D;
+    class H2D;
+  }  // namespace qa
+
+  namespace tof
+  {
+    class Hit;
+  }
+}  // namespace cbm::algo
+
+namespace cbm::algo::tof
+{
+  /// \class HitfindQa
+  /// \brief A QA module for the BMON hit-finder
+  class HitfindQa : public qa::TaskHeader {
+   public:
+    /// \brief Constructor
+    /// \param pManager  Pointer to the QA manager
+    /// \param name      Name of the QA (directory)
+    HitfindQa(const std::unique_ptr<qa::Manager>& pManager, std::string_view name) : qa::TaskHeader(pManager, name) {}
+
+    /// \brief Constructor from the configuration object
+    HitfindQa() = default;
+
+    /// \brief Copy constructor
+    HitfindQa(const HitfindQa&) = delete;
+
+    /// \brief Move constructor
+    HitfindQa(HitfindQa&&) = delete;
+
+    /// \brief Destructor
+    ~HitfindQa() = default;
+
+    /// \brief Copy assignment operator
+    HitfindQa& operator=(const HitfindQa&) = delete;
+
+    /// \brief Move assignment operator
+    HitfindQa& operator=(HitfindQa&&) = delete;
+
+    /// \brief Executes the task, fills the histograms
+    void Exec();
+
+    /// \brief Initialized the task
+    void Init();
+
+    /// \brief Initialisation of the parameters
+    void InitParameters(const HitfindSetup& hitSetup) { fParameters = std::move(HitfindQaParameters(hitSetup)); }
+
+    /// \brief Registers a sample of hits
+    /// \param pHits  A pointer to a vector of hits
+    void RegisterHits(const PartitionedVector<tof::Hit>* pHits) { fpHits = pHits; }
+
+   private:
+    //* Constants
+    static constexpr int kHitOccupB{200};       ///< Hit occupancy: n bins
+    static constexpr double kHitOccupL{-100.};  ///< Hit occupancy: lower bound [cm]
+    static constexpr double kHitOccupU{+100.};  ///< Hit occupancy: upper bound [cm]
+
+    //* Parameters
+    HitfindQaParameters fParameters;  ///< Parameters of the hit finder QA
+
+    //* Data samples
+    const PartitionedVector<tof::Hit>* fpHits{nullptr};  ///< Pointer to TOF hit sample
+
+    //* Histograms
+    std::vector<qa::H1D*> fvphRpcHitOccupX;   ///< Hit occupancy in RPC vs. x
+    std::vector<qa::H1D*> fvphRpcHitOccupY;   ///< Hit occupancy in RPC vs. y
+    std::vector<qa::H1D*> fvphRpcHitOccupCh;  ///< Hit occupancy in RPC vs. channel
+  };
+}  // namespace cbm::algo::tof
diff --git a/algo/qa/hitfind/TofHitfindQaParameters.cxx b/algo/qa/hitfind/TofHitfindQaParameters.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3cb2f35b8cef672094e082cf4de445612f65f44b
--- /dev/null
+++ b/algo/qa/hitfind/TofHitfindQaParameters.cxx
@@ -0,0 +1,40 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   BmonHitfindQaParameters.cxx
+/// \brief  A BMON hitfinder QA parameter configuration (implementation)
+/// \since  10.02.2025
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#include "qa/hitfind/TofHitfindQaParameters.h"
+
+#include "AlgoFairloggerCompat.h"
+#include "CbmTofAddress.h"
+
+using cbm::algo::tof::HitfindQaParameters;
+using cbm::algo::tof::HitfindSetup;
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+HitfindQaParameters::HitfindQaParameters(const HitfindSetup& hitSetup)
+{
+  rpcs.clear();
+  lookupMap.clear();
+  uint32_t iUniqueRpcId = 0;
+  for (const auto& smType : hitSetup.rpcs) {
+    for (const auto& rpc : smType) {
+      uint32_t address   = static_cast<uint32_t>(CbmTofAddress::GetModFullId(rpc.chanPar[0].address));
+      lookupMap[address] = iUniqueRpcId;
+      auto& rpcPar       = rpcs.emplace_back();
+      rpcPar.address     = address;
+      rpcPar.chAddresses.resize(rpc.chanPar.size());
+      L_(debug) << "RPC: " << CbmTofAddress::ToString(address);
+      for (int iCh = 0; iCh < rpcPar.chAddresses.size(); ++iCh) {
+        rpcPar.chAddresses[iCh] = rpc.chanPar[iCh].address;
+        L_(debug) << "----> ch: " << CbmTofAddress::ToString(rpcPar.chAddresses[iCh]);
+      }
+      iUniqueRpcId++;
+    }
+  }
+}
diff --git a/algo/qa/hitfind/TofHitfindQaParameters.h b/algo/qa/hitfind/TofHitfindQaParameters.h
new file mode 100644
index 0000000000000000000000000000000000000000..f64fe1e9f324749c98f268eb3eb6a838278f70fc
--- /dev/null
+++ b/algo/qa/hitfind/TofHitfindQaParameters.h
@@ -0,0 +1,39 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   TofHitfindQaParameters.h
+/// \brief  A TOF hitfinder QA parameter configuration
+/// \since  03.03.2025
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#pragma once
+
+#include "tof/HitfindSetup.h"
+
+#include <unordered_map>
+#include <vector>
+
+namespace cbm::algo::tof
+{
+  /// \struct HitfindQaParameters
+  /// \brief  A structure to handle TOF QA parameters
+  struct HitfindQaParameters {
+
+    /// \struct Rpc
+    struct Rpc {
+      std::vector<uint32_t> chAddresses;  ///< Address of channel vs channel ID
+      uint32_t address;                   ///< Address of RPC
+    };
+
+    std::unordered_map<uint32_t, uint32_t> lookupMap;  ///< A lookup map for RPC addresses
+    std::vector<Rpc> rpcs;                             ///< A map for different RPC properties
+
+    /// \brief Default constructor
+    HitfindQaParameters() = default;
+
+    /// \brief Constructor
+    /// \param hitSetup  Hitfinder parameters
+    HitfindQaParameters(const HitfindSetup& hitSetup);
+  };
+}  // namespace cbm::algo::tof
diff --git a/algo/qa/trigger/V0TriggerQa.cxx b/algo/qa/trigger/V0TriggerQa.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..234cf13b19a8603b6f443164c1c12cb4102eb6ac
--- /dev/null
+++ b/algo/qa/trigger/V0TriggerQa.cxx
@@ -0,0 +1,34 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   V0TriggerQa.cxx
+/// \brief  A V0-trigger QA (implementation)
+/// \since  06.03.2025
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#include "qa/trigger/V0TriggerQa.h"
+
+#include "qa/Histogram.h"
+
+using cbm::algo::evbuild::V0TriggerQa;
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void V0TriggerQa::Init()
+{
+  // Histograms
+  fphPairDeltaT  = MakeObj<qa::H1D>("v0trigger_pair_delta_t", "Time difference of track pair;#Delta t [ns];Counts",
+                                   kPairDeltaTB, kPairDeltaTL, kPairDeltaTU);
+  fphPairZVertex = MakeObj<qa::H1D>("v0trigger_pair_z_vertex", "z-verex of track pair;z [cm];Counts", kPairZVertexB,
+                                    kPairZVertexL, kPairZVertexU);
+  fphPairDca     = MakeObj<qa::H1D>("v0trigger_pair_dca", "Track pair distance of closest approach;DCA [cm];Counts",
+                                kPairDcaB, kPairDcaL, kPairDcaU);
+
+  // Canvas
+  auto canv = qa::CanvasConfig(GetTaskName(), "V0 Trigger summary", 3, 1);
+  canv.AddPadConfig(qa::PadConfig(fphPairDeltaT, "hist"));
+  canv.AddPadConfig(qa::PadConfig(fphPairZVertex, "hist"));
+  canv.AddPadConfig(qa::PadConfig(fphPairDca, "hist"));
+  AddCanvasConfig(canv);
+}
diff --git a/algo/qa/trigger/V0TriggerQa.h b/algo/qa/trigger/V0TriggerQa.h
new file mode 100644
index 0000000000000000000000000000000000000000..fff885f86fea36430e70ac8a51446c3577833035
--- /dev/null
+++ b/algo/qa/trigger/V0TriggerQa.h
@@ -0,0 +1,68 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   V0TriggerQa.h
+/// \brief  A V0-trigger QA
+/// \since  06.03.2025
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#pragma once
+
+#include "qa/QaTaskHeader.h"
+
+namespace cbm::algo::qa
+{
+  class H1D;
+}  // namespace cbm::algo::qa
+
+
+namespace cbm::algo::evbuild
+{
+  /// \class V0TriggerQa
+  /// \brief A QA module for the V0-trigger
+  class V0TriggerQa : public qa::TaskHeader {
+   public:
+    friend class V0Trigger;  // for access to histograms
+
+    /// \brief Constructor
+    /// \param pManager  Pointer to the QA manager
+    /// \param name      Name of the QA (directory)
+    V0TriggerQa(const std::unique_ptr<qa::Manager>& pManager) : qa::TaskHeader(pManager, "V0Trigger") {}
+
+    /// \brief Copy constructor
+    V0TriggerQa(const V0TriggerQa&) = delete;
+
+    /// \brief Move constructor
+    V0TriggerQa(V0TriggerQa&&) = delete;
+
+    /// \brief Destructor
+    ~V0TriggerQa() = default;
+
+    /// \brief Copy assignment operator
+    V0TriggerQa& operator=(const V0TriggerQa&) = delete;
+
+    /// \brief Move assignment operator
+    V0TriggerQa& operator=(V0TriggerQa&&) = delete;
+
+    /// \brief Initializes the task
+    void Init();
+
+   private:
+    //* Constants
+    static constexpr int kPairDeltaTB{100};       ///< Track pair time difference: n bins
+    static constexpr double kPairDeltaTL{-50.};   ///< Track pair time difference: lower bound [ns]
+    static constexpr double kPairDeltaTU{+50.};   ///< Track pair time difference: upper bound [ns]
+    static constexpr int kPairZVertexB{120};      ///< Track pair z vertex: n bins
+    static constexpr double kPairZVertexL{-60.};  ///< Track pair z vertex: lower bound [cm]
+    static constexpr double kPairZVertexU{+60.};  ///< Track pair z vertex: upper bound [cm]
+    static constexpr int kPairDcaB{300};          ///< Track pair DCA: n bins
+    static constexpr double kPairDcaL{-0.5};      ///< Track pair DCA: lower bound [cm]
+    static constexpr double kPairDcaU{+5.5};      ///< Track pair DCA: upper bound [cm]
+
+    //* Histograms
+    qa::H1D* fphPairDeltaT{nullptr};   ///< Track pair delta T
+    qa::H1D* fphPairZVertex{nullptr};  ///< Track pair z-vertex
+    qa::H1D* fphPairDca{nullptr};      ///< Track pair distance at closest approach
+  };
+}  // namespace cbm::algo::evbuild
diff --git a/algo/trigger/V0Trigger.cxx b/algo/trigger/V0Trigger.cxx
index bf9264801a9a444d56dac990a8998f3cc3da511a..e3ff8ef9f50a58fda75b569cc974952e0bc61001 100644
--- a/algo/trigger/V0Trigger.cxx
+++ b/algo/trigger/V0Trigger.cxx
@@ -32,6 +32,11 @@ namespace cbm::algo::evbuild
         // Check track time difference
         float time1 = trackIter1->fParPV.GetTime();
         float time2 = trackIter2->fParPV.GetTime();
+
+        if (fpQa->IsActive()) {
+          fpQa->fphPairDeltaT->Fill(time2 - time1);
+        }
+
         if (time2 < time1) {
           result.second.errTracksUnsorted++;
           continue;
@@ -42,6 +47,11 @@ namespace cbm::algo::evbuild
 
         // Check PCA cuts
         auto [zVertex, dist] = CalcPCA(trackIter1->fParPV, trackIter2->fParPV);
+        if (fpQa->IsActive()) {
+          fpQa->fphPairZVertex->Fill(zVertex);
+          fpQa->fphPairDca->Fill(dist);
+        }
+
         if (dist < config.PairDist_max()) {
           result.second.numTrackPairsAfterDistCut++;
           if (zVertex >= config.PairZ_min() && zVertex <= config.PairZ_max()) {
diff --git a/algo/trigger/V0Trigger.h b/algo/trigger/V0Trigger.h
index 6bed8ce5d210aaed169931991c6b79eded3603c6..3736b64f23754f992e76199f1a957d210d213be4 100644
--- a/algo/trigger/V0Trigger.h
+++ b/algo/trigger/V0Trigger.h
@@ -7,6 +7,7 @@
 #include "CaTrack.h"
 #include "CaVector.h"
 #include "V0TriggerConfig.h"
+#include "qa/trigger/V0TriggerQa.h"
 
 #include <utility>
 #include <vector>
@@ -50,6 +51,7 @@ namespace cbm::algo::evbuild
     /** @brief Constructor **/
     V0Trigger() = default;
 
+
     /** @brief Execution
      ** @param  tracks      Input track vector
      ** @param  config      Trigger configuration
@@ -57,6 +59,13 @@ namespace cbm::algo::evbuild
      **/
     Result operator()(const TrackVector& tracks, const V0TriggerConfig& config) const;
 
+
+    /** @brief Sets QA module
+     ** @param pQa  Pointer to the QA module
+     **/
+    void SetQa(std::shared_ptr<V0TriggerQa> pQa) { fpQa = pQa; }
+
+
     /** @brief Info to string **/
     std::string ToString() const;
 
@@ -84,6 +93,8 @@ namespace cbm::algo::evbuild
      ** @return decision
      **/
     bool IsPrimary(const TrackParam& track, const V0TriggerConfig& config) const;
+
+    std::shared_ptr<V0TriggerQa> fpQa{std::make_shared<V0TriggerQa>(nullptr)};  //! QA module
   };
 
 }  // namespace cbm::algo::evbuild
diff --git a/core/detectors/tof/CbmMcbm2018TofPar.cxx b/core/detectors/tof/CbmMcbm2018TofPar.cxx
index d2441aecf6afb55abd8de4f9b918cdf827e830b2..ad8f36aff7be8fbd45e94e8f6cea7b34de2f918b 100644
--- a/core/detectors/tof/CbmMcbm2018TofPar.cxx
+++ b/core/detectors/tof/CbmMcbm2018TofPar.cxx
@@ -268,13 +268,15 @@ void CbmMcbm2018TofPar::BuildChannelsUidMap()
     uint32_t uGdpb = uCh0 / (fiNrOfFeesPerGdpb * fiNrOfGet4PerFee * fiNrOfChannelsPerGet4);
     LOG(info) << "Map at ch " << uCh << ", Gdpb " << uGdpb << ", Id " << std::hex << fiGdpbIdArray[uGdpb] << std::dec;
     switch (fiRpcType[uGbtx]) {
+      case 3:  // intended fall-through
       case 2:  // intended fall-through
+      case 1:  // intended fall-through
       case 0: {
         // CBM modules
         BuildChannelsUidMapCbm(uCh, uGbtx);
         break;
       }
-      case 1: {
+      case 11: {
         // STAR eTOF  modules
         BuildChannelsUidMapStar(uCh, uGbtx);
         break;
@@ -418,7 +420,7 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapStar(UInt_t& uCh, UInt_t uGbtx)
 // -------------------------------------------------------------------------
 void CbmMcbm2018TofPar::BuildChannelsUidMapBmon(UInt_t& uCh, UInt_t uGbtx)
 {
-  LOG(info) << " Map diamond  at GBTX  -  uCh = " << uCh;
+  LOG(info) << " Map diamond  at GBTX " << uGbtx << " -  uCh = " << uCh;
   for (UInt_t uFee = 0; uFee < kuNbFeePerGbtx; ++uFee) {
     for (UInt_t uFeeCh = 0; uFeeCh < kuNbChannelsPerFee; ++uFeeCh) {
       /// Mapping for the 2019 beamtime
@@ -432,6 +434,7 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapBmon(UInt_t& uCh, UInt_t uGbtx)
             /// => 1 Bmon channel per GET4
             /// => 1-2 eLinks per GET4 => GET4 ID = GET4 * 2 (+ 1)
             UInt_t uChannelBmon = uFeeCh / 8 + 4 * fiRpcSide[uGbtx];
+            fiRpcType[uGbtx]    = 5;  //for compatibility with TOF convention
             fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], 0, uChannelBmon, 0, fiRpcType[uGbtx]);
             LOG(info) << Form("Bmon channel: %u from GBTx %2u Fee %2u "
                               "Channel %2u, indx %d address %08x",
@@ -506,7 +509,8 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapCera(UInt_t& uCh, UInt_t /*uGbtx*/)
     fviRpcChUId[uCh] = CbmTofAddress::GetUniqueAddress(iModuleId, 7 - iRpc, 0, 0, iModuleType);
     uCh++;
   }
-  uCh += (24 + 2 * 32);
+  uCh += (24 + 4 * 32);  //for 2024 FSD
+  //uCh += (24 + 2 * 32);
   LOG(info) << " Map end ceramics  box  at GBTX  -  uCh = " << uCh;
 }
 // -------------------------------------------------------------------------
@@ -684,10 +688,52 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapStar2A(UInt_t& uCh, UInt_t uGbtx)
         }
       }
     }
+    else if (fiRpcSide[uGbtx] == 5) {
+      int iSideMap        = -1;
+      int iStrMap         = -1;
+      int iRpcMap         = -1;
+      const int ConOff[8] = {0, 2, 4, 6, 7, 1, 3, 5};  //Get4 after Gbtx
+      for (Int_t iFeet = 0; iFeet < 5; iFeet++) {
+        for (Int_t iStr = 0; iStr < 32; iStr++) {
+          switch (iFeet) {
+            case 0: iSideMap = -1; break;
+            case 1:
+              iRpcMap  = 0;
+              iStrMap  = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
+              iStrMap  = 31 - iStrMap;
+              iSideMap = 1;
+              break;
+            case 2:
+              iRpcMap  = 0;
+              iStrMap  = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
+              iStrMap  = 31 - iStrMap;
+              iSideMap = 0;
+              break;
+            case 3:
+              iRpcMap  = 1;
+              iStrMap  = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
+              iStrMap  = 31 - iStrMap;
+              iSideMap = 0;
+              break;
+            case 4:
+              iRpcMap  = 1;
+              iStrMap  = 3 - iStr % 4 + 4 * ConOff[iStr / 4];
+              iStrMap  = 31 - iStrMap;
+              iSideMap = 1;
+              break;
+          }
+          if (iSideMap > -1)
+            fviRpcChUId[uCh] =
+              CbmTofAddress::GetUniqueAddress(fiModuleId[uGbtx], iRpcMap, iStrMap, iSideMap, fiRpcType[uGbtx]);
+          else
+            fviRpcChUId[uCh] = 0;
+          uCh++;
+        }
+      }
+    }
   }
 }
 
-// -------------------------------------------------------------------------
 void CbmMcbm2018TofPar::BuildChannelsUidMapBuc(UInt_t& uCh, UInt_t uGbtx)
 {
   LOG(info) << " Map Buc box " << fiModuleId[uGbtx] << " at GBTX " << uGbtx << " -  uCh = " << uCh;
@@ -745,7 +791,12 @@ void CbmMcbm2018TofPar::BuildChannelsUidMapBuc(UInt_t& uCh, UInt_t uGbtx)
         case 4:  // HD cosmic 2019, Buc2018, v18o
           iRpcMap = 1 - iRpcMap;
           break;
-        case 5:  // HD cosmic 2020, Buc2018, v20a
+        case 5:  // Buc2025, mCBM
+          iRpcMap = 1 - iRpcMap;
+          //iStrMap  = 31 - iStr;
+          iSideMap = 1 - iSideMap;
+          break;
+        case 55:  // HD cosmic 2020, Buc2018, v20a
           iStrMap = 31 - iStr;
           break;
         case 6:  //BUC special
diff --git a/core/detectors/tof/CbmMcbm2018TofPar.h b/core/detectors/tof/CbmMcbm2018TofPar.h
index 6ede9c726ac88bf55d704c1c6d302d1491fb61b8..fa38cb39ec793e5a493d823b2651556e5fb2e855 100644
--- a/core/detectors/tof/CbmMcbm2018TofPar.h
+++ b/core/detectors/tof/CbmMcbm2018TofPar.h
@@ -85,7 +85,8 @@ class CbmMcbm2018TofPar : public FairParGenericSet {
   inline Double_t GetTsDeadtimePeriod() { return fdTsDeadtimePeriod; }
 
   inline bool CheckBmonComp(uint32_t uCompId) { return ((uCompId & 0xFFF0) == 0xABF0); }
-  inline bool CheckInnerComp(uint32_t uCompId) { return ((uCompId & 0xFFF0) == 0xBBC0); }
+  //inline bool CheckInnerComp(uint32_t uCompId) { return ((uCompId & 0xFFF0) == 0xBBC0); }
+  inline bool CheckInnerComp(uint32_t uCompId) { return ((uCompId & 0xFF00) == 0xBB00); }
 
  private:
   void BuildChannelsUidMap();
@@ -121,6 +122,7 @@ class CbmMcbm2018TofPar : public FairParGenericSet {
   const UInt_t kuPaditoget4[kuNbChannelsPerFee] = {
     3,  2,  1,  0,  7,  6,  5,  4,  11, 10, 9,  8,  15, 14, 13, 12,
     19, 18, 17, 16, 23, 22, 21, 20, 27, 26, 25, 24, 31, 30, 29, 28};  //! Map from PADI channel to GET4 channel
+
   const UInt_t kuElinkToGet4[kuNbGet4PerGbtx] = {27, 2,  7,  3,  31, 26, 30, 1,  33, 37, 32, 13, 9,  14,
                                                  10, 15, 17, 21, 16, 35, 34, 38, 25, 24, 0,  6,  20, 23,
                                                  18, 22, 28, 4,  29, 5,  19, 36, 39, 8,  12, 11};
diff --git a/external/InstallParameter.cmake b/external/InstallParameter.cmake
index e2c98a2f89de41e69ef18f30969ee696f5c1e9f3..7d97a642abd711e516874c0e1bc1d7bdf17ebe1d 100644
--- a/external/InstallParameter.cmake
+++ b/external/InstallParameter.cmake
@@ -1,4 +1,4 @@
-set(PARAMETER_VERSION 99acefb7a5d6667893b319a44a20b265cfb6fbac) # 2025/02/15
+set(PARAMETER_VERSION 837c4d8a6ad72455bf5843d85360580f19700644) # 2025/03/07
 set(PARAMETER_SRC_URL "https://git.cbm.gsi.de/CbmSoft/cbmroot_parameter.git")
 
 download_project_if_needed(PROJECT         Parameter_source