| The Gaudi Framework v27r1

- 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 <utility>
5 #include <vector>
6 #include <algorithm>
7 #include <functional>
8 // ============================================================================
9 // GaudiKernel
10 // ============================================================================
11 #include "GaudiKernel/ICounterSvc.h"
12 #include "GaudiKernel/ISvcLocator.h"
13 #include "GaudiKernel/MsgStream.h"
14 #include "GaudiKernel/Service.h"
15 #include "GaudiKernel/HashMap.h"
16 #include "GaudiKernel/Stat.h"
17 // ============================================================================
24 class CounterSvc: public extends<Service,
25 ICounterSvc> {
26 public:
28 CounterSvc ( const std::string& name ,
29 ISvcLocator* svcLoc )
30 : base_class(name, svcLoc)
31 // the header row
32 , m_header ( " Counter :: Group | # | sum | mean/eff^* | rms/err^* | min | max |")
33 // format for regular statistical printout rows
34 , m_format1 ( " %|15.15s|%|-15.15s|%|32t||%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" )
35 // format for "efficiency" statistical printout rows
36 , m_format2 ( "*%|15.15s|%|-15.15s|%|32t||%|10d| |%|11.5g| |(%|#9.7g| +- %|-#9.7g|)%%| ------- | ------- |" )
37 //
38 {
39 declareProperty ("PrintStat" , m_print ) ;
40 //
41 declareProperty
42 ( "StatTableHeader" , m_header ,
43 "The header row for the output Stat-table" ) ;
44 //
45 declareProperty
46 ( "RegularRowFormat" , m_format1 ,
47 "The format for the regular row in the output Stat-table" ) ;
48 //
49 declareProperty
50 ( "EfficiencyRowFormat" , m_format2 ,
51 "The format for the regular row in the outptu Stat-table" ) ;
52 //
53 declareProperty
54 ( "UseEfficiencyRowFormat" , m_useEffFormat ,
55 "Use the special format for printout of efficiency counters" ) ;
56 }
58 ~CounterSvc() override { remove().ignore() ; }
60 StatusCode finalize() override
61 {
62 if ( msgLevel(MSG::DEBUG) || m_print ) { print () ; }
63 remove().ignore() ;
64 // finalize the base class
65 return Service::finalize() ;
66 }
67 // ==========================================================================
75 Counter* get
76 ( const std::string& group ,
77 const std::string& name ) const override;
79 ICounterSvc::Counters get ( const std::string& group ) const override ;
92 StatusCode create
93 ( const std::string& group ,
94 const std::string& name ,
95 longlong initial_value ,
96 Counter*& refpCounter ) override ;
108 CountObject create
109 ( const std::string& group ,
110 const std::string& name ,
111 longlong initial_value = 0 ) override ;
121 StatusCode remove
122 ( const std::string& group ,
123 const std::string& name ) override ;
129 StatusCode remove
130 ( const std::string& group ) override ;
132 virtual StatusCode remove();
140 StatusCode print
141 ( const std::string& group,
142 const std::string& name,
143 Printout& printer) const override;
151 StatusCode print
152 (const std::string& group,
153 Printout& printer) const override;
160 StatusCode print
161 ( const Counter* pCounter,
162 Printout& printer) const override;
169 StatusCode print
170 ( const CountObject& pCounter,
171 Printout& printer) const override;
175 StatusCode print(Printout& printer) const override;
177 StatusCode defaultPrintout
178 ( MsgStream& log,
179 const Counter* pCounter) const override ;
180 private:
181 // find group/name for the counter:
182 inline std::pair<std::string,std::string> _find ( const Counter* c ) const
183 {
184 if ( c ) {
185 for ( const auto& i : m_counts ) {
186 auto j = std::find_if( i.second.begin(), i.second.end(),
187 [&](const NameMap::value_type& k) {
188 return k.second == c;
189 });
190 if (j!=i.second.end()) return { i.first, j->first } ;
191 }
192 }
193 return { };
194 }
195 // get the overall number of counters
196 inline size_t num () const
197 {
198 return std::accumulate( m_counts.begin(), m_counts.end(), size_t{0},
199 [](size_t r, const CountMap::value_type& i) {
200 return r + std::count_if(i.second.begin(),i.second.end(),
201 [](const NameMap::value_type& j) -> bool { return j.second; });
202 });
203 }
204 public:
206 void print () const ;
207 private:
208 typedef GaudiUtils::HashMap<std::string,Counter*> NameMap ;
209 typedef GaudiUtils::HashMap<std::string,NameMap> CountMap ;
210 // the actual map of counters
211 CountMap m_counts ;
212 // boolean flag to print statistics
213 bool m_print = true ;
214 // the header row
215 std::string m_header ;
216 // format for regular statistical printout rows
217 std::string m_format1 ;
218 // format for "efficiency" statistical printout rows
219 std::string m_format2 ;
220 // flag to use the special "efficiency" format
221 bool m_useEffFormat = true;
222 } ;
223 // ===========================================================================
224 // Instantiation of a static factory class used by clients
225 // ===========================================================================
226 DECLARE_COMPONENT(CounterSvc)
227 // ===========================================================================
228 // Access a counter object by name and group
229 // ===========================================================================
230 CounterSvc::Counter* CounterSvc::get
231 ( const std::string& grp ,
232 const std::string& nam ) const
233 {
234 auto i = m_counts.find ( grp ) ;
235 if ( m_counts.end() == i ) { return nullptr ; } // RETURN
236 auto j = i->second.find ( nam ) ;
237 if ( i->second.end() == j ) { return nullptr ; } // RETURN
238 return j->second ; // RETURN
239 }
240 // ===========================================================================
241 // get all counters form the given group:
242 // ===========================================================================
243 ICounterSvc::Counters CounterSvc::get ( const std::string& group ) const
244 {
245 ICounterSvc::Counters result ;
246 auto i = m_counts.find ( group ) ;
247 if ( i != m_counts.end() ) {
248 std::transform( i->second.begin(), i->second.end(),
249 std::back_inserter(result),
250 [&](const NameMap::value_type& j) {
251 return CountObject{ j.second, i->first, j.first };
252 } );
253 }
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
264 StatusCode CounterSvc::create
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 ( refpCounter ) { return COUNTER_EXISTS ; } // RETURN
273 // create the new counter
274 auto 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 auto i = m_counts.find ( grp ) ;
281 // (create a group if needed)
282 if ( m_counts.end() == i )
283 { i = m_counts.emplace ( grp , NameMap() ).first ; }
284 // insert new counter with proper name into proper group:
285 i->second.emplace( 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 // ===========================================================================
295 CounterSvc::CountObject CounterSvc::create
296 ( const std::string& group ,
297 const std::string& name ,
298 longlong initial_value )
299 {
300 Counter* p = nullptr;
301 StatusCode sc = create ( group, name, initial_value, p ) ;
302 if ( sc.isSuccess() && 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 // ===========================================================================
308 StatusCode CounterSvc::remove
309 ( const std::string& grp ,
310 const std::string& nam )
311 {
312 auto i = m_counts.find ( grp ) ;
313 if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; } // RETURN
314 auto 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 auto i = m_counts.find ( grp ) ;
326 if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; } // RETURN
327 for ( auto& j : i->second ) delete j.second ;
328 i->second.clear() ;
329 return StatusCode::SUCCESS ;
330 }
331 // ===========================================================================
332 // Remove all known counter objects
333 // ===========================================================================
334 StatusCode CounterSvc::remove()
335 {
336 // remove group by group
337 for ( auto& i : m_counts ) remove ( i.first ).ignore () ;
338 m_counts.clear() ;
339 return StatusCode::SUCCESS;
340 }
341 // ===========================================================================
342 // Print counter value
343 // ===========================================================================
344 StatusCode CounterSvc::print
345 ( const std::string& grp,
346 const std::string& nam,
347 Printout& printer) const
348 {
349 const Counter* c = get( grp , nam ) ;
350 if ( !c ) { return COUNTER_NOT_PRESENT ; } // RETURN
351 // create the stream and use it!
352 return printer ( msgStream() , c ) ;
353 }
354
355 namespace {
357 class conditionalPrint {
358 private:
359 CounterSvc::Printout *printer;
360 MsgStream *log;
361 public:
362 conditionalPrint(CounterSvc::Printout &_p, MsgStream &_l): printer(&_p), log(&_l) {}
363 template<class Pair>
364 void operator() (const Pair &p) {
365 if (p.second) {
366 (*printer)(*log, p.second).ignore();
367 }
368 }
369 };
370 }
371 // ===========================================================================
372 // Print the counter value for the whole group of counters
373 // ===========================================================================
374 StatusCode CounterSvc::print
375 ( const std::string& grp ,
376 Printout& printer ) const
377 {
378 auto i = m_counts.find ( grp ) ;
379 if ( m_counts.end() == i ) { return COUNTER_NOT_PRESENT ; }
380
381 // Force printing in alphabetical order
382 std::map<std::string, Counter*> sorted_map(i->second.begin(), i->second.end());
383 std::for_each(sorted_map.begin(), sorted_map.end(),
384 conditionalPrint(printer, msgStream()));
385 return StatusCode::SUCCESS; // RETURN
386 }
387 // ===========================================================================
388 // Print counter value
389 // ===========================================================================
390 StatusCode CounterSvc::print
391 ( const Counter* pCounter,
392 Printout& printer ) const
393 {
394 return printer ( msgStream() , pCounter ) ;
395 }
396 // ===========================================================================
397 // Print counter value
398 // ===========================================================================
399 StatusCode CounterSvc::print
400 ( const CountObject& refCounter,
401 Printout& printer) const
402 { return print( refCounter.counter() , printer ) ; }
403 // ===========================================================================
404 // Print all known counters
405 // ===========================================================================
406 StatusCode CounterSvc::print( Printout& printer ) const
407 {
408 // Force printing in alphabetical order
409 std::map<std::pair<std::string,std::string>, Counter*> sorted_map;
410 for ( const auto& i : m_counts ) for ( const auto& j : i.second )
411 sorted_map[ { i.first, j.first } ] = j.second;
412 std::for_each(sorted_map.begin(), sorted_map.end(),
413 conditionalPrint(printer, msgStream()));
414 return StatusCode::SUCCESS;
415 }
416 // ===========================================================================
417 // Print counter value
418 // ===========================================================================
419 StatusCode CounterSvc::defaultPrintout
420 ( MsgStream& log,
421 const Counter* c ) const
422 {
423 if ( !c ) { return StatusCode::FAILURE ; }
424 auto p = _find ( c ) ;
425
426 log << MSG::ALWAYS
427 << CountObject( const_cast<Counter*>(c) , p.first , p.second )
428 << endmsg ;
429
430 return StatusCode::SUCCESS;
431 }
432 // ===========================================================================
433 // "standard" printout a'la GaudiCommon
434 // ===========================================================================
435 void CounterSvc::print () const
436 {
437 // number of counters
438 const auto _num = num() ;
439 if ( 0 != _num )
440 {
441 always()
442 << "Number of counters : " << _num << endmsg
443 << m_header << endmsg ;
444 }
445 // Force printing in alphabetical order
446 std::map<std::pair<std::string,std::string>, Counter*> sorted_map;
447 for ( const auto& i : m_counts ) {
448 for ( const auto& j : i.second ) {
449 if ( j.second ) sorted_map[ {i.first, j.first} ] = j.second;
450 }
451 }
452 for ( const auto& i : sorted_map ) {
453 always() << Gaudi::Utils::formatAsTableRow( i.first.second
454 , i.first.first
455 , *i.second
456 , m_useEffFormat
457 , m_format1
458 , m_format2 )
459 << endmsg ;
460 }
461 }
462 // ============================================================================
463
464 // ============================================================================
465 // The END
466 // ============================================================================
CounterSvc::_find
std::pair< std::string, std::string > _find(const Counter *c) const
Definition: CounterSvc.cpp:182
CounterSvc::CountMap
GaudiUtils::HashMap< std::string, NameMap > CountMap
Definition: CounterSvc.cpp:209
MsgStream
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
CounterSvc::remove
virtual StatusCode remove()
Remove all known counter objects.
Definition: CounterSvc.cpp:334
ISvcLocator
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
CounterSvc::m_header
std::string m_header
the header row
Definition: CounterSvc.cpp:215
gaudiComponentHelp.name
name
Definition: gaudiComponentHelp.py:28
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:193
MsgStream.h
Gaudi.Configuration.log
tuple log
Definition: Configuration.py:13
StatusCode::isSuccess
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
gaudirun.c
tuple c
Definition: gaudirun.py:391
CounterSvc::get
Counter * get(const std::string &group, const std::string &name) const override
Access an existing counter object.
Definition: CounterSvc.cpp:231
MSG::DEBUG
Definition: IMessageSvc.h:18
CounterSvc::m_useEffFormat
bool m_useEffFormat
flag to use the special "efficiency" format
Definition: CounterSvc.cpp:221
CounterSvc::m_print
bool m_print
boolean flag to print statistics
Definition: CounterSvc.cpp:213
std
STL namespace.
std::map::end
T end(T...args)
CounterSvc::m_format2
std::string m_format2
format for "efficiency" statistical printout rows
Definition: CounterSvc.cpp:219
CounterSvc
Simple implementation of the abstract interface ICounterSvc.
Definition: CounterSvc.cpp:24
HashMap.h
merge_files.sc
int sc
Definition: merge_files.py:167
std::map
STL class.
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
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:299
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:265
Service.h
CounterSvc::NameMap
GaudiUtils::HashMap< std::string, Counter * > NameMap
Definition: CounterSvc.cpp:208
Service::name
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:319
GaudiUtils::Map::end
iterator end()
Definition: Map.h:132
CounterSvc::print
void print() const
"standard" printout a'la GaudiCommon
Definition: CounterSvc.cpp:435
StatusCode::FAILURE
Definition: StatusCode.h:29
__longlong
Definition: Kernel.h:56
StatusCode::SUCCESS
Definition: StatusCode.h:30
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
CounterSvc::m_counts
CountMap m_counts
the actual map of counters
Definition: CounterSvc.cpp:211
std::runtime_error
STL class.
CounterSvc::CounterSvc
CounterSvc(const std::string &name, ISvcLocator *svcLoc)
Standard Constructor.
Definition: CounterSvc.cpp:28
GaudiUtils::Map::find
iterator find(const key_type &key)
Definition: Map.h:149
CounterSvc::m_format1
std::string m_format1
format for regular statistical printout rows
Definition: CounterSvc.cpp:217
std::count_if
T count_if(T...args)
GaudiUtils::Map::begin
iterator begin()
Definition: Map.h:131
std::pair< std::string, std::string >
CounterSvc::defaultPrintout
StatusCode defaultPrintout(MsgStream &log, const Counter *pCounter) const override
Default Printout for counters.
Definition: CounterSvc.cpp:420
std::find_if
T find_if(T...args)
std::vector
STL class.
GaudiPython.Persistency.get
def get(type_)
Definition: Persistency.py:23
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)
print
void print(string text)
Definition: mergesort.cpp:33
GaudiUtils::HashMap
Common class providing an architecture-independent hash map.
Definition: HashMap.h:77
CommonMessagingBase::msgStream
MsgStream & msgStream() const
Return an uninitialized MsgStream.
Definition: CommonMessaging.h:89
CommonMessaging
Definition: CommonMessaging.h:58
Stat.h
std::transform
T transform(T...args)
std::accumulate
T accumulate(T...args)
Service::declareProperty
Property * declareProperty(const std::string &name, T &property, const std::string &doc="none") const
Declare the named property.
Definition: Service.h:215
CommonMessagingBase::msgLevel
MSG::Level msgLevel() const
get the output level from the embedded MsgStream
Definition: CommonMessaging.h:136
std::for_each
T for_each(T...args)
CommonMessagingBase::always
MsgStream & always() const
shortcut for the method msgStream(MSG::ALWAYS)
Definition: CommonMessaging.h:109
ICounterSvc.h
CounterSvc::num
size_t num() const
Definition: CounterSvc.cpp:196
ana.i
list i
Definition: ana.py:128
ISvcLocator.h
MSG::ALWAYS
Definition: IMessageSvc.h:23
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
CounterSvc::~CounterSvc
~CounterSvc() override
Standard destructor.
Definition: CounterSvc.cpp:58
CounterSvc::finalize
StatusCode finalize() override
Finalization.
Definition: CounterSvc.cpp:60