diff --git a/algo/ca/TrackingChain.cxx b/algo/ca/TrackingChain.cxx
index 5ce7a4e51d717bc4ec01905717ad2644b32e54a8..374c23bb1e053d132dda601a4049746b910c90e7 100644
--- a/algo/ca/TrackingChain.cxx
+++ b/algo/ca/TrackingChain.cxx
@@ -133,6 +133,7 @@ void TrackingChain::Init()
     fQa.RegisterParameters(&fCaFramework.GetParameters());
     fQa.Init();
   }
+  L_(info) << "TRACKING QA: " << fQa.IsActive();
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
@@ -225,6 +226,7 @@ TrackingChain::Output_t TrackingChain::PrepareOutput()
       int iHitInternal = fCaFramework.GetInputData().GetHit(fCaFramework.fRecoHits[trackFirstHit + iHit]).Id();
       const auto [detID, iPartition, iPartHit] = faHitExternalIndices[iHitInternal];
       switch (detID) {
+        // FIXME: store a global hit index instead of (partition, hit)
         case ca::EDetectorID::kSts: output.stsHitIndices[iTrk].push_back(std::make_pair(iPartition, iPartHit)); break;
         case ca::EDetectorID::kTof: output.tofHitIndices[iTrk].push_back(std::make_pair(iPartition, iPartHit)); break;
         case ca::EDetectorID::kTrd: output.trdHitIndices[iTrk].push_back(std::make_pair(iPartition, iPartHit)); break;
diff --git a/algo/ca/core/utils/CaEnumArray.h b/algo/ca/core/utils/CaEnumArray.h
index 5acd385893cffa7941e92182c268f44adbe0aed8..84e90a0eda1557717935c876b51dd6514b69235a 100644
--- a/algo/ca/core/utils/CaEnumArray.h
+++ b/algo/ca/core/utils/CaEnumArray.h
@@ -38,7 +38,7 @@ namespace cbm::algo::ca
 
    public:
     /// \brief Mutable access operator, indexed by enum entry
-    T& operator[](const E& entry)
+    T& operator[](const E entry)
     {
       return std::array<T, static_cast<std::size_t>(E::END)>::operator[](static_cast<U>(entry));
     }
diff --git a/algo/ca/qa/CaQa.cxx b/algo/ca/qa/CaQa.cxx
index 05815198dd6e6a228f9db995496470a830d18b2c..8d081862c78d399aca6ec01d0dda38e432517185 100644
--- a/algo/ca/qa/CaQa.cxx
+++ b/algo/ca/qa/CaQa.cxx
@@ -187,22 +187,22 @@ void Qa::Init()
       continue;
     }
     {
-      auto sName      = format("track_{}_theta", vsPointName[i]);
+      auto sName      = format("{}_track_{}_theta", GetTaskName(), vsPointName[i]);
       auto sTitl      = format("#theta at {} hit; #theta", vsPointName[i]);
       fvphTrkTheta[i] = MakeObj<H1D>(sName, sTitl, 62, 0., 90.);
     }
     {
-      auto sName    = format("track_{}_phi", vsPointName[i]);
+      auto sName    = format("{}_track_{}_phi", GetTaskName(), vsPointName[i]);
       auto sTitl    = format("#phi at {} hit; #phi", vsPointName[i]);
       fvphTrkPhi[i] = MakeObj<H1D>(sName, sTitl, 62, -180., 180.);
     }
     {
-      auto sName         = format("track_{}_thata_phi", vsPointName[i]);
+      auto sName         = format("{}_track_{}_thata_phi", GetTaskName(), vsPointName[i]);
       auto sTitl         = format("#theta vs #phi at {} hit; #phi; #theta", vsPointName[i]);
       fvphTrkPhiTheta[i] = MakeObj<H2D>(sName, sTitl, 62, -180., 180., 62, 0., 90.);
     }
     {
-      auto sName        = format("track_{}_chi2_ndf", vsPointName[i]);
+      auto sName        = format("{}_track_{}_chi2_ndf", GetTaskName(), vsPointName[i]);
       auto sTitl        = format("#chi^{{2}}/NDF at {} hit; #chi^{{2}}/NDF", vsPointName[i]);
       fvphTrkChi2Ndf[i] = MakeObj<H1D>(sName, sTitl, 100, 0., 20.);
     }
@@ -212,7 +212,7 @@ void Qa::Init()
     double xMin = -0.5;
     double xMax = double(knStaMax) - 0.5;
     {
-      auto sName      = "track_fst_lst_sta";
+      auto sName      = format("{}_track_fst_lst_sta", GetTaskName());
       auto sTitl      = "First vs. last station index;ID^{last}_{station};ID^{first}_{station}";
       fphTrkFstLstSta = MakeObj<H2D>(sName, sTitl, nBins, xMin, xMax, nBins, xMin, xMax);
     }
