File indexing completed on 2025-07-02 08:34:39
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <Gaudi/BaseSink.h>
0013 #include <Gaudi/MonitoringHub.h>
0014 #include <TFile.h>
0015 #include <filesystem>
0016 #include <map>
0017 #include <nlohmann/json.hpp>
0018 #include <string>
0019 #include <vector>
0020
0021 namespace Gaudi::Histograming::Sink {
0022
0023
0024
0025
0026
0027
0028 class Base : public Monitoring::BaseSink {
0029 public:
0030 using HistoIdentification = std::pair<std::string, int>;
0031 using HistoHandler = std::function<void( TFile& file, std::string, std::string, nlohmann::json const& )>;
0032 using HistoRegistry = std::map<HistoIdentification, HistoHandler>;
0033
0034 using HistoBinIdentification = std::type_index;
0035 using HistoBinHandler =
0036 std::function<void( TFile& file, std::string, std::string, Monitoring::Hub::Entity const& )>;
0037 using HistoBinRegistry = std::map<HistoBinIdentification, HistoBinHandler>;
0038
0039 Base( std::string name, ISvcLocator* svcloc ) : Monitoring::BaseSink( name, svcloc ) {
0040
0041 setProperty( "TypesToSave", std::vector<std::string>{ "histogram:.*" } )
0042 .orThrow( "Unable to set typesToSaveProperty", "Histograming::Sink::Base" );
0043 }
0044
0045 StatusCode initialize() override {
0046 return BaseSink::initialize().andThen( [&] {
0047
0048
0049 std::filesystem::remove( m_fileName.value() );
0050 info() << "Writing ROOT histograms to: " << m_fileName.value() << endmsg;
0051 } );
0052 }
0053
0054 void flush( bool ) override {
0055
0056
0057
0058
0059 TFile histoFile( m_fileName.value().c_str(), "UPDATE" );
0060
0061 applyToAllSortedEntities( [this, &histoFile]( std::string const& component, std::string const& name,
0062 Monitoring::Hub::Entity const& ent ) {
0063
0064 auto typeIndex = ent.typeIndex();
0065 auto binSaver = m_binRegistry.find( typeIndex );
0066 if ( binSaver != m_binRegistry.end() ) {
0067 binSaver->second( histoFile, component, name, ent );
0068 return;
0069 }
0070
0071 nlohmann::json j = ent;
0072 auto dim = j.at( "dimension" ).template get<unsigned int>();
0073 auto type = j.at( "type" ).template get<std::string>();
0074
0075
0076 type = type.substr( 0, type.find_last_of( ':' ) );
0077 auto saver = m_registry.find( { type, dim } );
0078 if ( saver != m_registry.end() ) ( saver->second )( histoFile, component, name, j );
0079 } );
0080 info() << "Completed update of ROOT histograms in: " << m_fileName.value() << endmsg;
0081 }
0082
0083 void registerHandler( HistoBinIdentification const& id, HistoBinHandler const& func ) {
0084 m_binRegistry.emplace( std::piecewise_construct, std::make_tuple( id ), std::make_tuple( func ) );
0085 }
0086
0087 void registerHandler( HistoIdentification const& id, HistoHandler const& func ) {
0088 m_registry.emplace( std::piecewise_construct, std::make_tuple( id ), std::make_tuple( func ) );
0089 }
0090
0091 private:
0092
0093 HistoBinRegistry m_binRegistry{};
0094
0095 HistoRegistry m_registry{};
0096
0097 Gaudi::Property<std::string> m_fileName{ this, "FileName", "testHisto.root",
0098 "Name of file where to save histograms" };
0099 };
0100
0101 }