diff --git a/FT/FTMonitors/options/nzs_cluster_monitoring.py b/FT/FTMonitors/options/nzs_cluster_monitoring.py
index 5dae14ca0a058a1988f381baf798e6ca9db240d2..4957c04e3c59403c10fea9a5a13a89ae3fa47f91 100644
--- a/FT/FTMonitors/options/nzs_cluster_monitoring.py
+++ b/FT/FTMonitors/options/nzs_cluster_monitoring.py
@@ -24,26 +24,37 @@ from Configurables import FTNZSClusterCreator
 from Configurables import FTNZSClusterMonitor
 from Configurables import createODIN
 from Configurables import LHCb__UnpackRawEvent
+from Configurables import EventSelector
 from os.path import basename
 from glob import glob
 
-runnumber = "238161"
-side = "A"
+# runnumber, side = "238692", "C"
+# runnumber, side = "240033", "C"
+# runnumber, side = "240121", "both"
+# runnumber, side = "240455", "both"
+runnumber, side = "240863", "both"
 
 app = LHCbApp()
-app.DDDBtag = "upgrade/master"
-app.CondDBtag = "upgrade/SFCAVERN_C_20220705_160436_All-FixedOrder"
-if side == "A":
-    app.CondDBtag = "upgrade/SFCAVERN_A_20220715_004848_All-FixedOrder"
-
 app.DataType = "Upgrade"
 app.Simulation = True
 CondDB().Upgrade = True
 CondDB().IgnoreHeartBeat = True
 LoKiSvc().Welcome = False
+EventSelector().PrintFreq = 5000
+
+app.DDDBtag = "upgrade/master"
+app.CondDBtag = "upgrade/SFCAVERN_SF_20220729_00000_All-FixedOrder"
+side_name = "SF"
+if side == "A":
+    app.CondDBtag = "upgrade/SFCAVERN_A_20220713_092503_All-FixedOrder"
+    side_name = "SFA"
+if side == "C":
+    app.CondDBtag = "upgrade/SFCAVERN_C_20220705_160436_All-FixedOrder"
+    side_name = "SFC"
+if side == "global":
+    side_name = 'LHCb'
+files = glob(f"/hlt2/objects/{side_name}/0000{runnumber}/*_S*EB*.mdf")
 
-files = glob("/hlt2/objects/SF" + side + "/0000" + runnumber + "/*_S" + side +
-             "EB*.mdf")
 output_name = basename(files[0]).replace(".mdf", "_nzs_clusters.root")
 
 IOHelper("MDF").inputFiles(files)
