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