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 <algorithm>
#include <cstdint>
#include <map>
#include <mutex>
#include <nlohmann/json.hpp>
#include <string>
#include <utility>
namespace LHCb {
/// Special counter to split counts of events by run.
///
/// A LuminosityCounter instance can be used as any Gaudi::Accumulator::Counter. To increment the counter
/// for a given run number one has to invoke the method LuminosityCounter::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/LuminosityCounter.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::LuminosityCounter m_lumiCount{this, "eventsByRun"};
/// };
/// ```
class LuminosityCounter final {
public:
LuminosityCounter() = default;
template <typename OWNER>
LuminosityCounter( OWNER* o, std::string name ) : m_monitoringHub{&o->serviceLocator()->monitoringHub()} {
m_monitoringHub->registerEntity( o->name(), std::move( name ), "LuminosityCounter", *this );
}
~LuminosityCounter() {
if ( m_monitoringHub ) m_monitoringHub->removeEntity( *this );
}
nlohmann::json toJSON() const { return *this; }
void reset() { m_counts.clear(); }
void inc( std::uint32_t run, std::size_t count = 1 ) {
std::lock_guard g{m_countsMutex};
m_counts[run] += count;
}
std::size_t get( std::uint32_t run ) const {
std::lock_guard g{m_countsMutex};
if ( auto it = m_counts.find( run ); it != m_counts.end() ) {
return it->second;
} else {
return 0;
}
}
bool empty() const {
std::lock_guard g{m_countsMutex};
return std::all_of( m_counts.begin(), m_counts.end(), []( const auto& item ) { return item.second == 0; } );
}
private:
std::map<std::uint32_t, std::size_t> m_counts;
+6
mutable std::mutex m_countsMutex;
Gaudi::Monitoring::Hub* m_monitoringHub{nullptr};
friend void to_json( nlohmann::json&, const LuminosityCounter& );
};
void to_json( nlohmann::json& j, const LuminosityCounter& c ) {
j["type"] = "LuminosityCounter";
j["empty"] = c.empty();
std::lock_guard g{c.m_countsMutex};
auto tmp = nlohmann::json::object();
for ( const auto [run, count] : c.m_counts ) { tmp.emplace( std::to_string( run ), count ); }
j["counts"] = std::move( tmp );
}
} // namespace LHCb
Loading