From 20180fba11a443f3aba2bca15d082afb0394d3a2 Mon Sep 17 00:00:00 2001
From: Sebastien Ponce <sebastien.ponce@cern.ch>
Date: Thu, 1 Sep 2022 10:24:37 +0200
Subject: [PATCH] Modernized CaloFutureDigitMonitor and dropped dependency on
 CaloFutureMoniAlg

---
 CaloFuture/CaloFutureMoniDst/CMakeLists.txt   |   2 +-
 .../src/CaloDigitMonitor.cpp                  | 160 +++++++++++++++
 .../src/CaloFutureDigitMonitor.cpp            | 194 ------------------
 3 files changed, 161 insertions(+), 195 deletions(-)
 create mode 100644 CaloFuture/CaloFutureMoniDst/src/CaloDigitMonitor.cpp
 delete mode 100644 CaloFuture/CaloFutureMoniDst/src/CaloFutureDigitMonitor.cpp

diff --git a/CaloFuture/CaloFutureMoniDst/CMakeLists.txt b/CaloFuture/CaloFutureMoniDst/CMakeLists.txt
index fd4a3ee3815..585d92c1dbe 100644
--- a/CaloFuture/CaloFutureMoniDst/CMakeLists.txt
+++ b/CaloFuture/CaloFutureMoniDst/CMakeLists.txt
@@ -16,7 +16,7 @@ CaloFuture/CaloFutureMoniDst
 gaudi_add_module(CaloFutureMoniDst
     SOURCES
         src/CaloClusterMonitor.cpp
-        src/CaloFutureDigitMonitor.cpp
+        src/CaloDigitMonitor.cpp
 	src/CaloFutureLEDMonitor.cpp
         src/CaloFutureMoniAlg.cpp
         src/CaloFutureTimeAlignment.cpp
diff --git a/CaloFuture/CaloFutureMoniDst/src/CaloDigitMonitor.cpp b/CaloFuture/CaloFutureMoniDst/src/CaloDigitMonitor.cpp
new file mode 100644
index 00000000000..b41b89f503f
--- /dev/null
+++ b/CaloFuture/CaloFutureMoniDst/src/CaloDigitMonitor.cpp
@@ -0,0 +1,160 @@
+/*****************************************************************************\
+* (c) Copyright 2000-2018 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.                                       *
+\*****************************************************************************/
+
+#include "CaloDet/DeCalorimeter.h"
+#include "CaloFutureUtils/CaloFutureAlgUtils.h"
+#include "CaloFutureUtils/CellIDHistogram.h"
+#include "DetDesc/GenericConditionAccessorHolder.h"
+#include "Event/CaloDigits_v2.h"
+#include "Event/ODIN.h"
+#include "LHCbAlgs/Consumer.h"
+
+#include <Gaudi/Accumulators/Histogram.h>
+
+#include <mutex>
+
+namespace LHCb::Calo {
+
+  /**
+   *  The algorithm for trivial monitoring of "CaloDigit" containers.
+   *  The algorithm produces the following histograms:
+   *   1. CaloDigit multiplicity
+   *   2. CaloDigit ocupancy 2D plot per area
+   *   3. CaloDigit energy 2D plot per area
+   *  The same set of histograms, but with cut on Et (or E), is produced if specified
+   *
+   *  Histograms reside in the directory @p /stat/"Name" , where
+   *  @p "Name" is the name of the algorithm
+   *
+   *  @author Konstantin Belous Konstantin.Beloous@itep.ru
+   *  @date   21/06/2007
+   */
+
+  using Input = Event::Calo::Digits;
+
+  template <Detector::Calo::CellCode::Index calo>
+  class DigitMonitor final
+      : public LHCb::Algorithm::Consumer<void( const Input&, const LHCb::ODIN&, const DeCalorimeter& ),
+                                         DetDesc::usesConditions<DeCalorimeter>> {
+  public:
+    StatusCode initialize() override;
+    void       operator()( const Input&, const LHCb::ODIN&, const DeCalorimeter& ) const override;
+
+    DigitMonitor( const std::string& name, ISvcLocator* pSvcLocator );
+
+  private:
+    std::string m_detData{};
+
+    mutable Gaudi::Accumulators::Histogram<1>  m_histoMultiplicity{this, "Multiplicity"};
+    mutable Gaudi::Accumulators::Histogram<1>  m_histoDigitX{this, "DigitX"};
+    mutable Gaudi::Accumulators::Histogram<1>  m_histoDigitY{this, "DigitY"};
+    mutable Gaudi::Accumulators::Histogram<2>  m_histoDigitXY{this, "DigitXY"};
+    mutable Gaudi::Accumulators::Histogram<1>  m_histoET{this, "ET"};
+    mutable Gaudi::Accumulators::Histogram<1>  m_histoADC{this, "ADC"};
+    mutable Gaudi::Accumulators::StatCounter<> m_digits{this, "# digits over threshold"};
+    mutable WeightedCellIDHistogram<calo>      m_histoAccEnergy{this, "_7"};
+    mutable CellIDHistogram<calo>              m_histoAccDigits{this, "_8"};
+    mutable WeightedCellIDHistogram<calo>      m_histoAccADCs{this, "_9"};
+
+    Gaudi::Property<std::vector<int>> m_Calib_BXIDsA{this, "Calib_BXIDsA"};
+    Gaudi::Property<std::vector<int>> m_Calib_BXIDsB{this, "Calib_BXIDsB"};
+
+    Gaudi::Property<Gaudi::Histo1DDef> m_multHist{this, "HistoMultiplicity", Gaudi::Histo1DDef( 0., 2000., 100 )};
+    Gaudi::Property<Gaudi::Histo1DDef> m_etHist{
+        this, "HistoEt", Gaudi::Histo1DDef( 0. * Gaudi::Units::GeV, 15. * Gaudi::Units::GeV, 100 )};
+    Gaudi::Property<Gaudi::Histo1DDef> m_xHist{
+        this, "HistoX", Gaudi::Histo1DDef( -4 * Gaudi::Units::meter, +4 * Gaudi::Units::meter, 50 )};
+    Gaudi::Property<Gaudi::Histo1DDef> m_yHist{
+        this, "HistoY", Gaudi::Histo1DDef( -4 * Gaudi::Units::meter, +4 * Gaudi::Units::meter, 50 )};
+    Gaudi::Property<Gaudi::Histo1DDef> m_adcHist{this, "HistoAdc", Gaudi::Histo1DDef( 0., 4096., 4096 )};
+
+    Gaudi::Property<float> m_eFilter{this, "EnergyFilter", -100.};
+    Gaudi::Property<float> m_etFilter{this, "EtFilter", -100.};
+    Gaudi::Property<float> m_adcFilter{this, "ADCFilter", -100.};
+  };
+
+  DECLARE_COMPONENT_WITH_ID( DigitMonitor<Detector::Calo::CellCode::Index::EcalCalo>, "CaloDigitECALMonitor" )
+  DECLARE_COMPONENT_WITH_ID( DigitMonitor<Detector::Calo::CellCode::Index::HcalCalo>, "CaloDigitHCALMonitor" )
+
+} // namespace LHCb::Calo
+
+template <LHCb::Detector::Calo::CellCode::Index calo>
+LHCb::Calo::DigitMonitor<calo>::DigitMonitor( const std::string& name, ISvcLocator* pSvcLocator )
+    : Consumer( name, pSvcLocator,
+                {KeyValue{"Input", CaloFutureAlgUtils::CaloFutureDigitLocation( toString( calo ) )},
+                 KeyValue{"ODINLocation", ODINLocation::Default},
+                 KeyValue{"Detector", Calo::Utilities::DeCaloFutureLocation( toString( calo ) )}} )
+    , m_detData{toString( calo )} {}
+
+template <LHCb::Detector::Calo::CellCode::Index calo>
+StatusCode LHCb::Calo::DigitMonitor<calo>::initialize() {
+  return Consumer::initialize().andThen( [&] {
+    info() << m_detData << " digits from " << inputLocation() << endmsg;
+    // book physics histograms so they are always created and found by Monet
+    m_histoAccEnergy.setTitle( fmt::format( "{} Accumulated Energy", m_detData ) );
+    m_histoAccDigits.setTitle( fmt::format( "{} Accumulated Digits filled", m_detData ) );
+    m_histoAccADCs.setTitle( fmt::format( "{} Accumulated ADCs", m_detData ) );
+    // define range of new histograms from properties
+    using Axis1D = Gaudi::Accumulators::Axis<double>;
+    m_histoMultiplicity.setTitle( "Number of digits" );
+    m_histoMultiplicity.setAxis<0>( Axis1D{m_multHist} );
+    m_histoDigitX.setTitle( "Digit X" );
+    m_histoDigitX.setAxis<0>( Axis1D{m_xHist} );
+    m_histoDigitY.setTitle( "Digit Y" );
+    m_histoDigitY.setAxis<0>( Axis1D{m_yHist} );
+    m_histoDigitXY.setTitle( "Digit position x vs y" );
+    m_histoDigitXY.setAxis<0>( Axis1D{m_xHist} );
+    m_histoDigitXY.setAxis<1>( Axis1D{m_yHist} );
+    m_histoET.setTitle( "ET" );
+    m_histoET.setAxis<0>( Axis1D{m_etHist} );
+    m_histoADC.setTitle( "ADC" );
+    m_histoADC.setAxis<0>( Axis1D{m_adcHist} );
+  } );
+}
+
+template <LHCb::Detector::Calo::CellCode::Index calo>
+void LHCb::Calo::DigitMonitor<calo>::operator()( const Input& digits, const LHCb::ODIN& odin,
+                                                 const DeCalorimeter& caloDet ) const {
+  if ( digits.empty() ) {
+    if ( msgLevel( MSG::DEBUG ) ) { debug() << "Found empty container in " << inputLocation() << endmsg; }
+    return;
+  }
+
+  // count digits NB: digits.size() has a fixed value no matter the state of the detector
+  uint ndigits = 0;
+
+  for ( const auto& digit : digits ) {
+    const auto id  = digit.cellID();
+    const auto e   = digit.energy();
+    const auto adc = digit.adc();
+    const auto et  = e * caloDet.cellSine( id );
+    if ( e < m_eFilter ) continue;
+    if ( et < m_etFilter ) continue;
+    if ( adc < m_adcFilter ) continue;
+    const double x = caloDet.cellCenter( id ).X();
+    const double y = caloDet.cellCenter( id ).Y();
+    if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) {
+      ++ndigits;
+      ++m_histoDigitX[x];
+      ++m_histoDigitY[y];
+      ++m_histoDigitXY[{x, y}];
+    }
+    m_histoAccEnergy[id] += e;
+    ++m_histoAccDigits[id];
+    m_histoAccADCs[id] += adc;
+    ++m_histoET[et];
+    ++m_histoADC[adc];
+  }
+  m_digits += ndigits;
+  if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing )
+    ++m_histoMultiplicity[ndigits];
+  return;
+}
diff --git a/CaloFuture/CaloFutureMoniDst/src/CaloFutureDigitMonitor.cpp b/CaloFuture/CaloFutureMoniDst/src/CaloFutureDigitMonitor.cpp
deleted file mode 100644
index 21f37b56a35..00000000000
--- a/CaloFuture/CaloFutureMoniDst/src/CaloFutureDigitMonitor.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/*****************************************************************************\
-* (c) Copyright 2000-2018 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.                                       *
-\*****************************************************************************/
-// Includes
-#include "CaloDet/DeCalorimeter.h"
-#include "CaloFutureMoniAlg.h"
-#include "CaloFutureUtils/CaloFutureAlgUtils.h"
-#include "DetDesc/GenericConditionAccessorHolder.h"
-#include "Event/CaloDigits_v2.h"
-#include "Event/ODIN.h"
-#include "LHCbAlgs/Consumer.h"
-#include <Gaudi/Accumulators/Histogram.h>
-
-// =============================================================================
-
-/** @class CaloFutureDigitMonitor CaloFutureDigitMonitor.cpp
- *
- *  The algorithm for trivial monitoring of "CaloDigit" containers.
- *  The algorithm produces the following histograms:
- *   1. CaloDigit multiplicity
- *   2. CaloDigit ocupancy 2D plot per area
- *   3. CaloDigit energy 2D plot per area
- *  The same set of histograms, but with cut on Et (or E), is produced if specified
- *
- *  Histograms reside in the directory @p /stat/"Name" , where
- *  @p "Name" is the name of the algorithm
- *
- *  @author Konstantin Belous Konstantin.Beloous@itep.ru
- *  @date   21/06/2007
- */
-
-using Input = LHCb::Event::Calo::Digits;
-
-class CaloFutureDigitMonitor final
-    : public LHCb::Algorithm::Consumer<
-          void( const Input&, const LHCb::ODIN&, const DeCalorimeter& ),
-          LHCb::Algorithm::Traits::usesBaseAndConditions<CaloFutureMoniAlg, DeCalorimeter>> {
-public:
-  StatusCode initialize() override;
-  void       operator()( const Input&, const LHCb::ODIN&, const DeCalorimeter& ) const override;
-
-  CaloFutureDigitMonitor( const std::string& name, ISvcLocator* pSvcLocator );
-
-private:
-  Gaudi::Property<bool> m_spectrum{this, "Spectrum", false, "activate spectrum per channel histogramming"};
-  Gaudi::Property<bool> m_SeparateCalib{this, "SeparateCalib", true, "separate Calib BXIDs/Triger type to Calib plots"};
-  Gaudi::Property<std::vector<int>>                        m_Calib_BXIDsA{this, "Calib_BXIDsA"};
-  Gaudi::Property<std::vector<int>>                        m_Calib_BXIDsB{this, "Calib_BXIDsB"};
-  Gaudi::Property<std::vector<int>>                        m_perBXIDlist{this, "perBXIDlist"};
-  mutable std::optional<Gaudi::Accumulators::Histogram<1>> m_histoMultiplicity;
-  mutable std::optional<Gaudi::Accumulators::Histogram<1>> m_histoDigitX;
-  mutable std::optional<Gaudi::Accumulators::Histogram<1>> m_histoDigitY;
-  mutable std::optional<Gaudi::Accumulators::Histogram<2>> m_histoDigitXY;
-  mutable std::optional<Gaudi::Accumulators::Histogram<1>> m_histoET;
-  mutable std::optional<Gaudi::Accumulators::Histogram<1>> m_histoADC;
-  mutable Gaudi::Accumulators::StatCounter<>               m_digits{this, "# digits over threshold"};
-};
-
-// =============================================================================
-
-DECLARE_COMPONENT_WITH_ID( CaloFutureDigitMonitor, "CaloFutureDigitMonitor" )
-
-// =============================================================================
-
-CaloFutureDigitMonitor::CaloFutureDigitMonitor( const std::string& name, ISvcLocator* pSvcLocator )
-    : Consumer( name, pSvcLocator,
-                {KeyValue{"Input", LHCb::CaloFutureAlgUtils::CaloFutureDigitLocation( name )},
-                 KeyValue{"ODINLocation", LHCb::ODINLocation::Default},
-                 KeyValue{"Detector", LHCb::Calo::Utilities::DeCaloFutureLocation( name )}} ) {}
-
-// =============================================================================
-// standard initialize method
-// =============================================================================
-
-StatusCode CaloFutureDigitMonitor::initialize() {
-  return Consumer::initialize().andThen( [&] {
-    info() << detData() << " digits from " << inputLocation() << endmsg;
-    // book physics histograms so they are always created and found by Monet
-    bookCaloFuture2D( "7", fmt::format( "{} Accumulated Energy", detData() ), detData(), -1 );
-    bookCaloFuture2D( "8", fmt::format( "{} Accumulated Digits filled", detData() ), detData() );
-    bookCaloFuture2D( "9", fmt::format( "{} Accumulated ADCs", detData() ), detData() );
-    // define range of new histograms from properties
-    using axis1D = Gaudi::Accumulators::Axis<decltype( m_histoMultiplicity )::value_type::AxisArithmeticType>;
-    m_histoMultiplicity.emplace( this, "Multiplicity", "Number of digits", axis1D{m_multBin, m_multMin, m_multMax} );
-    m_histoDigitX.emplace( this, "DigitX", "Digit X", axis1D{m_xBin, m_xMin, m_xMax} );
-    m_histoDigitY.emplace( this, "DigitY", "Digit Y", axis1D{m_yBin, m_yMin, m_yMax} );
-    m_histoDigitXY.emplace( this, "DigitXY", "Digit position x vs y", axis1D{m_xBin, m_xMin, m_xMax},
-                            axis1D{m_yBin, m_yMin, m_yMax} );
-    m_histoET.emplace( this, "ET", "ET", axis1D{m_etBin, m_etMin, m_etMax} );
-    m_histoADC.emplace( this, "ADC", "ADC", axis1D{m_adcBin, m_adcMin, m_adcMax} );
-  } );
-}
-
-// ============================================================================
-// standard execution method
-// ============================================================================
-
-void CaloFutureDigitMonitor::operator()( const Input& digits, const LHCb::ODIN& odin,
-                                         const DeCalorimeter& calo ) const {
-
-  if ( msgLevel( MSG::DEBUG ) ) debug() << name() << " execute " << endmsg;
-
-  // produce histos ?
-  if ( msgLevel( MSG::DEBUG ) ) debug() << " Producing histo " << produceHistos() << endmsg;
-  if ( !produceHistos() ) return; // StatusCode::SUCCESS;
-
-  if ( digits.empty() ) {
-    if ( msgLevel( MSG::DEBUG ) ) debug() << "Found empty container in " << inputLocation() << endmsg;
-    return;
-  }
-
-  std::string Suff      = "_Other";
-  std::string Suff_BXID = "";
-  if ( m_SeparateCalib ) {
-    if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) {
-      Suff = "";
-    } else if ( odin.calibrationType() > 0 ) {
-      Suff = fmt::format( "_Calib{}", odin.calibrationType() );
-    }
-    if ( std::find( m_Calib_BXIDsA.begin(), m_Calib_BXIDsA.end(), odin.bunchId() ) != m_Calib_BXIDsA.end() ) {
-      Suff = std::string( "_Calib1" );
-    }
-    if ( std::find( m_Calib_BXIDsB.begin(), m_Calib_BXIDsB.end(), odin.bunchId() ) != m_Calib_BXIDsB.end() ) {
-      Suff = std::string( "_Calib2" );
-    }
-  }
-  if ( std::find( m_perBXIDlist.begin(), m_perBXIDlist.end(), odin.bunchId() ) != m_perBXIDlist.end() ) {
-    Suff_BXID = fmt::format( "_BXID_{}", odin.bunchId() );
-  }
-
-  // count digits NB: digits.size() has a fixed value no matter the state of the detector
-  uint ndigits = 0;
-
-  for ( const auto& digit : digits ) {
-    const auto id  = digit.cellID();
-    const auto e   = digit.energy();
-    const auto adc = digit.adc();
-    const auto et  = e * calo.cellSine( id );
-    if ( e < m_eFilter ) continue;
-    if ( et < m_etFilter ) continue;
-    if ( adc < m_adcFilter ) continue;
-    const double x = calo.cellCenter( id ).X();
-    const double y = calo.cellCenter( id ).Y();
-    if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing ) {
-      ++ndigits;
-      ++m_histoDigitX.value()[x];
-      ++m_histoDigitY.value()[y];
-      ++m_histoDigitXY.value()[{x, y}];
-    }
-    fillCaloFuture2D( fmt::format( "7{}", Suff ), id, e, calo,
-                      fmt::format( "{} Accumulated Energy {}", detData(), Suff ) );
-    fillCaloFuture2D( fmt::format( "8{}", Suff ), id, 1., calo,
-                      fmt::format( "{} Accumulated Digits filled {}", detData(), Suff ) );
-    fillCaloFuture2D( fmt::format( "9{}", Suff ), id, adc, calo,
-                      fmt::format( "{} Accumulated ADCs {}", detData(), Suff ) );
-    if ( Suff_BXID != "" ) {
-      fillCaloFuture2D( fmt::format( "ADC{}", Suff_BXID ), id, adc, calo,
-                        fmt::format( "{} Accumulated ADCs {}", detData(), Suff_BXID ) );
-      fillCaloFuture2D( fmt::format( "Occupancy{}", Suff_BXID ), id, 1, calo,
-                        fmt::format( "{} Accumulated ADCs {}", detData(), Suff_BXID ) );
-    }
-
-    if ( m_spectrum ) {
-      if ( msgLevel( MSG::DEBUG ) ) debug() << "Filling cell by cell histograms" << endmsg;
-      const int          col = id.col();
-      const int          row = id.row();
-      std::ostringstream tit;
-      tit << detData() << " channel : " << id;
-      const auto unit_adc = detData() + "Cells/" + id.areaName() + "/" + Gaudi::Utils::toString( row ) + ";" +
-                            Gaudi::Utils::toString( col ) + "_adc";
-      const auto unit_et = detData() + "Cells/" + id.areaName() + "/" + Gaudi::Utils::toString( row ) + ";" +
-                           Gaudi::Utils::toString( col ) + "_et";
-      if ( msgLevel( MSG::VERBOSE ) ) {
-        verbose() << " et  " << et << " cell " << unit_et << endmsg;
-        verbose() << " adc  " << adc << " cell " << unit_adc << endmsg;
-      } else {
-        ++m_histoET.value()[et];
-        ++m_histoADC.value()[adc];
-      }
-    }
-  }
-  if ( msgLevel( MSG::VERBOSE ) ) verbose() << "# digits: " << ndigits << endmsg;
-  m_digits += ndigits;
-  if ( odin.bunchCrossingType() == LHCb::ODINImplementation::v7::ODIN::BXTypes::BeamCrossing )
-    ++m_histoMultiplicity.value()[ndigits];
-  return;
-}
-- 
GitLab