The Gaudi Framework  master (37c0b60a)
Base.h
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 
12 #include <Gaudi/BaseSink.h>
13 #include <Gaudi/MonitoringHub.h>
14 #include <TFile.h>
15 #include <filesystem>
16 #include <map>
17 #include <nlohmann/json.hpp>
18 #include <string>
19 #include <vector>
20 
21 namespace Gaudi::Histograming::Sink {
22 
23  /*
24  * a Base class for Root related Sinks dealing with Histograms.
25  *
26  * provides the common method plus a generic way of registering handler for different types
27  */
28  class Base : public Monitoring::BaseSink {
29  public:
31  using HistoHandler = std::function<void( TFile& file, std::string, std::string, nlohmann::json const& )>;
33 
36  std::function<void( TFile& file, std::string, std::string, Monitoring::Hub::Entity const& )>;
38 
39  Base( const std::string& name, ISvcLocator* svcloc ) : Monitoring::BaseSink( name, svcloc ) {
40  // only deal with histograms
41  setProperty( "TypesToSave", std::vector<std::string>{ "histogram:.*" } )
42  .orThrow( "Unable to set typesToSaveProperty", "Histograming::Sink::Base" );
43  }
44 
45  StatusCode initialize() override {
46  return BaseSink::initialize().andThen( [&] {
47  // empty output file if it exists, as we will update it at the end
48  // This allows multiple Sinks to write to the same ROOT file
49  std::filesystem::remove( m_fileName.value() );
50  info() << "Writing ROOT histograms to: " << m_fileName.value() << endmsg;
51  } );
52  }
53 
54  void flush( bool ) override {
55  // File is updated so that multiple sinks can write to the same file
56  // As we are in stop, there is no multithreading so it is safe
57  // As we dropped the file at initialization, no old data from a previous
58  // run may be mixed with new one
59  TFile histoFile( m_fileName.value().c_str(), "UPDATE" );
60  // get all entities, sorted by component and name
61  applyToAllSortedEntities( [this, &histoFile]( std::string const& component, std::string const& name,
62  Monitoring::Hub::Entity const& ent ) {
63  // try first a dedicated flush, bypassing json (more efficient)
64  auto typeIndex = ent.typeIndex();
65  auto binSaver = m_binRegistry.find( typeIndex );
66  if ( binSaver != m_binRegistry.end() ) {
67  binSaver->second( histoFile, component, name, ent );
68  return;
69  }
70  // no fast track, let's use json intermediate format
71  nlohmann::json j = ent;
72  auto dim = j.at( "dimension" ).template get<unsigned int>();
73  auto type = j.at( "type" ).template get<std::string>();
74  // cut type after last ':' if there is one. The rest is precision parameter that we do not need here
75  // as ROOT anyway treats everything as doubles in histograms
76  type = type.substr( 0, type.find_last_of( ':' ) );
77  auto saver = m_registry.find( { type, dim } );
78  if ( saver != m_registry.end() ) ( saver->second )( histoFile, component, name, j );
79  } );
80  info() << "Completed update of ROOT histograms in: " << m_fileName.value() << endmsg;
81  }
82 
84  m_binRegistry.emplace( std::piecewise_construct, std::make_tuple( id ), std::make_tuple( func ) );
85  }
86 
88  m_registry.emplace( std::piecewise_construct, std::make_tuple( id ), std::make_tuple( func ) );
89  }
90 
91  private:
96 
97  Gaudi::Property<std::string> m_fileName{ this, "FileName", "testHisto.root",
98  "Name of file where to save histograms" };
99  };
100 
101 } // namespace Gaudi::Histograming::Sink
Gaudi::Histograming::Sink::Base::m_fileName
Gaudi::Property< std::string > m_fileName
Definition: Base.h:97
Gaudi::Monitoring::BaseSink
Base class for all Sinks registering to the Monitoring Hub Should be extended by actual Sinks.
Definition: BaseSink.h:40
std::make_tuple
T make_tuple(T... args)
std::string
STL class.
StatusCode::andThen
StatusCode andThen(F &&f, ARGS &&... args) const
Chain code blocks making the execution conditional a success result.
Definition: StatusCode.h:163
MonitoringHub.h
std::pair
std::vector< std::string >
std::map::find
T find(T... args)
PropertyHolder< CommonMessaging< implements< IService, IProperty, IStateful > > >::setProperty
StatusCode setProperty(const Gaudi::Details::PropertyBase &p)
Set the property from a property.
Definition: IProperty.h:39
ISvcLocator
Definition: ISvcLocator.h:46
jsonFromLHCbLog.json
json
Definition: jsonFromLHCbLog.py:86
std::map::emplace
T emplace(T... args)
std::type_index
Gaudi::Histograming::Sink::Base::initialize
StatusCode initialize() override
Definition: Base.h:45
Gaudi::Histograming::Sink::Base::flush
void flush(bool) override
pure virtual method to be defined by children and responsible for flushing current data of the Sink.
Definition: Base.h:54
std::function
Service::name
const std::string & name() const override
Retrieve name of the service
Definition: Service.cpp:332
StatusCode
Definition: StatusCode.h:65
cpluginsvc.func
func
Definition: cpluginsvc.py:235
Gaudi::Histograming::Sink::Base::registerHandler
void registerHandler(HistoBinIdentification const &id, HistoBinHandler const &func)
Definition: Base.h:83
ProduceConsume.j
j
Definition: ProduceConsume.py:104
Gaudi::Histograming::Sink
Definition: RootHistogramSink.cpp:23
Gaudi::Histograming::Sink::Base::registerHandler
void registerHandler(HistoIdentification const &id, HistoHandler const &func)
Definition: Base.h:87
Gaudi::Property::value
const ValueType & value() const
Definition: Property.h:237
Gaudi::Monitoring::Hub::Entity::typeIndex
std::type_index typeIndex() const
function to get internal type
Definition: MonitoringHub.h:90
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
Gaudi::Monitoring::BaseSink::applyToAllSortedEntities
void applyToAllSortedEntities(Callable func) const
applies a callable to all monitoring entities ordered by component the callable will be called once p...
Definition: BaseSink.h:110
std::map< HistoIdentification, HistoHandler >
Gaudi::Histograming::Sink::Base::m_registry
HistoRegistry m_registry
map of supported type and the way to handle them
Definition: Base.h:95
gaudirun.type
type
Definition: gaudirun.py:160
Gaudi::Histograming::Sink::Base
Definition: Base.h:28
BaseSink.h
std::map::end
T end(T... args)
Gaudi::Monitoring::Hub::Entity
Wrapper class for arbitrary monitoring objects.
Definition: MonitoringHub.h:65
Gaudi::Histograming::Sink::Base::m_binRegistry
HistoBinRegistry m_binRegistry
map of supported type and the way to handle them
Definition: Base.h:93
Gaudi::Property< std::string >
Gaudi::Histograming::Sink::Base::Base
Base(const std::string &name, ISvcLocator *svcloc)
Definition: Base.h:39