@@ -64,7 +75,7 @@ unpacker = LHCb__UnpackRawEvent(
 odin = createODIN(RawBanks="DAQ/RawBanks/ODIN")
 
 decoder = FTNZSRawBankDecoder("DecodeFT")
-decoder.OutputLevel = INFO
+decoder.OutputLevel = 5
 
 clusterer = FTNZSClusterCreator("ClusterFT")
 clusterer.OutputLevel = 5
@@ -74,12 +85,11 @@ monitor.OutputLevel = INFO
 monitor.DrawHistsPerStation = True
 monitor.DrawHistsPerQuarter = True
 monitor.DrawHistsPerModule = True
-monitor.DrawHistsPerSiPM = True
-monitor.manualTAEBunchIdFirst = 1930
-monitor.manualTAESpacing = 2821 - 1930
-monitor.manualTAENTAE = 2
-monitor.TAEHalfWindow = 2
+monitor.DrawCorrelationPlots = True
 monitor.enableTAE = True
+monitor.TAEHalfWindow = 2
+monitor.TAEBunchIds = [1686, 2577]
+monitor.ExtraInfo = f" (run: {runnumber})"
 
 monSeq.Members = [
     unpacker,
@@ -90,7 +100,7 @@ monSeq.Members = [
 ]
 
 appMgr = ApplicationMgr(
-    EvtMax=30000,
+    EvtMax=10000,
     TopAlg=[monSeq],
     HistogramPersistency="ROOT",
     ExtSvc=[
diff --git a/FT/FTMonitors/options/nzs_digit_monitoring.py b/FT/FTMonitors/options/nzs_digit_monitoring.py
index b067093ee1604205fcc288ff46b1e10533468bf4..dd52890d60460d7928a6d8cceb2aa06f379ffc6c 100644
--- a/FT/FTMonitors/options/nzs_digit_monitoring.py
+++ b/FT/FTMonitors/options/nzs_digit_monitoring.py
@@ -25,25 +25,34 @@ from Configurables import FTNZSRawBankDecoder
 from Configurables import FTDigitMonitor
 from Configurables import createODIN
 from Configurables import LHCb__UnpackRawEvent
+from Configurables import EventSelector
 from glob import glob
 
-runnumber = "236203"
-side = "C"
+# runnumber, side = "238692", "A"
+# runnumber, side = "238709", "C"
+runnumber, side = "240033", "C"
 
 app = LHCbApp()
-app.DDDBtag = "upgrade/master"
-app.CondDBtag = "upgrade/SFCAVERN_C_20220705_160436_All-FixedOrder"
-if side == "A":
-    app.CondDBtag = "upgrade/SFCAVERN_A_20220715_004848_All-FixedOrder"
-
 app.DataType = "Upgrade"
 app.Simulation = True
 CondDB().Upgrade = True
 CondDB().IgnoreHeartBeat = True
 LoKiSvc().Welcome = False
 MessageSvc().OutputLevel = INFO
+EventSelector().PrintFreq = 1000
 
-files = glob("/hlt2/objects/SFC/0000" + runnumber + "/*_SCEB*.mdf")
+app.DDDBtag = "upgrade/master"
+app.CondDBtag = "upgrade/SFCAVERN_SF_20220729_00000_All-FixedOrder"
+side_name = "SF",
+if side == "A":
+    app.CondDBtag = "upgrade/SFCAVERN_A_20220713_092503_All-FixedOrder"
+    side_name = "SFA"
+if side == "C":
+    app.CondDBtag = "upgrade/SFCAVERN_C_20220705_160436_All-FixedOrder"
+    side_name = "SFC"
+if side == "global":
+    side_name = 'LHCb'
+files = glob(f"/hlt2/objects/{side_name}/0000{runnumber}/*_S*EB*.mdf")
 
 output_name = basename(files[0]).replace(".mdf", "_nzs.root")
 
@@ -65,14 +74,14 @@ unpacker = LHCb__UnpackRawEvent(
 odin = createODIN(RawBanks="DAQ/RawBanks/ODIN")
 
 decoder = FTNZSRawBankDecoder("DecodeFT")
-decoder.OutputLevel = INFO
+decoder.OutputLevel = 5
 
 monitor = FTDigitMonitor()
 monitor.OutputLevel = INFO
-monitor.manualTAENTAE = 2
-monitor.manualTAEBunchIdFirst = 895
-monitor.manualTAESpacing = 1786 - 895
 monitor.enableTAE = True
+monitor.TAEHalfWindow = 2
+monitor.TAEBunchIds = [1752, 2643]
+monitor.ExtraInfo = f" (run: {runnumber})"
 
 monSeq.Members = [
     unpacker,
@@ -82,7 +91,7 @@ monSeq.Members = [
 ]
 
 appMgr = ApplicationMgr(
-    EvtMax=-1,
+    EvtMax=5000,
     TopAlg=[monSeq],
     HistogramPersistency="ROOT",
     ExtSvc=[
diff --git a/FT/FTMonitors/options/zs_cluster_monitoring.py b/FT/FTMonitors/options/zs_cluster_monitoring.py
index 95c8f55e922d71a2e610cc0916262b764c4ef03c..780b63646f924e37b59246efdd453b3d43e6bd14 100644
--- a/FT/FTMonitors/options/zs_cluster_monitoring.py
+++ b/FT/FTMonitors/options/zs_cluster_monitoring.py
@@ -21,21 +21,30 @@ from Configurables import GaudiSequencer
 from Configurables import FTRawBankDecoder
 from Configurables import FTClusterMonitor
 from Configurables import LHCb__UnpackRawEvent
+from Configurables import EventSelector
 from glob import glob
 
-runnumber = "238209"
-side = "A"
+# runnumber, side = "236211", "C"
+runnumber, side = "240929", "global"
 
 app = LHCbApp()
-app.DDDBtag = "upgrade/master"
-app.CondDBtag = "upgrade/SFCAVERN_C_20220705_160436_All-FixedOrder"
-if side == "A":
-    app.CondDBtag = "upgrade/SFCAVERN_A_20220715_004848_All-FixedOrder"
 app.Simulation = True  # complains about not finding Alignment if set to False on Data
 app.DataType = "Upgrade"
+app.DDDBtag = "upgrade/master"
+app.CondDBtag = "upgrade/SFCAVERN_SF_20220729_00000_All-FixedOrder"
+side_name = "SF"
+if side == "A":
+    app.CondDBtag = "upgrade/SFCAVERN_A_20220713_092503_All-FixedOrder"
+    side_name = "SFA"
+if side == "C":
+    app.CondDBtag = "upgrade/SFCAVERN_C_20220705_160436_All-FixedOrder"
+    side_name = "SFC"
+if side == "global":
+    side_name = 'LHCb'
+
+EventSelector().PrintFreq = 10000
 
-files = glob("/hlt2/objects/SF" + side + "/0000" + runnumber + "/*_S" + side +
-             "EB*.mdf")
+files = glob(f"/hlt2/objects/{side_name}/0000{runnumber}/*_S*EB*.mdf")
 
 IOHelper("MDF").inputFiles(files)
 output_name = basename(files[0]).replace(".mdf", "_zs.root")
@@ -48,12 +57,11 @@ monitor.OutputLevel = INFO
 monitor.DrawHistsPerStation = True
 monitor.DrawHistsPerQuarter = True
 monitor.DrawHistsPerModule = True
-monitor.DrawHistsPerSiPM = True
-monitor.manualTAENTAE = 2
-monitor.manualTAEBunchIdFirst = 1930
-monitor.manualTAESpacing = 2821 - 1930
-monitor.TAEHalfWindow = 5
+monitor.DrawCorrelationPlots = True
 monitor.enableTAE = True
+monitor.TAEHalfWindow = 3
+monitor.TAEBunchIds = [1686, 2577]
+monitor.ExtraInfo = f" (run: {runnumber})"
 
 # https://gitlab.cern.ch/lhcb/Boole/-/commit/62c15cebc68e71a5a7b71b8649495b7191b3367e
 # this might change
@@ -77,7 +85,7 @@ monSeq.Members = [
 ]
 
 appMgr = ApplicationMgr(
-    EvtMax=50000,
+    EvtMax=100000,
     TopAlg=[monSeq],
     HistogramPersistency="ROOT",
     ExtSvc=[
diff --git a/FT/FTMonitors/src/ClusterMonitor.h b/FT/FTMonitors/src/ClusterMonitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..ae289388b997e5da8b7a74c0c40903f9d582433e
--- /dev/null
+++ b/FT/FTMonitors/src/ClusterMonitor.h
@@ -0,0 +1,524 @@
+/*****************************************************************************\
+* (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration           *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+
+#pragma once
+
+#include "Detector/FT/FTChannelID.h"
+#include "Detector/FT/FTConstants.h"
+#include "Event/FTLiteCluster.h"
+#include "Event/ODIN.h"
+#include "FTDet/DeFTDetector.h"
+#include "FTMonitoring.h"
+#include <Gaudi/Accumulators/Histogram.h>
+
+using FTLiteClusters  = LHCb::FTLiteCluster::FTLiteClusters;
+using ODIN            = LHCb::ODIN;
+namespace GA          = Gaudi::Accumulators;
+namespace FTConstants = LHCb::Detector::FT;
+
+template <typename T>
+class ClusterMonitor {
+private:
+  T*           m_owner;
+  bool         m_drawHistsPerStation;
+  bool         m_drawHistsPerQuarter;
+  bool         m_drawHistsPerModule;
+  bool         m_drawCorrelationPlots;
+  unsigned int m_TAEHalfWindow;
+  unsigned int m_timingStepsTotal;
+
+  enum FillType {
+    DEFAULT,
+    WEIGHTED,
+    NUM_FillTypes,
+  };
+
+  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>>                  m_clustersPerBunchCrossing;
+  mutable std::map<unsigned int, GA::Histogram<1, GA::atomicity::full, float>>         m_clustersPerBunchCrossingInSide;
+  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>>                  m_clustersPerTAE;
+  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>>                  m_clustersPerTAEShift;
+  mutable std::map<unsigned int, GA::Histogram<1, GA::atomicity::full, float>>         m_clustersPerTAEShiftInSide;
+  mutable std::optional<GA::Histogram<2, Gaudi::Accumulators::atomicity::full, float>> m_meanTAEShiftSiPM;
+  mutable std::optional<GA::ProfileHistogram<1, Gaudi::Accumulators::atomicity::full, float>> m_meanTAEShiftSiPMProfile;
+
+  using fillT    = unsigned int;
+  using taeT     = unsigned int;
+  using stationT = unsigned int;
+  using layerT   = unsigned int;
+  using quarterT = unsigned int;
+  using moduleT  = unsigned int;
+  using binT     = unsigned int;
+  using stepT    = unsigned int;
+
+  mutable std::map<std::tuple<stationT, layerT, quarterT>,
+                   GA::Histogram<2, Gaudi::Accumulators::atomicity::full, float>>
+      m_meanTAEShiftSiPMinQuarter;
+
+  mutable std::map<taeT, GA::Histogram<1, GA::atomicity::full, float>> m_nClustersPerEvent;
+  mutable std::map<taeT, GA::Histogram<1, GA::atomicity::full, float>> m_lcisipm;
+
+  mutable std::map<std::tuple<fillT, taeT>, GA::WeightedHistogram<1, GA::atomicity::full, float>> m_lcps;
+  mutable std::map<std::tuple<fillT, taeT>, GA::WeightedHistogram<1, GA::atomicity::full, float>> m_lcpm;
+  mutable std::map<std::tuple<fillT, taeT>, GA::WeightedHistogram<1, GA::atomicity::full, float>> m_lcpsipm;
+  mutable std::map<std::tuple<fillT, taeT>, GA::WeightedHistogram<1, GA::atomicity::full, float>> m_lcpc;
+  mutable std::map<std::tuple<fillT, taeT>, GA::WeightedHistogram<1, GA::atomicity::full, float>> m_lcf;
+  mutable std::map<std::tuple<fillT, taeT>, GA::WeightedHistogram<1, GA::atomicity::full, float>> m_lcs;
+  mutable std::map<std::tuple<fillT, taeT>, GA::WeightedHistogram<1, GA::atomicity::full, float>> m_lciq;
+  mutable std::map<std::tuple<fillT, taeT>, GA::WeightedHistogram<2, GA::atomicity::full, float>> m_lcsf;
+  mutable std::map<std::tuple<fillT, taeT>, GA::WeightedHistogram<2, GA::atomicity::full, float>> m_lcqsipm;
+
+  mutable std::deque<GA::Histogram<2, GA::atomicity::full, float>> m_correlationSiPM;
+
+  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>>          m_clustersPerStep;
+  mutable std::map<stepT, GA::Histogram<2, GA::atomicity::full, float>>        m_meanTAEShiftSiPMZS_step;
+  mutable std::map<stepT, GA::ProfileHistogram<1, GA::atomicity::full, float>> m_meanTAEShiftSiPMProfileZS_step;
+
+  mutable std::map<std::tuple<fillT, taeT, binT>, GA::WeightedHistogram<1, GA::atomicity::full, float>> m_PseudoChannel;
+  mutable std::map<std::tuple<fillT, taeT, binT, layerT>, GA::WeightedHistogram<1, GA::atomicity::full, float>>
+      m_PseudoChannelPerLayer;
+  mutable std::map<std::tuple<fillT, taeT, binT, quarterT>, GA::WeightedHistogram<1, GA::atomicity::full, float>>
+      m_PseudoChannelPerQuarter;
+  mutable std::map<std::tuple<fillT, taeT, binT, stationT, layerT>,
+                   GA::WeightedHistogram<1, GA::atomicity::full, float>>
+      m_PseudoChannelPerStationAndLayer;
+  mutable std::map<std::tuple<fillT, taeT, binT, stationT, layerT, quarterT>,
+                   GA::WeightedHistogram<1, GA::atomicity::full, float>>
+      m_PseudoChannelPerStationAndLayerAndQuarter;
+
+  mutable std::map<std::tuple<fillT, taeT, stationT>, GA::WeightedHistogram<1, GA::atomicity::full, float>> m_lcpst;
+  mutable std::map<std::tuple<fillT, taeT, stationT, layerT, quarterT>,
+                   GA::WeightedHistogram<1, GA::atomicity::full, float>>
+      m_sipmpq;
+  mutable std::map<std::tuple<fillT, taeT, stationT, layerT, quarterT>,
+                   GA::WeightedHistogram<1, GA::atomicity::full, float>>
+      m_fracpq;
+  mutable std::map<std::tuple<fillT, taeT, stationT, layerT, quarterT>,
+                   GA::WeightedHistogram<1, GA::atomicity::full, float>>
+      m_pseusizepq;
+  mutable std::map<std::tuple<fillT, taeT, stationT, layerT, quarterT, moduleT>,
+                   GA::WeightedHistogram<1, GA::atomicity::full, float>>
+      m_lcichpm;
+
+public:
+  ClusterMonitor( T* owner ) : m_owner( owner ) {}
+  double m_normalization;
+
+  void createHistograms( std::string prefix, unsigned int TAEHalfWindow, bool drawHistsPerStation,
+                         bool drawHistsPerQuarter, bool drawHistsPerModule, bool drawCorrelationPlots,
+                         double normalization, unsigned int timingStepsTotal, const std::string extraInfo ) {
+    m_TAEHalfWindow        = TAEHalfWindow;
+    unsigned int TAESize   = 2 * TAEHalfWindow + 1;
+    m_drawHistsPerStation  = drawHistsPerStation;
+    m_drawHistsPerQuarter  = drawHistsPerQuarter;
+    m_drawHistsPerModule   = drawHistsPerModule;
+    m_drawCorrelationPlots = drawCorrelationPlots;
+    m_timingStepsTotal     = timingStepsTotal;
+    m_normalization        = normalization;
+
+    for ( unsigned int side = 0; side < 2; ++side ) {
+      std::vector<std::string> sideName = {"C", "A"};
+
+      buildHistogram( m_owner, m_clustersPerBunchCrossingInSide, side,
+                      prefix + fmt::format( "ClustersPerBunchCrossing{}Side", sideName[side] ),
+                      fmt::format( "Bunch crossing ID in {}-side{};BX ID;Clusters", sideName[side], extraInfo ),
+                      GA::Axis<float>{4096, -0.5f, 4096 - 0.5f} );
+      buildHistogram(
+          m_owner, m_clustersPerTAEShiftInSide, side,
+          prefix + fmt::format( "nClustersPerTAEShift{}Side", sideName[side] ),
+          fmt::format( "Number of clusters per TAE shift in {}-side{};TAE shift;Clusters", sideName[side], extraInfo ),
+          GA::Axis<float>{TAESize, -0.5f - TAEHalfWindow, TAEHalfWindow + 0.5f} );
+    }
+
+    if ( m_timingStepsTotal > 0 && TAEHalfWindow > 0 ) {
+      m_clustersPerStep.emplace( m_owner, prefix + "stepping/clustersPerStep",
+                                 fmt::format( "Clusters per step{};Step;Clusters", extraInfo ),
+                                 GA::Axis<float>{512, -0.5f, 512 - 0.5f} );
+      for ( unsigned int step = 0; step < timingStepsTotal; step++ ) {
+        buildHistogram( m_owner, m_meanTAEShiftSiPMZS_step, step,
+                        prefix + "stepping/meanTAEShiftSiPMZS_step" + std::to_string( step ),
+                        fmt::format( "mean TAE per SiPM step {}{};SiPM;mean TAE shift", step, extraInfo ),
+                        std::tuple{GA::Axis<float>{FTMonitoring::nSiPMsTotal, -0.5f, FTMonitoring::nSiPMsTotal - 0.5f},
+                                   GA::Axis<float>{20, -0.5f, 20 - 0.5f}} );
+
+        buildHistogram( m_owner, m_meanTAEShiftSiPMProfileZS_step, step,
+                        prefix + "stepping/meanTAEShiftSiPMProfileZS" + std::to_string( step ),
+                        fmt::format( "mean TAE shift per SiPM {}{};SiPM; mean TAE shift", step, extraInfo ),
+                        GA::Axis<float>{FTMonitoring::nSiPMsTotal, -0.5f, FTMonitoring::nSiPMsTotal - 0.5f} );
+      }
+    }
+
+    if ( m_drawCorrelationPlots ) {
+      /// correlation plots
+      for ( size_t station = 1; station < FTConstants::nStations + 1; station++ ) {
+        for ( size_t layerAIdx = 0; layerAIdx < FTConstants::nLayers; layerAIdx++ ) {
+          for ( size_t layerBIdx = layerAIdx + 1; layerBIdx < FTConstants::nLayers; layerBIdx++ ) {
+            for ( size_t quarter = 0; quarter < FTConstants::nQuarters; quarter++ ) {
+              m_correlationSiPM.emplace_back(
+                  m_owner,
+                  fmt::format( "{}Correlation/CorrSiPM_T{}_L{}vsL{}_Q{}", prefix, station, layerAIdx, layerBIdx,
+                               quarter ),
+                  fmt::format( "SiPM Correlation T{} L{} vs L{} for Q{}{};SiPMNumber_L{};SiPM number_L{}", station,
+                               layerAIdx, layerBIdx, quarter, extraInfo, layerAIdx, layerBIdx ),
+                  std::tuple{
+                      GA::Axis<float>{FTConstants::nMaxSiPMsPerQuarter, -0.5f, FTConstants::nMaxSiPMsPerQuarter - 0.5f,
+                                      "SiPM Number L" + std::to_string( layerAIdx )},
+                      GA::Axis<float>{FTConstants::nMaxSiPMsPerQuarter, -0.5f, FTConstants::nMaxSiPMsPerQuarter - 0.5f,
+                                      "SiPM number L" + std::to_string( layerBIdx )}} );
+            }
+          }
+        }
+      }
+    }
+
+    m_clustersPerBunchCrossing.emplace( m_owner, prefix + "ClustersPerBunchCrossing",
+                                        fmt::format( "bunch crossing ID{};BX ID;Clusters", extraInfo ),
+                                        GA::Axis<float>{4096, -0.5f, 4095 + 0.5f} );
+    m_clustersPerTAE.emplace( m_owner, prefix + "nClustersPerTAE",
+                              fmt::format( "Number of clusters per TAE{};TAE type;Clusters", extraInfo ),
+                              GA::Axis<float>{TAESize + 2, -1.5f, ( TAESize + 1 ) - 0.5f} );
+    m_clustersPerTAEShift.emplace( m_owner, prefix + "nClustersPerTAEShift",
+                                   fmt::format( "Number of clusters per TAE shift{};TAE shift;Clusters", extraInfo ),
+                                   GA::Axis<float>{TAESize, -0.5f - TAEHalfWindow, TAEHalfWindow + 0.5f} );
+    m_meanTAEShiftSiPM.emplace(
+        m_owner, prefix + "meanTAESiPM", fmt::format( "mean TAE shift per SiPM{};SiPM;mean TAE shift", extraInfo ),
+        std::tuple{GA::Axis<float>{FTMonitoring::nSiPMsTotal, -0.5f, FTMonitoring::nSiPMsTotal - 0.5f},
+                   GA::Axis<float>{TAESize, -0.5f - TAEHalfWindow, TAEHalfWindow + 0.5f}} );
+    m_meanTAEShiftSiPMProfile.emplace(
+        m_owner, prefix + "meanTAEShiftSiPMProfile",
+        fmt::format( "mean TAE shift per SiPM{};SiPM;mean TAE shift", extraInfo ),
+        GA::Axis<float>{FTMonitoring::nSiPMsTotal, -0.5f, FTMonitoring::nSiPMsTotal - 0.5f} );
+
+    for ( size_t station = 1; station < FTConstants::nStations + 1; ++station ) {
+      for ( size_t layer = 0; layer < FTConstants::nLayers; ++layer ) {
+        for ( size_t quarter = 0; quarter < FTConstants::nQuarters; ++quarter ) {
+          buildHistogram(
+              m_owner, m_meanTAEShiftSiPMinQuarter, {station, layer, quarter},
+              prefix + fmt::format( "meanTAEShiftPerSiPMInQuarter/T{}L{}Q{}", station, layer, quarter ),
+              fmt::format( "Mean TAE shift in T{}L{}Q{}{};SiPM;mean TAE shift", station, layer, quarter, extraInfo ),
+              std::tuple{
+                  GA::Axis<float>{FTConstants::nMaxSiPMsPerQuarter, -0.5f, FTConstants::nMaxSiPMsPerQuarter - 0.5f},
+                  GA::Axis<float>{TAESize, -0.5f - TAEHalfWindow, TAEHalfWindow + 0.5f}} );
+        }
+      }
+    }
+
+    for ( unsigned int tae = 0; tae < ( TAESize ) + 1; ++tae ) {
+      auto number = []( unsigned int num ) { return num == 0 ? "" : std::to_string( num ); };
+
+      std::string taePrefix = prefix + "nonTAE/";
+      if ( tae > 0 ) {
+        const size_t tae_index = tae - 1;
+        std::string  name      = "MainEvent";
+        if ( tae_index < ( TAESize ) / 2 ) { name = "Prev"; }
+        if ( tae_index > ( TAESize ) / 2 ) { name = "Next"; }
+        auto index = number( abs( static_cast<int>( tae_index ) - static_cast<int>( TAESize ) / 2 ) );
+        taePrefix  = fmt::format( "{}TAE/{:02d}_{}{}/", prefix, tae_index, name, index );
+      }
+
+      buildHistogram( m_owner, m_nClustersPerEvent, tae, taePrefix + "nClusters",
+                      fmt::format( "Number of clusters{}; Clusters/event; Events", extraInfo ),
+                      GA::Axis<float>{100, -0.5f, 1000 - 0.5f} );
+      buildHistogram( m_owner, m_lcisipm, tae, taePrefix + "LiteClustersInSiPM",
+                      fmt::format( "Lite clusters per SiPM{};Number of clusters;Number of SiPMs", extraInfo ),
+                      GA::Axis<float>{21, -0.5f, 21 - 0.5f} );
+
+      for ( unsigned int fillType = 0; fillType < FillType::NUM_FillTypes; ++fillType ) {
+        std::string fprefix = taePrefix;
+        if ( FillType::WEIGHTED == fillType ) { fprefix += "weighted/"; }
+        buildHistogram( m_owner, m_lciq, {fillType, tae}, fprefix + "LiteClustersPerQuarter",
+                        fmt::format( "Number of clusters{};Quarter;Clusters", extraInfo ),
+                        GA::Axis<float>{FTConstants::nQuartersTotal, -0.5, FTConstants::nQuartersTotal} );
+        buildHistogram( m_owner, m_lcps, {fillType, tae}, fprefix + "LiteClustersPerStation",
+                        fmt::format( "Lite clusters per station{}; Station; Clusters", extraInfo ),
+                        GA::Axis<float>{FTConstants::nStations, 0.5f, FTConstants::nStations + 0.5f} );
+        buildHistogram( m_owner, m_lcpm, {fillType, tae}, fprefix + "LiteClustersPerModule",
+                        fmt::format( "Lite clusters per module{}; Module; Clusters", extraInfo ),
+                        GA::Axis<float>{FTConstants::nModulesMax, -0.5f, FTConstants::nModulesMax - 0.5f} );
+        buildHistogram( m_owner, m_lcpsipm, {fillType, tae}, fprefix + "LiteClustersPerSiPM",
+                        fmt::format( "Lite clusters per SiPM; SiPMID; Clusters", extraInfo ),
+                        GA::Axis<float>{FTConstants::nSiPMsPerModule, -0.5f, FTConstants::nSiPMsPerModule - 0.5f} );
+        buildHistogram( m_owner, m_lcpc, {fillType, tae}, fprefix + "LiteClustersPerChannel",
+                        fmt::format( "Lite clusters per channel; Channel; Clusters", extraInfo ),
+                        GA::Axis<float>{FTConstants::nChannels, -0.5f, FTConstants::nChannels - 0.5f} );
+        buildHistogram( m_owner, m_lcf, {fillType, tae}, fprefix + "LiteClusterFraction",
+                        fmt::format( "Lite cluster fraction;Fraction", extraInfo ), GA::Axis<float>{2, -0.25, 0.75} );
+        buildHistogram( m_owner, m_lcs, {fillType, tae}, fprefix + "LiteClusterSize",
+                        fmt::format( "Lite cluster size{};Size;Clusters", extraInfo ),
+                        GA::Axis<float>{FTMonitoring::maxPseudoSize, -0.5f, FTMonitoring::maxPseudoSize - 0.5f} );
+        buildHistogram(
+            m_owner, m_lcsf, {fillType, tae}, fprefix + "LiteClusterSizeVsFraction",
+            fmt::format( "Cluster size vs fraction{};Size;Fraction", extraInfo ),
+            std::tuple{GA::Axis<float>{FTMonitoring::maxPseudoSize, -0.5f, FTMonitoring::maxPseudoSize - 0.5f, "Size"},
+                       GA::Axis<float>{2, -0.25, 0.75, "Fraction"}} );
+
+        buildHistogram( m_owner, m_lcqsipm, {fillType, tae}, fprefix + "QuarterVsSiPMNumber",
+                        fmt::format( "Quarter ID vs SiPMNumber{}; Quarter ID; SiPM number", extraInfo ),
+                        std::tuple{GA::Axis<float>{FTConstants::nQuartersTotal, -0.5f,
+                                                   FTConstants::nQuartersTotal - 0.5f, "Quarter ID"},
+                                   GA::Axis<float>{FTConstants::nMaxSiPMsPerQuarter, -0.5f,
+                                                   FTConstants::nMaxSiPMsPerQuarter - 0.5f, "SiPM number"}} );
+
+        for ( const unsigned int channelsPerBin : {1, 64} ) {
+          std::string channelsPerBinStr  = "";
+          std::string channelsPerBinName = "";
+          if ( channelsPerBin != 1 ) {
+            channelsPerBinName = fmt::format( "_{}", channelsPerBin );
+            channelsPerBinStr  = fmt::format( " / ({} channels)", channelsPerBin );
+          }
+          std::string post = channelsPerBinName;
+          buildHistogram(
+              m_owner, m_PseudoChannel, {fillType, tae, channelsPerBin},
+              fprefix + "LiteClustersPerPseudoChannel" + post,
+              fmt::format( "clusters per pseudo channel{};Pseudo channel;Clusters{}", extraInfo, channelsPerBinStr ),
+              GA::Axis<float>{FTConstants::nMaxChannelsPerQuarter / channelsPerBin, -0.5,
+                              FTConstants::nMaxChannelsPerQuarter - 0.5f} );
+          for ( size_t layer = 0; layer < FTConstants::nLayersTotal; ++layer ) {
+            buildHistogram( m_owner, m_PseudoChannelPerLayer, {fillType, tae, channelsPerBin, layer},
+                            fprefix + fmt::format( "perLayer/LiteClustersPerPseudoChannel/L{}{}", layer, post ),
+                            fmt::format( "clusters per pseudo channel in L{}{};Pseudo channel;Clusters{}", layer,
+                                         extraInfo, channelsPerBinStr ),
+                            GA::Axis{FTConstants::nMaxChannelsPerQuarter / channelsPerBin, -0.5f,
+                                     FTConstants::nMaxChannelsPerQuarter - 0.5f} );
+          }
+
+          for ( size_t quarter = 0; quarter < FTConstants::nQuartersTotal; ++quarter ) {
+            buildHistogram( m_owner, m_PseudoChannelPerQuarter, {fillType, tae, channelsPerBin, quarter},
+                            fprefix + fmt::format( "perQuarter/LiteClustersPerPseudoChannel/Q{:02d}{}", quarter, post ),
+                            fmt::format( "clusters per pseudo channel in Q{}{};Pseudo channel;Clusters{}", quarter,
+                                         extraInfo, channelsPerBinStr ),
+                            GA::Axis<float>{FTConstants::nMaxChannelsPerQuarter / channelsPerBin, -0.5,
+                                            FTConstants::nMaxChannelsPerQuarter - 0.5f} );
+          }
+
+          for ( size_t station = 1; station < FTConstants::nStations + 1; ++station ) {
+            for ( size_t layer = 0; layer < FTConstants::nLayers; ++layer ) {
+              buildHistogram( m_owner, m_PseudoChannelPerStationAndLayer,
+                              {fillType, tae, channelsPerBin, station, layer},
+                              fprefix + fmt::format( "perStationAndLayer/LiteClustersPerPseudoChannel/T{}L{}{}",
+                                                     station, layer, post ),
+                              fmt::format( "clusters per pseudo channel in T{}L{}{};Pseudo channel;Clusters{}", station,
+                                           layer, extraInfo, channelsPerBinStr ),
+                              GA::Axis<float>{FTConstants::nMaxChannelsPerQuarter / channelsPerBin, -0.5,
+                                              FTConstants::nMaxChannelsPerQuarter - 0.5f} );
+            }
+          }
+
+          for ( size_t station = 1; station < FTConstants::nStations + 1; ++station ) {
+            for ( size_t layer = 0; layer < FTConstants::nLayers; ++layer ) {
+              for ( size_t quarter = 0; quarter < FTConstants::nQuarters; ++quarter ) {
+                buildHistogram(
+                    m_owner, m_PseudoChannelPerStationAndLayerAndQuarter,
+                    {fillType, tae, channelsPerBin, station, layer, quarter},
+                    fprefix + fmt::format( "perStationAndLayerAndQuarter/LiteClustersPerPseudoChannel/T{}L{}Q{}{}",
+                                           station, layer, quarter, post ),
+                    fmt::format( "clusters per pseudo channel in T{}L{}Q{}{};Pseudo "
+                                 "channel;Clusters",
+                                 station, layer, quarter, extraInfo ),
+                    GA::Axis<float>{FTConstants::nMaxChannelsPerQuarter / channelsPerBin, -0.5,
+                                    FTConstants::nMaxChannelsPerQuarter - 0.5f} );
+              }
+            }
+          }
+        }
+
+        // Histograms per station/quarter/module
+        for ( size_t station = 1; station < FTConstants::nStations + 1; station++ ) {
+          if ( m_drawHistsPerStation ) {
+            buildHistogram( m_owner, m_lcpst, {fillType, tae, station},
+                            fprefix + "perStation/LiteClusters/T" + std::to_string( station ),
+                            fmt::format( "Lite Clusters In Station {}{}; Module ID; Clusters", station, extraInfo ),
+                            GA::Axis<float>{FTMonitoring::nModulesPerStation( station ), -0.5f,
+                                            FTMonitoring::nModulesPerStation( station ) - 0.5f} );
+          }
+
+          for ( size_t layer = 0; layer < FTConstants::nLayers; layer++ ) {
+            for ( size_t quarter = 0; quarter < FTConstants::nQuarters; quarter++ ) {
+              const auto SLQ = fmt::format( "S{}L{}Q{}", station, layer, quarter );
+
+              if ( m_drawHistsPerQuarter ) {
+
+                buildHistogram( m_owner, m_fracpq, {fillType, tae, station, layer, quarter},
+                                fprefix + "perQuarter/Fraction/" + SLQ,
+                                fmt::format( "Fraction in {}{};Fraction;Clusters", SLQ, extraInfo ),
+                                GA::Axis<float>{2, -0.25, 0.75} );
+                buildHistogram(
+                    m_owner, m_pseusizepq, {fillType, tae, station, layer, quarter},
+                    fprefix + "perQuarter/PseudoSize/" + SLQ,
+                    fmt::format( "Pseudo size in {}{};Pseudo size; Clusters", SLQ, extraInfo ),
+                    GA::Axis<float>{FTMonitoring::maxPseudoSize, -0.5f, FTMonitoring::maxPseudoSize - 0.5f} );
+                buildHistogram(
+                    m_owner, m_sipmpq, {fillType, tae, station, layer, quarter},
+                    fprefix + "perQuarter/ClustersPerSiPM/" + SLQ,
+                    fmt::format( "Clusters per SiPM in {}{};SiPM number;Clusters", SLQ, extraInfo ),
+                    GA::Axis<float>{FTConstants::nMaxSiPMsPerQuarter, -0.5f, FTConstants::nMaxSiPMsPerQuarter - 0.5f} );
+              }
+              if ( m_drawHistsPerModule ) {
+                for ( size_t module = 0; module < FTMonitoring::nModulesPerQuarter( station ); module++ ) {
+                  const auto SLQM = fmt::format( "S{}L{}Q{}M{}", station, layer, quarter, module );
+                  buildHistogram(
+                      m_owner, m_lcichpm, {fillType, tae, station, layer, quarter, module},
+                      fprefix + "perModule/LiteClustersPerChannel/" + SLQM,
+                      fmt::format( "Lite Clusters Per Channel in {}{};Channel number; Clusters", SLQM, extraInfo ),
+                      GA::Axis<float>{FTConstants::nChannelsPerModule, -0.5f, FTConstants::nChannelsPerModule - 0.5f} );
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  };
+
+  void fill( const DeFT& deFT, const ODIN& odin, unsigned int taeIndex, const FTLiteClusters& clusters,
+             std::vector<unsigned int> SiPMsToSkip ) {
+    std::array<std::array<std::array<std::vector<unsigned int>, FTConstants::nQuarters>, FTConstants::nLayers>,
+               FTConstants::nMaxSiPMsPerQuarter>
+                        clustersPerSiPMIdxQuarter;
+    std::optional<uint> prevSiPM, prevModuleID;
+    int                 clustersInSiPM = 0;
+
+    ( *m_clustersPerBunchCrossing )[odin.bunchId()] += clusters.size();
+    ++m_nClustersPerEvent.at( taeIndex )[clusters.size()];
+
+    for ( const auto& cluster : clusters.range() ) {
+      LHCb::Detector::FTChannelID chanID               = cluster.channelID();
+      unsigned int                globalQuarterIdx     = chanID.globalQuarterIdx();
+      unsigned int                localSiPMIdx_quarter = chanID.localSiPMIdx_quarter();
+      unsigned int                station              = to_unsigned( chanID.station() );
+      unsigned int                stationIdx           = station - 1;
+      unsigned int                layerIdx             = to_unsigned( chanID.layer() );
+      unsigned int                globalLayerIdx       = layerIdx + FTConstants::nLayers * stationIdx;
+      unsigned int                globalMatIdx  = chanID.localMatIdx() + FTConstants::nMats * chanID.globalModuleIdx();
+      unsigned int                globalSiPMIdx = chanID.localSiPMIdx() + FTConstants::nSiPM * globalMatIdx;
+      unsigned int                quarterIdx    = to_unsigned( chanID.quarter() );
+      unsigned int                moduleIdx     = chanID.localModuleIdx();
+      unsigned int                pseudoChannelIdx = 0;
+      const auto                  mod              = deFT.findModule( chanID );
+
+      if ( mod ) { pseudoChannelIdx = mod->pseudoChannel( chanID ); }
+
+      if ( std::find( SiPMsToSkip.begin(), SiPMsToSkip.end(), globalSiPMIdx ) != SiPMsToSkip.end() ) continue;
+
+      ++m_clustersPerBunchCrossingInSide.at( chanID.getSide() )[odin.bunchId()];
+
+      if ( odin.isTAE() ) {
+        const int taeCenter = 1 + m_TAEHalfWindow;
+        const int taeShift  = taeIndex - taeCenter;
+        ( *m_meanTAEShiftSiPMProfile )[globalSiPMIdx] += taeShift;
+        ++( *m_meanTAEShiftSiPM )[{globalSiPMIdx, taeShift}];
+        ++m_meanTAEShiftSiPMinQuarter.at( {station, layerIdx, quarterIdx} )[{localSiPMIdx_quarter, taeShift}];
+        ++( *m_clustersPerTAE )[taeIndex];
+        ++( *m_clustersPerTAEShift )[taeShift];
+        ++m_clustersPerTAEShiftInSide.at( chanID.getSide() )[taeShift];
+
+        if ( m_timingStepsTotal > 0 && odin.calibrationStep() < m_timingStepsTotal ) {
+          m_meanTAEShiftSiPMProfileZS_step.at( odin.calibrationStep() )[globalSiPMIdx] += taeShift;
+          ++m_meanTAEShiftSiPMZS_step.at(
+              odin.calibrationStep() )[GA::HistoInputType<float, 2>( globalSiPMIdx, taeShift )];
+          ++( *m_clustersPerStep )[odin.calibrationStep()];
+        }
+      }
+
+      if ( m_drawCorrelationPlots ) {
+        // save sipmIdx per quarter of each cluster for correlation plots
+        clustersPerSiPMIdxQuarter[stationIdx][layerIdx][quarterIdx].push_back( localSiPMIdx_quarter );
+      }
+      for ( unsigned int fillType = 0; fillType < FillType::NUM_FillTypes; ++fillType ) {
+        double weight = 1;
+        if ( FillType::WEIGHTED == fillType ) {
+          weight = 1. / (double)clusters.size();
+          weight /= m_normalization;
+        }
+        m_lcps.at( {fillType, taeIndex} )[to_unsigned( chanID.station() )] += weight;
+        m_lcpm.at( {fillType, taeIndex} )[to_unsigned( chanID.module() )] += weight;
+        m_lcpsipm.at( {fillType, taeIndex} )[chanID.sipmInModule()] += weight;
+        m_lcpc.at( {fillType, taeIndex} )[chanID.channel()] += weight;
+        if ( mod ) {
+          for ( const unsigned int channelsPerBin : {1, 64} ) {
+            m_PseudoChannel.at( {fillType, taeIndex, channelsPerBin} )[pseudoChannelIdx] += weight;
+            m_PseudoChannelPerQuarter.at( {fillType, taeIndex, channelsPerBin, globalQuarterIdx} )[pseudoChannelIdx] +=
+                weight;
+            m_PseudoChannelPerLayer.at( {fillType, taeIndex, channelsPerBin, globalLayerIdx} )[pseudoChannelIdx] +=
+                weight;
+            m_PseudoChannelPerStationAndLayer.at(
+                {fillType, taeIndex, channelsPerBin, station, layerIdx} )[pseudoChannelIdx] += weight;
+            m_PseudoChannelPerStationAndLayerAndQuarter.at(
+                {fillType, taeIndex, channelsPerBin, station, layerIdx, quarterIdx} )[pseudoChannelIdx] += weight;
+          }
+        }
+
+        m_lcf.at( {fillType, taeIndex} )[cluster.fraction()] += weight;
+        m_lcs.at( {fillType, taeIndex} )[cluster.pseudoSize()] += weight;
+        m_lcsf.at( {fillType, taeIndex} )[GA::HistoInputType<float, 2>( cluster.pseudoSize(), cluster.fraction() )] +=
+            weight;
+
+        if ( m_drawHistsPerQuarter ) {
+          m_lciq.at( {fillType, taeIndex} )[globalQuarterIdx] += weight;
+          m_lcqsipm.at(
+              {fillType, taeIndex} )[GA::HistoInputType<float, 2>( globalQuarterIdx, localSiPMIdx_quarter )] += weight;
+          m_fracpq.at( {fillType, taeIndex, station, layerIdx, quarterIdx} )[cluster.fraction()] += weight;
+          m_pseusizepq.at( {fillType, taeIndex, station, layerIdx, quarterIdx} )[cluster.pseudoSize()] += weight;
+          m_sipmpq.at( {fillType, taeIndex, station, layerIdx, quarterIdx} )[localSiPMIdx_quarter] += weight;
+        }
+        if ( m_drawHistsPerStation ) {
+          m_lcpst.at( {fillType, taeIndex, station} )[chanID.localModuleIdx_station()] += weight;
+        }
+        if ( m_drawHistsPerModule ) {
+          m_lcichpm.at( {fillType, taeIndex, station, layerIdx, quarterIdx,
+                         moduleIdx} )[chanID.localChannelIdx_module()] += weight;
+        }
+      }
+      // Count the number of clusters per SiPM
+      uint thisSiPM = chanID.globalSiPMID();
+      if ( prevSiPM && thisSiPM != *prevSiPM && clustersInSiPM != 0 ) {
+        ++m_lcisipm.at( taeIndex )[clustersInSiPM];
+        clustersInSiPM = 0;
+      }
+      prevSiPM     = thisSiPM;
+      prevModuleID = chanID.globalModuleIdx();
+      ++clustersInSiPM;
+    }
+    ++m_lcisipm.at( taeIndex )[clustersInSiPM]; // Fill this for the last time
+
+    if ( m_drawCorrelationPlots ) {
+      /// sort clusters by SiPM index in every layer
+      for ( size_t stationIdx = 0; stationIdx < FTConstants::nStations; stationIdx++ ) {
+        for ( size_t quarterIdx = 0; quarterIdx < FTConstants::nQuarters; quarterIdx++ ) {
+          for ( size_t layerIdx = 0; layerIdx < FTConstants::nLayers; layerIdx++ ) {
+            auto& layer = clustersPerSiPMIdxQuarter[stationIdx][layerIdx][quarterIdx];
+            sort( layer.begin(), layer.end() );
+          }
+        }
+      }
+
+      /// correlation plots
+      size_t correlationPlot = 0;
+      for ( size_t stationIdx = 0; stationIdx < FTConstants::nStations; stationIdx++ ) {
+        for ( size_t layerAIdx = 0; layerAIdx < FTConstants::nLayers; layerAIdx++ ) {
+          for ( size_t layerBIdx = layerAIdx + 1; layerBIdx < FTConstants::nLayers; layerBIdx++ ) {
+            for ( size_t quarterIdx = 0; quarterIdx < FTConstants::nQuarters; quarterIdx++ ) {
+              ++correlationPlot;
+              const auto layerA = clustersPerSiPMIdxQuarter[stationIdx][layerAIdx][quarterIdx];
+              const auto layerB = clustersPerSiPMIdxQuarter[stationIdx][layerBIdx][quarterIdx];
+              if ( layerA.size() != layerB.size() )
+                continue; // try cluster matching between layers only when layers have the
+                          // same number of clusters
+
+              for ( size_t i = 0; i < layerA.size(); ++i ) {
+                ++m_correlationSiPM[correlationPlot - 1][GA::HistoInputType<float, 2>( layerA[i], layerB[i] )];
+              }
+            }
+          }
+        }
+      }
+    }
+  };
+};
\ No newline at end of file
diff --git a/FT/FTMonitors/src/FTClusterMonitor.cpp b/FT/FTMonitors/src/FTClusterMonitor.cpp
index 656dbde5fcaab638eac1e9579d233575849ccb1b..930c31f780fc0984c714a39e68af1f62f905a163 100644
--- a/FT/FTMonitors/src/FTClusterMonitor.cpp
+++ b/FT/FTMonitors/src/FTClusterMonitor.cpp
@@ -20,10 +20,12 @@
 #include <Gaudi/Accumulators/Histogram.h>
 #include <GaudiKernel/GaudiException.h>
 
+#include "ClusterMonitor.h"
 #include "Detector/FT/FTChannelID.h"
 #include "Detector/FT/FTConstants.h"
 #include "FTMonitoring.h"
 #include "Kernel/FastClusterContainer.h"
+#include "TAEHandler.h"
 
 /** @class FTClusterMonitor FTClusterMonitor.cpp
  *
@@ -31,9 +33,11 @@
  *  @author Roel Aaij, adapted by Lex Greeven, Johannes Heuel
  *  @date   2018-12-13
  */
-using FTLiteClusters = LHCb::FTLiteCluster::FTLiteClusters;
-using ODIN           = LHCb::ODIN;
-namespace GA         = Gaudi::Accumulators;
+using FTLiteClusters  = LHCb::FTLiteCluster::FTLiteClusters;
+using ODIN            = LHCb::ODIN;
+namespace GA          = Gaudi::Accumulators;
+namespace FTConstants = LHCb::Detector::FT;
+
 class FTClusterMonitor : public Gaudi::Functional::Consumer<void( const FTLiteClusters&, const DeFT&, const ODIN& ),
                                                             LHCb::DetDesc::usesBaseAndConditions<GaudiHistoAlg, DeFT>> {
 public:
@@ -41,82 +45,35 @@ public:
 
   StatusCode initialize() override;
 
-  void operator()( const FTLiteClusters&, const DeFT&, ODIN const& ) const override;
+  void operator()( const FTLiteClusters&, const DeFT&, const ODIN& ) const override;
 
 private:
   void createHistograms();
 
-  mutable TAEHandler<FTClusterMonitor> m_TAEHandler;
+  mutable TAEHandler<FTClusterMonitor>     m_TAEHandler;
+  mutable ClusterMonitor<FTClusterMonitor> m_clusterMonitor;
 
   // TAE global
-  mutable GA::Counter<>                                m_nCalls{this, "number of calls"};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_TAEtype{
-      this, "tae_type", "TAE type; TAE type; Events", {26, -4.5f, 21.5f}};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_TAEidx{
-      this, "tae_index", "TAE index; TAE index; Events", {22, -0.5f, 21.5f}};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_clustersPerTAE{
-      this, "nClustersPerTAE", "Number of clusters per TAE; TAE type; Clusters", GA::Axis<float>{22, -0.5f, 21.5f}};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_eventsPerBunchCrossing{
-      this, "EventsPerBunchCrossing", "bunch crossing ID; BX ID; Events", {4096, -0.5f, 4095 + 0.5f}};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_clustersPerBunchCrossing{
-      this, "ClustersPerBunchCrossing", "bunch crossing ID; BX ID; Clusters", {4096, -0.5f, 4095 + 0.5f}};
-
-  // once per TAE
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_lcps;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_lcpm;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_lcpsipm;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_lcpc;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_lcf;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_lcs;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_nc;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_lcisipm;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_lciq;
-  mutable MultiIndex<GA::Histogram<2, GA::atomicity::full, float>> m_lcsf;
-  mutable MultiIndex<GA::Histogram<2, GA::atomicity::full, float>> m_lcqsipm;
-
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_PseudoChannel;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_PseudoChannelPerLayer;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_PseudoChannelPerQuarter;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_PseudoChannelPerStationAndLayer;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_PseudoChannelPerStationAndLayerAndQuarter;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_PseudoChannel64PerStationAndLayerAndQuarter;
-
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_PseudoChannel64;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_PseudoChannel64PerLayer;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_PseudoChannel64PerQuarter;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_PseudoChannel64PerStationAndLayer;
-
-  // once per TAE/station/quarter/module
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_lcichpm;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_lcipchpq;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_sipmpq;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_fracpq;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_pseusizepq;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_lcpst;
-
-  // Property for drawing histograms per station
-  Gaudi::Property<bool> m_drawHistsPerStation{this, "DrawHistsPerStation", true,
-                                              "Boolean for drawing histrograms per station"};
-
-  // Property for drawing histograms per quarter
-  Gaudi::Property<bool> m_drawHistsPerQuarter{this, "DrawHistsPerQuarter", true,
-                                              "Boolean for drawing histrograms per quarter"};
-
-  // Property for drawing histograms per module
-  Gaudi::Property<bool> m_drawHistsPerModule{this, "DrawHistsPerModule", true,
-                                             "Boolean for drawing histograms per module"};
-
-  // Property for drawing histograms per SiPM
-  Gaudi::Property<bool> m_drawHistsPerSiPM{this, "DrawHistsPerSiPM", true, "Boolean for drawing histrograms per SiPM"};
-
-  Gaudi::Property<unsigned int> m_manualTAEBunchIdFirst{this, "manualTAEBunchIdFirst", 0,
-                                                        "center of first event in a TAE group"};
-  Gaudi::Property<unsigned int> m_manualTAESpacing{this, "manualTAESpacing", 0, "spacing between TAE groups"};
-  Gaudi::Property<unsigned int> m_manualTAENTAE{this, "manualTAENTAE", 0, "number of TAE groups"};
-  Gaudi::Property<unsigned int> m_TAEHalfWindow{this, "TAEHalfWindow", 2, "TAE half window"};
-  Gaudi::Property<unsigned int> m_clustersPerBxMin{this, "ClustersPerBxMin", 0, "Low threshold for cluster per BX"};
-  Gaudi::Property<bool>         m_enableTAE{this, "enableTAE", false, "enable TAE mode"};
-  Gaudi::Property<bool>         m_enableTest{this, "enableTest", false, "enable test mode"};
+  mutable GA::Counter<> m_nCalls{this, "number of calls"};
+
+  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>> m_belowThreshold;
+  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>> m_eventsPerBunchCrossing;
+
+  Gaudi::Property<bool> m_drawHistsPerStation{this, "DrawHistsPerStation", true, "Enable histrograms per station"};
+  Gaudi::Property<bool> m_drawHistsPerQuarter{this, "DrawHistsPerQuarter", true, "Enable histrograms per quarter"};
+  Gaudi::Property<bool> m_drawHistsPerModule{this, "DrawHistsPerModule", true, "Enable histograms per module"};
+  Gaudi::Property<bool> m_drawCorrelationPlots{this, "DrawCorrelationPlots", true, "Enable correlation plots"};
+
+  Gaudi::Property<double>       m_normalization{this, "Normalization", 1.,
+                                          "Normalization factor to use in weighted histograms"};
+  Gaudi::Property<std::string>  m_extraInfo{this, "ExtraInfo", "", "Extra information to add to the plot"};
+  Gaudi::Property<unsigned int> m_timingStepsTotal{this, "TimingStepsTotal", 0, "Total number of timing scan steps"};
+  Gaudi::Property<std::vector<unsigned int>> m_SiPMsToSkip{this, "SiPMsToSkip", {}, "a list of SiPMs to skip"};
+  Gaudi::Property<unsigned int>              m_TAEHalfWindow{this, "TAEHalfWindow", 2, "TAE half window"};
+  Gaudi::Property<unsigned int> m_clustersPerBxMin{this, "ClustersPerBxMin", 10, "Low threshold for cluster per BX"};
+  Gaudi::Property<std::vector<unsigned int>> m_TAEBunchIds{
+      this, "TAEBunchIds", {}, "Center bunch ids of all TAE groups"};
+  Gaudi::Property<bool> m_enableTAE{this, "enableTAE", false, "enable TAE mode"};
 };
 
 // Declaration of the Algorithm Factory
@@ -127,356 +84,48 @@ FTClusterMonitor::FTClusterMonitor( const std::string& name, ISvcLocator* pSvcLo
                 {KeyValue{"ClusterLocation", LHCb::FTLiteClusterLocation::Default},
                  KeyValue{"FTDetectorLocation", DeFTDetectorLocation::Default},
                  KeyValue{"InputODIN", LHCb::ODINLocation::Default}} )
-    , m_TAEHandler( this ) {}
-
-void FTClusterMonitor::createHistograms() {
-  unsigned int TAESize = 2 * m_TAEHalfWindow + 1;
-  m_lcps.set_dimensions( TAESize + 1 );
-  m_lcpm.set_dimensions( TAESize + 1 );
-  m_lcpsipm.set_dimensions( TAESize + 1 );
-  m_lcpc.set_dimensions( TAESize + 1 );
-  m_lcf.set_dimensions( TAESize + 1 );
-  m_lcs.set_dimensions( TAESize + 1 );
-  m_nc.set_dimensions( TAESize + 1 );
-  m_lcisipm.set_dimensions( TAESize + 1 );
-  m_lciq.set_dimensions( TAESize + 1 );
-  m_lcsf.set_dimensions( TAESize + 1 );
-  m_lcqsipm.set_dimensions( TAESize + 1 );
-  m_lcichpm.set_dimensions( TAESize + 1 );
-
-  m_PseudoChannel.set_dimensions( TAESize + 1 );
-  m_PseudoChannelPerLayer.set_dimensions( TAESize + 1, LHCb::Detector::FT::nLayersTotal );
-  m_PseudoChannelPerQuarter.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_PseudoChannelPerStationAndLayer.set_dimensions( TAESize + 1, LHCb::Detector::FT::nStations,
-                                                    LHCb::Detector::FT::nLayers );
-  m_PseudoChannelPerStationAndLayerAndQuarter.set_dimensions(
-      TAESize + 1, LHCb::Detector::FT::nStations, LHCb::Detector::FT::nLayers, LHCb::Detector::FT::nQuarters );
-  m_PseudoChannel64.set_dimensions( TAESize + 1 );
-  m_PseudoChannel64PerLayer.set_dimensions( TAESize + 1, LHCb::Detector::FT::nLayersTotal );
-  m_PseudoChannel64PerQuarter.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_PseudoChannel64PerStationAndLayer.set_dimensions( TAESize + 1, LHCb::Detector::FT::nStations,
-                                                      LHCb::Detector::FT::nLayers );
-  m_PseudoChannel64PerStationAndLayerAndQuarter.set_dimensions(
-      TAESize + 1, LHCb::Detector::FT::nStations, LHCb::Detector::FT::nLayers, LHCb::Detector::FT::nQuarters );
-
-  m_lcipchpq.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_sipmpq.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_fracpq.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_pseusizepq.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_lcpst.set_dimensions( TAESize + 1, LHCb::Detector::FT::nStations );
-
-  for ( size_t i = 0; i < ( TAESize ) + 1; ++i ) {
-    if ( !m_enableTAE && i > 0 ) { return; }
-    auto number = []( unsigned int num ) { return num == 0 ? "" : std::to_string( num ); };
-
-    std::string prefix = "nonTAE/";
-    if ( i > 0 ) {
-      const size_t tae_index = i - 1;
-      std::string  name      = "MainEvent";
-      if ( tae_index < ( TAESize ) / 2 ) { name = "Prev"; }
-      if ( tae_index > ( TAESize ) / 2 ) { name = "Next"; }
-      auto index = number( abs( static_cast<int>( tae_index ) - static_cast<int>( TAESize ) / 2 ) );
-      prefix     = fmt::format( "TAE/{:02d}_{}{}/", tae_index, name, index );
-    }
-
-    m_lcps.emplace_back( this, prefix + "LiteClustersPerStation", "Lite clusters per station; Station; Clusters",
-                         GA::Axis<float>{LHCb::Detector::FT::nStations, 0.5f, LHCb::Detector::FT::nStations + 0.5f} );
-    m_lcpm.emplace_back(
-        this, prefix + "LiteClustersPerModule", "Lite clusters per module; Module; Clusters",
-        GA::Axis<float>{LHCb::Detector::FT::nModulesMax, -0.5f, LHCb::Detector::FT::nModulesMax - 0.5f} );
-    m_lcpsipm.emplace_back(
-        this, prefix + "LiteClustersPerSiPM", "Lite clusters per SiPM; SiPMID; Clusters",
-        GA::Axis<float>{LHCb::Detector::FT::nSiPMsPerModule, -0.5f, LHCb::Detector::FT::nSiPMsPerModule - 0.5f} );
-    m_lcpc.emplace_back( this, prefix + "LiteClustersPerChannel", "Lite clusters per channel; Channel; Clusters",
-                         GA::Axis<float>{LHCb::Detector::FT::nChannels, -0.5f, LHCb::Detector::FT::nChannels - 0.5f} );
-    m_lcf.emplace_back( this, prefix + "LiteClusterFraction", "Lite cluster fraction; Fraction",
-                        GA::Axis<float>{2, -0.25, 0.75} );
-    m_lcs.emplace_back( this, prefix + "LiteClusterSize", "Lite cluster size; Size",
-                        GA::Axis<float>{FTMonitoring::maxPseudoSize, -0.5f, FTMonitoring::maxPseudoSize - 0.5f} );
-    m_nc.emplace_back( this, prefix + "nClusters", "Number of clusters; Clusters/event; Events",
-                       GA::Axis<float>{100, -0.5f, 1000 - 0.5f} );
-    m_lcisipm.emplace_back( this, prefix + "LiteClustersInSiPM",
-                            "Lite clusters per SiPM; Number of clusters; Number of SiPMs",
-                            GA::Axis<float>{21, -0.5f, 21 - 0.5f} );
-    m_lcsf.emplace_back(
-        this, prefix + "LiteClusterSizeVsFraction", "Cluster size vs fraction ; Size; Fraction",
-        std::tuple{GA::Axis<float>{FTMonitoring::maxPseudoSize, -0.5f, FTMonitoring::maxPseudoSize - 0.5f, "Size"},
-                   GA::Axis<float>{2, -0.25, 0.75, "Fraction"}} );
-
-    m_lcqsipm.emplace_back(
-        this, prefix + "QuarterVsSiPMNumber", "Quarter ID vs SiPMNumber; Quarter ID; SiPM number",
-        std::tuple{GA::Axis<float>{LHCb::Detector::FT::nQuartersTotal, -0.5f, LHCb::Detector::FT::nQuartersTotal - 0.5f,
-                                   "Quarter ID"},
-                   GA::Axis<float>{LHCb::Detector::FT::nMaxSiPMsPerQuarter, -0.5f,
-                                   LHCb::Detector::FT::nMaxSiPMsPerQuarter - 0.5f, "SiPM number"}} );
-
-    m_PseudoChannel.emplace_back( this, prefix + "LiteClustersPerPseudoChannel",
-                                  "Lite clusters per pseudo channel; Pseudo channel; Clusters",
-                                  GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter, -0.5f,
-                                                  LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-    for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayersTotal; ++layer ) {
-      m_PseudoChannelPerLayer.emplace_back(
-          this, prefix + "perLayer/" + "LiteClustersPerPseudoChannelLayer" + std::to_string( layer ),
-          "Lite clusters per pseudo channel in layer " + std::to_string( layer ) + "; Pseudo channel; Clusters",
-          GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter, -0.5f,
-                          LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-    }
-
-    for ( size_t quarter = 0; quarter < LHCb::Detector::FT::nQuartersTotal; ++quarter ) {
-      m_PseudoChannelPerQuarter.emplace_back(
-          this, prefix + "perQuarter/" + "LiteClustersPerPseudoChannelQuarter" + fmt::format( "{:02d}", quarter ),
-          "Lite clusters per pseudo channel in quarter " + std::to_string( quarter ) + "; Pseudo channel; Clusters",
-          GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter, -0.5f,
-                          LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-    }
-
-    for ( size_t station = 1; station < LHCb::Detector::FT::nStations + 1; ++station ) {
-      for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayers; ++layer ) {
-        m_PseudoChannelPerStationAndLayer.emplace_back(
-            this,
-            prefix + "perStationAndLayer/" + "LiteClustersPerPseudoChannelStation" + std::to_string( station ) +
-                "Layer" + std::to_string( layer ),
-            "Lite clusters per pseudo channel in station " + std::to_string( station ) + " in layer " +
-                std::to_string( layer ) + "; Pseudo channel; Clusters",
-            GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter, -0.5f,
-                            LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-      }
-    }
-
-    for ( size_t station = 1; station < LHCb::Detector::FT::nStations + 1; ++station ) {
-      for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayers; ++layer ) {
-        for ( size_t quarter = 0; quarter < LHCb::Detector::FT::nQuarters; ++quarter ) {
-          m_PseudoChannelPerStationAndLayerAndQuarter.emplace_back(
-              this,
-              prefix + "perStationAndLayerAndQuarter/" + "LiteClustersPerPseudoChannelStation" +
-                  std::to_string( station ) + "Layer" + std::to_string( layer ) + "Quarter" + std::to_string( quarter ),
-              "Lite clusters per pseudo channel in station " + std::to_string( station ) + " in layer " +
-                  std::to_string( layer ) + " in quarter " + std::to_string( quarter ) + "; Pseudo channel; Clusters",
-              GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter, -0.5f,
-                              LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-        }
-      }
-    }
-
-    m_PseudoChannel64.emplace_back( this, prefix + "coarse/LiteClustersPerPseudoChannel",
-                                    "Lite clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)",
-                                    GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter / 64, -0.5f,
-                                                    LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-    for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayersTotal; ++layer ) {
-      m_PseudoChannel64PerLayer.emplace_back(
-          this, prefix + "perLayer/" + "coarse/LiteClustersPerPseudoChannelLayer" + std::to_string( layer ),
-          "Lite clusters per pseudo channel in layer " + std::to_string( layer ) +
-              "; Pseudo channel; Clusters / (64 channels)",
-          GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter / 64, -0.5f,
-                          LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-    }
-
-    for ( size_t quarter = 0; quarter < LHCb::Detector::FT::nQuartersTotal; ++quarter ) {
-      m_PseudoChannel64PerQuarter.emplace_back(
-          this,
-          prefix + "perQuarter/" + "coarse/LiteClustersPerPseudoChannelQuarter" + fmt::format( "{:02d}", quarter ),
-          "Lite clusters per pseudo channel in quarter " + std::to_string( quarter ) +
-              "; Pseudo channel; Clusters / (64 channels)",
-          GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter / 64, -0.5f,
-                          LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-    }
-
-    for ( size_t station = 1; station < LHCb::Detector::FT::nStations + 1; ++station ) {
-      for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayers; ++layer ) {
-        m_PseudoChannel64PerStationAndLayer.emplace_back(
-            this,
-            prefix + "perStationAndLayer/" + "coarse/LiteClustersPerPseudoChannelStation" + std::to_string( station ) +
-                "Layer" + std::to_string( layer ),
-            "Lite clusters per pseudo channel in station " + std::to_string( station ) + " in layer " +
-                std::to_string( layer ) + "; Pseudo channel; Clusters / (64 channels)",
-            GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter / 64, -0.5f,
-                            LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-      }
-    }
-
-    for ( size_t station = 1; station < LHCb::Detector::FT::nStations + 1; ++station ) {
-      for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayers; ++layer ) {
-        for ( size_t quarter = 0; quarter < LHCb::Detector::FT::nQuarters; ++quarter ) {
-          m_PseudoChannel64PerStationAndLayerAndQuarter.emplace_back(
-              this,
-              prefix + "perStationAndLayerAndQuarter/" + "coarse/LiteClustersPerPseudoChannelStation" +
-                  std::to_string( station ) + "Layer" + std::to_string( layer ) + "Quarter" + std::to_string( quarter ),
-              "Lite clusters per pseudo channel in station " + std::to_string( station ) + " in layer " +
-                  std::to_string( layer ) + " in quarter " + std::to_string( quarter ) +
-                  "; Pseudo channel; Clusters / (64 channels)",
-              GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter / 64, -0.5f,
-                              LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-        }
-      }
-    }
-
-    if ( m_drawHistsPerQuarter ) {
-      m_lciq.emplace_back( this, prefix + "LiteClustersPerQuarter", "Number of clusters; Quarter; Clusters",
-                           GA::Axis<float>{LHCb::Detector::FT::nQuartersTotal, 0, LHCb::Detector::FT::nQuartersTotal} );
-    }
-
-    // Histograms per station/quarter/module
-    size_t prev_stationID( 999 );
-    size_t prev_quarter( 999 );
-    for ( size_t station = 1; station < LHCb::Detector::FT::nStations + 1; station++ ) {
-      for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayers; layer++ ) {
-        for ( size_t quarter = 0; quarter < LHCb::Detector::FT::nQuarters; quarter++ ) {
-          for ( size_t module = 0; module < FTMonitoring::nModulesPerQuarter( station ); module++ ) {
-
-            const auto& SLQ =
-                "_S" + std::to_string( station ) + "L" + std::to_string( layer ) + "Q" + std::to_string( quarter );
-            const auto& QSLQ  = " in quarter" + SLQ + "; ";
-            const auto& ISLQ  = "InQuarter" + SLQ;
-            const auto& SLQM  = SLQ + "M" + std::to_string( module );
-            const auto& MSLQM = " in module" + SLQM + "; ";
-
-            if ( m_drawHistsPerQuarter && ( quarter != prev_quarter ) ) {
-
-              m_fracpq.emplace_back( this, prefix + "Fraction" + ISLQ, "Fraction" + QSLQ + "Fraction; Clusters",
-                                     GA::Axis<float>{2, -0.25, 0.75} );
-              m_pseusizepq.emplace_back(
-                  this, prefix + "PseudoSize" + ISLQ, "Pseudo size" + QSLQ + "Pseudo size; Clusters",
-                  GA::Axis<float>{FTMonitoring::maxPseudoSize, -0.5f, FTMonitoring::maxPseudoSize - 0.5f} );
-              m_sipmpq.emplace_back( this, prefix + "ClustersPerSiPM" + ISLQ,
-                                     "Clusters per SiPM" + QSLQ + "SiPM number; Clusters",
-                                     GA::Axis<float>{LHCb::Detector::FT::nMaxSiPMsPerQuarter, -0.5f,
-                                                     LHCb::Detector::FT::nMaxSiPMsPerQuarter - 0.5f} );
-              m_lcipchpq.emplace_back( this, prefix + "ClustersPerPseudochannel" + ISLQ,
-                                       "Clusters per pseudo channel" + QSLQ + "Pseudo channel; Clusters / (8 channels)",
-                                       GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter / 8, -0.5f,
-                                                       LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-            }
-            prev_quarter = quarter;
-            if ( m_drawHistsPerModule ) {
-              m_lcichpm.emplace_back( this, prefix + "LiteClustersPerChannelinModule" + SLQM,
-                                      "Lite Clusters Per Channel" + MSLQM + "Channel number; Clusters",
-                                      GA::Axis<float>{LHCb::Detector::FT::nChannelsPerModule, -0.5f,
-                                                      LHCb::Detector::FT::nChannelsPerModule - 0.5f} );
-            }
-            if ( m_drawHistsPerStation && ( station != prev_stationID ) ) {
-              m_lcpst.emplace_back( this, prefix + "LiteClustersInStation_S" + std::to_string( station ),
-                                    "Lite Clusters In Station " + std::to_string( station ) + "; Module ID; Clusters",
-                                    GA::Axis<float>{FTMonitoring::nMaxMoniModulePerStation( station ), -0.5f,
-                                                    FTMonitoring::nMaxMoniModulePerStation( station ) - 0.5f} );
-            }
-            prev_stationID = station;
-          }
-        }
-      }
-    }
-  }
-}
+    , m_TAEHandler( this )
+    , m_clusterMonitor( this ) {}
 
 StatusCode FTClusterMonitor::initialize() {
   return Consumer::initialize().andThen( [&] {
-    m_TAEHandler.setManualTAE( m_manualTAEBunchIdFirst, m_manualTAESpacing, m_manualTAENTAE );
-    createHistograms();
+    if ( m_clustersPerBxMin > 0 ) {
+      m_belowThreshold.emplace( this, "BelowThreshold",
+                                fmt::format( "Number of events below threshold{};Clusters;Events", m_extraInfo ),
+                                GA::Axis<float>{m_clustersPerBxMin, -0.5f, m_clustersPerBxMin - 0.5f} );
+    }
+    m_eventsPerBunchCrossing.emplace( this, "EventsPerBunchCrossing",
+                                      fmt::format( "bunch crossing ID{}; BX ID; Events", m_extraInfo ),
+                                      GA::Axis<float>{4096, -0.5f, 4095 + 0.5f} );
+
+    m_TAEHandler.setManualTAE( m_enableTAE, m_TAEBunchIds, m_TAEHalfWindow, m_extraInfo );
+    m_clusterMonitor.createHistograms( "", m_TAEHalfWindow, m_drawHistsPerStation, m_drawHistsPerQuarter,
+                                       m_drawHistsPerModule, m_drawCorrelationPlots, m_normalization,
+                                       m_timingStepsTotal, m_extraInfo );
     return StatusCode::SUCCESS;
   } );
 }
 
-void FTClusterMonitor::operator()( const FTLiteClusters& clusters, const DeFT& deFT, ODIN const& odin ) const {
+void FTClusterMonitor::operator()( const FTLiteClusters& clusters, const DeFT& deFT, const ODIN& odin ) const {
   if ( deFT.version() < 61 ) {
     throw GaudiException( "This version requires FTDet v6.1 or higher", "", StatusCode::FAILURE );
   };
 
-  if ( clusters.size() < m_clustersPerBxMin ) { return; }
+  if ( clusters.size() < m_clustersPerBxMin ) {
+    ++( *m_belowThreshold )[clusters.size()];
+    return;
+  }
 
-  ++m_eventsPerBunchCrossing[odin.bunchId()];
-  m_clustersPerBunchCrossing[odin.bunchId()] += clusters.size();
+  ++( *m_eventsPerBunchCrossing )[odin.bunchId()];
 
-  int          taeType  = 0;
   unsigned int taeIndex = 0;
   if ( odin.isTAE() ) {
-    if ( !m_enableTAE ) { return; }
-    if ( odin.timeAlignmentEventIndex() != m_TAEHalfWindow ) {
-      warning() << "TAE half window of event is " << odin.timeAlignmentEventIndex()
-                << " while monitoring is set up for half window of " << m_TAEHalfWindow << ". Skipping this event."
-                << endmsg;
-      return;
-    }
-    taeType = m_TAEHandler.TAEIndexFromOdin( odin );
-    ++m_TAEtype[taeType];
+    auto taeType = m_TAEHandler.TAEIndexFromOdin( odin );
     if ( taeType < 0 ) { return; }
     taeIndex = taeType;
-    ++m_TAEidx[taeIndex - 1];
-  } else {
-    ++m_TAEtype[taeType];
   }
-  m_clustersPerTAE[taeIndex] += clusters.size();
-
-  ++m_nc[taeIndex][clusters.size()];
-  std::optional<uint> prevSiPM, prevModuleID;
-  int                 clustersInSiPM = 0;
-
-  // Loop over FTLiteCluster
-  for ( const auto& cluster : clusters.range() ) {
-    LHCb::Detector::FTChannelID chanID             = cluster.channelID();
-    unsigned int                q_ID               = chanID.globalQuarterIdx();
-    unsigned int                SiPM_ID            = chanID.localSiPMIdx_quarter();
-    unsigned int                stationIndex       = to_unsigned( chanID.station() ) - 1;
-    unsigned int                layerIndex         = to_unsigned( chanID.layer() );
-    unsigned int                layerGlobalIndex   = layerIndex + stationIndex * LHCb::Detector::FT::nLayers;
-    unsigned int                pseudoChannelIndex = 0;
-    const auto                  mod                = deFT.findModule( chanID );
-
-    if ( mod ) { pseudoChannelIndex = mod->pseudoChannel( chanID ); }
-
-    // Draw cluster channel properties
-    ++m_lcps[taeIndex][to_unsigned( chanID.station() )];
-    ++m_lcpm[taeIndex][to_unsigned( chanID.module() )];
-    ++m_lcpsipm[taeIndex][chanID.sipmInModule()];
-    ++m_lcpc[taeIndex][chanID.channel()];
-    if ( mod ) {
-      ++m_PseudoChannel[taeIndex][pseudoChannelIndex];
-      ++m_PseudoChannelPerQuarter[{taeIndex, q_ID}][pseudoChannelIndex];
-      ++m_PseudoChannelPerLayer[{taeIndex, layerGlobalIndex}][pseudoChannelIndex];
-      ++m_PseudoChannelPerStationAndLayer[{taeIndex, stationIndex, layerIndex}][pseudoChannelIndex];
-      ++m_PseudoChannelPerStationAndLayerAndQuarter[{taeIndex, stationIndex, layerIndex,
-                                                     to_unsigned( chanID.quarter() )}][pseudoChannelIndex];
-      ++m_PseudoChannel64[taeIndex][pseudoChannelIndex];
-      ++m_PseudoChannel64PerQuarter[{taeIndex, q_ID}][pseudoChannelIndex];
-      ++m_PseudoChannel64PerLayer[{taeIndex, layerGlobalIndex}][pseudoChannelIndex];
-      ++m_PseudoChannel64PerStationAndLayer[{taeIndex, stationIndex, layerIndex}][pseudoChannelIndex];
-      ++m_PseudoChannel64PerStationAndLayerAndQuarter[{taeIndex, stationIndex, layerIndex,
-                                                       to_unsigned( chanID.quarter() )}][pseudoChannelIndex];
-    }
-    ++m_lcf[taeIndex][cluster.fraction()];
-    ++m_lcs[taeIndex][cluster.pseudoSize()];
-    ++m_lcsf[taeIndex][GA::HistoInputType<float, 2>( cluster.pseudoSize(), cluster.fraction() )];
-    ++m_lcqsipm[taeIndex][GA::HistoInputType<float, 2>( q_ID, SiPM_ID )];
-
-    if ( m_drawHistsPerQuarter ) {
-      ++m_lciq[taeIndex][q_ID];
-      ++m_fracpq[{taeIndex, q_ID}][cluster.fraction()];
-      ++m_pseusizepq[{taeIndex, q_ID}][cluster.pseudoSize()];
-      ++m_sipmpq[{taeIndex, q_ID}][SiPM_ID];
-      if ( mod ) ++m_lcipchpq[{taeIndex, q_ID}][pseudoChannelIndex];
-    }
-    if ( m_drawHistsPerStation ) { ++m_lcpst[{taeIndex, stationIndex}][chanID.localModuleIdx_station()]; }
-    if ( m_drawHistsPerModule ) {
-      ++m_lcichpm[taeIndex][to_unsigned( mod->moduleID() ) * chanID.localChannelIdx_module()];
-    }
 
-    // Count the number of clusters per SiPM
-    uint thisSiPM = chanID.globalSiPMID();
-    if ( prevSiPM && thisSiPM != *prevSiPM && clustersInSiPM != 0 ) {
-      ++m_lcisipm[taeIndex][clustersInSiPM];
-      clustersInSiPM = 0;
-    }
-    prevSiPM     = thisSiPM;
-    prevModuleID = chanID.globalModuleIdx();
-    ++clustersInSiPM;
-  }                                      // Loop over FTLiteClusters
-  ++m_lcisipm[taeIndex][clustersInSiPM]; // Fill this for the last time
-
-  if ( m_enableTest ) {
-    info() << "Print some histograms to compare against test references:" << endmsg;
-    info() << m_TAEidx.toJSON() << endmsg;
-    info() << m_TAEtype.toJSON() << endmsg;
-    info() << m_clustersPerBunchCrossing.toJSON() << endmsg;
-    for ( auto& pc : m_PseudoChannel64 ) info() << pc.toJSON() << endmsg;
-  }
+  m_clusterMonitor.fill( deFT, odin, taeIndex, clusters, m_SiPMsToSkip );
 
   if ( m_nCalls.nEntries() == 0 ) { always() << "Filling Histograms... Please be patient!" << endmsg; }
   ++m_nCalls;
diff --git a/FT/FTMonitors/src/FTDigitMonitor.cpp b/FT/FTMonitors/src/FTDigitMonitor.cpp
index 7e20e0acef4279c3db170f3e628d724eeb6b98b6..ff3a5d5d2cd1c64b7d391ead03e961421228d0f0 100644
--- a/FT/FTMonitors/src/FTDigitMonitor.cpp
+++ b/FT/FTMonitors/src/FTDigitMonitor.cpp
@@ -20,6 +20,7 @@
 #include "GaudiKernel/PhysicalConstants.h"
 #include "GaudiKernel/SystemOfUnits.h"
 #include "Kernel/FastClusterContainer.h"
+#include "TAEHandler.h"
 #include <DetDesc/GenericConditionAccessorHolder.h>
 #include <Gaudi/Accumulators/Histogram.h>
 #include <GaudiKernel/GaudiException.h>
@@ -33,8 +34,9 @@
  *  @date   2020-02-17
  */
 
-namespace GA = Gaudi::Accumulators;
-using ODIN   = LHCb::ODIN;
+using ODIN            = LHCb::ODIN;
+namespace GA          = Gaudi::Accumulators;
+namespace FTConstants = LHCb::Detector::FT;
 
 class FTDigitMonitor
     : public Gaudi::Functional::Consumer<void( const LHCb::FTDigit::FTDigits&, const DeFT&, const ODIN& ),
@@ -53,34 +55,29 @@ private:
 
   // TAE global
   mutable GA::Counter<>                                m_nCalls{this, "number of calls"};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_TAEtype{
-      this, "tae_type", "TAE type; TAE type; Events", {26, -4.5f, 21.5f}};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_TAEidx{
-      this, "tae_index", "TAE index; TAE index; Events", {22, -0.5f, 21.5f}};
   mutable GA::Histogram<1, GA::atomicity::full, float> m_eventsPerBunchCrossing{
-      this, "bunch_crossing", "bunch crossing ID; BX ID; Events", {4096, -0.5f, 4095 + 0.5f}};
+      this, "EventsPerBunchCrossing", "bunch crossing ID; BX ID; Events", {4096, -0.5f, 4095 + 0.5f}};
   mutable GA::Histogram<1, GA::atomicity::full, float> m_nDigits{
       this, "nDigits", "Number of digits; Digits/event; Events", {200, 0, 200000}};
 
   // once per TAE
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_ADCCounts;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerStation;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerModule;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerMat;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerSiPM;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerChannel;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerPseudoChannel;
-  mutable MultiIndex<GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerQuarter;
-  mutable MultiIndex<GA::Histogram<2, GA::atomicity::full, float>> m_digitsPerMatModule;
-  mutable MultiIndex<GA::Histogram<2, GA::atomicity::full, float>> m_digitsPerQuarterLayer;
-
-  Gaudi::Property<unsigned int> m_manualTAEBunchIdFirst{this, "manualTAEBunchIdFirst", 0,
-                                                        "center of first event in a TAE group"};
-  Gaudi::Property<unsigned int> m_manualTAESpacing{this, "manualTAESpacing", 0, "spacing between TAE groups"};
-  Gaudi::Property<unsigned int> m_manualTAENTAE{this, "manualTAENTAE", 0, "number of TAE groups"};
-  Gaudi::Property<unsigned int> m_TAEHalfWindow{this, "TAEHalfWindow", 2, "TAE half window"};
-  Gaudi::Property<bool>         m_enableTAE{this, "enableTAE", false, "enable TAE mode"};
-  Gaudi::Property<bool>         m_enableTest{this, "enableTest", false, "enable test mode"};
+  using taeT = unsigned int;
+  mutable std::map<taeT, GA::Histogram<1, GA::atomicity::full, float>> m_ADCCounts;
+  mutable std::map<taeT, GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerStation;
+  mutable std::map<taeT, GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerModule;
+  mutable std::map<taeT, GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerMat;
+  mutable std::map<taeT, GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerSiPM;
+  mutable std::map<taeT, GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerChannel;
+  mutable std::map<taeT, GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerPseudoChannel;
+  mutable std::map<taeT, GA::Histogram<1, GA::atomicity::full, float>> m_digitsPerQuarter;
+  mutable std::map<taeT, GA::Histogram<2, GA::atomicity::full, float>> m_digitsPerMatModule;
+  mutable std::map<taeT, GA::Histogram<2, GA::atomicity::full, float>> m_digitsPerQuarterLayer;
+
+  Gaudi::Property<std::string>               m_extraInfo{this, "ExtraInfo", "", "Extra information to add to the plot"};
+  Gaudi::Property<unsigned int>              m_TAEHalfWindow{this, "TAEHalfWindow", 2, "TAE half window"};
+  Gaudi::Property<std::vector<unsigned int>> m_TAEBunchIds{
+      this, "TAEBunchIds", {}, "Center bunch ids of all TAE groups"};
+  Gaudi::Property<bool> m_enableTAE{this, "enableTAE", false, "enable TAE mode"};
 };
 
 // Declaration of the Algorithm Factory
@@ -95,7 +92,7 @@ FTDigitMonitor::FTDigitMonitor( const std::string& name, ISvcLocator* pSvcLocato
 
 StatusCode FTDigitMonitor::initialize() {
   return Consumer::initialize().andThen( [&] {
-    m_TAEHandler.setManualTAE( m_manualTAEBunchIdFirst, m_manualTAESpacing, m_manualTAENTAE );
+    m_TAEHandler.setManualTAE( m_enableTAE, m_TAEBunchIds, m_TAEHalfWindow, m_extraInfo );
     createHistograms();
     return StatusCode::SUCCESS;
   } );
@@ -103,65 +100,55 @@ StatusCode FTDigitMonitor::initialize() {
 
 void FTDigitMonitor::createHistograms() {
   unsigned int TAESize = 2 * m_TAEHalfWindow + 1;
+  if ( !m_enableTAE ) { TAESize = 0; }
 
-  m_ADCCounts.set_dimensions( TAESize + 1 );
-  m_digitsPerStation.set_dimensions( TAESize + 1 );
-  m_digitsPerModule.set_dimensions( TAESize + 1 );
-  m_digitsPerMat.set_dimensions( TAESize + 1 );
-  m_digitsPerSiPM.set_dimensions( TAESize + 1 );
-  m_digitsPerChannel.set_dimensions( TAESize + 1 );
-  m_digitsPerPseudoChannel.set_dimensions( TAESize + 1 );
-  m_digitsPerQuarter.set_dimensions( TAESize + 1 );
-  m_digitsPerMatModule.set_dimensions( TAESize + 1 );
-  m_digitsPerQuarterLayer.set_dimensions( TAESize + 1 );
-
-  for ( size_t i = 0; i < TAESize + 1; ++i ) {
-    if ( !m_enableTAE && i > 0 ) { return; }
+  for ( unsigned int tae = 0; tae < TAESize + 1; ++tae ) {
 
     auto number = []( unsigned int num ) { return num == 0 ? "" : std::to_string( num ); };
 
     std::string prefix = "nonTAE/";
-    if ( i > 0 ) {
-      const size_t tae_index = i - 1;
+    if ( tae > 0 ) {
+      const size_t tae_index = tae - 1;
       std::string  name      = "MainEvent";
       if ( tae_index < TAESize / 2 ) { name = "Prev"; }
       if ( tae_index > TAESize / 2 ) { name = "Next"; }
       auto index = number( abs( static_cast<int>( tae_index ) - static_cast<int>( TAESize ) / 2 ) );
       prefix     = fmt::format( "TAE/{:02d}_{}{}/", tae_index, name, index );
     }
-    m_ADCCounts.emplace_back( this, prefix + "ADCCounts", "Charge in 2bit ADC; Charge/digit [ADC]; Number of digits",
-                              GA::Axis<float>{FTMonitoring::maxAdcCharge, -0.5f, FTMonitoring::maxAdcCharge - 0.5f} );
-    m_digitsPerStation.emplace_back(
-        this, prefix + "DigitsPerStation", "Digits per station; Station; Digits",
-        GA::Axis<float>{LHCb::Detector::FT::nStations, 0.5f, LHCb::Detector::FT::nStations + 0.5f} );
-    m_digitsPerModule.emplace_back(
-        this, prefix + "DigitsPerModule", "Digits per module; Module; Digits",
-        GA::Axis<float>{LHCb::Detector::FT::nModulesMax, -0.5f, LHCb::Detector::FT::nModulesMax - 0.5f} );
-    m_digitsPerMat.emplace_back( this, prefix + "DigitsPerMat", "Digits per mat; Mat; Digits",
-                                 GA::Axis<float>{LHCb::Detector::FT::nMats, -0.5f, LHCb::Detector::FT::nMats - 0.5f} );
-    m_digitsPerSiPM.emplace_back(
-        this, prefix + "DigitsPerSiPM", "Digits per SiPM; SiPMID; Digits",
-        GA::Axis<float>{LHCb::Detector::FT::nSiPMsPerModule, -0.5f, LHCb::Detector::FT::nSiPMsPerModule - 0.5f} );
-    m_digitsPerChannel.emplace_back(
-        this, prefix + "DigitsPerChannel", "Digits per channel; Channel; Digits",
-        GA::Axis<float>{LHCb::Detector::FT::nChannels, -0.5f, LHCb::Detector::FT::nChannels - 0.5f} );
-    m_digitsPerPseudoChannel.emplace_back( this, prefix + "DigitsPerPseudoChannel",
-                                           "Digits per pseudochannel; Pseudo channel; Digits",
-                                           GA::Axis<float>{LHCb::Detector::FT::nMaxChannelsPerQuarter / 64, -0.5f,
-                                                           LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f} );
-    m_digitsPerQuarter.emplace_back(
-        this, prefix + "DigitsPerQuarter", "Digits per quarter; Quarter; Digits",
-        GA::Axis<float>{LHCb::Detector::FT::nQuarters, -0.5f, LHCb::Detector::FT::nQuarters - 0.5f} );
-    m_digitsPerMatModule.emplace_back(
-        this, prefix + "DigitsPerMatModule", "Digits per mat and module; Mat; Module",
-        std::tuple{GA::Axis<float>{LHCb::Detector::FT::nMats, -0.5f, LHCb::Detector::FT::nMats - 0.5f, "Mat"},
-                   GA::Axis<float>{LHCb::Detector::FT::nModulesMax, -0.5f, LHCb::Detector::FT::nModulesMax - 0.5f,
-                                   "Module"}} );
-    m_digitsPerQuarterLayer.emplace_back(
-        this, prefix + "DigitsPerQuarterLayer", "Digits per quarter and layer; Quarter; Layer",
-        std::tuple{
-            GA::Axis<float>{LHCb::Detector::FT::nQuarters, -0.5f, LHCb::Detector::FT::nQuarters - 0.5f, "Quarter"},
-            GA::Axis<float>{LHCb::Detector::FT::nLayers, -0.5f, LHCb::Detector::FT::nLayers - 0.5f, "Layer"}} );
+    buildHistogram( this, m_ADCCounts, {tae}, prefix + "ADCCounts",
+                    fmt::format( "Charge in 2bit ADC{};Charge/digit [ADC];Number of digits", m_extraInfo ),
+                    GA::Axis<float>{FTMonitoring::maxAdcCharge, -0.5f, FTMonitoring::maxAdcCharge - 0.5f} );
+    buildHistogram( this, m_digitsPerStation, {tae}, prefix + "DigitsPerStation",
+                    fmt::format( "Digits per station{};Station;Digits", m_extraInfo ),
+                    GA::Axis<float>{FTConstants::nStations, 0.5f, FTConstants::nStations + 0.5f} );
+    buildHistogram( this, m_digitsPerModule, {tae}, prefix + "DigitsPerModule",
+                    fmt::format( "Digits per module;Module;Digits", m_extraInfo ),
+                    GA::Axis<float>{FTConstants::nModulesMax, -0.5f, FTConstants::nModulesMax - 0.5f} );
+    buildHistogram( this, m_digitsPerMat, {tae}, prefix + "DigitsPerMat",
+                    fmt::format( "Digits per mat;Mat;Digits", m_extraInfo ),
+                    GA::Axis<float>{FTConstants::nMats, -0.5f, FTConstants::nMats - 0.5f} );
+    buildHistogram( this, m_digitsPerSiPM, {tae}, prefix + "DigitsPerSiPM",
+                    fmt::format( "Digits per SiPM;SiPMID;Digits", m_extraInfo ),
+                    GA::Axis<float>{FTConstants::nSiPMsPerModule, -0.5f, FTConstants::nSiPMsPerModule - 0.5f} );
+    buildHistogram( this, m_digitsPerChannel, {tae}, prefix + "DigitsPerChannel",
+                    fmt::format( "Digits per channel;Channel;Digits", m_extraInfo ),
+                    GA::Axis<float>{FTConstants::nChannels, -0.5f, FTConstants::nChannels - 0.5f} );
+    buildHistogram(
+        this, m_digitsPerPseudoChannel, {tae}, prefix + "DigitsPerPseudoChannel",
+        "Digits per pseudochannel; Pseudo channel; Digits",
+        GA::Axis<float>{FTConstants::nMaxChannelsPerQuarter / 64, -0.5f, FTConstants::nMaxChannelsPerQuarter - 0.5f} );
+    buildHistogram( this, m_digitsPerQuarter, {tae}, prefix + "DigitsPerQuarter",
+                    fmt::format( "Digits per quarter{};Quarter;Digits", m_extraInfo ),
+                    GA::Axis<float>{FTConstants::nQuarters, -0.5f, FTConstants::nQuarters - 0.5f} );
+    buildHistogram(
+        this, m_digitsPerMatModule, {tae}, prefix + "DigitsPerMatModule",
+        fmt::format( "Digits per mat and module{};Mat;Module", m_extraInfo ),
+        std::tuple{GA::Axis<float>{FTConstants::nMats, -0.5f, FTConstants::nMats - 0.5f, "Mat"},
+                   GA::Axis<float>{FTConstants::nModulesMax, -0.5f, FTConstants::nModulesMax - 0.5f, "Module"}} );
+    buildHistogram( this, m_digitsPerQuarterLayer, {tae}, prefix + "DigitsPerQuarterLayer",
+                    fmt::format( "Digits per quarter and layer{};Quarter;Layer", m_extraInfo ),
+                    std::tuple{GA::Axis<float>{FTConstants::nQuarters, -0.5f, FTConstants::nQuarters - 0.5f, "Quarter"},
+                               GA::Axis<float>{FTConstants::nLayers, -0.5f, FTConstants::nLayers - 0.5f, "Layer"}} );
   }
 }
 
@@ -172,39 +159,21 @@ void FTDigitMonitor::operator()( const LHCb::FTDigit::FTDigits& DigitsCont, cons
 
   ++m_eventsPerBunchCrossing[odin.bunchId()];
 
-  int          taeType  = 0;
   unsigned int taeIndex = 0;
   if ( odin.isTAE() ) {
-    if ( !m_enableTAE ) { return; }
-    if ( odin.timeAlignmentEventIndex() != m_TAEHalfWindow ) {
-      warning() << "TAE half window of event is " << odin.timeAlignmentEventIndex()
-                << " while monitoring is set up for half window of " << m_TAEHalfWindow << ". Skipping this event."
-                << endmsg;
-      return;
-    }
-    taeType = m_TAEHandler.TAEIndexFromOdin( odin );
-    ++m_TAEtype[taeType];
+    auto taeType = m_TAEHandler.TAEIndexFromOdin( odin );
     if ( taeType < 0 ) { return; }
     taeIndex = taeType;
-    ++m_TAEidx[taeIndex - 1];
-  } else {
-    ++m_TAEtype[taeType];
   }
 
   for ( const auto& Digit : DigitsCont.range() ) { fillHistograms( taeIndex, Digit, deFT ); }
   debug() << "ndigits: " << DigitsCont.size() << endmsg;
   ++m_nDigits[DigitsCont.size()];
-
-  if ( m_enableTest ) {
-    info() << "Print some histograms to compare against test references:" << endmsg;
-    info() << m_TAEidx.toJSON() << endmsg;
-    info() << m_TAEtype.toJSON() << endmsg;
-  }
 }
 
 void FTDigitMonitor::fillHistograms( const size_t taeIndex, const LHCb::FTDigit& Digit, const DeFT& deFT ) const {
 
-  ++m_ADCCounts[taeIndex][Digit.adcCount()];
+  ++m_ADCCounts.at( taeIndex )[Digit.adcCount()];
 
   const LHCb::Detector::FTChannelID chanID             = Digit.channelID();
   const auto                        mod                = deFT.findModule( chanID );
@@ -213,20 +182,20 @@ void FTDigitMonitor::fillHistograms( const size_t taeIndex, const LHCb::FTDigit&
   if ( mod ) { pseudoChannelIndex = mod->pseudoChannel( chanID ); }
 
   // 1D
-  ++m_digitsPerStation[taeIndex][(unsigned int)chanID.station()];
-  ++m_digitsPerModule[taeIndex][(unsigned int)chanID.module()];
-  ++m_digitsPerMat[taeIndex][(unsigned int)chanID.mat()];
-  ++m_digitsPerSiPM[taeIndex][(unsigned int)chanID.sipmInModule()];
-  ++m_digitsPerChannel[taeIndex][(unsigned int)chanID.channel()];
-  ++m_digitsPerQuarter[taeIndex][(unsigned int)chanID.quarter()];
+  ++m_digitsPerStation.at( taeIndex )[(unsigned int)chanID.station()];
+  ++m_digitsPerModule.at( taeIndex )[(unsigned int)chanID.module()];
+  ++m_digitsPerMat.at( taeIndex )[(unsigned int)chanID.mat()];
+  ++m_digitsPerSiPM.at( taeIndex )[(unsigned int)chanID.sipmInModule()];
+  ++m_digitsPerChannel.at( taeIndex )[(unsigned int)chanID.channel()];
+  ++m_digitsPerQuarter.at( taeIndex )[(unsigned int)chanID.quarter()];
 
   // 2D
-  ++m_digitsPerMatModule[taeIndex]
-                        [GA::HistoInputType<float, 2>( (unsigned int)chanID.mat(), (unsigned int)chanID.module() )];
-  ++m_digitsPerQuarterLayer[taeIndex][GA::HistoInputType<float, 2>( (unsigned int)chanID.quarter(),
-                                                                    (unsigned int)chanID.layer() )];
+  ++m_digitsPerMatModule.at(
+      taeIndex )[GA::HistoInputType<float, 2>( (unsigned int)chanID.mat(), (unsigned int)chanID.module() )];
+  ++m_digitsPerQuarterLayer.at(
+      taeIndex )[GA::HistoInputType<float, 2>( (unsigned int)chanID.quarter(), (unsigned int)chanID.layer() )];
 
-  if ( mod ) { ++m_digitsPerPseudoChannel[taeIndex][pseudoChannelIndex]; }
+  if ( mod ) { ++m_digitsPerPseudoChannel.at( taeIndex )[pseudoChannelIndex]; }
 
   if ( m_nCalls.nEntries() == 0 ) { always() << "Filling Histograms... Please be patient!" << endmsg; }
   ++m_nCalls;
diff --git a/FT/FTMonitors/src/FTMonitoring.h b/FT/FTMonitors/src/FTMonitoring.h
index 62d5c368ef27648ebc176a35a84140cb41318e4b..ee45459ab17ce989841a98e4693898c177942040 100644
--- a/FT/FTMonitors/src/FTMonitoring.h
+++ b/FT/FTMonitors/src/FTMonitoring.h
@@ -15,82 +15,19 @@
 #include "Event/ODIN.h"
 #include "FTDAQ/FTInfo.h"
 
+namespace FTConstants = LHCb::Detector::FT;
+
 namespace FTMonitoring {
   static constexpr uint16_t maxPseudoSize = 16;
   static constexpr uint16_t maxAdcCharge  = 4;
+  static constexpr uint16_t nSiPMsTotal   = FTConstants::nSiPMsPerModule * FTConstants::nModulesTotal;
   constexpr uint16_t        nModulesPerQuarter( const uint16_t station ) { return station < 3 ? 5u : 6u; }
-  constexpr uint16_t        nMaxMoniModulePerStation( const uint16_t station ) {
-    return nModulesPerQuarter( station ) * LHCb::Detector::FT::nQuarters * LHCb::Detector::FT::nLayers;
+  constexpr uint16_t        nModulesPerStation( const uint16_t station ) {
+    return nModulesPerQuarter( station ) * FTConstants::nQuarters * FTConstants::nLayers;
   }
 } // namespace FTMonitoring
 
-template <typename T>
-class TAEHandler {
-private:
-  T*           m_owner;
-  unsigned int m_firstBunchId;
-  unsigned int m_spacing;
-  unsigned int m_nTAE;
-
-public:
-  TAEHandler( T* owner ) : m_owner( owner ) {}
-
-  void setManualTAE( unsigned int firstBunchId, unsigned int spacing, unsigned int nTAE ) {
-    m_firstBunchId = firstBunchId;
-    m_spacing      = spacing;
-    m_nTAE         = nTAE;
-  }
-
-  enum errors {
-    Skipped = 1,
-  };
-
-  int TAEIndexFromOdin( const LHCb::ODIN& odin ) const {
-    if ( !odin.isTAE() ) { return 0; }
-    for ( unsigned int i = 0; i < m_nTAE; ++i ) {
-      int testIDX = static_cast<int>( odin.bunchId() ) - static_cast<int>( m_firstBunchId + m_spacing * i );
-      if ( abs( testIDX ) <= odin.timeAlignmentEventIndex() ) { return 1 + testIDX + odin.timeAlignmentEventIndex(); }
-    }
-    return -errors::Skipped;
-  }
-};
-
-template <typename T>
-class MultiIndex {
-private:
-  std::vector<size_t> dimensions;
-  std::deque<T>       d;
-
-public:
-  auto begin() const { return d.begin(); }
-  auto begin() { return d.begin(); }
-  auto end() const { return d.end(); }
-  auto end() { return d.end(); }
-
-  T& operator[]( size_t index ) { return d[index]; }
-
-  T& operator[]( std::initializer_list<const size_t> indices ) {
-    if ( dimensions.size() != indices.size() ) { throw std::out_of_range( "dimensions are not set correctly" ); }
-    size_t idx = 0;
-    size_t dim = 0;
-    for ( const auto& localIndex : indices ) {
-      if ( localIndex >= dimensions[dim] ) {
-        throw std::out_of_range(
-            fmt::format( "index {} with value {} is out of bound {}", dim, localIndex, dimensions[dim] ) );
-      }
-      idx *= dimensions[dim++];
-      idx += localIndex;
-    }
-    return d[idx];
-  }
-
-  template <typename... _Args>
-  T& emplace_back( _Args&&... args ) {
-    return d.emplace_back( args... );
-  }
-
-  template <typename... Dims>
-  void set_dimensions( Dims... dim ) {
-    dimensions = {dim...};
-  }
-};
+template <typename OWNER, typename K, typename H, typename A>
+void buildHistogram( OWNER owner, std::map<K, H>& h, K k, std::string name, std::string labels, A axis ) {
+  h.emplace( std::piecewise_construct, std::forward_as_tuple( k ), std::forward_as_tuple( owner, name, labels, axis ) );
+}
diff --git a/FT/FTMonitors/src/FTNZSClusterMonitor.cpp b/FT/FTMonitors/src/FTNZSClusterMonitor.cpp
index 72c99614e27470737ce390d75fe1e848acd94f43..33c8279c341c1e76adc2b1fb3993f4108e9cc770 100644
--- a/FT/FTMonitors/src/FTNZSClusterMonitor.cpp
+++ b/FT/FTMonitors/src/FTNZSClusterMonitor.cpp
@@ -20,15 +20,16 @@
 #include <GaudiKernel/GaudiException.h>
 
 // from LHCb
+#include "ClusterMonitor.h"
 #include "Detector/FT/FTChannelID.h"
 #include "Detector/FT/FTConstants.h"
 #include "Event/FTLiteCluster.h"
 #include "FTDet/DeFTDetector.h"
 #include "Kernel/FastClusterContainer.h"
+#include "TAEHandler.h"
 
 #include "FTMonitoring.h"
 
-#include "boost/range/combine.hpp"
 #include <optional>
 
 /** @class FTNZSClusterMonitor FTNZSClusterMonitor.cpp
@@ -38,56 +39,11 @@
  *  @date   2020-04-09
  */
 
-using FTLiteClusters = LHCb::FTLiteCluster::FTLiteClusters;
-using FTLiteCluster  = LHCb::FTLiteCluster;
-namespace GA         = Gaudi::Accumulators;
-using ODIN           = LHCb::ODIN;
-
-template <typename OWNER>
-class FTNZSHist {
-private:
-  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>> m_histNZS;
-  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>> m_histDigits;
-
-public:
-  FTNZSHist( OWNER* owner, const std::string_view histName, const std::string_view histTitle,
-             const std::string_view xAxis, const std::string_view yAxis, const float xMin, const float xMax,
-             const unsigned int nBins ) {
-    std::string titleString = std::string( histTitle ) + "; " + std::string( xAxis ) + "; " + std::string( yAxis );
-    m_histNZS.emplace( owner, std::string( histName ), titleString, GA::Axis<float>{nBins, xMin, xMax} );
-    m_histDigits.emplace( owner, std::string( histName ) + "Digits", titleString, GA::Axis<float>{nBins, xMin, xMax} );
-  }
-
-  // Make class non-copyable but movable
-  FTNZSHist& operator=( const FTNZSHist& ) = delete;
-  FTNZSHist( const FTNZSHist& )            = delete;
-  FTNZSHist( FTNZSHist&& )                 = default;
-  FTNZSHist& operator=( FTNZSHist&& ) = default;
-
-  nlohmann::json toJSON() {
-    if ( !m_histNZS || !m_histDigits ) return {};
-    return {m_histNZS->toJSON(), m_histDigits->toJSON()};
-  }
-
-  // Functions to fill histograms
-  template <class T>
-  void fillNZS( T value ) const {
-    if constexpr ( std::is_enum_v<T> ) {
-      ++( *m_histNZS )[to_unsigned( value )];
-    } else {
-      ++( *m_histNZS )[value];
-    }
-  }
-
-  template <class T>
-  void fillDigit( T value ) const {
-    if constexpr ( std::is_enum_v<T> ) {
-      ++( *m_histDigits )[to_unsigned( value )];
-    } else {
-      ++( *m_histDigits )[value];
-    }
-  }
-};
+using FTLiteClusters  = LHCb::FTLiteCluster::FTLiteClusters;
+using FTLiteCluster   = LHCb::FTLiteCluster;
+using ODIN            = LHCb::ODIN;
+namespace GA          = Gaudi::Accumulators;
+namespace FTConstants = LHCb::Detector::FT;
 
 class FTNZSClusterMonitor
     : public Gaudi::Functional::Consumer<void( const FTLiteClusters&, const FTLiteClusters&, const DeFT&, const ODIN& ),
@@ -101,83 +57,36 @@ public:
                    const ODIN& odin ) const override;
 
 private:
-  mutable TAEHandler<FTNZSClusterMonitor> m_TAEHandler;
-  void                                    createHistograms();
-  bool                                    valid( const FTLiteCluster& cluster ) const;
-
-  // TAE global
-  mutable GA::Counter<>                                m_nCalls{this, "number of calls"};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_TAEtype{
-      this, "tae_type", "TAE type; TAE type; Events", {26, -4.5f, 21.5f}};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_TAEidx{
-      this, "tae_index", "TAE index; TAE index; Events", {22, -0.5f, 21.5f}};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_clustersPerTAENZS{
-      this, "nClustersPerTAENZS", "Number of clusters per TAE; TAE type; Clusters", GA::Axis<float>{22, -0.5f, 21.5f}};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_clustersPerTAEDigits{
-      this, "nClustersPerTAEDigits", "Number of clusters per TAE; TAE type; Offline clusters",
-      GA::Axis<float>{22, -0.5f, 21.5f}};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_eventsPerBunchCrossing{
-      this, "bunch_crossing", "bunch crossing ID; BX ID; Events", {4096, -0.5f, 4095 + 0.5f}};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_clustersPerBunchCrossingNZS{
-      this, "ClustersPerBunchCrossing", "bunch crossing ID; BX ID; Clusters", {4096, -0.5f, 4095 + 0.5f}};
-  mutable GA::Histogram<1, GA::atomicity::full, float> m_clustersPerBunchCrossingNZSDigits{
-      this, "ClustersPerBunchCrossingDigits", "bunch crossing ID; BX ID; Offline clusters", {4096, -0.5f, 4095 + 0.5f}};
-
-  mutable std::optional<FTNZSHist<FTNZSClusterMonitor>> m_belowThreshold;
-
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>>               m_nc_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>>               m_lcps_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>>               m_lcpm_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>>               m_lcpsipm_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>>               m_lcpc_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>>               m_lcf_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>>               m_lcs_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>>               m_lcisipm_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>>               m_lciq_NZS;
-  mutable MultiIndex<GA::Histogram<2, GA::atomicity::full, float>> m_lcsf_NZS;
-  mutable MultiIndex<GA::Histogram<2, GA::atomicity::full, float>> m_lcsf_NZS_digits;
-  mutable MultiIndex<GA::Histogram<2, GA::atomicity::full, float>> m_lcqsipm_NZS;
-  mutable MultiIndex<GA::Histogram<2, GA::atomicity::full, float>> m_lcqsipm_NZS_digits;
-
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_PseudoChannel;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_PseudoChannelPerLayer;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_PseudoChannelPerQuarter;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_PseudoChannelPerStationAndLayer;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_PseudoChannelPerStationAndLayerAndQuarter;
-
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_PseudoChannel64;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_PseudoChannel64PerLayer;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_PseudoChannel64PerQuarter;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_PseudoChannel64PerStationAndLayer;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_PseudoChannel64PerStationAndLayerAndQuarter;
-
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_lcichpm_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_lcipchpq_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_sipmpq_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_fracpq_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_pseusizepq_NZS;
-  mutable MultiIndex<FTNZSHist<FTNZSClusterMonitor>> m_lcpst_NZS;
-
-  // Properties for drawing histograms per X
-  Gaudi::Property<bool> m_drawHistsPerStation{this, "DrawHistsPerStation", true,
-                                              "Boolean for drawing histrograms per station"};
-  Gaudi::Property<bool> m_drawHistsPerQuarter{this, "DrawHistsPerQuarter", true,
-                                              "Boolean for drawing histrograms per quarter"};
-  Gaudi::Property<bool> m_drawHistsPerModule{this, "DrawHistsPerModule", true,
-                                             "Boolean for drawing histrograms per module"};
-  Gaudi::Property<bool> m_drawHistsPerSiPM{this, "DrawHistsPerSiPM", true, "Boolean for drawing histrograms per SiPM"};
-
-  mutable GA::Counter<> m_nInvalidClusters{this, "invalid clusters"};
-  mutable GA::Counter<> m_nInvalidDigitClusters{this, "invalid digit clusters"};
-
-  Gaudi::Property<unsigned int> m_manualTAEBunchIdFirst{this, "manualTAEBunchIdFirst", 0,
-                                                        "center of first event in a TAE group"};
-  Gaudi::Property<unsigned int> m_manualTAESpacing{this, "manualTAESpacing", 0, "spacing between TAE groups"};
-  Gaudi::Property<unsigned int> m_manualTAENTAE{this, "manualTAENTAE", 0, "number of TAE groups"};
+  enum ClusterType {
+    FPGA,
+    Offline,
+  };
+  mutable TAEHandler<FTNZSClusterMonitor>     m_TAEHandler;
+  mutable ClusterMonitor<FTNZSClusterMonitor> m_clusterMonitorFPGA;
+  mutable ClusterMonitor<FTNZSClusterMonitor> m_clusterMonitorOffline;
+  void                                        createHistograms();
+  bool                                        valid( const FTLiteCluster& cluster ) const;
+
+  mutable GA::Counter<> m_nCalls{this, "number of calls"};
+
+  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>>                     m_eventsPerBunchCrossing;
+  mutable std::map<std::tuple<ClusterType>, GA::Histogram<1, GA::atomicity::full, float>> m_belowThreshold;
+
+  Gaudi::Property<bool> m_drawHistsPerStation{this, "DrawHistsPerStation", true, "Enable histrograms per station"};
+  Gaudi::Property<bool> m_drawHistsPerQuarter{this, "DrawHistsPerQuarter", true, "Enable histrograms per quarter"};
+  Gaudi::Property<bool> m_drawHistsPerModule{this, "DrawHistsPerModule", true, "Enable histrograms per module"};
+  Gaudi::Property<bool> m_drawCorrelationPlots{this, "DrawCorrelationPlots", true, "Enable correlation plots"};
+
+  Gaudi::Property<double>       m_normalization{this, "Normalization", 1.,
+                                          "Normalization factor to use in weighted histograms"};
+  Gaudi::Property<std::string>  m_extraInfo{this, "ExtraInfo", "", "Extra information to add to the plot"};
+  Gaudi::Property<unsigned int> m_timingStepsTotal{this, "TimingStepsTotal", 0, "Total number of timing scan steps"};
+  Gaudi::Property<std::vector<unsigned int>> m_SiPMsToSkip{this, "SiPMsToSkip", {}, "a list of SiPMs to skip"};
   Gaudi::Property<unsigned int> m_clustersPerBxMin{this, "ClustersPerBxMin", 10, "Low threshold for cluster per BX"};
   Gaudi::Property<unsigned int> m_TAEHalfWindow{this, "TAEHalfWindow", 2, "TAE half window"};
-  Gaudi::Property<bool>         m_enableTAE{this, "enableTAE", false, "enable TAE mode"};
-  Gaudi::Property<bool>         m_enableTest{this, "enableTest", false, "enable test mode"};
+  Gaudi::Property<std::vector<unsigned int>> m_TAEBunchIds{
+      this, "TAEBunchIds", {}, "Center bunch ids of all TAE groups"};
+  Gaudi::Property<bool> m_enableTAE{this, "enableTAE", false, "enable TAE mode"};
 };
 
 // Declaration of the Algorithm Factory
@@ -189,476 +98,71 @@ FTNZSClusterMonitor::FTNZSClusterMonitor( const std::string& name, ISvcLocator*
                  KeyValue{"ClusterLocationfromNZSdigits", LHCb::FTLiteClusterLocation::Default + "fromNZSdigits"},
                  KeyValue{"FTDetectorLocation", DeFTDetectorLocation::Default},
                  KeyValue{"InputODIN", LHCb::ODINLocation::Default}} )
-    , m_TAEHandler( this ) {}
-
-void FTNZSClusterMonitor::createHistograms() {
-  m_belowThreshold.emplace( this, "BelowThreshold", "Number of events below threshold", "Clusters", "Events", -0.5,
-                            10.5, 11 );
-
-  unsigned int TAESize = 2 * m_TAEHalfWindow + 1;
-
-  m_nc_NZS.set_dimensions( TAESize + 1 );
-  m_lcps_NZS.set_dimensions( TAESize + 1 );
-  m_lcpm_NZS.set_dimensions( TAESize + 1 );
-  m_lcpsipm_NZS.set_dimensions( TAESize + 1 );
-  m_lcpc_NZS.set_dimensions( TAESize + 1 );
-  m_lcf_NZS.set_dimensions( TAESize + 1 );
-  m_lcs_NZS.set_dimensions( TAESize + 1 );
-  m_lcisipm_NZS.set_dimensions( TAESize + 1 );
-  m_lciq_NZS.set_dimensions( TAESize + 1 );
-  m_lcsf_NZS.set_dimensions( TAESize + 1 );
-  m_lcsf_NZS_digits.set_dimensions( TAESize + 1 );
-  m_lcqsipm_NZS.set_dimensions( TAESize + 1 );
-  m_lcqsipm_NZS_digits.set_dimensions( TAESize + 1 );
-
-  m_PseudoChannel.set_dimensions( TAESize + 1 );
-  m_PseudoChannelPerLayer.set_dimensions( TAESize + 1, LHCb::Detector::FT::nLayersTotal );
-  m_PseudoChannelPerQuarter.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_PseudoChannelPerStationAndLayer.set_dimensions( TAESize + 1, LHCb::Detector::FT::nStations,
-                                                    LHCb::Detector::FT::nLayers );
-  m_PseudoChannelPerStationAndLayerAndQuarter.set_dimensions(
-      TAESize + 1, LHCb::Detector::FT::nStations, LHCb::Detector::FT::nLayers, LHCb::Detector::FT::nQuarters );
-  m_PseudoChannel64.set_dimensions( TAESize + 1 );
-  m_PseudoChannel64PerLayer.set_dimensions( TAESize + 1, LHCb::Detector::FT::nLayersTotal );
-  m_PseudoChannel64PerQuarter.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_PseudoChannel64PerStationAndLayer.set_dimensions( TAESize + 1, LHCb::Detector::FT::nStations,
-                                                      LHCb::Detector::FT::nLayers );
-  m_PseudoChannel64PerStationAndLayerAndQuarter.set_dimensions(
-      TAESize + 1, LHCb::Detector::FT::nStations, LHCb::Detector::FT::nLayers, LHCb::Detector::FT::nQuarters );
-
-  m_lcichpm_NZS.set_dimensions( TAESize + 1, LHCb::Detector::FT::nModulesTotal );
-  m_lcipchpq_NZS.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_sipmpq_NZS.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_fracpq_NZS.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_pseusizepq_NZS.set_dimensions( TAESize + 1, LHCb::Detector::FT::nQuartersTotal );
-  m_lcpst_NZS.set_dimensions( TAESize + 1, LHCb::Detector::FT::nStations );
-
-  for ( size_t i = 0; i < ( TAESize ) + 1; ++i ) {
-    if ( !m_enableTAE && i > 0 ) { return; }
-
-    auto number = []( unsigned int num ) { return num == 0 ? "" : std::to_string( num ); };
-
-    std::string prefix = "nonTAE/";
-    if ( i > 0 ) {
-      const size_t tae_index = i - 1;
-      std::string  name      = "MainEvent";
-      if ( tae_index < ( TAESize ) / 2 ) { name = "Prev"; }
-      if ( tae_index > ( TAESize ) / 2 ) { name = "Next"; }
-      auto index = number( abs( static_cast<int>( tae_index ) - static_cast<int>( TAESize ) / 2 ) );
-      prefix     = fmt::format( "TAE/{:02d}_{}{}/", tae_index, name, index );
-    }
-
-    // Overview histograms
-    m_nc_NZS.emplace_back( this, prefix + "NZSnClusters", "Number of NZS clusters", "Clusters / event", "Events", 0.,
-                           1000, 100 );
-    m_lciq_NZS.emplace_back( this, prefix + "NZSLiteClustersPerQuarter", "Number of NZS clusters", "Quarter",
-                             "Clusters", -0.5, LHCb::Detector::FT::nQuartersTotal, LHCb::Detector::FT::nQuartersTotal );
-    m_lcpm_NZS.emplace_back( this, prefix + "NZSLiteClustersPerModule", "NZS clusters per module", "Module", "Clusters",
-                             -0.5, LHCb::Detector::FT::nModulesMax - 0.5f, LHCb::Detector::FT::nModulesMax );
-    m_lcps_NZS.emplace_back( this, prefix + "NZSLiteClustersPerStation", "NZS clusters per station", "Station",
-                             "Clusters", 0.5, 3.5, 3 );
-    m_lcpsipm_NZS.emplace_back( this, prefix + "NZSLiteClustersPerSiPM", "NZS clusters per SiPM", "SiPMID", "Clusters",
-                                -0.5, LHCb::Detector::FT::nSiPMsPerModule, LHCb::Detector::FT::nSiPMsPerModule );
-    m_lcpc_NZS.emplace_back( this, prefix + "NZSLiteClustersPerChannel", "NZS clusters per channel", "Channel",
-                             "Clusters", -0.5, LHCb::Detector::FT::nChannels - 0.5f, LHCb::Detector::FT::nChannels );
-    m_lcf_NZS.emplace_back( this, prefix + "NZSLiteClusterFraction", "", "NZS cluster fraction", "Fraction", -0.25,
-                            0.75, 2 );
-    m_lcs_NZS.emplace_back( this, prefix + "NZSLiteClusterSize", "", "NZS cluster size", "Size", -0.5,
-                            FTMonitoring::maxPseudoSize - 0.5f, FTMonitoring::maxPseudoSize );
-    m_lcisipm_NZS.emplace_back( this, prefix + "NZSLiteClustersInSiPM", "NZS clusters per SiPM", "Number of clusters",
-                                "Number of SiPMs", -0.5, 20.5, 21 );
-
-    m_lcsf_NZS.emplace_back(
-        this, prefix + "NZSLiteClusterSizeVsFraction", "NZS Cluster size vs fraction; Size; Fraction",
-        std::tuple{GA::Axis<float>{FTMonitoring::maxPseudoSize, -0.5, FTMonitoring::maxPseudoSize - 0.5f, "Size"},
-                   GA::Axis<float>{100, -0.25, 0.75, "Fraction"}} );
-    m_lcsf_NZS_digits.emplace_back(
-        this, prefix + "NZSDigitLiteClusterSizeVsFraction", "NZS digit Cluster size vs fraction; Size; Fraction",
-        std::tuple{GA::Axis<float>{FTMonitoring::maxPseudoSize, -0.5, FTMonitoring::maxPseudoSize - 0.5f, "Size"},
-                   GA::Axis<float>{100, -0.25, 0.75, "Fraction"}} );
-
-    m_lcqsipm_NZS.emplace_back(
-        this, prefix + "NZSQuarterVsSiPMNumber", "NZS Quarter ID vs SiPMNumber; Quarter ID; SiPM number",
-        std::tuple{GA::Axis<float>{LHCb::Detector::FT::nQuartersTotal, -0.5, LHCb::Detector::FT::nQuartersTotal - 0.5f,
-                                   "Quarter ID"},
-                   GA::Axis<float>{LHCb::Detector::FT::nMaxSiPMsPerQuarter, -0.5,
-                                   LHCb::Detector::FT::nMaxSiPMsPerQuarter - 0.5f, "SiPM number"}} );
-    m_lcqsipm_NZS_digits.emplace_back(
-        this, prefix + "NZSDigitQuarterVsSiPMNumber", "NZS digit Quarter vs SiPMNumber; Quarter ID; SiPM number",
-        std::tuple{GA::Axis<float>{LHCb::Detector::FT::nQuartersTotal, -0.5, LHCb::Detector::FT::nQuartersTotal - 0.5f,
-                                   "Quarter ID"},
-                   GA::Axis<float>{LHCb::Detector::FT::nMaxSiPMsPerQuarter, -0.5,
-                                   LHCb::Detector::FT::nMaxSiPMsPerQuarter - 0.5f, "SiPM number"}} );
-
-    m_PseudoChannel.emplace_back( this, prefix + "NZSLiteClustersPerPseudoChannel", "NZS clusters per pseudo channel",
-                                  "Pseudo channel", "Clusters", -0.5, LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f,
-                                  LHCb::Detector::FT::nMaxChannelsPerQuarter );
-    for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayersTotal; ++layer ) {
-      m_PseudoChannelPerLayer.emplace_back(
-          this, prefix + "perLayer/" + "NZSLiteClustersPerPseudoChannelLayer" + std::to_string( layer ),
-          "NZS clusters per pseudo channel in layer " + std::to_string( layer ), "Pseudo channel", "Clusters", -0.5,
-          LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f, LHCb::Detector::FT::nMaxChannelsPerQuarter );
-    }
-
-    for ( size_t quarter = 0; quarter < LHCb::Detector::FT::nQuartersTotal; ++quarter ) {
-      m_PseudoChannelPerQuarter.emplace_back(
-          this, prefix + "perQuarter/" + "NZSLiteClustersPerPseudoChannelQuarter" + fmt::format( "{:02d}", quarter ),
-          "NZS clusters per pseudo channel in quarter " + std::to_string( quarter ), "Pseudo channel", "Clusters", -0.5,
-          LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f, LHCb::Detector::FT::nMaxChannelsPerQuarter );
-    }
-
-    for ( size_t station = 1; station < LHCb::Detector::FT::nStations + 1; ++station ) {
-      for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayers; ++layer ) {
-        m_PseudoChannelPerStationAndLayer.emplace_back(
-            this,
-            prefix + "perStationAndLayer/" + "NZSLiteClustersPerPseudoChannelStation" + std::to_string( station ) +
-                "Layer" + std::to_string( layer ),
-            "NZS clusters per pseudo channel in station " + std::to_string( station ) + " in layer " +
-                std::to_string( layer ),
-            "Pseudo channel", "Clusters", -0.5, LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f,
-            LHCb::Detector::FT::nMaxChannelsPerQuarter );
-      }
-    }
-
-    for ( size_t station = 1; station < LHCb::Detector::FT::nStations + 1; ++station ) {
-      for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayers; ++layer ) {
-        for ( size_t quarter = 0; quarter < LHCb::Detector::FT::nQuarters; ++quarter ) {
-          m_PseudoChannelPerStationAndLayerAndQuarter.emplace_back(
-              this,
-              prefix + "perStationAndLayerAndQuarter/" + "NZSLiteClustersPerPseudoChannelStation" +
-                  std::to_string( station ) + "Layer" + std::to_string( layer ) + "Quarter" + std::to_string( quarter ),
-              "NZS clusters per pseudo channel in station " + std::to_string( station ) + " in layer " +
-                  std::to_string( layer ) + " in quarter " + std::to_string( quarter ),
-              "Pseudo channel", "Clusters", -0.5, LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f,
-              LHCb::Detector::FT::nMaxChannelsPerQuarter );
-        }
-      }
-    }
-
-    m_PseudoChannel64.emplace_back( this, prefix + "coarse/NZSLiteClustersPerPseudoChannel",
-                                    "NZS clusters per pseudo channel", "Pseudo channel", "Clusters / (64 channels)",
-                                    -0.5, LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f,
-                                    LHCb::Detector::FT::nMaxChannelsPerQuarter / 64 );
-    for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayersTotal; ++layer ) {
-      m_PseudoChannel64PerLayer.emplace_back(
-          this, prefix + "perLayer/" + "coarse/NZSLiteClustersPerPseudoChannelLayer" + std::to_string( layer ),
-          "NZS clusters per pseudo channel in layer " + std::to_string( layer ), "Pseudo channel",
-          "Clusters / (64 channels)", -0.5, LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f,
-          LHCb::Detector::FT::nMaxChannelsPerQuarter / 64 );
-    }
-
-    for ( size_t quarter = 0; quarter < LHCb::Detector::FT::nQuartersTotal; ++quarter ) {
-      m_PseudoChannel64PerQuarter.emplace_back(
-          this,
-          prefix + "perQuarter/" + "coarse/NZSLiteClustersPerPseudoChannelQuarter" + fmt::format( "{:02d}", quarter ),
-          "NZS clusters per pseudo channel in quarter " + std::to_string( quarter ), "Pseudo channel",
-          "Clusters / (64 channels)", -0.5, LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f,
-          LHCb::Detector::FT::nMaxChannelsPerQuarter / 64 );
-    }
-
-    for ( size_t station = 1; station < LHCb::Detector::FT::nStations + 1; ++station ) {
-      for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayers; ++layer ) {
-        m_PseudoChannel64PerStationAndLayer.emplace_back(
-            this,
-            prefix + "perStationAndLayer/" + "coarse/NZSLiteClustersPerPseudoChannelStation" +
-                std::to_string( station ) + "Layer" + std::to_string( layer ),
-            "NZS clusters per pseudo channel in station " + std::to_string( station ) + " in layer " +
-                std::to_string( layer ),
-            "Pseudo channel", "Clusters / (64 channels)", -0.5, LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f,
-            LHCb::Detector::FT::nMaxChannelsPerQuarter / 64 );
-      }
-    }
-
-    for ( size_t station = 1; station < LHCb::Detector::FT::nStations + 1; ++station ) {
-      for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayers; ++layer ) {
-        for ( size_t quarter = 0; quarter < LHCb::Detector::FT::nQuarters; ++quarter ) {
-          m_PseudoChannel64PerStationAndLayerAndQuarter.emplace_back(
-              this,
-              prefix + "perStationAndLayerAndQuarter/" + "coarse/NZSLiteClustersPerPseudoChannelStation" +
-                  std::to_string( station ) + "Layer" + std::to_string( layer ) + "Quarter" + std::to_string( quarter ),
-              "NZS clusters per pseudo channel in station " + std::to_string( station ) + " in layer " +
-                  std::to_string( layer ) + " in quarter " + std::to_string( quarter ),
-              "Pseudo channel", "Clusters / (64 channels)", -0.5, LHCb::Detector::FT::nMaxChannelsPerQuarter - 0.5f,
-              LHCb::Detector::FT::nMaxChannelsPerQuarter / 64 );
-        }
-      }
-    }
-
-    // Histograms per station/quarter/module
-    size_t prev_stationID( 999 );
-    size_t prev_quarter( 999 );
-    for ( size_t station = 1; station < 1 + LHCb::Detector::FT::nStations; station++ ) {
-      for ( size_t layer = 0; layer < LHCb::Detector::FT::nLayers; layer++ ) {
-        for ( size_t quarter = 0; quarter < LHCb::Detector::FT::nQuarters; quarter++ ) {
-          for ( size_t module = 0; module < FTMonitoring::nModulesPerQuarter( station ); module++ ) {
-
-            // Define the histograms per quarter if asked for
-            if ( m_drawHistsPerQuarter && ( quarter != prev_quarter ) ) {
-              std::string locationString =
-                  std::to_string( station ) + "L" + std::to_string( layer ) + "Q" + std::to_string( quarter );
-              // Now create all hists
-              m_fracpq_NZS.emplace_back( this, prefix + "perQuarter/" + "NZSFractionInQuarter_S" + locationString,
-                                         "NZS Fraction in quarter_S" + locationString, "Fraction", "Number of clusters",
-                                         -0.25, 0.75, 2 );
-              m_pseusizepq_NZS.emplace_back( this, prefix + "perQuarter/" + "NZSPseudosizeInQuarter_S" + locationString,
-                                             "NZS Pseudosize in quarter_S" + locationString, "Pseudosize",
-                                             "Number of clusters", -0.5, FTMonitoring::maxPseudoSize - 0.5f,
-                                             FTMonitoring::maxPseudoSize );
-              m_sipmpq_NZS.emplace_back(
-                  this, prefix + "perQuarter/" + "NZSClustersPerSiPMInQuarter_S" + locationString,
-                  "NZS Clusters per SiPM in quarter_S" + locationString, "SiPM number", "Number of clusters", -0.5,
-                  LHCb::Detector::FT::nMaxSiPMsPerQuarter - 0.5f, LHCb::Detector::FT::nMaxSiPMsPerQuarter );
-              m_lcipchpq_NZS.emplace_back(
-                  this, prefix + "perQuarter/" + "NZSClustersPerPseudochannelInQuarter_S" + locationString,
-                  "NZS Clusters per Pseudochannel in quarter_S" + locationString, "Pseudochannel",
-                  "Number of clusters / 8 pseudochannels", -0.5, LHCb::Detector::FT::nMaxChannelsPerQuarter,
-                  LHCb::Detector::FT::nMaxChannelsPerQuarter / 8 );
-            }
-            prev_quarter = quarter;
-
-            // Histograms per module
-            if ( m_drawHistsPerModule ) {
-              std::string locationString = std::to_string( station ) + "L" + std::to_string( layer ) + "Q" +
-                                           std::to_string( quarter ) + "M" + std::to_string( module );
-              m_lcichpm_NZS.emplace_back(
-                  this, prefix + "perModule/" + "NZSLiteClustersPerChannelinModuleM_S" + locationString,
-                  "NZS Clusters Per Channel in Module_S" + locationString, "Channel number", "Number of clusters", -0.5,
-                  LHCb::Detector::FT::nChannelsPerModule - 0.5f, LHCb::Detector::FT::nChannelsPerModule );
-            }
-
-            // Histograms per station
-            if ( m_drawHistsPerStation && ( station != prev_stationID ) ) {
-              m_lcpst_NZS.emplace_back(
-                  this, prefix + "perStation/" + "NZSLiteClustersInStation_S" + std::to_string( station ),
-                  "NZS Clusters In Station " + std::to_string( station ), "Module ID", "Number of clusters", -0.5,
-                  LHCb::Detector::FT::nMaxSiPMsPerQuarter - 0.5f, LHCb::Detector::FT::nMaxSiPMsPerQuarter );
-            }
-            prev_stationID = station;
-          } // module loop
-        }   // quarter loop
-      }     // layer loop
-    }       // station loop
-  }
-}
+    , m_TAEHandler( this )
+    , m_clusterMonitorFPGA( this )
+    , m_clusterMonitorOffline( this ) {}
 
 StatusCode FTNZSClusterMonitor::initialize() {
   return Consumer::initialize().andThen( [&] {
-    m_TAEHandler.setManualTAE( m_manualTAEBunchIdFirst, m_manualTAESpacing, m_manualTAENTAE );
+    m_TAEHandler.setManualTAE( m_enableTAE, m_TAEBunchIds, m_TAEHalfWindow, m_extraInfo );
+    m_clusterMonitorFPGA.createHistograms( "FPGA/", m_TAEHalfWindow, m_drawHistsPerStation, m_drawHistsPerQuarter,
+                                           m_drawHistsPerModule, m_drawCorrelationPlots, m_normalization,
+                                           m_timingStepsTotal, m_extraInfo );
+    m_clusterMonitorOffline.createHistograms( "Offline/", m_TAEHalfWindow, m_drawHistsPerStation, m_drawHistsPerQuarter,
+                                              m_drawHistsPerModule, m_drawCorrelationPlots, m_normalization,
+                                              m_timingStepsTotal, m_extraInfo );
     createHistograms();
     return StatusCode::SUCCESS;
   } );
 }
 
-bool FTNZSClusterMonitor::valid( const FTLiteCluster& cluster ) const {
-  LHCb::Detector::FTChannelID chanID  = cluster.channelID();
-  size_t                      q_ID    = chanID.globalQuarterIdx();
-  uint                        SiPM_ID = chanID.localSiPMIdx_quarter();
-
-  if ( q_ID > LHCb::Detector::FT::nQuartersTotal ) {
-    debug() << "Found invalid quarter ID of value " << q_ID << ", SiPM ID: " << SiPM_ID << endmsg;
-    return false;
+void FTNZSClusterMonitor::createHistograms() {
+  m_eventsPerBunchCrossing.emplace( this, "EventsPerBunchCrossing",
+                                    fmt::format( "bunch crossing ID{};BX ID;Events", m_extraInfo ),
+                                    GA::Axis<float>{4096, -0.5f, 4095 + 0.5f} );
+
+  if ( m_clustersPerBxMin > 0 ) {
+    for ( auto clusterType : {ClusterType::FPGA, ClusterType::Offline} ) {
+      std::string clusterTypeStr = ClusterType::FPGA == clusterType ? "FPGA" : "Offline";
+      buildHistogram(
+          this, m_belowThreshold, {clusterType}, clusterTypeStr + "/BelowThreshold",
+          fmt::format( "Number of events below threshold{};{} clusters;Events", m_extraInfo, clusterTypeStr ),
+          GA::Axis<float>{m_clustersPerBxMin, -0.5f, m_clustersPerBxMin - 0.5f} );
+    }
   }
-  return true;
 }
 
 void FTNZSClusterMonitor::operator()( const FTLiteClusters& clustersNZS, const FTLiteClusters& clustersNZSdigits,
                                       const DeFT& deFT, const ODIN& odin ) const {
-
   if ( deFT.version() < 61 ) {
     throw GaudiException( "This version requires FTDet v6.1 or higher", "", StatusCode::FAILURE );
   };
 
-  if ( clustersNZS.size() < m_clustersPerBxMin ) { m_belowThreshold->fillNZS( clustersNZS.size() ); }
+  std::vector<std::tuple<ClusterType, const FTLiteClusters&, ClusterMonitor<FTNZSClusterMonitor>&>> clusterConfigs{
+      {ClusterType::FPGA, clustersNZS, m_clusterMonitorFPGA},
+      {ClusterType::Offline, clustersNZSdigits, m_clusterMonitorOffline},
+  };
 
-  if ( clustersNZSdigits.size() < m_clustersPerBxMin ) { m_belowThreshold->fillDigit( clustersNZSdigits.size() ); }
+  for ( auto [clusterType, clusters, clusterMonitor] : clusterConfigs ) {
+    if ( clusters.size() < m_clustersPerBxMin ) { ++m_belowThreshold.at( clusterType )[clusters.size()]; }
+  }
 
-  if ( ( clustersNZSdigits.size() < m_clustersPerBxMin ) && ( clustersNZS.size() < m_clustersPerBxMin ) ) { return; }
+  if ( ( clustersNZSdigits.size() < m_clustersPerBxMin ) &&
+       ( clustersNZS.size() < m_clustersPerBxMin ) ) { // apply min cluster threshold
+    return;
+  }
 
-  ++m_eventsPerBunchCrossing[odin.bunchId()];
-  m_clustersPerBunchCrossingNZS[odin.bunchId()] += clustersNZS.size();
-  m_clustersPerBunchCrossingNZSDigits[odin.bunchId()] += clustersNZSdigits.size();
+  ++( *m_eventsPerBunchCrossing )[odin.bunchId()];
 
-  int          taeType  = 0;
   unsigned int taeIndex = 0;
   if ( odin.isTAE() ) {
-    if ( !m_enableTAE ) { return; }
-    if ( odin.timeAlignmentEventIndex() != m_TAEHalfWindow ) {
-      warning() << "TAE half window of event is " << odin.timeAlignmentEventIndex()
-                << " while monitoring is set up for half window of " << m_TAEHalfWindow << ". Skipping this event."
-                << endmsg;
-      return;
-    }
-    taeType = m_TAEHandler.TAEIndexFromOdin( odin );
-    ++m_TAEtype[taeType];
+    auto taeType = m_TAEHandler.TAEIndexFromOdin( odin );
     if ( taeType < 0 ) { return; }
     taeIndex = taeType;
-    ++m_TAEidx[taeIndex - 1];
-  } else {
-    ++m_TAEtype[taeType];
   }
-  m_clustersPerTAENZS[taeIndex] += clustersNZS.size();
-  m_clustersPerTAEDigits[taeIndex] += clustersNZSdigits.size();
-
-  if ( msgLevel( MSG::DEBUG ) ) debug() << "Filling the histograms" << endmsg;
-  m_nc_NZS[taeIndex].fillNZS( clustersNZS.size() );
-  m_nc_NZS[taeIndex].fillDigit( clustersNZSdigits.size() );
-  std::optional<uint> prevSiPM, prevModuleID;
-  int                 clustersInSiPM = 0;
-
-  // Loop over NZS FTLiteCluster
-  for ( const auto& cluster : clustersNZS.range() ) {
-    if ( !valid( cluster ) ) {
-      ++m_nInvalidClusters;
-      continue;
-    }
-
-    LHCb::Detector::FTChannelID chanID             = cluster.channelID();
-    unsigned int                q_ID               = chanID.globalQuarterIdx();
-    unsigned int                SiPM_ID            = chanID.localSiPMIdx_quarter();
-    unsigned int                stationIndex       = to_unsigned( chanID.station() ) - 1;
-    unsigned int                layerIndex         = to_unsigned( chanID.layer() );
-    unsigned int                layerGlobalIndex   = layerIndex + stationIndex * LHCb::Detector::FT::nLayers;
-    const auto                  mod                = deFT.findModule( chanID );
-    unsigned int                pseudoChannelIndex = 0;
-
-    if ( mod ) { pseudoChannelIndex = mod->pseudoChannel( chanID ); }
-
-    // Fill cluster channel properties
-    m_lcps_NZS[taeIndex].fillNZS( chanID.station() );
-    m_lcpm_NZS[taeIndex].fillNZS( chanID.module() );
-    m_lcpsipm_NZS[taeIndex].fillNZS( chanID.sipmInModule() );
-    m_lcpc_NZS[taeIndex].fillNZS( chanID.channel() );
-    if ( mod ) {
-      m_PseudoChannel[taeIndex].fillNZS( pseudoChannelIndex );
-      m_PseudoChannelPerQuarter[{taeIndex, q_ID}].fillNZS( pseudoChannelIndex );
-      m_PseudoChannelPerLayer[{taeIndex, layerGlobalIndex}].fillNZS( pseudoChannelIndex );
-      m_PseudoChannelPerStationAndLayer[{taeIndex, stationIndex, layerIndex}].fillNZS( pseudoChannelIndex );
-      m_PseudoChannelPerStationAndLayerAndQuarter[{taeIndex, stationIndex, layerIndex, to_unsigned( chanID.quarter() )}]
-          .fillNZS( pseudoChannelIndex );
-
-      m_PseudoChannel64[taeIndex].fillNZS( pseudoChannelIndex );
-      m_PseudoChannel64PerQuarter[{taeIndex, q_ID}].fillNZS( pseudoChannelIndex );
-      m_PseudoChannel64PerLayer[{taeIndex, layerGlobalIndex}].fillNZS( pseudoChannelIndex );
-      m_PseudoChannel64PerStationAndLayer[{taeIndex, stationIndex, layerIndex}].fillNZS( pseudoChannelIndex );
-      m_PseudoChannel64PerStationAndLayerAndQuarter[{taeIndex, stationIndex, layerIndex,
-                                                     to_unsigned( chanID.quarter() )}]
-          .fillNZS( pseudoChannelIndex );
-    }
-    m_lcf_NZS[taeIndex].fillNZS( cluster.fraction() );
-    m_lcs_NZS[taeIndex].fillNZS( cluster.pseudoSize() );
-
-    // 2D hists are not FTNZSHist objects, so "normal" fill
-    ++m_lcsf_NZS[taeIndex][GA::HistoInputType<float, 2>( cluster.pseudoSize(), cluster.fraction() )];
-    ++m_lcqsipm_NZS[taeIndex][GA::HistoInputType<float, 2>( q_ID, SiPM_ID )];
-    if ( m_drawHistsPerQuarter ) {
-      m_lciq_NZS[taeIndex].fillNZS( q_ID );
-      m_fracpq_NZS[{taeIndex, q_ID}].fillNZS( cluster.fraction() );
-      m_pseusizepq_NZS[{taeIndex, q_ID}].fillNZS( cluster.pseudoSize() );
-      m_sipmpq_NZS[{taeIndex, q_ID}].fillNZS( SiPM_ID );
-      m_lcipchpq_NZS[{taeIndex, q_ID}].fillNZS( pseudoChannelIndex );
-    }
-    if ( m_drawHistsPerStation ) {
-      m_lcpst_NZS[{taeIndex, to_unsigned( mod->stationID() ) - 1}].fillNZS( chanID.localModuleIdx_station() );
-    }
-    if ( m_drawHistsPerModule ) {
-      m_lcichpm_NZS[{taeIndex, chanID.localModuleIdx_station()}].fillNZS( chanID.localChannelIdx_module() );
-    }
-
-    // Count the number of clusters per SiPM
-    uint thisSiPM = chanID.globalSiPMID();
-    if ( prevSiPM && thisSiPM != *prevSiPM && clustersInSiPM != 0 ) {
-      m_lcisipm_NZS[taeIndex].fillNZS( clustersInSiPM );
-      clustersInSiPM = 0;
-    }
-    prevSiPM     = thisSiPM;
-    prevModuleID = chanID.globalModuleIdx();
-    ++clustersInSiPM;
-
-  } // Loop over NZS FTLiteClusters
-  if ( msgLevel( MSG::DEBUG ) ) debug() << "Done looping over NZS clusters!" << endmsg;
-  m_lcisipm_NZS[taeIndex].fillNZS( clustersInSiPM ); // fill this for the last time
-
-  // Now do the same for the NZS digits clusters
-  clustersInSiPM = 0;
-  for ( const auto& cluster : clustersNZSdigits.range() ) {
-    if ( !valid( cluster ) ) {
-      ++m_nInvalidDigitClusters;
-      continue;
-    }
-
-    LHCb::Detector::FTChannelID chanID             = cluster.channelID();
-    unsigned int                q_ID               = chanID.globalQuarterIdx();
-    unsigned int                SiPM_ID            = chanID.localSiPMIdx_quarter();
-    unsigned int                stationIndex       = to_unsigned( chanID.station() ) - 1;
-    unsigned int                layerIndex         = to_unsigned( chanID.layer() );
-    unsigned int                layerGlobalIndex   = layerIndex + stationIndex * LHCb::Detector::FT::nLayers;
-    const auto                  mod                = deFT.findModule( chanID );
-    unsigned int                pseudoChannelIndex = 0;
-
-    if ( mod ) { pseudoChannelIndex = mod->pseudoChannel( chanID ); }
-
-    // Draw cluster channel properties
-    m_lcps_NZS[taeIndex].fillDigit( chanID.station() );
-    m_lcpm_NZS[taeIndex].fillDigit( chanID.module() );
-    m_lcpsipm_NZS[taeIndex].fillDigit( chanID.sipmInModule() );
-    m_lcpc_NZS[taeIndex].fillDigit( chanID.channel() );
-    if ( mod ) {
-      m_PseudoChannel[taeIndex].fillDigit( pseudoChannelIndex );
-      m_PseudoChannelPerQuarter[{taeIndex, q_ID}].fillDigit( pseudoChannelIndex );
-      m_PseudoChannelPerLayer[{taeIndex, layerGlobalIndex}].fillDigit( pseudoChannelIndex );
-      m_PseudoChannelPerStationAndLayer[{taeIndex, stationIndex, layerIndex}].fillDigit( pseudoChannelIndex );
-      m_PseudoChannelPerStationAndLayerAndQuarter[{taeIndex, stationIndex, layerIndex, to_unsigned( chanID.quarter() )}]
-          .fillDigit( pseudoChannelIndex );
-
-      m_PseudoChannel64[taeIndex].fillDigit( pseudoChannelIndex );
-      m_PseudoChannel64PerQuarter[{taeIndex, q_ID}].fillDigit( pseudoChannelIndex );
-      m_PseudoChannel64PerLayer[{taeIndex, layerGlobalIndex}].fillDigit( pseudoChannelIndex );
-      m_PseudoChannel64PerStationAndLayer[{taeIndex, stationIndex, layerIndex}].fillDigit( pseudoChannelIndex );
-      m_PseudoChannel64PerStationAndLayerAndQuarter[{taeIndex, stationIndex, layerIndex,
-                                                     to_unsigned( chanID.quarter() )}]
-          .fillDigit( pseudoChannelIndex );
-    }
-    m_lcf_NZS[taeIndex].fillDigit( cluster.fraction() );
-    m_lcs_NZS[taeIndex].fillDigit( cluster.pseudoSize() );
-
-    // 2D hists are not FTNZSHist objects, so "normal" fill
-    ++m_lcsf_NZS_digits[taeIndex][GA::HistoInputType<float, 2>( cluster.pseudoSize(), cluster.fraction() )];
-    ++m_lcqsipm_NZS_digits[taeIndex][GA::HistoInputType<float, 2>( q_ID, SiPM_ID )];
-
-    // Check if properties were set
-    if ( m_drawHistsPerQuarter ) {
-      m_lciq_NZS[taeIndex].fillDigit( q_ID );
-      m_fracpq_NZS[{taeIndex, q_ID}].fillDigit( cluster.fraction() );
-      m_pseusizepq_NZS[{taeIndex, q_ID}].fillDigit( cluster.pseudoSize() );
-      m_sipmpq_NZS[{taeIndex, q_ID}].fillDigit( SiPM_ID );
-      m_lcipchpq_NZS[{taeIndex, q_ID}].fillDigit( pseudoChannelIndex );
-    }
-    if ( m_drawHistsPerStation ) {
-      m_lcpst_NZS[{taeIndex, to_unsigned( mod->stationID() ) - 1}].fillNZS( chanID.localModuleIdx_station() );
-    }
-    if ( m_drawHistsPerModule ) {
-      m_lcichpm_NZS[{taeIndex, chanID.localModuleIdx_station()}].fillNZS( chanID.localChannelIdx_module() );
-    }
-
-    // Count the number of clusters per SiPM
-    uint thisSiPM = chanID.globalSiPMID();
-    if ( prevSiPM && thisSiPM != *prevSiPM && clustersInSiPM != 0 ) {
-      m_lcisipm_NZS[taeIndex].fillDigit( clustersInSiPM );
-      clustersInSiPM = 0;
-    }
-    prevSiPM     = thisSiPM;
-    prevModuleID = chanID.globalModuleIdx();
-    ++clustersInSiPM;
-  } // Loop over NZS digits FTLiteClusters
-  if ( msgLevel( MSG::DEBUG ) ) debug() << "Done looping over NZS from digits clusters!" << endmsg;
-  m_lcisipm_NZS[taeIndex].fillDigit( clustersInSiPM ); // Fill this for the last time
 
-  if ( m_enableTest ) {
-    info() << "Print some histograms to compare against test references:" << endmsg;
-    info() << m_TAEidx.toJSON() << endmsg;
-    info() << m_TAEtype.toJSON() << endmsg;
-    info() << m_clustersPerBunchCrossingNZS.toJSON() << endmsg;
-    for ( auto& pc : m_PseudoChannel64 ) info() << pc.toJSON() << endmsg;
+  for ( auto [clusterType, clusters, clusterMonitor] : clusterConfigs ) {
+    clusterMonitor.fill( deFT, odin, taeIndex, clusters, m_SiPMsToSkip );
   }
 
   if ( m_nCalls.nEntries() == 0 ) { always() << "Filling Histograms... Please be patient!" << endmsg; }
diff --git a/FT/FTMonitors/src/TAEHandler.h b/FT/FTMonitors/src/TAEHandler.h
new file mode 100644
index 0000000000000000000000000000000000000000..258dbd642a7b29f224ded6fbd2b9b38177505838
--- /dev/null
+++ b/FT/FTMonitors/src/TAEHandler.h
@@ -0,0 +1,97 @@
+/*****************************************************************************\
+* (c) Copyright 2022 CERN for the benefit of the LHCb Collaboration           *
+*                                                                             *
+* This software is distributed under the terms of the GNU General Public      *
+* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   *
+*                                                                             *
+* In applying this licence, CERN does not waive the privileges and immunities *
+* granted to it by virtue of its status as an Intergovernmental Organization  *
+* or submit itself to any jurisdiction.                                       *
+\*****************************************************************************/
+
+#pragma once
+
+#include "Event/ODIN.h"
+#include <Gaudi/Accumulators/Histogram.h>
+
+using ODIN   = LHCb::ODIN;
+namespace GA = Gaudi::Accumulators;
+
+template <typename T>
+class TAEHandler {
+private:
+  T*                        m_owner;
+  bool                      m_enableTAE;
+  std::vector<unsigned int> m_bunchIds;
+  unsigned int              m_TAEHalfWindow;
+
+  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>> m_TAEType;
+  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>> m_TAEIndex;
+  mutable std::optional<GA::Histogram<1, GA::atomicity::full, float>> m_TAEShift;
+
+public:
+  TAEHandler( T* owner ) : m_owner( owner ) {}
+
+  void setManualTAE( bool enableTAE, std::vector<unsigned int> bunchIds, unsigned int TAEHalfWindow,
+                     const std::string extraInfo ) {
+    m_enableTAE     = enableTAE;
+    m_TAEHalfWindow = TAEHalfWindow;
+    m_bunchIds      = bunchIds;
+
+    const unsigned int TAESize = 2 * TAEHalfWindow + 1;
+    m_TAEType.emplace(
+        m_owner, "TAEType", extraInfo + ";TAE type;Events",
+        GA::Axis<float>{TAESize + 1 + errors::NUM_ERRORS, -0.5f - errors::NUM_ERRORS, ( TAESize + 1 ) - 0.5f} );
+    m_TAEIndex.emplace( m_owner, "TAEIndex", extraInfo + ";TAE index;Events",
+                        GA::Axis<float>{TAESize + 1, -0.5f, ( TAESize + 1 ) - 0.5f} );
+    m_TAEShift.emplace( m_owner, "TAEShift", extraInfo + ";TAE shift;Events",
+                        GA::Axis<float>{TAESize, -0.5f - TAEHalfWindow, TAEHalfWindow + 0.5f} );
+  }
+
+  enum errors {
+    NotTAE,
+    Skipped,
+    TAEDisabled,
+    WrongTAEHalfWindow,
+    NUM_ERRORS,
+  };
+
+  int TAEIndexFromOdin( const LHCb::ODIN& odin ) const {
+    if ( !m_enableTAE ) {
+      ++( *m_TAEType )[errors::TAEDisabled];
+      return errors::TAEDisabled;
+    }
+
+    if ( !odin.isTAE() ) {
+      ++( *m_TAEType )[errors::NotTAE];
+      return errors::NotTAE;
+    }
+
+    if ( m_bunchIds.empty() ) { m_owner->error() << "TAE bunch IDs are not set" << endmsg; }
+
+    if ( odin.timeAlignmentEventIndex() != m_TAEHalfWindow ) {
+      m_owner->warning() << "TAE half window of event is " << odin.timeAlignmentEventIndex()
+                         << " while monitoring is set up for half window of " << m_TAEHalfWindow
+                         << ". Skipping this event." << endmsg;
+      ++( *m_TAEType )[errors::WrongTAEHalfWindow];
+      return -errors::WrongTAEHalfWindow;
+    }
+
+    int taeType = -errors::Skipped;
+    for ( const auto bunchId : m_bunchIds ) {
+      int testIDX = static_cast<int>( odin.bunchId() ) - static_cast<int>( bunchId );
+      if ( abs( testIDX ) <= odin.timeAlignmentEventIndex() ) {
+        taeType = 1 + testIDX + odin.timeAlignmentEventIndex();
+        break;
+      }
+    }
+
+    ++( *m_TAEType )[taeType];
+    ++( *m_TAEIndex )[taeType - 1];
+
+    const int taeCenter = 1 + m_TAEHalfWindow;
+    const int taeShift  = taeType - taeCenter;
+    ++( *m_TAEShift )[taeShift];
+    return taeType;
+  }
+};
diff --git a/FT/FTMonitors/tests/options/nzs_cluster_monitoring.py b/FT/FTMonitors/tests/options/nzs_cluster_monitoring.py
index a7dc11e846b2505626a1330108f870e1bb203bb9..b749f61c7f44b7ec36c869e0ad7e9296bf2ad253 100644
--- a/FT/FTMonitors/tests/options/nzs_cluster_monitoring.py
+++ b/FT/FTMonitors/tests/options/nzs_cluster_monitoring.py
@@ -15,7 +15,7 @@ from Configurables import LHCbApp
 from Configurables import GaudiSequencer
 from Configurables import LoKiSvc
 from GaudiConf import IOHelper
-from Configurables import Gaudi__Histograming__Sink__Root as RootHistoSink
+from Configurables import Gaudi__Monitoring__JSONSink as JSONSink
 from Configurables import Gaudi__Monitoring__MessageSvcSink as MessageSvcSink
 from Gaudi.Configuration import INFO
 from GaudiConf import IOHelper
@@ -68,13 +68,10 @@ monitor.OutputLevel = INFO
 monitor.DrawHistsPerStation = True
 monitor.DrawHistsPerQuarter = True
 monitor.DrawHistsPerModule = True
-monitor.DrawHistsPerSiPM = True
-monitor.manualTAEBunchIdFirst = 895
-monitor.manualTAESpacing = 1786 - 895
-monitor.manualTAENTAE = 2
-monitor.TAEHalfWindow = 2
+monitor.DrawCorrelationPlots = True
 monitor.enableTAE = True
-monitor.enableTest = True
+monitor.TAEHalfWindow = 2
+monitor.TAEBunchIds = [895, 1786]
 
 monSeq.Members = [
     unpacker,
@@ -85,11 +82,16 @@ monSeq.Members = [
 ]
 
 appMgr = ApplicationMgr(
-    EvtMax=1,
+    EvtMax=100,
     TopAlg=[monSeq],
     HistogramPersistency="ROOT",
     ExtSvc=[
         MessageSvcSink(),
-        RootHistoSink(FileName=output_name),
+        JSONSink(
+            FileName='nzs_cluster_monitoring.json',
+            NamesToSave=[
+                '.*MainEvent/LiteClustersPerPseudoChannel_64',
+                '.*nClustersPerTAE',
+            ]),
     ],
 )
diff --git a/FT/FTMonitors/tests/options/nzs_digit_monitoring.py b/FT/FTMonitors/tests/options/nzs_digit_monitoring.py
index d32c3101d1de518051be7a2064c0bcf7feaedd34..c807c5994f858c9dcb74d9d19803091bbde4bdf2 100644
--- a/FT/FTMonitors/tests/options/nzs_digit_monitoring.py
+++ b/FT/FTMonitors/tests/options/nzs_digit_monitoring.py
@@ -18,7 +18,7 @@ from Configurables import FTDigitMonitor
 from GaudiConf import IOHelper
 from os.path import basename
 from Gaudi.Configuration import MessageSvc, INFO
-from Configurables import Gaudi__Histograming__Sink__Root as RootHistoSink
+from Configurables import Gaudi__Monitoring__JSONSink as JSONSink
 from Configurables import Gaudi__Monitoring__MessageSvcSink as MessageSvcSink
 from GaudiConf import IOHelper
 from Configurables import FTNZSRawBankDecoder
@@ -62,11 +62,9 @@ decoder.OutputLevel = INFO
 
 monitor = FTDigitMonitor()
 monitor.OutputLevel = INFO
-monitor.manualTAENTAE = 2
-monitor.manualTAEBunchIdFirst = 895
-monitor.manualTAESpacing = 1786 - 895
 monitor.enableTAE = True
-monitor.enableTest = True
+monitor.TAEHalfWindow = 2
+monitor.TAEBunchIds = [895, 1786]
 
 monSeq.Members = [
     unpacker,
@@ -76,11 +74,14 @@ monSeq.Members = [
 ]
 
 appMgr = ApplicationMgr(
-    EvtMax=1,
+    EvtMax=100,
     TopAlg=[monSeq],
     HistogramPersistency="ROOT",
     ExtSvc=[
         MessageSvcSink(),
-        RootHistoSink(FileName=output_name),
+        JSONSink(
+            FileName='nzs_digit_monitoring.json', NamesToSave=[
+                'TAEType',
+            ]),
     ],
 )
diff --git a/FT/FTMonitors/tests/options/zs_cluster_monitoring.py b/FT/FTMonitors/tests/options/zs_cluster_monitoring.py
index 72c17350d37fa317b14ec02c6ad60a125e7ddff2..5e49fbb8e2ea23707061f956798115c0100114be 100644
--- a/FT/FTMonitors/tests/options/zs_cluster_monitoring.py
+++ b/FT/FTMonitors/tests/options/zs_cluster_monitoring.py
@@ -12,7 +12,7 @@
 from os.path import basename
 from Gaudi.Configuration import ApplicationMgr
 from Gaudi.Configuration import INFO
-from Configurables import Gaudi__Histograming__Sink__Root as RootHistoSink
+from Configurables import Gaudi__Monitoring__JSONSink as JSONSink
 from Configurables import Gaudi__Monitoring__MessageSvcSink as MessageSvcSink
 from Configurables import createODIN
 from GaudiConf import IOHelper
@@ -29,7 +29,6 @@ app.CondDBtag = "upgrade/master"
 
 app.Simulation = True
 app.DataType = "Upgrade"
-app.EvtMax = 1
 
 files = [
     "mdf:root://eoslhcb.cern.ch//eos/lhcb/wg/SciFi/Monitoring/test_files/Run_0000236211_20220705-171620-710_SCEB21.mdf",
@@ -46,18 +45,10 @@ monitor.OutputLevel = INFO
 monitor.DrawHistsPerStation = True
 monitor.DrawHistsPerQuarter = True
 monitor.DrawHistsPerModule = True
-monitor.DrawHistsPerSiPM = True
-monitor.OutputLevel = INFO
-monitor.DrawHistsPerStation = True
-monitor.DrawHistsPerQuarter = True
-monitor.DrawHistsPerModule = True
-monitor.DrawHistsPerSiPM = True
-monitor.manualTAENTAE = 2
-monitor.manualTAEBunchIdFirst = 895
-monitor.manualTAESpacing = 1786 - 895
-monitor.TAEHalfWindow = 2
+monitor.DrawCorrelationPlots = True
 monitor.enableTAE = True
-monitor.enableTest = True
+monitor.TAEHalfWindow = 2
+monitor.TAEBunchIds = [895, 1786]
 
 unpacker = LHCb__UnpackRawEvent(
     'UnpackRawEvent',
@@ -79,11 +70,15 @@ monSeq.Members = [
 ]
 
 appMgr = ApplicationMgr(
-    EvtMax=1,
+    EvtMax=1000,
     TopAlg=[monSeq],
-    HistogramPersistency="ROOT",
     ExtSvc=[
         MessageSvcSink(),
-        RootHistoSink(FileName=output_name),
+        JSONSink(
+            FileName='zs_cluster_monitoring.json',
+            NamesToSave=[
+                '.*MainEvent/LiteClustersPerPseudoChannel_64',
+                '.*nClustersPerTAE',
+            ]),
     ],
 )
diff --git a/FT/FTMonitors/tests/qmtest/nzs_cluster_monitoring.qmt b/FT/FTMonitors/tests/qmtest/nzs_cluster_monitoring.qmt
index 2da19416c201d3c1f8593c68c17f851239f547e1..32a89e2a19c37e27e92ff95764323e35ebb102ee 100644
--- a/FT/FTMonitors/tests/qmtest/nzs_cluster_monitoring.qmt
+++ b/FT/FTMonitors/tests/qmtest/nzs_cluster_monitoring.qmt
@@ -19,5 +19,6 @@
   <argument name="validator"><text>
 from RecConf.QMTest.exclusions import preprocessor
 validateWithReference(preproc=preprocessor)
+validateJSONWithReference("nzs_cluster_monitoring.json", "../refs/nzs_cluster_monitoring.json")
   </text></argument>
 </extension>
diff --git a/FT/FTMonitors/tests/qmtest/nzs_digit_monitoring.qmt b/FT/FTMonitors/tests/qmtest/nzs_digit_monitoring.qmt
index 80fdfb827083e442baf5f36f3668a98fe8609546..ee16e5b6b56d384131baddbc065ae0153d9b3dfc 100644
--- a/FT/FTMonitors/tests/qmtest/nzs_digit_monitoring.qmt
+++ b/FT/FTMonitors/tests/qmtest/nzs_digit_monitoring.qmt
@@ -19,5 +19,6 @@
   <argument name="validator"><text>
 from RecConf.QMTest.exclusions import preprocessor
 validateWithReference(preproc=preprocessor)
+validateJSONWithReference("nzs_digit_monitoring.json", "../refs/nzs_digit_monitoring.json")
   </text></argument>
 </extension>
\ No newline at end of file
diff --git a/FT/FTMonitors/tests/qmtest/zs_cluster_monitoring.qmt b/FT/FTMonitors/tests/qmtest/zs_cluster_monitoring.qmt
index 61aa85c7d4cc4da29c0f37f267f3e27057140623..e4ee983c0320e55de179a38cb550e85a09beb151 100644
--- a/FT/FTMonitors/tests/qmtest/zs_cluster_monitoring.qmt
+++ b/FT/FTMonitors/tests/qmtest/zs_cluster_monitoring.qmt
@@ -19,5 +19,6 @@
   <argument name="validator"><text>
 from RecConf.QMTest.exclusions import preprocessor
 validateWithReference(preproc=preprocessor)
+validateJSONWithReference("zs_cluster_monitoring.json", "../refs/zs_cluster_monitoring.json")
   </text></argument>
 </extension>
\ No newline at end of file
diff --git a/FT/FTMonitors/tests/refs/nzs_cluster_monitoring.json b/FT/FTMonitors/tests/refs/nzs_cluster_monitoring.json
new file mode 100644
index 0000000000000000000000000000000000000000..e0cceb9119835837d5e855296d5867736b4f1c11
--- /dev/null
+++ b/FT/FTMonitors/tests/refs/nzs_cluster_monitoring.json
@@ -0,0 +1,492 @@
+[
+    {
+        "component": "FTNZSClusterMonitor",
+        "entity": {
+            "axis": [
+                {
+                    "maxValue": 5.5,
+                    "minValue": -1.5,
+                    "nBins": 7,
+                    "title": ""
+                }
+            ],
+            "bins": [
+                0,
+                0,
+                0,
+                0,
+                2791,
+                6582,
+                611,
+                94,
+                0
+            ],
+            "dimension": 1,
+            "empty": false,
+            "nEntries": 10078,
+            "title": "Number of clusters per TAE;TAE type;Clusters",
+            "type": "histogram:Histogram:f"
+        },
+        "name": "FPGA/nClustersPerTAE"
+    },
+    {
+        "component": "FTNZSClusterMonitor",
+        "entity": {
+            "axis": [
+                {
+                    "maxValue": 12287.5,
+                    "minValue": -0.5,
+                    "nBins": 192,
+                    "title": ""
+                }
+            ],
+            "bins": [
+                0.0,
+                78.0,
+                44.0,
+                70.0,
+                48.0,
+                74.0,
+                50.0,
+                87.0,
+                49.0,
+                134.0,
+                83.0,
+                120.0,
+                86.0,
+                98.0,
+                98.0,
+                97.0,
+                71.0,
+                60.0,
+                101.0,
+                104.0,
+                113.0,
+                77.0,
+                98.0,
+                108.0,
+                117.0,
+                66.0,
+                58.0,
+                53.0,
+                81.0,
+                42.0,
+                59.0,
+                45.0,
+                62.0,
+                91.0,
+                50.0,
+                79.0,
+                42.0,
+                71.0,
+                57.0,
+                88.0,
+                46.0,
+                60.0,
+                34.0,
+                82.0,
+                54.0,
+                64.0,
+                56.0,
+                35.0,
+                35.0,
+                41.0,
+                36.0,
+                49.0,
+                57.0,
+                57.0,
+                51.0,
+                41.0,
+                54.0,
+                44.0,
+                46.0,
+                48.0,
+                42.0,
+                41.0,
+                51.0,
+                31.0,
+                29.0,
+                32.0,
+                18.0,
+                24.0,
+                16.0,
+                24.0,
+                19.0,
+                35.0,
+                30.0,
+                33.0,
+                18.0,
+                25.0,
+                33.0,
+                37.0,
+                12.0,
+                28.0,
+                22.0,
+                33.0,
+                33.0,
+                30.0,
+                27.0,
+                37.0,
+                35.0,
+                19.0,
+                28.0,
+                28.0,
+                33.0,
+                24.0,
+                20.0,
+                37.0,
+                38.0,
+                24.0,
+                25.0,
+                26.0,
+                20.0,
+                22.0,
+                23.0,
+                16.0,
+                16.0,
+                14.0,
+                21.0,
+                18.0,
+                24.0,
+                16.0,
+                25.0,
+                17.0,
+                14.0,
+                21.0,
+                28.0,
+                26.0,
+                34.0,
+                19.0,
+                23.0,
+                19.0,
+                10.0,
+                25.0,
+                24.0,
+                23.0,
+                34.0,
+                26.0,
+                26.0,
+                23.0,
+                24.0,
+                9.0,
+                19.0,
+                19.0,
+                10.0,
+                9.0,
+                21.0,
+                18.0,
+                22.0,
+                25.0,
+                29.0,
+                18.0,
+                19.0,
+                12.0,
+                15.0,
+                18.0,
+                21.0,
+                17.0,
+                15.0,
+                34.0,
+                22.0,
+                23.0,
+                23.0,
+                31.0,
+                27.0,
+                21.0,
+                13.0,
+                23.0,
+                16.0,
+                28.0,
+                20.0,
+                19.0,
+                17.0,
+                23.0,
+                21.0,
+                1.0,
+                6.0,
+                1.0,
+                6.0,
+                5.0,
+                7.0,
+                6.0,
+                8.0,
+                3.0,
+                6.0,
+                6.0,
+                11.0,
+                6.0,
+                4.0,
+                4.0,
+                0.0,
+                5.0,
+                3.0,
+                5.0,
+                4.0,
+                9.0,
+                8.0,
+                4.0,
+                4.0,
+                8.0,
+                7.0,
+                6.0,
+                5.0,
+                8.0,
+                5.0,
+                6.0,
+                11.0,
+                0.0
+            ],
+            "dimension": 1,
+            "empty": false,
+            "nEntries": 6582,
+            "title": "clusters per pseudo channel;Pseudo channel;Clusters / (64 channels)",
+            "type": "histogram:WeightedHistogram:f"
+        },
+        "name": "FPGA/TAE/02_MainEvent/LiteClustersPerPseudoChannel_64"
+    },
+    {
+        "component": "FTNZSClusterMonitor",
+        "entity": {
+            "axis": [
+                {
+                    "maxValue": 5.5,
+                    "minValue": -1.5,
+                    "nBins": 7,
+                    "title": ""
+                }
+            ],
+            "bins": [
+                0,
+                0,
+                0,
+                0,
+                3280,
+                7980,
+                1042,
+                108,
+                0
+            ],
+            "dimension": 1,
+            "empty": false,
+            "nEntries": 12410,
+            "title": "Number of clusters per TAE;TAE type;Clusters",
+            "type": "histogram:Histogram:f"
+        },
+        "name": "Offline/nClustersPerTAE"
+    },
+    {
+        "component": "FTNZSClusterMonitor",
+        "entity": {
+            "axis": [
+                {
+                    "maxValue": 12287.5,
+                    "minValue": -0.5,
+                    "nBins": 192,
+                    "title": ""
+                }
+            ],
+            "bins": [
+                0.0,
+                74.0,
+                73.0,
+                66.0,
+                64.0,
+                87.0,
+                74.0,
+                61.0,
+                68.0,
+                158.0,
+                131.0,
+                142.0,
+                118.0,
+                117.0,
+                144.0,
+                95.0,
+                106.0,
+                104.0,
+                124.0,
+                141.0,
+                121.0,
+                95.0,
+                105.0,
+                167.0,
+                137.0,
+                94.0,
+                65.0,
+                75.0,
+                76.0,
+                65.0,
+                73.0,
+                61.0,
+                59.0,
+                96.0,
+                82.0,
+                72.0,
+                59.0,
+                67.0,
+                80.0,
+                94.0,
+                80.0,
+                66.0,
+                54.0,
+                67.0,
+                83.0,
+                52.0,
+                80.0,
+                49.0,
+                52.0,
+                33.0,
+                42.0,
+                57.0,
+                67.0,
+                73.0,
+                65.0,
+                54.0,
+                67.0,
+                54.0,
+                55.0,
+                58.0,
+                49.0,
+                49.0,
+                57.0,
+                46.0,
+                45.0,
+                30.0,
+                29.0,
+                16.0,
+                23.0,
+                31.0,
+                31.0,
+                34.0,
+                35.0,
+                27.0,
+                18.0,
+                27.0,
+                43.0,
+                40.0,
+                23.0,
+                41.0,
+                29.0,
+                49.0,
+                28.0,
+                32.0,
+                28.0,
+                43.0,
+                33.0,
+                22.0,
+                38.0,
+                34.0,
+                35.0,
+                36.0,
+                34.0,
+                35.0,
+                46.0,
+                40.0,
+                25.0,
+                27.0,
+                30.0,
+                18.0,
+                28.0,
+                23.0,
+                13.0,
+                20.0,
+                17.0,
+                19.0,
+                27.0,
+                21.0,
+                23.0,
+                18.0,
+                16.0,
+                30.0,
+                30.0,
+                32.0,
+                33.0,
+                25.0,
+                25.0,
+                24.0,
+                19.0,
+                26.0,
+                26.0,
+                29.0,
+                35.0,
+                38.0,
+                28.0,
+                37.0,
+                20.0,
+                15.0,
+                20.0,
+                17.0,
+                19.0,
+                25.0,
+                24.0,
+                25.0,
+                26.0,
+                28.0,
+                31.0,
+                18.0,
+                27.0,
+                10.0,
+                25.0,
+                19.0,
+                21.0,
+                16.0,
+                25.0,
+                44.0,
+                24.0,
+                25.0,
+                32.0,
+                31.0,
+                29.0,
+                33.0,
+                12.0,
+                20.0,
+                31.0,
+                29.0,
+                34.0,
+                18.0,
+                32.0,
+                24.0,
+                29.0,
+                3.0,
+                4.0,
+                2.0,
+                5.0,
+                7.0,
+                6.0,
+                7.0,
+                8.0,
+                5.0,
+                9.0,
+                10.0,
+                13.0,
+                7.0,
+                6.0,
+                4.0,
+                3.0,
+                6.0,
+                4.0,
+                6.0,
+                6.0,
+                13.0,
+                6.0,
+                5.0,
+                4.0,
+                5.0,
+                11.0,
+                6.0,
+                8.0,
+                3.0,
+                6.0,
+                5.0,
+                13.0,
+                0.0
+            ],
+            "dimension": 1,
+            "empty": false,
+            "nEntries": 7980,
+            "title": "clusters per pseudo channel;Pseudo channel;Clusters / (64 channels)",
+            "type": "histogram:WeightedHistogram:f"
+        },
+        "name": "Offline/TAE/02_MainEvent/LiteClustersPerPseudoChannel_64"
+    }
+]
\ No newline at end of file
diff --git a/FT/FTMonitors/tests/refs/nzs_cluster_monitoring.ref b/FT/FTMonitors/tests/refs/nzs_cluster_monitoring.ref
index 49bca19b6ca3f593f85fdcb7dabfcd698008fe95..693791d4b99ce4255f8c60066e2d235c89bb60a3 100644
--- a/FT/FTMonitors/tests/refs/nzs_cluster_monitoring.ref
+++ b/FT/FTMonitors/tests/refs/nzs_cluster_monitoring.ref
@@ -26,17 +26,215 @@ DecodeFT             INFO Conditions DB is compatible with FT bank version 7.
 DeFTDetector         INFO Current FT geometry version =   64
 ClusterFT            INFO found 659 candidates
 ClusterFT            INFO found 363 clusters
-FTNZSClusterMon...   INFO Print some histograms to compare against test references:
-FTNZSClusterMon...   INFO {"axis":[{"maxValue":21.5,"minValue":-0.5,"nBins":22,"title":""}],"bins":[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":false,"nEntries":1,"title":"TAE index; TAE index; Events","type":"histogram:Histogram:f"}
-FTNZSClusterMon...   INFO {"axis":[{"maxValue":21.5,"minValue":-4.5,"nBins":26,"title":""}],"bins":[0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":false,"nEntries":1,"title":"TAE type; TAE type; Events","type":"histogram:Histogram:f"}
-FTNZSClusterMon...   INFO {"axis":[{"maxValue":4095.5,"minValue":-0.5,"nBins":4096,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,311,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":false,"nEntries":311,"title":"bunch crossing ID; BX ID; Clusters","type":"histogram:Histogram:f"}
-FTNZSClusterMon...   INFO [{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"},{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}]
-FTNZSClusterMon...   INFO [{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"},{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}]
-FTNZSClusterMon...   INFO [{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,6,4,5,3,5,7,3,6,3,4,3,4,1,3,4,7,1,2,3,2,4,4,5,8,12,4,2,2,1,2,6,3,0,2,1,1,2,4,3,5,0,2,2,1,2,2,3,6,0,1,6,3,1,0,3,5,4,4,3,2,6,5,1,2,1,2,7,3,2,0,2,1,4,5,1,7,2,2,2,1,2,1,1,1,1,5,1,4,1,2,5,4,0,3,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,1,0,2,2,2,1,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":false,"nEntries":311,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"},{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,9,4,8,2,5,5,4,5,4,7,4,5,4,7,5,6,2,3,3,4,3,6,3,10,8,3,1,3,3,4,4,4,0,2,1,0,3,1,3,5,1,1,1,0,2,3,2,6,0,4,3,3,3,2,5,3,4,4,4,1,8,7,4,4,1,2,5,3,1,2,2,1,7,2,1,10,5,2,0,1,1,2,2,0,1,8,2,4,4,1,6,6,3,1,1,1,1,0,1,0,0,0,0,1,1,0,0,0,1,0,0,0,0,1,0,1,0,2,1,0,0,0,1,0,1,0,0,0,2,1,2,0,0,0,2,0,2,1,1,1,1,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":false,"nEntries":363,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}]
-FTNZSClusterMon...   INFO [{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"},{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}]
-FTNZSClusterMon...   INFO [{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"},{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}]
-FTNZSClusterMon...   INFO [{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"},{"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"NZS clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}]
 FTNZSClusterMon...SUCCESS Filling Histograms... Please be patient!
+ClusterFT            INFO found 214 candidates
+ClusterFT            INFO found 97 clusters
+ClusterFT            INFO found 22 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 1478 candidates
+ClusterFT            INFO found 781 clusters
+ClusterFT            INFO found 201 candidates
+ClusterFT            INFO found 66 clusters
+ClusterFT            INFO found 36 candidates
+ClusterFT            INFO found 8 clusters
+ClusterFT            INFO found 71 candidates
+ClusterFT            INFO found 25 clusters
+ClusterFT            INFO found 111 candidates
+ClusterFT            INFO found 48 clusters
+ClusterFT            INFO found 207 candidates
+ClusterFT            INFO found 105 clusters
+ClusterFT            INFO found 25 candidates
+ClusterFT            INFO found 2 clusters
+EventSelector     SUCCESS Reading Event record 11. Record number within stream 1: 11
+ClusterFT            INFO found 24 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 23 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 94 candidates
+ClusterFT            INFO found 35 clusters
+ClusterFT            INFO found 456 candidates
+ClusterFT            INFO found 237 clusters
+ClusterFT            INFO found 35 candidates
+ClusterFT            INFO found 4 clusters
+ClusterFT            INFO found 22 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 292 candidates
+ClusterFT            INFO found 135 clusters
+ClusterFT            INFO found 25 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 36 candidates
+ClusterFT            INFO found 5 clusters
+ClusterFT            INFO found 56 candidates
+ClusterFT            INFO found 16 clusters
+EventSelector     SUCCESS Reading Event record 21. Record number within stream 1: 21
+ClusterFT            INFO found 24 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 293 candidates
+ClusterFT            INFO found 157 clusters
+ClusterFT            INFO found 773 candidates
+ClusterFT            INFO found 375 clusters
+ClusterFT            INFO found 138 candidates
+ClusterFT            INFO found 58 clusters
+ClusterFT            INFO found 40 candidates
+ClusterFT            INFO found 8 clusters
+ClusterFT            INFO found 25 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 291 candidates
+ClusterFT            INFO found 135 clusters
+ClusterFT            INFO found 820 candidates
+ClusterFT            INFO found 429 clusters
+ClusterFT            INFO found 62 candidates
+ClusterFT            INFO found 17 clusters
+ClusterFT            INFO found 32 candidates
+ClusterFT            INFO found 5 clusters
+EventSelector     SUCCESS Reading Event record 31. Record number within stream 1: 31
+ClusterFT            INFO found 766 candidates
+ClusterFT            INFO found 388 clusters
+ClusterFT            INFO found 174 candidates
+ClusterFT            INFO found 97 clusters
+ClusterFT            INFO found 419 candidates
+ClusterFT            INFO found 207 clusters
+ClusterFT            INFO found 91 candidates
+ClusterFT            INFO found 39 clusters
+ClusterFT            INFO found 37 candidates
+ClusterFT            INFO found 10 clusters
+ClusterFT            INFO found 23 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 565 candidates
+ClusterFT            INFO found 292 clusters
+ClusterFT            INFO found 1261 candidates
+ClusterFT            INFO found 627 clusters
+ClusterFT            INFO found 266 candidates
+ClusterFT            INFO found 124 clusters
+ClusterFT            INFO found 24 candidates
+ClusterFT            INFO found 1 clusters
+EventSelector     SUCCESS Reading Event record 41. Record number within stream 1: 41
+ClusterFT            INFO found 107 candidates
+ClusterFT            INFO found 28 clusters
+ClusterFT            INFO found 605 candidates
+ClusterFT            INFO found 286 clusters
+ClusterFT            INFO found 1910 candidates
+ClusterFT            INFO found 947 clusters
+ClusterFT            INFO found 272 candidates
+ClusterFT            INFO found 113 clusters
+ClusterFT            INFO found 250 candidates
+ClusterFT            INFO found 132 clusters
+ClusterFT            INFO found 24 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 326 candidates
+ClusterFT            INFO found 147 clusters
+ClusterFT            INFO found 142 candidates
+ClusterFT            INFO found 59 clusters
+ClusterFT            INFO found 874 candidates
+ClusterFT            INFO found 432 clusters
+ClusterFT            INFO found 43 candidates
+ClusterFT            INFO found 10 clusters
+EventSelector     SUCCESS Reading Event record 51. Record number within stream 1: 51
+ClusterFT            INFO found 25 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 165 candidates
+ClusterFT            INFO found 60 clusters
+ClusterFT            INFO found 439 candidates
+ClusterFT            INFO found 215 clusters
+ClusterFT            INFO found 55 candidates
+ClusterFT            INFO found 11 clusters
+ClusterFT            INFO found 26 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 25 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 78 candidates
+ClusterFT            INFO found 25 clusters
+ClusterFT            INFO found 352 candidates
+ClusterFT            INFO found 164 clusters
+ClusterFT            INFO found 79 candidates
+ClusterFT            INFO found 31 clusters
+ClusterFT            INFO found 34 candidates
+ClusterFT            INFO found 2 clusters
+EventSelector     SUCCESS Reading Event record 61. Record number within stream 1: 61
+ClusterFT            INFO found 24 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 754 candidates
+ClusterFT            INFO found 378 clusters
+ClusterFT            INFO found 391 candidates
+ClusterFT            INFO found 183 clusters
+ClusterFT            INFO found 113 candidates
+ClusterFT            INFO found 34 clusters
+ClusterFT            INFO found 30 candidates
+ClusterFT            INFO found 5 clusters
+ClusterFT            INFO found 22 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 330 candidates
+ClusterFT            INFO found 171 clusters
+ClusterFT            INFO found 496 candidates
+ClusterFT            INFO found 198 clusters
+ClusterFT            INFO found 25 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 32 candidates
+ClusterFT            INFO found 5 clusters
+EventSelector     SUCCESS Reading Event record 71. Record number within stream 1: 71
+ClusterFT            INFO found 25 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 274 candidates
+ClusterFT            INFO found 125 clusters
+ClusterFT            INFO found 41 candidates
+ClusterFT            INFO found 13 clusters
+ClusterFT            INFO found 141 candidates
+ClusterFT            INFO found 60 clusters
+ClusterFT            INFO found 48 candidates
+ClusterFT            INFO found 12 clusters
+ClusterFT            INFO found 25 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 766 candidates
+ClusterFT            INFO found 376 clusters
+ClusterFT            INFO found 24 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 333 candidates
+ClusterFT            INFO found 148 clusters
+ClusterFT            INFO found 54 candidates
+ClusterFT            INFO found 13 clusters
+EventSelector     SUCCESS Reading Event record 81. Record number within stream 1: 81
+ClusterFT            INFO found 307 candidates
+ClusterFT            INFO found 167 clusters
+ClusterFT            INFO found 424 candidates
+ClusterFT            INFO found 211 clusters
+ClusterFT            INFO found 813 candidates
+ClusterFT            INFO found 376 clusters
+ClusterFT            INFO found 26 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 690 candidates
+ClusterFT            INFO found 369 clusters
+ClusterFT            INFO found 23 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 47 candidates
+ClusterFT            INFO found 15 clusters
+ClusterFT            INFO found 108 candidates
+ClusterFT            INFO found 54 clusters
+ClusterFT            INFO found 23 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 2071 candidates
+ClusterFT            INFO found 1084 clusters
+EventSelector     SUCCESS Reading Event record 91. Record number within stream 1: 91
+ClusterFT            INFO found 25 candidates
+ClusterFT            INFO found 1 clusters
+ClusterFT            INFO found 186 candidates
+ClusterFT            INFO found 113 clusters
+ClusterFT            INFO found 124 candidates
+ClusterFT            INFO found 55 clusters
+ClusterFT            INFO found 67 candidates
+ClusterFT            INFO found 11 clusters
+ClusterFT            INFO found 33 candidates
+ClusterFT            INFO found 7 clusters
+ClusterFT            INFO found 131 candidates
+ClusterFT            INFO found 47 clusters
+ClusterFT            INFO found 348 candidates
+ClusterFT            INFO found 160 clusters
+ClusterFT            INFO found 893 candidates
+ClusterFT            INFO found 447 clusters
+ClusterFT            INFO found 129 candidates
+ClusterFT            INFO found 45 clusters
+ClusterFT            INFO found 46 candidates
+ClusterFT            INFO found 14 clusters
+Gaudi::Monitori...   INFO Writing JSON file nzs_cluster_monitoring.json
 ApplicationMgr       INFO Application Manager Stopped successfully
 RootHistSvc       WARNING no ROOT output file name, Histograms cannot be persistified
 EventLoopMgr         INFO Histograms converted successfully according to request.
@@ -45,4 +243,4 @@ ApplicationMgr       INFO Application Manager Finalized successfully
 ApplicationMgr       INFO Application Manager Terminated successfully
 FTNZSClusterMon...   INFO Number of counters : 1
  |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
- | "number of calls"                               |         1 |
+ | "number of calls"                               |        68 |
diff --git a/FT/FTMonitors/tests/refs/nzs_digit_monitoring.json b/FT/FTMonitors/tests/refs/nzs_digit_monitoring.json
new file mode 100644
index 0000000000000000000000000000000000000000..646a8caa77cb19d4c4bc715c4ca44cad0ad4f2b8
--- /dev/null
+++ b/FT/FTMonitors/tests/refs/nzs_digit_monitoring.json
@@ -0,0 +1,35 @@
+[
+    {
+        "component": "FTDigitMonitor",
+        "entity": {
+            "axis": [
+                {
+                    "maxValue": 5.5,
+                    "minValue": -4.5,
+                    "nBins": 10,
+                    "title": ""
+                }
+            ],
+            "bins": [
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                21,
+                20,
+                20,
+                20,
+                19,
+                0
+            ],
+            "dimension": 1,
+            "empty": false,
+            "nEntries": 100,
+            "title": ";TAE type;Events",
+            "type": "histogram:Histogram:f"
+        },
+        "name": "TAEType"
+    }
+]
\ No newline at end of file
diff --git a/FT/FTMonitors/tests/refs/nzs_digit_monitoring.ref b/FT/FTMonitors/tests/refs/nzs_digit_monitoring.ref
index ce172cd44452f3532e61560ca197f3fced74b743..64f0edaa1d2fa87da8a2fe14046ac90032d56088 100644
--- a/FT/FTMonitors/tests/refs/nzs_digit_monitoring.ref
+++ b/FT/FTMonitors/tests/refs/nzs_digit_monitoring.ref
@@ -25,9 +25,16 @@ EventPersistenc...   INFO Added successfully Conversion service:LHCb::RawDataCnv
 DecodeFT             INFO Conditions DB is compatible with FT bank version 7.
 DeFTDetector         INFO Current FT geometry version =   64
 FTDigitMonitor    SUCCESS Filling Histograms... Please be patient!
-FTDigitMonitor       INFO Print some histograms to compare against test references:
-FTDigitMonitor       INFO {"axis":[{"maxValue":21.5,"minValue":-0.5,"nBins":22,"title":""}],"bins":[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":false,"nEntries":1,"title":"TAE index; TAE index; Events","type":"histogram:Histogram:f"}
-FTDigitMonitor       INFO {"axis":[{"maxValue":21.5,"minValue":-4.5,"nBins":26,"title":""}],"bins":[0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":false,"nEntries":1,"title":"TAE type; TAE type; Events","type":"histogram:Histogram:f"}
+EventSelector     SUCCESS Reading Event record 11. Record number within stream 1: 11
+EventSelector     SUCCESS Reading Event record 21. Record number within stream 1: 21
+EventSelector     SUCCESS Reading Event record 31. Record number within stream 1: 31
+EventSelector     SUCCESS Reading Event record 41. Record number within stream 1: 41
+EventSelector     SUCCESS Reading Event record 51. Record number within stream 1: 51
+EventSelector     SUCCESS Reading Event record 61. Record number within stream 1: 61
+EventSelector     SUCCESS Reading Event record 71. Record number within stream 1: 71
+EventSelector     SUCCESS Reading Event record 81. Record number within stream 1: 81
+EventSelector     SUCCESS Reading Event record 91. Record number within stream 1: 91
+Gaudi::Monitori...   INFO Writing JSON file nzs_digit_monitoring.json
 ApplicationMgr       INFO Application Manager Stopped successfully
 RootHistSvc       WARNING no ROOT output file name, Histograms cannot be persistified
 EventLoopMgr         INFO Histograms converted successfully according to request.
@@ -36,4 +43,4 @@ ApplicationMgr       INFO Application Manager Finalized successfully
 ApplicationMgr       INFO Application Manager Terminated successfully
 FTDigitMonitor       INFO Number of counters : 1
  |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
- | "number of calls"                               |    259584 |
+ | "number of calls"                               |  25958400 |
diff --git a/FT/FTMonitors/tests/refs/zs_cluster_monitoring.json b/FT/FTMonitors/tests/refs/zs_cluster_monitoring.json
new file mode 100644
index 0000000000000000000000000000000000000000..593e5a3d0f6215230faeaf75113b55c1abdf1f50
--- /dev/null
+++ b/FT/FTMonitors/tests/refs/zs_cluster_monitoring.json
@@ -0,0 +1,247 @@
+[
+    {
+        "component": "FTClusterMonitor",
+        "entity": {
+            "axis": [
+                {
+                    "maxValue": 5.5,
+                    "minValue": -1.5,
+                    "nBins": 7,
+                    "title": ""
+                }
+            ],
+            "bins": [
+                0,
+                0,
+                0,
+                0,
+                27277,
+                68788,
+                5585,
+                498,
+                0
+            ],
+            "dimension": 1,
+            "empty": false,
+            "nEntries": 102148,
+            "title": "Number of clusters per TAE;TAE type;Clusters",
+            "type": "histogram:Histogram:f"
+        },
+        "name": "nClustersPerTAE"
+    },
+    {
+        "component": "FTClusterMonitor",
+        "entity": {
+            "axis": [
+                {
+                    "maxValue": 12287.5,
+                    "minValue": -0.5,
+                    "nBins": 192,
+                    "title": ""
+                }
+            ],
+            "bins": [
+                0.0,
+                820.0,
+                465.0,
+                904.0,
+                548.0,
+                888.0,
+                504.0,
+                913.0,
+                515.0,
+                1470.0,
+                1008.0,
+                1433.0,
+                868.0,
+                1400.0,
+                842.0,
+                1264.0,
+                739.0,
+                923.0,
+                1085.0,
+                1055.0,
+                1250.0,
+                1001.0,
+                1193.0,
+                1104.0,
+                1263.0,
+                623.0,
+                680.0,
+                596.0,
+                676.0,
+                549.0,
+                615.0,
+                505.0,
+                629.0,
+                691.0,
+                414.0,
+                811.0,
+                431.0,
+                732.0,
+                437.0,
+                740.0,
+                454.0,
+                667.0,
+                368.0,
+                836.0,
+                488.0,
+                647.0,
+                396.0,
+                638.0,
+                375.0,
+                429.0,
+                433.0,
+                393.0,
+                421.0,
+                635.0,
+                492.0,
+                434.0,
+                450.0,
+                369.0,
+                399.0,
+                395.0,
+                414.0,
+                357.0,
+                411.0,
+                306.0,
+                404.0,
+                275.0,
+                217.0,
+                258.0,
+                220.0,
+                267.0,
+                204.0,
+                272.0,
+                249.0,
+                271.0,
+                219.0,
+                241.0,
+                219.0,
+                243.0,
+                214.0,
+                249.0,
+                205.0,
+                277.0,
+                266.0,
+                310.0,
+                266.0,
+                302.0,
+                267.0,
+                315.0,
+                298.0,
+                298.0,
+                289.0,
+                271.0,
+                267.0,
+                284.0,
+                250.0,
+                233.0,
+                299.0,
+                206.0,
+                179.0,
+                206.0,
+                194.0,
+                206.0,
+                248.0,
+                175.0,
+                222.0,
+                200.0,
+                216.0,
+                207.0,
+                241.0,
+                184.0,
+                205.0,
+                192.0,
+                227.0,
+                210.0,
+                246.0,
+                223.0,
+                232.0,
+                201.0,
+                281.0,
+                226.0,
+                221.0,
+                199.0,
+                210.0,
+                240.0,
+                258.0,
+                197.0,
+                266.0,
+                179.0,
+                268.0,
+                171.0,
+                174.0,
+                235.0,
+                204.0,
+                194.0,
+                189.0,
+                187.0,
+                228.0,
+                175.0,
+                215.0,
+                161.0,
+                186.0,
+                164.0,
+                190.0,
+                166.0,
+                204.0,
+                219.0,
+                208.0,
+                279.0,
+                209.0,
+                249.0,
+                228.0,
+                247.0,
+                247.0,
+                231.0,
+                242.0,
+                269.0,
+                255.0,
+                257.0,
+                269.0,
+                271.0,
+                230.0,
+                49.0,
+                72.0,
+                61.0,
+                56.0,
+                53.0,
+                57.0,
+                45.0,
+                66.0,
+                71.0,
+                79.0,
+                70.0,
+                51.0,
+                64.0,
+                64.0,
+                64.0,
+                62.0,
+                87.0,
+                94.0,
+                89.0,
+                87.0,
+                92.0,
+                79.0,
+                90.0,
+                99.0,
+                87.0,
+                85.0,
+                85.0,
+                76.0,
+                83.0,
+                83.0,
+                91.0,
+                69.0,
+                0.0
+            ],
+            "dimension": 1,
+            "empty": false,
+            "nEntries": 68788,
+            "title": "clusters per pseudo channel;Pseudo channel;Clusters / (64 channels)",
+            "type": "histogram:WeightedHistogram:f"
+        },
+        "name": "TAE/02_MainEvent/LiteClustersPerPseudoChannel_64"
+    }
+]
\ No newline at end of file
diff --git a/FT/FTMonitors/tests/refs/zs_cluster_monitoring.ref b/FT/FTMonitors/tests/refs/zs_cluster_monitoring.ref
index 4a87a18b9f8735d2a18e9994782d00d254213be8..6394ccde0c1a5fd2f50ade18f08f2f8814432258 100644
--- a/FT/FTMonitors/tests/refs/zs_cluster_monitoring.ref
+++ b/FT/FTMonitors/tests/refs/zs_cluster_monitoring.ref
@@ -12,8 +12,6 @@ SciFiMonitorSeq...   INFO Member list: LHCb::UnpackRawEvent/UnpackRawEvent, crea
 RndmGenSvc.Engine    INFO Generator engine type:CLHEP::RanluxEngine
 RndmGenSvc.Engine    INFO Current Seed:1234567 Luxury:3
 RndmGenSvc           INFO Using Random engine:HepRndm::Engine<CLHEP::RanluxEngine>
-RootHistSvc          INFO Writing ROOT histograms to: UndefinedROOTOutputFileName
-HistogramPersis...   INFO Added successfully Conversion service:RootHistSvc
 IODataManager       ERROR Referring to existing dataset mdf:root://eoslhcb.cern.ch//eos/lhcb/wg/SciFi/Monitoring/test_files/Run_0000236211_20220705-171620-710_SCEB21.mdf by its physical name.
 IODataManager       ERROR You may not be able to navigate back to the input file -- processing continues
 ApplicationMgr       INFO Application Manager Initialized successfully
@@ -24,23 +22,125 @@ EventPersistenc...   INFO Added successfully Conversion service:RootCnvSvc
 EventPersistenc...   INFO Added successfully Conversion service:LHCb::RawDataCnvSvc
 DecodeFT             INFO Conditions DB is compatible with FT bank version 7.
 DeFTDetector         INFO Current FT geometry version =   64
-FTClusterMonitor     INFO Print some histograms to compare against test references:
-FTClusterMonitor     INFO {"axis":[{"maxValue":21.5,"minValue":-0.5,"nBins":22,"title":""}],"bins":[0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":false,"nEntries":1,"title":"TAE index; TAE index; Events","type":"histogram:Histogram:f"}
-FTClusterMonitor     INFO {"axis":[{"maxValue":21.5,"minValue":-4.5,"nBins":26,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":false,"nEntries":1,"title":"TAE type; TAE type; Events","type":"histogram:Histogram:f"}
-FTClusterMonitor     INFO {"axis":[{"maxValue":4095.5,"minValue":-0.5,"nBins":4096,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":false,"nEntries":8,"title":"bunch crossing ID; BX ID; Clusters","type":"histogram:Histogram:f"}
-FTClusterMonitor     INFO {"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"Lite clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}
-FTClusterMonitor     INFO {"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"Lite clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}
-FTClusterMonitor     INFO {"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"Lite clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}
-FTClusterMonitor     INFO {"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"Lite clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}
-FTClusterMonitor     INFO {"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":false,"nEntries":8,"title":"Lite clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}
-FTClusterMonitor     INFO {"axis":[{"maxValue":12287.5,"minValue":-0.5,"nBins":192,"title":""}],"bins":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"dimension":1,"empty":true,"nEntries":0,"title":"Lite clusters per pseudo channel; Pseudo channel; Clusters / (64 channels)","type":"histogram:Histogram:f"}
+DecodeFT            ERROR Possibly corrupt data. Ignoring the cluster.
+DecodeFT            ERROR Possibly corrupt data. Ignoring the cluster.
+DecodeFT            ERROR Possibly corrupt data. Ignoring the cluster.
+DecodeFT            ERROR Possibly corrupt data. Ignoring the cluster.
+DecodeFT            ERROR Possibly corrupt data. Ignoring the cluster.
+DecodeFT            ERROR Possibly corrupt data. Ignoring the cluster.
+DecodeFT            ERROR Possibly corrupt data. Ignoring the cluster.
 FTClusterMonitor  SUCCESS Filling Histograms... Please be patient!
+DecodeFT            ERROR Possibly corrupt data. Ignoring the cluster.
+DecodeFT            ERROR Possibly corrupt data. Ignoring the cluster.
+DecodeFT            ERROR Suppressing message: 'Possibly corrupt data. Ignoring the cluster.'
+EventSelector     SUCCESS Reading Event record 11. Record number within stream 1: 11
+EventSelector     SUCCESS Reading Event record 21. Record number within stream 1: 21
+EventSelector     SUCCESS Reading Event record 31. Record number within stream 1: 31
+EventSelector     SUCCESS Reading Event record 41. Record number within stream 1: 41
+EventSelector     SUCCESS Reading Event record 51. Record number within stream 1: 51
+EventSelector     SUCCESS Reading Event record 61. Record number within stream 1: 61
+EventSelector     SUCCESS Reading Event record 71. Record number within stream 1: 71
+EventSelector     SUCCESS Reading Event record 81. Record number within stream 1: 81
+EventSelector     SUCCESS Reading Event record 91. Record number within stream 1: 91
+EventSelector     SUCCESS Reading Event record 101. Record number within stream 1: 101
+EventSelector     SUCCESS Reading Event record 111. Record number within stream 1: 111
+EventSelector     SUCCESS Reading Event record 121. Record number within stream 1: 121
+EventSelector     SUCCESS Reading Event record 131. Record number within stream 1: 131
+EventSelector     SUCCESS Reading Event record 141. Record number within stream 1: 141
+EventSelector     SUCCESS Reading Event record 151. Record number within stream 1: 151
+EventSelector     SUCCESS Reading Event record 161. Record number within stream 1: 161
+EventSelector     SUCCESS Reading Event record 171. Record number within stream 1: 171
+EventSelector     SUCCESS Reading Event record 181. Record number within stream 1: 181
+EventSelector     SUCCESS Reading Event record 191. Record number within stream 1: 191
+EventSelector     SUCCESS Reading Event record 201. Record number within stream 1: 201
+EventSelector     SUCCESS Reading Event record 211. Record number within stream 1: 211
+EventSelector     SUCCESS Reading Event record 221. Record number within stream 1: 221
+EventSelector     SUCCESS Reading Event record 231. Record number within stream 1: 231
+EventSelector     SUCCESS Reading Event record 241. Record number within stream 1: 241
+EventSelector     SUCCESS Reading Event record 251. Record number within stream 1: 251
+EventSelector     SUCCESS Reading Event record 261. Record number within stream 1: 261
+EventSelector     SUCCESS Reading Event record 271. Record number within stream 1: 271
+EventSelector     SUCCESS Reading Event record 281. Record number within stream 1: 281
+EventSelector     SUCCESS Reading Event record 291. Record number within stream 1: 291
+EventSelector     SUCCESS Reading Event record 301. Record number within stream 1: 301
+EventSelector     SUCCESS Reading Event record 311. Record number within stream 1: 311
+EventSelector     SUCCESS Reading Event record 321. Record number within stream 1: 321
+EventSelector     SUCCESS Reading Event record 331. Record number within stream 1: 331
+EventSelector     SUCCESS Reading Event record 341. Record number within stream 1: 341
+EventSelector     SUCCESS Reading Event record 351. Record number within stream 1: 351
+EventSelector     SUCCESS Reading Event record 361. Record number within stream 1: 361
+EventSelector     SUCCESS Reading Event record 371. Record number within stream 1: 371
+EventSelector     SUCCESS Reading Event record 381. Record number within stream 1: 381
+EventSelector     SUCCESS Reading Event record 391. Record number within stream 1: 391
+EventSelector     SUCCESS Reading Event record 401. Record number within stream 1: 401
+EventSelector     SUCCESS Reading Event record 411. Record number within stream 1: 411
+EventSelector     SUCCESS Reading Event record 421. Record number within stream 1: 421
+EventSelector     SUCCESS Reading Event record 431. Record number within stream 1: 431
+EventSelector     SUCCESS Reading Event record 441. Record number within stream 1: 441
+EventSelector     SUCCESS Reading Event record 451. Record number within stream 1: 451
+EventSelector     SUCCESS Reading Event record 461. Record number within stream 1: 461
+EventSelector     SUCCESS Reading Event record 471. Record number within stream 1: 471
+EventSelector     SUCCESS Reading Event record 481. Record number within stream 1: 481
+EventSelector     SUCCESS Reading Event record 491. Record number within stream 1: 491
+EventSelector     SUCCESS Reading Event record 501. Record number within stream 1: 501
+EventSelector     SUCCESS Reading Event record 511. Record number within stream 1: 511
+EventSelector     SUCCESS Reading Event record 521. Record number within stream 1: 521
+EventSelector     SUCCESS Reading Event record 531. Record number within stream 1: 531
+EventSelector     SUCCESS Reading Event record 541. Record number within stream 1: 541
+EventSelector     SUCCESS Reading Event record 551. Record number within stream 1: 551
+EventSelector     SUCCESS Reading Event record 561. Record number within stream 1: 561
+EventSelector     SUCCESS Reading Event record 571. Record number within stream 1: 571
+EventSelector     SUCCESS Reading Event record 581. Record number within stream 1: 581
+EventSelector     SUCCESS Reading Event record 591. Record number within stream 1: 591
+EventSelector     SUCCESS Reading Event record 601. Record number within stream 1: 601
+EventSelector     SUCCESS Reading Event record 611. Record number within stream 1: 611
+EventSelector     SUCCESS Reading Event record 621. Record number within stream 1: 621
+EventSelector     SUCCESS Reading Event record 631. Record number within stream 1: 631
+EventSelector     SUCCESS Reading Event record 641. Record number within stream 1: 641
+EventSelector     SUCCESS Reading Event record 651. Record number within stream 1: 651
+EventSelector     SUCCESS Reading Event record 661. Record number within stream 1: 661
+EventSelector     SUCCESS Reading Event record 671. Record number within stream 1: 671
+EventSelector     SUCCESS Reading Event record 681. Record number within stream 1: 681
+EventSelector     SUCCESS Reading Event record 691. Record number within stream 1: 691
+EventSelector     SUCCESS Reading Event record 701. Record number within stream 1: 701
+EventSelector     SUCCESS Reading Event record 711. Record number within stream 1: 711
+EventSelector     SUCCESS Reading Event record 721. Record number within stream 1: 721
+EventSelector     SUCCESS Reading Event record 731. Record number within stream 1: 731
+EventSelector     SUCCESS Reading Event record 741. Record number within stream 1: 741
+EventSelector     SUCCESS Reading Event record 751. Record number within stream 1: 751
+EventSelector     SUCCESS Reading Event record 761. Record number within stream 1: 761
+EventSelector     SUCCESS Reading Event record 771. Record number within stream 1: 771
+EventSelector     SUCCESS Reading Event record 781. Record number within stream 1: 781
+EventSelector     SUCCESS Reading Event record 791. Record number within stream 1: 791
+EventSelector     SUCCESS Reading Event record 801. Record number within stream 1: 801
+EventSelector     SUCCESS Reading Event record 811. Record number within stream 1: 811
+EventSelector     SUCCESS Reading Event record 821. Record number within stream 1: 821
+EventSelector     SUCCESS Reading Event record 831. Record number within stream 1: 831
+EventSelector     SUCCESS Reading Event record 841. Record number within stream 1: 841
+EventSelector     SUCCESS Reading Event record 851. Record number within stream 1: 851
+EventSelector     SUCCESS Reading Event record 861. Record number within stream 1: 861
+EventSelector     SUCCESS Reading Event record 871. Record number within stream 1: 871
+EventSelector     SUCCESS Reading Event record 881. Record number within stream 1: 881
+EventSelector     SUCCESS Reading Event record 891. Record number within stream 1: 891
+EventSelector     SUCCESS Reading Event record 901. Record number within stream 1: 901
+EventSelector     SUCCESS Reading Event record 911. Record number within stream 1: 911
+EventSelector     SUCCESS Reading Event record 921. Record number within stream 1: 921
+EventSelector     SUCCESS Reading Event record 931. Record number within stream 1: 931
+EventSelector     SUCCESS Reading Event record 941. Record number within stream 1: 941
+EventSelector     SUCCESS Reading Event record 951. Record number within stream 1: 951
+EventSelector     SUCCESS Reading Event record 961. Record number within stream 1: 961
+EventSelector     SUCCESS Reading Event record 971. Record number within stream 1: 971
+EventSelector     SUCCESS Reading Event record 981. Record number within stream 1: 981
+EventSelector     SUCCESS Reading Event record 991. Record number within stream 1: 991
+Gaudi::Monitori...   INFO Writing JSON file zs_cluster_monitoring.json
 ApplicationMgr       INFO Application Manager Stopped successfully
-RootHistSvc       WARNING no ROOT output file name, Histograms cannot be persistified
 EventLoopMgr         INFO Histograms converted successfully according to request.
 ToolSvc              INFO Removing all tools created by ToolSvc
 ApplicationMgr       INFO Application Manager Finalized successfully
 ApplicationMgr       INFO Application Manager Terminated successfully
+DecodeFT             INFO Number of counters : 1
+ |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
+ | "Possibly corrupt data. Ignoring the cluster."  |      5099 |
 FTClusterMonitor     INFO Number of counters : 1
  |    Counter                                      |     #     |    sum     | mean/eff^* | rms/err^*  |     min     |     max     |
- | "number of calls"                               |         1 |
+ | "number of calls"                               |       584 |
diff --git a/Pr/PrAlgorithms/src/PrHybridSeeding.cpp b/Pr/PrAlgorithms/src/PrHybridSeeding.cpp
index 5c5d408e0656d0e7427406b182c18d3c047a580c..a28780b7f24c379ad5cad637b12a837cae33b7ad 100644
--- a/Pr/PrAlgorithms/src/PrHybridSeeding.cpp
+++ b/Pr/PrAlgorithms/src/PrHybridSeeding.cpp
@@ -26,6 +26,7 @@
 #include "FTDAQ/FTInfo.h"
 #include "FTDet/DeFTDetector.h"
 #include "GaudiKernel/StdArrayAsProperty.h"
+#include "Gaudi/Accumulators/Histogram.h"
 #include "Kernel/STLExtensions.h" // ASSUME statement
 #include "LHCbAlgs/Transformer.h"
 #include "Magnet/DeMagnet.h"
@@ -383,14 +384,45 @@ namespace LHCb::Pr {
   private:
     // Counters about the total number of tracks
     using SC = Gaudi::Accumulators::StatCounter<>;
+    static constexpr int  nbins_chi2ndfos_hist = 50; // EN: to be decided    
+
+    mutable Gaudi::Accumulators::Histogram<1, Gaudi::Accumulators::atomicity::full, float> m_chi2_FullFit_hist{
+            this, "chi2_FullFit_hist", "Chi2ndofs of the Full Fit", {nbins_chi2ndfos_hist, 0, 7}}; // max 6 + 1
+    mutable Gaudi::Accumulators::Histogram<1, Gaudi::Accumulators::atomicity::full, float>  m_nHitsXZ_hist{
+            this, "nHitsXZ_hist", "nHitsXZ", {nbins_chi2ndfos_hist, 0, 7}}; // max 6 + 1
+
+    mutable std::array<Gaudi::Accumulators::Histogram<1>, NCases> m_chi2_XZ_Cnt_cases_hist{
+        Gaudi::Accumulators::Histogram<1>{this, "Chi2_XZ_fit_case_0", "Chi2 of the XZ fit in case 0" , {nbins_chi2ndfos_hist, 0, 7} },
+        Gaudi::Accumulators::Histogram<1>{this, "Chi2_XZ_fit_case_1", "Chi2 of the XZ fit in case 1" , {nbins_chi2ndfos_hist, 0, 7} },
+	      Gaudi::Accumulators::Histogram<1>{this, "Chi2_XZ_fit_case_2", "Chi2 of the XZ fit in case 2" , {nbins_chi2ndfos_hist, 0, 7} }};
+        
+    mutable std::array<Gaudi::Accumulators::Histogram<1>, NCases> m_chi2_FullFit_Cnt_cases_hist{
+        Gaudi::Accumulators::Histogram<1>{this, "Chi2_XZ_full_fit_case_0", "Chi2 of the XZ full fit in case 0" , {nbins_chi2ndfos_hist, 0, 7} },
+        Gaudi::Accumulators::Histogram<1>{this, "Chi2_XZ_full_fit_case_1", "Chi2 of the XZ full fit in case 1" , {nbins_chi2ndfos_hist, 0, 7} },
+	      Gaudi::Accumulators::Histogram<1>{this, "Chi2_XZ_full_fit_case_2", "Chi2 of the XZ full fit in case 2" , {nbins_chi2ndfos_hist, 0, 7} }};
+        
+    mutable std::array<SC, NCases> m_chi2_XZ_Cnt_cases{
+        SC{this, "Chi2 of the XZ fit in case 0"},
+        SC{this, "Chi2 of the XZ fit in case 1"},
+	      SC{this, "Chi2 of the XZ fit in case 2"}};
+        
+    mutable std::array<SC, NCases+1> m_chi2_FullFit_Cnt_cases{
+        SC{this, "Chi2 of the full fit in case 0"},
+        SC{this, "Chi2 of the full fit in case 1"},
+	      SC{this, "Chi2 of the full fit in case 2"},
+	      SC{this, "Chi2 of the full fit in recovery"},
+	    };
+
     mutable SC                         m_outputTracksCnt{this, "Created seed tracks"};
     mutable std::array<SC, 2>          m_outputTracksCnt_part{SC{this, "Created seed tracks (part 0)"},
                                                      SC{this, "Created seed tracks (part 1)"}};
     mutable std::array<SC, NCases + 1> m_outputTracksCnt_cases{
         SC{this, "Created seed tracks in case 0"}, SC{this, "Created seed tracks in case 1"},
         SC{this, "Created seed tracks in case 2"}, SC{this, "Created seed tracks in recovery step"}};
+
     mutable std::array<SC, 2>          m_outputXZTracksCnt_part{SC{this, "Created XZ tracks (part 0)"},
                                                        SC{this, "Created XZ tracks (part 1)"}};
+
     mutable std::array<SC, NCases + 1> m_outputXZTracksCnt_cases{
         SC{this, "Created XZ tracks in case 0"}, SC{this, "Created XZ tracks in case 1"},
         SC{this, "Created XZ tracks in case 2"}, SC{this, "Created XZ tracks in recovery step"}};
@@ -1107,6 +1139,9 @@ namespace LHCb::Pr {
                                                         HoughCandidateHitIter itBeg, HoughCandidateHitIter itEnd,
                                                         unsigned int& nTarget, float& chi2Target,
                                                         unsigned int& nValidCandidates ) const noexcept {
+
+    auto chi2YBuf_hist       = m_hybridSeeding.m_chi2_FullFit_hist.buffer();
+
     constexpr int      LOW_NTOT_YSEL_TH = CASE == 2 ? 10 : 11;
     constexpr int      LOW_NTOT_TH      = 11;
     constexpr int      LOW_NUV_TH       = CASE == 2 ? 5 : 6;
@@ -1122,7 +1157,7 @@ namespace LHCb::Pr {
     PrTrackFitterYZ fitterYZ( xCandidate );
     bool            fitY = fitterYZ.fit( sciFiHits, itBeg, itEnd );
     if ( !fitY ) return;
-
+    
     auto worstHitY     = removeWorstY( fitterYZ, itBeg, itEnd );
     bool canRemoveHitY = nHits > nTarget && nUVHits > m_hybridSeeding.m_minUV[CASE][6 - nXHits];
     while ( worstHitY != itEnd ) {
@@ -1141,7 +1176,6 @@ namespace LHCb::Pr {
     if ( ( nUVHits >= LOW_NUV_TH && fitterYZ.chi2PerDoF() > m_hybridSeeding.m_maxChi2PerDofYHigh[CASE] ) ||
          ( nUVHits < LOW_NUV_TH && fitterYZ.chi2PerDoF() > m_hybridSeeding.m_maxChi2PerDofYLow[CASE] ) )
       return;
-
     Pr::Hybrid::SeedTrack trackCand( xCandidate );
     for ( auto hit = itBeg; hit != itEnd; ++hit ) trackCand.hits().push_back( *( *hit ) );
     trackCand.setYParam( fitterYZ.ay(), fitterYZ.by() );
@@ -1163,6 +1197,7 @@ namespace LHCb::Pr {
       if ( !fitXY ) return;
       worstHit      = removeWorstXY( trackCand );
       canRemoveHitY = nHits > nTarget && nUVHits > m_hybridSeeding.m_minUV[CASE][6 - nHits + nUVHits];
+      ++ (chi2YBuf_hist ) [trackCand.chi2PerDoF()];
     }
 
     if ( nHits > nTarget ) {
@@ -1385,6 +1420,14 @@ namespace LHCb::Pr {
     // Counters
     auto twoHitCombCnt   = m_twoHitCombCnt_cases[iCase].buffer();
     auto threeHitCombCnt = m_threeHitCombCnt_cases[iCase].buffer();
+    auto chi2XZBuf       = m_chi2_XZ_Cnt_cases[iCase].buffer();
+    auto chi2XZBuf_hist       = m_chi2_XZ_Cnt_cases_hist[iCase].buffer();
+    auto chi2XZBufAll       = m_chi2_FullFit_Cnt_cases[iCase].buffer();
+    auto chi2XZBufAll_hist       = m_chi2_FullFit_Cnt_cases_hist[iCase].buffer();
+
+    // auto chi2UVBuf       = m_chi2_UV_Cnt_cases[iCase].buffer();
+    // auto chi2UVBufAll       = m_chi2_FullFit_Cnt_cases_UV[iCase].buffer();
+    // auto chi2UVBufAll_hist       = m_chi2_FullFit_Cnt_cases_hist_UV[iCase].buffer();
 
     auto&          xCands = xCandidates[part];
     CaseGeomInfoXZ xZones = initializeXProjections( zoneCache, iCase, part );
@@ -1464,8 +1507,15 @@ namespace LHCb::Pr {
           fillXhits0( sciFiHits, iCase, Fhit, parabolaSeedHits[0][i], Lhit, xZones, hitComb, zoneLimits, xCands,
                       tempWindows );
         }
+        //--LoH: For EN: Put here counters for all XZ segments
+        chi2XZBufAll+= xCands[xCands.size()-1].chi2PerDoF();
+        ++( chi2XZBufAll_hist )[xCands[xCands.size()-1].chi2PerDoF()];
         //---LoH: do not even try to reconstruct a track if you already got one before.
-        if ( n0 != xCands.size() ) { continue; }
+        if ( n0 != xCands.size() ) { 
+          chi2XZBuf += xCands[xCands.size()-1].chi2PerDoF() ; 
+          ++( chi2XZBuf_hist )[xCands[xCands.size()-1].chi2PerDoF()];
+          continue; 
+          }
         // First parabola
         hitComb.x0 += xZones.t2Dist * hitComb.tx; // x0 is now the projected x on T2x2
         for ( unsigned int i = 0; i < parabolaSeedHits[1].size(); ++i ) {
@@ -1542,6 +1592,7 @@ namespace LHCb::Pr {
                                     Pr::Hybrid::SeedTrackX&              xCand ) const noexcept {
     //---LoH: called 27k times
     //---LoH: out of all the calls, less than 50% refused
+    // EN: fill here the X hits? auto m_nHitsXZ_hist_buff = m_nHitsXZ_hist.buffer();
     // Create the track
     PrTrackFitterXZ fitter;
     bool            fitX = fitter.fit( sciFiHits, xCand );
@@ -1563,6 +1614,7 @@ namespace LHCb::Pr {
       xCand.setXT1( xCand.xFromDz( StateParameters::ZBegT - Pr::Hybrid::zReference ) );
       xCand.setXT3( xCand.xFromDz( StateParameters::ZEndT - Pr::Hybrid::zReference ) );
       xCandidates.push_back( xCand );
+      ++ (m_nHitsXZ_hist_buff ) [1];
     }
   }