diff --git a/reco/detectors/tof/unpack/CbmTofUnpackAlgo.cxx b/reco/detectors/tof/unpack/CbmTofUnpackAlgo.cxx
index 881ac5d8020a1ab3a1ef7bbf2b5fd5abd6abf53c..58ea492591fca09401021f9f6f80d87fbf1977f7 100644
--- a/reco/detectors/tof/unpack/CbmTofUnpackAlgo.cxx
+++ b/reco/detectors/tof/unpack/CbmTofUnpackAlgo.cxx
@@ -505,7 +505,7 @@ void CbmTofUnpackAlgo::ProcessHit(const critof001::Message& mess)
              << " at epoch " << fulEpochIndexInTs;
 
   if (fMonitor && 0x90 == fuCurrentMsSysId && 0 == uChannel) {  //
-    fMonitor->FillHitBmonMicroSpillHistos(dHitTime);
+    fMonitor->FillHitBmonMicroSpillHistos(fdCurrentMsTime, dHitTime);
   }
 
   /// Create output object and store it
diff --git a/reco/detectors/tof/unpack/CbmTofUnpackMonitor.cxx b/reco/detectors/tof/unpack/CbmTofUnpackMonitor.cxx
index d4e0e2c0815d2f6831b82a6187caab9694275238..e859e7341f4a62ae43b9684974587417bf653937 100644
--- a/reco/detectors/tof/unpack/CbmTofUnpackMonitor.cxx
+++ b/reco/detectors/tof/unpack/CbmTofUnpackMonitor.cxx
@@ -434,14 +434,6 @@ Bool_t CbmTofUnpackMonitor::ResetHistograms()
 
 Bool_t CbmTofUnpackMonitor::CreateBmonHistograms()
 {
-  if (fBmonScvdMode) {
-    fuNbChanBmon  = kuNbChanBmonScvd;
-    fuBmonChanMap = std::vector<UInt_t>(kuBmonChanMapScvd, kuBmonChanMapScvd + kuNbChanBmonScvd);
-  }
-  else {
-    fuNbChanBmon  = kuNbChanBmon;
-    fuBmonChanMap = std::vector<UInt_t>(kuBmonChanMap, kuBmonChanMap + kuNbChanBmon);
-  }
   fvuBmonHitCntChanMs.resize(fuNbChanBmon, 0);
   fvuBmonErrorCntChanMs.resize(fuNbChanBmon, 0);
   fvuBmonEvtLostCntChanMs.resize(fuNbChanBmon, 0);
@@ -999,7 +991,6 @@ void CbmTofUnpackMonitor::DrawBmonCanvases()
 }
 // -------------------------------------------------------------------------
 
-
 // -------------------------------------------------------------------------
 Bool_t CbmTofUnpackMonitor::CreateHistogramsMicroSpills()
 {
@@ -1187,17 +1178,157 @@ void CbmTofUnpackMonitor::DrawCanvasesMicroSpills()
 }
 // -------------------------------------------------------------------------
 
