ATLAS Offline Software
Loading...
Searching...
No Matches
AthenaHiveEventLoopMgr.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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
317inline
320 return m_eventStore.get();
321}
322
323//=========================================================================
324// property handlers
325//=========================================================================
326void
327AthenaHiveEventLoopMgr::setupPreSelectTools(Gaudi::Details::PropertyBase&) {
328
329 m_toolInvoke.clear();
330 m_toolReject.clear();
331 m_toolAccept.clear();
332
333 m_tools.retrieve().ignore();
334 if(m_tools.size() > 0) {
335 m_useTools=true;
336 m_toolInvoke.resize(m_tools.size());
337 m_toolReject.resize(m_tools.size());
338 m_toolAccept.resize(m_tools.size());
339
340 tool_iterator firstTool = m_tools.begin();
341 tool_iterator lastTool = m_tools.end();
342 unsigned int toolCtr = 0;
343 for ( ; firstTool != lastTool; ++firstTool )
344 {
345 // reset statistics
346 m_toolInvoke[toolCtr] = 0;
347 m_toolReject[toolCtr] = 0;
348 m_toolAccept[toolCtr] = 0;
349 toolCtr++;
350 }
351 }
352
353 return;
354
355}
356
357//=========================================================================
358// implementation of IAppMgrUI::finalize
359//=========================================================================
361{
362
363 StatusCode sc = MinimalEventLoopMgr::finalize();
364 if (sc.isFailure())
365 {
366 ATH_MSG_ERROR ( "Error in Service base class Finalize" );
367 }
368
369 StatusCode sc2 = writeHistograms(true);
370 if (sc2.isFailure())
371 {
372 ATH_MSG_ERROR ( "Error in writing Histograms" );
373 }
374
375 // Release all interfaces (ignore StatusCodes)
376 m_histoDataMgrSvc.release().ignore();
377 m_histoPersSvc.release().ignore();
378
379 m_whiteboard = 0;
381 m_schedulerSvc = 0;
382 // m_evtDataSvc = 0;
383
384 m_incidentSvc.release().ignore();
385
386 // Release event selector context
387 if ( m_evtSelector && m_evtContext ) {
388 m_evtSelector->releaseContext(m_evtContext).ignore();
389 // m_evtSelector = releaseInterface(m_evtSelector);
390 delete m_evtContext; m_evtContext = 0;
391 }
392
393
394 if(m_useTools) {
395 tool_iterator firstTool = m_tools.begin();
396 tool_iterator lastTool = m_tools.end();
397 unsigned int toolCtr = 0;
398 ATH_MSG_INFO ( "Summary of AthenaEvtLoopPreSelectTool invocation: (invoked/success/failure)" );
399 ATH_MSG_INFO ( "-----------------------------------------------------" );
400
401 for ( ; firstTool != lastTool; ++firstTool ) {
402 ATH_MSG_INFO ( std::setw(2) << std::setiosflags(std::ios_base::right)
403 << toolCtr+1 << ".) " << std::resetiosflags(std::ios_base::right)
404 << std::setw(48) << std::setfill('.')
405 << std::setiosflags(std::ios_base::left)
406 << (*firstTool)->name() << std::resetiosflags(std::ios_base::left)
407 << std::setfill(' ')
408 << " ("
409 << std::setw(6) << std::setiosflags(std::ios_base::right)
410 << m_toolInvoke[toolCtr]
411 << "/"
412 << m_toolAccept[toolCtr]
413 << "/"
414 << m_toolReject[toolCtr]
415 << ")"
416 );
417 toolCtr++;
418 }
419 }
420 return ( sc.isFailure() || sc2.isFailure() ) ? StatusCode::FAILURE :
421 StatusCode::SUCCESS;
422
423}
424
425//=========================================================================
426// write out the histograms
427//=========================================================================
429
430 StatusCode sc (StatusCode::SUCCESS);
431
432 if ( 0 != m_histoPersSvc && m_writeHists ) {
433 std::vector<DataObject*> objects;
434 sc = m_histoDataMgrSvc->traverseTree( [&objects]( IRegistry* reg, int ) {
435 DataObject* obj = reg->object();
436 if ( !obj || obj->clID() == CLID_StatisticsFile ) return false;
437 objects.push_back( obj );
438 return true;
439 } );
440
441 if ( !sc.isSuccess() ) {
442 ATH_MSG_ERROR ( "Error while traversing Histogram data store" );
443 return sc;
444 }
445
446 if ( objects.size() > 0) {
447 int writeInterval(m_writeInterval.value());
448
449 if ( m_nevt == 1 || force ||
450 (writeInterval != 0 && m_nevt%writeInterval == 0) ) {
451
452 // skip /stat entry!
453 sc = std::accumulate( begin( objects ), end( objects ), sc, [&]( StatusCode isc, auto& i ) {
454 IOpaqueAddress* pAddr = nullptr;
455 StatusCode iret = m_histoPersSvc->createRep( i, pAddr );
456 if ( iret.isFailure() ) return iret;
457 i->registry()->setAddress( pAddr );
458 return isc;
459 } );
460 sc = std::accumulate( begin( objects ), end( objects ), sc, [&]( StatusCode isc, auto& i ) {
461 IRegistry* reg = i->registry();
462 StatusCode iret = m_histoPersSvc->fillRepRefs( reg->address(), i );
463 return iret.isFailure() ? iret : isc;
464 } );
465 if ( ! sc.isSuccess() ) {
466 ATH_MSG_ERROR ( "Error while saving Histograms." );
467 }
468 }
469
470 if (force || (writeInterval != 0 && m_nevt%writeInterval == 0) ) {
471 ATH_MSG_DEBUG ( "committing Histograms" );
472 m_histoPersSvc->conversionSvc()->commitOutput("",true).ignore();
473 }
474 }
475
476 }
477
478 return sc;
479}
480
481//=========================================================================
482// Call sysInitialize() on all algorithms and output streams
483//=========================================================================
485
486 return StatusCode::SUCCESS;
487}
488
489//=========================================================================
490// Run the algorithms for the current event
491//=========================================================================
493
494 return StatusCode::SUCCESS;
495}
496
497
498//=========================================================================
499// executeEvent( EventContext &&ctx )
500//=========================================================================
501StatusCode AthenaHiveEventLoopMgr::executeEvent( EventContext &&ctx )
502{
503
504 // An incident may schedule a stop, in which case is better to exit before the actual execution.
505 if ( m_scheduledStop ) {
506 ATH_MSG_ALWAYS ( "A stopRun was requested by an incidentListener. "
507 << "Do not process this event." );
508 m_terminateLoop = true;
509 return (StatusCode::SUCCESS);
510 }
511
512 m_aess->reset( ctx );
513
514 // Make sure context with slot is set before calling es->next().
515 Gaudi::Hive::setCurrentContext ( ctx );
516
517 int declEvtRootSc = declareEventRootAddress( ctx );
518 if (declEvtRootSc == 0 ) { // We ran out of events!
519 m_terminateLoop = true; // we have finished!
520 return StatusCode::SUCCESS;
521 } else if ( declEvtRootSc == -1) {
522 ATH_MSG_ERROR ( "declareEventRootAddress for context " << ctx << " failed" );
523 return StatusCode::FAILURE;
524 }
525
526 EventID::event_number_t evtNumber = ctx.eventID().event_number();
527 unsigned int conditionsRun = ctx.eventID().run_number();
528 if (!m_evtIdModSvc.isSet()) {
529 const AthenaAttributeList* attr = nullptr;
530 if (eventStore()->contains<AthenaAttributeList> ("Input") &&
531 eventStore()->retrieve(attr, "Input").isSuccess()) {
532 if (attr->exists ("ConditionsRun")) {
533 conditionsRun = (*attr)["ConditionsRun"].data<unsigned int>();
534 }
535 }
536 }
538 Gaudi::Hive::setCurrentContext ( ctx );
539
540 // Record EventContext in current whiteboard
541 if (eventStore()->record(std::make_unique<EventContext> (ctx),
542 "EventContext").isFailure())
543 {
544 ATH_MSG_ERROR ( "Error recording event context object" );
545 return (StatusCode::FAILURE);
546 }
547
549 if (m_firstRun || (m_currentRun != ctx.eventID().run_number()) ) {
550 // Fire EndRun incident unless this is the first run
551 if (!m_firstRun) {
552 // FIXME!!!
553 m_incidentSvc->fireIncident(Incident(name(), IncidentType::EndRun));
554 }
555 m_firstRun=false;
556 m_currentRun = ctx.eventID().run_number();
557
558 ATH_MSG_INFO ( " ===>>> start of run " << m_currentRun << " <<<===" );
559
560 // FIXME!!! Fire BeginRun "Incident"
561 m_incidentSvc->fireIncident(Incident(name(),IncidentType::BeginRun,ctx));
562
563 }
564
565 bool toolsPassed=true;
566 // CGL: FIXME
567 // bool eventFailed = false;
568
569 // Call any attached tools to reject events early
570 unsigned int toolCtr=0;
571 if(m_useTools) {
572 tool_store::iterator theTool = m_tools.begin();
573 tool_store::iterator lastTool = m_tools.end();
574 while(toolsPassed && theTool!=lastTool )
575 {
576 toolsPassed = (*theTool)->passEvent(ctx.eventID());
577 m_toolInvoke[toolCtr]++;
578 {toolsPassed ? m_toolAccept[toolCtr]++ : m_toolReject[toolCtr]++;}
579 ++toolCtr;
580 ++theTool;
581 }
582 }
583
585 0 == (m_nev % m_eventPrintoutInterval.value()));
586 if (m_doEvtHeartbeat) {
587 if(!m_useTools) {
588 ATH_MSG_INFO ( " ===>>> start processing event #" << evtNumber << ", run #" << m_currentRun
589 << " on slot " << ctx.slot() << ", " << m_proc
590 << " events processed so far <<<===" );
591 }
592 else {
593 ATH_MSG_INFO ( " ===>>> start processing event #" << evtNumber << ", run #" << m_currentRun
594 << " on slot " << ctx.slot() << ", "
595 << m_nev << " events read and " << m_proc
596 << " events processed so far <<<===" );
597 }
598 }
599
600 // Reset the timeout singleton
602 if(toolsPassed) {
603
604 CHECK( m_conditionsCleaner->event (ctx, true) );
605
606 // Remember the last event context for after event processing finishes.
607 m_lastEventContext = ctx;
608
609 // Now add event to the scheduler
610 ATH_MSG_DEBUG ( "Adding event " << ctx.evt()
611 << ", slot " << ctx.slot()
612 << " to the scheduler" );
613
614 m_incidentSvc->fireIncident(Incident(name(), IncidentType::BeginProcessing,
615 ctx));
616 StatusCode addEventStatus = m_schedulerSvc->pushNewEvent( new EventContext{ std::move(ctx) } );
617
618 // If this fails, we need to wait for something to complete
619 if (!addEventStatus.isSuccess()){
620 ATH_MSG_FATAL ( "An event processing slot should be now free in the scheduler, but it appears not to be the case." );
621 }
622
623 } // end of toolsPassed test
624
625 ++m_nev;
626
627 ++m_nevt;
628
629 // invalidate thread local context once outside of event execute loop
630 Gaudi::Hive::setCurrentContext( EventContext() );
631
632 return StatusCode::SUCCESS;
633
634}
635
636//=========================================================================
637// implementation of IEventProcessor::executeRun
638//=========================================================================
640{
641
642 StatusCode sc;
643 bool eventfailed = false;
644
645 // Call now the nextEvent(...)
646 sc = nextEvent(maxevt);
647 if (!sc.isSuccess())
648 eventfailed = true;
649
650 if (eventfailed)
651 return StatusCode::FAILURE;
652
653 m_incidentSvc->fireIncident(Incident(name(),"EndEvtLoop"));
654 return StatusCode::SUCCESS;
655}
656//-----------------------------------------------------------------------------
657// Implementation of IEventProcessor::stopRun()
658//-----------------------------------------------------------------------------
660 // Set the application return code
661 SmartIF<IProperty> appmgr(serviceLocator());
662 if(Gaudi::setAppReturnCode(appmgr, Gaudi::ReturnCode::ScheduledStop, true).isFailure()) {
663 ATH_MSG_ERROR ( "Could not set return code of the application ("
664 << Gaudi::ReturnCode::ScheduledStop << ")" );
665 }
666 m_scheduledStop = true;
667 return StatusCode::SUCCESS;
668}
669
670
671//-----------------------------------------------------------------------------
672// Implementation of IService::stop()
673//-----------------------------------------------------------------------------
675{
676 // To enable conditions access during stop we set an invalid EventContext
677 // (no event/slot number) but with valid EventID (and extended EventContext).
678 m_lastEventContext.setValid(false);
679 Gaudi::Hive::setCurrentContext( m_lastEventContext );
680
681 StatusCode sc = MinimalEventLoopMgr::stop();
682
683 // If we exit the event loop early due to an error, some event stores
684 // may not have been cleared. This can lead to segfaults later,
685 // as DetectorStore will usually get finalized before HiveSvcMgr.
686 // So make sure that all stores have been cleared at this point.
687 size_t nslot = m_whiteboard->getNumberOfStores();
688 for (size_t islot = 0; islot < nslot; islot++) {
689 sc &= clearWBSlot (islot);
690 }
691
692 Gaudi::Hive::setCurrentContext( EventContext() );
693 return sc;
694}
695
696
697//=========================================================================
698// implementation of IAppMgrUI::nextEvent
699//=========================================================================
701{
702 // make nextEvent(0) a dummy call
703 if (0 == maxevt) return StatusCode::SUCCESS;
704
705 // Reset the application return code.
706 Gaudi::setAppReturnCode(m_appMgrProperty, Gaudi::ReturnCode::Success, true).ignore();
707
708 int finishedEvts =0;
709 int createdEvts =0;
710 ATH_MSG_INFO ( "Starting loop on events" );
711
712 // loop over events if the maxevt (received as input) is different from -1.
713 // if evtmax is -1 it means infinite loop (till time limit that is)
714 // int nevt(0);
715 // CGL: FIXME
716 // bool noTimeLimit(false);
717 bool loop_ended=false;
718 StatusCode sc(StatusCode::SUCCESS);
719
720 bool newEvtAllowed = ! m_firstEventAlone;
721
722 // Calculate runtime
723 auto start_time = tbb::tick_count::now();
724 auto secsFromStart = [&start_time]()->double{
725 return (tbb::tick_count::now()-start_time).seconds();
726 };
727
728 while ( !loop_ended and ( (maxevt < 0) or (finishedEvts < maxevt) ) ){
729
730 ATH_MSG_DEBUG ( " -> createdEvts: " << createdEvts );
731
732 if ( ( !m_terminateLoop ) && // The events are not finished with an unlimited number of events
733 (newEvtAllowed || createdEvts == 0) && // Launch first event alone
734 ( (createdEvts < maxevt) or (maxevt<0) ) && // The events are not finished with a limited number of events
735 (m_schedulerSvc->freeSlots()>0) ){ // There are still free slots in the scheduler
736
737 ATH_MSG_DEBUG ( "createdEvts: " << createdEvts << ", freeslots: " << m_schedulerSvc->freeSlots() );
738
739 auto ctx = createEventContext();
740
741 if ( !ctx.valid() ) {
742 sc = StatusCode::FAILURE;
743 } else {
744 sc = executeEvent( std::move(ctx) );
745 }
746
747 if (sc.isFailure()) {
748 ATH_MSG_ERROR ( "Terminating event processing loop due to errors" );
749 loop_ended = true;
750 } else {
751 ++createdEvts;
752 }
753
754 } // end if condition createdEvts < maxevt
755
756 else {
757 // all the events were created but not all finished or the slots were
758 // all busy: the scheduler should finish its job
759
760 ATH_MSG_DEBUG ( "Draining the scheduler" );
761
762 // Pull out of the scheduler the finished events
763 int ir = drainScheduler(finishedEvts);
764 if (ir < 0) {
765 // some sort of error draining scheduler;
766 loop_ended = true;
767 sc = StatusCode::FAILURE;
768 } else if (ir == 0) {
769 // no more events in scheduler. we're done
770 loop_ended = true;
771 sc = StatusCode::SUCCESS;
772 } else {
773 // keep going!
774 }
775 newEvtAllowed = true;
776
777 }
778 } // end main loop on finished events
779
780 ATH_MSG_INFO ( "---> Loop Finished (seconds): " << secsFromStart() );
781
782
783 return sc;
784
785
786}
787
788
789//=========================================================================
790// Seek to a given event.
791// The event selector must support the IEventSeek interface for this to work.
792//=========================================================================
794{
795 IEvtSelectorSeek* is = dynamic_cast<IEvtSelectorSeek*> (m_evtSelector);
796 if (is == 0) {
797 ATH_MSG_ERROR ( "Seek failed; unsupported by event selector" );
798 return StatusCode::FAILURE;
799 }
800 //cppcheck-suppress nullPointerRedundantCheck
801 if (!m_evtContext) {
802 if (m_evtSelector->createContext(m_evtContext).isFailure()) {
803 ATH_MSG_FATAL ( "Can not create the event selector Context." );
804 return StatusCode::FAILURE;
805 }
806 }
807 //m_evtContext cannot be null if createContext succeeded
808 //cppcheck-suppress nullPointerRedundantCheck
809 StatusCode sc = is->seek (*m_evtContext, evt);
810 if (sc.isSuccess()) {
811 m_incidentSvc->fireIncident(ContextIncident<std::tuple<int, int>>(
812 name(), "SkipEvents", std::tuple<int, int>(m_nevt, evt)));
813 m_nevt = evt;
814 }
815 else {
816 ATH_MSG_ERROR ( "Seek failed." );
817 }
818 return sc;
819}
820
821
822//=========================================================================
823// Return the current event count.
824//=========================================================================
826{
827 return m_nevt;
828}
829
830//=========================================================================
831// Return the collection size
832//=========================================================================
834{
835 IEvtSelectorSeek* cs = dynamic_cast<IEvtSelectorSeek*> (m_evtSelector);
836 if (cs == 0) {
837 ATH_MSG_ERROR ( "Collection size unsupported by event selector" );
838 return -1;
839 }
840 //cppcheck-suppress nullPointerRedundantCheck
841 if (!m_evtContext) {
842 if (m_evtSelector->createContext(m_evtContext).isFailure()) {
843 ATH_MSG_FATAL ( "Can not create the event selector Context." );
844 return -1;
845 }
846 }
847 //m_evtContext cannot be null if createContext succeeded
848 //cppcheck-suppress nullPointerRedundantCheck
849 return cs->size (*m_evtContext);
850}
851
852//=========================================================================
853// Handle Incidents
854//=========================================================================
855void AthenaHiveEventLoopMgr::handle(const Incident& inc)
856{
857
858 if(inc.type() == "EndAlgorithms") {
859 // Clear the store at the end of the event.
860 // Do it here so that it executes in an algorithm context and thus
861 // multiple stores can be cleared at the same time.
862 StatusCode sc = m_whiteboard->clearStore(inc.context().slot());
863 if( !sc.isSuccess() ) {
864 ATH_MSG_WARNING ( "Clear of Event data store failed" );
865 }
866 return;
867 }
868
869 if(inc.type()!="BeforeFork")
870 return;
871
872 if(!m_evtContext || !m_firstRun) {
873 ATH_MSG_WARNING ( "Skipping BeforeFork handler. Either no event selector is provided or begin run has already passed" );
874 }
875
876 // Initialize Algorithms and Output Streams
877 StatusCode sc = initializeAlgorithms();
878 if(sc.isFailure()) {
879 ATH_MSG_ERROR ( "Failed to initialize Algorithms" );
880 return;
881 }
882
883 // Construct EventInfo
884 sc = m_evtSelector->next(*m_evtContext);
885 if(!sc.isSuccess()) {
886 ATH_MSG_INFO ( "No more events in event selection " );
887 return;
888 }
889 IOpaqueAddress* addr{nullptr};
890 sc = m_evtSelector->createAddress(*m_evtContext, addr);
891 if (sc.isFailure()) {
892 ATH_MSG_ERROR ( "Could not create an IOpaqueAddress" );
893 return;
894 }
895 if (0 != addr) {
896 //create its proxy
897 sc = eventStore()->recordAddress(addr);
898 if(!sc.isSuccess()) {
899 ATH_MSG_ERROR ( "Error declaring Event object" );
900 return;
901 }
902 }
903
904 if(eventStore()->loadEventProxies().isFailure()) {
905 ATH_MSG_WARNING ( "Error loading Event proxies" );
906 return;
907 }
908
909 // Retrieve the legacy EventInfo object
910 const EventInfo* pEvent{nullptr};
911 sc = eventStore()->retrieve(pEvent);
912 if(!sc.isSuccess()) {
913 ATH_MSG_ERROR ( "Unable to retrieve Event root object" );
914 return;
915 }
916
917 m_firstRun=false;
918 m_currentRun = pEvent->event_ID()->run_number();
919
920 // Clear Store
921 sc = eventStore()->clearStore();
922 if(!sc.isSuccess()) {
923 ATH_MSG_ERROR ( "Clear of Event data store failed" );
924 }
925}
926
927//---------------------------------------------------------------------------
928
930StatusCode AthenaHiveEventLoopMgr::getEventRoot(IOpaqueAddress*& refpAddr) {
931 refpAddr = 0;
932 StatusCode sc = m_evtSelector->next(*m_evtContext);
933 if ( !sc.isSuccess() ) {
934 return sc;
935 }
936 // Create root address and assign address to data service
937 sc = m_evtSelector->createAddress(*m_evtContext,refpAddr);
938 if( !sc.isSuccess() ) {
939 sc = m_evtSelector->next(*m_evtContext);
940 if ( sc.isSuccess() ) {
941 sc = m_evtSelector->createAddress(*m_evtContext,refpAddr);
942 if ( !sc.isSuccess() ) {
943 ATH_MSG_WARNING ( "Error creating IOpaqueAddress." );
944 }
945 }
946 }
947 return sc;
948}
949
950//---------------------------------------------------------------------------
951
953
954 // return codes:
955 // -1 : error
956 // 0 : no more events in selection
957 // 1 : ok
958
959 StatusCode sc(StatusCode::SUCCESS);
960
961 //-----------------------------------------------------------------------
962 // we need an EventInfo Object to fire the incidents.
963 //-----------------------------------------------------------------------
964 std::unique_ptr<const EventInfo> pEvent{};
965 if ( m_evtContext ) {
966 // Deal with the case when an EventSelector is provided
967 //
968 // FIXME: flow control if no more events in selector, etc.
969 //
970
971 IOpaqueAddress* addr{};
972
973 sc = m_evtSelector->next(*m_evtContext);
974
975 if ( !sc.isSuccess() ) {
976 // This is the end of the loop. No more events in the selection
977 ATH_MSG_INFO ( "No more events in event selection " );
978 return 0;
979 }
980
981 if (m_evtSelector->createAddress(*m_evtContext, addr).isFailure()) {
982 ATH_MSG_ERROR ( "Could not create an IOpaqueAddress" );
983 return -1;
984 }
985
986
987 // Most iterators provide the IOA of an event header (EventInfo, DataHeader)
988 if (0 != addr) {
989 //create its proxy
990 sc = eventStore()->recordAddress(addr);
991 if( !sc.isSuccess() ) {
993 ATH_MSG_WARNING ( "Error declaring Event object" );
994 return 0;
995 }
996 } if ((sc=eventStore()->loadEventProxies()).isFailure()) {
997 ATH_MSG_ERROR ( "Error loading Event proxies" );
998 return -1;
999 }
1000
1001 bool consume_modifier_stream = false;
1002 // First try to build a legacy EventInfo object from the TAG information
1003 // Read the attribute list
1005 if ( pAttrList != nullptr && pAttrList->size() > 6 ) { // Try making EventID-only EventInfo object from in-file TAG
1006 try {
1007 unsigned int runNumber = (*pAttrList)["RunNumber"].data<unsigned int>();
1008 unsigned long long eventNumber = (*pAttrList)["EventNumber"].data<unsigned long long>();
1009 unsigned int eventTime = (*pAttrList)["EventTime"].data<unsigned int>();
1010 unsigned int eventTimeNS = (*pAttrList)["EventTimeNanoSec"].data<unsigned int>();
1011 unsigned int lumiBlock = (*pAttrList)["LumiBlockN"].data<unsigned int>();
1012 unsigned int bunchId = (*pAttrList)["BunchId"].data<unsigned int>();
1013
1014 ATH_MSG_DEBUG ( "use TAG with runNumber=" << runNumber );
1015 consume_modifier_stream = true;
1016 // an option to override primary eventNumber with the secondary one in case of DoubleEventSelector
1018 unsigned long long eventNumberSecondary{};
1019 if ( !(pAttrList->exists("hasSecondaryInput") && (*pAttrList)["hasSecondaryInput"].data<bool>()) ) {
1020 ATH_MSG_FATAL ( "Secondary EventNumber requested, but secondary input does not exist!" );
1021 return -1;
1022 }
1023 if ( pAttrList->exists("EventNumber_secondary") ) {
1024 eventNumberSecondary = (*pAttrList)["EventNumber_secondary"].data<unsigned long long>();
1025 }
1026 else {
1027 // try legacy EventInfo if secondary input did not have attribute list
1028 // primary input should not have this EventInfo type
1029 const EventInfo* pEventSecondary = eventStore()->tryConstRetrieve<EventInfo>();
1030 if (pEventSecondary) {
1031 eventNumberSecondary = pEventSecondary->event_ID()->event_number();
1032 }
1033 else {
1034 ATH_MSG_FATAL ( "Secondary EventNumber requested, but it does not exist!" );
1035 return -1;
1036 }
1037 }
1038 if (eventNumberSecondary != 0) {
1039 m_doEvtHeartbeat = (m_eventPrintoutInterval.value() > 0 &&
1040 0 == (m_nev % m_eventPrintoutInterval.value()));
1041 if (m_doEvtHeartbeat) {
1042 ATH_MSG_INFO ( " ===>>> using secondary event #" << eventNumberSecondary << " instead of #" << eventNumber << " <<<===" );
1043 }
1044 eventNumber = eventNumberSecondary;
1045 }
1046 }
1047
1048 pEvent = std::make_unique<EventInfo>(
1049 std::make_unique<EventID>(runNumber, eventNumber, eventTime,
1050 eventTimeNS, lumiBlock, bunchId),
1051 nullptr);
1052 } catch (...) {
1053 }
1054 } else if (m_requireInputAttributeList) {
1055 ATH_MSG_FATAL ( "Valid input attribute list required but not present!" );
1056 return -1;
1057 }
1058 // In the case that there is no TAG information
1059 const EventInfo* pEventObserver{pEvent.get()};
1060 if (!pEventObserver) {
1061 // Secondly try to retrieve a legacy EventInfo object from the input file
1062 // Again, m_nevt is incremented after executeEvent in the Hive manager so we don't need a -1
1064 pEventObserver = eventStore()->tryConstRetrieve<EventInfo>();
1065 if (pEventObserver) {
1066 consume_modifier_stream = false; // stream will already have been consumed during EventInfo TP conversion
1067 ATH_MSG_DEBUG ( "use EventInfo" );
1068 } else {
1069 // Finally try to retrieve an xAOD::EventInfo object from the
1070 // input file and build a legacy EventInfo object from that.
1071 const xAOD::EventInfo* pXEvent{nullptr};
1072 sc = eventStore()->retrieve(pXEvent);
1073 if( !sc.isSuccess() ) {
1074 ATH_MSG_ERROR ( "Unable to retrieve Event root object" );
1075 return -1;
1076 }
1077 consume_modifier_stream = true;
1078 ATH_MSG_DEBUG ( "use xAOD::EventInfo with runNumber=" << pXEvent->runNumber() );
1079 // Build the old-style Event Info object for those clients that still need it
1080 pEvent = std::make_unique<EventInfo>(
1081 std::make_unique<EventID>(eventIDFromxAOD(pXEvent)),
1082 std::make_unique<EventType>(eventTypeFromxAOD(pXEvent)));
1083 pEventObserver = pEvent.get();
1084 sc = eventStore()->record(std::move(pEvent), "");
1085 if( !sc.isSuccess() ) {
1086 ATH_MSG_ERROR ( "Error declaring event data object" );
1087 return -1;
1088 }
1089 }
1090 }
1091
1092 modifyEventContext(ctx, *(pEventObserver->event_ID()),
1093 consume_modifier_stream);
1094
1095 }
1096 else {
1097 // No EventSelector is provided, so with no iterator it's up to us
1098 // to create an EventInfo
1099 // first event # == 1
1100 unsigned int runNmb{1}, evtNmb{m_nevt + 1};
1101
1102 // increment the run/lumiBlock number if desired
1103 if (m_flmbi != 0) {
1104 runNmb = m_nevt / m_flmbi + 1;
1105 evtNmb = m_nevt % m_flmbi + 1;
1106 }
1107 auto eid = std::make_unique<EventID> (runNmb,evtNmb, m_timeStamp);
1108 // Change lumiBlock# to match runNumber
1109 eid->set_lumi_block( runNmb );
1110
1112
1113 pEvent = std::make_unique<EventInfo>(std::move(eid),
1114 std::make_unique<EventType>());
1115
1116 bool consume_modifier_stream = true;
1117 // EventInfo TP Conversion not called in this case, so we would
1118 // want to consume the next IoV from the list in the
1119 // EvtIdModifierSvc.
1120 modifyEventContext(ctx,*(pEvent->event_ID()), consume_modifier_stream);
1121
1122 ATH_MSG_DEBUG ( "selecting store: " << ctx.slot() );
1123
1124 m_whiteboard->selectStore( ctx.slot() ).ignore();
1125
1126 ATH_MSG_DEBUG ( "recording EventInfo " << *pEvent->event_ID() << " in "
1127 << eventStore()->name() );
1128
1129 sc = eventStore()->record(std::move(pEvent), "McEventInfo");
1130 if( !sc.isSuccess() ) {
1131 ATH_MSG_ERROR ( "Error declaring event data object" );
1132 return -1;
1133 }
1134 }
1135
1136 return 1;
1137}
1138
1139//---------------------------------------------------------------------------
1140
1141void AthenaHiveEventLoopMgr::modifyEventContext(EventContext& ctx, const EventID& eID, bool consume_modifier_stream) {
1142
1143 if(m_evtIdModSvc.isSet()) {
1144 EventID new_eID(eID);
1145 // In Hive EventLoopMgr ctx.evt() gets set to m_nevt and *then* m_nevt is
1146 // incremented later so it's zero-indexed and we don't need to subtract one
1147 m_evtIdModSvc->modify_evtid(new_eID, ctx.evt(), consume_modifier_stream);
1148 if (msgLevel(MSG::DEBUG)) {
1149 unsigned int oldrunnr=eID.run_number();
1150 unsigned int oldLB=eID.lumi_block();
1151 unsigned int oldTS=eID.time_stamp();
1152 unsigned int oldTSno=eID.time_stamp_ns_offset();
1153 ATH_MSG_DEBUG ( "modifyEventContext: use evtIdModSvc runnr=" << oldrunnr << " -> " << new_eID.run_number() );
1154 ATH_MSG_DEBUG ( "modifyEventContext: use evtIdModSvc LB=" << oldLB << " -> " << new_eID.lumi_block() );
1155 ATH_MSG_DEBUG ( "modifyEventContext: use evtIdModSvc TimeStamp=" << oldTS << " -> " << new_eID.time_stamp() );
1156 ATH_MSG_DEBUG ( "modifyEventContext: use evtIdModSvc TimeStamp ns Offset=" << oldTSno << " -> " << new_eID.time_stamp_ns_offset() );
1157 }
1158 ctx.setEventID( new_eID );
1159 Atlas::getExtendedEventContext(ctx).setConditionsRun( ctx.eventID().run_number() );
1160 return;
1161 }
1162
1163 ctx.setEventID( eID );
1164}
1165
1166//---------------------------------------------------------------------------
1168
1169 EventContext ctx{ m_nevt, m_whiteboard->allocateStore( m_nevt ) };
1170
1171 StatusCode sc = m_whiteboard->selectStore( ctx.slot() );
1172 if (sc.isFailure()) {
1173 ATH_MSG_FATAL ( "Slot " << ctx.slot()
1174 << " could not be selected for the WhiteBoard" );
1175 return EventContext{}; // invalid EventContext
1176 } else {
1178 Atlas::ExtendedEventContext( eventStore()->hiveProxyDict() ) );
1179
1180 ATH_MSG_DEBUG ( "created EventContext, num: " << ctx.evt() << " in slot: "
1181 << ctx.slot() );
1182 }
1183
1184 return ctx;
1185}
1186
1187//---------------------------------------------------------------------------
1188
1189int
1191
1192 StatusCode sc(StatusCode::SUCCESS);
1193
1194 // maybe we can do better
1195 std::vector<std::unique_ptr<EventContext>> finishedEvtContexts;
1196
1197 EventContext* finishedEvtContext(nullptr);
1198
1199 // Here we wait not to loose cpu resources
1200 ATH_MSG_DEBUG ( "drainScheduler: [" << finishedEvts << "] Waiting for a context" );
1201 sc = m_schedulerSvc->popFinishedEvent(finishedEvtContext);
1202
1203 // We got past it: cache the pointer
1204 if (sc.isSuccess()){
1205 ATH_MSG_DEBUG ( "drainScheduler: scheduler not empty: Context "
1206 << finishedEvtContext );
1207 finishedEvtContexts.emplace_back(finishedEvtContext);
1208 } else{
1209 // no more events left in scheduler to be drained
1210 ATH_MSG_DEBUG ( "drainScheduler: scheduler empty" );
1211 return 0;
1212 }
1213
1214 // Let's see if we can pop other event contexts
1215 while (m_schedulerSvc->tryPopFinishedEvent(finishedEvtContext).isSuccess()){
1216 finishedEvtContexts.emplace_back(finishedEvtContext);
1217 }
1218
1219 // Now we flush them
1220 bool fail(false);
1221 for (auto& thisFinishedEvtContext : finishedEvtContexts){
1222 if (!thisFinishedEvtContext) {
1223 ATH_MSG_FATAL ( "Detected nullptr ctxt while clearing WB!");
1224 fail = true;
1225 continue;
1226 }
1227
1228 if (m_aess->eventStatus(*thisFinishedEvtContext) != EventStatus::Success) {
1229 ATH_MSG_FATAL ( "Failed event detected on " << thisFinishedEvtContext
1230 << " w/ fail mode: "
1231 << m_aess->eventStatus(*thisFinishedEvtContext) );
1232 fail = true;
1233 continue;
1234 }
1235
1236 EventID::number_type n_run(0);
1237 EventID::event_number_t n_evt(0);
1238
1239 if (m_whiteboard->selectStore(thisFinishedEvtContext->slot()).isSuccess()) {
1240 n_run = thisFinishedEvtContext->eventID().run_number();
1241 n_evt = thisFinishedEvtContext->eventID().event_number();
1242 } else {
1243 ATH_MSG_ERROR ( "DrainSched: unable to select store "
1244 << thisFinishedEvtContext->slot() );
1245 fail = true;
1246 continue;
1247 }
1248
1249 // m_incidentSvc->fireIncident(Incident(name(), IncidentType::EndEvent,
1250 // *thisFinishedEvtContext ));
1251
1252 // Some code still needs global context in addition to that passed in the incident
1253 Gaudi::Hive::setCurrentContext( *thisFinishedEvtContext );
1254 m_incidentSvc->fireIncident(Incident(name(), IncidentType::EndProcessing, *thisFinishedEvtContext ));
1255
1256 ATH_MSG_DEBUG ( "Clearing slot " << thisFinishedEvtContext->slot()
1257 << " (event " << thisFinishedEvtContext->evt()
1258 << ") of the whiteboard" );
1259
1260 StatusCode sc = clearWBSlot(thisFinishedEvtContext->slot());
1261 if (!sc.isSuccess()) {
1262 ATH_MSG_ERROR ( "Whiteboard slot " << thisFinishedEvtContext->slot()
1263 << " could not be properly cleared" );
1264 fail = true;
1265 continue;
1266 }
1267
1268 finishedEvts++;
1269
1270 writeHistograms().ignore();
1271 ++m_proc;
1272
1273 if (m_doEvtHeartbeat) {
1274 if(!m_useTools)
1275 ATH_MSG_INFO ( " ===>>> done processing event #" << n_evt << ", run #" << n_run
1276 << " on slot " << thisFinishedEvtContext->slot() << ", "
1277 << m_proc << " events processed so far <<<===" );
1278 else
1279 ATH_MSG_INFO ( " ===>>> done processing event #" << n_evt << ", run #" << n_run
1280 << " on slot " << thisFinishedEvtContext->slot() << ", "
1281 << m_nev << " events read and " << m_proc
1282 << " events processed so far <<<===" );
1283 std::ofstream outfile( "eventLoopHeartBeat.txt");
1284 if ( !outfile ) {
1285 ATH_MSG_ERROR ( " unable to open: eventLoopHeartBeat.txt" );
1286 fail = true;
1287 continue;
1288 } else {
1289 outfile << " done processing event #" << n_evt << ", run #" << n_run
1290 << " " << m_nev << " events read so far <<<===" << std::endl;
1291 outfile.close();
1292 }
1293 }
1294
1295 ATH_MSG_DEBUG ( "drainScheduler thisFinishedEvtContext: " << thisFinishedEvtContext );
1296 }
1297
1298 return ( fail ? -1 : 1 );
1299
1300}
1301
1302//---------------------------------------------------------------------------
1303
1305 return m_whiteboard->freeStore(evtSlot);
1306}
1307//---------------------------------------------------------------------------
1308
#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.
StoreGateSvc * eventStore() const
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.
The Athena Transient Store API.
StatusCode recordAddress(const std::string &skey, CxxUtils::RefCountedPtr< IOpaqueAddress > pAddress, bool clearAddressFlag=true)
Create a proxy object using an IOpaqueAddress and a transient key.
StatusCode record(T *p2BRegistered, const TKEY &key)
Record an object with a key.
const T * tryConstRetrieve() const
StatusCode retrieve(const T *&ptr) const
Retrieve the default object into a const T*.
virtual StatusCode clearStore(bool forceRemove=false) override final
clear DataStore contents: called by the event loop mgrs
uint32_t runNumber() const
The current event's run number.
int ir
counter of the current depth
Definition fastadd.cxx:49
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:114
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.