@@ -227,7 +227,7 @@ void Qa::Init()
         auto setNm = EHitSet::Input == hitSet ? "input" : "used";
         auto setTl = EHitSet::Input == hitSet ? "Input" : "Used";
         {  // XY
-          auto name = format("ca_hit_{}_occupancy_xy", setNm);
+          auto name = format("{}_ca_hit_{}_occupancy_xy", GetTaskName(), setNm);
           auto titl = format("{} hit occupancy in different stations in XY plane", setNm);
           auto canv = CanvasConfig(name, titl);
           for (int iSt = 0; iSt < nSt; ++iSt) {
@@ -238,7 +238,7 @@ void Qa::Init()
           AddCanvasConfig(canv);
         }
         {  // ZX and ZY
-          auto name = format("ca_hit_{}_occupancy_zx_zy", setNm);
+          auto name = format("{}_ca_hit_{}_occupancy_zx_zy", GetTaskName(), setNm);
           auto titl = format("{} hit occupancy in different stations in ZX and ZY planes", setTl);
           auto canv = CanvasConfig(name, titl);
           {  // ZX
@@ -259,7 +259,7 @@ void Qa::Init()
         }
       }
       if (kDebug) {
-        auto name = format("ca_hit_usage_xy");
+        auto name = format("{}_ca_hit_usage_xy", GetTaskName());
         auto titl = format("Hit usage in different stations in XY plane");
         auto canv = CanvasConfig(name, titl);
         for (int iSt = 0; iSt < nSt; ++iSt) {
@@ -273,7 +273,7 @@ void Qa::Init()
 
     // Tracks canvas
     {
-      auto canv = CanvasConfig("ca_tracks", "Tracking output QA");
+      auto canv = CanvasConfig(format("{}_ca_tracks", GetTaskName()), "Tracking output QA");
       {
         auto pad = PadConfig(true, true, false, false, true);
         pad.RegisterHistogram(fvphTrkPhiTheta[0], "colz");
diff --git a/algo/detectors/bmon/Hitfind.h b/algo/detectors/bmon/Hitfind.h
index 68d7d3a9b57e80099a6a4ce3854445622cca5384..0257a9b7483a588e0f06b89f54de477d08a1445a 100644
--- a/algo/detectors/bmon/Hitfind.h
+++ b/algo/detectors/bmon/Hitfind.h
@@ -45,11 +45,14 @@ namespace cbm::algo::bmon
     /// \param iThread  Index of thread
     Output_t operator()(gsl::span<CbmBmonDigi> digisIn, uint32_t iThread = 0);
 
-   private:  // members
     /// \brief Returns an index of the diamond by the address
     /// \param address  A hardware address of the digi
     size_t GetDiamondIndex(uint32_t address) const { return ((fSelectionBitmask & address) >> fSelectionBitsOffset); }
 
+    /// \brief  Gets diamond addresses vector
+    const PODVector<uint32_t>& GetDiamondAddresses() const { return fDiamondAddress; }
+
+   private:                         // members
     uint32_t fNofThreads;           ///< Number of threads
     uint32_t fSelectionBitsOffset;  ///< Number of bits to ther right from the first bit in the selection mask
     uint32_t fSelectionBitmask;     ///< Selection bitmask
diff --git a/algo/detectors/tof/Clusterizer.cxx b/algo/detectors/tof/Clusterizer.cxx
index caf6d34f758dcc976f9c70358f1c133605f1bbf6..1a182b62509860a32a86f5f4deb82a45c0a97758 100644
--- a/algo/detectors/tof/Clusterizer.cxx
+++ b/algo/detectors/tof/Clusterizer.cxx
@@ -12,6 +12,9 @@
 #include <iomanip>
 #include <iostream>
 #include <map>
+#include <numeric>
+
+#include <fmt/format.h>
 
 namespace cbm::algo::tof
 {
@@ -49,6 +52,8 @@ namespace cbm::algo::tof
   //Iterator-based version. Faster than index-based version.
   Clusterizer::resultType Clusterizer::buildClusters(std::vector<inputType>& input)
   {
+    size_t nInputDigis{
+      std::accumulate(input.begin(), input.end(), 0, [](size_t s, const auto& v) { return s + v.size(); })};
     // Hit variables
     Hit cluster;
 
@@ -72,6 +77,10 @@ namespace cbm::algo::tof
       lastChanPos.push_back(input[chan].begin());
     }
 
+    size_t nInputDigisUsed{0};
+    if (nInputDigis > 0) {
+      //std::cout << "------------- call: buildClusters: number of digis: " << nInputDigis << '\n';
+    }
     for (int32_t chan = 0; (size_t) chan < numChan; chan++) {
 
       // Set partition vectors
@@ -83,11 +92,18 @@ namespace cbm::algo::tof
         chanSizes.back() = 0;
         continue;
       }
+      nInputDigisUsed += input[chan].size();
       inputType& storDigi = input[chan];
       auto digiIt         = storDigi.begin();
 
+      if (std::distance(storDigi.begin(), storDigi.end())) {
+        //std::cout << "DISTANCE: " << std::distance(storDigi.begin(), storDigi.end()) << '\n';
+        for (const auto& digi : storDigi) {
+          std::string sAddress = fmt::format("{:#08x}", digi.first->GetAddress());
+          //std::cout << "   " << digi.first->GetTime() << "ns, address: " << sAddress  << '\n';
+        }
+      }
       while (1 < std::distance(digiIt, storDigi.end())) {
-
         while (digiIt->first->GetSide() == std::next(digiIt)->first->GetSide()) {  // Not one Digi of each end!
           digiIt++;
           if (2 > std::distance(digiIt, storDigi.end())) {
@@ -181,6 +197,10 @@ namespace cbm::algo::tof
       storDigi.clear();
     }  // for( int32_t chan = 0; chan < iNbCh; chan++ )
 
+    //if (nInputDigis> 0) {
+    //  std::cout << ">>>>>> " << nInputDigisUsed << "/" << nInputDigis << '\n';
+    //}
+
     // Now check if another hit/cluster is started
     // and save it if it's the case.
     if (0 < cluster.numChan()) {
diff --git a/algo/detectors/tof/Hitfind.cxx b/algo/detectors/tof/Hitfind.cxx
index 119db83b1a43a26b37db80abe1e919ec39953f00..5abf282f3aecabec76ed6b541cd8f2877962360a 100644
--- a/algo/detectors/tof/Hitfind.cxx
+++ b/algo/detectors/tof/Hitfind.cxx
@@ -28,7 +28,6 @@ namespace cbm::algo::tof
 
       for (int32_t Sm = 0; Sm < NbSm; Sm++) {
         for (int32_t Rpc = 0; Rpc < NbRpc; Rpc++) {
-
           auto par = std::make_unique<cbm::algo::tof::ClusterizerRpcPar>();
 
           HitfindSetup::Rpc rpcPar = setup.rpcs[SmType][Sm * NbRpc + Rpc];
diff --git a/algo/evselector/KfpfV0FinderConfig.h b/algo/evselector/KfpfV0FinderConfig.h
deleted file mode 100644
index cbeaec0a7685c5391065c3561f0ac44a3904c907..0000000000000000000000000000000000000000
--- a/algo/evselector/KfpfV0FinderConfig.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
-   SPDX-License-Identifier: GPL-3.0-only
-   Authors: Sergei Zharko [committer] */
-
-/// \file   KfpfV0FinderConfig.h
-/// \date   29.01.2025
-/// \brief  Configuration structure for V0 selector in mCBM
-/// \author Sergei Zharko <s.zharko@gsi.de>
-
-#pragma once
-
-#include "yaml/Yaml.h"
-
-#include <vector>
-
-namespace cbm::algo::kfpf
-{
-  /// \struct CutsKfpf
-  /// \brief  Cuts for the KFParticleFinder
-  struct CutsKfpf {
-    float minDecayLength;  ///< Minimal decay length of particles [cm]
-    float minDecayLDL;     ///< Minimal value of decay length to decay length error ratio
-    float maxChi2NdfPrim;  ///< Maximal chi2/NDF for primary particles (coming from the PV)
-    float maxChi2NdfGeo;   ///< Maximal chi2/NDF for V0 candidates
-
-    CBM_YAML_PROPERTIES(
-      yaml::Property(&CutsKfpf::minDecayLength, "min_decay_length", "Minimal decay length of particles [cm]"),
-      yaml::Property(&CutsKfpf::minDecayLDL, "min_decay_ldl", "Minimal value of decay length to decay length error ratio"),
-      yaml::Property(&CutsKfpf::maxChi2NdfPrim, "max_chi2_ndf_prim", "Maximal chi2/NDF for primary particles"),
-      yaml::Property(&CutsKfpf::maxChi2NdfGeo, "max_chi2_ndf_geo", "Maximal chi2/NDF for V0 candidates"));
-  };
-
-  /// \struct ParticlePid
-  /// \brief  PID and pre-selection cuts for a given particle
-  struct ParticlePid {
-    int pdg;             ///< PDG code for particle
-    double minDca;       ///< Minimal DCA to PV [cm]
-    double minVelocity;  ///< Minimal velocity [cm/ns]
-    double maxVelocity;  ///< Maximal velocity [cm/ns]
-
-    CBM_YAML_PROPERTIES(
-      yaml::Property(&ParticlePid::pdg, "pdg", "PDG code of the particle"),
-      yaml::Property(&ParticlePid::minDca, "min_dca", "Minimal DCA to PV [cm]"),
-      yaml::Property(&ParticlePid::minVelocity, "min_velocity", "Minimal velocity [cm/ns]"),
-      yaml::Property(&ParticlePid::maxVelocity, "max_velocity", "Maximal velocity [cm/ns]"));
-  };
-
-  /// \struct Cuts;
-  struct Cuts {
-    CutsKfpf kfpf;                       ///< KFParticleFinder specific cuts
-    std::vector<ParticlePid> particles;  ///< Daughter PID cuts and other properties
-
-    CBM_YAML_PROPERTIES(
-      yaml::Property(&Cuts::kfpf, "kfpf", "Specific cuts for the KFParticleFinder"),
-      yaml::Property(&Cuts::particles,  "particles", "Particle identification cuts and properties"));
-  };
-
-  /// \struct LambdaFinderConfig
-  /// \brief  Configuration for the V0 finder
-  struct V0FinderConfig {
-    Cuts cuts;                     ///< Different selection cuts
-    double tZeroOffset;            ///< Offset for T0 [ns]
-    double qpAssignedUncertainty;  ///< Assigned relative uncertainty for q/p estimation
-    int primaryAssignedPdg;        ///< Assigned PDG hypothesis for primary particles
-    int reconstructPdg;            ///< PDG of the particle, the decay of which is to be reconstructed
-
-    CBM_YAML_PROPERTIES(
-      yaml::Property(&V0FinderConfig::cuts, "cuts", "Different selection cuts"),
-      yaml::Property(&V0FinderConfig::tZeroOffset, "t0_offset", "The t0 offset [ns]"),
-      yaml::Property(&V0FinderConfig::qpAssignedUncertainty, "qa_uncertainty", "Assigned relative uncertainty for q/p"),
-      yaml::Property(&V0FinderConfig::primaryAssignedPdg, "primary_pdg", "Assigned PDG code for primary tracks"),
-      yaml::Property(&V0FinderConfig::reconstructPdg, "reconstruct_pdg", "PDG code of the particle to be reconstructed"));
-  };
-}  // namespace cbm::algo::kfpf
diff --git a/algo/evselector/RecoEventSelectorMonitor.h b/algo/evselector/RecoEventSelectorMonitor.h
index 41bc2ff13691a636060485442aea1e018348dae0..82c68535c758ac23cad2ddc4dcbd9b334a5b8c58 100644
--- a/algo/evselector/RecoEventSelectorMonitor.h
+++ b/algo/evselector/RecoEventSelectorMonitor.h
@@ -19,11 +19,12 @@ namespace cbm::algo::evselect
   /// \brief Counter keys for the event selector monitor
   enum class ECounter
   {
-    EventsTotal,      ///< Total number of events processed
-    EventsNeStsHits,  ///< Events with not enough STS hits
-    EventsNeTofHits,  ///< Events with enough STS hits, but not enough TOF hits
-    EventsNeTracks,   ///< Events with enough hits, but not enough tracks
-    EventsSelected,   ///< Number of selected events
+    EventsTotal,       ///< Total number of events processed
+    EventsNeStsHits,   ///< Events with not enough STS hits
+    EventsNeTofHits,   ///< Events with enough STS hits, but not enough TOF hits
+    EventsNeBmonHits,  ///< Events with not enough BMon hits
+    EventsNeTracks,    ///< Events with enough hits, but not enough tracks
+    EventsSelected,    ///< Number of selected events
     END
   };
 
@@ -32,6 +33,7 @@ namespace cbm::algo::evselect
   /* clang-format off */
   enum class ETimer {
     EventReconstruction,
+      BmonHitFinder,
       StsHitFinder,
       TofHitFinder,
       TrdHitFinder,
@@ -53,10 +55,12 @@ namespace cbm::algo::evselect
       SetCounterName(ECounter::EventsTotal, "total events");
       SetCounterName(ECounter::EventsNeStsHits, "events discarded by N STS hits");
       SetCounterName(ECounter::EventsNeTofHits, "events discarded by N TOF hits");
+      SetCounterName(ECounter::EventsNeBmonHits, "events discarded by N BMon hits");
       SetCounterName(ECounter::EventsNeTracks, "events discarded by N tracks");
       SetCounterName(ECounter::EventsSelected, "selected events");
 
       SetTimerName(ETimer::EventReconstruction, "event reconstruction");
+      SetTimerName(ETimer::BmonHitFinder, "hit finding in Bmon");
       SetTimerName(ETimer::StsHitFinder, "hit finding in STS");
       SetTimerName(ETimer::TofHitFinder, "hit finding in TOF");
       SetTimerName(ETimer::TrdHitFinder, "hit finding in TRD");
diff --git a/algo/global/ParFiles.cxx b/algo/global/ParFiles.cxx
index 38773a0e813f9f7e5d3aa259caab1a1544480412..7b73fe77991c059b37d962a3694a552e36e278fd 100644
--- a/algo/global/ParFiles.cxx
+++ b/algo/global/ParFiles.cxx
@@ -46,7 +46,7 @@ ParFiles::ParFiles(uint32_t runId)
 
       ca.mainConfig = "TrackingChainConfig_mcbm2022.yaml";
 
-      kfp.V0FinderConfig = "mcbm_kfp_lambda.yaml";
+      kfp.V0FinderConfig = "kfp_lambda_v22a.yaml";
       break;
 
     case Setup::mCBM2024_03:
@@ -71,7 +71,7 @@ ParFiles::ParFiles(uint32_t runId)
 
       ca.mainConfig = "TrackingChainConfig_mcbm2024.yaml";
 
-      kfp.V0FinderConfig = "mcbm_kfp_lambda.yaml";
+      kfp.V0FinderConfig = "kfp_lambda_v24a.yaml";
       break;
 
     case Setup::mCBM2024_05:
@@ -96,7 +96,7 @@ ParFiles::ParFiles(uint32_t runId)
 
       ca.mainConfig = "mcbm2024_05/TrackingChainConfig.yaml";
 
-      kfp.V0FinderConfig = "mcbm_kfp_lambda.yaml";
+      kfp.V0FinderConfig = "kfp_lambda_v24b.yaml";
       break;
 
     case Setup::mCBM2025_02:
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 0f933400df495d66049f9ef7e681c4091249806f..37c37b5088df2105c5d6d4aa562643bc52fb3de5 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -266,7 +266,7 @@ void Reco::Init(const Options& opts)
 
     // Tracking in event reconstruction
     if (fQaManager != nullptr && Opts().Has(QaStep::Tracking)) {
-      fTracking = std::make_unique<TrackingChain>(ECbmRecoMode::EventByEvent, fQaManager, "CaEvent");
+      fTrackingEvent = std::make_unique<TrackingChain>(ECbmRecoMode::EventByEvent, fQaManager, "CaEvent");
     }
     else {
       fTrackingEvent = std::make_unique<TrackingChain>(ECbmRecoMode::EventByEvent);
@@ -277,6 +277,7 @@ void Reco::Init(const Options& opts)
 
     fV0Finder = std::make_unique<V0FinderChain>();
     fV0Finder->SetContext(&fContext);
+    fV0Finder->SetBmonDefinedAddresses(fBmonHitFinder->GetDiamondAddresses());
     fV0Finder->Init();
   }
 
@@ -524,8 +525,10 @@ bool Reco::ReconstructEvent(const DigiEvent& digiEvent)
   RecoResults recoEvent;
   //* BMON hit reconstruction
   {
-    auto [calDigis, calMonitor]          = (*fBmonCalibrator)(recoEvent.fBmon);
+    fEvSelectingMonitor.StartTimer(evselect::ETimer::BmonHitFinder);
+    auto [calDigis, calMonitor]          = (*fBmonCalibrator)(digiEvent.fBmon);
     auto [hits, hitMonitor, digiIndices] = (*fBmonHitFinder)(calDigis);
+    fEvSelectingMonitor.StopTimer(evselect::ETimer::BmonHitFinder);
     if (fBmonHitFinderQa != nullptr) {
       fBmonHitFinderQa->RegisterDigis(&calDigis);
       fBmonHitFinderQa->RegisterHits(&hits);
diff --git a/algo/global/RecoResults.h b/algo/global/RecoResults.h
index 25a3f73a2a567d118aa3638b5feb85a6ba19e104..7795dda39642248cf56ea72f05843d2792f51da8 100644
--- a/algo/global/RecoResults.h
+++ b/algo/global/RecoResults.h
@@ -45,8 +45,8 @@ namespace cbm::algo
     PartitionedVector<bmon::Hit> bmonHits;
 
     ca::Vector<ca::Track> tracks;
-    ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackStsHitIndices;
-    ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackTofHitIndices;
-    ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackTrdHitIndices;
+    ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackStsHitIndices;  // [trk][hit][(iPart, iHit)]
+    ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackTofHitIndices;  // [trk][hit][(iPart, iHit)]
+    ca::Vector<std::vector<std::pair<uint32_t, uint32_t>>> trackTrdHitIndices;  // [trk][hit][(iPart, iHit)]
   };
 }  // namespace cbm::algo
diff --git a/algo/kfp/KfpV0Finder.cxx b/algo/kfp/KfpV0Finder.cxx
index 5677dc5f6dcafa86a2b7d5ee513a50e05d0985fd..5a5ddbc6e84370d9ad845f3c5ac6e08907ab794b 100644
--- a/algo/kfp/KfpV0Finder.cxx
+++ b/algo/kfp/KfpV0Finder.cxx
@@ -9,19 +9,87 @@
 
 #include "kfp/KfpV0Finder.h"
 
+#include "global/RecoResults.h"
+
+#include <algorithm>
+#include <limits>
+#include <sstream>
+
+using cbm::algo::RecoResults;
 using cbm::algo::kfp::V0Finder;
 
+// ---------------------------------------------------------------------------------------------------------------------
+//
+std::vector<double> V0Finder::CollectDca(const RecoResults& recoEvent) const
+{
+  std::vector<double> dca(recoEvent.trackStsHitIndices.size(), std::numeric_limits<double>::signaling_NaN());
+  const auto& stsHitIndices = recoEvent.trackStsHitIndices;
+  for (size_t iTrk = 0; iTrk < stsHitIndices.size(); ++iTrk) {
+    const auto& stsHitIndicesInTrack = stsHitIndices[iTrk];
+    if (stsHitIndicesInTrack.size() < 2) {  // less then two sts hits
+      continue;
+    }
+    auto [iPtFst, iHitFst] = stsHitIndicesInTrack[0];
+    auto [iPtSnd, iHitSnd] = stsHitIndicesInTrack[1];
+    dca[iTrk]              = EstimateDca(recoEvent.stsHits[iPtFst][iHitFst], recoEvent.stsHits[iPtSnd][iHitSnd]);
+  }
+  return dca;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+std::vector<double> V0Finder::CollectT0(gsl::span<const bmon::Hit> bmonHits) const
+{
+  std::vector<double> t0;
+  t0.reserve(bmonHits.size());
+  std::transform(bmonHits.begin(), bmonHits.end(), std::back_inserter(t0), [&](const auto& h) { return h.GetTime(); });
+  return t0;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+double V0Finder::EstimateDca(const sts::Hit& fst, const sts::Hit& snd) const
+{
+  double factor{(fst.Z() - fOrigin[2]) / (snd.Z() - fst.Z())};
+  double dcaX{fst.X() - fOrigin[0] - factor * (snd.X() - fst.X())};
+  double dcaY{fst.Y() - fOrigin[1] - factor * (snd.Y() - fst.Y())};
+  return std::sqrt(dcaX * dcaX + dcaY * dcaY);
+}
+
 // ---------------------------------------------------------------------------------------------------------------------
 //
 void V0Finder::Init() {}
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-CbmEventTriggers V0Finder::Process(const RecoResults&)
+CbmEventTriggers V0Finder::Process(const RecoResults& recoEvent)
 {
   CbmEventTriggers res;
   fEventMonitor.Reset();
   fEventMonitor.StartTimer(ETimer::Event);
+  fEventMonitor.IncrementCounter(ECounter::EventsTotal);
+
+  // ----- Define T0
+  // So far we cannot preselect a hit from multiple ones, we will be using all of them iteratively to find lambdas
+  auto vT0 = CollectT0(recoEvent.bmonHits[fBmonPartitionIndex]);
+  if (vT0.empty()) {
+    fEventMonitor.IncrementCounter(ECounter::EventsWoTzero);
+    return res;
+  }
+
+  //L_(info) << "------- Event: ";
+
+  // ----- Estimate DCA of tracks
+  // If a track has less then two STS hits, and undefined DCA value is stored
+  std::vector<double> vDca = CollectDca(recoEvent);
+
+  // ***** DEBUG: BEGIN
+  //for (auto dca: vDca) {
+  //  L_(info) << "dca=" << dca;
+  //}
+  // ***** DEBUG: END
+
+
   fEventMonitor.StopTimer(ETimer::Event);
   return res;
 }
diff --git a/algo/kfp/KfpV0Finder.h b/algo/kfp/KfpV0Finder.h
index e34e543d26b6d31dcfc0b528bd191d5e28aef32e..ef8b1e22b72a335fa7c38b807f1f28e0d4ea2adb 100644
--- a/algo/kfp/KfpV0Finder.h
+++ b/algo/kfp/KfpV0Finder.h
@@ -14,6 +14,7 @@
 #include "global/RecoResults.h"
 #include "kfp/KfpV0FinderMonitor.h"
 
+#include <limits>
 #include <memory>
 
 
@@ -60,7 +61,10 @@ namespace cbm::algo::kfp
     /// \brief  Processes a reconstructed data sample, returns a collection of fired triggers
     CbmEventTriggers Process(const RecoResults& recoEvent);
 
-    /// \brief  Sets minimal pion DCA to primary vertex
+    /// \brief  Sets an address of a reference BMON diamond
+    /// \param  iPartition  An index of the BMON hit partition: used to selected the hits from the particular config
+    void SetBmonPartitionIndex(int iPartition) { fBmonPartitionIndex = iPartition; }
+
     /// \param  dca  DCA [cm]
     void SetMinPionDca(double dca) { fMinPionDca = dca; }
 
@@ -68,6 +72,14 @@ namespace cbm::algo::kfp
     /// \param  dca  DCA [cm]
     void SetMinProtonDca(double dca) { fMinProtonDca = dca; }
 
+    /// \brief  Sets origin
+    /// \param  x  X-coordinate of the origin [cm]
+    /// \param  y  Y-coordinate of the origin [cm]
+    /// \param  z  Z-coordinate of the origin [cm]
+    // FIXME: for now origin is defined as the target center, later it can be changed
+    void SetOrigin(double x, double y, double z) { fOrigin = {x, y, z}; }
+
+    /// \brief  Sets minimal pion DCA to primary vertex
     /// \brief  Sets pion velocity range
     /// \param  vMin  Minimal velocity [cm/ns]
     /// \param  vMax  Maximal velocity [cm/ns]
@@ -116,13 +128,29 @@ namespace cbm::algo::kfp
     void SetLdLCut2D(float cut) { GetKFParticleFinder()->SetLdLCut2D(cut); }
 
    private:
+    /// \brief  Collects T0 values among the BMON hits
+    /// \param  bmonHits  A span of BMON hits
+    /// \return A vector of T0-s
+    ///
+    /// If multiple T0-s are found, the routine will run multiple times, until V0-candidates are found
+    std::vector<double> CollectT0(gsl::span<const bmon::Hit> bmonHits) const;
+
+    /// \brief  Collects a vector of DCA
+    /// \param  recoEvent  Instance of a reconstructed event
+    /// \return A vector of DCAs to origin
+    std::vector<double> CollectDca(const RecoResults& recoEvent) const;
+
+    /// \brief  Estimate DCA of a track to origin
+    /// \param  fst  first  STS hit
+    /// \param  snd  second STS hit
+    /// \return dca [cm]
+    double EstimateDca(const sts::Hit& fst, const sts::Hit& snd) const;
+
     //* Physical constants
     static constexpr double kPionMass{0.13957039};      ///< Pion mass [GeV/c2]
     static constexpr double kProtonMass{0.938272088};   ///< Proton mass [GeV/c2]
     static constexpr double kSpeedOfLight{29.9792458};  ///< Speed of light [cm/ns]
 
-    /// \brief An instance of the topology reconstructor
-    std::unique_ptr<KFParticleTopoReconstructor> fpTopoReconstructor{std::make_unique<KFParticleTopoReconstructor>()};
 
     V0FinderMonitorData_t fEventMonitor;  ///< Monitor data instance (per event)
 
@@ -136,5 +164,15 @@ namespace cbm::algo::kfp
     double fMaxBetaProton{1.};           ///< Maximal proton velocity (beta) [c]
     double fMinBetaPion{0.};             ///< Minimal proton velocity (beta) [c]
     double fMaxBetaPion{1.};             ///< Maximal proton velocity (beta) [c]
+
+
+    //* Run-time variables, provided by framework
+    int fBmonPartitionIndex{-1};                ///< Index of selected partition in BMON hit vector
+    std::array<double, 3> fOrigin{0., 0., 0.};  ///< Coordinates of origin [cm]
+
+    //* Auxilary variables
+
+    /// \brief An instance of the topology reconstructor
+    std::unique_ptr<KFParticleTopoReconstructor> fpTopoReconstructor{std::make_unique<KFParticleTopoReconstructor>()};
   };
 }  // namespace cbm::algo::kfp
diff --git a/algo/kfp/KfpV0FinderChain.cxx b/algo/kfp/KfpV0FinderChain.cxx
index 621f4d0d88b2b11216b31c2d8df07455678766cc..f41a0597ac8adce96b374ee90e3ff00e02cdaf34 100644
--- a/algo/kfp/KfpV0FinderChain.cxx
+++ b/algo/kfp/KfpV0FinderChain.cxx
@@ -70,10 +70,29 @@ try {
   const auto& pion{particles[iPion]};
   const auto& proton{particles[iProton]};
 
+  // ----- Define a BMON diamond
+  if (fBmonDefinedAddresses.empty()) {
+    throw std::runtime_error("kfp::V0FinderChain: BMON available addresses were not set");
+  }
+  int iBmonPartitionSelect = -1;
+  for (int iPart = 0; iPart < static_cast<int>(fBmonDefinedAddresses.size()); ++iPart) {
+    if (config.bmonAddress == fBmonDefinedAddresses[iPart]) {
+      iBmonPartitionSelect = iPart;
+      break;
+    }
+  }
+  if (iBmonPartitionSelect < 0) {
+    std::stringstream msg;
+    msg << "kfp::V0FinderChain: a reference BMON address ( " << std::hex << config.bmonAddress << std::dec
+        << " ) differs from ones, provided by hitfinder. Please check your configuration";
+    throw std::runtime_error(msg.str());
+  }
+
   // ----- Set the V0-finder properties
   // TODO: In future, there are will be a several instances of the V0Finder, each for a particular thread
   {
     //* Set particle PID properties
+    fFinder.SetBmonPartitionIndex(iBmonPartitionSelect);
     fFinder.SetMinPionDca(pion.minDca);
     fFinder.SetMinProtonDca(proton.minDca);
     fFinder.SetPionVelocityRange(pion.minVelocity, pion.maxVelocity);
diff --git a/algo/kfp/KfpV0FinderChain.h b/algo/kfp/KfpV0FinderChain.h
index c328750aac9dd2aa74d9226754a0ee7f71238630..630fc02e63e52d9e07dd89bf53669b3994224a0c 100644
--- a/algo/kfp/KfpV0FinderChain.h
+++ b/algo/kfp/KfpV0FinderChain.h
@@ -10,6 +10,7 @@
 #pragma once
 
 #include "CbmEventTriggers.h"
+#include "PODVector.h"
 #include "base/SubChain.h"
 #include "global/RecoResults.h"
 #include "kfp/KfpV0Finder.h"
@@ -49,16 +50,19 @@ namespace cbm::algo
     /// \brief Finalizes the instance (called in the end of the run)
     void Finalize();
 
+    /// \brief Sets BMON diamond addresses array
+    /// \note  The addresses must be taken from bmon::Hitfind::GetDiamondAddresses()
+    void SetBmonDefinedAddresses(const PODVector<uint32_t>& addresses) { fBmonDefinedAddresses = addresses; }
+
     /// \brief Initializes the instance (called in the beginning of the run)
     void Init();
 
     /// \brief  Processes an event, returns a collection of fired triggers
     EventOutput ProcessEvent(const RecoResults& recoEvent);
 
-
    private:
-    kfp::V0Finder fFinder;             ///< Instance of the V0-finding algorithm
-    kfp::V0FinderMonitor fMonitorRun;  ///< Monitor per run
-    uint32_t fBmonAddress;             ///< Address of selected BMON
+    kfp::V0Finder fFinder;                      ///< Instance of the V0-finding algorithm
+    kfp::V0FinderMonitor fMonitorRun;           ///< Monitor per run
+    PODVector<uint32_t> fBmonDefinedAddresses;  ///< Available addresses of BMON
   };
 }  // namespace cbm::algo
diff --git a/algo/kfp/KfpV0FinderConfig.h b/algo/kfp/KfpV0FinderConfig.h
index dacc3705d843874c33d196909dd85b2ac655294e..4bd992e0cb406145ad29495f89acfc00827b6622 100644
--- a/algo/kfp/KfpV0FinderConfig.h
+++ b/algo/kfp/KfpV0FinderConfig.h
@@ -69,6 +69,7 @@ namespace cbm::algo::kfp
   /// \brief  Configuration for the V0 finder
   struct V0FinderConfig {
     Cuts cuts;                     ///< Different selection cuts
+    uint32_t bmonAddress;  ///< Address of BMON diamond (if multiple alternative are present, only one must be selected)
     double tZeroOffset;            ///< Offset for T0 [ns]
     double qpAssignedUncertainty;  ///< Assigned relative uncertainty for q/p estimation
     int primaryAssignedPdg;        ///< Assigned PDG hypothesis for primary particles
@@ -76,6 +77,7 @@ namespace cbm::algo::kfp
 
     CBM_YAML_PROPERTIES(
       yaml::Property(&V0FinderConfig::cuts, "cuts", "Different selection cuts"),
+      yaml::Property(&V0FinderConfig::bmonAddress, "bmon_address", "Address of reference BMON diamond"),
       yaml::Property(&V0FinderConfig::tZeroOffset, "t0_offset", "The t0 offset [ns]"),
       yaml::Property(&V0FinderConfig::qpAssignedUncertainty, "qa_uncertainty", "Assigned relative uncertainty for q/p"),
       yaml::Property(&V0FinderConfig::primaryAssignedPdg, "primary_pdg", "Assigned PDG code for primary tracks"),
diff --git a/algo/kfp/interface/CMakeLists.txt b/algo/kfp/interface/CMakeLists.txt
index 8b037a70e5f554f7aa3871bae62b46e6ec5fbc88..ce26ad980038dfe6439bfb621a8ab61eba0e8552 100644
--- a/algo/kfp/interface/CMakeLists.txt
+++ b/algo/kfp/interface/CMakeLists.txt
@@ -3,35 +3,19 @@
 #  2) CbmKFParticleOfflineInterface -- a specific interface for the offline reconstruction in CBM.
 # The both libraries contain only the KFParticle core and do not include KFParticleTest or KFParticlePerformance.
 
-set(KFP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../external/KFParticle/KFParticle)
 
-set(SRCS
-  ${KFP_SOURCE_DIR}/KFParticle.cxx
-  ${KFP_SOURCE_DIR}/KFParticleBase.cxx
-  ${KFP_SOURCE_DIR}/KFParticleBaseSIMD.cxx
-  ${KFP_SOURCE_DIR}/KFParticleDatabase.cxx
-  ${KFP_SOURCE_DIR}/KFParticleFinder.cxx
-  ${KFP_SOURCE_DIR}/KFParticlePVReconstructor.cxx
-  ${KFP_SOURCE_DIR}/KFParticleSIMD.cxx
-  ${KFP_SOURCE_DIR}/KFParticleTopoReconstructor.cxx
-  ${KFP_SOURCE_DIR}/KFPEmcCluster.cxx
-  ${KFP_SOURCE_DIR}/KFPTrack.cxx
-  ${KFP_SOURCE_DIR}/KFPTrackVector.cxx
-  ${KFP_SOURCE_DIR}/KFPVertex.cxx
-  ${KFP_SOURCE_DIR}/KFVertex.cxx
-)
-
-### CbmKFParticleOnlineInterface
-add_library(CbmKFParticleOnlineInterface INTERFACE)
-target_include_directories(CbmKFParticleOnlineInterface INTERFACE)
-target_compile_definitions(CbmKFParticleOnlineInterface 
-  INTERFACE DO_TPCCATRACKER_EFF_PERFORMANCE NonhomogeneousField CBM USE_TIMERS)
-target_link_libraries(CbmKFParticleOnlineInterface 
-  INTERFACE ROOT::Core KFParticle)
-install(TARGETS CbmKFParticleOnlineInterface DESTINATION lib)
 
 if(NOT CBM_ONLINE_STANDALONE)
-### CbmKFParticleOfflineInterface
+  ### CbmKFParticleOnlineInterface
+  add_library(CbmKFParticleOnlineInterface INTERFACE)
+  target_include_directories(CbmKFParticleOnlineInterface INTERFACE)
+  target_compile_definitions(CbmKFParticleOnlineInterface 
+    INTERFACE DO_TPCCATRACKER_EFF_PERFORMANCE NonhomogeneousField CBM USE_TIMERS)
+  target_link_libraries(CbmKFParticleOnlineInterface 
+    INTERFACE ROOT::Core KFParticle)
+  install(TARGETS CbmKFParticleOnlineInterface DESTINATION lib)
+
+  ### CbmKFParticleOfflineInterface
   add_library(CbmKFParticleOfflineInterface INTERFACE)
   target_include_directories(CbmKFParticleOfflineInterface INTERFACE)
   target_compile_definitions(CbmKFParticleOfflineInterface 
@@ -39,4 +23,31 @@ if(NOT CBM_ONLINE_STANDALONE)
   target_link_libraries(CbmKFParticleOfflineInterface 
     INTERFACE ROOT::Core KFParticle)
   install(TARGETS CbmKFParticleOfflineInterface DESTINATION lib)
+else()
+  # Creating a replacement of the CbmKFParticleOnlineInterface library for a standalone mode
+  set(KFP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../external/KFParticle/KFParticle)
+
+  set(SRCS
+    ${KFP_SOURCE_DIR}/KFParticle.cxx
+    ${KFP_SOURCE_DIR}/KFParticleBase.cxx
+    ${KFP_SOURCE_DIR}/KFParticleBaseSIMD.cxx
+    ${KFP_SOURCE_DIR}/KFParticleDatabase.cxx
+    ${KFP_SOURCE_DIR}/KFParticleFinder.cxx
+    ${KFP_SOURCE_DIR}/KFParticlePVReconstructor.cxx
+    ${KFP_SOURCE_DIR}/KFParticleSIMD.cxx
+    ${KFP_SOURCE_DIR}/KFParticleTopoReconstructor.cxx
+    ${KFP_SOURCE_DIR}/KFPEmcCluster.cxx
+    ${KFP_SOURCE_DIR}/KFPTrack.cxx
+    ${KFP_SOURCE_DIR}/KFPTrackVector.cxx
+    ${KFP_SOURCE_DIR}/KFPVertex.cxx
+    ${KFP_SOURCE_DIR}/KFVertex.cxx
+  )
+  
+  add_library(CbmKFParticleOnlineInterface SHARED ${SRCS})
+  target_include_directories(CbmKFParticleOnlineInterface PUBLIC ${KFP_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
+  target_compile_definitions(CbmKFParticleOnlineInterface PUBLIC NonhomogeneousField CBM CBM_ONLINE)
+  target_link_libraries(CbmKFParticleOnlineInterface 
+                 PUBLIC Vc::Vc 
+                        ROOT::Core)
+  install(TARGETS CbmKFParticleOnlineInterface DESTINATION lib)
 endif()
diff --git a/algo/kfp/interface/RootTypesDef.h b/algo/kfp/interface/RootTypesDef.h
new file mode 100644
index 0000000000000000000000000000000000000000..e6eaa5500553524aaf4192d2a17108cd81b30da8
--- /dev/null
+++ b/algo/kfp/interface/RootTypesDef.h
@@ -0,0 +1,18 @@
+/* Copyright (C) 2025 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergei Zharko [committer] */
+
+/// \file   RootTypesDef.h
+/// \date   11.02.2025
+/// \brief  A compatibility header for the KFParticle code
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#pragma once
+
+#if __has_include(<RtypesCore.h>)
+#include <RtypesCore.h>
+#else
+using Bool_t  = bool;
+using Int_t   = int;
+using Float_t = float;
+#endif
diff --git a/algo/qa/QaData.cxx b/algo/qa/QaData.cxx
index 520ed4e522e022e742179e2ecb4c5f564b95da4d..6c42b3a5237df1cad00eacd1d9b9a579cf661f6d 100644
--- a/algo/qa/QaData.cxx
+++ b/algo/qa/QaData.cxx
@@ -57,6 +57,7 @@ try {
               << " with inconsistent flags (see HistogramMetadata::CheckFlags for detailes)";
           throw std::runtime_error(msg.str());
         }
+        L_(info) << " - task: " << task.fsName << ", histogram: " << h.GetName();
         vHistCfgs.emplace_back(h.GetName() + "!" + h.GetMetadataString(), task.fsName);
       };
       fsTaskNames += fmt::format("{} ", task.fsName);
diff --git a/core/data/CbmEventTriggers.h b/core/data/CbmEventTriggers.h
index 365d286e505137cabe5551fe180a53d4a2572318..841d86bd4a0bc680469527a9dfa2507c914a3cd6 100644
--- a/core/data/CbmEventTriggers.h
+++ b/core/data/CbmEventTriggers.h
@@ -73,7 +73,7 @@ class CbmEventTriggers {
   std::string ToString() const;
 
  private:
-  Trigger_t fTriggers;
+  Trigger_t fTriggers{0};
 
 #if !defined(NO_ROOT) && !XPU_IS_HIP_CUDA
   ClassDefNV(CbmEventTriggers, 1);
diff --git a/core/data/tof/CbmTofAddress.cxx b/core/data/tof/CbmTofAddress.cxx
index 71554dd1ad19a3a1523842d603a5e9aff97ae20a..29c1573452a1713f962b5a4347e47577000aca0e 100644
--- a/core/data/tof/CbmTofAddress.cxx
+++ b/core/data/tof/CbmTofAddress.cxx
@@ -66,4 +66,3 @@ std::string CbmTofAddress::ToString(int32_t address)
   msg << ", RpcType=" << setw(2) << CbmTofAddress::GetRpcType(address);
   return msg.str();
 }
-
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
index d0843683605e1ffeec46e52a02158a289405d0ab..9328a585c1d7b5ed3640fea9f1126a30a34820bd 100644
--- a/external/CMakeLists.txt
+++ b/external/CMakeLists.txt
@@ -70,6 +70,7 @@ if(DOWNLOAD_EXTERNALS)
   Include(InstallYamlCpp.cmake)
   Include(InstallPoolSTL.cmake)
 
+
   if (NOT CBM_ONLINE_STANDALONE) # Not required for online standalone
 
     Include(InstallKFParticle.cmake)
@@ -86,8 +87,22 @@ if(DOWNLOAD_EXTERNALS)
       Include(InstallQa.cmake)
     endif()
 
+  else()
+
+    # Download KFParticle source from the repository, but do not install it
+    download_project_if_needed(PROJECT kfparticle_source
+      GIT_REPOSITORY "https://github.com/szharko/KFParticle.git"
+      GIT_TAG "d088e3e019ac588a0528aa560ceaca247580d881" # CBM_ONLINE directive to turn off dependencies on ROOT
+      SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/KFParticle
+      CONFIGURE_COMMAND ""
+      BUILD_COMMAND ""
+      INSTALL_COMMAND ""
+    )
+  
   endif()
 
+  
+
 else()
   # Define targets which are needed by CbmRoot but are not available
   # whithout the external packages
diff --git a/macro/KF/configs/mcbm_kfpf_lambda.yaml b/macro/KF/configs/mcbm_kfpf_lambda.yaml
index 01e77b1855b37c5f3f763f6f1175faf7ff89af12..fc5599d3723479b6fc379a60f56e3d0d5983131c 100644
--- a/macro/KF/configs/mcbm_kfpf_lambda.yaml
+++ b/macro/KF/configs/mcbm_kfpf_lambda.yaml
@@ -7,11 +7,11 @@
 # \brief  Standard configuration for the lambda finding in mCBM
 # \author Sergei Zharko <s.zharko@gsi.de>
 
-reconstruct_pdg: 3122  # Lambda -> pi- p
-
-t0_offset: 0.12      # Time offset for T0 [ns]
-qa_uncertainty: 0.1  # Assigned relative uncertainty for the q/p estimation
-primary_pdg: 321     # Assigned PDG code for primary tracks
+reconstruct_pdg: 3122     # Lambda -> pi- p
+bmon_address: 0x00202806  # Address of reference BMON diamond
+t0_offset: 0.12           # Time offset for T0 [ns]
+qa_uncertainty: 0.1       # Assigned relative uncertainty for the q/p estimation
+primary_pdg: 321          # Assigned PDG code for primary tracks
 
 cuts:  # Different cuts
   kfp:  # KFParticleFinder specific cuts