Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:30

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2023 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
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    * a Base class for Root related Sinks dealing with Histograms.
0025    *
0026    * provides the common method plus a generic way of registering handler for different types
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     Base( std::string name, ISvcLocator* svcloc ) : Monitoring::BaseSink( name, svcloc ) {
0035       // only deal with histograms
0036       setProperty( "TypesToSave", std::vector<std::string>{ "histogram:.*" } )
0037           .orThrow( "Unable to set typesToSaveProperty", "Histograming::Sink::Base" );
0038     }
0039 
0040     StatusCode initialize() override {
0041       return BaseSink::initialize().andThen( [&] {
0042         // empty output file if it exists, as we will update it at the end
0043         // This allows multiple Sinks to write to the same ROOT file
0044         std::filesystem::remove( m_fileName.value() );
0045         info() << "Writing ROOT histograms to: " << m_fileName.value() << endmsg;
0046       } );
0047     }
0048 
0049     void flush( bool ) override {
0050       // File is updated so that multiple sinks can write to the same file
0051       // As we are in stop, there is no multithreading so it is safe
0052       // As we dropped the file at initialization, no old data from a previous
0053       // run may be mixed with new one
0054       TFile histoFile( m_fileName.value().c_str(), "UPDATE" );
0055       // get all entities, sorted by component and name
0056       applyToAllSortedEntities(
0057           [this, &histoFile]( std::string const& component, std::string const& name, nlohmann::json const& j ) {
0058             auto dim  = j.at( "dimension" ).template get<unsigned int>();
0059             auto type = j.at( "type" ).template get<std::string>();
0060             // cut type after last ':' if there is one. The rest is precision parameter that we do not need here
0061             // as ROOT anyway treats everything as doubles in histograms
0062             type       = type.substr( 0, type.find_last_of( ':' ) );
0063             auto saver = m_registry.find( { type, dim } );
0064             if ( saver != m_registry.end() ) ( saver->second )( histoFile, component, name, j );
0065           } );
0066       info() << "Completed update of ROOT histograms in: " << m_fileName.value() << endmsg;
0067     }
0068 
0069     void registerHandler( HistoIdentification const& id, HistoHandler const& func ) {
0070       m_registry.emplace( std::piecewise_construct, std::make_tuple( id ), std::make_tuple( func ) );
0071     }
0072 
0073   private:
0074     /// map of supported type and the way to handle them
0075     HistoRegistry m_registry{};
0076 
0077     Gaudi::Property<std::string> m_fileName{ this, "FileName", "testHisto.root",
0078                                              "Name of file where to save histograms" };
0079   };
0080 
0081 } // namespace Gaudi::Histograming::Sink