ATLAS Offline Software
Loading...
Searching...
No Matches
AthenaHiveEventLoopMgr.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <GaudiKernel/DataIncident.h>
6
7#include <memory>
8#define ATHENASERVICES_ATHENAHIVEEVENTLOOPMGR_CPP
9
10#include <cassert>
11#include <ios>
12#include <iostream>
13#include <fstream> /* ofstream */
14#include <iomanip>
15#include <memory>
16#include <print>
17
18// Athena includes
28
29#include "GaudiKernel/IAlgorithm.h"
30#include "GaudiKernel/SmartIF.h"
31#include "GaudiKernel/Incident.h"
32#include "GaudiKernel/DataObject.h"
33#include "GaudiKernel/IIncidentSvc.h"
34#include "GaudiKernel/IEvtSelector.h"
35#include "GaudiKernel/IDataManagerSvc.h"
36#include "GaudiKernel/IDataProviderSvc.h"
37#include "GaudiKernel/IConversionSvc.h"
38#include "GaudiKernel/GaudiException.h"
39#include "GaudiKernel/AppReturnCode.h"
40#include "GaudiKernel/MsgStream.h"
41#include "Gaudi/Property.h"
42#include "GaudiKernel/EventIDBase.h"
43#include "GaudiKernel/ThreadLocalContext.h"
44
46
47#include "EventInfo/EventInfo.h"
48#include "EventInfo/EventID.h"
49#include "EventInfo/EventType.h"
52
54
55#include <GaudiKernel/IScheduler.h>
56// External libraries
57#include "tbb/tick_count.h"
58
59
60
61//=========================================================================
62// Standard Constructor
63//=========================================================================
65 ISvcLocator* svcLoc)
66 : base_class(nam, svcLoc),
67 AthMessaging (nam),
68 m_incidentSvc ( "IncidentSvc", nam ),
69 m_eventStore( "StoreGateSvc", nam ),
71 m_histoDataMgrSvc( "HistogramDataSvc", nam ),
72 m_histoPersSvc ( "HistogramPersistencySvc", nam ),
73 m_evtIdModSvc ( "", nam ),
74 m_currentRun(0), m_firstRun(true), m_tools(this), m_nevt(0), m_writeHists(false),
75 m_nev(0), m_proc(0), m_useTools(false),m_doEvtHeartbeat(false),
76 m_conditionsCleaner( "Athena::ConditionsCleanerSvc", nam )
77{
78 declareProperty("EvtSel", m_evtsel,
79 "Name of Event Selector to use. If empty string (default) "
80 "take value from ApplicationMgr");
81 declareProperty("HistogramPersistency", m_histPersName="",
82 "Histogram persistency technology to use: ROOT, HBOOK, NONE. "
83 "By default (empty string) get property value from "
84 "ApplicationMgr");
85 declareProperty("HistWriteInterval", m_writeInterval=0 ,
86 "histogram write/update interval");
87 declareProperty("FailureMode", m_failureMode=1 ,
88 "Controls behaviour of event loop depending on return code of"
89 " Algorithms. 0: all non-SUCCESSes terminate job. "
90 "1: RECOVERABLE skips to next event, FAILURE terminates job "
91 "(DEFAULT). 2: RECOVERABLE and FAILURE skip to next events");
92 declareProperty("EventPrintoutInterval", m_eventPrintoutInterval=1,
93 "Print event heartbeat printouts every m_eventPrintoutInterval events");
94 declareProperty("PreSelectTools",m_tools,"AlgTools for event pre-selection")->
95 declareUpdateHandler( &AthenaHiveEventLoopMgr::setupPreSelectTools, this ); ;
96
97 declareProperty("SchedulerSvc", m_schedulerName="ForwardSchedulerSvc",
98 "Name of the scheduler to be used");
99
100 declareProperty("WhiteboardSvc", m_whiteboardName="EventDataSvc",
101 "Name of the Whiteboard to be used");
102
103 declareProperty("EventStore", m_eventStore);
104
105 declareProperty("EvtIdModifierSvc", m_evtIdModSvc,
106 "ServiceHandle for EvtIdModifierSvc");
107
108 declareProperty("FakeLumiBlockInterval", m_flmbi = 0,
109 "Event interval at which to increment lumiBlock# when "
110 "creating events without an EventSelector. Zero means "
111 "don't increment it");
112 declareProperty("FakeTimestampInterval", m_timeStampInt = 1,
113 "timestamp interval between events when creating Events "
114 "without an EventSelector");
115 declareProperty("RequireInputAttributeList", m_requireInputAttributeList = false,
116 "Require valid input attribute list to be present");
117 declareProperty("UseSecondaryEventNumber", m_useSecondaryEventNumber = false,
118 "In case of DoubleEventSelector use event number from secondary input");
119
120 declareProperty("FirstEventAlone", m_firstEventAlone = true,
121 "process all of first event before scheduling any more");
122
123 m_scheduledStop = false;
124
125}
126
127//=========================================================================
128// Standard Destructor
129//=========================================================================
133
134//=========================================================================
135// implementation of IAppMgrUI::initalize
136//=========================================================================
138{
139
140 ATH_MSG_INFO ( "Initializing {}", name() );
141
142
143 StatusCode sc = MinimalEventLoopMgr::initialize();
144 if ( !sc.isSuccess() )
145 {
146 ATH_MSG_ERROR ( "Failed to initialize base class MinimalEventLoopMgr" );
147 return sc;
148 }
149
150//-------------------------------------------------------------------------
151// Setup stuff for hive
152//-------------------------------------------------------------------------
153
154 m_whiteboard = serviceLocator()->service(m_whiteboardName);
155 if( !m_whiteboard.isValid() ) {
156 ATH_MSG_FATAL ( "Error retrieving {} interface IHiveWhiteBoard.", m_whiteboardName );
157 return StatusCode::FAILURE;
158 }
159
160 m_schedulerSvc = serviceLocator()->service(m_schedulerName);
161 if ( !m_schedulerSvc.isValid()){
162 ATH_MSG_FATAL ( "Error retrieving SchedulerSvc interface ISchedulerSvc." );
163 return StatusCode::FAILURE;
164 }
165 // Setup algorithm resource pool
166 m_algResourcePool = serviceLocator()->service("AlgResourcePool");
167 if( !m_algResourcePool.isValid() ) {
168 ATH_MSG_FATAL ( "Error retrieving AlgResourcePool" );
169 return StatusCode::FAILURE;
170 }
171
172 m_aess = serviceLocator()->service("AlgExecStateSvc");
173 if( !m_aess.isValid() ) {
174 ATH_MSG_FATAL ( "Error retrieving AlgExecStateSvc" );
175 return StatusCode::FAILURE;
176 }
177
178 sc = m_eventStore.retrieve();
179 if( !sc.isSuccess() )
180 {
181 ATH_MSG_FATAL ( "Error retrieving pointer to StoreGateSvc" );
182 return sc;
183 }
184
185//--------------------------------------------------------------------------
186// Get the references to the services that are needed by the ApplicationMgr
187// itself
188//--------------------------------------------------------------------------
189 sc = m_incidentSvc.retrieve();
190 if( !sc.isSuccess() )
191 {
192 ATH_MSG_FATAL ( "Error retrieving IncidentSvc." );
193 return sc;
194 }
195
196//--------------------------------------------------------------------------
197// Access Property Manager interface:
198//--------------------------------------------------------------------------
199 SmartIF<IProperty> prpMgr(serviceLocator());
200 if ( !prpMgr.isValid() )
201 {
202 ATH_MSG_FATAL ( "IProperty interface not found in ApplicationMgr." );
203 return StatusCode::FAILURE;
204 }
205
206
207//--------------------------------------------------------------------------
208// Set up the Histogram Service
209//--------------------------------------------------------------------------
210 sc = m_histoDataMgrSvc.retrieve();
211 if( !sc.isSuccess() )
212 {
213 ATH_MSG_FATAL ( "Error retrieving HistogramDataSvc" );
214 return sc;
215 }
216
217 const std::string& histPersName(m_histPersName.value());
218 if ( histPersName.length() == 0 )
219 {
220 CHECK(setProperty(prpMgr->getProperty("HistogramPersistency")));
221 }
222
223 if ( histPersName != "NONE" ) {
224
225 m_histoPersSvc = IConversionSvc_t( "HistogramPersistencySvc",
226 this->name() );
227
228 SmartIF<IProperty> histSvc;
229 if (histPersName == "ROOT") {
230 histSvc = serviceLocator()->service("RootHistSvc");
231 } else if ( histPersName == "HBOOK" ) {
232 histSvc = serviceLocator()->service("HbookHistSvc");
233 }
234
235 if (!histSvc) {
236 ATH_MSG_ERROR ( "could not locate actual Histogram persistency service" );
237 } else {
238 const Gaudi::Details::PropertyBase &prop = histSvc->getProperty("OutputFile");
239 std::string val;
240 try {
241 const StringProperty &sprop = dynamic_cast<const StringProperty&>( prop );
242 val = sprop.value();
243 } catch (...) {
244 ATH_MSG_VERBOSE ( "could not dcast OutputFile property to a StringProperty."
245 " Need to fix Gaudi." );
246 val = prop.toString();
247 }
248
249 if (val != "" &&
250 val != "UndefinedROOTOutputFileName" &&
251 val != "UndefinedHbookOutputFileName" ) {
252 m_writeHists = true;
253 }
254 }
255 } else {
256 ATH_MSG_DEBUG ( "Histograms saving not required." );
257 }
258
259
260//--------------------------------------------------------------------------
261// Set up the EventID modifier Service
262//--------------------------------------------------------------------------
263 if( m_evtIdModSvc.empty() ) {
264 ATH_MSG_DEBUG ( "EventID modifier Service not set. No run number, ... overrides will be applied." );
265 }
266 else if ( !m_evtIdModSvc.retrieve().isSuccess() ) {
267 ATH_MSG_INFO ( "Could not find EventID modifier Service. No run number, ... overrides will be applied." );
268 }
269
270//-------------------------------------------------------------------------
271// Setup EventSelector service
272//-------------------------------------------------------------------------
273 const std::string& selName(m_evtsel.value());
274 // the evt sel is usually specified as a property of ApplicationMgr
275 if (selName.empty())
276 sc = setProperty(prpMgr->getProperty("EvtSel"));
277 if (sc.isFailure()) ATH_MSG_WARNING ( "Unable to set EvtSel property" );
278
279 // We do not expect a Event Selector necessarily being declared
280 if( !selName.empty() && selName != "NONE") {
281 SmartIF<IEvtSelector> theEvtSel{serviceLocator()->service( selName )};
282 if( theEvtSel && ( theEvtSel != m_evtSelector ) ) {
283 // Event Selector changed (or setup for the first time)
284 m_evtSelector = theEvtSel;
285
286 // reset iterator
287 if (m_evtSelector->createContext(m_evtContext).isFailure()) {
288 ATH_MSG_FATAL ( "Can not create the event selector Context." );
289 return StatusCode::FAILURE;
290 }
291 if (msgLevel(MSG::INFO)) {
292 SmartIF<INamedInterface> named(theEvtSel);
293 if (named) {
294 ATH_MSG_INFO ( "Setup EventSelector service {}", named->name( ) );
295 }
296 }
297 } else if (sc.isFailure()) {
298 ATH_MSG_FATAL ( "No valid event selector called {}", selName );
299 return StatusCode::FAILURE;
300 }
301 }
302
303 // Listen to the BeforeFork and EndAlgorithms incidents
304 m_incidentSvc->addListener(this,"BeforeFork",0);
305 m_incidentSvc->addListener(this, "EndAlgorithms",0);
306
307 CHECK( m_conditionsCleaner.retrieve() );
308
309 // Print if we override the event number using the one from secondary event
311 {
312 ATH_MSG_INFO ( "Using secondary event number." );
313 }
314
315 return sc;
316}
317
318//=========================================================================
319// property handlers
320//=========================================================================
321void
322AthenaHiveEventLoopMgr::setupPreSelectTools(Gaudi::Details::PropertyBase&) {
323
324 m_toolInvoke.clear();
325 m_toolReject.clear();
326 m_toolAccept.clear();
327
328 m_tools.retrieve().ignore();
329 if(m_tools.size() > 0) {
330 m_useTools=true;
331 m_toolInvoke.resize(m_tools.size());
332 m_toolReject.resize(m_tools.size());
333 m_toolAccept.resize(m_tools.size());
334
335 tool_iterator firstTool = m_tools.begin();
336 tool_iterator lastTool = m_tools.end();
337 unsigned int toolCtr = 0;
338 for ( ; firstTool != lastTool; ++firstTool )
339 {
340 // reset statistics
341 m_toolInvoke[toolCtr] = 0;
342 m_toolReject[toolCtr] = 0;
343 m_toolAccept[toolCtr] = 0;
344 toolCtr++;
345 }
346 }
347
348 return;
349
350}
351
352//=========================================================================
353// implementation of IAppMgrUI::finalize
354//=========================================================================
356{
357
358 StatusCode sc = MinimalEventLoopMgr::finalize();
359 if (sc.isFailure())
360 {
361 ATH_MSG_ERROR ( "Error in Service base class Finalize" );
362 }
363
364 StatusCode sc2 = writeHistograms(true);
365 if (sc2.isFailure())
366 {
367 ATH_MSG_ERROR ( "Error in writing Histograms" );
368 }
369
370 // Release all interfaces (ignore StatusCodes)
371 m_histoDataMgrSvc.release().ignore();
372 m_histoPersSvc.release().ignore();
373
374 m_whiteboard = 0;
376 m_schedulerSvc = 0;
377 // m_evtDataSvc = 0;
378
379 m_incidentSvc.release().ignore();
380
381 // Release event selector context
382 if ( m_evtSelector && m_evtContext ) {
383 m_evtSelector->releaseContext(m_evtContext).ignore();
384 // m_evtSelector = releaseInterface(m_evtSelector);
385 delete m_evtContext; m_evtContext = 0;
386 }
387
388
389 if(m_useTools) {
390 tool_iterator firstTool = m_tools.begin();
391 tool_iterator lastTool = m_tools.end();
392 unsigned int toolCtr = 0;
393 ATH_MSG_INFO ( "Summary of AthenaEvtLoopPreSelectTool invocation: (invoked/success/failure)" );
394 ATH_MSG_INFO ( "-----------------------------------------------------" );
395
396 for ( ; firstTool != lastTool; ++firstTool ) {
397 ATH_MSG_INFO ( "{:>2}.) {:.<48} ({:>6}/{:>6}/{:>6})",
398 toolCtr+1,
399 (*firstTool)->name(),
400 m_toolInvoke[toolCtr],
401 m_toolAccept[toolCtr],
402 m_toolReject[toolCtr]);
403 toolCtr++;
404 }
405 }
406 return ( sc.isFailure() || sc2.isFailure() ) ? StatusCode::FAILURE :
407 StatusCode::SUCCESS;
408
409}
410
411//=========================================================================
412// write out the histograms
413//=========================================================================
415
416 StatusCode sc (StatusCode::SUCCESS);
417
418 if ( 0 != m_histoPersSvc && m_writeHists ) {
419 std::vector<DataObject*> objects;
420 sc = m_histoDataMgrSvc->traverseTree( [&objects]( IRegistry* reg, int ) {
421 DataObject* obj = reg->object();
422 if ( !obj || obj->clID() == CLID_StatisticsFile ) return false;
423 objects.push_back( obj );
424 return true;
425 } );
426
427 if ( !sc.isSuccess() ) {
428 ATH_MSG_ERROR ( "Error while traversing Histogram data store" );
429 return sc;
430 }
431
432 if ( objects.size() > 0) {
433 int writeInterval(m_writeInterval.value());
434
435 if ( m_nevt == 1 || force ||
436 (writeInterval != 0 && m_nevt%writeInterval == 0) ) {
437
438 // skip /stat entry!
439 sc = std::accumulate( begin( objects ), end( objects ), sc, [&]( StatusCode isc, auto& i ) {
440 IOpaqueAddress* pAddr = nullptr;
441 StatusCode iret = m_histoPersSvc->createRep( i, pAddr );
442 if ( iret.isFailure() ) return iret;
443 i->registry()->setAddress( pAddr );
444 return isc;
445 } );
446 sc = std::accumulate( begin( objects ), end( objects ), sc, [&]( StatusCode isc, auto& i ) {
447 IRegistry* reg = i->registry();
448 StatusCode iret = m_histoPersSvc->fillRepRefs( reg->address(), i );
449 return iret.isFailure() ? iret : isc;
450 } );
451 if ( ! sc.isSuccess() ) {
452 ATH_MSG_ERROR ( "Error while saving Histograms." );
453 }
454 }
455
456 if (force || (writeInterval != 0 && m_nevt%writeInterval == 0) ) {
457 ATH_MSG_DEBUG ( "committing Histograms" );
458 m_histoPersSvc->conversionSvc()->commitOutput("",true).ignore();
459 }
460 }
461
462 }
463
464 return sc;
465}
466
467//=========================================================================
468// Call sysInitialize() on all algorithms and output streams
469//=========================================================================
471
472 return StatusCode::SUCCESS;
473}
474
475//=========================================================================
476// Run the algorithms for the current event
477//=========================================================================
479
480 return StatusCode::SUCCESS;
481}
482
483
484//=========================================================================
485// executeEvent( EventContext &&ctx )
486//=========================================================================
487StatusCode AthenaHiveEventLoopMgr::executeEvent( EventContext &&ctx )
488{
489
490 // An incident may schedule a stop, in which case is better to exit before the actual execution.
491 if ( m_scheduledStop ) {
492 ATH_MSG_ALWAYS ( "A stopRun was requested by an incidentListener. "
493 "Do not process this event." );
494 m_terminateLoop = true;
495 return (StatusCode::SUCCESS);
496 }
497
498 m_aess->reset( ctx );
499
500 // Make sure context with slot is set before calling es->next().
501 Gaudi::Hive::setCurrentContext ( ctx );
502
503 int declEvtRootSc = declareEventRootAddress( ctx );
504 if (declEvtRootSc == 0 ) { // We ran out of events!
505 m_terminateLoop = true; // we have finished!
506 return StatusCode::SUCCESS;
507 } else if ( declEvtRootSc == -1) {
508 // No std::format for EventContext
509 ATH_MSG_ERROR ( "declareEventRootAddress for context " << ctx << " failed" );
510 return StatusCode::FAILURE;
511 }
512
513 EventID::event_number_t evtNumber = ctx.eventID().event_number();
514 unsigned int conditionsRun = ctx.eventID().run_number();
515 if (!m_evtIdModSvc.isSet()) {
516 const AthenaAttributeList* attr = nullptr;
517 if (m_eventStore->contains<AthenaAttributeList> ("Input") &&
518 m_eventStore->retrieve(attr, "Input").isSuccess()) {
519 if (attr->exists ("ConditionsRun")) {
520 conditionsRun = (*attr)["ConditionsRun"].data<unsigned int>();
521 }
522 }
523 }
525 Gaudi::Hive::setCurrentContext ( ctx );
526
527 // Record EventContext in current whiteboard
528 if (m_eventStore->record(std::make_unique<EventContext> (ctx),
529 "EventContext").isFailure())
530 {
531 ATH_MSG_ERROR ( "Error recording event context object" );
532 return (StatusCode::FAILURE);
533 }
534
536 if (m_firstRun || (m_currentRun != ctx.eventID().run_number()) ) {
537 // Fire EndRun incident unless this is the first run
538 if (!m_firstRun) {
539 // FIXME!!!
540 m_incidentSvc->fireIncident(Incident(name(), IncidentType::EndRun));
541 }
542 m_firstRun=false;
543 m_currentRun = ctx.eventID().run_number();
544
545 ATH_MSG_INFO ( " ===>>> start of run {} <<<===", m_currentRun);
546
547 // FIXME!!! Fire BeginRun "Incident"
548 m_incidentSvc->fireIncident(Incident(name(),IncidentType::BeginRun,ctx));
549
550 }
551
552 bool toolsPassed=true;
553 // CGL: FIXME
554 // bool eventFailed = false;
555
556 // Call any attached tools to reject events early
557 unsigned int toolCtr=0;
558 if(m_useTools) {
559 tool_store::iterator theTool = m_tools.begin();
560 tool_store::iterator lastTool = m_tools.end();
561 while(toolsPassed && theTool!=lastTool )
562 {
563 toolsPassed = (*theTool)->passEvent(ctx.eventID());
564 m_toolInvoke[toolCtr]++;
565 {toolsPassed ? m_toolAccept[toolCtr]++ : m_toolReject[toolCtr]++;}
566 ++toolCtr;
567 ++theTool;
568 }
569 }
570
572 0 == (m_nev % m_eventPrintoutInterval.value()));
573 if (m_doEvtHeartbeat) {
574 if(!m_useTools) {
575 ATH_MSG_INFO ( " ===>>> start processing event #{}, run #{} on slot {}, {} events processed so far <<<===",
576 evtNumber, m_currentRun, ctx.slot(), m_proc);
577 }
578 else {
579 ATH_MSG_INFO ( " ===>>> start processing event #{}, run #{} on slot {}, {} events read and {} events processed so far <<<===",
580 evtNumber, m_currentRun, ctx.slot(), m_nev, m_proc);
581 }
582 }
583
584 // Reset the timeout singleton
586 if(toolsPassed) {
587
588 CHECK( m_conditionsCleaner->event (ctx, true) );
589
590 // Remember the last event context for after event processing finishes.
591 m_lastEventContext = ctx;
592
593 // Now add event to the scheduler
594 ATH_MSG_DEBUG ( "Adding event {}, slot {} to the scheduler",
595 ctx.evt(), ctx.slot());
596
597 m_incidentSvc->fireIncident(Incident(name(), IncidentType::BeginProcessing,
598 ctx));
599 StatusCode addEventStatus = m_schedulerSvc->pushNewEvent( new EventContext{ std::move(ctx) } );
600
601 // If this fails, we need to wait for something to complete
602 if (!addEventStatus.isSuccess()){
603 ATH_MSG_FATAL ( "An event processing slot should be now free in the scheduler, but it appears not to be the case." );
604 }
605
606 } // end of toolsPassed test
607
608 ++m_nev;
609
610 ++m_nevt;
611
612 // invalidate thread local context once outside of event execute loop
613 Gaudi::Hive::setCurrentContext( EventContext() );
614
615 return StatusCode::SUCCESS;
616
617}
618
619//=========================================================================
620// implementation of IEventProcessor::executeRun
621//=========================================================================
623{
624
625 StatusCode sc;
626 bool eventfailed = false;
627
628 // Call now the nextEvent(...)
629 sc = nextEvent(maxevt);
630 if (!sc.isSuccess())
631 eventfailed = true;
632
633 if (eventfailed)
634 return StatusCode::FAILURE;
635
636 m_incidentSvc->fireIncident(Incident(name(),"EndEvtLoop"));
637 return StatusCode::SUCCESS;
638}
639//-----------------------------------------------------------------------------
640// Implementation of IEventProcessor::stopRun()
641//-----------------------------------------------------------------------------
643 // Set the application return code
644 SmartIF<IProperty> appmgr(serviceLocator());
645 if(Gaudi::setAppReturnCode(appmgr, Gaudi::ReturnCode::ScheduledStop, true).isFailure()) {
646 ATH_MSG_ERROR ( "Could not set return code of the application ({})",
647 Gaudi::ReturnCode::ScheduledStop);
648 }
649 m_scheduledStop = true;
650 return StatusCode::SUCCESS;
651}
652
653
654//-----------------------------------------------------------------------------
655// Implementation of IService::stop()
656//-----------------------------------------------------------------------------
658{
659 // To enable conditions access during stop we set an invalid EventContext
660 // (no event/slot number) but with valid EventID (and extended EventContext).
661 m_lastEventContext.setValid(false);
662 Gaudi::Hive::setCurrentContext( m_lastEventContext );
663
664 StatusCode sc = MinimalEventLoopMgr::stop();
665
666 // If we exit the event loop early due to an error, some event stores
667 // may not have been cleared. This can lead to segfaults later,
668 // as DetectorStore will usually get finalized before HiveSvcMgr.
669 // So make sure that all stores have been cleared at this point.
670 size_t nslot = m_whiteboard->getNumberOfStores();
671 for (size_t islot = 0; islot < nslot; islot++) {
672 sc &= clearWBSlot (islot);
673 }
674
675 Gaudi::Hive::setCurrentContext( EventContext() );
676 return sc;
677}
678
679
680//=========================================================================
681// implementation of IAppMgrUI::nextEvent
682//=========================================================================
684{
685 // make nextEvent(0) a dummy call
686 if (0 == maxevt) return StatusCode::SUCCESS;
687
688 // Reset the application return code.
689 Gaudi::setAppReturnCode(m_appMgrProperty, Gaudi::ReturnCode::Success, true).ignore();
690
691 int finishedEvts =0;
692 int createdEvts =0;
693 ATH_MSG_INFO ( "Starting loop on events" );
694
695 // loop over events if the maxevt (received as input) is different from -1.
696 // if evtmax is -1 it means infinite loop (till time limit that is)
697 // int nevt(0);
698 // CGL: FIXME
699 // bool noTimeLimit(false);
700 bool loop_ended=false;
701 StatusCode sc(StatusCode::SUCCESS);
702
703 bool newEvtAllowed = ! m_firstEventAlone;
704
705 // Calculate runtime
706 auto start_time = tbb::tick_count::now();
707 auto secsFromStart = [&start_time]()->double{
708 return (tbb::tick_count::now()-start_time).seconds();
709 };
710
711 while ( !loop_ended and ( (maxevt < 0) or (finishedEvts < maxevt) ) ){
712
713 ATH_MSG_DEBUG ( " -> createdEvts: {}", createdEvts );
714
715 if ( ( !m_terminateLoop ) && // The events are not finished with an unlimited number of events
716 (newEvtAllowed || createdEvts == 0) && // Launch first event alone
717 ( (createdEvts < maxevt) or (maxevt<0) ) && // The events are not finished with a limited number of events
718 (m_schedulerSvc->freeSlots()>0) ){ // There are still free slots in the scheduler
719
720 ATH_MSG_DEBUG ( "createdEvts: {}, freeslots: {}",
721 createdEvts, m_schedulerSvc->freeSlots());
722
723 auto ctx = createEventContext();
724
725 if ( !ctx.valid() ) {
726 sc = StatusCode::FAILURE;
727 } else {
728 sc = executeEvent( std::move(ctx) );
729 }
730
731 if (sc.isFailure()) {
732 ATH_MSG_ERROR ( "Terminating event processing loop due to errors" );
733 loop_ended = true;
734 } else {
735 ++createdEvts;
736 }
737
738 } // end if condition createdEvts < maxevt
739
740 else {
741 // all the events were created but not all finished or the slots were
742 // all busy: the scheduler should finish its job
743
744 ATH_MSG_DEBUG ( "Draining the scheduler" );
745
746 // Pull out of the scheduler the finished events
747 int ir = drainScheduler(finishedEvts);
748 if (ir < 0) {
749 // some sort of error draining scheduler;
750 loop_ended = true;
751 sc = StatusCode::FAILURE;
752 } else if (ir == 0) {
753 // no more events in scheduler. we're done
754 loop_ended = true;
755 sc = StatusCode::SUCCESS;
756 } else {
757 // keep going!
758 }
759 newEvtAllowed = true;
760
761 }
762 } // end main loop on finished events
763
764 ATH_MSG_INFO ( "---> Loop Finished (seconds): {}", secsFromStart() );
765
766
767 return sc;
768
769
770}
771
772
773//=========================================================================
774// Seek to a given event.
775// The event selector must support the IEventSeek interface for this to work.
776//=========================================================================
778{
779 IEvtSelectorSeek* is = dynamic_cast<IEvtSelectorSeek*> (m_evtSelector);
780 if (is == 0) {
781 ATH_MSG_ERROR ( "Seek failed; unsupported by event selector" );
782 return StatusCode::FAILURE;
783 }
784 //cppcheck-suppress nullPointerRedundantCheck
785 if (!m_evtContext) {
786 if (m_evtSelector->createContext(m_evtContext).isFailure()) {
787 ATH_MSG_FATAL ( "Can not create the event selector Context." );
788 return StatusCode::FAILURE;
789 }
790 }
791 //m_evtContext cannot be null if createContext succeeded
792 //cppcheck-suppress nullPointerRedundantCheck
793 StatusCode sc = is->seek (*m_evtContext, evt);
794 if (sc.isSuccess()) {
795 m_incidentSvc->fireIncident(ContextIncident<std::tuple<int, int>>(
796 name(), "SkipEvents", std::tuple<int, int>(m_nevt, evt)));
797 m_nevt = evt;
798 }
799 else {
800 ATH_MSG_ERROR ( "Seek failed." );
801 }
802 return sc;
803}
804
805
806//=========================================================================
807// Return the current event count.
808//=========================================================================
810{
811 return m_nevt;
812}
813
814//=========================================================================
815// Return the collection size
816//=========================================================================
818{
819 IEvtSelectorSeek* cs = dynamic_cast<IEvtSelectorSeek*> (m_evtSelector);
820 if (cs == 0) {
821 ATH_MSG_ERROR ( "Collection size unsupported by event selector" );
822 return -1;
823 }
824 //cppcheck-suppress nullPointerRedundantCheck
825 if (!m_evtContext) {
826 if (m_evtSelector->createContext(m_evtContext).isFailure()) {
827 ATH_MSG_FATAL ( "Can not create the event selector Context." );
828 return -1;
829 }
830 }
831 //m_evtContext cannot be null if createContext succeeded
832 //cppcheck-suppress nullPointerRedundantCheck
833 return cs->size (*m_evtContext);
834}
835
836//=========================================================================
837// Handle Incidents
838//=========================================================================
839void AthenaHiveEventLoopMgr::handle(const Incident& inc)
840{
841
842 if(inc.type() == "EndAlgorithms") {
843 // Clear the store at the end of the event.
844 // Do it here so that it executes in an algorithm context and thus
845 // multiple stores can be cleared at the same time.
846 StatusCode sc = m_whiteboard->clearStore(inc.context().slot());
847 if( !sc.isSuccess() ) {
848 ATH_MSG_WARNING ( "Clear of Event data store failed" );
849 }
850 return;
851 }
852
853 if(inc.type()!="BeforeFork")
854 return;
855
856 if(!m_evtContext || !m_firstRun) {
857 ATH_MSG_WARNING ( "Skipping BeforeFork handler. Either no event selector is provided or begin run has already passed" );
858 }
859
860 // Initialize Algorithms and Output Streams
861 StatusCode sc = initializeAlgorithms();
862 if(sc.isFailure()) {
863 ATH_MSG_ERROR ( "Failed to initialize Algorithms" );
864 return;
865 }
866
867 // Construct EventInfo
868 sc = m_evtSelector->next(*m_evtContext);
869 if(!sc.isSuccess()) {
870 ATH_MSG_INFO ( "No more events in event selection " );
871 return;
872 }
873 IOpaqueAddress* addr{nullptr};
874 sc = m_evtSelector->createAddress(*m_evtContext, addr);
875 if (sc.isFailure()) {
876 ATH_MSG_ERROR ( "Could not create an IOpaqueAddress" );
877 return;
878 }
879 if (0 != addr) {
880 //create its proxy
881 sc = m_eventStore->recordAddress(addr);
882 if(!sc.isSuccess()) {
883 ATH_MSG_ERROR ( "Error declaring Event object" );
884 return;
885 }
886 }
887
888 if(m_eventStore->loadEventProxies().isFailure()) {
889 ATH_MSG_WARNING ( "Error loading Event proxies" );
890 return;
891 }
892
893 // Retrieve the legacy EventInfo object
894 const EventInfo* pEvent{nullptr};
895 sc = m_eventStore->retrieve(pEvent);
896 if(!sc.isSuccess()) {
897 ATH_MSG_ERROR ( "Unable to retrieve Event root object" );
898 return;
899 }
900
901 m_firstRun=false;
902 m_currentRun = pEvent->event_ID()->run_number();
903
904 // Clear Store
905 sc = m_eventStore->clearStore();
906 if(!sc.isSuccess()) {
907 ATH_MSG_ERROR ( "Clear of Event data store failed" );
908 }
909}
910
911//---------------------------------------------------------------------------
912
914StatusCode AthenaHiveEventLoopMgr::getEventRoot(IOpaqueAddress*& refpAddr) {
915 refpAddr = 0;
916 StatusCode sc = m_evtSelector->next(*m_evtContext);
917 if ( !sc.isSuccess() ) {
918 return sc;
919 }
920 // Create root address and assign address to data service
921 sc = m_evtSelector->createAddress(*m_evtContext,refpAddr);
922 if( !sc.isSuccess() ) {
923 sc = m_evtSelector->next(*m_evtContext);
924 if ( sc.isSuccess() ) {
925 sc = m_evtSelector->createAddress(*m_evtContext,refpAddr);
926 if ( !sc.isSuccess() ) {
927 ATH_MSG_WARNING ( "Error creating IOpaqueAddress." );
928 }
929 }
930 }
931 return sc;
932}
933
934//---------------------------------------------------------------------------
935
937
938 // return codes:
939 // -1 : error
940 // 0 : no more events in selection
941 // 1 : ok
942
943 StatusCode sc(StatusCode::SUCCESS);
944
945 //-----------------------------------------------------------------------
946 // we need an EventInfo Object to fire the incidents.
947 //-----------------------------------------------------------------------
948 std::unique_ptr<const EventInfo> pEvent{};
949 if ( m_evtContext ) {
950 // Deal with the case when an EventSelector is provided
951 //
952 // FIXME: flow control if no more events in selector, etc.
953 //
954
955 IOpaqueAddress* addr{};
956
957 sc = m_evtSelector->next(*m_evtContext);
958
959 if ( !sc.isSuccess() ) {
960 // This is the end of the loop. No more events in the selection
961 ATH_MSG_INFO ( "No more events in event selection " );
962 return 0;
963 }
964
965 if (m_evtSelector->createAddress(*m_evtContext, addr).isFailure()) {
966 ATH_MSG_ERROR ( "Could not create an IOpaqueAddress" );
967 return -1;
968 }
969
970
971 // Most iterators provide the IOA of an event header (EventInfo, DataHeader)
972 if (0 != addr) {
973 //create its proxy
974 sc = m_eventStore->recordAddress(addr);
975 if( !sc.isSuccess() ) {
977 ATH_MSG_WARNING ( "Error declaring Event object" );
978 return 0;
979 }
980 } if ((sc=m_eventStore->loadEventProxies()).isFailure()) {
981 ATH_MSG_ERROR ( "Error loading Event proxies" );
982 return -1;
983 }
984
985 bool consume_modifier_stream = false;
986 // First try to build a legacy EventInfo object from the TAG information
987 // Read the attribute list
988 const AthenaAttributeList* pAttrList = m_eventStore->tryConstRetrieve<AthenaAttributeList>("Input");
989 if ( pAttrList != nullptr && pAttrList->size() > 6 ) { // Try making EventID-only EventInfo object from in-file TAG
990 try {
991 unsigned int runNumber = (*pAttrList)["RunNumber"].data<unsigned int>();
992 unsigned long long eventNumber = (*pAttrList)["EventNumber"].data<unsigned long long>();
993 unsigned int eventTime = (*pAttrList)["EventTime"].data<unsigned int>();
994 unsigned int eventTimeNS = (*pAttrList)["EventTimeNanoSec"].data<unsigned int>();
995 unsigned int lumiBlock = (*pAttrList)["LumiBlockN"].data<unsigned int>();
996 unsigned int bunchId = (*pAttrList)["BunchId"].data<unsigned int>();
997
998 ATH_MSG_DEBUG ( "use TAG with runNumber={}", runNumber );
999 consume_modifier_stream = true;
1000 // an option to override primary eventNumber with the secondary one in case of DoubleEventSelector
1002 unsigned long long eventNumberSecondary{};
1003 if ( !(pAttrList->exists("hasSecondaryInput") && (*pAttrList)["hasSecondaryInput"].data<bool>()) ) {
1004 ATH_MSG_FATAL ( "Secondary EventNumber requested, but secondary input does not exist!" );
1005 return -1;
1006 }
1007 if ( pAttrList->exists("EventNumber_secondary") ) {
1008 eventNumberSecondary = (*pAttrList)["EventNumber_secondary"].data<unsigned long long>();
1009 }
1010 else {
1011 // try legacy EventInfo if secondary input did not have attribute list
1012 // primary input should not have this EventInfo type
1013 const EventInfo* pEventSecondary = m_eventStore->tryConstRetrieve<EventInfo>();
1014 if (pEventSecondary) {
1015 eventNumberSecondary = pEventSecondary->event_ID()->event_number();
1016 }
1017 else {
1018 ATH_MSG_FATAL ( "Secondary EventNumber requested, but it does not exist!" );
1019 return -1;
1020 }
1021 }
1022 if (eventNumberSecondary != 0) {
1023 m_doEvtHeartbeat = (m_eventPrintoutInterval.value() > 0 &&
1024 0 == (m_nev % m_eventPrintoutInterval.value()));
1025 if (m_doEvtHeartbeat) {
1026 ATH_MSG_INFO ( " ===>>> using secondary event #{} instead of #{} <<<===",
1027 eventNumberSecondary, eventNumber);
1028 }
1029 eventNumber = eventNumberSecondary;
1030 }
1031 }
1032
1033 pEvent = std::make_unique<EventInfo>(
1034 std::make_unique<EventID>(runNumber, eventNumber, eventTime,
1035 eventTimeNS, lumiBlock, bunchId),
1036 nullptr);
1037 } catch (...) {
1038 }
1039 } else if (m_requireInputAttributeList) {
1040 ATH_MSG_FATAL ( "Valid input attribute list required but not present!" );
1041 return -1;
1042 }
1043 // In the case that there is no TAG information
1044 const EventInfo* pEventObserver{pEvent.get()};
1045 if (!pEventObserver) {
1046 // Secondly try to retrieve a legacy EventInfo object from the input file
1047 // Again, m_nevt is incremented after executeEvent in the Hive manager so we don't need a -1
1049 pEventObserver = m_eventStore->tryConstRetrieve<EventInfo>();
1050 if (pEventObserver) {
1051 consume_modifier_stream = false; // stream will already have been consumed during EventInfo TP conversion
1052 ATH_MSG_DEBUG ( "use EventInfo" );
1053 } else {
1054 // Finally try to retrieve an xAOD::EventInfo object from the
1055 // input file and build a legacy EventInfo object from that.
1056 const xAOD::EventInfo* pXEvent{nullptr};
1057 sc = m_eventStore->retrieve(pXEvent);
1058 if( !sc.isSuccess() ) {
1059 ATH_MSG_ERROR ( "Unable to retrieve Event root object" );
1060 return -1;
1061 }
1062 consume_modifier_stream = true;
1063 ATH_MSG_DEBUG ( "use xAOD::EventInfo with runNumber={}", pXEvent->runNumber() );
1064 // Build the old-style Event Info object for those clients that still need it
1065 pEvent = std::make_unique<EventInfo>(
1066 std::make_unique<EventID>(eventIDFromxAOD(pXEvent)),
1067 std::make_unique<EventType>(eventTypeFromxAOD(pXEvent)));
1068 pEventObserver = pEvent.get();
1069 sc = m_eventStore->record(std::move(pEvent), "");
1070 if( !sc.isSuccess() ) {
1071 ATH_MSG_ERROR ( "Error declaring event data object" );
1072 return -1;
1073 }
1074 }
1075 }
1076
1077 modifyEventContext(ctx, *(pEventObserver->event_ID()),
1078 consume_modifier_stream);
1079
1080 }
1081 else {
1082 // No EventSelector is provided, so with no iterator it's up to us
1083 // to create an EventInfo
1084 // first event # == 1
1085 unsigned int runNmb{1}, evtNmb{m_nevt + 1};
1086
1087 // increment the run/lumiBlock number if desired
1088 if (m_flmbi != 0) {
1089 runNmb = m_nevt / m_flmbi + 1;
1090 evtNmb = m_nevt % m_flmbi + 1;
1091 }
1092 auto eid = std::make_unique<EventID> (runNmb,evtNmb, m_timeStamp);
1093 // Change lumiBlock# to match runNumber
1094 eid->set_lumi_block( runNmb );
1095
1097
1098 pEvent = std::make_unique<EventInfo>(std::move(eid),
1099 std::make_unique<EventType>());
1100
1101 bool consume_modifier_stream = true;
1102 // EventInfo TP Conversion not called in this case, so we would
1103 // want to consume the next IoV from the list in the
1104 // EvtIdModifierSvc.
1105 modifyEventContext(ctx,*(pEvent->event_ID()), consume_modifier_stream);
1106
1107 ATH_MSG_DEBUG ( "selecting store: {}", ctx.slot() );
1108
1109 m_whiteboard->selectStore( ctx.slot() ).ignore();
1110
1111 // EventInfo not working with format
1112 ATH_MSG_DEBUG ( "recording EventInfo " << *pEvent->event_ID() << " in "
1113 << m_eventStore->name() );
1114
1115 sc = m_eventStore->record(std::move(pEvent), "McEventInfo");
1116 if( !sc.isSuccess() ) {
1117 ATH_MSG_ERROR ( "Error declaring event data object" );
1118 return -1;
1119 }
1120 }
1121
1122 return 1;
1123}
1124
1125//---------------------------------------------------------------------------
1126
1127void AthenaHiveEventLoopMgr::modifyEventContext(EventContext& ctx, const EventID& eID, bool consume_modifier_stream) {
1128
1129 if(m_evtIdModSvc.isSet()) {
1130 EventID new_eID(eID);
1131 // In Hive EventLoopMgr ctx.evt() gets set to m_nevt and *then* m_nevt is
1132 // incremented later so it's zero-indexed and we don't need to subtract one
1133 m_evtIdModSvc->modify_evtid(new_eID, ctx.evt(), consume_modifier_stream);
1134 if (msgLevel(MSG::DEBUG)) {
1135 unsigned int oldrunnr=eID.run_number();
1136 unsigned int oldLB=eID.lumi_block();
1137 unsigned int oldTS=eID.time_stamp();
1138 unsigned int oldTSno=eID.time_stamp_ns_offset();
1139 ATH_MSG_DEBUG ( "modifyEventContext: use evtIdModSvc runnr={} -> {}",
1140 oldrunnr, new_eID.run_number());
1141 ATH_MSG_DEBUG ( "modifyEventContext: use evtIdModSvc LB={} -> {}",
1142 oldLB, new_eID.lumi_block());
1143 ATH_MSG_DEBUG ( "modifyEventContext: use evtIdModSvc TimeStamp={} -> {}",
1144 oldTS, new_eID.time_stamp());
1145 ATH_MSG_DEBUG ( "modifyEventContext: use evtIdModSvc TimeStamp ns Offset={} -> {}",
1146 oldTSno, new_eID.time_stamp_ns_offset());
1147 }
1148 ctx.setEventID( new_eID );
1149 Atlas::getExtendedEventContext(ctx).setConditionsRun( ctx.eventID().run_number() );
1150 return;
1151 }
1152
1153 ctx.setEventID( eID );
1154}
1155
1156//---------------------------------------------------------------------------
1158
1159 EventContext ctx{ m_nevt, m_whiteboard->allocateStore( m_nevt ) };
1160
1161 StatusCode sc = m_whiteboard->selectStore( ctx.slot() );
1162 if (sc.isFailure()) {
1163 ATH_MSG_FATAL ( "Slot {} could not be selected for the WhiteBoard",
1164 ctx.slot());
1165 return EventContext{}; // invalid EventContext
1166 } else {
1168 Atlas::ExtendedEventContext( m_eventStore->hiveProxyDict() ) );
1169
1170 ATH_MSG_DEBUG ( "created EventContext, num: {} in slot: {}",
1171 ctx.evt(), ctx.slot());
1172 }
1173
1174 return ctx;
1175}
1176
1177//---------------------------------------------------------------------------
1178
1179int
1181
1182 StatusCode sc(StatusCode::SUCCESS);
1183
1184 // maybe we can do better
1185 std::vector<std::unique_ptr<EventContext>> finishedEvtContexts;
1186
1187 EventContext* finishedEvtContext(nullptr);
1188
1189 // Here we wait not to loose cpu resources
1190 ATH_MSG_DEBUG ( "drainScheduler: [{}] Waiting for a context", finishedEvts);
1191 sc = m_schedulerSvc->popFinishedEvent(finishedEvtContext);
1192
1193 // We got past it: cache the pointer
1194 if (sc.isSuccess()){
1195 // EventContext not working with std::format
1196 ATH_MSG_DEBUG ( "drainScheduler: scheduler not empty: Context "
1197 << finishedEvtContext );
1198 finishedEvtContexts.emplace_back(finishedEvtContext);
1199 } else{
1200 // no more events left in scheduler to be drained
1201 ATH_MSG_DEBUG ( "drainScheduler: scheduler empty" );
1202 return 0;
1203 }
1204
1205 // Let's see if we can pop other event contexts
1206 while (m_schedulerSvc->tryPopFinishedEvent(finishedEvtContext).isSuccess()){
1207 finishedEvtContexts.emplace_back(finishedEvtContext);
1208 }
1209
1210 // Now we flush them
1211 bool fail(false);
1212 for (auto& thisFinishedEvtContext : finishedEvtContexts){
1213 if (!thisFinishedEvtContext) {
1214 ATH_MSG_FATAL ( "Detected nullptr ctxt while clearing WB!");
1215 fail = true;
1216 continue;
1217 }
1218
1219 if (m_aess->eventStatus(*thisFinishedEvtContext) != EventStatus::Success) {
1220 // EventContext not working with std::format
1221 ATH_MSG_FATAL ( "Failed event detected on " << thisFinishedEvtContext
1222 << " w/ fail mode: "
1223 << m_aess->eventStatus(*thisFinishedEvtContext) );
1224 fail = true;
1225 continue;
1226 }
1227
1228 EventID::number_type n_run(0);
1229 EventID::event_number_t n_evt(0);
1230
1231 if (m_whiteboard->selectStore(thisFinishedEvtContext->slot()).isSuccess()) {
1232 n_run = thisFinishedEvtContext->eventID().run_number();
1233 n_evt = thisFinishedEvtContext->eventID().event_number();
1234 } else {
1235 ATH_MSG_ERROR ( "DrainSched: unable to select store {}",
1236 thisFinishedEvtContext->slot() );
1237 fail = true;
1238 continue;
1239 }
1240
1241 // m_incidentSvc->fireIncident(Incident(name(), IncidentType::EndEvent,
1242 // *thisFinishedEvtContext ));
1243
1244 // Some code still needs global context in addition to that passed in the incident
1245 Gaudi::Hive::setCurrentContext( *thisFinishedEvtContext );
1246 m_incidentSvc->fireIncident(Incident(name(), IncidentType::EndProcessing, *thisFinishedEvtContext ));
1247
1248 ATH_MSG_DEBUG( "Clearing slot {} (event {}) of the whiteboard",
1249 thisFinishedEvtContext->slot(),
1250 thisFinishedEvtContext->evt() );
1251
1252 StatusCode sc = clearWBSlot(thisFinishedEvtContext->slot());
1253 if (!sc.isSuccess()) {
1254 ATH_MSG_ERROR ( "Whiteboard slot {} could not be properly cleared",
1255 thisFinishedEvtContext->slot() );
1256 fail = true;
1257 continue;
1258 }
1259
1260 finishedEvts++;
1261
1262 writeHistograms().ignore();
1263 ++m_proc;
1264
1265 if (m_doEvtHeartbeat) {
1266 if(!m_useTools)
1267 ATH_MSG_INFO ( " ===>>> done processing event #{}, run #{} on slot {}, {} events processed so far <<<===",
1268 n_evt, n_run, thisFinishedEvtContext->slot(), m_proc);
1269 else
1270 ATH_MSG_INFO ( " ===>>> done processing event #{}, run #{} on slot {}, {} events read and {} events processed so far <<<===",
1271 n_evt, n_run, thisFinishedEvtContext->slot(), m_nev, m_proc);
1272 std::ofstream outfile( "eventLoopHeartBeat.txt");
1273 if ( !outfile ) {
1274 ATH_MSG_ERROR ( " unable to open: eventLoopHeartBeat.txt" );
1275 fail = true;
1276 continue;
1277 } else {
1278 std::print (outfile, " done processing event #{}, run # {} events read so far <<<===",
1279 n_evt, n_run, m_nev);
1280 outfile.close();
1281 }
1282 }
1283
1284 // EventContext not working with format.
1285 ATH_MSG_DEBUG ( "drainScheduler thisFinishedEvtContext: " << thisFinishedEvtContext );
1286 }
1287
1288 return ( fail ? -1 : 1 );
1289
1290}
1291
1292//---------------------------------------------------------------------------
1293
1295 return m_whiteboard->freeStore(evtSlot);
1296}
1297//---------------------------------------------------------------------------
1298
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_ALWAYS(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
The default ATLAS batch event loop manager.
Helpers for checking error return status codes and reporting errors.
#define CHECK(...)
Evaluate an expression and check for errors.
Assign a CLID to EventContext.
This class provides a unique identification for each event, in terms of run/event number and/or a tim...
EventID eventIDFromxAOD(const xAOD::EventInfo *xaod)
Create EventID object from xAOD::EventInfo.
EventType eventTypeFromxAOD(const xAOD::EventInfo *xaod)
Create EventType object from xAOD::EventInfo.
This class provides general information about an event.
This file contains the class definition for the IAthenaEvtLoopPreSelectTool class.
Abstract interface for seeking within an event stream.
Extension to IEvtSelector to allow for seeking.
static Double_t sc
void setProperty(columnar::PythonToolHandle &self, const std::string &key, nb::object value)
An AttributeList represents a logical row of attributes in a metadata table.
AthMessaging(IMessageSvc *msgSvc, const std::string &name)
Constructor.
An AttributeList represents a logical row of attributes in a metadata table.
UnsignedIntegerProperty m_eventPrintoutInterval
IEvtSelector * m_evtSelector
Reference to the Event Selector.
virtual StatusCode stopRun() override
implementation of IEventProcessor::stopRun()
virtual void handle(const Incident &inc) override
IIncidentListenet interfaces.
ServiceHandle< IConversionSvc > IConversionSvc_t
virtual StatusCode initialize() override
implementation of IAppMgrUI::initalize
SmartIF< IHiveWhiteBoard > m_whiteboard
Reference to the Whiteboard interface.
StatusCode getEventRoot(IOpaqueAddress *&refpAddr)
Create event address using event selector.
int drainScheduler(int &finishedEvents)
Drain the scheduler from all actions that may be queued.
number_type m_currentRun
current run number
virtual int size() override
Return the size of the collection.
SmartIF< IAlgExecStateSvc > m_aess
Reference to the Algorithm Execution State Svc.
virtual const std::string & name() const override
std::string m_schedulerName
Name of the scheduler to be used.
UnsignedIntegerProperty m_writeInterval
std::string m_whiteboardName
Name of the Whiteboard to be used.
tool_stats m_toolAccept
tool returns StatusCode::SUCCESS counter
virtual StatusCode executeRun(int maxevt) override
implementation of IEventProcessor::executeRun(int maxevt)
tool_store::const_iterator tool_iterator
unsigned int m_nev
events processed
tool_stats m_toolInvoke
tool called counter
IIncidentSvc_t m_incidentSvc
Reference to the incident service.
virtual StatusCode stop() override
implementation of IService::stop
bool m_useSecondaryEventNumber
read event number from secondary input
bool m_requireInputAttributeList
require input attribute list
SmartIF< IProperty > m_appMgrProperty
Property interface of ApplicationMgr.
StoreGateSvc_t m_eventStore
Reference to StoreGateSvc;.
EvtContext * m_evtContext
Gaudi event selector Context (may be used as a cursor by the evt selector).
virtual StatusCode seek(int evt) override
Seek to a given event.
int declareEventRootAddress(EventContext &)
Declare the root address of the event.
AthenaHiveEventLoopMgr()=delete
virtual StatusCode finalize() override
implementation of IAppMgrUI::finalize
virtual StatusCode executeEvent(EventContext &&ctx) override
implementation of IEventProcessor::executeEvent(void* par)
IDataManagerSvc_t m_histoDataMgrSvc
Reference to the Histogram Data Service.
bool m_scheduledStop
Scheduled stop of event processing.
virtual EventContext createEventContext() override
Create event context.
StatusCode initializeAlgorithms()
Initialize all algorithms and output streams.
virtual ~AthenaHiveEventLoopMgr()
Standard Destructor.
StatusCode clearWBSlot(int evtSlot)
Clear a slot in the WB.
ServiceHandle< Athena::IConditionsCleanerSvc > m_conditionsCleaner
tool_store m_tools
internal tool store
virtual void modifyEventContext(EventContext &ctx, const EventID &eID, bool consume_modifier_stream)
virtual StatusCode writeHistograms(bool force=false)
Dump out histograms as needed.
void setupPreSelectTools(Gaudi::Details::PropertyBase &)
property update handler:sets up the Pre-selection tools
SmartIF< IScheduler > m_schedulerSvc
A shortcut for the scheduler.
virtual int curEvent() const override
Return the current event count.
tool_stats m_toolReject
tool returns StatusCode::FAILURE counter
IEvtIdModifierSvc_t m_evtIdModSvc
SmartIF< IAlgResourcePool > m_algResourcePool
Reference to the Algorithm resource pool.
virtual StatusCode nextEvent(int maxevt) override
implementation of IAppMgrUI::nextEvent. maxevt==0 returns immediately
virtual StatusCode executeAlgorithms()
Run the algorithms for the current event.
void resetTimeout(Timeout &instance)
Reset timeout.
Definition Timeout.h:83
static Timeout & instance()
Get reference to Timeout singleton.
Definition Timeout.h:64
void setConditionsRun(EventIDBase::number_type conditionsRun)
This class provides a unique identification for each event, in terms of run/event number and/or a tim...
Definition EventID.h:34
EventIDBase::number_type number_type
Definition EventID.h:36
This class provides general information about an event.
EventID * event_ID()
the unique identification of the event.
Abstract interface for seeking for an event selector.
virtual StatusCode seek(IEvtSelector::Context &c, int evtnum) const =0
Seek to a given event number.
virtual int size(IEvtSelector::Context &c) const =0
Return the size of the collection, or -1 if we can't get the size.
uint32_t runNumber() const
The current event's run number.
int ir
counter of the current depth
Definition fastadd.cxx:49
void setExtendedEventContext(EventContext &ctx, ExtendedEventContext &&ectx)
Move an extended context into a context object.
const ExtendedEventContext & getExtendedEventContext(const EventContext &ctx)
Retrieve an extended context from a context object.
event_number_t eventIndex
EventInfo_v1 EventInfo
Definition of the latest event info version.