| The Gaudi Framework v29r0 (ff2e7097)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

CounterSvc.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // STD & SLT
3 // ============================================================================
4 #include <algorithm>
5 #include <functional>
6 #include <numeric>
7 #include <utility>
8 #include <vector>
9 // ============================================================================
10 // GaudiKernel
11 // ============================================================================
12 #include "GaudiKernel/HashMap.h"
13 #include "GaudiKernel/ICounterSvc.h"
14 #include "GaudiKernel/ISvcLocator.h"
15 #include "GaudiKernel/MsgStream.h"
16 #include "GaudiKernel/Service.h"
17 #include "GaudiKernel/Stat.h"
18 // ============================================================================
25 class CounterSvc : public extends<Service, ICounterSvc>
26 {
27 public:
28 // inherit constructor
29 using extends::extends;
31 ~CounterSvc() override { remove().ignore(); }
33 StatusCode finalize() override
34 {
35 if ( msgLevel( MSG::DEBUG ) || m_print ) {
36 print();
37 }
38 remove().ignore();
39 // finalize the base class
40 return Service::finalize();
41 }
42 // ==========================================================================
50 Counter* get( const std::string& group, const std::string& name ) const override;
52 ICounterSvc::Counters get( const std::string& group ) const override;
65 StatusCode create( const std::string& group, const std::string& name, longlong initial_value,
66 Counter*& refpCounter ) override;
78 CountObject create( const std::string& group, const std::string& name, longlong initial_value = 0 ) override;
88 StatusCode remove( const std::string& group, const std::string& name ) override;
94 StatusCode remove( const std::string& group ) override;
96 virtual StatusCode remove();
104 StatusCode print( const std::string& group, const std::string& name, Printout& printer ) const override;
112 StatusCode print( const std::string& group, Printout& printer ) const override;
119 StatusCode print( const Counter* pCounter, Printout& printer ) const override;
126 StatusCode print( const CountObject& pCounter, Printout& printer ) const override;
130 StatusCode print( Printout& printer ) const override;
132 StatusCode defaultPrintout( MsgStream& log, const Counter* pCounter ) const override;
133
134 private:
135 // find group/name for the counter:
136 inline std::pair<std::string, std::string> _find( const Counter* c ) const
137 {
138 if ( c ) {
139 for ( const auto& i : m_counts ) {
140 auto j = std::find_if( i.second.begin(), i.second.end(),
141 [&]( const NameMap::value_type& k ) { return k.second == c; } );
142 if ( j != i.second.end() ) return {i.first, j->first};
143 }
144 }
145 return {};
146 }
147 // get the overall number of counters
148 inline size_t num() const
149 {
150 return std::accumulate( m_counts.begin(), m_counts.end(), size_t{0}, []( size_t r, const CountMap::value_type& i ) {
151 return r + std::count_if( i.second.begin(), i.second.end(),
152 []( const NameMap::value_type& j ) -> bool { return j.second; } );
153 } );
154 }
155
156 public:
158 void print() const;
159
160 private:
161 typedef GaudiUtils::HashMap<std::string, Counter*> NameMap;
162 typedef GaudiUtils::HashMap<std::string, NameMap> CountMap;
163 // the actual map of counters
164 CountMap m_counts;
165
166 Gaudi::Property<bool> m_print{this, "PrintStat", true, "print statistics"};
167 Gaudi::Property<std::string> m_header{this, "StatTableHeader",
168 " Counter :: Group | # | sum | "
169 "mean/eff^* | rms/err^* | min | max |",
170 "the header row for the output Stat-table"};
171 Gaudi::Property<std::string> m_format1{
172 this, "RegularRowFormat",
173 " %|15.15s|%|-15.15s|%|32t||%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |",
174 "the format for the regular row in the output Stat-table"};
175 Gaudi::Property<std::string> m_format2{
176 this, "EfficiencyRowFormat",
177 "*%|15.15s|%|-15.15s|%|32t||%|10d| |%|11.5g| |(%|#9.7g| +- %|-#9.7g|)%%| ------- | ------- |",
178 "the format for the regular row in the outptu Stat-table"};
179 Gaudi::Property<bool> m_useEffFormat{this, "UseEfficiencyRowFormat", true,
180 "use the special format for printout of efficiency counters"};
181 };
182 // ===========================================================================
183 // Instantiation of a static factory class used by clients
184 // ===========================================================================
185 DECLARE_COMPONENT( CounterSvc )
186 // ===========================================================================
187 // Access a counter object by name and group
188 // ===========================================================================
189 CounterSvc::Counter* CounterSvc::get( const std::string& grp, const std::string& nam ) const
190 {
191 auto i = m_counts.find( grp );
192 if ( m_counts.end() == i ) {
193 return nullptr;
194 } // RETURN
195 auto j = i->second.find( nam );
196 if ( i->second.end() == j ) {
197 return nullptr;
198 } // RETURN
199 return j->second; // RETURN
200 }
201 // ===========================================================================
202 // get all counters form the given group:
203 // ===========================================================================
204 ICounterSvc::Counters CounterSvc::get( const std::string& group ) const
205 {
206 ICounterSvc::Counters result;
207 auto i = m_counts.find( group );
208 if ( i != m_counts.end() ) {
209 std::transform( i->second.begin(), i->second.end(), std::back_inserter( result ),
210 [&]( const NameMap::value_type& j ) {
211 return CountObject{j.second, i->first, j.first};
212 } );
213 }
214 return result;
215 }
216 // ===========================================================================
217 // Create/get a counter object.
218 // ===========================================================================
219 #ifdef __ICC
220 // disable icc remark #2259: non-pointer conversion from "longlong={long long}" to "double" may lose significant bits
221 #pragma warning( push )
222 #pragma warning( disable : 2259 )
223 #endif
224 StatusCode CounterSvc::create( const std::string& grp, const std::string& nam, longlong initial_value,
225 Counter*& refpCounter )
226 {
227 // try to find existing counter:
228 refpCounter = get( grp, nam );
229 if ( refpCounter ) {
230 return COUNTER_EXISTS;
231 } // RETURN
232 // create the new counter
233 auto newc = new Counter();
234 refpCounter = newc;
235 if ( 0 != initial_value ) {
236 refpCounter->addFlag( static_cast<double>( initial_value ) ); // icc remark #2259
237 }
238 // find a proper group
239 auto i = m_counts.find( grp );
240 // (create a group if needed)
241 if ( m_counts.end() == i ) {
242 i = m_counts.emplace( grp, NameMap() ).first;
243 }
244 // insert new counter with proper name into proper group:
245 i->second.emplace( nam, newc );
246 return StatusCode::SUCCESS; // RETURN
247 }
248 #ifdef __ICC
249 // re-enable icc remark #2259
250 #pragma warning( pop )
251 #endif
252 // ===========================================================================
253 // Create a new counter object. If the counter object exists already,
254 // ===========================================================================
255 CounterSvc::CountObject CounterSvc::create( const std::string& group, const std::string& name, longlong initial_value )
256 {
257 Counter* p = nullptr;
258 StatusCode sc = create( group, name, initial_value, p );
259 if ( sc.isSuccess() && p ) {
260 return CountObject( p, group, name );
261 }
262 throw std::runtime_error( "CounterSvc::Counter('" + group + "::" + name + "') exists already!" );
263 }
264 // ===========================================================================
265 // Remove a counter object. The tuple (group,name) identifies the counter uniquely
266 // ===========================================================================
267 StatusCode CounterSvc::remove( const std::string& grp, const std::string& nam )
268 {
269 auto i = m_counts.find( grp );
270 if ( m_counts.end() == i ) {
271 return COUNTER_NOT_PRESENT;
272 } // RETURN
273 auto j = i->second.find( nam );
274 if ( i->second.end() == j ) {
275 return COUNTER_NOT_PRESENT;
276 } // RETURN
277 delete j->second;
278 i->second.erase( j );
279 return StatusCode::SUCCESS;
280 }
281 // ===========================================================================
282 // Remove a group of counter objects.
283 // ===========================================================================
284 StatusCode CounterSvc::remove( const std::string& grp )
285 {
286 auto i = m_counts.find( grp );
287 if ( m_counts.end() == i ) {
288 return COUNTER_NOT_PRESENT;
289 } // RETURN
290 for ( auto& j : i->second ) delete j.second;
291 i->second.clear();
292 return StatusCode::SUCCESS;
293 }
294 // ===========================================================================
295 // Remove all known counter objects
296 // ===========================================================================
297 StatusCode CounterSvc::remove()
298 {
299 // remove group by group
300 for ( auto& i : m_counts ) remove( i.first ).ignore();
301 m_counts.clear();
302 return StatusCode::SUCCESS;
303 }
304 // ===========================================================================
305 // Print counter value
306 // ===========================================================================
307 StatusCode CounterSvc::print( const std::string& grp, const std::string& nam, Printout& printer ) const
308 {
309 const Counter* c = get( grp, nam );
310 if ( !c ) {
311 return COUNTER_NOT_PRESENT;
312 } // RETURN
313 // create the stream and use it!
314 return printer( msgStream(), c );
315 }
316
317 namespace
318 {
320 class conditionalPrint
321 {
322 private:
323 CounterSvc::Printout* printer;
324 MsgStream* log;
325
326 public:
327 conditionalPrint( CounterSvc::Printout& _p, MsgStream& _l ) : printer( &_p ), log( &_l ) {}
328 template <class Pair>
329 void operator()( const Pair& p )
330 {
331 if ( p.second ) {
332 ( *printer )( *log, p.second ).ignore();
333 }
334 }
335 };
336 }
337 // ===========================================================================
338 // Print the counter value for the whole group of counters
339 // ===========================================================================
340 StatusCode CounterSvc::print( const std::string& grp, Printout& printer ) const
341 {
342 auto i = m_counts.find( grp );
343 if ( m_counts.end() == i ) {
344 return COUNTER_NOT_PRESENT;
345 }
346
347 // Force printing in alphabetical order
348 std::map<std::string, Counter*> sorted_map( i->second.begin(), i->second.end() );
349 std::for_each( sorted_map.begin(), sorted_map.end(), conditionalPrint( printer, msgStream() ) );
350 return StatusCode::SUCCESS; // RETURN
351 }
352 // ===========================================================================
353 // Print counter value
354 // ===========================================================================
355 StatusCode CounterSvc::print( const Counter* pCounter, Printout& printer ) const
356 {
357 return printer( msgStream(), pCounter );
358 }
359 // ===========================================================================
360 // Print counter value
361 // ===========================================================================
362 StatusCode CounterSvc::print( const CountObject& refCounter, Printout& printer ) const
363 {
364 return print( refCounter.counter(), printer );
365 }
366 // ===========================================================================
367 // Print all known counters
368 // ===========================================================================
369 StatusCode CounterSvc::print( Printout& printer ) const
370 {
371 // Force printing in alphabetical order
372 std::map<std::pair<std::string, std::string>, Counter*> sorted_map;
373 for ( const auto& i : m_counts )
374 for ( const auto& j : i.second ) sorted_map[{i.first, j.first}] = j.second;
375 std::for_each( sorted_map.begin(), sorted_map.end(), conditionalPrint( printer, msgStream() ) );
376 return StatusCode::SUCCESS;
377 }
378 // ===========================================================================
379 // Print counter value
380 // ===========================================================================
381 StatusCode CounterSvc::defaultPrintout( MsgStream& log, const Counter* c ) const
382 {
383 if ( !c ) {
384 return StatusCode::FAILURE;
385 }
386 auto p = _find( c );
387
388 log << MSG::ALWAYS << CountObject( const_cast<Counter*>( c ), p.first, p.second ) << endmsg;
389
390 return StatusCode::SUCCESS;
391 }
392 // ===========================================================================
393 // "standard" printout a'la GaudiCommon
394 // ===========================================================================
395 void CounterSvc::print() const
396 {
397 // number of counters
398 const auto _num = num();
399 if ( 0 != _num ) {
400 always() << "Number of counters : " << _num << endmsg << m_header.value() << endmsg;
401 }
402 // Force printing in alphabetical order
403 std::map<std::pair<std::string, std::string>, Counter*> sorted_map;
404 for ( const auto& i : m_counts ) {
405 for ( const auto& j : i.second ) {
406 if ( j.second ) sorted_map[{i.first, j.first}] = j.second;
407 }
408 }
409 for ( const auto& i : sorted_map ) {
410 always() << Gaudi::Utils::formatAsTableRow( i.first.second, i.first.first, *i.second, m_useEffFormat, m_format1,
411 m_format2 )
412 << endmsg;
413 }
414 }
415 // ============================================================================
416
417 // ============================================================================
418 // The END
419 // ============================================================================
CounterSvc::m_useEffFormat
Gaudi::Property< bool > m_useEffFormat
Definition: CounterSvc.cpp:179
MsgStream
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode::SUCCESS
Definition: StatusCode.h:31
CounterSvc::remove
virtual StatusCode remove()
Remove all known counter objects.
Definition: CounterSvc.cpp:297
CounterSvc::m_print
Gaudi::Property< bool > m_print
Definition: CounterSvc.cpp:166
gaudirun.c
c
Definition: gaudirun.py:407
Service::name
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:289
StatusCode::FAILURE
Definition: StatusCode.h:31
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:174
Gaudi::Property
Implementation of property with value of concrete type.
Definition: Property.h:319
MsgStream.h
CounterSvc::NameMap
GaudiUtils::HashMap< std::string, Counter * > NameMap
Definition: CounterSvc.cpp:161
StatusCode::isSuccess
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:75
CounterSvc::m_format1
Gaudi::Property< std::string > m_format1
Definition: CounterSvc.cpp:171
MSG::DEBUG
Definition: IMessageSvc.h:16
CounterSvc::m_header
Gaudi::Property< std::string > m_header
Definition: CounterSvc.cpp:167
std
STL namespace.
std::map::end
T end(T...args)
CounterSvc
Simple implementation of the abstract interface ICounterSvc.
Definition: CounterSvc.cpp:25
HashMap.h
std::map
STL class.
CounterSvc::m_format2
Gaudi::Property< std::string > m_format2
Definition: CounterSvc.cpp:175
CounterSvc::defaultPrintout
StatusCode defaultPrintout(MsgStream &log, const Counter *pCounter) const override
Default Printout for counters.
Definition: CounterSvc.cpp:381
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:33
Gaudi::Utils::formatAsTableRow
GAUDI_API std::string formatAsTableRow(const StatEntity &counter, const bool flag, const std::string &format1=" |%|7d| |%|11.7g| |%|#11.5g| |%|#10.5g| |%|#10.5g| |%|#10.5g| |", const std::string &format2="*|%|7d| |%|11.5g| |(%|#9.7g| +- %|-#8.6g|)%%| ----- | ----- |")
print the counter in a form of the table row
Definition: StatEntity.cpp:305
std::string
STL class.
CounterSvc::create
StatusCode create(const std::string &group, const std::string &name, longlong initial_value, Counter *&refpCounter) override
Create a new counter object.
Definition: CounterSvc.cpp:224
Service.h
GaudiUtils::Map::end
iterator end()
Definition: Map.h:134
CounterSvc::CountMap
GaudiUtils::HashMap< std::string, NameMap > CountMap
Definition: CounterSvc.cpp:162
CounterSvc::print
void print() const
"standard" printout a&#39;la GaudiCommon
Definition: CounterSvc.cpp:395
__longlong
Definition: Kernel.h:56
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
CounterSvc::m_counts
CountMap m_counts
the actual map of counters
Definition: CounterSvc.cpp:164
std::runtime_error
STL class.
GaudiUtils::Map::find
iterator find(const key_type &key)
Definition: Map.h:151
GaudiPython.GaudiAlgs.Counter
Counter
Definition: GaudiAlgs.py:1620
GaudiUtils::Map::emplace
std::pair< iterator, bool > emplace(Args &&...args)
Definition: Map.h:169
CounterSvc::_find
std::pair< std::string, std::string > _find(const Counter *c) const
Definition: CounterSvc.cpp:136
std::count_if
T count_if(T...args)
GaudiUtils::Map::begin
iterator begin()
Definition: Map.h:133
std::pair< std::string, std::string >
std::find_if
T find_if(T...args)
std::vector
STL class.
Gaudi::Functional::operator()
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
extends
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
std::map::begin
T begin(T...args)
std::back_inserter
T back_inserter(T...args)
GaudiUtils::HashMap
Common class providing an architecture-independent hash map.
Definition: HashMap.h:74
CommonMessagingBase::msgStream
MsgStream & msgStream() const
Return an uninitialized MsgStream.
Definition: CommonMessaging.h:83
Stat.h
std::transform
T transform(T...args)
CounterSvc::get
Counter * get(const std::string &group, const std::string &name) const override
Access an existing counter object.
Definition: CounterSvc.cpp:189
std::accumulate
T accumulate(T...args)
CommonMessagingBase::msgLevel
MSG::Level msgLevel() const
get the output level from the embedded MsgStream
Definition: CommonMessaging.h:129
std::for_each
T for_each(T...args)
CommonMessagingBase::always
MsgStream & always() const
shortcut for the method msgStream(MSG::ALWAYS)
Definition: CommonMessaging.h:102
ICounterSvc.h
CounterSvc::num
size_t num() const
Definition: CounterSvc.cpp:148
ISvcLocator.h
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
CounterSvc::~CounterSvc
~CounterSvc() override
Standard destructor.
Definition: CounterSvc.cpp:31
Gaudi.Configuration.log
log
Definition: Configuration.py:13
CounterSvc::finalize
StatusCode finalize() override
Finalization.
Definition: CounterSvc.cpp:33