16#include <boost/algorithm/string.hpp>
18#include <fmt/format.h>
35 static const auto registry = std::map<std::string_view, std::string_view>{
36 {
"counter",
"{0:nEntries|10d}" },
37 {
"counter:AveragingCounter",
"{0:nEntries|10d} |{0:sum|11.7g} |{0:mean|#11.5g}" },
38 {
"counter:SigmaCounter",
"{0:nEntries|10d} |{0:sum|11.7g} |{0:mean|#11.5g} |{0:standard_deviation|#11.5g}" },
39 {
"counter:StatCounter",
"{0:nEntries|10d} |{0:sum|11.7g} |{0:mean|#11.5g} |{0:standard_deviation|#11.5g} "
40 "|{0:min|#12.5g} |{0:max|#12.5g}" },
41 {
"counter:BinomialCounter",
42 "{0:nEntries|10d} |{0:nTrueEntries|11d} |({0:efficiency|#9.7p} +- {0:efficiencyErr|-#8.7p})%" },
48 using HistoBinHandler =
49 std::pair<
unsigned int,
56 std::map<std::type_index, HistoBinHandler>
const binRegistry = {
57 { std::type_index(
typeid( Acc::StaticProfileHistogram<1u, Acc::atomicity::full, double> ) ),
59 { std::type_index(
typeid( Acc::StaticProfileHistogram<1u, Acc::atomicity::none, double> ) ),
61 { std::type_index(
typeid( Acc::StaticProfileHistogram<1u, Acc::atomicity::full, float> ) ),
63 { std::type_index(
typeid( Acc::StaticProfileHistogram<1u, Acc::atomicity::none, float> ) ),
65 { std::type_index(
typeid( Acc::StaticProfileHistogram<2u, Acc::atomicity::full, double> ) ),
67 { std::type_index(
typeid( Acc::StaticProfileHistogram<2u, Acc::atomicity::none, double> ) ),
69 { std::type_index(
typeid( Acc::StaticProfileHistogram<2u, Acc::atomicity::full, float> ) ),
71 { std::type_index(
typeid( Acc::StaticProfileHistogram<2u, Acc::atomicity::none, float> ) ),
73 { std::type_index(
typeid( Acc::StaticProfileHistogram<3u, Acc::atomicity::full, double> ) ),
75 { std::type_index(
typeid( Acc::StaticProfileHistogram<3u, Acc::atomicity::none, double> ) ),
77 { std::type_index(
typeid( Acc::StaticProfileHistogram<3u, Acc::atomicity::full, float> ) ),
79 { std::type_index(
typeid( Acc::StaticProfileHistogram<3u, Acc::atomicity::none, float> ) ),
86 json_fmt_arg(
const nlohmann::json& j ) : payload{ j } {}
87 const nlohmann::json& payload;
102class fmt::formatter<json_fmt_arg> {
104 template <
typename ParseContext>
105 constexpr auto parse( ParseContext& ctx ) {
106 auto fmt_begin = ctx.begin();
107 auto fmt_end = std::find( fmt_begin, ctx.end(),
'}' );
108 if ( fmt_begin == fmt_end ) {
113 auto fmt_colon = std::find( fmt_begin, fmt_end,
'|' );
114 currentName = std::string( fmt_begin, fmt_colon - fmt_begin );
115 currentFormat = std::string( fmt_colon + 1, fmt_end - fmt_colon - 1 );
119 template <
typename FormatContext>
120 auto format(
const json_fmt_arg& json_arg, FormatContext& ctx )
const {
121 const auto& j = json_arg.payload;
124 const auto type = j.at(
"type" ).get<std::string>();
126 std::string_view type_key{ type };
128 auto entry = registry.find( type_key );
130 auto sep = type_key.rfind(
':' );
131 while ( sep != type_key.npos && entry == registry.end() ) {
133 type_key.remove_suffix( type_key.size() - sep );
135 sep = type_key.rfind(
':' );
137 entry = registry.find( type_key );
140 if ( entry == registry.end() ) entry = registry.find(
"counter" );
141 assert( entry != registry.end() );
144 return fmt::format_to( ctx.out(), fmt::runtime( entry->second ), json_arg );
150 return fmt::format_to( ctx.out(), fmt::runtime( actualFormat ),
151 j.at(
currentName ).template get<unsigned int>() );
153 return fmt::format_to( ctx.out(), fmt::runtime( actualFormat ), j.at(
currentName ).template get<double>() );
155 actualFormat[actualFormat.size() - 2] =
'g';
156 return fmt::format_to( ctx.out(), fmt::runtime( actualFormat ),
157 j.at(
currentName ).template get<double>() * 100 );
159 return fmt::format_to( ctx.out(),
"Unknown counter format : {}",
currentFormat );
171 void printCounter( std::ostringstream& log, std::string_view
id,
const nlohmann::json& j ) {
172 const auto type = j.at(
"type" ).get<std::string>();
175 if ( type ==
"statentity" ) {
176 using boost::algorithm::icontains;
177 bool isBinomial = icontains(
id,
"eff" ) || icontains(
id,
"acc" ) || icontains(
id,
"filt" ) ||
178 icontains(
id,
"fltr" ) || icontains(
id,
"pass" );
180 nj[
"type"] = isBinomial ?
"counter:BinomialCounter" :
"counter:StatCounter";
181 return printCounter( log,
id, nj );
186 log << fmt::format( fmt::runtime(
" |{}{:48}|{} |" ),
187 ( std::string_view{ type }.substr( 0, 23 ) ==
"counter:BinomialCounter" ?
'*' :
' ' ),
188 fmt::format( fmt::runtime(
"\"{}\"" ),
id ), json_fmt_arg{ j } );
205 setProperty(
"TypesToSave", std::vector<std::string>{
"counter:.*",
"statentity",
"histogram:.*" } )
206 .orThrow(
"Unable to set TypesToSave property",
"Gaudi::Monitoring::MessageSvcSink" );
208 setProperty(
"ComponentsToSave", std::vector<std::string>{
"^.+$" } )
209 .orThrow(
"Unable to set ComponentsToSave property",
"Gaudi::Monitoring::MessageSvcSink" );
212 void flush(
bool )
override;
214 "length of histograms names and titles in the output" };
221 std::string curAlgo =
"";
225 std::array<std::ostringstream, 7> curLog;
228 std::array<unsigned int, 7> nbNonEmptyEntities{};
229 auto dumpAlgoCounters = [&]() {
232 if ( nbNonEmptyEntities[0] > 0 ) {
233 log <<
MSG::INFO <<
"Number of counters : " << nbNonEmptyEntities[0] <<
"\n"
234 <<
" | Counter | # | "
235 <<
" sum | mean/eff^* | rms/err^* | min | max |";
236 log << curLog[0].str() <<
endmsg;
239 unsigned int nHistos = nbNonEmptyEntities[1] + nbNonEmptyEntities[2] + nbNonEmptyEntities[3] +
240 nbNonEmptyEntities[4] + nbNonEmptyEntities[5] + nbNonEmptyEntities[6];
242 log <<
MSG::INFO <<
"Booked " << nHistos <<
" Histogram(s) : 1D=" << nbNonEmptyEntities[1]
243 <<
" 2D=" << nbNonEmptyEntities[2] <<
" 3D=" << nbNonEmptyEntities[3] <<
" 1DProf=" << nbNonEmptyEntities[4]
244 <<
" 2DProf=" << nbNonEmptyEntities[5] <<
" 3DProf=" << nbNonEmptyEntities[6] <<
endmsg;
245 if ( nbNonEmptyEntities[1] > 0 ) {
246 log <<
MSG::INFO <<
"1D histograms in directory \"" << curAlgo <<
"\" : " << nbNonEmptyEntities[1] <<
"\n"
249 " | {:{}s} | {:{}s} | # | Mean | RMS | Skewness | Kurtosis |" ),
251 << curLog[1].str() <<
endmsg;
253 if ( nbNonEmptyEntities[2] > 0 ) {
254 log <<
MSG::INFO <<
"2D histograms in directory \"" << curAlgo <<
"\" : " << nbNonEmptyEntities[2]
255 << curLog[2].str() <<
endmsg;
257 if ( nbNonEmptyEntities[3] > 0 ) {
258 log <<
MSG::INFO <<
"3D histograms in directory \"" << curAlgo <<
"\" : " << nbNonEmptyEntities[3]
259 << curLog[3].str() <<
endmsg;
261 if ( nbNonEmptyEntities[4] > 0 ) {
262 log <<
MSG::INFO <<
"1D profile histograms in directory \"" << curAlgo <<
"\" : " << nbNonEmptyEntities[4]
266 " | {:{}s} | {:{}s} | # | Mean | RMS | Skewness | Kurtosis |" ),
268 << curLog[4].str() <<
endmsg;
270 if ( nbNonEmptyEntities[5] > 0 ) {
271 log <<
MSG::INFO <<
"2D profile histograms in directory \"" << curAlgo <<
"\" : " << nbNonEmptyEntities[5]
272 << curLog[5].str() <<
endmsg;
274 if ( nbNonEmptyEntities[6] > 0 ) {
275 log <<
MSG::INFO <<
"3D profile histograms in directory \"" << curAlgo <<
"\" : " << nbNonEmptyEntities[6]
276 << curLog[6].str() <<
endmsg;
283 if ( algo != curAlgo ) {
286 nbNonEmptyEntities = { 0, 0, 0, 0, 0, 0, 0 };
287 curLog = { std::ostringstream{}, std::ostringstream{}, std::ostringstream{}, std::ostringstream{},
288 std::ostringstream{}, std::ostringstream{}, std::ostringstream{} };
292 auto binWriter = binRegistry.find( typeIndex );
293 if ( binWriter != binRegistry.end() ) {
294 auto index = binWriter->second.first;
295 ++nbNonEmptyEntities[index];
297 if ( logLine.size() > 0 ) { curLog[index] <<
"\n" << logLine; }
300 nlohmann::json
const j = ent;
302 const auto type = j.at(
"type" ).get<std::string>();
303 if ( type.find(
"histogram" ) == 0 ) {
304 if ( !j.at(
"empty" ).template get<bool>() ) {
305 unsigned int d = j.at(
"dimension" ).get<
int>();
306 auto subtype = std::string_view( type ).substr( 10 );
307 bool isProfile = subtype.substr( 0, 15 ) ==
"WeightedProfile" || subtype.substr( 0, 7 ) ==
"Profile";
308 unsigned int index = ( isProfile ? 3 : 0 ) + d;
309 auto title = j.at(
"title" ).get<std::string>();
310 std::string logLine{
"" };
322 if ( logLine.size() > 0 ) {
323 curLog[index] <<
"\n" << logLine;
324 ++nbNonEmptyEntities[index];
329 if ( !j.at(
"empty" ).template get<bool>() ) {
330 ++nbNonEmptyEntities[0];
332 printCounter( curLog[0],
name, j );
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
#define DECLARE_COMPONENT(type)
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
Base class for all Sinks registering to the Monitoring Hub Should be extended by actual Sinks.
void applyToAllSortedEntities(Callable func) const
applies a callable to all monitoring entities ordered by component the callable will be called once p...
Wrapper class for arbitrary monitoring objects.
std::type_index typeIndex() const
function to get internal type
Implementation of property with value of concrete type.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition of the MsgStream class used to transmit messages.
StatusCode setProperty(const Gaudi::Details::PropertyBase &p)
const std::string & name() const override
Retrieve name of the service.
Efficient counter implementations for Gaudi.
std::string printProfileHisto3D(std::string_view name, Gaudi::Monitoring::Hub::Entity const &ent, unsigned int stringsWidth=45)
std::string printProfileHisto1D(std::string_view name, Gaudi::Monitoring::Hub::Entity const &ent, unsigned int stringsWidth=45)
std::string printHistogram1D(std::string_view type, std::string_view name, std::string_view title, const nlohmann::json &j, unsigned int stringsWidth=45)
std::string printHistogram2D(std::string_view type, std::string_view name, std::string_view title, const nlohmann::json &j, unsigned int stringsWidth=45)
std::string printHistogram3D(std::string_view type, std::string_view name, std::string_view title, const nlohmann::json &j, unsigned int stringsWidth=45)
std::string printProfileHisto2D(std::string_view name, Gaudi::Monitoring::Hub::Entity const &ent, unsigned int stringsWidth=45)
void flush(bool) override
stop method, handles the printing
Gaudi::Property< unsigned int > m_histoStringsWidth
MessageSvcSink(const std::string &name, ISvcLocator *svcloc)