diff --git a/algo/detectors/bmon/Calibrate.cxx b/algo/detectors/bmon/Calibrate.cxx
index 70d99daeb463f1563bd4594e6c1b0a03f56a384b..53b40e6b13fdec26b63778780af01d1a0d696ff8 100644
--- a/algo/detectors/bmon/Calibrate.cxx
+++ b/algo/detectors/bmon/Calibrate.cxx
@@ -13,6 +13,7 @@
 #include "CbmTofAddress.h"
 #include "util/TimingsFormat.h"
 
+#include <bitset>
 #include <chrono>
 
 using cbm::algo::bmon::Calibrate;
@@ -21,36 +22,56 @@ using fles::Subsystem;
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
-Calibrate::Calibrate(CalibrateSetup setup) : fSetup(setup), fSmOffset(1, 0), fRpcOffset(1, 0)
+Calibrate::Calibrate(CalibrateSetup setup) : fSetup(setup), fSelectionBitsOffset(0)
 {
   // Initialize offset arrays for channel deadtime check
-  int32_t NbSm  = fSetup.NbSm;
-  int32_t NbRpc = fSetup.NbRpc;
-  for (int32_t Sm = 0; Sm < NbSm; Sm++) {
-    fSmOffset.push_back(fSmOffset.back() + NbRpc);
-    for (int32_t Rpc = 0; Rpc < NbRpc; Rpc++) {
-      int32_t NbChan = fSetup.rpcs[Sm * NbRpc + Rpc].chanPar.size();
-      fRpcOffset.push_back(fRpcOffset.back() + 2 * NbChan);  //Factor 2 for channel sides
+  int nDiamondsInSetup = fSetup.diamonds.size();
+  if (nDiamondsInSetup == 0) {
+    throw std::runtime_error("No diamonds found in the BMON calibration config");
+  }
+  if (!(fSetup.selectionMask) != (nDiamondsInSetup == 1)) {
+    throw std::runtime_error("Wrong diamond selection mask: for a single diamond it must be zero, and for multiple"
+                             " diamonds it must be non-zero");
+  }
+  if (nDiamondsInSetup > 1) {
+    // Define the selection bit offset
+    while (!((fSetup.selectionMask >> fSelectionBitsOffset) % 2)) {
+      ++fSelectionBitsOffset;
     }
+
+    // Sort the diamonds in the setup by their SM or Side or other distinguishing index
+    std::sort(fSetup.diamonds.begin(), fSetup.diamonds.end(), [&](const auto& lhs, const auto& rhs) {
+      return GetDiamondIndex(lhs.refAddress) < GetDiamondIndex(rhs.refAddress);
+    });
   }
 
-  // **** DEBUG: BEGIN
-  for (size_t iO = 0; iO < fSmOffset.size(); ++iO) {
-    L_(info) << "SM offset: " << iO << ", " << fSmOffset[iO];
+  // Remove the channel information from the reference address
+  for (auto& diamond : fSetup.diamonds) {
+    diamond.refAddress = CbmTofAddress::GetModFullId(diamond.refAddress);
   }
-  for (size_t iO = 0; iO < fRpcOffset.size(); ++iO) {
-    L_(info) << "RPC offset: " << iO << ", " << fRpcOffset[iO];
+
+  // Calculate the channel offsets, needed for the dead time
+  fChannelOffset = std::vector<size_t>(nDiamondsInSetup + 1, 0);  // the last element -- total number of channels
+  for (int32_t iD = 0; iD < nDiamondsInSetup; ++iD) {
+    fChannelOffset[iD + 1] = fChannelOffset[iD] + fSetup.diamonds[iD].chanPar.size();
   }
-  // **** DEBUG: END
+  fChannelDeadTime = std::vector<double>(fChannelOffset.back(), std::numeric_limits<double>::quiet_NaN());
 
-  fChannelDeadTime = std::vector<double>(fRpcOffset.back(), std::numeric_limits<double>::quiet_NaN());
+  // **** DEBUG: BEGIN
+  for (size_t iO = 0; iO < fChannelOffset.size(); ++iO) {
+    L_(info) << "Channel offset: diamond=" << iO << ", offset=" << fChannelOffset[iO];
+  }
+  L_(info) << "Selection mask: 0b" << std::bitset<32>(fSetup.selectionMask);
+  L_(info) << "Bits offset: " << static_cast<uint32_t>(fSelectionBitsOffset);
+  L_(info) << "Size of the channel dead time vector: " << fChannelDeadTime.size();
+  // **** DEBUG: END
 }
 
 // ---------------------------------------------------------------------------------------------------------------------
 //
 Calibrate::resultType Calibrate::operator()(gsl::span<const CbmBmonDigi> digiIn)
 {
-  xpu::push_timer("TofCalibrate");
+  xpu::push_timer("BmonCalibrate");
   xpu::t_add_bytes(digiIn.size_bytes());
 
   // --- Output data
@@ -60,79 +81,60 @@ Calibrate::resultType Calibrate::operator()(gsl::span<const CbmBmonDigi> digiIn)
   auto& monitor    = result.second;
   calDigiOut.reserve(digiIn.size());
 
+  // Reset the channel dead time
   std::fill(fChannelDeadTime.begin(), fChannelDeadTime.end(), std::numeric_limits<double>::quiet_NaN());
 
+  const auto& diamonds = fSetup.diamonds;
   for (const auto& digi : digiIn) {
     uint32_t address = static_cast<uint32_t>(digi.GetAddress());
-    const int32_t SmType{CbmTofAddress::GetSmType(address)};
-    const int32_t Sm{CbmTofAddress::GetSmId(address)};
-    const int32_t Rpc{CbmTofAddress::GetRpcId(address)};
-    const int NbRpc{fSetup.NbRpc};
-
-    int32_t Chan{CbmTofAddress::GetChannelId(address)};
-    int32_t Side{CbmTofAddress::GetChannelSide(address)};
-
-    // NOTE: Follow the hack in the CbmTofEventClusterizer::Exec() for the BMON digis and change the address
-    //       of calibrated digis. In general it is incorrect and needs further investigation.
-    uint32_t calAddress = address;
-    if (Side == 1) {
-      Side = 0;
-      Chan += 6;
-      calAddress = CbmTofAddress::GetUniqueAddress(Sm, Rpc, Chan, Side, SmType);
-    }
-
-    auto& rpcs = fSetup.rpcs;
-    if (SmType != fSetup.SmType || Sm * NbRpc + Rpc >= static_cast<int>(rpcs.size())) {
+    int32_t iChannel = CbmTofAddress::GetChannelId(address);
+    size_t iDiamond  = GetDiamondIndex(address);
+    if (iDiamond >= diamonds.size()
+        || static_cast<uint32_t>(CbmTofAddress::GetModFullId(address)) != diamonds[iDiamond].refAddress) {
       monitor.fDigiCalibUnknownRPC++;
-      L_(error) << "Unknown BMON digi address: " << CbmTofAddress::ToString(calAddress);
+      L_(error) << "Unknown BMON digi address: " << CbmTofAddress::ToString(address) << ", iDiamond = " << iDiamond;
       continue;
     }
 
-    CalibrateSetup::Rpc& rpcPar      = fSetup.rpcs[Sm * NbRpc + Rpc];
-    CalibrateSetup::Channel& chanPar = rpcPar.chanPar[Chan];
+    const auto& diamondPar = diamonds[iDiamond];
+    const auto& channelPar = diamondPar.chanPar[iChannel];
 
     // Check dead time
-    // FIXME: BMON digis (must) have only one side -> Fix the offsets, when mcbm2024_05 will be fixed
-    const size_t chanIdx  = fRpcOffset[fSmOffset[Sm] + Rpc] + Chan + Side * rpcPar.chanPar.size();
-    const double deadTime = fChannelDeadTime[chanIdx];
+    const size_t iChannelGlb = fChannelOffset[iDiamond] + iChannel;
+    const double deadTime    = fChannelDeadTime[iChannelGlb];
 
     if (!std::isnan(deadTime) && digi.GetTime() <= deadTime) {
-      fChannelDeadTime[chanIdx] = digi.GetTime() + rpcPar.channelDeadtime;
+      fChannelDeadTime[iChannelGlb] = digi.GetTime() + diamondPar.channelDeadtime;
       monitor.fDigiDeadTimeCount++;
       continue;
     }
-    fChannelDeadTime[chanIdx] = digi.GetTime() + rpcPar.channelDeadtime;
+    fChannelDeadTime[iChannelGlb] = digi.GetTime() + diamondPar.channelDeadtime;
 
     // Create calibrated digi
     CbmBmonDigi& pCalDigi = calDigiOut.emplace_back(digi);
-    pCalDigi.SetAddress(calAddress);
-
-    // Check if channel sides need to be swapped
-    if (rpcPar.swapChannelSides) {
-      pCalDigi.SetAddress(CbmTofAddress::GetUniqueAddress(Sm, Rpc, Chan, (0 == Side) ? 1 : 0, SmType));
-    }
+    pCalDigi.SetAddress(address);
 
     // calibrate Digi Time
-    pCalDigi.SetTime(pCalDigi.GetTime() - chanPar.vCPTOff[Side]);
+    pCalDigi.SetTime(pCalDigi.GetTime() - channelPar.vCPTOff);
 
     // subtract Offset
-    const double dTot = std::max(pCalDigi.GetCharge() - chanPar.vCPTotOff[Side], 0.001);
+    const double dTot = std::max(pCalDigi.GetCharge() - channelPar.vCPTotOff, 0.001);
 
     // calibrate Digi charge (corresponds to TOF ToT)
-    pCalDigi.SetCharge(dTot * chanPar.vCPTotGain[Side]);
+    pCalDigi.SetCharge(dTot * channelPar.vCPTotGain);
 
     // walk correction
-    std::vector<double>& walk = chanPar.vCPWalk[Side];
-    const double dTotBinSize  = (rpcPar.TOTMax - rpcPar.TOTMin) / rpcPar.numClWalkBinX;
-    int32_t iWx               = std::max((int32_t)((pCalDigi.GetCharge() - rpcPar.TOTMin) / dTotBinSize), 0);
-    iWx                       = std::min(iWx, rpcPar.numClWalkBinX - 1);
+    const std::vector<double>& walk = channelPar.vCPWalk;
+    const double dTotBinSize        = (diamondPar.TOTMax - diamondPar.TOTMin) / diamondPar.numClWalkBinX;
+    int32_t iWx                     = std::max((int32_t)((pCalDigi.GetCharge() - diamondPar.TOTMin) / dTotBinSize), 0);
+    iWx                             = std::min(iWx, diamondPar.numClWalkBinX - 1);
 
-    const double dDTot = (pCalDigi.GetCharge() - rpcPar.TOTMin) / dTotBinSize - (double) iWx - 0.5;
+    const double dDTot = (pCalDigi.GetCharge() - diamondPar.TOTMin) / dTotBinSize - (double) iWx - 0.5;
     double dWT         = walk[iWx];
 
     // linear interpolation to next bin
     if (dDTot > 0) {
-      if (iWx < rpcPar.numClWalkBinX - 1) {
+      if (iWx < diamondPar.numClWalkBinX - 1) {
         dWT += dDTot * (walk[iWx + 1] - walk[iWx]);
       }
     }
diff --git a/algo/detectors/bmon/Calibrate.h b/algo/detectors/bmon/Calibrate.h
index 291a6882b4074035b2e0c3f01429dff069806a08..72d3914794d5bfa1161e1ee37052e4d658625b25 100644
--- a/algo/detectors/bmon/Calibrate.h
+++ b/algo/detectors/bmon/Calibrate.h
@@ -13,7 +13,6 @@
 #include "PartitionedVector.h"
 #include "bmon/CalibrateSetup.h"
 #include "tof/Calibrate.h"  // for the monitor data
-#include "tof/Clusterizer.h"
 
 #include <gsl/span>
 #include <optional>
@@ -42,9 +41,15 @@ namespace cbm::algo::bmon
     resultType operator()(gsl::span<const CbmBmonDigi> digiIn);
 
    private:
+    /// \brief  A digi address
+    size_t GetDiamondIndex(uint32_t address) const
+    {
+      return ((fSetup.selectionMask & address) >> fSelectionBitsOffset);
+    }
+
     CalibrateSetup fSetup;                 ///< Parameters of calibrator
-    std::vector<double> fChannelDeadTime;  ///< Storage for dead time check
-    std::vector<size_t> fSmOffset;         ///< Super module offset
-    std::vector<size_t> fRpcOffset;        ///< RPC offset
+    std::vector<size_t> fChannelOffset;    ///< Channel offset: offset for the channel index of each diamond
+    std::vector<double> fChannelDeadTime;  ///< Channel dead time
+    uint32_t fSelectionBitsOffset;         ///< Number of bits to ther right from the first bit in the selection mask
   };
 }  // namespace cbm::algo::bmon
diff --git a/algo/detectors/bmon/CalibrateSetup.h b/algo/detectors/bmon/CalibrateSetup.h
index 0d9dedd93c2b547e3f40768988dfa5c2d003233c..26803bd010da857a78908b48da369e043566dba7 100644
--- a/algo/detectors/bmon/CalibrateSetup.h
+++ b/algo/detectors/bmon/CalibrateSetup.h
@@ -22,12 +22,12 @@ namespace cbm::algo::bmon
   /// \struct  CalibrateSetup
   /// \brief   BMON calibration per channel
   struct CalibrateSetup {
-
+    // FIXME: remove 'v' from non-vector variable names
     struct Channel {
-      std::vector<double> vCPTOff;
-      std::vector<double> vCPTotGain;
-      std::vector<double> vCPTotOff;
-      std::vector<std::vector<double>> vCPWalk;
+      double vCPTOff;
+      double vCPTotGain;
+      double vCPTotOff;
+      std::vector<double> vCPWalk;
 
       CBM_YAML_PROPERTIES(yaml::Property(&Channel::vCPTOff, "vCPTOff", "CPT offset"),
                         yaml::Property(&Channel::vCPTotGain, "vCPTotGain", "CP time over threshold gain"),
@@ -35,7 +35,8 @@ namespace cbm::algo::bmon
                         yaml::Property(&Channel::vCPWalk, "vCPWalk", "CP walk correction", YAML::Block, YAML::Flow));
     };
 
-    struct Rpc {
+    struct Diamond {
+      uint32_t refAddress;
       int32_t numClWalkBinX;
       double TOTMax;
       double TOTMin;
@@ -43,25 +44,23 @@ namespace cbm::algo::bmon
       double channelDeadtime;
       std::vector<Channel> chanPar;
 
-      CBM_YAML_PROPERTIES(yaml::Property(&Rpc::numClWalkBinX, "numClWalkBinX", "number of walk correction bins"),
-                        yaml::Property(&Rpc::TOTMax, "TOTMax", "maximum time over threshold"),
-                        yaml::Property(&Rpc::TOTMin, "TOTMin", "minimum time over threshold"),
-                        yaml::Property(&Rpc::swapChannelSides, "swapChannelSides", "flag for swapping channel sides"),
-                        yaml::Property(&Rpc::channelDeadtime, "channelDeadtime", "channel dead time"),
-                        yaml::Property(&Rpc::chanPar, "chanPar", "channel parameters"));
+      CBM_YAML_PROPERTIES(
+                        yaml::Property(&Diamond::refAddress, "refAddress", "reference HW address to distinguish this BMON"),
+                        yaml::Property(&Diamond::numClWalkBinX, "numClWalkBinX", "number of walk correction bins"),
+                        yaml::Property(&Diamond::TOTMax, "TOTMax", "maximum time over threshold"),
+                        yaml::Property(&Diamond::TOTMin, "TOTMin", "minimum time over threshold"),
+                        yaml::Property(&Diamond::swapChannelSides, "swapChannelSides", "flag for swapping channel sides"),
+                        yaml::Property(&Diamond::channelDeadtime, "channelDeadtime", "channel dead time"),
+                        yaml::Property(&Diamond::chanPar, "chanPar", "channel parameters"));
     };
 
     /* Members */
-    int32_t SmType;
-    int32_t NbSm;
-    int32_t NbRpc;
-    std::vector<Rpc> rpcs;
+    uint32_t selectionMask;
+    std::vector<Diamond> diamonds;
 
     CBM_YAML_PROPERTIES(
-      yaml::Property(&CalibrateSetup::SmType, "SmType", "Super module type"),
-      yaml::Property(&CalibrateSetup::NbSm, "NbSm", "Number of SMs"),
-      yaml::Property(&CalibrateSetup::NbRpc, "NbRpc", "Number of RPCs"),
-      yaml::Property(&CalibrateSetup::rpcs, "rpcs", "Parameters of RPCs"));
+      yaml::Property(&CalibrateSetup::selectionMask, "selectionMask", "A mask to distinguish between different diamonds"),
+      yaml::Property(&CalibrateSetup::diamonds, "diamonds", "Parameters of each diamond"));
   };
 
 }  // namespace cbm::algo::bmon
diff --git a/algo/global/Reco.cxx b/algo/global/Reco.cxx
index 9bdc35bb6bf856c443779334dee966ee848a8a1d..b16a463d0758b0af1d13c8c5a2154028e754df18 100644
--- a/algo/global/Reco.cxx
+++ b/algo/global/Reco.cxx
@@ -390,7 +390,7 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
       std::set<uint32_t> bmonFoundAddressesUnp;  // found addresses among unpacked bmon digis
       std::set<uint32_t> bmonFoundAddressesCal;  // found addresses among clalibrated bmon digis
 
-      int nEvents = 20;  //events.size();
+      int nEvents = events.size();
       for (int iE = 0; iE < nEvents; ++iE) {
         //L_(info) << "-------------- event #" << iE;
         const auto& event = events[iE];
@@ -428,9 +428,9 @@ RecoResults Reco::Run(const fles::Timeslice& ts)
           stsMinT = std::min(stsMinT, digi.GetTime());
           stsMaxT = std::max(stsMaxT, digi.GetTime());
         }
-        L_(info) << "BMON time: " << bmonMinT << ", " << bmonMaxT << ", " << (bmonMaxT - bmonMinT);
-        L_(info) << "TOF time: " << tofMinT << ", " << tofMaxT << ", " << (tofMaxT - tofMinT);
-        L_(info) << "STS time: " << stsMinT << ", " << stsMaxT << ", " << (stsMaxT - stsMinT);
+        //L_(info) << "BMON time: " << bmonMinT << ", " << bmonMaxT << ", " << (bmonMaxT - bmonMinT);
+        //L_(info) << "TOF time: " << tofMinT << ", " << tofMaxT << ", " << (tofMaxT - tofMinT);
+        //L_(info) << "STS time: " << stsMinT << ", " << stsMaxT << ", " << (stsMaxT - stsMinT);
       }
       L_(info) << "!!!! Found addresses in BMON after unpacking: ";
       for (auto address : bmonFoundAddressesUnp) {
diff --git a/core/data/tof/CbmTofAddress.h b/core/data/tof/CbmTofAddress.h
index 3abf9b170309c5d97d0ee02f8a8fe01d7d2651be..d174064bf263428eb7fb2f6a8cc87a4b9bf9351f 100644
--- a/core/data/tof/CbmTofAddress.h
+++ b/core/data/tof/CbmTofAddress.h
@@ -182,6 +182,7 @@ public:
   static std::string ToString(int32_t address);
 
  private:
+  // FIXME: SZh 7.2.2025: Make these fields constexpr
   /**
    ** To adapt the address sub-fields repartition in size,
    ** you just need to change number of bits of the two sub-fields changing length.
diff --git a/external/InstallParameter.cmake b/external/InstallParameter.cmake
index b368899baf13fbb817e5b97a7dcb7cb6fb5fd3ed..74e6f43126f4c5990ecbe4300caade7e4469b631 100644
--- a/external/InstallParameter.cmake
+++ b/external/InstallParameter.cmake
@@ -1,7 +1,5 @@
 set(PARAMETER_VERSION ab9972f137bc52efd58bf3672e670a2d4fbcb1be) # 2025/02/11
 set(PARAMETER_SRC_URL "https://git.cbm.gsi.de/CbmSoft/cbmroot_parameter.git")
-#set(PARAMETER_VERSION 96b2189ac86b3d49c32f63da76e68f66544bba55) # 2025/05/02, BMON hitfinder parameters for online
-#set(PARAMETER_SRC_URL "https://git.cbm.gsi.de/s.zharko/cbmroot_parameter.git")
 
 download_project_if_needed(PROJECT         Parameter_source
                            GIT_REPOSITORY  ${PARAMETER_SRC_URL}