20 #include "GaudiKernel/IDataProviderSvc.h"
21 #include "GaudiKernel/IToolSvc.h"
22 #include "GaudiKernel/IProperty.h"
23 #include "GaudiKernel/Property.h"
24 #include "GaudiKernel/ISvcLocator.h"
25 #include "GaudiKernel/MsgStream.h"
26 #include "GaudiKernel/ObjectVector.h"
27 #include "GaudiKernel/SmartDataPtr.h"
28 #include "GaudiKernel/SmartRef.h"
29 #include "GaudiKernel/Stat.h"
30 #include "GaudiKernel/System.h"
31 #include "GaudiKernel/IJobOptionsSvc.h"
32 #include "GaudiKernel/StatEntity.h"
33 #include "GaudiKernel/Algorithm.h"
34 #include "GaudiKernel/AlgTool.h"
35 #include "GaudiKernel/reverse.h"
39 #include "GaudiAlg/Print.h"
40 #include "GaudiAlg/GaudiCommon.h"
41 #include "GaudiAlg/GaudiAlgorithm.h"
42 #include "GaudiAlg/GaudiTool.h"
46 #include "GaudiUtils/RegEx.h"
50 #include "boost/format.hpp"
54 #pragma warning ( disable:4661 ) // incomplete explicit templates
61 template <
class PBASE>
68 m_header =
" | Counter | # | sum | mean/eff^* | rms/err^* | min | max |" ;
70 m_format1 =
" | %|-48.48s|%|50t||%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" ;
72 m_format2 =
" |*%|-48.48s|%|50t||%|10d| |%|11.5g| |(%|#9.6g| +- %|-#9.6g|)%%| ------- | ------- |" ;
74 m_useEffFormat = true ;
79 (
"ErrorsPrint" , m_errorsPrint ,
80 "Print the statistics of errors/warnings/exceptions")
81 -> declareUpdateHandler
85 (
"PropertiesPrint" , m_propsPrint ,
86 "Print the properties of the component ")
87 -> declareUpdateHandler
91 (
"StatPrint" , m_statPrint ,
92 "Print the table of counters" )
93 -> declareUpdateHandler
97 (
"TypePrint" , m_typePrint ,
98 "Add the actal C++ component type into the messages" ) ;
100 this->declareProperty (
"Context" , m_context ) ;
102 this->declareProperty (
"RootInTES" , m_rootInTES ) ;
104 this->declareProperty (
"RootOnTES" , m_rootOnTES ) ;
106 this->declareProperty (
"GlobalTimeOffset", m_globalTimeOffset ) ;
110 this->declareProperty
111 (
"StatTableHeader" , m_header ,
112 "The header row for the output Stat-table" ) ;
114 this->declareProperty
115 (
"RegularRowFormat" , m_format1 ,
116 "The format for the regular row in the output Stat-table" ) ;
118 this->declareProperty
119 (
"EfficiencyRowFormat" , m_format2 ,
120 "The format for the regular row in the output Stat-table" ) ;
122 this->declareProperty
123 (
"UseEfficiencyRowFormat" , m_useEffFormat ,
124 "Use the special format for printout of efficiency counters" ) ;
128 this->declareProperty(
130 m_counterList=std::vector<std::string>(1,
".*"),
131 "RegEx list, of simple integer counters for CounterSummary.");
133 this->declareProperty(
135 m_statEntityList=std::vector<std::string>(0),
136 "RegEx list, of StatEntity counters for CounterSummary.");
144 if (
const GaudiAlgorithm* gAlg = dynamic_cast<const GaudiAlgorithm*>(parent) )
146 m_context = gAlg->context();
147 m_rootInTES = gAlg->rootInTES();
148 m_globalTimeOffset = gAlg->globalTimeOffset();
150 else if (
const GaudiTool* gTool = dynamic_cast<const GaudiTool*> (parent) )
152 m_context = gTool->context();
153 m_rootInTES = gTool->rootInTES();
154 m_globalTimeOffset = gTool->globalTimeOffset();
159 auto jos = this->
template service<IJobOptionsSvc>(
"JobOptionsSvc");
160 if (!jos) Exception(
"Cannot get JobOptionsSvc");
163 const auto myList = jos->getProperties( this->
name() );
167 for (
const auto& iter : *myList )
172 if ( iter->name() ==
"Context" ) {
173 m_context = sp->
value();
174 }
else if ( iter->name() ==
"RootInTES" ) {
175 m_rootInTES = sp->
value();
176 }
else if ( iter->name() ==
"GlobalTimeOffset" ) {
177 m_globalTimeOffset = std::stod( sp->
value() );
189 template <
class PBASE >
202 {
return Error (
"Failed to initialise base class PBASE", sc ) ; }
209 if ( !context().empty() )
210 this->debug() <<
"Created with context = '" << context() <<
"'" <<
endmsg;
215 if ( m_rootInTES.empty() && !m_rootOnTES.empty() )
217 m_rootInTES = m_rootOnTES;
218 Warning(
"RootOnTES option is OBSOLETE -> Use RootInTES instead. RootInTES has been updated to "
221 else if ( !m_rootInTES.empty() && !m_rootOnTES.empty() )
223 Warning(
"Options RootOnTES AND RootInTES are defined ! Use RootInTES. RootOnTES is ignored",
228 if ( !m_rootInTES.empty() &&
229 m_rootInTES.substr(m_rootInTES.size()-1) !=
"/" ) m_rootInTES +=
"/";
232 m_counterSummarySvc = this->svcLoc()->service(
"CounterSummarySvc",
false);
235 if (!m_counterSummarySvc)
236 this->debug() <<
"could not locate CounterSummarySvc, no counter summary will be made" <<
endmsg;
237 else this->debug() <<
"found CounterSummarySvc OK" <<
endmsg;
251 template <
class PBASE >
263 if ( this->msgLevel(
MSG::DEBUG) || (statPrint() && !counters().empty()) )
269 if(m_counterSummarySvc && this->svcLoc()->existsService(
"CounterSummarySvc"))
271 if ( this->msgLevel(
MSG::DEBUG) ) this->debug() <<
"adding counters to CounterSummarySvc" <<
endmsg;
276 for(
const auto&
i : this->counters() )
278 if (statList.Or(
i.first) )
279 m_counterSummarySvc->addCounter(this->name(),
i.first,
i.second,
281 else if (counterList.Or(
i.first))
282 m_counterSummarySvc->addCounter(this->name(),
i.first,
i.second);
288 this->debug() <<
"Tools to release :";
289 for (
const auto&
i : m_tools )
291 this->debug() <<
" " <<
i->name();
295 while ( !m_tools.empty() ) { sc = releaseTool( m_tools.back() ) && sc; }
300 this->debug() <<
"Services to release :";
301 for (
const auto&
i : m_services )
303 this->debug() <<
" " <<
i->name();
307 while ( !m_services.empty() ) { sc = releaseSvc( m_services.front() ) && sc; }
310 m_counterSummarySvc.reset();
313 if ( !m_errors.empty() || !m_warnings.empty() || !m_exceptions.empty() )
315 this->always() <<
"Exceptions/Errors/Warnings/Infos Statistics : "
316 << m_exceptions .size () <<
"/"
317 << m_errors .size () <<
"/"
318 << m_warnings .size () <<
"/"
319 << m_infos .size () <<
endmsg ;
320 if ( errorsPrint() ) { printErrors () ; }
327 m_counters .clear() ;
328 m_exceptions .clear() ;
330 m_warnings .clear() ;
332 m_counterList.clear() ;
333 m_statEntityList.clear() ;
336 return sc && PBASE::finalize();
347 template <
class PBASE >
351 {
return Error (
"release(IInterface):: IInterface* points to NULL!" ) ; }
355 return algTool ? releaseTool( algTool ) : releaseSvc( interface ) ;
362 template <
class PBASE >
366 {
return Error (
"releaseTool(IAlgTool):: IAlgTool* points to NULL!" ) ; }
367 if( !this->toolSvc() )
368 {
return Error (
"releaseTool(IAlgTool):: IToolSvc* points to NULL!" ) ; }
370 auto it = std::find( m_tools.rbegin() , m_tools.rend() , algTool ) ;
371 if( m_tools.rend() == it )
372 {
return Warning(
"releaseTool(IAlgTool):: IAlgTool* is not active" ) ; }
376 const std::string
name = t->name();
378 { this->debug() <<
"Releasing tool '" << name <<
"'" <<
endmsg; }
380 m_tools.erase( --it.base() ) ;
383 this->debug() <<
"The tool '" << t->name() <<
"' of type '"
385 <<
"' is released" <<
endmsg;
387 const StatusCode sc = this->toolSvc()->releaseTool( t ) ;
390 Warning(
"releaseTool(IAlgTool):: error from IToolSvc releasing "+name , sc ) ;
397 template <
class PBASE >
400 if( !Svc )
return Error (
"releaseSvc(IInterface):: IInterface* points to NULL!" ) ;
402 if (!svc)
return Warning(
"releaseSvc(IInterface):: IInterface* is not a service" );
405 return Warning(
"releaseSvc(IInterface):: IInterface* is not active" );
408 this->debug() <<
"Releasing service '" << (*it)->name() <<
"'" <<
endmsg;
410 m_services.erase(it);
418 template <
class PBASE >
423 this->debug() <<
"The tool of type '"
425 <<
"' has been added with the name '"
426 << tool->name() <<
"'" <<
endmsg ;
428 m_tools.push_back( tool ) ;
436 template <
class PBASE >
442 m_services.insert(
i, std::move(svc) );
444 this->warning() <<
"Service " << svc->name() <<
" already present -- skipping" <<
endmsg;
457 template <
class PBASE >
460 const size_t mx )
const
463 const size_t num = ++m_errors[
msg] ;
465 if ( num > mx ) {
return st ; }
467 {
return Print (
"The ERROR message is suppressed : '" +
477 template <
class PBASE >
479 (
const std::string&
msg ,
481 const size_t mx )
const
484 const size_t num = ++m_warnings[
msg] ;
486 if ( num > mx ) {
return st ; }
488 {
return Print (
"The WARNING message is suppressed : '" +
498 template <
class PBASE >
500 (
const std::string& msg ,
502 const size_t mx )
const
505 const size_t num = ++m_infos[
msg] ;
507 if ( num > mx ) {
return st ; }
509 {
return Print (
"The INFO message is suppressed : '" +
519 template <
class PBASE >
525 if ( !this->msgLevel( lvl ) ) {
return st ; }
528 MsgStream& str = this->msgStream( lvl ) ;
537 { str <<
" StatusCode=" << st.
getCode() ; }
539 { str <<
" StatusCode=FAILURE" ; }
552 template <
class PBASE >
558 ++m_exceptions[
msg ];
559 Print (
"Exception (re)throw: " + msg , sc ,
MSG::FATAL ).ignore();
567 template <
class PBASE >
569 const std::exception & exc ,
573 ++m_exceptions[
msg ];
574 Print (
"Exception (re)throw: " + msg , sc ,
MSG::FATAL ).ignore();
582 template <
class PBASE >
587 ++m_exceptions[
msg ];
588 Print (
"Exception throw: " + msg , sc ,
MSG::FATAL ).ignore();
596 template <
class PBASE >
600 if ( counters().empty() ) {
return 0 ; }
601 MsgStream& msg = this->msgStream ( level ) ;
603 msg <<
"Number of counters : " << counters().size() ;
605 if ( !counters().empty() ) { msg << std::endl << m_header ; }
607 for (
const auto& entry : counters() )
614 m_format1 , m_format2 );
619 return counters().size() ;
626 template <
class PBASE >
630 boost::format ftm (
" #%|-10s| = %|.8s| %|23t| Message = '%s'" );
632 auto print = [&](
const Counter&
c,
const std::string& label) {
633 for (
const auto&
i : c ) {
634 this->msgStream(level)
635 << ( ftm % label %
i.second %
i.first )
640 print( m_exceptions,
"EXCEPTIONS" );
641 print( m_errors,
"ERRORS" );
642 print( m_warnings,
"WARNINGS" );
643 print( m_infos,
"INFOS" );
647 m_exceptions .size () +
649 m_warnings .size () +
659 template <
class PBASE >
664 MsgStream& msg = this->msgStream ( level );
665 const auto&
properties = this->getProperties() ;
666 msg <<
"List of ALL properties of "
671 msg <<
"Property ['Name': Value] = " << *property <<
endmsg ;
680 template <
class PBASE >
693 if ( this->msgSvc()->outputLevel(this->
name()) != this->outputLevel() )
695 this->msgSvc()->setOutputLevel( this->
name(), this->outputLevel() );
701 this->debug() <<
"Property update for "
702 << theProp.
name() <<
" : new value = " << this->outputLevel() <<
endmsg;
714 template <
class PBASE >
717 const std::string& location ,
718 const bool useRootInTES )
const
721 Assert ( svc ,
"put():: Invalid 'service'!" ) ;
722 Assert (
object ,
"put():: Invalid 'Object'!" ) ;
723 Assert ( !location.empty() ,
"put():: Invalid 'address' = '' " ) ;
725 const std::string & fullLocation = fullTESLocation( location, useRootInTES );
727 const StatusCode status =
'/' == fullLocation[0] ?
728 svc -> registerObject( fullLocation ,
object ) :
729 svc -> registerObject(
"/Event/" + fullLocation ,
object ) ;
732 { Exception (
"put():: could not register '" +
734 "' at address '" + fullLocation +
"'" , status ) ; }
736 { Print(
"The object of type '" +
738 "' is registered in TS at address '"
739 + fullLocation +
"'" , status ,
MSG::DEBUG ).ignore() ; }
747 template <
class PBASE >
752 if (
this -> errorsPrint() ) {
this -> printErrors () ; }
757 template <
class PBASE >
762 if (
this -> propsPrint() ) {
this -> printProps (
MSG::ALWAYS ) ; }
767 template <
class PBASE >
772 if (
this -> statPrint() ) {
this -> printStat (
MSG::ALWAYS ) ; }
Definition of the MsgStream class used to transmit messages.
Define general base for Gaudi exception.
reverse_wrapper< T > reverse(T &&iterable)
StatusCode releaseSvc(const IInterface *svc) const
manual forced (and 'safe') release of the service
DataObject * put(IDataProviderSvc *svc, DataObject *object, const std::string &location, const bool useRootInTES=true) const
Register a data object or container into Gaudi Event Transient Store.
std::map< std::string, unsigned int > Counter
the actual type error/warning counter
unsigned long getCode() const
Get the status code by value.
const std::string & name() const
property name
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
void addToServiceList(SmartIF< IService > svc) const
Add the given service to the list of acquired services.
auto begin(reverse_wrapper< T > &w)
bool isSuccess() const
Test for a status code of SUCCESS.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
StatusCode Error(const std::string &msg, const StatusCode st=StatusCode::FAILURE, const size_t mx=10) const
Print the error message and return with the given StatusCode.
void initGaudiCommonConstructor(const IInterface *parent=0)
Constructor initializations.
Data provider interface definition.
bool isFailure() const
Test for a status code of FAILURE.
auto end(reverse_wrapper< T > &w)
This class is used for returning status codes from appropriate routines.
Definition of the basic interface.
void printStatHandler(Property &)
handler for "StatPrint" property
StatusCode Print(const std::string &msg, const StatusCode st=StatusCode::SUCCESS, const MSG::Level lev=MSG::INFO) const
Print the message and return with the given StatusCode.
The useful base class for data processing algorithms.
StatusCode Warning(const std::string &msg, const StatusCode st=StatusCode::FAILURE, const size_t mx=10) const
Print the warning message and return with the given StatusCode.
void msgLevelHandler(Property &theProp)
Handle method for changes in the Messaging levels.
const TYPE & value() const
explicit conversion
constexpr const struct GaudiCommon_details::svc_eq_t svc_eq
Property base class allowing Property* collections to be "homogeneous".
StatusCode releaseTool(const IAlgTool *tool) const
manual forced (and 'safe') release of the tool
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
Implements the common functionality between GaudiTools and GaudiAlgorithms.
void printPropsHandler(Property &)
handler for "PropertiesPrint" property
StatusCode Info(const std::string &msg, const StatusCode st=StatusCode::SUCCESS, const size_t mx=10) const
Print the info message and return with the given StatusCode.
long printStat(const MSG::Level level=MSG::ALWAYS) const
perform the actual printout of statistical counters
void addToToolList(IAlgTool *tool) const
Add the given tool to the list of acquired tools.
constexpr const struct GaudiCommon_details::svc_lt_t svc_lt
A DataObject is the base class of any identifiable object on any data store.
StatusCode release(const IInterface *interface) const
Manual forced (and 'safe') release of the active tool or service.
long printProps(const MSG::Level level=MSG::ALWAYS) const
perform the actual printout of properties
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
void printErrorHandler(Property &)
handler for "ErrorPrint" property
long printErrors(const MSG::Level level=MSG::ALWAYS) const
perform the actual printout of error counters
void Exception(const std::string &msg, const GaudiException &exc, const StatusCode sc=StatusCode(StatusCode::FAILURE, true)) const
Create and (re)-throw a given GaudiException.