Skip to content
Snippets Groups Projects

Add counter class for luminosity counters

Merged Marco Clemencic requested to merge add-lumi-counter-impl into master
Files
7
/*****************************************************************************\
* (c) Copyright 2023 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 <Gaudi/MonitoringHub.h>
#include <Kernel/SynchronizedValue.h>
#include <algorithm>
#include <cstdint>
#include <map>
#include <nlohmann/json.hpp>
#include <string>
#include <utility>
namespace LHCb {
/// Special counter to split counts of events by run.
///
/// A LumiEventCounter instance can be used as any Gaudi::Accumulator::Counter. To increment the counter
/// for a given run number one has to invoke the method LumiEventCounter::inc(std::uint32_t) passing the
/// current run number and optionally the increase step (by default it's 1).
///
/// Example of use:
/// ```cpp
/// #include <Event/LumiEventCounter.h>
/// #include <LHCbAlgs/Consumer.h>
/// #include <Event/ODIN.h>
/// struct LumiCountAlg final : public LHCb::Algorithm::Consumer<void( const LHCb::ODIN& )> {
/// LumiCountAlg( const std::string& name, ISvcLocator* pSvcLocator )
/// : Consumer( name, pSvcLocator, KeyValue{"ODIN", ODINLocation::Default} ) {}
/// void operator()( const LHCb::ODIN& odin ) const override { m_lumiCount.inc( odin.runNumber() ); }
///
/// mutable LHCb::LumiEventCounter m_lumiCount{this, "eventsByRun"};
/// };
/// ```
class LumiEventCounter final {
public:
LumiEventCounter() = default;
template <typename OWNER>
LumiEventCounter( OWNER* o, std::string name ) : m_monitoringHub{&o->serviceLocator()->monitoringHub()} {
m_monitoringHub->registerEntity( o->name(), std::move( name ), "LumiEventCounter", *this );
}
~LumiEventCounter() {
if ( m_monitoringHub ) m_monitoringHub->removeEntity( *this );
}
nlohmann::json toJSON() const { return *this; }
void reset() {
m_counts.with_lock( []( map_type& counts ) { counts.clear(); } );
}
void inc( std::uint32_t run, std::size_t count = 1 ) {
m_counts.with_lock( [run, count]( map_type& counts ) { counts[run] += count; } );
}
std::size_t get( std::uint32_t run ) const {
return m_counts.with_lock( [run]( auto& counts ) -> std::size_t {
if ( auto it = counts.find( run ); it != counts.end() ) {
return it->second;
} else {
return 0;
}
} );
}
bool empty() const {
return m_counts.with_lock( []( auto& counts ) {
return std::all_of( counts.begin(), counts.end(), []( const auto& item ) { return item.second == 0; } );
} );
}
private:
using map_type = std::map<std::uint32_t, std::size_t>;
cxx::SynchronizedValue<map_type> m_counts;
Gaudi::Monitoring::Hub* m_monitoringHub{nullptr};
friend void to_json( nlohmann::json&, const LumiEventCounter& );
};
void to_json( nlohmann::json& j, const LumiEventCounter& c ) {
j["type"] = "LumiEventCounter";
j["empty"] = c.empty();
j["counts"] = c.m_counts.with_lock( []( auto& counts ) {
auto tmp = nlohmann::json::object();
for ( const auto [run, count] : counts ) { tmp.emplace( std::to_string( run ), count ); }
return tmp;
} );
}
} // namespace LHCb
Loading