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 "HistogramAgent.h"
14 #include "EventLoopMgr.h"
15 
16 
17 // Instantiation of a static factory class used by clients to create instances of this service
19 
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 Constructor
29 //--------------------------------------------------------------------------------------------
30 EventLoopMgr::EventLoopMgr(const std::string& nam, ISvcLocator* svcLoc)
31 : MinimalEventLoopMgr(nam, svcLoc)
32 {
33  // Declare properties
34  declareProperty("HistogramPersistency", m_histPersName );
35  declareProperty("EvtSel", m_evtsel );
36  declareProperty("Warnings",m_warnings=true,
37  "Set this property to false to suppress warning messages");
38 }
39 
40 //--------------------------------------------------------------------------------------------
41 // Standard Destructor
42 //--------------------------------------------------------------------------------------------
44  delete m_evtContext;
45 }
46 
47 //--------------------------------------------------------------------------------------------
48 // implementation of IAppMgrUI::initialize
49 //--------------------------------------------------------------------------------------------
51  // Initialize the base class
53  if( !sc.isSuccess() ) {
54  DEBMSG << "Error Initializing base class MinimalEventLoopMgr." << endmsg;
55  return sc;
56  }
57 
58  // Setup access to event data services
59  m_evtDataMgrSvc = serviceLocator()->service("EventDataSvc");
60  if( !m_evtDataMgrSvc ) {
61  fatal() << "Error retrieving EventDataSvc interface IDataManagerSvc." << endmsg;
62  return StatusCode::FAILURE;
63  }
64  m_evtDataSvc = serviceLocator()->service("EventDataSvc");
65  if( !m_evtDataSvc ) {
66  fatal() << "Error retrieving EventDataSvc interface IDataProviderSvc." << endmsg;
67  return StatusCode::FAILURE;
68  }
69 
70  // Obtain the IProperty of the ApplicationMgr
71  m_appMgrProperty = serviceLocator();
72  if ( ! m_appMgrProperty ) {
73  fatal() << "IProperty interface not found in ApplicationMgr." << endmsg;
74  return StatusCode::FAILURE;
75  }
76 
77  // We do not expect a Event Selector necessarily being declared
78  setProperty(m_appMgrProperty->getProperty("EvtSel")).ignore();
79 
80  if( m_evtsel != "NONE" || m_evtsel.length() == 0) {
81  m_evtSelector = serviceLocator()->service("EventSelector");
82  if( m_evtSelector ) {
83  // Setup Event Selector
85  if( !sc.isSuccess() ) {
86  fatal() << "Can not create the event selector Context." << endmsg;
87  return sc;
88  }
89  }
90  else {
91  fatal() << "EventSelector not found." << endmsg;
92  return sc;
93  }
94  } else {
95  m_evtSelector = nullptr;
96  m_evtContext = nullptr;
97  if ( m_warnings ) {
98  warning() << "Unable to locate service \"EventSelector\" " << endmsg;
99  warning() << "No events will be processed from external input." << endmsg;
100  }
101  }
102 
103  // Setup access to histogramming services
104  m_histoDataMgrSvc = serviceLocator()->service("HistogramDataSvc");
105  if( !m_histoDataMgrSvc ) {
106  fatal() << "Error retrieving HistogramDataSvc." << endmsg;
107  return sc;
108  }
109  // Setup histogram persistency
110  m_histoPersSvc = serviceLocator()->service("HistogramPersistencySvc");
111  if( !m_histoPersSvc ) {
112  warning() << "Histograms cannot not be saved - though required." << endmsg;
113  return sc;
114  }
115 
116  return StatusCode::SUCCESS;
117 }
118 //--------------------------------------------------------------------------------------------
119 // implementation of IService::reinitialize
120 //--------------------------------------------------------------------------------------------
122 
123  // Initialize the base class
125  if( !sc.isSuccess() ) {
126  DEBMSG << "Error Initializing base class MinimalEventLoopMgr." << endmsg;
127  return sc;
128  }
129 
130  // Check to see whether a new Event Selector has been specified
132  if( m_evtsel != "NONE" || m_evtsel.length() == 0) {
133  auto theSvc = serviceLocator()->service<IService>("EventSelector");
134  auto theEvtSel = theSvc.as<IEvtSelector>();
135  if( theEvtSel && ( theEvtSel.get() != m_evtSelector.get() ) ) {
136  // Setup Event Selector
137  if ( m_evtSelector.get() && m_evtContext ) {
138  // Need to release context before switching to new event selector
140  m_evtContext = nullptr;
141  }
142  m_evtSelector = theEvtSel;
143  if (theSvc->FSMState() == Gaudi::StateMachine::INITIALIZED) {
144  sc = theSvc->reinitialize();
145  if( !sc.isSuccess() ) {
146  error() << "Failure Reinitializing EventSelector "
147  << theSvc->name( ) << endmsg;
148  return sc;
149  }
150  } else {
151  sc = theSvc->sysInitialize();
152  if( !sc.isSuccess() ) {
153  error() << "Failure Initializing EventSelector "
154  << theSvc->name( ) << endmsg;
155  return sc;
156  }
157  }
159  if( !sc.isSuccess() ) {
160  error() << "Can not create Context " << theSvc->name( ) << endmsg;
161  return sc;
162  }
163  info() << "EventSelector service changed to "
164  << theSvc->name( ) << endmsg;
165  }
166  else if ( m_evtSelector ) {
167  if ( m_evtContext ) {
169  m_evtContext = nullptr;
170  }
172  if( !sc.isSuccess() ) {
173  error() << "Can not create Context " << theSvc->name( ) << endmsg;
174  return sc;
175  }
176  }
177  }
178  else if ( m_evtSelector && m_evtContext ) {
180  m_evtSelector = nullptr;
181  m_evtContext = nullptr;
182  }
183  return StatusCode::SUCCESS;
184 }
185 
186 
187 //--------------------------------------------------------------------------------------------
188 // implementation of IService::stop
189 //--------------------------------------------------------------------------------------------
191  if ( ! m_endEventFired ) {
192  // Fire pending EndEvent incident
194  m_endEventFired = true;
195  }
196  return MinimalEventLoopMgr::stop();
197 }
198 
199 //--------------------------------------------------------------------------------------------
200 // implementation of IAppMgrUI::finalize
201 //--------------------------------------------------------------------------------------------
203  StatusCode sc;
204 
205  // Finalize base class
207  if (! sc.isSuccess()) {
208  error() << "Error finalizing base class" << endmsg;
209  return sc;
210  }
211 
212  // Save Histograms Now
213  if ( m_histoPersSvc ) {
214  HistogramAgent agent;
215  sc = m_histoDataMgrSvc->traverseTree( &agent );
216  if( sc.isSuccess() ) {
217  IDataSelector* objects = agent.selectedObjects();
218  // skip /stat entry!
219  if ( objects->size() > 0 ) {
220  for ( auto& i : *objects ) {
221  IOpaqueAddress* pAddr = nullptr;
222  StatusCode iret = m_histoPersSvc->createRep(i, pAddr);
223  if ( iret.isSuccess() ) {
224  i->registry()->setAddress(pAddr);
225  }
226  else {
227  sc = iret;
228  }
229  }
230  for ( auto& i : *objects ) {
231  IRegistry* reg = i->registry();
232  StatusCode iret = m_histoPersSvc->fillRepRefs(reg->address(), i);
233  if ( !iret.isSuccess() ) sc = iret;
234  }
235  }
236  if ( sc.isSuccess() ) {
237  info() << "Histograms converted successfully according to request." << endmsg;
238  }
239  else {
240  error() << "Error while saving Histograms." << endmsg;
241  }
242  }
243  else {
244  error() << "Error while traversing Histogram data store" << endmsg;
245  }
246  }
247 
248  // Release event selector context
249  if ( m_evtSelector && m_evtContext ) {
251  m_evtContext = nullptr;
252  }
253 
254  // Release all interfaces...
255  m_histoDataMgrSvc = nullptr;
256  m_histoPersSvc = nullptr;
257 
258  m_evtSelector = nullptr;
259  m_evtDataSvc = nullptr;
260  m_evtDataMgrSvc = nullptr;
261 
262  return StatusCode::SUCCESS;
263 }
264 
265 //--------------------------------------------------------------------------------------------
266 // executeEvent(void* par)
267 //--------------------------------------------------------------------------------------------
269 
270  // Fire BeginEvent "Incident"
272  // An incident may schedule a stop, in which case is better to exit before the actual execution.
273  if ( m_scheduledStop ) {
274  always() << "Terminating event processing loop due to a stop scheduled by an incident listener" << endmsg;
275  return StatusCode::SUCCESS;
276  }
277 
278  // Execute Algorithms
282 
283  // Check if there was an error processing current event
284  if( UNLIKELY(!sc.isSuccess()) ){
285  error() << "Terminating event processing loop due to errors" << endmsg;
286  }
287  return sc;
288 }
289 
290 //--------------------------------------------------------------------------------------------
291 // implementation of IAppMgrUI::nextEvent
292 //--------------------------------------------------------------------------------------------
294  static int total_nevt = 0;
295  DataObject* pObject = nullptr;
297 
298  // loop over events if the maxevt (received as input) if different from -1.
299  // if evtmax is -1 it means infinite loop
300  for( int nevt = 0; maxevt == -1 || nevt < maxevt; ++nevt, ++total_nevt) {
301 
302  // Check if there is a scheduled stop issued by some algorithm/service
303  if ( m_scheduledStop ) {
304  m_scheduledStop = false;
305  always() << "Terminating event processing loop due to scheduled stop" << endmsg;
306  break;
307  }
308  // Clear the event store, if used in the event loop
309  if( 0 != total_nevt ) {
310 
311  if ( ! m_endEventFired ) {
312  // Fire EndEvent "Incident" (it is considered part of the clearing of the TS)
314  m_endEventFired = true;
315  }
316  sc = m_evtDataMgrSvc->clearStore();
317  if( !sc.isSuccess() ) {
318  DEBMSG << "Clear of Event data store failed" << endmsg;
319  }
320  }
321 
322  // Setup event in the event store
323  if( m_evtContext ) {
324  IOpaqueAddress* addr = nullptr;
325  // Only if there is a EventSelector
326  sc = getEventRoot(addr);
327  if( !sc.isSuccess() ) {
328  info() << "No more events in event selection " << endmsg;
329  break;
330  }
331  // Set root clears the event data store first
332  sc = m_evtDataMgrSvc->setRoot ("/Event", addr);
333  if( !sc.isSuccess() ) {
334  warning() << "Error declaring event root address." << endmsg;
335  continue;
336  }
337  sc = m_evtDataSvc->retrieveObject("/Event", pObject);
338  if( !sc.isSuccess() ) {
339  warning() << "Unable to retrieve Event root object" << endmsg;
340  break;
341  }
342  } else {
343  sc = m_evtDataMgrSvc->setRoot ("/Event", new DataObject());
344  if( !sc.isSuccess() ) {
345  warning() << "Error declaring event root DataObject" << endmsg;
346  }
347  }
348  // Execute event for all required algorithms
349  sc = executeEvent(nullptr);
350  m_endEventFired = false;
351  if( !sc.isSuccess() ){
352  error() << "Terminating event processing loop due to errors" << endmsg;
354  return sc;
355  }
356  }
357  return StatusCode::SUCCESS;
358 }
359 
362  refpAddr = nullptr;
364  if ( !sc.isSuccess() ) return sc;
365  // Create root address and assign address to data service
366  sc = m_evtSelector->createAddress(*m_evtContext,refpAddr);
367  if( !sc.isSuccess() ) {
369  if ( sc.isSuccess() ) {
370  sc = m_evtSelector->createAddress(*m_evtContext,refpAddr);
371  if ( !sc.isSuccess() ) {
372  warning() << "Error creating IOpaqueAddress." << endmsg;
373  }
374  }
375  }
376  return sc;
377 }
const std::string BeginEvent
Processing of a new event has started.
Definition: Incident.h:60
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
bool m_scheduledStop
Scheduled stop of event processing.
const std::string BeginProcessing
Incident raised just before entering loop over the algorithms.
Definition: Incident.h:84
SmartIF< IConversionSvc > m_histoPersSvc
Reference to the Histogram Persistency Service.
Definition: EventLoopMgr.h:55
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
virtual StatusCode initialize()
implementation of IService::initialize
const std::string EndProcessing
Incident raised just after the loop over the algorithms (note: before the execution of OutputStreams)...
Definition: Incident.h:86
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...
std::string m_histPersName
Name of the Hist Pers type.
Definition: EventLoopMgr.h:57
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
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:76
const std::string EndEvent
Processing of the last event has finished.
Definition: Incident.h:61
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
virtual StatusCode executeEvent(void *par)
implementation of IEventProcessor::executeEvent(void* par)
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)
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
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
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:255
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 reinitialize()
implementation of IService::reinitialize
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.
virtual StatusCode stop()
implementation of IService::stop
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
virtual StatusCode finalize()
implementation of IService::finalize
#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.
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.
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.