BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
OfflineEventLoopMgr.cxx
Go to the documentation of this file.
1#include "GaudiKernel/DataObject.h"
2#include "GaudiKernel/EventContext.h"
3#include "GaudiKernel/IAlgorithm.h"
4#include "GaudiKernel/IRegistry.h"
5#include "GaudiKernel/Incident.h"
6#include "GaudiKernel/SmartDataPtr.h"
7
8#include "EventModel/EventHeader.h"
9
10#include "OfflineEventLoopMgr.h"
11
12extern const CLID& CLID_Event;
14
15//--------------------------------------------------------------------------------------------
16// Standard Constructor
17//--------------------------------------------------------------------------------------------
18OfflineEventLoopMgr::OfflineEventLoopMgr( const std::string& name, ISvcLocator* svcLoc )
19 : MinimalEventLoopMgr( name, svcLoc ) {
20 // Reset the pointers
21 m_histoDataMgrSvc = nullptr;
22 m_histoPersSvc = nullptr;
23 m_incidentSvc = nullptr;
24 m_evtDataMgrSvc = nullptr;
25 m_evtDataSvc = nullptr;
26 m_evtSelector = nullptr;
27
28 m_evtContext = nullptr;
29 m_runNo = 0;
30 m_runNoSet = false;
31}
32
33//--------------------------------------------------------------------------------------------
34// Standard Destructor
35//--------------------------------------------------------------------------------------------
39
40//--------------------------------------------------------------------------------------------
41// implementation of IAppMgrUI::initalize
42//--------------------------------------------------------------------------------------------
44 info() << "In initialize()" << endmsg;
45
46 // Initialize the base class
47 StatusCode sc = MinimalEventLoopMgr::initialize();
48 if ( !sc.isSuccess() )
49 {
50 fatal() << "Failed to initialize the MinimalEventLoopMgr" << endmsg;
51 return sc;
52 }
53
54 // Setup access to event data services
55 m_evtDataMgrSvc = service( "EventDataSvc", true );
56 if ( !m_evtDataMgrSvc )
57 {
58 fatal() << "Failed to get the EventDataSvc" << endmsg;
59 return StatusCode::FAILURE;
60 }
61
62 m_evtDataSvc = service( "EventDataSvc", true );
63 if ( !m_evtDataSvc )
64 {
65 fatal() << "Failed to get the EventDataSvc" << endmsg;
66 return StatusCode::FAILURE;
67 }
68
69 // Get the references to the services that are needed by the ApplicationMgr itself
70 m_incidentSvc = service( "IncidentSvc", true );
71 if ( !m_incidentSvc )
72 {
73 fatal() << "Failed to get the IncidentSvc" << endmsg;
74 return StatusCode::FAILURE;
75 }
76
77 // Obtain the IProperty of the ApplicationMgr
78 m_appMgrProperty = serviceLocator();
79 if ( !m_appMgrProperty )
80 {
81 fatal() << "Failed to get the IProperty of the ApplicationMgr" << endmsg;
82 return StatusCode::FAILURE;
83 }
84
85 // We do not expect an EventSelector necessarily being declared
86 if ( m_evtsel == "NONE" )
87 {
88 m_evtSelector = nullptr;
89 m_evtContext = nullptr;
90 warning() << "Unable to locate service \"EventSelector\" " << endmsg;
91 warning() << "No events will be processed from external input." << endmsg;
92 }
93 else
94 {
95 // an EventSelector is declared
96 m_evtSelector = service( "EventSelector", true );
97 if ( !m_evtSelector )
98 {
99 fatal() << "EventSelector not found." << endmsg;
100 return StatusCode::FAILURE;
101 }
102 debug() << "Found EventSelector" << endmsg;
103
104 // Setup Event selector
105 sc = m_evtSelector->createContext( m_evtContext );
106 if ( !sc.isSuccess() )
107 {
108 fatal() << "Can not create the context" << endmsg;
109 return StatusCode::FAILURE;
110 }
111
112 debug() << "Context created." << endmsg;
113 }
114
115 // Setup access to histogramming services
116 m_histoDataMgrSvc = service( "HistogramDataSvc", true );
117 if ( !m_histoDataMgrSvc )
118 {
119 fatal() << "Failed to get the HistogramDataSvc" << endmsg;
120 return StatusCode::FAILURE;
121 }
122
123 // Setup histogram persistency
124 m_histoPersSvc = service( "HistogramPersistencySvc", true );
125 if ( !m_histoPersSvc )
126 {
127 warning() << "Histograms cannot not be saved - though required." << endmsg;
128 return StatusCode::FAILURE;
129 }
130
131 // setup progress showing
133 {
134 switch ( m_progressLevelSetting )
135 {
136 case 1: m_progressLevel = MSG::VERBOSE; break;
137 case 2: m_progressLevel = MSG::DEBUG; break;
138 case 3: m_progressLevel = MSG::INFO; break;
139 case 4: m_progressLevel = MSG::WARNING; break;
140 case 5: m_progressLevel = MSG::ERROR; break;
141 case 6: m_progressLevel = MSG::FATAL; break;
142 case 7: m_progressLevel = MSG::ALWAYS; break;
143 default:
144 error() << "Unknown progress level setting: " << m_progressLevelSetting << endmsg;
145 return StatusCode::FAILURE;
146 }
147 }
148
149 if ( m_startEvtNo > 0 || m_startRunNo != 0 ) { m_skipEvt = true; }
150 else { m_skipEvt = false; }
151
152 return StatusCode::SUCCESS;
153}
154
155//--------------------------------------------------------------------------------------------
156// implementation of IService::reinitialize
157//--------------------------------------------------------------------------------------------
159
160 info() << "In reinitialize()" << endmsg;
161
162 // Initialize the base class
163 StatusCode sc = MinimalEventLoopMgr::reinitialize();
164 if ( !sc.isSuccess() )
165 {
166 error() << "Error Initializing base class MinimalEventLoopMgr." << endmsg;
167 return sc;
168 }
169
170 // Check to see whether a new Event Selector has been specified
171 if ( sc = setProperty( m_appMgrProperty->getProperty( "EvtSel" ) ); !sc ) return sc;
172 if ( m_evtsel != "NONE" || m_evtsel.length() == 0 )
173 {
174 auto theSvc = serviceLocator()->service<IService>( "EventSelector" );
175 auto theEvtSel = theSvc.as<IEvtSelector>();
176 if ( theEvtSel && ( theEvtSel.get() != m_evtSelector.get() ) )
177 {
178 // Setup Event Selector
179 if ( m_evtSelector.get() && m_evtContext )
180 {
181 // Need to release context before switching to new event selector
182 if ( sc = m_evtSelector->releaseContext( m_evtContext ); !sc ) return sc;
183 m_evtContext = nullptr;
184 }
185 m_evtSelector = theEvtSel;
186 if ( theSvc->FSMState() == Gaudi::StateMachine::INITIALIZED )
187 {
188 sc = theSvc->reinitialize();
189 if ( !sc.isSuccess() )
190 {
191 error() << "Failure Reinitializing EventSelector " << theSvc->name() << endmsg;
192 return sc;
193 }
194 }
195 else
196 {
197 sc = theSvc->sysInitialize();
198 if ( !sc.isSuccess() )
199 {
200 error() << "Failure Initializing EventSelector " << theSvc->name() << endmsg;
201 return sc;
202 }
203 }
204 sc = m_evtSelector->createContext( m_evtContext );
205 if ( !sc.isSuccess() )
206 {
207 error() << "Can not create Context " << theSvc->name() << endmsg;
208 return sc;
209 }
210 info() << "EventSelector service changed to " << theSvc->name() << endmsg;
211 }
212 else if ( m_evtSelector )
213 {
214 if ( m_evtContext )
215 {
216 if ( sc = m_evtSelector->releaseContext( m_evtContext ); !sc ) return sc;
217 m_evtContext = nullptr;
218 }
219 sc = m_evtSelector->createContext( m_evtContext );
220 if ( !sc.isSuccess() )
221 {
222 error() << "Can not create Context " << theSvc->name() << endmsg;
223 return sc;
224 }
225 }
226 }
227 else if ( m_evtSelector && m_evtContext )
228 {
229 sc = m_evtSelector->releaseContext( m_evtContext );
230 m_evtSelector = nullptr;
231 m_evtContext = nullptr;
232 }
233 return sc;
234}
235
236//--------------------------------------------------------------------------------------------
237// implementation of IAppMgrUI::finalize
238//--------------------------------------------------------------------------------------------
240 info() << "In finalize()" << endmsg;
241
242 // Finalize base class
243 StatusCode sc = MinimalEventLoopMgr::finalize();
244 if ( !sc.isSuccess() )
245 {
246 error() << "Error finalizing base class" << endmsg;
247 return sc;
248 }
249
250 // Save Histograms Now
251 if ( m_histoPersSvc )
252 {
253 std::vector<DataObject*> objects;
254 sc = m_histoDataMgrSvc->traverseTree( [&objects]( IRegistry* reg, int ) {
255 DataObject* obj = reg->object();
256 if ( !obj || obj->clID() == CLID_StatisticsFile ) return false;
257 objects.push_back( obj );
258 return true;
259 } );
260 if ( sc.isSuccess() )
261 {
262 // skip /stat entry!
263 sc = std::accumulate( begin( objects ), end( objects ), sc,
264 [&]( StatusCode isc, auto& i ) {
265 IOpaqueAddress* pAddr = nullptr;
266 StatusCode iret = m_histoPersSvc->createRep( i, pAddr );
267 if ( iret.isFailure() ) return iret;
268 i->registry()->setAddress( pAddr );
269 return isc;
270 } );
271
272 sc = std::accumulate(
273 begin( objects ), end( objects ), sc, [&]( StatusCode isc, auto& i ) {
274 IRegistry* reg = i->registry();
275 StatusCode iret = m_histoPersSvc->fillRepRefs( reg->address(), i );
276 return iret.isFailure() ? iret : isc;
277 } );
278
279 if ( sc.isSuccess() )
280 { info() << "Histograms converted successfully according to request." << endmsg; }
281 else { error() << "Error while saving Histograms." << endmsg; }
282 }
283 else { error() << "Error while traversing Histogram data store" << endmsg; }
284 }
285
286 // Release event selector context
288 {
289 m_evtSelector->releaseContext( m_evtContext ).ignore();
290 m_evtContext = nullptr;
291 }
292
293 // Release all interfaces...
294 m_histoDataMgrSvc = nullptr;
295 m_histoPersSvc = nullptr;
296
297 m_evtSelector = nullptr;
298 m_evtDataSvc = nullptr;
299 m_evtDataMgrSvc = nullptr;
300
301 return StatusCode::SUCCESS;
302}
303
304//--------------------------------------------------------------------------------------------
305// executeEvent( EventContext&& ctx)
306//--------------------------------------------------------------------------------------------
307StatusCode OfflineEventLoopMgr::executeEvent( EventContext&& ctx ) {
308
309 m_incidentSvc->fireIncident( Incident( name(), IncidentType::BeginEvent ) );
310
311 // An incident may schedule a stop, in which case is better to exit before the actual
312 // execution.
313 if ( m_scheduledStop )
314 {
315 always()
316 << "Terminating event processing loop due to a stop scheduled by an incident listener"
317 << endmsg;
318 return StatusCode::SUCCESS;
319 }
320
321 SmartDataPtr<Event::EventHeader> evt( m_evtDataSvc, "/Event/EventHeader" );
322 if ( !evt )
323 {
324 error() << "Error accessing Event" << endmsg;
325 return StatusCode::FAILURE;
326 }
327
328 int runNo = evt->runNumber();
329 int evtNo = evt->eventNumber();
330
331 // Skip events if requested
332 if ( m_skipEvt )
333 {
334 bool match_evt_no = m_startEvtNo == 0; // startEvtNo==0 means skip no event
335 bool match_run_no = m_startRunNo == 0; // startRunNo==0 means skip no event
336
337 if ( m_startEvtNo > 0 && evtNo == m_startEvtNo ) match_evt_no = true;
338 if ( m_startRunNo != 0 && abs( runNo ) == abs( m_startRunNo ) ) match_run_no = true;
339
340 if ( match_evt_no && match_run_no )
341 {
342 info() << "Reached the requested event " << evtNo << " in run " << runNo
343 << ", will start processing from next event." << endmsg;
344 m_skipEvt = false;
345 }
346 else
347 {
348 debug() << "Skipping event " << evtNo << " in run " << runNo << endmsg;
349 return StatusCode::SUCCESS;
350 }
351 }
352
353 info() << "The runNo of current event is " << runNo << endmsg;
354
355 // If (!m_runNoSet), always fire an incident of begin run
356 // otherwise, only fire the incident when the runNo is changed
357 if ( !m_runNoSet || runNo != m_runNo )
358 {
359 info() << "Fire an incident of begin run" << endmsg;
360 m_incidentSvc->fireIncident( Incident( name(), "NewRun" ) );
361
362 m_runNoSet = true;
363 m_runNo = runNo;
364 }
365
366 // Execute Algorithms
367 m_incidentSvc->fireIncident( Incident( name(), IncidentType::BeginProcessing ) );
368 StatusCode sc = MinimalEventLoopMgr::executeEvent( std::move( ctx ) );
369 m_incidentSvc->fireIncident( Incident( name(), IncidentType::EndProcessing ) );
370
371 if ( !sc.isSuccess() )
372 error() << "Terminating event processing loop due to errors" << endmsg;
373
374 m_incidentSvc->fireIncident( Incident( name(), IncidentType::EndEvent ) );
375
376 return sc;
377}
378
379//--------------------------------------------------------------------------------------------
380// implementation of IAppMgrUI::nextEvent
381//--------------------------------------------------------------------------------------------
382StatusCode OfflineEventLoopMgr::nextEvent( int maxevt ) {
383 static int total_nevt = 0;
384 DataObject* pObject = 0;
385 StatusCode sc;
386
387 for ( int nevt = 0; maxevt == -1 || nevt < maxevt; ++nevt )
388 {
389
391 { msgStream( m_progressLevel ) << "Processing event " << nevt << endmsg; }
392
393 auto ctx = createEventContext();
394
395 // Check if there is a scheduled stop issued by some algorithm/service
396 if ( m_scheduledStop )
397 {
398 m_scheduledStop = false;
399 always() << "Terminating event processing loop due to scheduled stop" << endmsg;
400 break;
401 }
402
403 // Clear event store, if used in event loop
404 if ( ctx.evt() != 0 )
405 {
406 sc = m_evtDataMgrSvc->clearStore();
407 if ( sc.isSuccess() ) debug() << "Event data storecleared" << endmsg;
408 else debug() << "Failed to clear the store" << endmsg;
409 }
410
411 // Setup event in the event store
412 if ( m_evtContext )
413 {
414 IOpaqueAddress* addr = nullptr;
415
416 // Only if there is an EventSelector
417 sc = getEventRoot( addr );
418 if ( !sc.isSuccess() )
419 {
420 info() << "No more events in event selection" << endmsg;
421 break;
422 }
423
424 // Set root clearstheevent data store first
425 sc = m_evtDataMgrSvc->setRoot( "/Event", addr );
426 if ( !sc.isSuccess() )
427 {
428 warning() << "Error declaring event root address." << endmsg;
429 continue;
430 }
431
432 // register event header for mc
433 SmartDataPtr<Event::EventHeader> evt( m_evtDataSvc, "/Event/EventHeader" );
434 if ( !evt )
435 {
436 sc = m_evtDataMgrSvc->registerAddress( "/Event/EventHeader", addr );
437 if ( !sc.isSuccess() ) warning() << "Error register EventHeader address." << endmsg;
438 }
439
440 sc = m_evtDataSvc->retrieveObject( "/Event", pObject );
441 if ( !sc.isSuccess() )
442 {
443 warning() << "Unable to retrieve Event root object" << endmsg;
444 break;
445 }
446 }
447 else
448 {
449 sc = m_evtDataMgrSvc->setRoot( "/Event", new DataObject() );
450 if ( !sc.isSuccess() ) warning() << "Error declaring event root DataObject" << endmsg;
451 }
452
453 // Execute event for all required algorithms
454 sc = executeEvent( std::move( ctx ) );
455 if ( !sc.isSuccess() )
456 {
457 error() << "Terminating event processing loop due to errors" << endmsg;
458 break;
459 }
460 }
461
462 return StatusCode::SUCCESS;
463}
464
465//--------------------------------------------------------------------------------------------
466// implementation of getEventROOT
467//--------------------------------------------------------------------------------------------
468/// Create event address using event selector
469StatusCode OfflineEventLoopMgr::getEventRoot( IOpaqueAddress*& refpAddr ) {
470 refpAddr = 0;
471 StatusCode sc = m_evtSelector->next( *m_evtContext );
472 if ( !sc.isSuccess() )
473 {
474 debug() << "Failed to get next eventContext [1]" << endmsg;
475 return sc;
476 }
477
478 sc = m_evtSelector->createAddress( *m_evtContext, refpAddr );
479 if ( sc.isSuccess() )
480 {
481 debug() << "Event address created successfully." << endmsg;
482 return sc;
483 }
484
485 sc = m_evtSelector->next( *m_evtContext );
486 if ( sc.isFailure() )
487 {
488 debug() << "Failed to get next eventContext [2]" << endmsg;
489 return sc;
490 }
491
492 sc = m_evtSelector->createAddress( *m_evtContext, refpAddr );
493 if ( sc.isFailure() ) { warning() << "Error creating IOpaqueAddress." << endmsg; }
494 else debug() << "Event address created successfully finally." << endmsg;
495
496 return sc;
497}
DECLARE_COMPONENT(BesBdkRc)
int runNo
Definition DQA_TO_DB.cxx:13
Int_t nevt[10]
const CLID & CLID_Event
SmartIF< IEvtSelector > m_evtSelector
Reference to the Event Selector.
virtual StatusCode reinitialize()
implementation of IService::reinitalize
IntegerProperty m_startEvtNo
Locate start event number.
virtual StatusCode executeEvent(EventContext &&ctx)
implementation of IEventProcessor::executeEvent(EventContext&&)
SmartIF< IConversionSvc > m_histoPersSvc
Reference to the Histogram Persistency Service.
UnsignedIntegerProperty m_progressLevelSetting
progress level
StatusCode getEventRoot(IOpaqueAddress *&refpAddr)
Create event address using event selector.
UnsignedIntegerProperty m_showProgressInterval
show progress
virtual StatusCode finalize()
implementation of IService::finalize
SmartIF< IDataProviderSvc > m_evtDataSvc
Reference to the Event Data Service's IDataProviderSvc interface.
SmartIF< IProperty > m_appMgrProperty
Property interface of ApplicationMgr.
SmartIF< IDataManagerSvc > m_histoDataMgrSvc
Reference to the Histogram Data Service.
OfflineEventLoopMgr(const std::string &nam, ISvcLocator *svcLoc)
Standard Constructor.
virtual StatusCode initialize()
implementation of IService::initalize
SmartIF< IDataManagerSvc > m_evtDataMgrSvc
Reference to the Event Data Service's IDataManagerSvc interface.
virtual StatusCode nextEvent(int maxevt)
implementation of IService::nextEvent
IEvtSelector::Context * m_evtContext
Event Iterator.
StringProperty m_evtsel
Event selector.
SmartIF< IIncidentSvc > m_incidentSvc
Reference to the indicent service.
virtual ~OfflineEventLoopMgr()
Standard Destructor.
IntegerProperty m_startRunNo