All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
CounterSvc.cpp
Go to the documentation of this file.
1 // ============================================================================
2 // STD & SLT
3 // ============================================================================
4 #include <utility>
5 #include <vector>
6 #include <algorithm>
7 #include <functional>
8 // ============================================================================
9 // GaudiKernel
10 // ============================================================================
13 #include "GaudiKernel/MsgStream.h"
14 #include "GaudiKernel/Service.h"
15 #include "GaudiKernel/HashMap.h"
16 // ============================================================================
23 class CounterSvc: public extends1<Service, ICounterSvc> {
24 public:
26  CounterSvc ( const std::string& name ,
27  ISvcLocator* svcLoc )
28  : base_class(name, svcLoc)
29  , m_counts ()
30  , m_print ( true )
31  //
32  // the header row
33  , m_header ( " Counter :: Group | # | sum | mean/eff^* | rms/err^* | min | max |")
34  // format for regular statistical printout rows
35  , m_format1 ( " %|15.15s|%|-15.15s|%|32t||%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" )
36  // format for "efficiency" statistical printout rows
37  , m_format2 ( "*%|15.15s|%|-15.15s|%|32t||%|10d| |%|11.5g| |(%|#9.7g| +- %|-#9.7g|)%%| ------- | ------- |" )
38  // flag to use the special "efficiency" format
39  , m_useEffFormat ( true )
40  //
41  {
42  declareProperty ("PrintStat" , m_print ) ;
43  //
45  ( "StatTableHeader" , m_header ,
46  "The header row for the output Stat-table" ) ;
47  //
49  ( "RegularRowFormat" , m_format1 ,
50  "The format for the regular row in the output Stat-table" ) ;
51  //
53  ( "EfficiencyRowFormat" , m_format2 ,
54  "The format for the regular row in the outptu Stat-table" ) ;
55  //
57  ( "UseEfficiencyRowFormat" , m_useEffFormat ,
58  "Use the special format for printout of efficiency counters" ) ;
59  }
61  virtual ~CounterSvc() { remove().ignore() ; }
63  virtual StatusCode finalize()
64  {
65  if ( outputLevel() <= MSG::DEBUG || m_print ) { print () ; }
66  remove().ignore() ;
67  // finalize the base class
68  return Service::finalize() ;
69  }
70  // ==========================================================================
78  virtual Counter* get
79  ( const std::string& group ,
80  const std::string& name ) const;
82  virtual ICounterSvc::Counters get ( const std::string& group ) const ;
95  virtual StatusCode create
96  ( const std::string& group ,
97  const std::string& name ,
98  longlong initial_value ,
99  Counter*& refpCounter ) ;
111  virtual CountObject create
112  ( const std::string& group ,
113  const std::string& name ,
114  longlong initial_value = 0 ) ;
124  virtual StatusCode remove
125  ( const std::string& group ,
126  const std::string& name ) ;
132  virtual StatusCode remove
133  ( const std::string& group ) ;
135  virtual StatusCode remove();
143  virtual StatusCode print
144  ( const std::string& group,
145  const std::string& name,
146  Printout& printer) const;
154  virtual StatusCode print
155  (const std::string& group,
156  Printout& printer) const;
163  virtual StatusCode print
164  ( const Counter* pCounter,
165  Printout& printer) const;
172  virtual StatusCode print
173  ( const CountObject& pCounter,
174  Printout& printer) const;
178  virtual StatusCode print(Printout& printer) const;
181  ( MsgStream& log,
182  const Counter* pCounter) const ;
183 private:
184  // find group/name for the counter:
185  inline std::pair<std::string,std::string> _find ( const Counter* c ) const
186  {
187  if ( 0 == c ) { return std::pair<std::string,std::string>() ; }
188  for ( CountMap::const_iterator i = m_counts.begin() ; m_counts.end() != i ; ++i )
189  {
190  for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
191  { if ( j->second == c ) { return std::make_pair( i->first , j->first ) ; } }
192  }
193  return std::pair<std::string,std::string>() ;
194  }
195  // get the overall number of counters
196  inline size_t num () const
197  {
198  size_t result = 0 ;
199  {
200  for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i )
201  {
202  for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
203  { if ( 0 != j->second ) { ++result ; } ; }
204  }
205  }
206  return result ;
207  }
208 public:
210  void print () const ;
211 private:
214  // the actual map of counters
216  // boolean flag to print statistics
217  bool m_print ;
218  // the header row
219  std::string m_header ;
220  // format for regular statistical printout rows
221  std::string m_format1 ;
222  // format for "efficiency" statistical printout rows
223  std::string m_format2 ;
224  // flag to use the special "efficiency" format
226 } ;
227 // ===========================================================================
228 // Instantiation of a static factory class used by clients
229 // ===========================================================================
231 // ===========================================================================
232 // Access a counter object by name and group
233 // ===========================================================================
234 CounterSvc::Counter* CounterSvc::get
235 ( const std::string& grp ,
236  const std::string& nam ) const
237 {
238  CountMap::const_iterator i = m_counts.find ( grp ) ;
239  if ( m_counts.end() == i ) { return 0 ; } // RETURN
240  NameMap::const_iterator j = i->second.find ( nam ) ;
241  if ( i->second.end() == j ) { return 0 ; } // RETURN
242  return j->second ; // RETURN
243 }
244 // ===========================================================================
245 // get all counters form the given group:
246 // ===========================================================================
247 ICounterSvc::Counters CounterSvc::get ( const std::string& group ) const
248 {
249  ICounterSvc::Counters result ;
251  if ( m_counts.end() == i ) { return result ; } // RETURN
252  for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
253  { result.push_back( CountObject ( j->second, i->first , j->first ) ) ; }
254  return result ;
255 }
256 // ===========================================================================
257 // Create/get a counter object.
258 // ===========================================================================
259 #ifdef __ICC
260 // disable icc remark #2259: non-pointer conversion from "longlong={long long}" to "double" may lose significant bits
261 #pragma warning(push)
262 #pragma warning(disable:2259)
263 #endif
265 ( const std::string& grp ,
266  const std::string& nam ,
267  longlong initial_value ,
268  Counter*& refpCounter )
269 {
270  // try to find existing counter:
271  refpCounter = get ( grp , nam ) ;
272  if ( 0 != refpCounter ) { return COUNTER_EXISTS ; } // RETURN
273  // create the new counter
274  Counter* newc = new Counter() ;
275  refpCounter = newc ;
276  if ( 0 != initial_value ) {
277  refpCounter->addFlag ( static_cast<double>(initial_value) ) ; // icc remark #2259
278  }
279  // find a proper group
280  CountMap::iterator i = m_counts.find ( grp ) ;
281  // (create a group if needed)
282  if ( m_counts.end() == i )
283  { i = m_counts.insert ( std::make_pair ( grp , NameMap() ) ).first ; }
284  // insert new counter with proper name into proper group:
285  i->second.insert( std::make_pair( nam , newc ) );
286  return StatusCode::SUCCESS ; // RETURN
287 }
288 #ifdef __ICC
289 // re-enable icc remark #2259
290 #pragma warning(pop)
291 #endif
292 // ===========================================================================
293 // Create a new counter object. If the counter object exists already,
294 // ===========================================================================
296 ( const std::string& group ,
297  const std::string& name ,
298  longlong initial_value )
299 {
300  Counter* p = 0;
301  StatusCode sc = create ( group, name, initial_value, p ) ;
302  if ( sc.isSuccess() && 0 != p ) { return CountObject ( p , group , name ) ; }
303  throw std::runtime_error("CounterSvc::Counter('"+group+"::"+name+"') exists already!");
304 }
305 // ===========================================================================
306 // Remove a counter object. The tuple (group,name) identifies the counter uniquely
307 // ===========================================================================
309 ( const std::string& grp ,
310  const std::string& nam )
311 {
312  CountMap::iterator i = m_counts.find ( grp ) ;
313  if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; } // RETURN
314  NameMap::iterator j = i->second.find ( nam ) ;
315  if ( i->second.end() == j ) { return COUNTER_NOT_PRESENT ; } // RETURN
316  delete j->second ;
317  i->second.erase ( j ) ;
318  return StatusCode::SUCCESS ;
319 }
320 // ===========================================================================
321 // Remove a group of counter objects.
322 // ===========================================================================
323 StatusCode CounterSvc::remove ( const std::string& grp )
324 {
325  CountMap::iterator i = m_counts.find ( grp ) ;
326  if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; } // RETURN
327  for ( NameMap::iterator j = i->second.begin() ; i->second.end() != j ; ++j )
328  { delete j->second ; }
329  i->second.clear() ;
330  return StatusCode::SUCCESS ;
331 }
332 // ===========================================================================
333 // Remove all known counter objects
334 // ===========================================================================
336 {
337  // remove group by group
338  for ( CountMap::iterator i = m_counts.begin() ; m_counts.end() != i ; ++i )
339  { remove ( i->first ).ignore () ; }
340  m_counts.clear() ;
341  return StatusCode::SUCCESS;
342 }
343 // ===========================================================================
344 // Print counter value
345 // ===========================================================================
347 ( const std::string& grp,
348  const std::string& nam,
349  Printout& printer) const
350 {
351  const Counter* c = get( grp , nam ) ;
352  if ( 0 == c ) { return COUNTER_NOT_PRESENT ; } // RETURN
353  // create the stream and use it!
354  MsgStream log ( msgSvc() , name() ) ;
355  return printer ( log , c ) ;
356 }
357 
358 namespace {
360  class conditionalPrint {
361  private:
362  CounterSvc::Printout *printer;
363  MsgStream *log;
364  public:
365  conditionalPrint(CounterSvc::Printout &_p, MsgStream &_l): printer(&_p), log(&_l) {}
366  template<class Pair>
367  void operator() (const Pair &p) {
368  if (p.second) {
369  (*printer)(*log, p.second).ignore();
370  }
371  }
372  };
373 }
374 // ===========================================================================
375 // Print the counter value for the whole group of counters
376 // ===========================================================================
378 ( const std::string& grp ,
379  Printout& printer ) const
380 {
381  CountMap::const_iterator i = m_counts.find ( grp ) ;
382  if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; }
383 
384  MsgStream log(msgSvc(), name());
385  // Force printing in alphabetical order
386  typedef std::map<std::string, Counter*> sorted_map_t;
387  sorted_map_t sorted_map(i->second.begin(), i->second.end());
388  std::for_each(sorted_map.begin(), sorted_map.end(),
389  conditionalPrint(printer, log));
390  return StatusCode::SUCCESS; // RETURN
391 }
392 // ===========================================================================
393 // Print counter value
394 // ===========================================================================
396 ( const Counter* pCounter,
397  Printout& printer ) const
398 {
399  MsgStream log(msgSvc(), name() ) ;
400  return printer ( log , pCounter ) ;
401 }
402 // ===========================================================================
403 // Print counter value
404 // ===========================================================================
406 ( const CountObject& refCounter,
407  Printout& printer) const
408 { return print( refCounter.counter() , printer ) ; }
409 // ===========================================================================
410 // Print all known counters
411 // ===========================================================================
413 {
414  MsgStream log ( msgSvc() , name() ) ;
415  // Force printing in alphabetical order
416  typedef std::map<std::pair<std::string,std::string>, Counter*> sorted_map_t;
417  sorted_map_t sorted_map;
418  for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i )
419  {
420  for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
421  {
422  sorted_map[std::make_pair(i->first, j->first)] = j->second;
423  }
424  }
425  std::for_each(sorted_map.begin(), sorted_map.end(),
426  conditionalPrint(printer, log));
427  return StatusCode::SUCCESS;
428 }
429 // ===========================================================================
430 // Print counter value
431 // ===========================================================================
434  const Counter* c ) const
435 {
436  if ( 0 == c ) { return StatusCode::FAILURE ; }
437  std::pair<std::string,std::string> p = _find ( c ) ;
438 
439  log << MSG::ALWAYS
440  << CountObject( const_cast<Counter*>(c) , p.first , p.second )
441  << endmsg ;
442 
443  return StatusCode::SUCCESS;
444 }
445 // ===========================================================================
446 // "standard" printout a'la GaudiCommon
447 // ===========================================================================
448 void CounterSvc::print () const
449 {
450  MsgStream log ( msgSvc() , name() ) ;
451  // number of counters
452  const size_t _num = num() ;
453  if ( 0 != _num )
454  {
455  log << MSG::ALWAYS
456  << "Number of counters : " << _num << endmsg
457  << m_header << endmsg ;
458  }
459  {
460  // Force printing in alphabetical order
461  typedef std::map<std::pair<std::string,std::string>, Counter*> sorted_map_t;
462  sorted_map_t sorted_map;
463  for ( CountMap::const_iterator i = m_counts.begin(); i != m_counts.end(); ++i )
464  {
465  for ( NameMap::const_iterator j = i->second.begin() ; i->second.end() != j ; ++j )
466  {
467  Counter* c = j->second ;
468  if ( 0 == c ) { continue ; }
469  sorted_map[std::make_pair(i->first, j->first)] = c;
470  }
471  }
472  for (sorted_map_t::const_iterator i = sorted_map.begin(); i != sorted_map.end(); ++i )
473  log << Gaudi::Utils::formatAsTableRow( i->first.second
474  , i->first.first
475  , *i->second
477  , m_format1
478  , m_format2 )
479  << endmsg ;
480  }
481 }
482 // ============================================================================
483 
484 // ============================================================================
485 // The END
486 // ============================================================================
std::pair< std::string, std::string > _find(const Counter *c) const
Definition: CounterSvc.cpp:185
GaudiUtils::HashMap< std::string, NameMap > CountMap
Definition: CounterSvc.cpp:213
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
virtual StatusCode remove()
Remove all known counter objects.
Definition: CounterSvc.cpp:335
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:26
virtual StatusCode create(const std::string &group, const std::string &name, longlong initial_value, Counter *&refpCounter)
Create a new counter object.
Definition: CounterSvc.cpp:265
std::string m_header
the header row
Definition: CounterSvc.cpp:219
SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
Small wrapper class for easy manipulation with generic counters and IStatSvc&ICounterSvc interface...
Definition: Stat.h:50
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:62
tuple c
Definition: gaudirun.py:341
StatEntity * counter() const
alternative access to underlying counter (for ICounterSvc::CounterObj)
Definition: Stat.h:282
int outputLevel() const
get the Service's output level
Definition: Service.h:248
bool m_useEffFormat
flag to use the special "efficiency" format
Definition: CounterSvc.cpp:225
bool m_print
boolean flag to print statistics
Definition: CounterSvc.cpp:217
std::vector< CountObject > Counters
the actual type of vectors of initialized counters
Definition: ICounterSvc.h:102
std::string m_format2
format for "efficiency" statistical printout rows
Definition: CounterSvc.cpp:223
Simple implementation of the abstract interface ICounterSvc.
Definition: CounterSvc.cpp:23
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:35
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:302
StatEntity Counter
the actual type of counter
Definition: ICounterSvc.h:84
GaudiUtils::HashMap< std::string, Counter * > NameMap
Definition: CounterSvc.cpp:212
iterator end()
Definition: Map.h:131
void print() const
"standard" printout a'la GaudiCommon
Definition: CounterSvc.cpp:448
Print counters for each element in the range [first, last) e.g.
Definition: ICounterSvc.h:111
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:30
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
CountMap m_counts
the actual map of counters
Definition: CounterSvc.cpp:215
CounterSvc(const std::string &name, ISvcLocator *svcLoc)
Standard Constructor.
Definition: CounterSvc.cpp:26
iterator find(const key_type &key)
Definition: Map.h:148
Stat CountObject
Ease the manipulation of counters in a way, that they behave like objects: Avoid: Counter* cnt = ...
Definition: ICounterSvc.h:100
virtual ~CounterSvc()
Standard destructor.
Definition: CounterSvc.cpp:61
std::string m_format1
format for regular statistical printout rows
Definition: CounterSvc.cpp:221
map_type::const_iterator const_iterator
Definition: Map.h:99
unsigned long addFlag(const double Flag)
add a flag
Definition: StatEntity.h:416
virtual const std::string & name() const
Retrieve name of the service.
Definition: Service.cpp:331
iterator begin()
Definition: Map.h:130
virtual StatusCode defaultPrintout(MsgStream &log, const Counter *pCounter) const
Default Printout for counters.
Definition: CounterSvc.cpp:433
std
AIDA -> ROTO converter.
Definition: GaudiAlgs.py:73
Common class providing an architecture-independent hash map.
Definition: HashMap.h:108
Templated class to add the standard messaging functionalities.
void clear()
Definition: Map.h:176
virtual Counter * get(const std::string &group, const std::string &name) const
Access an existing counter object.
Definition: CounterSvc.cpp:235
Property * declareProperty(const std::string &name, T &property, const std::string &doc="none") const
Declare the named property.
Definition: Service.h:209
The basic counter used for Monitoring purposes.
Definition: StatEntity.h:68
size_t num() const
Definition: CounterSvc.cpp:196
list i
Definition: ana.py:128
virtual StatusCode finalize()
Finalize (from INITIALIZED to CONFIGURED).
Definition: Service.cpp:199
virtual StatusCode finalize()
Finalization.
Definition: CounterSvc.cpp:63
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:243