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