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