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