| The Gaudi Framework v28r2p1 (f1a77ff4)

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