+// -------------------------------------------------------------------------
+Bool_t CbmTofUnpackMonitor::CreateHistogramsQFactors(Bool_t bBmon)
+{
+  std::string sFolder = "Q-Factors";
+
+  uint32_t uMinNbBins = 10;
+  uint32_t uMaxNbBins = 300000;
+
+  /// Initialize Vector storing Cycles inside TS
+  fvuQfactorIdxHistoCycleinTS.resize(fvdQfactorIntegrationNs.size(), 0);
+
+  std::vector<std::vector<uint32_t>> vuNbBinsHisto(fvdQfactorIntegrationNs.size(),
+                                                   std::vector<uint32_t>(fvdQfactorBinSizesNs.size(), 0));
+  fvuNbHistoCyclesPerTS.resize(fvdQfactorIntegrationNs.size(), 0);
+
+  fvhBmonQfactHisto.resize(fvdQfactorIntegrationNs.size(), std::vector<TH1*>(fvdQfactorBinSizesNs.size(), nullptr));
+  fvhBmonQfactQval.resize(fvdQfactorIntegrationNs.size(), std::vector<TH1*>(fvdQfactorBinSizesNs.size(), nullptr));
+  fvhBmonQfactMean.resize(fvdQfactorIntegrationNs.size(), std::vector<TH1*>(fvdQfactorBinSizesNs.size(), nullptr));
+
+  fvhBmonQfactBinCountDistribution.resize(fvdQfactorBinSizesNs.size(), nullptr);
+  fvhBmonQfactBinCountDistributionEvo.resize(fvdQfactorBinSizesNs.size(), nullptr);
+
+  for (uint32_t uHistSz = 0; uHistSz < fvdQfactorIntegrationNs.size(); ++uHistSz) {
+    /// Pre-check values before in spreadsheet to make sure integer !!!!
+    fvuNbHistoCyclesPerTS[uHistSz] = fdTsSizeNs / fvdQfactorIntegrationNs[uHistSz];
+
+    for (uint32_t uBinSz = 0; uBinSz < fvdQfactorBinSizesNs.size(); ++uBinSz) {
+      /// Pre-check values before in spreadsheet to make sure integer !!!!
+      vuNbBinsHisto[uHistSz][uBinSz] = fvdQfactorIntegrationNs[uHistSz] / fvdQfactorBinSizesNs[uBinSz];
+      if (uMinNbBins <= vuNbBinsHisto[uHistSz][uBinSz] /*&& vuNbBinsHisto[uHistSz][uBinSz] <= uMaxNbBins*/) {
+        fvhBmonQfactHisto[uHistSz][uBinSz] = new TH1D(
+          Form("BmonQfactBinHist_%09.0f_%05.0f", fvdQfactorIntegrationNs[uHistSz], fvdQfactorBinSizesNs[uBinSz]),
+          Form("Counts per %5.0f ns bin in cycle of range %9.0f ns, Bmon; Time in Cycle [ns]; Digis []",
+               fvdQfactorBinSizesNs[uBinSz], fvdQfactorIntegrationNs[uHistSz]),  //
+          vuNbBinsHisto[uHistSz][uBinSz], 0.0, fvdQfactorIntegrationNs[uHistSz]);
+
+        double_t dBinOffset = 1.0 / (2.0 * fvuNbHistoCyclesPerTS[uHistSz]);
+        fvhBmonQfactQval[uHistSz][uBinSz] =
+          new TH1D(Form("BmonQFactorEvo_%09.0f_%05.0f", fvdQfactorIntegrationNs[uHistSz], fvdQfactorBinSizesNs[uBinSz]),
+                   Form("Q Factor, %5.0f ns bin, %9.0f ns range, Bmon; Time in Run [TS]; Q Factor []",
+                        fvdQfactorBinSizesNs[uBinSz], fvdQfactorIntegrationNs[uHistSz]),  //
+                   fvuNbHistoCyclesPerTS[uHistSz] * fuQFactorMaxNbTs, 0.0 - dBinOffset, fuQFactorMaxNbTs - dBinOffset);
+
+        fvhBmonQfactMean[uHistSz][uBinSz] = new TH1D(
+          Form("BmonQfactMeanEvo_%09.0f_%05.0f", fvdQfactorIntegrationNs[uHistSz], fvdQfactorBinSizesNs[uBinSz]),
+          Form("Mean, %5.0f ns bin, %9.0f ns range, Bmon; Time in Run [TS]; Mean []", fvdQfactorBinSizesNs[uBinSz],
+               fvdQfactorIntegrationNs[uHistSz]),  //
+          fvuNbHistoCyclesPerTS[uHistSz] * fuQFactorMaxNbTs, 0.0 - dBinOffset, fuQFactorMaxNbTs - dBinOffset);
+
+        fuQfactorNbPlots++;
+
+        /// Add pointers to the vector with all histo for access by steering class
+        // AddHistoToVector(fvhBmonQfactHisto[uHistSz][uBinSz], sFolder);
+        AddHistoToVector(fvhBmonQfactQval[uHistSz][uBinSz], sFolder);
+        AddHistoToVector(fvhBmonQfactMean[uHistSz][uBinSz], sFolder);
+      }
+    }
+  }
+
+  sFolder = "BinCounts";
+  for (uint32_t uBinSz = 0; uBinSz < fvdQfactorBinSizesNs.size(); ++uBinSz) {
+    fvhBmonQfactBinCountDistribution[uBinSz] =
+      new TH1D(Form("BmonQfactBinCntDist_%5.0f", fvdQfactorBinSizesNs[uBinSz]),
+               Form("Counts per %5.0f ns bin Bmon; Digis []; Bins []", fvdQfactorBinSizesNs[uBinSz]),  //
+               10000, -0.5, 9999.5);
+    AddHistoToVector(fvhBmonQfactBinCountDistribution[uBinSz], sFolder);
+
+    fvhBmonQfactBinCountDistributionEvo[uBinSz] =
+      new TH2D(Form("BmonQfactBinCntDistEvo_%5.0f", fvdQfactorBinSizesNs[uBinSz]),
+               Form("Counts per %5.0f ns bin Bmon; Time in Run [TS];Digis []; Bins []", fvdQfactorBinSizesNs[uBinSz]),
+               fuQFactorMaxNbTs, 0.0, fuQFactorMaxNbTs, 1000, -0.5, 999.5);
+    AddHistoToVector(fvhBmonQfactBinCountDistributionEvo[uBinSz], sFolder);
+  }
+
+  return kTRUE;
+}
+
+Bool_t CbmTofUnpackMonitor::ResetHistogramsQFactors(Bool_t /*bResetTime*/)
+{
+  // No reset possible as absolute time in run
+  return kTRUE;
+}
+
+void CbmTofUnpackMonitor::DrawCanvasesQFactors(Bool_t bBmon)
+{
+  std::string sFolder = "canvases";
+
+  uint16_t nPadX = std::ceil(std::sqrt(fuQfactorNbPlots));
+  uint16_t nPadY = std::ceil(1.0 * fuQfactorNbPlots / nPadX);
+
+  fcBmonQFactorVal = new TCanvas("cBmonQFactorVal", "Q-Factor values for various bins sizes and integration time");
+  fcBmonQFactorVal->Divide(nPadX, nPadY);
+
+  fcBmonQFactorMean = new TCanvas("cBmonQFactorMean", "Mean bin counts for various bins sizes and integration time");
+  fcBmonQFactorMean->Divide(nPadX, nPadY);
+
+  uint32_t uPadIdx = 1;
+  for (uint32_t uHistSz = 0; uHistSz < fvdQfactorIntegrationNs.size(); ++uHistSz) {
+    for (uint32_t uBinSz = 0; uBinSz < fvdQfactorBinSizesNs.size(); ++uBinSz) {
+      if (nullptr != fvhBmonQfactQval[uHistSz][uBinSz]) {
+        fcBmonQFactorVal->cd(uPadIdx);
+        gPad->SetGridx();
+        gPad->SetGridy();
+        fvhBmonQfactQval[uHistSz][uBinSz]->SetLineColor(kBlue);
+        fvhBmonQfactQval[uHistSz][uBinSz]->SetLineWidth(2);
+        fvhBmonQfactQval[uHistSz][uBinSz]->GetYaxis()->SetRangeUser(0., fvdQfactorHistMax[uBinSz]);
+        fvhBmonQfactQval[uHistSz][uBinSz]->Draw("hist");
+
+        fcBmonQFactorMean->cd(uPadIdx);
+        gPad->SetGridx();
+        gPad->SetGridy();
+        fvhBmonQfactMean[uHistSz][uBinSz]->SetLineColor(kBlue);
+        fvhBmonQfactMean[uHistSz][uBinSz]->SetLineWidth(2);
+        fvhBmonQfactMean[uHistSz][uBinSz]->Draw("hist");
+
+        uPadIdx++;
+      }
+    }
+  }
+  AddCanvasToVector(fcBmonQFactorVal, sFolder);
+  AddCanvasToVector(fcBmonQFactorMean, sFolder);
+
+  nPadX                   = std::ceil(std::sqrt(fvdQfactorBinSizesNs.size()));
+  nPadY                   = std::ceil(1.0 * fvdQfactorBinSizesNs.size() / nPadX);
+  fcBmonQFactorBinCntDist = new TCanvas("fcBmonQFactorBinCntDist", "BMon Q-Factor BinCntDist");
+  fcBmonQFactorBinCntDist->Divide(nPadX, nPadY);
+  uPadIdx = 1;
+  for (uint32_t uBinSz = 0; uBinSz < fvdQfactorBinSizesNs.size(); ++uBinSz) {
+    fcBmonQFactorBinCntDist->cd(uPadIdx);
+    gPad->SetGridx();
+    gPad->SetGridy();
+    gPad->SetLogx();
+    gPad->SetLogy();
+    fvhBmonQfactBinCountDistribution[uBinSz]->Draw("hist");
+
+    uPadIdx++;
+  }
+  AddCanvasToVector(fcBmonQFactorBinCntDist, sFolder);
+}
+// -------------------------------------------------------------------------
+
 // -------------------------------------------------------------------------
 void CbmTofUnpackMonitor::FillHitMonitoringHistos(const double_t& dMsTime, const uint32_t& uCurrCompIdx,
                                                   const uint32_t& uGet4Id, const uint32_t& uRawCh,
                                                   const uint32_t& uRemapCh, const uint32_t& uTot)
 {
-  if (-1 == fdStartTime) {
-    /// Initialize Start time for evolution plots
-    fdStartTime = dMsTime;
-  }
-
-  if (!fBmonMicroSpillMode) {
+  if (!fBmonMicroSpillMode && !fBmonQfactorsMode) {
+    if (-1 == fdStartTime) {
+      /// Initialize Start time for evolution plots
+      fdStartTime = dMsTime;
+    }
     /// ---> Per GET4 in system
     uint32_t uGet4InSys = uGet4Id + uCurrCompIdx * fuNbOfGet4PerComp;
     fhGet4MessType->Fill(uGet4InSys, 0);
@@ -1220,7 +1351,7 @@ void CbmTofUnpackMonitor::FillEpochMonitoringHistos(const uint32_t& uCurrCompIdx
                                                     const bool& bMissmMatch  // mess.getGdpbEpMissmatch()
 )
 {
-  if (!fBmonMicroSpillMode) {
+  if (!fBmonMicroSpillMode && !fBmonQfactorsMode) {
     /// ---> Per GET4 in system
     uint32_t uGet4InSys = uGet4Id + uCurrCompIdx * fuNbOfGet4PerComp;
     fhGet4MessType->Fill(uGet4InSys, 1);
@@ -1238,7 +1369,7 @@ void CbmTofUnpackMonitor::FillScmMonitoringHistos(const uint32_t& uCurrCompIdx,
                                                   const uint32_t& uType   // mess.getGdpbSlcType()
 )
 {
-  if (!fBmonMicroSpillMode) {
+  if (!fBmonMicroSpillMode && !fBmonQfactorsMode) {
     /// ---> Per GET4 in system
     uint32_t uGet4InSys = uGet4Id + uCurrCompIdx * fuNbOfGet4PerComp;
     fhGet4MessType->Fill(uGet4InSys, 2);
@@ -1261,7 +1392,7 @@ void CbmTofUnpackMonitor::FillSysMonitoringHistos(const uint32_t& uCurrCompIdx,
                                                   const uint32_t& uType  // mess.getGdpbSysSubType()
 )
 {
-  if (!fBmonMicroSpillMode) {
+  if (!fBmonMicroSpillMode && !fBmonQfactorsMode) {
     /// ---> Per GET4 in system
     uint32_t uGet4InSys = uGet4Id + uCurrCompIdx * fuNbOfGet4PerComp;
     fhGet4SysMessType->Fill(uGet4InSys, uType);
@@ -1272,7 +1403,7 @@ void CbmTofUnpackMonitor::FillErrMonitoringHistos(const uint32_t& uCurrCompIdx,
                                                   const uint32_t& uType  // mess.getGdpbSysErrData()
 )
 {
-  if (!fBmonMicroSpillMode) {
+  if (!fBmonMicroSpillMode && !fBmonQfactorsMode) {
     /// ---> Per GET4 in system
     uint32_t uGet4InSys = uGet4Id + uCurrCompIdx * fuNbOfGet4PerComp;
     fhGet4MessType->Fill(uGet4InSys, 3);
@@ -1400,12 +1531,11 @@ void CbmTofUnpackMonitor::FillErrMonitoringHistos(const uint32_t& uCurrCompIdx,
 // -------------------------------------------------------------------------
 void CbmTofUnpackMonitor::CheckBmonSpillLimits(const double_t& dMsTime)
 {
-  if (-1 == fdStartTime) {
-    /// Initialize Start time for evolution plots
-    fdStartTime = dMsTime;
-  }
-
-  if (!fBmonMicroSpillMode) {
+  if (!fBmonMicroSpillMode && !fBmonQfactorsMode) {
+    if (-1 == fdStartTime) {
+      /// Initialize Start time for evolution plots
+      fdStartTime = dMsTime;
+    }
     /// Spill Detection
     /// Check only every second
     if (fdSpillCheckInterval < dMsTime - fdBmonLastInterTime) {
@@ -1435,11 +1565,12 @@ void CbmTofUnpackMonitor::CheckBmonSpillLimits(const double_t& dMsTime)
 void CbmTofUnpackMonitor::FillHitBmonMonitoringHistos(const double_t& dMsTime, const uint32_t& uCurrCompIdx,
                                                       const uint32_t& uGet4Id, const uint32_t& uTot)
 {
-  if (-1 == fdStartTime) {
-    /// Initialize Start time for evolution plots
-    fdStartTime = dMsTime;
-  }
-  if (!fBmonMicroSpillMode) {
+  if (!fBmonMicroSpillMode && !fBmonQfactorsMode) {
+    if (-1 == fdStartTime) {
+      /// Initialize Start time for evolution plots
+      fdStartTime = dMsTime;
+    }
+
     /// 2022 mapping: Y[0-3] on c0, Y[4-7] on c1, X[0-3] on c2, X[4-7] on c3
     /// Y not cabled for diamond but pulser there
     UInt_t uChannelBmon = (uGet4Id / 8) + 4 * uCurrCompIdx;
@@ -1498,14 +1629,21 @@ void CbmTofUnpackMonitor::FillHitBmonMonitoringHistos(const double_t& dMsTime, c
 void CbmTofUnpackMonitor::FillErrBmonMonitoringHistos(const double_t& dMsTime, const uint32_t& uCurrCompIdx,
                                                       const uint32_t& uGet4Id, const bool& bErrEvtLost)
 {
-  if (-1 == fdStartTime) {
-    /// Initialize Start time for evolution plots
-    fdStartTime = dMsTime;
-  }
   if (fBmonMicroSpillMode) {  //
+    if (-1 == fdStartTime) {
+      /// Initialize Start time for evolution plots
+      fdStartTime = dMsTime;
+    }
     fhBmonMicrospillsDistErrs->Fill((dMsTime - fdStartTime) * 1e6);
   }
+  else if (fBmonQfactorsMode) {  //
+    return;
+  }
   else {
+    if (-1 == fdStartTime) {
+      /// Initialize Start time for evolution plots
+      fdStartTime = dMsTime;
+    }
     /// 2022 mapping:
     /// Y[0-3] on c0, Y[4-7] on c1, X[0-3] on c2, X[4-7] on c3
     /// Y not cabled for diamond but pulser there
@@ -1538,14 +1676,13 @@ void CbmTofUnpackMonitor::FillErrBmonMonitoringHistos(const double_t& dMsTime, c
 // -------------------------------------------------------------------------
 
 // -------------------------------------------------------------------------
-void CbmTofUnpackMonitor::FillHitBmonMicroSpillHistos(const double_t& dTime)
+void CbmTofUnpackMonitor::FillHitBmonMicroSpillHistos(const double_t& dMsTime, const double_t& dTime)
 {
-
-  if (-1 == fdStartTime) {
-    /// Initialize Start time for evolution plots
-    fdStartTime = dTime * 1e-9;
-  }
   if (fBmonMicroSpillMode) {
+    if (-1 == fdStartTime) {
+      /// Initialize Start time for evolution plots
+      fdStartTime = dMsTime;
+    }
     fhBmonMicrospillsDistHits->Fill(dTime / 1e3);
   }
 }
@@ -1590,6 +1727,122 @@ void CbmTofUnpackMonitor::FinalizeTsBmonMicroSpillHistos()
 }
 // -------------------------------------------------------------------------
 
+// -------------------------------------------------------------------------
+double_t CbmTofUnpackMonitor::ExtractQFactor(TH1* pHistoIn)
+{
+  // Q-Factor = Max Bin Content / Mean Content of all bin in range
+  // => Tend toward 1 if bins are more identical
+  if (pHistoIn->Integral()) {
+    return (pHistoIn->GetBinContent(pHistoIn->GetMaximumBin())) / (pHistoIn->Integral() / pHistoIn->GetNbinsX());
+  }
+  else {
+    return 0.0;
+  }
+}
+double_t CbmTofUnpackMonitor::ExtractMean(TH1* pHistoIn)
+{
+  // Q-Factor = Max Bin Content / Mean Content of all bin in range
+  // => Tend toward 1 if bins are more identical
+  if (pHistoIn->Integral()) {
+    return (pHistoIn->Integral() / pHistoIn->GetNbinsX());
+  }
+  else {
+    return 0.0;
+  }
+}
+void CbmTofUnpackMonitor::FillHitBmonQfactorHistos(const double_t& dMsTime, const double_t& dTime)
+{
+  if (fBmonQfactorsMode) {
+    if (-1 == fdStartTime) {
+      /// Initialize Start time for evolution plots
+      fdStartTime = dMsTime;
+    }
+    if (dTime < 0) {
+      // Digi with time before TS start
+      return;
+    }
+    if (fdTsSizeNs * 1.01 < dTime) {
+      // Digi with time before TS start
+      return;
+    }
+    if (fuQFactorMaxNbTs < std::floor((dMsTime - fdStartTime) / fdTsSizeNs)) {
+      // Beyond max TS in plots => do not update anymore!
+      return;
+    }
+    for (uint32_t uHistSz = 0; uHistSz < fvdQfactorIntegrationNs.size(); ++uHistSz) {
+      uint32_t uCurrentCycle = std::floor(dTime / fvdQfactorIntegrationNs[uHistSz]);
+      if (fvuQfactorIdxHistoCycleinTS[uHistSz] < uCurrentCycle) {
+        for (; fvuQfactorIdxHistoCycleinTS[uHistSz] < uCurrentCycle; ++fvuQfactorIdxHistoCycleinTS[uHistSz]) {
+          double_t dTsFractional =
+            (fvdQfactorIntegrationNs[uHistSz] * fvuQfactorIdxHistoCycleinTS[uHistSz]) / fdTsSizeNs
+            + std::floor((dMsTime - fdStartTime) / fdTsSizeNs);
+          for (uint32_t uBinSz = 0; uBinSz < fvdQfactorBinSizesNs.size(); ++uBinSz) {
+            if (nullptr != fvhBmonQfactQval[uHistSz][uBinSz]) {
+              double_t dQFactor = ExtractQFactor(fvhBmonQfactHisto[uHistSz][uBinSz]);
+              fvhBmonQfactQval[uHistSz][uBinSz]->Fill(dTsFractional, dQFactor);
+              fvhBmonQfactMean[uHistSz][uBinSz]->Fill(dTsFractional, ExtractMean(fvhBmonQfactHisto[uHistSz][uBinSz]));
+              for (uint32_t uBin = 1; uBin <= fvhBmonQfactHisto[uHistSz][uBinSz]->GetNbinsX(); ++uBin) {
+                fvhBmonQfactBinCountDistribution[uBinSz]->Fill(fvhBmonQfactHisto[uHistSz][uBinSz]->GetBinContent(uBin));
+                fvhBmonQfactBinCountDistributionEvo[uBinSz]->Fill(
+                  dTsFractional, fvhBmonQfactHisto[uHistSz][uBinSz]->GetBinContent(uBin));
+              }
+
+              if (0.0 < dQFactor) {
+                fvhBmonQfactHisto[uHistSz][uBinSz]->Reset();
+              }
+            }
+          }
+        }
+      }
+
+      double_t dTimeInCycle = std::fmod(dTime, fvdQfactorIntegrationNs[uHistSz]);
+      for (uint32_t uBinSz = 0; uBinSz < fvdQfactorBinSizesNs.size(); ++uBinSz) {
+        if (nullptr != fvhBmonQfactQval[uHistSz][uBinSz]) {
+          fvhBmonQfactHisto[uHistSz][uBinSz]->Fill(dTimeInCycle);
+        }
+      }
+    }
+  }
+}
+
+void CbmTofUnpackMonitor::FinalizeTsBmonQfactorHistos(uint64_t uTsTimeNs, std::vector<CbmBmonDigi>* vDigis)
+{
+  if (fBmonQfactorsMode) {
+    fvuQfactorIdxHistoCycleinTS.assign(fvdQfactorIntegrationNs.size(), 0);
+    if (vDigis && 0 < vDigis->size()) {
+      for (auto it = vDigis->begin(); it != vDigis->end(); ++it) {
+        FillHitBmonQfactorHistos(uTsTimeNs, (*it).GetTime());
+      }
+    }
+
+    /// Process last cycle (as will never receive a digi later than its end)
+    for (uint32_t uHistSz = 0; uHistSz < fvdQfactorIntegrationNs.size(); ++uHistSz) {
+      for (; fvuQfactorIdxHistoCycleinTS[uHistSz] < fvuNbHistoCyclesPerTS[uHistSz];
+           ++fvuQfactorIdxHistoCycleinTS[uHistSz]) {
+        double_t dTsFractional = (fvdQfactorIntegrationNs[uHistSz] * fvuQfactorIdxHistoCycleinTS[uHistSz]) / fdTsSizeNs
+                                 + std::floor((uTsTimeNs - fdStartTime) / fdTsSizeNs);
+        for (uint32_t uBinSz = 0; uBinSz < fvdQfactorBinSizesNs.size(); ++uBinSz) {
+          if (nullptr != fvhBmonQfactQval[uHistSz][uBinSz]) {
+            double_t dQFactor = ExtractQFactor(fvhBmonQfactHisto[uHistSz][uBinSz]);
+            fvhBmonQfactQval[uHistSz][uBinSz]->Fill(dTsFractional, dQFactor);
+            fvhBmonQfactMean[uHistSz][uBinSz]->Fill(dTsFractional, ExtractMean(fvhBmonQfactHisto[uHistSz][uBinSz]));
+            for (uint32_t uBin = 1; uBin <= fvhBmonQfactHisto[uHistSz][uBinSz]->GetNbinsX(); ++uBin) {
+              fvhBmonQfactBinCountDistribution[uBinSz]->Fill(fvhBmonQfactHisto[uHistSz][uBinSz]->GetBinContent(uBin));
+              fvhBmonQfactBinCountDistributionEvo[uBinSz]->Fill(
+                dTsFractional, fvhBmonQfactHisto[uHistSz][uBinSz]->GetBinContent(uBin));
+            }
+
+            if (0.0 < dQFactor) {
+              fvhBmonQfactHisto[uHistSz][uBinSz]->Reset();
+            }
+          }
+        }
+      }
+    }
+  }
+}
+// -------------------------------------------------------------------------
+
 // ---- Init ----
 Bool_t CbmTofUnpackMonitor::Init(CbmMcbm2018TofPar* parset)
 {
@@ -1609,11 +1862,27 @@ Bool_t CbmTofUnpackMonitor::Init(CbmMcbm2018TofPar* parset)
   TDirectory* oldDir = gDirectory;
   gROOT->cd();
 
+  /// Setup channel map for BMon if needed
+  if (fBmonMicroSpillMode || fBmonQfactorsMode || fBmonMode) {
+    if (fBmonScvdMode) {
+      fuNbChanBmon  = kuNbChanBmonScvd;
+      fuBmonChanMap = std::vector<UInt_t>(kuBmonChanMapScvd, kuBmonChanMapScvd + kuNbChanBmonScvd);
+    }
+    else {
+      fuNbChanBmon  = kuNbChanBmon;
+      fuBmonChanMap = std::vector<UInt_t>(kuBmonChanMap, kuBmonChanMap + kuNbChanBmon);
+    }
+  }
+
   /// Trigger histo creation on all associated monitors
   if (fBmonMicroSpillMode) {
     CreateHistogramsMicroSpills();
     DrawCanvasesMicroSpills();
   }
+  else if (fBmonQfactorsMode) {
+    CreateHistogramsQFactors();
+    DrawCanvasesQFactors();
+  }
   else {
     CreateHistograms();
     DrawCanvases();
@@ -1635,7 +1904,7 @@ Bool_t CbmTofUnpackMonitor::Init(CbmMcbm2018TofPar* parset)
 
   /// Register the histos and canvases in the HTTP server
   std::string sSystem = "tof";
-  if (fBmonMode || fBmonMicroSpillMode) {
+  if (fBmonMode || fBmonMicroSpillMode || fBmonQfactorsMode) {
     //
     sSystem = "bmon";
   }
diff --git a/reco/detectors/tof/unpack/CbmTofUnpackMonitor.h b/reco/detectors/tof/unpack/CbmTofUnpackMonitor.h
index dd2f264646ac0f70c7bad766b6c8999ee44c51e4..9a027571f41f5b6d984c57ad7afa49678758e093 100644
--- a/reco/detectors/tof/unpack/CbmTofUnpackMonitor.h
+++ b/reco/detectors/tof/unpack/CbmTofUnpackMonitor.h
@@ -5,12 +5,14 @@
 #ifndef CbmTofUnpackMonitor_H
 #define CbmTofUnpackMonitor_H
 
+#include "CbmBmonDigi.h"
 #include "CbmMcbm2018TofPar.h"
-#include "Rtypes.h"
-#include "TH1.h"
-#include "TH2.h"
-#include "TProfile.h"
-#include "TProfile2D.h"
+
+#include <Rtypes.h>
+#include <TH1.h>
+#include <TH2.h>
+#include <TProfile.h>
+#include <TProfile2D.h>
 
 #include <array>
 #include <cstdint>
@@ -39,6 +41,10 @@ class CbmTofUnpackMonitor {
   Bool_t ResetHistogramsMicroSpills(Bool_t bResetTime);
   void DrawCanvasesMicroSpills();
 
+  Bool_t CreateHistogramsQFactors(Bool_t bBmon = kTRUE);
+  Bool_t ResetHistogramsQFactors(Bool_t bResetTime);
+  void DrawCanvasesQFactors(Bool_t bBmon = kTRUE);
+
   Bool_t CreateMsComponentSizeHistos(UInt_t component);
   Bool_t ResetMsComponentSizeHistos(UInt_t component);
 
@@ -110,10 +116,15 @@ class CbmTofUnpackMonitor {
   bool GetBmonMode() { return fBmonMode; }
 
   /// Fill BMon Microspill histograms
-  void FillHitBmonMicroSpillHistos(const double_t& dTime);
+  void FillHitBmonMicroSpillHistos(const double_t& dMsTime, const double_t& dTime);
   /// Finalize BMon Microspill histograms
   void FinalizeTsBmonMicroSpillHistos();
 
+  /// Fill Microspill histograms
+  void FillHitBmonQfactorHistos(const double_t& dMsTime, const double_t& dTime);
+  /// Finalize Microspill histograms
+  void FinalizeTsBmonQfactorHistos(uint64_t uTsTimeNs, std::vector<CbmBmonDigi>* vDigis);
+
   /** @brief Activate the BMon mode */
   void SetBmonMicroSpillMode(bool value) { fBmonMicroSpillMode = value; }
 
@@ -126,6 +137,25 @@ class CbmTofUnpackMonitor {
   /** @brief Read the BMon mode */
   bool GetBmonScvdMode() { return fBmonScvdMode; }
 
+  /** @brief Activate the Bmon QFactor mode */
+  void SetBmonQFactorMode(bool value)
+  {
+    fBmonQfactorsMode = value;
+    if (fBmonQfactorsMode) {
+      fBmonMicroSpillMode = false;
+      fBmonScvdMode       = false;
+    }
+  }
+
+  /** @brief Read the Bmon QFactor mode */
+  bool GetBmonQFactorMode() { return fBmonQfactorsMode; }
+
+  /** @brief Activate the Tof QFactor mode */
+  void SetTofQFactorMode(bool value) { fTofQfactorsMode = value; }
+
+  /** @brief Read the Tof QFactor mode */
+  bool GetTofQFactorMode() { return fTofQfactorsMode; }
+
   /** @brief Activate/de-activate the internal histo serve mode */
   void SetInternalHttpMode(bool value) { fbInternalHttp = value; }
 
@@ -163,6 +193,8 @@ class CbmTofUnpackMonitor {
   bool fBmonMode           = false;
   bool fBmonScvdMode       = false;
   bool fBmonMicroSpillMode = false;
+  bool fBmonQfactorsMode   = false;
+  bool fTofQfactorsMode    = false;
   bool fbInternalHttp      = true;
 
   /// ---> Constants
@@ -292,6 +324,30 @@ class CbmTofUnpackMonitor {
   TH2* fhBmonMicrospillsTsBinFractHits = nullptr;
   TH2* fhBmonMicrospillsTsBinFractErrs = nullptr;
 
+  /// BMon Q-Factors monitoring histograms
+  /// Hint: keep fractions of TS size and under 100 us
+  double_t fdTsSizeNs                        = fdBmonMicrospillsTsLengthSec * 1e9;
+  uint32_t fuQFactorMaxNbTs                  = 400;
+  std::vector<double_t> fvdQfactorBinSizesNs = {20, 200, 1.28e3, 10.24e3, 25.6e3, 102.4e3, 204.8e3};  // 7 values
+  /// Hint: keep fractions of TS size + multiples of bin size and above 10 us
+  std::vector<double_t> fvdQfactorIntegrationNs     = {2.56e6};  // 1 value
+  std::vector<uint32_t> fvuNbHistoCyclesPerTS       = {};
+  std::vector<uint32_t> fvuQfactorIdxHistoCycleinTS = {};
+  /// Dimension: same as BinSizes vector!!
+  std::vector<double_t> fvdQfactorHistMax = {2000., 400., 40., 20., 20., 20., 20.};
+  uint16_t fuQfactorNbPlots               = 0;
+  std::vector<std::vector<uint32_t>> fvuQfactorNbBinsHisto;
+  std::vector<uint32_t> fvuQfactorNbHistoCyclesPerTS;
+  std::vector<std::vector<TH1*>> fvhBmonQfactHisto;
+  std::vector<std::vector<TH1*>> fvhBmonQfactQval;
+  std::vector<std::vector<TH1*>> fvhBmonQfactMean;
+  std::vector<TH1*> fvhBmonQfactBinCountDistribution;
+  std::vector<TH2*> fvhBmonQfactBinCountDistributionEvo;
+  /// Q-Factor helper methods
+  double_t ExtractQFactor(TH1* pHistoIn);
+  double_t ExtractMean(TH1* pHistoIn);
+
+
   /// Canvases
   /// ---> Generic
   TCanvas* fcSummaryGet4s          = nullptr;
@@ -308,6 +364,10 @@ class CbmTofUnpackMonitor {
   TCanvas* fcBmonMicrospillsBinCnts  = nullptr;
   TCanvas* fcBmonMicrospillsRatios   = nullptr;
   TCanvas* fcBmonMicrospillsFraction = nullptr;
+  /// ---> BMon Q-Factors monitoring
+  TCanvas* fcBmonQFactorVal        = nullptr;
+  TCanvas* fcBmonQFactorMean       = nullptr;
+  TCanvas* fcBmonQFactorBinCntDist = nullptr;
 
   /// Spill detection
   Bool_t fbSpillOn                      = kTRUE;
diff --git a/reco/steer/CbmRecoUnpack.cxx b/reco/steer/CbmRecoUnpack.cxx
index f409e6fac30a9ee18832be0c8fd984dedf40c2b6..10b9b3850ac96dcf6e44c76b7a43c47b58706fa5 100644
--- a/reco/steer/CbmRecoUnpack.cxx
+++ b/reco/steer/CbmRecoUnpack.cxx
@@ -622,6 +622,7 @@ void CbmRecoUnpack::Unpack(unique_ptr<Timeslice> ts)
 
   if (fBmonConfig && fBmonConfig->GetMonitor()) {  //
     fBmonConfig->GetMonitor()->FinalizeTsBmonMicroSpillHistos();
+    fBmonConfig->GetMonitor()->FinalizeTsBmonQfactorHistos(ts->start_time(), fBmonConfig->GetOutputVec());
   }
 
   if (fDoPerfProfPerTs) {