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