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/IDataManagerSvc.h"
27 #include "GaudiKernel/ObjectVector.h"
28 #include "GaudiKernel/SmartDataPtr.h"
29 #include "GaudiKernel/SmartRef.h"
30 #include "GaudiKernel/Stat.h"
31 #include "GaudiKernel/System.h"
32 #include "GaudiKernel/IJobOptionsSvc.h"
33 #include "GaudiKernel/StatEntity.h"
34 #include "GaudiKernel/Algorithm.h"
35 #include "GaudiKernel/AlgTool.h"
36 #include "GaudiKernel/reverse.h"
40 #include "GaudiAlg/Print.h"
41 #include "GaudiAlg/GaudiCommon.h"
42 #include "GaudiAlg/GaudiAlgorithm.h"
43 #include "GaudiAlg/GaudiTool.h"
47 #include "GaudiUtils/RegEx.h"
51 #include "boost/format.hpp"
55 #pragma warning ( disable:4661 ) // incomplete explicit templates
62 template <
class PBASE>
69 m_header =
" | Counter | # | sum | mean/eff^* | rms/err^* | min | max |" ;
71 m_format1 =
" | %|-48.48s|%|50t||%|10d| |%|11.7g| |%|#11.5g| |%|#11.5g| |%|#12.5g| |%|#12.5g| |" ;
73 m_format2 =
" |*%|-48.48s|%|50t||%|10d| |%|11.5g| |(%|#9.6g| +- %|-#9.6g|)%%| ------- | ------- |" ;
75 m_useEffFormat = true ;
80 (
"ErrorsPrint" , m_errorsPrint ,
81 "Print the statistics of errors/warnings/exceptions")
82 -> declareUpdateHandler
86 (
"PropertiesPrint" , m_propsPrint ,
87 "Print the properties of the component ")
88 -> declareUpdateHandler
92 (
"StatPrint" , m_statPrint ,
93 "Print the table of counters" )
94 -> declareUpdateHandler
98 (
"TypePrint" , m_typePrint ,
99 "Add the actal C++ component type into the messages" ) ;
101 this->declareProperty (
"Context" , m_context ) ;
103 this->declareProperty (
"RootInTES" , m_rootInTES ) ;
105 this->declareProperty (
"GlobalTimeOffset", m_globalTimeOffset ) ;
109 this->declareProperty
110 (
"StatTableHeader" , m_header ,
111 "The header row for the output Stat-table" ) ;
113 this->declareProperty
114 (
"RegularRowFormat" , m_format1 ,
115 "The format for the regular row in the output Stat-table" ) ;
117 this->declareProperty
118 (
"EfficiencyRowFormat" , m_format2 ,
119 "The format for the regular row in the output Stat-table" ) ;
121 this->declareProperty
122 (
"UseEfficiencyRowFormat" , m_useEffFormat ,
123 "Use the special format for printout of efficiency counters" ) ;
127 this->declareProperty(
129 m_counterList=std::vector<std::string>(1,
".*"),
130 "RegEx list, of simple integer counters for CounterSummary.");
132 this->declareProperty(
134 m_statEntityList=std::vector<std::string>(0),
135 "RegEx list, of StatEntity counters for CounterSummary.");
143 if (
const GaudiAlgorithm* gAlg = dynamic_cast<const GaudiAlgorithm*>(parent) )
145 m_context = gAlg->context();
146 m_rootInTES = gAlg->rootInTES();
147 m_globalTimeOffset = gAlg->globalTimeOffset();
149 else if (
const GaudiTool* gTool = dynamic_cast<const GaudiTool*> (parent) )
151 m_context = gTool->context();
152 m_rootInTES = gTool->rootInTES();
153 m_globalTimeOffset = gTool->globalTimeOffset();
159 if (!jos.
isValid()) Exception(
"Cannot get JobOptionsSvc");
166 for (
const auto& iter : *myList )
171 if ( iter->name().compare(
"Context") == 0 ) {
172 m_context = sp->
value();
173 }
else if ( iter->name().compare(
"RootInTES") == 0 ) {
174 m_rootInTES = sp->
value();
175 }
else if ( iter->name().compare(
"GlobalTimeOffset") == 0 ) {
176 m_globalTimeOffset = std::stod( sp->
value() );
188 template <
class PBASE >
201 {
return Error (
"Failed to initialise base class PBASE", sc ) ; }
208 if ( !context().empty() )
209 this->debug() <<
"Created with context = '" << context() <<
"'" <<
endmsg;
213 if ( !m_rootInTES.empty() &&
214 m_rootInTES.substr(m_rootInTES.size()-1) !=
"/" ) m_rootInTES +=
"/";
217 m_counterSummarySvc = this->svcLoc()->service(
"CounterSummarySvc",
false);
220 if (!m_counterSummarySvc)
221 this->debug() <<
"could not locate CounterSummarySvc, no counter summary will be made" <<
endmsg;
222 else this->debug() <<
"found CounterSummarySvc OK" <<
endmsg;
233 std::string rootName(dataMgrSvc->
rootName());
234 if (
"" != rootName &&
'/' != rootName[rootName.size() - 1]) {
235 rootName = rootName +
"/";
238 auto fixLocation = [&] (
const std::string & location) -> std::string {
239 std::string result = fullTESLocation(location, UseRootInTES);
241 result = (result[0] ==
'/' ? result : rootName + result);
243 this->debug() <<
"Changing " << location <<
" to " << result <<
endmsg;
248 for(
auto tag : PBASE::inputDataObjects()){
249 if(PBASE::inputDataObjects()[tag].isValid()){
250 PBASE::inputDataObjects()[tag].setDataProductName(
251 fixLocation(PBASE::inputDataObjects()[tag].dataProductName())).ignore();
253 auto altAddress = PBASE::inputDataObjects()[tag].alternativeDataProductNames();
254 for(uint
i = 0;
i < altAddress.size(); ++
i)
255 altAddress[
i] = fixLocation(altAddress[
i]);
256 PBASE::inputDataObjects()[tag].setAlternativeDataProductNames(altAddress).ignore();
259 for(
auto tag : PBASE::outputDataObjects()){
260 if(PBASE::outputDataObjects()[tag].isValid()){
261 PBASE::outputDataObjects()[tag].setDataProductName(
262 fixLocation(PBASE::outputDataObjects()[tag].dataProductName())).ignore();
273 template <
class PBASE >
285 if ( this->msgLevel(
MSG::DEBUG) || (statPrint() && !counters().empty()) )
291 if(m_counterSummarySvc && this->svcLoc()->existsService(
"CounterSummarySvc"))
293 if ( this->msgLevel(
MSG::DEBUG) ) this->debug() <<
"adding counters to CounterSummarySvc" <<
endmsg;
298 for(
const auto&
i : this->counters() )
300 if (statList.Or(
i.first) )
301 m_counterSummarySvc->addCounter(this->name(),
i.first,
i.second,
303 else if (counterList.Or(
i.first))
304 m_counterSummarySvc->addCounter(this->name(),
i.first,
i.second);
310 this->debug() <<
"Tools to release :";
311 for (
const auto&
i : PBASE::tools() )
313 this->debug() <<
" " <<
i->name();
317 while ( !PBASE::tools().empty() ) { sc = releaseTool( PBASE::tools().back() ) &&
sc; }
322 this->debug() <<
"Services to release :";
323 for (
const auto&
i : m_services ) this->debug() <<
" " <<
i->name();
326 while ( !m_services.empty() ) { sc = releaseSvc( m_services.front() ) && sc; }
329 m_counterSummarySvc.reset();
332 if ( !m_errors.empty() || !m_warnings.empty() || !m_exceptions.empty() )
334 this->always() <<
"Exceptions/Errors/Warnings/Infos Statistics : "
335 << m_exceptions .size () <<
"/"
336 << m_errors .size () <<
"/"
337 << m_warnings .size () <<
"/"
338 << m_infos .size () <<
endmsg ;
339 if ( errorsPrint() ) { printErrors () ; }
346 m_counters .clear() ;
347 m_exceptions .clear() ;
349 m_warnings .clear() ;
351 m_counterList.clear() ;
352 m_statEntityList.clear() ;
355 return sc && PBASE::finalize();
366 template <
class PBASE >
370 {
return Error (
"release(IInterface):: IInterface* points to NULL!" ) ; }
374 return algTool ? releaseTool( algTool ) : releaseSvc( interface ) ;
381 template <
class PBASE >
385 {
return Error (
"releaseTool(IAlgTool):: IAlgTool* points to NULL!" ) ; }
386 if( !this->toolSvc() )
387 {
return Error (
"releaseTool(IAlgTool):: IToolSvc* points to NULL!" ) ; }
389 auto it = std::find( PBASE::tools().rbegin() , PBASE::tools().rend() , algTool ) ;
390 if( PBASE::tools().rend() == it )
391 {
return Warning(
"releaseTool(IAlgTool):: IAlgTool* is not active" ) ; }
395 const std::string
name = t->name();
397 { this->debug() <<
"Releasing tool '" << name <<
"'" <<
endmsg; }
399 PBASE::deregisterTool(t);
402 this->debug() <<
"The tool '" << t->name() <<
"' of type '"
404 <<
"' is released" <<
endmsg;
406 const StatusCode sc = this->toolSvc()->releaseTool( t ) ;
409 Warning(
"releaseTool(IAlgTool):: error from IToolSvc releasing "+name , sc ) ;
416 template <
class PBASE >
419 if( !Svc )
return Error (
"releaseSvc(IInterface):: IInterface* points to NULL!" ) ;
421 if (!svc)
return Warning(
"releaseSvc(IInterface):: IInterface* is not a service" );
424 return Warning(
"releaseSvc(IInterface):: IInterface* is not active" );
427 this->debug() <<
"Releasing service '" << (*it)->name() <<
"'" <<
endmsg;
429 m_services.erase(it);
438 template <
class PBASE >
444 m_services.insert(
i, std::move(svc) );
446 this->warning() <<
"Service " << svc->name() <<
" already present -- skipping" <<
endmsg;
459 template <
class PBASE >
462 const size_t mx )
const
465 const size_t num = ++m_errors[
msg] ;
467 if ( num > mx ) {
return st ; }
469 {
return Print (
"The ERROR message is suppressed : '" +
479 template <
class PBASE >
481 (
const std::string&
msg ,
483 const size_t mx )
const
486 const size_t num = ++m_warnings[
msg] ;
488 if ( num > mx ) {
return st ; }
490 {
return Print (
"The WARNING message is suppressed : '" +
500 template <
class PBASE >
502 (
const std::string& msg ,
504 const size_t mx )
const
507 const size_t num = ++m_infos[
msg] ;
509 if ( num > mx ) {
return st ; }
511 {
return Print (
"The INFO message is suppressed : '" +
521 template <
class PBASE >
527 if ( !this->msgLevel( lvl ) ) {
return st ; }
530 MsgStream& str = this->msgStream( lvl ) ;
539 { str <<
" StatusCode=" << st.
getCode() ; }
541 { str <<
" StatusCode=FAILURE" ; }
554 template <
class PBASE >
560 ++m_exceptions[
msg ];
561 Print (
"Exception (re)throw: " + msg , sc ,
MSG::FATAL ).ignore();
569 template <
class PBASE >
571 const std::exception & exc ,
575 ++m_exceptions[
msg ];
576 Print (
"Exception (re)throw: " + msg , sc ,
MSG::FATAL ).ignore();
584 template <
class PBASE >
589 ++m_exceptions[
msg ];
590 Print (
"Exception throw: " + msg , sc ,
MSG::FATAL ).ignore();
598 template <
class PBASE >
602 if ( counters().empty() ) {
return 0 ; }
603 MsgStream& msg = this->msgStream ( level ) ;
605 msg <<
"Number of counters : " << counters().size() ;
607 if ( !counters().empty() ) { msg << std::endl << m_header ; }
609 for (
const auto& entry : counters() )
616 m_format1 , m_format2 );
621 return counters().size() ;
628 template <
class PBASE >
632 boost::format ftm (
" #%|-10s| = %|.8s| %|23t| Message = '%s'" );
634 auto print = [&](
const Counter&
c,
const std::string& label) {
635 for (
const auto&
i : c ) {
636 this->msgStream(level)
637 << ( ftm % label %
i.second %
i.first )
642 print( m_exceptions,
"EXCEPTIONS" );
643 print( m_errors,
"ERRORS" );
644 print( m_warnings,
"WARNINGS" );
645 print( m_infos,
"INFOS" );
649 m_exceptions .size () +
651 m_warnings .size () +
661 template <
class PBASE >
666 MsgStream& msg = this->msgStream ( level );
667 const auto&
properties = this->getProperties() ;
668 msg <<
"List of ALL properties of "
673 msg <<
"Property ['Name': Value] = " << *
property <<
endmsg ;
682 template <
class PBASE >
695 if ( this->
msgSvc()->outputLevel(this->
name()) != this->outputLevel() )
697 this->
msgSvc()->setOutputLevel( this->
name(), this->outputLevel() );
703 this->debug() <<
"Property update for "
704 << theProp.
name() <<
" : new value = " << this->outputLevel() <<
endmsg;
716 template <
class PBASE >
719 const std::string& location ,
720 const bool useRootInTES )
const
723 Assert ( svc ,
"put():: Invalid 'service'!" ) ;
724 Assert (
object ,
"put():: Invalid 'Object'!" ) ;
725 Assert ( !location.empty() ,
"put():: Invalid 'address' = '' " ) ;
727 const std::string & fullLocation = fullTESLocation( location, useRootInTES );
729 const StatusCode status =
'/' == fullLocation[0] ?
730 svc -> registerObject( fullLocation ,
object ) :
731 svc -> registerObject(
"/Event/" + fullLocation ,
object ) ;
734 { Exception (
"put():: could not register '" +
736 "' at address '" + fullLocation +
"'" , status ) ; }
738 { Print(
"The object of type '" +
740 "' is registered in TS at address '"
741 + fullLocation +
"'" , status ,
MSG::DEBUG ).ignore() ; }
749 template <
class PBASE >
754 if (
this -> errorsPrint() ) {
this -> printErrors () ; }
759 template <
class PBASE >
764 if (
this -> propsPrint() ) {
this -> printProps (
MSG::ALWAYS ) ; }
769 template <
class PBASE >
774 if (
this -> statPrint() ) {
this -> printStat (
MSG::ALWAYS ) ; }
Definition of the MsgStream class used to transmit messages.
virtual const std::vector< const Property * > * getProperties(const std::string &client) const =0
Get the properties associated to a given client.
reverse_wrapper< T > reverse(T &&iterable)
Define general base for Gaudi exception.
StatusCode releaseSvc(const IInterface *svc) const
manual forced (and 'safe') release of the service
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
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
void addToServiceList(SmartIF< IService > svc) const
Add the given service to the list of acquired services.
bool isSuccess() const
Test for a status code of SUCCESS.
auto begin(reverse_wrapper< T > &w)
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.
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
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.
virtual const std::string & rootName() const =0
Get Name of root Event.
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".
bool isValid() const
Allow for check if smart pointer is valid.
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
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
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.