The Gaudi Framework  v30r3 (a5ef0a68)
EventLoopMgr.cpp
Go to the documentation of this file.
1 #define GAUDISVC_EVENTLOOPMGR_CPP
2 
10 #include "GaudiKernel/Incident.h"
11 #include "GaudiKernel/MsgStream.h"
12 
13 #include <chrono>
14 
15 #include "EventLoopMgr.h"
16 #include "HistogramAgent.h"
17 
18 // Instantiation of a static factory class used by clients to create instances of this service
20 
21 #define ON_DEBUG if ( UNLIKELY( outputLevel() <= MSG::DEBUG ) )
22 #define ON_VERBOSE if ( UNLIKELY( outputLevel() <= MSG::VERBOSE ) )
23 
24 #define DEBMSG ON_DEBUG debug()
25 #define VERMSG ON_VERBOSE verbose()
26 
27 //--------------------------------------------------------------------------------------------
28 // Standard Destructor
29 //--------------------------------------------------------------------------------------------
31 
32 //--------------------------------------------------------------------------------------------
33 // implementation of IAppMgrUI::initialize
34 //--------------------------------------------------------------------------------------------
36 {
37  // Initialize the base class
39  if ( !sc.isSuccess() ) {
40  DEBMSG << "Error Initializing base class MinimalEventLoopMgr." << endmsg;
41  return sc;
42  }
43 
44  // Setup access to event data services
45  m_evtDataMgrSvc = serviceLocator()->service( "EventDataSvc" );
46  if ( !m_evtDataMgrSvc ) {
47  fatal() << "Error retrieving EventDataSvc interface IDataManagerSvc." << endmsg;
48  return StatusCode::FAILURE;
49  }
50  m_evtDataSvc = serviceLocator()->service( "EventDataSvc" );
51  if ( !m_evtDataSvc ) {
52  fatal() << "Error retrieving EventDataSvc interface IDataProviderSvc." << endmsg;
53  return StatusCode::FAILURE;
54  }
55 
56  // Obtain the IProperty of the ApplicationMgr
58  if ( !m_appMgrProperty ) {
59  fatal() << "IProperty interface not found in ApplicationMgr." << endmsg;
60  return StatusCode::FAILURE;
61  }
62 
63  // We do not expect a Event Selector necessarily being declared
64  setProperty( m_appMgrProperty->getProperty( "EvtSel" ) ).ignore();
65 
66  if ( m_evtsel != "NONE" || m_evtsel.length() == 0 ) {
67  m_evtSelector = serviceLocator()->service( "EventSelector" );
68  if ( m_evtSelector ) {
69  // Setup Event Selector
71  if ( !sc.isSuccess() ) {
72  fatal() << "Can not create the event selector Context." << endmsg;
73  return sc;
74  }
75  } else {
76  fatal() << "EventSelector not found." << endmsg;
77  return sc;
78  }
79  } else {
80  m_evtSelector = nullptr;
81  m_evtContext = nullptr;
82  if ( m_warnings ) {
83  warning() << "Unable to locate service \"EventSelector\" " << endmsg;
84  warning() << "No events will be processed from external input." << endmsg;
85  }
86  }
87 
88  // Setup access to histogramming services
89  m_histoDataMgrSvc = serviceLocator()->service( "HistogramDataSvc" );
90  if ( !m_histoDataMgrSvc ) {
91  fatal() << "Error retrieving HistogramDataSvc." << endmsg;
92  return sc;
93  }
94  // Setup histogram persistency
95  m_histoPersSvc = serviceLocator()->service( "HistogramPersistencySvc" );
96  if ( !m_histoPersSvc ) {
97  warning() << "Histograms cannot not be saved - though required." << endmsg;
98  return sc;
99  }
100 
101  return StatusCode::SUCCESS;
102 }
103 //--------------------------------------------------------------------------------------------
104 // implementation of IService::reinitialize
105 //--------------------------------------------------------------------------------------------
107 {
108 
109  // Initialize the base class
111  if ( !sc.isSuccess() ) {
112  DEBMSG << "Error Initializing base class MinimalEventLoopMgr." << endmsg;
113  return sc;
114  }
115 
116  // Check to see whether a new Event Selector has been specified
117  setProperty( m_appMgrProperty->getProperty( "EvtSel" ) );
118  if ( m_evtsel != "NONE" || m_evtsel.length() == 0 ) {
119  auto theSvc = serviceLocator()->service<IService>( "EventSelector" );
120  auto theEvtSel = theSvc.as<IEvtSelector>();
121  if ( theEvtSel && ( theEvtSel.get() != m_evtSelector.get() ) ) {
122  // Setup Event Selector
123  if ( m_evtSelector.get() && m_evtContext ) {
124  // Need to release context before switching to new event selector
126  m_evtContext = nullptr;
127  }
128  m_evtSelector = theEvtSel;
129  if ( theSvc->FSMState() == Gaudi::StateMachine::INITIALIZED ) {
130  sc = theSvc->reinitialize();
131  if ( !sc.isSuccess() ) {
132  error() << "Failure Reinitializing EventSelector " << theSvc->name() << endmsg;
133  return sc;
134  }
135  } else {
136  sc = theSvc->sysInitialize();
137  if ( !sc.isSuccess() ) {
138  error() << "Failure Initializing EventSelector " << theSvc->name() << endmsg;
139  return sc;
140  }
141  }
143  if ( !sc.isSuccess() ) {
144  error() << "Can not create Context " << theSvc->name() << endmsg;
145  return sc;
146  }
147  info() << "EventSelector service changed to " << theSvc->name() << endmsg;
148  } else if ( m_evtSelector ) {
149  if ( m_evtContext ) {
151  m_evtContext = nullptr;
152  }
154  if ( !sc.isSuccess() ) {
155  error() << "Can not create Context " << theSvc->name() << endmsg;
156  return sc;
157  }
158  }
159  } else if ( m_evtSelector && m_evtContext ) {
161  m_evtSelector = nullptr;
162  m_evtContext = nullptr;
163  }
164  return StatusCode::SUCCESS;
165 }
166 
167 //--------------------------------------------------------------------------------------------
168 // implementation of IService::stop
169 //--------------------------------------------------------------------------------------------
171 {
172  if ( !m_endEventFired ) {
173  // Fire pending EndEvent incident
174  m_incidentSvc->fireIncident( Incident( name(), IncidentType::EndEvent ) );
175  m_endEventFired = true;
176  }
177  return MinimalEventLoopMgr::stop();
178 }
179 
180 //--------------------------------------------------------------------------------------------
181 // implementation of IAppMgrUI::finalize
182 //--------------------------------------------------------------------------------------------
184 {
185  StatusCode sc;
186 
187  // Finalize base class
189  if ( !sc.isSuccess() ) {
190  error() << "Error finalizing base class" << endmsg;
191  return sc;
192  }
193 
194  // Save Histograms Now
195  if ( m_histoPersSvc ) {
196  HistogramAgent agent;
197  sc = m_histoDataMgrSvc->traverseTree( &agent );
198  if ( sc.isSuccess() ) {
199  IDataSelector* objects = agent.selectedObjects();
200  // skip /stat entry!
201  if ( objects->size() > 0 ) {
202  for ( auto& i : *objects ) {
203  IOpaqueAddress* pAddr = nullptr;
204  StatusCode iret = m_histoPersSvc->createRep( i, pAddr );
205  if ( iret.isSuccess() ) {
206  i->registry()->setAddress( pAddr );
207  } else {
208  sc = iret;
209  }
210  }
211  for ( auto& i : *objects ) {
212  IRegistry* reg = i->registry();
213  StatusCode iret = m_histoPersSvc->fillRepRefs( reg->address(), i );
214  if ( !iret.isSuccess() ) sc = iret;
215  }
216  }
217  if ( sc.isSuccess() ) {
218  info() << "Histograms converted successfully according to request." << endmsg;
219  } else {
220  error() << "Error while saving Histograms." << endmsg;
221  }
222  } else {
223  error() << "Error while traversing Histogram data store" << endmsg;
224  }
225  }
226 
227  // Release event selector context
228  if ( m_evtSelector && m_evtContext ) {
230  m_evtContext = nullptr;
231  }
232 
233  // Release all interfaces...
234  m_histoDataMgrSvc = nullptr;
235  m_histoPersSvc = nullptr;
236 
237  m_evtSelector = nullptr;
238  m_evtDataSvc = nullptr;
239  m_evtDataMgrSvc = nullptr;
240 
241  return StatusCode::SUCCESS;
242 }
243 
244 //--------------------------------------------------------------------------------------------
245 // executeEvent(void* par)
246 //--------------------------------------------------------------------------------------------
248 {
249 
250  // DP Monitoring
251 
252  // Fire BeginEvent "Incident"
253  m_incidentSvc->fireIncident( Incident( name(), IncidentType::BeginEvent ) );
254  // An incident may schedule a stop, in which case is better to exit before the actual execution.
255  if ( m_scheduledStop ) {
256  always() << "Terminating event processing loop due to a stop scheduled by an incident listener" << endmsg;
257  return StatusCode::SUCCESS;
258  }
259 
260  // Execute Algorithms
261  m_incidentSvc->fireIncident( Incident( name(), IncidentType::BeginProcessing ) );
263  m_incidentSvc->fireIncident( Incident( name(), IncidentType::EndProcessing ) );
264 
265  // Check if there was an error processing current event
266  if ( UNLIKELY( !sc.isSuccess() ) ) {
267  error() << "Terminating event processing loop due to errors" << endmsg;
268  }
269  return sc;
270 }
271 
272 //--------------------------------------------------------------------------------------------
273 // implementation of IAppMgrUI::nextEvent
274 //--------------------------------------------------------------------------------------------
275 // External libraries
276 #include "GaudiKernel/Memory.h"
278 {
279 
280  // DP Monitoring
281  // Calculate runtime
283  typedef Clock::time_point time_point;
284 
285  const float oneOver1024 = 1.f / 1024.f;
286 
287  static int total_nevt = 0;
288  DataObject* pObject = nullptr;
289  StatusCode sc( StatusCode::SUCCESS, true );
290 
291  // loop over events if the maxevt (received as input) if different from -1.
292  // if evtmax is -1 it means infinite loop
293  time_point start_time = Clock::now();
294  for ( int nevt = 0; maxevt == -1 || nevt < maxevt; ++nevt, ++total_nevt ) {
295 
296  if ( 1 == nevt ) // reset after first evt
297  start_time = Clock::now();
298 
299  // always() << "Event Number = " << total_nevt
300  // << " WSS (MB) = " << System::mappedMemory(System::MemoryUnit::kByte)*oneOver1024
301  // << " Time (s) = " << secsFromStart(start_time) << endmsg;
302 
303  // Check if there is a scheduled stop issued by some algorithm/service
304  if ( m_scheduledStop ) {
305  m_scheduledStop = false;
306  always() << "Terminating event processing loop due to scheduled stop" << endmsg;
307  break;
308  }
309  // Clear the event store, if used in the event loop
310  if ( 0 != total_nevt ) {
311 
312  if ( !m_endEventFired ) {
313  // Fire EndEvent "Incident" (it is considered part of the clearing of the TS)
314  m_incidentSvc->fireIncident( Incident( name(), IncidentType::EndEvent ) );
315  m_endEventFired = true;
316  }
317  sc = m_evtDataMgrSvc->clearStore();
318  if ( !sc.isSuccess() ) {
319  DEBMSG << "Clear of Event data store failed" << endmsg;
320  }
321  }
322 
323  // Setup event in the event store
324  if ( m_evtContext ) {
325  IOpaqueAddress* addr = nullptr;
326  // Only if there is a EventSelector
327  sc = getEventRoot( addr );
328  if ( !sc.isSuccess() ) {
329  info() << "No more events in event selection " << endmsg;
330  break;
331  }
332  // Set root clears the event data store first
333  sc = m_evtDataMgrSvc->setRoot( "/Event", addr );
334  if ( !sc.isSuccess() ) {
335  warning() << "Error declaring event root address." << endmsg;
336  continue;
337  }
338  sc = m_evtDataSvc->retrieveObject( "/Event", pObject );
339  if ( !sc.isSuccess() ) {
340  warning() << "Unable to retrieve Event root object" << endmsg;
341  break;
342  }
343  } else {
344  sc = m_evtDataMgrSvc->setRoot( "/Event", new DataObject() );
345  if ( !sc.isSuccess() ) {
346  warning() << "Error declaring event root DataObject" << endmsg;
347  }
348  }
349  // Execute event for all required algorithms
350  sc = executeEvent( nullptr );
351  m_endEventFired = false;
352  if ( !sc.isSuccess() ) {
353  error() << "Terminating event processing loop due to errors" << endmsg;
355  return sc;
356  }
357  }
358  time_point end_time = Clock::now();
359 
360  if ( UNLIKELY( outputLevel() <= MSG::DEBUG ) )
361  debug() << "---> Loop Finished - "
362  << " WSS " << System::mappedMemory( System::MemoryUnit::kByte ) * oneOver1024
363  << " | total time (skipping 1st evt) "
364  << std::chrono::duration_cast<std::chrono::nanoseconds>( end_time - start_time ).count() << " ns" << endmsg;
365 
366  return StatusCode::SUCCESS;
367 }
368 
371 {
372  refpAddr = nullptr;
374  if ( !sc.isSuccess() ) return sc;
375  // Create root address and assign address to data service
376  sc = m_evtSelector->createAddress( *m_evtContext, refpAddr );
377  if ( !sc.isSuccess() ) {
378  sc = m_evtSelector->next( *m_evtContext );
379  if ( sc.isSuccess() ) {
380  sc = m_evtSelector->createAddress( *m_evtContext, refpAddr );
381  if ( !sc.isSuccess() ) {
382  warning() << "Error creating IOpaqueAddress." << endmsg;
383  }
384  }
385  }
386  return sc;
387 }
virtual StatusCode traverseTree(IDataStoreAgent *pAgent)=0
Analyse by traversing all data objects in the data store.
#define UNLIKELY(x)
Definition: Kernel.h:122
constexpr static const auto FAILURE
Definition: StatusCode.h:88
StatusCode finalize() override
implementation of IService::finalize
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:288
StatusCode finalize() override
implementation of IService::finalize
bool m_scheduledStop
Scheduled stop of event processing.
SmartIF< IConversionSvc > m_histoPersSvc
Reference to the Histogram Persistency Service.
Definition: EventLoopMgr.h:59
StatusCode setProperty(const Gaudi::Details::PropertyBase &p) override
set the property form another property
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
Gaudi::Property< bool > m_warnings
Definition: EventLoopMgr.h:46
The Event Selector Interface.
Definition: IEvtSelector.h:18
bool isSuccess() const
Definition: StatusCode.h:287
HistogramAgent base in charge of collecting all the refereces to DataObjects in a transient store tha...
virtual StatusCode setRoot(std::string root_name, DataObject *pObject)=0
Initialize data store for new event by giving new event path.
StatusCode initialize() override
implementation of IService::initialize
int outputLevel() const
get the Service&#39;s output level
Definition: Service.h:164
StatusCode reinitialize() override
implementation of IService::reinitialize
T duration_cast(T...args)
virtual StatusCode getProperty(Gaudi::Details::PropertyBase *p) const =0
Get the property by property.
virtual StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress)=0
Convert the transient object to the requested representation.
virtual StatusCode clearStore()=0
Remove all data objects in the data store.
Class definition of EventLoopMgr.
Definition: EventLoopMgr.h:38
StatusCode reinitialize() override
implementation of IService::reinitialize
StatusCode stop() override
implementation of IService::stop
#define DECLARE_COMPONENT(type)
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:82
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:79
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
StatusCode executeEvent(void *par) override
implementation of IEventProcessor::executeEvent(void* par)
StatusCode nextEvent(int maxevt) override
implementation of IService::nextEvent
General service interface definition.
Definition: IService.h:18
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
StatusCode getEventRoot(IOpaqueAddress *&refpAddr)
Create event address using event selector.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
virtual StatusCode releaseContext(Context *&) const =0
Release the Context object.
virtual StatusCode retrieveObject(IRegistry *pDirectory, boost::string_ref path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.
IDataSelector * selectedObjects()
Return the set of selected DataObjects.
SmartIF< IIncidentSvc > m_incidentSvc
Reference to the incident service.
StatusCode setAppReturnCode(SmartIF< IProperty > &appmgr, int value, bool force=false)
Set the application return code.
Definition: AppReturnCode.h:51
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
SmartIF< IDataManagerSvc > m_evtDataMgrSvc
Reference to the Event Data Service&#39;s IDataManagerSvc interface.
Definition: EventLoopMgr.h:49
GAUDI_API long mappedMemory(MemoryUnit unit=kByte, InfoType fetch=Memory, long pid=-1)
Basic Process Information: priority boost.
Definition: Memory.cpp:204
T size(T...args)
StatusCode initialize() override
implementation of IService::initialize
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
SmartIF< IProperty > m_appMgrProperty
Property interface of ApplicationMgr.
Definition: EventLoopMgr.h:61
IEvtSelector::Context * m_evtContext
Event Iterator.
Definition: EventLoopMgr.h:55
SmartIF< IEvtSelector > m_evtSelector
Reference to the Event Selector.
Definition: EventLoopMgr.h:53
#define DEBMSG
StatusCode stop() override
implementation of IService::stop
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:165
Base class for all Incidents (computing events).
Definition: Incident.h:17
constexpr int AlgorithmFailure
Definition: AppReturnCode.h:26
Gaudi::Property< std::string > m_evtsel
Definition: EventLoopMgr.h:45
bool m_endEventFired
Flag to avoid to fire the EnvEvent incident twice in a row (and also not before the first event) ...
Definition: EventLoopMgr.h:64
SmartIF< IDataProviderSvc > m_evtDataSvc
Reference to the Event Data Service&#39;s IDataProviderSvc interface.
Definition: EventLoopMgr.h:51
virtual StatusCode next(Context &c) const =0
Fetch the next event or the first event if it will be use soon after the creation of the context...
virtual StatusCode createContext(Context *&c) const =0
Create and return a context object that will keep track of the state of selection.
~EventLoopMgr() override
Standard Destructor.
virtual StatusCode createAddress(const Context &c, IOpaqueAddress *&iop) const =0
Create an IOpaqueAddress object from the event fetched.
Opaque address interface definition.
int maxevt
Definition: Bootstrap.cpp:276
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
MsgStream & always() const
shortcut for the method msgStream(MSG::ALWAYS)
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the converted object.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: Service.cpp:291
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
StatusCode executeEvent(void *par) override
implementation of IEventProcessor::executeEvent(void* par)
SmartIF< IDataManagerSvc > m_histoDataMgrSvc
Reference to the Histogram Data Service.
Definition: EventLoopMgr.h:57