13 #include "GaudiKernel/MsgStream.h"
14 #include "GaudiKernel/AttribStringParser.h"
15 #include "GaudiKernel/DataObject.h"
16 #include "GaudiKernel/IAlgorithm.h"
17 #include "GaudiKernel/ISvcLocator.h"
18 #include "GaudiKernel/IAlgManager.h"
19 #include "GaudiKernel/IIncidentSvc.h"
20 #include "GaudiKernel/DataIncident.h"
21 #include "GaudiKernel/IDataProviderSvc.h"
22 #include "GaudiKernel/IToolSvc.h"
23 #include "GaudiKernel/TypeNameString.h"
24 #include "GaudiKernel/ToStream.h"
25 #include "GaudiKernel/Chrono.h"
26 #include "GaudiKernel/LockedChrono.h"
37 #pragma warning(disable:2259)
39 #include "boost/format.hpp"
40 #include "boost/lexical_cast.hpp"
41 #include "GaudiKernel/Property.h"
52 , m_trapType (
"DataFault")
53 , m_dataSvcName (
"EventDataSvc" )
54 , m_partialPath (
true )
57 , m_allowInitFailure(
false)
65 , m_updateRequired (
true )
66 , m_prefix (
"/Event/" )
76 , m_locked_nodes (
false )
77 , m_locked_algs (
false )
78 , m_locked_all (
false )
85 "The type of handled Incident" ) ;
87 declareProperty (
"DataSvc" , m_dataSvcName ) ;
89 declareProperty (
"UsePreceedingPath" , m_partialPath ) ;
93 "Dump the configuration and stastics" ) ->
99 "Flag to (pre)initialize all algorithms" ) ;
101 (
"AllowPreInitializeFailure" ,
103 "Allow (pre)initialization of algorithms to fail without stopping the application" ) ;
105 declareProperty (
"Algorithms" , m_algMapping ) ->
107 declareProperty (
"Nodes" , m_nodeMapping ) ->
110 declareProperty (
"AlgMap" , m_algMap ) ->
112 declareProperty (
"NodeMap" , m_nodeMap ) ->
115 declareProperty (
"Prefix" , m_prefix ) ;
117 declareProperty(
"NodeMappingTools", m_nodeMapTools,
118 "List of tools of type IDODNodeMapper");
119 declareProperty(
"AlgMappingTools", m_algMapTools,
120 "List of tools of type IDODAlgMapper");
138 <<
"The property 'Nodes' is obsolete, switch to map-like 'NodeMap' "
139 <<
" = { 'data' : 'type' } "
150 <<
"The property 'Algorithms' is obsolete, switch to map-like 'AlgMap' "
151 <<
" = { 'data' : 'algorithm' } "
177 inline std::string no_prefix
178 (
const std::string&
value ,
179 const std::string& prefix )
182 !prefix.empty() && 0 == value.find(prefix) ?
183 std::string( value , prefix.size() ) : value ;
193 inline size_t add_prefix ( MAP& _map ,
const std::string& prefix )
196 if ( prefix.empty() ) {
return 0 ; }
198 for (
typename MAP::iterator it = _map.begin() ; _map.end() != it ; ++it )
200 if ( 0 != it->first.find(prefix) )
202 std::string key = prefix + it->first ;
203 std::string value = it->second ;
205 _map[ key ] =
value ;
206 return 1 + add_prefix ( _map , prefix ) ;
219 inline size_t get_dir (
const std::string&
object ,
SET& _set )
221 std::string::size_type ifind =
object.rfind(
'/') ;
223 if ( std::string::npos == ifind ) {
return 0 ; }
224 if ( 0 == ifind ) {
return 0 ; }
226 const std::string top = std::string(
object , 0 , ifind) ;
228 return 1 + get_dir ( top , _set ) ;
236 template <
class MAP,
class SET>
237 inline size_t get_dirs (
const MAP& _map,
SET& _set )
239 size_t size = _set.size() ;
240 for (
typename MAP::const_iterator
item = _map.begin() ;
241 _map.end() !=
item ; ++
item ) { get_dir (
item->first , _set ) ; }
242 return _set.size() - size ;
248 ClassH cl = TClass::GetClass(type.c_str()) ;
251 <<
"Failed to access dictionary class for "
252 << name <<
" of type:" << type <<
endmsg;
302 typedef std::set<std::string> Set ;
307 Set::iterator _e = dirs.find(
"/Event") ;
308 if ( dirs.end() != _e ) { dirs.erase( _e ) ; }
310 for ( Set::const_iterator dir = dirs.begin() ; dirs.end() != dir ; ++dir )
321 for ( Map::const_iterator ialg =
m_algMap.begin() ;
328 for ( Map::const_iterator inode =
m_nodeMap.begin() ;
369 <<
"Handled \"" <<
m_trapType <<
"\" incidents: "
377 (
"Algorithm timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " ,
System::milliSec )
382 (
"Nodes timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " ,
System::milliSec )
387 (
"Algs timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " ,
System::milliSec )
392 (
"All timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " ,
System::milliSec )
414 warning() <<
"ToolSvc already finalized: cannot release tools. Check options." <<
endmsg;
462 error() <<
"Failed to retrieve the IAlgManager interface." <<
endmsg;
468 error() <<
"Failed to retrieve Incident service." <<
endmsg;
476 <<
"Failed to retrieve the data provider interface of "
490 std::vector<std::string>::iterator
i;
511 std::string nam, typ, tag;
516 using Parser = Gaudi::Utils::AttribStringParser;
517 for (
auto attrib: Parser(node)) {
518 switch( ::
toupper(attrib.tag[0]) ) {
520 tag = std::move(attrib.value);
523 nam = std::move(attrib.value);
532 <<
"The obsolete property 'Nodes' redefines the action for '"
533 + tag +
"' to be '" +nam+
"'"
548 std::string typ, tag;
552 using Parser = Gaudi::Utils::AttribStringParser;
553 for (
auto attrib: Parser(alg)) {
554 switch( ::
toupper(attrib.tag[0]) ) {
556 tag = std::move(attrib.value);
559 typ = std::move(attrib.value);
569 <<
"The obsolete property 'Algorithms' redefines the action for '"
570 + tag +
"' to be '" +item.
type() +
"/"+item.
name()+
"'"
593 <<
"Failed to create algorithm "
605 <<
"Failed to initialize algorithm "
618 <<
"Failed to 'run' algorithm "
634 ToolGetter(
const std::string &_path): path(_path) {}
647 inline bool isGood(
const std::string& r) {
return !r.empty();}
654 const ToolGetter getter;
655 const std::list<IDODNodeMapper*> &nodes;
656 const std::list<IDODAlgMapper*> &algs;
658 template <
class R,
class T>
659 R find(
const std::list<T*> &
l)
const {
660 typename std::list<T*>::const_iterator
i;
661 for(i = l.begin(); i != l.end(); ++
i) {
662 R result = getter(*i);
663 if (isGood(result))
return result;
669 Finder(
const std::string &_path,
670 const std::list<IDODNodeMapper*> &_nodes,
671 const std::list<IDODAlgMapper*> &_algs): getter(_path), nodes(_nodes), algs(_algs) {
674 inline std::string node()
const {
675 return find<std::string>(nodes);
679 return find<Gaudi::Utils::TypeNameString>(algs);
698 if ( 0 == inc ) { return ; }
705 <<
"Incident: [" << incident.
type () <<
"] "
706 <<
" = " << incident.
source ()
707 <<
" Location:" << inc->tag() <<
endmsg;
732 verbose() <<
"Try to find mapping with mapping tools" <<
endmsg;
735 std::string node = finder.node();
782 <<
"Failed to get dictionary for class '"
784 <<
"' for location:" << tag <<
endmsg;
794 <<
"Failed to create an object of type:"
795 << n.
clazz->GetName() <<
" for location:" << tag
805 <<
MSG::ERROR <<
"Failed to register an object of type:"
806 << n.
name <<
" at location:" << tag
831 <<
"Failed to configure handler for: "
844 <<
"Failed to execute the algorithm:"
860 const bool mode )
const
862 if ( m_algs.empty() && m_nodes.empty() ) { return ; }
864 typedef std::pair<std::string,std::string> Pair ;
865 typedef std::map<std::string,Pair> PMap ;
869 m_algs.end() != alg ; ++alg )
871 PMap::const_iterator
check = _m.find(alg->first) ;
872 if ( _m.end() !=
check )
876 <<
" The data item is activated for '"
877 << check->first <<
"' as '" << check->second.first <<
"'" <<
endmsg ;
879 const Leaf& l = alg->second ;
882 if ( !mode && 0 == l.
num ) { continue ; }
885 if ( mode ) { val = ( 0 == l.
algorithm ) ?
"F" :
"T" ; }
886 else { val = boost::lexical_cast<std::string>( l.
num ) ; }
888 _m[ no_prefix ( alg->first , m_prefix ) ] = std::make_pair ( nam , val ) ;
892 m_nodes.end() != node ; ++node )
894 PMap::const_iterator
check = _m.find(node->first) ;
895 if ( _m.end() !=
check )
899 <<
" The data item is already activated for '"
900 << check->first <<
"' as '" << check->second.first <<
"'" <<
endmsg ;
902 const Node&
n = node->second ;
903 std::string nam =
"'" + n.
name +
"'" ;
907 if ( !mode && 0 == n.
num ) { continue ; }
909 if ( mode ) { val = ( 0 == n.
clazz ) ?
"F" :
"T" ; }
910 else { val = boost::lexical_cast<std::string>( n.
num ) ; }
912 _m[ no_prefix ( node->first , m_prefix ) ] = std::make_pair ( nam , val ) ;
915 if ( _m.empty() ) { return ; }
921 for ( PMap::const_iterator it = _m.begin() ; _m.end() != it ; ++it )
923 n1 = std::max ( n1 , it->first.size() ) ;
924 n2 = std::max ( n2 , it->second.first.size() ) ;
925 n3 = std::max ( n3 , it->second.second.size() ) ;
927 if ( 10 > n1 ) { n1 = 10 ; }
928 if ( 10 > n2 ) { n2 = 10 ; }
929 if ( 60 < n1 ) { n1 = 60 ; }
930 if ( 60 < n2 ) { n2 = 60 ; }
933 const std::string _f =
" | %%1$-%1%.%1%s | %%2$-%2%.%2%s | %%3$%3%.%3%s |" ;
937 const std::string _format = _ff.str() ;
941 if ( mode ) { msg <<
"Data-On-Demand Actions enabled for:" ; }
942 else { msg <<
"Data-On-Demand Actions has been used for:" ; }
945 fmt1 %
"Address" %
"Creator" % ( mode ?
"S" :
"#" ) ;
947 const std::string
header = fmt1.str() ;
948 std::string
line = std::string( header.size() ,
'-' ) ;
951 msg << std::endl << line
952 << std::endl << header
953 << std::endl <<
line ;
956 for ( PMap::const_iterator
item = _m.begin() ;
961 ( fmt %
item->first %
item->second.first %
item->second.second ) ;
964 msg << std::endl << line <<
endmsg ;
void i_setNodeHandler(const std::string &name, const std::string &type)
Internal method to initialize a node handler.
virtual SmartIF< IAlgorithm > & algorithm(const Gaudi::Utils::TypeNameString &typeName, const bool createIf=true)=0
Returns a smart pointer to a service.
Definition of the MsgStream class used to transmit messages.
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
const std::string & type() const
Access to the incident type.
The DataOnDemandSvc listens to incidents typically triggered by the data service of the configurable ...
virtual StatusCode sysStart()=0
Startup method invoked by the framework.
ChronoEntity m_timer_algs
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
std::list< IDODNodeMapper * > m_nodeMappers
const std::string & source() const
Access to the source of the incident.
bool isSuccess() const
Test for a status code of SUCCESS.
MsgStream & stream() const
get the message stream
SmartIF< IIncidentSvc > m_incSvc
Incident service.
virtual StatusCode reinitialize()
Inherited Service overrides: Service reinitialization.
int outputLevel() const
get the Service's output level
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
std::vector< std::string > m_algMapTools
std::string m_trapType
Trap name.
std::string m_dataSvcName
Data service name.
Setup m_nodeMapping
Mapping to nodes.
A small utility class for chronometry of user codes.
Map m_algMap
the major configuration property { 'data' : 'algorithm' }
bool isFailure() const
Test for a status code of FAILURE.
The helper class to represent the efficient "key" for access.
virtual StatusCode sysExecute()=0
System execution. This method invokes the execute() method of a concrete algorithm.
virtual StatusCode initialize()
Inherited Service overrides: Service initialization.
virtual const std::string & name() const =0
Retrieve the name of the instance.
SmartIF< IDataProviderSvc > m_dataSvc
Data provider reference.
virtual StatusCode createAlgorithm(const std::string &algtype, const std::string &algname, IAlgorithm *&alg, bool managed=false)=0
Create an instance of a algorithm type that has been declared beforehand and assigns to it a name...
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
ClassH clazz
the actual class
std::list< IDODAlgMapper * > m_algMappers
Interface of tools used by the DataOnDemandSvc to choose the type of node to be created at a path...
Setup m_algMapping
Mapping to algorithms.
Helper class to parse a string of format "type/name".
StatusCode setup()
Setup routine (called by (re-) initialize.
virtual void handle(const Incident &incident)
IIncidentListener interfaces overrides: incident handling.
bool m_allowInitFailure
flag to allow DataOnDemand initialization to succeed even if the (pre)initialization of the algorithm...
virtual Gaudi::StateMachine::State FSMState() const =0
Get the current state.
#define DECLARE_COMPONENT(type)
StatusCode execHandler(const std::string &tag, Leaf &leaf)
Execute leaf handler (algorithm)
This class is used for returning status codes from appropriate routines.
void update_dump(Property &)
update handler for 'Dump' property
StatusCode setupNodeHandlers()
Initialize node handlers.
iterator find(const key_type &key)
Helper class of the DataOnDemandSvc.
virtual Gaudi::Utils::TypeNameString algorithmForPath(const std::string &path)=0
For the given path, returns a TypeNameString object identifying the algorithm to be run to produce th...
std::vector< std::string > m_nodeMapTools
NodeMap m_nodes
Map of "empty" objects to be placed as intermediate nodes.
void dump(const MSG::Level level, const bool mode=true) const
dump the content of DataOnDemand service
map_type::const_iterator const_iterator
virtual Gaudi::StateMachine::State FSMState() const
Get the current state.
virtual const std::string & name() const
Retrieve name of the service.
void reset(TYPE *ptr=0)
Set the internal pointer to the passed one disposing of the old one.
virtual StatusCode sysInitialize()
Initialize Service.
bool m_partialPath
Flag to allow for the creation of partial leaves.
virtual StatusCode reinitialize()
Initialization (from INITIALIZED or RUNNING to INITIALIZED, via CONFIGURED).
std::string outputUserTime() const
print the chrono ;
Interface of tools used by the DataOnDemandSvc to choose the algorithm to be run to produce the data ...
Property base class allowing Property* collections to be "homogeneous".
map_type::iterator iterator
SmartIF< IAlgManager > m_algMgr
Algorithm manager.
virtual StatusCode initialize()
Initialization (from CONFIGURED to INITIALIZED).
SmartIF< IToolSvc > m_toolSvc
Data provider reference.
Helper object, useful for measurement of CPU-performance of highly-recursive structures, e.g.
AlgMap m_algs
Map of algorithms to handle incidents.
bool m_dump
flag to force the printout
bool m_init
flag to warm up the configuration
const std::string & type() const
ChronoEntity m_timer_nodes
Base class for all Incidents (computing events).
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
bool dataObject
trivial object? DataObject?
DataOnDemandSvc(const std::string &name, ISvcLocator *svc)
Standard initializing service constructor.
Templated class to add the standard messaging functionalities.
virtual StatusCode finalize()
Inherited Service overrides: Service finalization.
StatusCode service(const std::string &name, const T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn't already exist.
virtual bool isInitialized() const =0
check if the algorithm is initialized properly
Map m_nodeMap
the major configuration property { 'data' : 'type' }
virtual void removeListener(IIncidentListener *lis, const std::string &type="")=0
Remove listener.
Data service incident class.
const std::string & name() const
StatusCode setupAlgHandlers()
Initialize leaf handlers.
Helper class of the DataOnDemandSvc.
virtual std::string nodeTypeForPath(const std::string &path)=0
For the given path, returns a the type name of the object to be created at the path.
virtual StatusCode registerObject(const std::string &fullPath, DataObject *pObject)=0
Register object with the data store.
virtual ~DataOnDemandSvc()
Standard destructor.
A DataObject is the base class of any identifiable object on any data store.
StatusCode i_setAlgHandler(const std::string &name, const Gaudi::Utils::TypeNameString &alg)
Internal method to initialize an algorithm handler.
StatusCode configureHandler(Leaf &leaf)
Configure handler for leaf.
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
void update_2(Property &p)
void toupper(std::string &s)
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
virtual StatusCode finalize()
Finalize (from INITIALIZED to CONFIGURED).
void update_3(Property &p)
void update_1(Property &p)
StatusCode update()
update the handlers
SmartIF< ISvcLocator > & serviceLocator() const
Retrieve pointer to service locator.