Algorithm.cpp
Go to the documentation of this file.
1 #include <algorithm>
2 #include "GaudiKernel/Kernel.h"
3 #include "GaudiKernel/ISvcLocator.h"
4 #include "GaudiKernel/IMessageSvc.h"
5 #include "GaudiKernel/IJobOptionsSvc.h"
6 #include "GaudiKernel/IAlgManager.h"
7 #include "GaudiKernel/IAuditorSvc.h"
8 #include "GaudiKernel/IDataProviderSvc.h"
9 #include "GaudiKernel/IConversionSvc.h"
10 #include "GaudiKernel/IHistogramSvc.h"
11 #include "GaudiKernel/INTupleSvc.h"
12 #include "GaudiKernel/IRndmGenSvc.h"
13 #include "GaudiKernel/IToolSvc.h"
14 #include "GaudiKernel/IExceptionSvc.h"
15 #include "GaudiKernel/IAlgContextSvc.h"
16 #include "GaudiKernel/IProperty.h"
17 
18 #include "GaudiKernel/Algorithm.h"
19 #include "GaudiKernel/PropertyMgr.h"
20 #include "GaudiKernel/MsgStream.h"
21 #include "GaudiKernel/Chrono.h"
22 #include "GaudiKernel/Stat.h"
23 #include "GaudiKernel/GaudiException.h"
24 #include "GaudiKernel/ServiceLocatorHelper.h"
25 #include "GaudiKernel/ThreadGaudi.h"
26 #include "GaudiKernel/Guards.h"
27 
28 namespace {
29  template <StatusCode (Algorithm::*f)(), typename C > bool for_algorithms(C& c) {
30  return std::accumulate( std::begin(c), std::end(c), true,
31  [](bool b, Algorithm* a) { return (a->*f)().isSuccess() && b; } );
32  }
33 }
34 
35 // Constructor
36 Algorithm::Algorithm( const std::string& name, ISvcLocator *pSvcLocator,
37  const std::string& version)
38  : m_name(name),
39  m_version(version),
40  m_pSvcLocator(pSvcLocator),
41  m_propertyMgr( new PropertyMgr() )
42 {
43 
44  // Declare common Algorithm properties with their defaults
45  declareProperty( "OutputLevel", m_outputLevel = MSG::NIL);
46  declareProperty( "Enable", m_isEnabled = true);
47  declareProperty( "ErrorMax", m_errorMax = 1);
48  declareProperty( "ErrorCounter", m_errorCount = 0);
49  // Auditor monitoring properties
50 
51  // Get the default setting for service auditing from the AppMgr
52  declareProperty( "AuditAlgorithms", m_auditInit );
53 
54  bool audit(false);
55  auto appMgr = serviceLocator()->service<IProperty>("ApplicationMgr");
56  if (appMgr) {
57  const Property& prop = appMgr->getProperty("AuditAlgorithms");
58  Property &pr = const_cast<Property&>(prop);
59  if (m_name != "IncidentSvc") {
60  setProperty( pr ).ignore();
61  }
62  audit = m_auditInit.value();
63  }
64 
65  declareProperty( "AuditInitialize" , m_auditorInitialize = audit ) ;
66  declareProperty( "AuditReinitialize", m_auditorReinitialize = audit ) ;
67  declareProperty( "AuditRestart" , m_auditorRestart = audit ) ;
68  declareProperty( "AuditExecute" , m_auditorExecute = audit ) ;
69  declareProperty( "AuditFinalize" , m_auditorFinalize = audit ) ;
70  declareProperty( "AuditBeginRun" , m_auditorBeginRun = audit ) ;
71  declareProperty( "AuditEndRun" , m_auditorEndRun = audit ) ;
72  declareProperty( "AuditStart" , m_auditorStart = audit ) ;
73  declareProperty( "AuditStop" , m_auditorStop = audit ) ;
74 
75  declareProperty( "MonitorService" , m_monitorSvcName = "MonitorSvc" );
76 
77  declareProperty
78  ( "RegisterForContextService" ,
79  m_registerContext ,
80  "The flag to enforce the registration for Algorithm Context Service") ;
81 
82  // update handlers.
83  m_outputLevel.declareUpdateHandler(&Algorithm::initOutputLevel, this);
84 }
85 
86 // IAlgorithm implementation
88 
89  // Bypass the initialization if the algorithm
90  // has already been initialized.
91  if ( Gaudi::StateMachine::INITIALIZED <= FSMState() ) return StatusCode::SUCCESS;
92 
93  // Set the Algorithm's properties
94  StatusCode sc = setProperties();
95  if( sc.isFailure() ) return StatusCode::FAILURE;
96 
97  // Bypass the initialization if the algorithm is disabled.
98  // Need to do this after setProperties.
99  if ( !isEnabled( ) ) return StatusCode::SUCCESS;
100 
102 
103  // Check current outputLevel to eventually inform the MessagsSvc
104  //if( m_outputLevel != MSG::NIL ) {
105  setOutputLevel( m_outputLevel );
106  //}
107 
108  // TODO: (MCl) where shoud we do this? initialize or start?
109  // Reset Error count
110  //m_errorCount = 0;
111 
112  // lock the context service
114  ( this , registerContext() ? contextSvc().get() : 0 ) ;
115 
116  // Invoke initialize() method of the derived class inside a try/catch clause
117  try {
118 
119  { // limit the scope of the guard
121  ( this,
122  // check if we want to audit the initialize
123  (m_auditorInitialize) ? auditorSvc().get() : 0,
125  // Invoke the initialize() method of the derived class
126  sc = initialize();
127  }
128  if( sc.isSuccess() ) {
129 
130  // Now initialize care of any sub-algorithms
131  bool fail(false);
132  for (auto& it : m_subAlgms ) {
133  if (it->sysInitialize().isFailure()) fail = true;
134  }
135  if( fail ) {
136  sc = StatusCode::FAILURE;
137  MsgStream log ( msgSvc() , name() );
138  log << MSG::ERROR << " Error initializing one or several sub-algorithms"
139  << endmsg;
140  } else {
141  // Update the state.
142  m_state = m_targetState;
143  }
144  }
145  }
146  catch ( const GaudiException& Exception )
147  {
148  MsgStream log ( msgSvc() , name() ) ;
149  log << MSG::FATAL << " Exception with tag=" << Exception.tag()
150  << " is caught " << endmsg;
151  log << MSG::ERROR << Exception << endmsg;
152  Stat stat( chronoSvc() , Exception.tag() );
153  sc = StatusCode::FAILURE;
154  }
155  catch( const std::exception& Exception )
156  {
157  MsgStream log ( msgSvc() , name() ) ;
158  log << MSG::FATAL << " Standard std::exception is caught " << endmsg;
159  log << MSG::ERROR << Exception.what() << endmsg;
160  Stat stat( chronoSvc() , "*std::exception*" );
161  sc = StatusCode::FAILURE;
162  }
163  catch(...)
164  {
165  MsgStream log ( msgSvc() , name() ) ;
166  log << MSG::FATAL << "UNKNOWN Exception is caught " << endmsg;
167  Stat stat( chronoSvc() , "*UNKNOWN Exception*" ) ;
168  sc = StatusCode::FAILURE;
169  }
170 
171  return sc;
172 }
173 
174 // IAlgorithm implementation
176 
177  // Bypass the startup if already running or disabled.
178  if ( Gaudi::StateMachine::RUNNING == FSMState() ||
179  !isEnabled() ) return StatusCode::SUCCESS;
180 
182 
183  // TODO: (MCl) where shoud we do this? initialize or start?
184  // Reset Error count
185  m_errorCount = 0;
186 
187  // lock the context service
189  ( this , registerContext() ? contextSvc().get() : 0 ) ;
190 
192  // Invoke start() method of the derived class inside a try/catch clause
193  try
194  {
195  { // limit the scope of the guard
197  (this,
198  // check if we want to audit the initialize
199  (m_auditorStart) ? auditorSvc().get() : 0,
201  // Invoke the start() method of the derived class
202  sc = start();
203  }
204  if( sc.isSuccess() ) {
205 
206  // Now start any sub-algorithms
207  if( !for_algorithms<&Algorithm::sysStart>( m_subAlgms ) ) {
208  sc = StatusCode::FAILURE;
209  MsgStream log ( msgSvc() , name() );
210  log << MSG::ERROR << " Error starting one or several sub-algorithms"
211  << endmsg;
212  } else {
213  // Update the state.
214  m_state = m_targetState;
215  }
216  }
217  }
218  catch ( const GaudiException& Exception )
219  {
220  MsgStream log ( msgSvc() , name() );
221  log << MSG::FATAL << "in sysStart(): exception with tag=" << Exception.tag()
222  << " is caught" << endmsg;
223  log << MSG::ERROR << Exception << endmsg;
224  Stat stat( chronoSvc() , Exception.tag() );
225  sc = StatusCode::FAILURE;
226  }
227  catch( const std::exception& Exception )
228  {
229  MsgStream log ( msgSvc() , name() );
230  log << MSG::FATAL << "in sysStart(): standard std::exception is caught" << endmsg;
231  log << MSG::ERROR << Exception.what() << endmsg;
232  Stat stat( chronoSvc() , "*std::exception*" );
233  sc = StatusCode::FAILURE;
234  }
235  catch(...)
236  {
237  MsgStream log ( msgSvc() , name() );
238  log << MSG::FATAL << "in sysStart(): UNKNOWN Exception is caught" << endmsg;
239  Stat stat( chronoSvc() , "*UNKNOWN Exception*" ) ;
240  sc = StatusCode::FAILURE;
241  }
242 
243  return sc;
244 }
245 
246 // IAlgorithm implementation
248 
249  // Bypass the initialization if the algorithm is disabled.
250  if ( !isEnabled( ) ) return StatusCode::SUCCESS;
251 
252  // Check that the current status is the correct one.
253  if ( Gaudi::StateMachine::INITIALIZED != FSMState() ) {
254  MsgStream log ( msgSvc() , name() );
255  log << MSG::ERROR
256  << "sysReinitialize(): cannot reinitialize algorithm not initialized"
257  << endmsg;
258  return StatusCode::FAILURE;
259  }
260 
261  // Check current outputLevel to evetually inform the MessagsSvc
262  //if( m_outputLevel != MSG::NIL ) {
263  setOutputLevel( m_outputLevel );
264  //}
265 
266  // Reset Error count
267  // m_errorCount = 0; // done during start
268 
269  // lock the context service
271  ( this , registerContext() ? contextSvc().get() : 0 ) ;
272 
274  // Invoke reinitialize() method of the derived class inside a try/catch clause
275  try {
276  { // limit the scope of the guard
277  Gaudi::Guards::AuditorGuard guard(this,
278  // check if we want to audit the initialize
279  (m_auditorReinitialize) ? auditorSvc().get() : 0,
281  // Invoke the reinitialize() method of the derived class
282  sc = reinitialize();
283  }
284  if( sc.isSuccess() ) {
285 
286  // Now initialize care of any sub-algorithms
287  if ( !for_algorithms<&Algorithm::sysReinitialize>( m_subAlgms ) ) {
288  sc = StatusCode::FAILURE;
289  MsgStream log ( msgSvc() , name() );
290  log << MSG::ERROR
291  << "sysReinitialize(): Error reinitializing one or several "
292  << "sub-algorithms" << endmsg;
293  }
294  }
295  }
296  catch ( const GaudiException& Exception )
297  {
298  MsgStream log ( msgSvc() , name() );
299  log << MSG::FATAL << "sysReinitialize(): Exception with tag=" << Exception.tag()
300  << " is caught" << endmsg;
301  log << MSG::ERROR << Exception << endmsg;
302  Stat stat( chronoSvc() , Exception.tag() );
303  sc = StatusCode::FAILURE;
304  }
305  catch( const std::exception& Exception )
306  {
307  MsgStream log ( msgSvc() , name() );
308  log << MSG::FATAL << "sysReinitialize(): Standard std::exception is caught" << endmsg;
309  log << MSG::ERROR << Exception.what() << endmsg;
310  Stat stat( chronoSvc() , "*std::exception*" );
311  sc = StatusCode::FAILURE;
312  }
313  catch(...)
314  {
315  MsgStream log ( msgSvc() , name() );
316  log << MSG::FATAL << "sysReinitialize(): UNKNOWN Exception is caught" << endmsg;
317  Stat stat( chronoSvc() , "*UNKNOWN Exception*" ) ;
318  sc = StatusCode::FAILURE;
319  }
320 
321  return sc;
322 }
323 
324 // IAlgorithm implementation
326 
327  // Bypass the initialization if the algorithm is disabled.
328  if ( !isEnabled( ) ) return StatusCode::SUCCESS;
329 
330  // Check that the current status is the correct one.
331  if ( Gaudi::StateMachine::RUNNING != FSMState() ) {
332  MsgStream log ( msgSvc() , name() );
333  log << MSG::ERROR
334  << "sysRestart(): cannot restart algorithm not started"
335  << endmsg;
336  return StatusCode::FAILURE;
337  }
338 
339  // Check current outputLevel to evetually inform the MessagsSvc
340  //if( m_outputLevel != MSG::NIL ) {
341  setOutputLevel( m_outputLevel );
342  //}
343 
344  // Reset Error count
345  m_errorCount = 0;
346 
347  // lock the context service
349  ( this , registerContext() ? contextSvc().get() : 0 ) ;
350 
352  // Invoke reinitialize() method of the derived class inside a try/catch clause
353  try {
354  { // limit the scope of the guard
355  Gaudi::Guards::AuditorGuard guard(this,
356  // check if we want to audit the initialize
357  (m_auditorRestart) ? auditorSvc().get() : 0,
359  // Invoke the reinitialize() method of the derived class
360  sc = restart();
361  }
362  if( sc.isSuccess() ) {
363 
364  // Now initialize care of any sub-algorithms
365  if( !for_algorithms<&Algorithm::sysRestart>( m_subAlgms ) ) {
366  sc = StatusCode::FAILURE;
367  MsgStream log ( msgSvc() , name() );
368  log << MSG::ERROR
369  << "sysRestart(): Error restarting one or several sub-algorithms"
370  << endmsg;
371  }
372  }
373  }
374  catch ( const GaudiException& Exception )
375  {
376  MsgStream log ( msgSvc() , name() );
377  log << MSG::FATAL << "sysRestart(): Exception with tag=" << Exception.tag()
378  << " is caught" << endmsg;
379  log << MSG::ERROR << Exception << endmsg;
380  Stat stat( chronoSvc() , Exception.tag() );
381  sc = StatusCode::FAILURE;
382  }
383  catch( const std::exception& Exception )
384  {
385  MsgStream log ( msgSvc() , name() );
386  log << MSG::FATAL << "sysRestart(): Standard std::exception is caught" << endmsg;
387  log << MSG::ERROR << Exception.what() << endmsg;
388  Stat stat( chronoSvc() , "*std::exception*" );
389  sc = StatusCode::FAILURE;
390  }
391  catch(...)
392  {
393  MsgStream log ( msgSvc() , name() );
394  log << MSG::FATAL << "sysRestart(): UNKNOWN Exception is caught" << endmsg;
395  Stat stat( chronoSvc() , "*UNKNOWN Exception*" ) ;
396  sc = StatusCode::FAILURE;
397  }
398 
399  return sc;
400 }
401 
402 // IAlgorithm implementation
404 
405  // Bypass the beginRun if the algorithm is disabled.
406  if ( !isEnabled( ) ) return StatusCode::SUCCESS;
407 
408  // Check current outputLevel to evetually inform the MessagsSvc
409  //if( m_outputLevel != MSG::NIL ) {
410  setOutputLevel( m_outputLevel );
411  //}
412 
413  // Reset Error count
414  m_errorCount = 0;
415 
416  // lock the context service
418  ( this , registerContext() ? contextSvc().get() : 0 ) ;
419 
421  // Invoke beginRun() method of the derived class inside a try/catch clause
422  try {
423  { // limit the scope of the guard
424  Gaudi::Guards::AuditorGuard guard(this,
425  // check if we want to audit the initialize
426  (m_auditorBeginRun) ? auditorSvc().get() : 0,
428  // Invoke the beginRun() method of the derived class
429  sc = beginRun();
430  }
431  if( sc.isSuccess() ) {
432 
433  // Now call beginRun for any sub-algorithms
434  if( !for_algorithms<&Algorithm::sysBeginRun>( m_subAlgms ) ) {
435  sc = StatusCode::FAILURE;
436  MsgStream log ( msgSvc() , name() );
437  log << MSG::ERROR << " Error executing BeginRun for one or several sub-algorithms"
438  << endmsg;
439  }
440  }
441  }
442  catch ( const GaudiException& Exception )
443  {
444  MsgStream log ( msgSvc() , name() );
445  log << MSG::FATAL << " Exception with tag=" << Exception.tag()
446  << " is caught " << endmsg;
447  log << MSG::ERROR << Exception << endmsg;
448  Stat stat( chronoSvc() , Exception.tag() );
449  sc = StatusCode::FAILURE;
450  }
451  catch( const std::exception& Exception )
452  {
453  MsgStream log ( msgSvc() , name() );
454  log << MSG::FATAL << " Standard std::exception is caught " << endmsg;
455  log << MSG::ERROR << Exception.what() << endmsg;
456  Stat stat( chronoSvc() , "*std::exception*" );
457  sc = StatusCode::FAILURE;
458  }
459  catch(...)
460  {
461  MsgStream log ( msgSvc() , name() );
462  log << MSG::FATAL << "UNKNOWN Exception is caught " << endmsg;
463  Stat stat( chronoSvc() , "*UNKNOWN Exception*" ) ;
464  sc = StatusCode::FAILURE;
465  }
466  return sc;
467 }
468 
470  return StatusCode::SUCCESS;
471 }
472 
473 // IAlgorithm implementation
475 
476  // Bypass the endRun if the algorithm is disabled.
477  if ( !isEnabled( ) ) return StatusCode::SUCCESS;
478 
479  // Check current outputLevel to eventually inform the MessagsSvc
480  //if( m_outputLevel != MSG::NIL ) {
481  setOutputLevel( m_outputLevel );
482  //}
483 
484  // Reset Error count
485  m_errorCount = 0;
486 
487  // lock the context service
489  ( this , registerContext() ? contextSvc().get() : nullptr ) ;
490 
491  // Invoke endRun() method of the derived class inside a try/catch clause
493  try {
494  { // limit the scope of the guard
495  Gaudi::Guards::AuditorGuard guard(this,
496  // check if we want to audit the initialize
497  (m_auditorEndRun) ? auditorSvc().get() : 0,
499  // Invoke the endRun() method of the derived class
500  sc = endRun();
501  }
502  if( sc.isSuccess() ) {
503 
504  // Now call endRun for any sub-algorithms
505  if( !for_algorithms<&Algorithm::sysEndRun>( m_subAlgms ) ) {
506  sc = StatusCode::FAILURE;
507  MsgStream log ( msgSvc() , name() );
508  log << MSG::ERROR << " Error calling endRun for one or several sub-algorithms"
509  << endmsg;
510  }
511  }
512  }
513  catch ( const GaudiException& Exception )
514  {
515  MsgStream log ( msgSvc() , name() );
516  log << MSG::FATAL << " Exception with tag=" << Exception.tag()
517  << " is caught " << endmsg;
518  log << MSG::ERROR << Exception << endmsg;
519  Stat stat( chronoSvc() , Exception.tag() );
520  sc = StatusCode::FAILURE;
521  }
522  catch( const std::exception& Exception )
523  {
524  MsgStream log ( msgSvc() , name() );
525  log << MSG::FATAL << " Standard std::exception is caught " << endmsg;
526  log << MSG::ERROR << Exception.what() << endmsg;
527  Stat stat( chronoSvc() , "*std::exception*" );
528  sc = StatusCode::FAILURE;
529  }
530  catch(...)
531  {
532  MsgStream log ( msgSvc() , name() );
533  log << MSG::FATAL << "UNKNOWN Exception is caught " << endmsg;
534  Stat stat( chronoSvc() , "*UNKNOWN Exception*" ) ;
535  sc = StatusCode::FAILURE;
536  }
537  return sc;
538 }
539 
541  return StatusCode::SUCCESS;
542 }
543 
544 
546  if (!isEnabled()) {
547  if (UNLIKELY(m_outputLevel <= MSG::VERBOSE)) {
548  MsgStream log ( msgSvc() , name() );
549  log << MSG::VERBOSE << ".sysExecute(): is not enabled. Skip execution" << endmsg;
550  }
551  return StatusCode::SUCCESS;
552  }
553 
554  StatusCode status;
555 
556  // Should performance profile be performed ?
557  // invoke execute() method of Algorithm class
558  // and catch all uncaught exceptions
559 
560  // lock the context service
562  ( this , registerContext() ? contextSvc().get() : 0 ) ;
563 
564  Gaudi::Guards::AuditorGuard guard(this,
565  // check if we want to audit the initialize
566  (m_auditorExecute) ? auditorSvc().get() : 0,
568  status);
569  try {
570  status = execute();
571  setExecuted(true); // set the executed flag
572 
573  if (status.isFailure()) {
574  status = exceptionSvc()->handleErr(*this,status);
575  }
576 
577  }
578  catch( const GaudiException& Exception )
579  {
580  setExecuted(true); // set the executed flag
581 
582  MsgStream log ( msgSvc() , name() );
583  if (Exception.code() == StatusCode::FAILURE) {
584  log << MSG::FATAL;
585  } else {
586  log << MSG::ERROR << " Recoverable";
587  }
588 
589  log << " Exception with tag=" << Exception.tag()
590  << " is caught " << endmsg;
591 
592  log << MSG::ERROR << Exception << endmsg;
593 
594  Stat stat( chronoSvc() , Exception.tag() ) ;
595  status = exceptionSvc()->handle(*this,Exception);
596  }
597  catch( const std::exception& Exception )
598  {
599  setExecuted(true); // set the executed flag
600 
601  MsgStream log ( msgSvc() , name() );
602  log << MSG::FATAL << " Standard std::exception is caught " << endmsg;
603  log << MSG::ERROR << Exception.what() << endmsg;
604  Stat stat( chronoSvc() , "*std::exception*" ) ;
605  status = exceptionSvc()->handle(*this,Exception);
606  }
607  catch(...)
608  {
609  setExecuted(true); // set the executed flag
610 
611  MsgStream log ( msgSvc() , name() );
612  log << MSG::FATAL << "UNKNOWN Exception is caught " << endmsg;
613  Stat stat( chronoSvc() , "*UNKNOWN Exception*" ) ;
614 
615  status = exceptionSvc()->handle(*this);
616  }
617 
618  if( status.isFailure() ) {
619  MsgStream log ( msgSvc() , name() );
620  // Increment the error count
621  m_errorCount++;
622  // Check if maximum is exeeded
623  if( m_errorCount < m_errorMax ) {
624  log << MSG::WARNING << "Continuing from error (cnt=" << m_errorCount
625  << ", max=" << m_errorMax << ")" << endmsg;
626  // convert to success
627  status = StatusCode::SUCCESS;
628  }
629  }
630  return status;
631 }
632 
633 // IAlgorithm implementation
635 
636  // Bypass the startup if already running or disabled.
637  if ( Gaudi::StateMachine::INITIALIZED == FSMState() ||
638  !isEnabled() ) return StatusCode::SUCCESS;
639 
641 
642  // lock the context service
644  ( this , registerContext() ? contextSvc().get() : 0 ) ;
645 
647  // Invoke stop() method of the derived class inside a try/catch clause
648  try {
649  // Stop first any sub-algorithms (in reverse order -- not?)
650  for_algorithms<&Algorithm::sysStop>( m_subAlgms );
651  { // limit the scope of the guard
652  Gaudi::Guards::AuditorGuard guard(this,
653  // check if we want to audit the initialize
654  (m_auditorStop) ? auditorSvc().get() : 0,
656 
657  // Invoke the stop() method of the derived class
658  sc = stop();
659  }
660  if( sc.isSuccess() ) {
661  // Update the state.
662  m_state = m_targetState;
663  }
664  }
665  catch ( const GaudiException& Exception ) {
666  MsgStream log ( msgSvc() , name() );
667  log << MSG::FATAL << "in sysStop(): exception with tag=" << Exception.tag()
668  << " is caught" << endmsg;
669  log << MSG::ERROR << Exception << endmsg;
670  Stat stat( chronoSvc() , Exception.tag() );
671  sc = StatusCode::FAILURE;
672  }
673  catch( const std::exception& Exception ) {
674  MsgStream log ( msgSvc() , name() );
675  log << MSG::FATAL << "in sysStop(): standard std::exception is caught" << endmsg;
676  log << MSG::ERROR << Exception.what() << endmsg;
677  Stat stat( chronoSvc() , "*std::exception*" );
678  sc = StatusCode::FAILURE;
679  }
680  catch(...) {
681  MsgStream log ( msgSvc() , name() );
682  log << MSG::FATAL << "in sysStop(): UNKNOWN Exception is caught" << endmsg;
683  Stat stat( chronoSvc() , "*UNKNOWN Exception*" ) ;
684  sc = StatusCode::FAILURE;
685  }
686 
687  return sc;
688 }
689 
691 
692  // Bypass the finalialization if the algorithm hasn't been initilized.
693  if ( Gaudi::StateMachine::CONFIGURED == FSMState() ||
694  !isEnabled() ) return StatusCode::SUCCESS;
695 
697 
698  // lock the context service
700  ( this , registerContext() ? contextSvc().get() : 0 ) ;
701 
703  // Invoke finalize() method of the derived class inside a try/catch clause
704  try {
705  // Order changed (bug #3903 overview: finalize and nested algorithms)
706  // Finalize first any sub-algorithms (it can be done more than once)
707  bool ok = for_algorithms<&Algorithm::sysFinalize>( m_subAlgms );
708  { // limit the scope of the guard
709  Gaudi::Guards::AuditorGuard guard(this,
710  // check if we want to audit the initialize
711  (m_auditorFinalize) ? auditorSvc().get() : 0,
713  // Invoke the finalize() method of the derived class
714  sc = finalize();
715  }
716  if (!ok) sc = StatusCode::FAILURE;
717 
718  if( sc.isSuccess() ) {
719 
720  // Release all sub-algorithms
721  for (auto& it : m_subAlgms ) it->release();
722  // Indicate that this Algorithm has been finalized to prevent duplicate attempts
723  m_state = m_targetState;
724  }
725  }
726  catch( const GaudiException& Exception )
727  {
728  MsgStream log ( msgSvc() , name() );
729  log << MSG::FATAL << " Exception with tag=" << Exception.tag()
730  << " is caught " << endmsg;
731  log << MSG::ERROR << Exception << endmsg;
732  Stat stat( chronoSvc() , Exception.tag() ) ;
733  sc = StatusCode::FAILURE;
734  }
735  catch( const std::exception& Exception )
736  {
737  MsgStream log ( msgSvc() , name() );
738  log << MSG::FATAL << " Standard std::exception is caught " << endmsg;
739  log << MSG::ERROR << Exception.what() << endmsg;
740  Stat stat( chronoSvc() , "*std::exception*" ) ;
741  sc = StatusCode::FAILURE;
742  }
743  catch( ... )
744  {
745  MsgStream log ( msgSvc() , name() );
746  log << MSG::FATAL << "UNKNOWN Exception is caught " << endmsg;
747  Stat stat( chronoSvc() , "*UNKNOWN Exception*" ) ;
748  sc = StatusCode::FAILURE;
749  }
750  return sc;
751 }
752 
754  /* @TODO
755  * MCl 2008-10-23: the implementation of reinitialize as finalize+initialize
756  * is causing too many problems
757  *
758  // Default implementation is finalize+initialize
759  StatusCode sc = finalize();
760  if (sc.isFailure()) {
761  MsgStream log ( msgSvc() , name() );
762  log << MSG::ERROR << "reinitialize(): cannot be finalized" << endmsg;
763  return sc;
764  }
765  sc = initialize();
766  if (sc.isFailure()) {
767  MsgStream log ( msgSvc() , name() );
768  log << MSG::ERROR << "reinitialize(): cannot be initialized" << endmsg;
769  return sc;
770  }
771  */
772  return StatusCode::SUCCESS;
773 }
774 
776  // Default implementation is stop+start
777  StatusCode sc = stop();
778  if (sc.isFailure()) {
779  MsgStream log ( msgSvc() , name() );
780  log << MSG::ERROR << "restart(): cannot be stopped" << endmsg;
781  return sc;
782  }
783  sc = start();
784  if (sc.isFailure()) {
785  MsgStream log ( msgSvc() , name() );
786  log << MSG::ERROR << "restart(): cannot be started" << endmsg;
787  return sc;
788  }
789  return StatusCode::SUCCESS;
790 }
791 
792 const std::string& Algorithm::name() const {
793  return m_name;
794 }
795 
796 const std::string& Algorithm::version() const {
797  return m_version;
798 }
799 
800 bool Algorithm::isExecuted() const {
801  return m_isExecuted;
802 }
803 
804 void Algorithm::setExecuted( bool state ) {
805  m_isExecuted = state;
806 }
807 
809  m_isExecuted = false;
810  m_filterPassed = true;
811 }
812 
813 bool Algorithm::isEnabled() const {
814  return m_isEnabled;
815 }
816 
817 bool Algorithm::filterPassed() const {
818  return m_filterPassed;
819 }
820 
821 void Algorithm::setFilterPassed( bool state ) {
822  m_filterPassed = state;
823 }
824 
825 const std::vector<Algorithm*>* Algorithm::subAlgorithms( ) const {
826  return &m_subAlgms;
827 }
828 
829 std::vector<Algorithm*>* Algorithm::subAlgorithms( ) {
830  return &m_subAlgms;
831 }
832 
833 void Algorithm::setOutputLevel( int level ) {
834  if ( msgSvc() )
835  {
836  if ( level != MSG::NIL )
837  { msgSvc()->setOutputLevel( name(), level ) ; }
838  m_outputLevel = msgSvc()->outputLevel( name() );
839  }
840 }
841 
842 #define serviceAccessor(METHOD,INTERFACE,NAME,MEMBER) \
843 SmartIF<INTERFACE>& Algorithm::METHOD() const { \
844  if ( !MEMBER ) { \
845  MEMBER = service(NAME); \
846  if( !MEMBER ) { \
847  throw GaudiException("Service [" NAME "] not found", name(), StatusCode::FAILURE); \
848  } \
849  } \
850  return MEMBER; \
851 }
852 
853 serviceAccessor(auditorSvc, IAuditorSvc, "AuditorSvc", m_pAuditorSvc)
854 serviceAccessor(chronoSvc, IChronoStatSvc, "ChronoStatSvc", m_CSS)
855 serviceAccessor(detSvc, IDataProviderSvc, "DetectorDataSvc", m_DDS)
857 serviceAccessor(eventSvc, IDataProviderSvc, "EventDataSvc", m_EDS)
858 serviceAccessor(eventCnvSvc, IConversionSvc, "EventPersistencySvc", m_ECS)
859 serviceAccessor(histoSvc, IHistogramSvc, "HistogramDataSvc", m_HDS)
860 serviceAccessor(exceptionSvc, IExceptionSvc, "ExceptionSvc", m_EXS)
861 serviceAccessor(ntupleSvc, INTupleSvc, "NTupleSvc", m_NTS)
862 serviceAccessor(randSvc, IRndmGenSvc, "RndmGenSvc", m_RGS)
863 serviceAccessor(toolSvc, IToolSvc, "ToolSvc", m_ptoolSvc)
864 serviceAccessor(contextSvc, IAlgContextSvc,"AlgContextSvc", m_contextSvc)
865 //serviceAccessor(msgSvc, IMessageSvc, "MessageSvc", m_MS)
866 // Message service needs a special treatment to avoid infinite recursion
867 SmartIF<IMessageSvc>& Algorithm::msgSvc() const {
868  if ( !m_MS ) {
869  //can not use service() method (infinite recursion!)
870  m_MS = serviceLocator(); // default message service
871  if( !m_MS ) {
872  throw GaudiException("Service [MessageSvc] not found", name(), StatusCode::FAILURE);
873  }
874  }
875  return m_MS;
876 }
877 
878 // Obsoleted name, kept due to the backwards compatibility
880  return chronoSvc();
881 }
882 // Obsoleted name, kept due to the backwards compatibility
884  return detSvc();
885 }
886 // Obsoleted name, kept due to the backwards compatibility
888  return detCnvSvc();
889 }
890 // Obsoleted name, kept due to the backwards compatibility
892  return eventSvc();
893 }
894 // Obsoleted name, kept due to the backwards compatibility
896  return eventCnvSvc();
897 }
898 // Obsoleted name, kept due to the backwards compatibility
900  return histoSvc();
901 }
902 // Obsoleted name, kept due to the backwards compatibility
904  return msgSvc();
905 }
906 // Obsoleted name, kept due to the backwards compatibility
908  return ntupleSvc();
909 }
910 
912  return *const_cast<SmartIF<ISvcLocator>*>(&m_pSvcLocator);
913 }
914 
915 // Use the job options service to set declared properties
917  if( m_pSvcLocator ) {
918  auto jos = m_pSvcLocator->service<IJobOptionsSvc>("JobOptionsSvc");
919  if( jos ) {
920  // set first generic Properties
921  StatusCode sc = jos->setMyProperties( getGaudiThreadGenericName(name()), this );
922  if( sc.isFailure() ) return StatusCode::FAILURE;
923 
924  // set specific Properties
925  if (isGaudiThreaded(name())) {
926  if(jos->setMyProperties( name(), this ).isFailure()) {
927  return StatusCode::FAILURE;
928  }
929  }
930  return sc;
931  }
932  }
933  return StatusCode::FAILURE;
934 }
935 
937  const std::string& name,
938  Algorithm*& pSubAlgorithm) {
939  if( !m_pSvcLocator ) return StatusCode::FAILURE;
940 
941  SmartIF<IAlgManager> am(m_pSvcLocator);
942  if ( !am ) return StatusCode::FAILURE;
943 
944  // Maybe modify the AppMgr interface to return Algorithm* ??
945  IAlgorithm *tmp;
946  StatusCode sc = am->createAlgorithm
947  (type, name+getGaudiThreadIDfromName(Algorithm::name()), tmp);
948  if( sc.isFailure() ) return StatusCode::FAILURE;
949 
950  try{
951  pSubAlgorithm = dynamic_cast<Algorithm*>(tmp);
952  m_subAlgms.push_back(pSubAlgorithm);
953  } catch(...){
954  sc = StatusCode::FAILURE;
955  }
956  return sc;
957 }
958 
959 // IProperty implementation
960 // Delegate to the Property manager
962  return m_propertyMgr->setProperty(p);
963 }
964 StatusCode Algorithm::setProperty(const std::string& s) {
965  return m_propertyMgr->setProperty(s);
966 }
967 StatusCode Algorithm::setProperty(const std::string& n, const std::string& v) {
968  return m_propertyMgr->setProperty(n,v);
969 }
971  return m_propertyMgr->getProperty(p);
972 }
973 const Property& Algorithm::getProperty( const std::string& name) const{
974  return m_propertyMgr->getProperty(name);
975 }
976 StatusCode Algorithm::getProperty(const std::string& n, std::string& v ) const {
977  return m_propertyMgr->getProperty(n,v);
978 }
979 const std::vector<Property*>& Algorithm::getProperties( ) const {
980  return m_propertyMgr->getProperties();
981 }
982 bool Algorithm::hasProperty(const std::string& name) const {
983  return m_propertyMgr->hasProperty(name);
984 }
985 
989 void
991 {
992  // do nothing... yet ?
993 }
994 
996 Algorithm::service_i(const std::string& svcName,
997  bool createIf,
998  const InterfaceID& iid,
999  void** ppSvc) const {
1000  const ServiceLocatorHelper helper(*serviceLocator(), *this);
1001  return helper.getService(svcName, createIf, iid, ppSvc);
1002 }
1003 
1004 StatusCode
1005 Algorithm::service_i(const std::string& svcType,
1006  const std::string& svcName,
1007  const InterfaceID& iid,
1008  void** ppSvc) const {
1009  const ServiceLocatorHelper helper(*serviceLocator(), *this);
1010  return helper.createService(svcType, svcName, iid, ppSvc);
1011 }
1012 
1013 SmartIF<IService> Algorithm::service(const std::string& name, const bool createIf, const bool quiet) const {
1014  const ServiceLocatorHelper helper(*serviceLocator(), *this);
1015  return helper.service(name, quiet, createIf);
1016 }
StatusCode endRun() override
Algorithm end run. This method is called at the end of the event loop.
Definition: Algorithm.cpp:540
StatusCode setProperty(IProperty *component, const std::string &name, const TYPE &value, const std::string &doc)
simple function to set the property of the given object from the value
Definition: Property.h:1187
void resetExecuted() override
Reset the executed state of the Algorithm for the duration of the current event.
Definition: Algorithm.cpp:808
The interface implemented by the IToolSvc base class.
Definition: IToolSvc.h:17
tuple c
Definition: gaudirun.py:392
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
an helper to share the implementation of service() among the various kernel base classes ...
Small smart pointer class with automatic reference counting for IInterface.
Definition: IConverter.h:14
SmartIF< IConversionSvc > & eventDataCnvService() const
Obsoleted name, kept due to the backwards compatibility.
Definition: Algorithm.cpp:895
Define general base for Gaudi exception.
def initialize()
Definition: AnalysisTest.py:12
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
GAUDI_API std::string getGaudiThreadIDfromName(const std::string &name)
helper function to extract Gaudi Thread ID from thread copy name
Definition: ThreadGaudi.cpp:26
StatusCode sysEndRun() override
endRun method invoked by the framework.
Definition: Algorithm.cpp:474
StatusCode createSubAlgorithm(const std::string &type, const std::string &name, Algorithm *&pSubAlg)
Create a sub algorithm.
Definition: Algorithm.cpp:936
Helper "sentry" class to automatize the safe register/unregister the algorithm's context.
const std::string & version() const override
Definition: Algorithm.cpp:796
SmartIF< ISvcLocator > & serviceLocator() const
The standard service locator.
Definition: Algorithm.cpp:911
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
GAUDI_API bool isGaudiThreaded(const std::string &name)
test if current Gaudi object is running /will run in a thread
Definition: ThreadGaudi.cpp:73
StatusCode setProperties()
Set the algorithm's properties.
Definition: Algorithm.cpp:916
Small wrapper class for easy manipulation with generic counters and IStatSvc&ICounterSvc interface...
Definition: Stat.h:46
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:45
StatusCode sysBeginRun() override
beginRun method invoked by the framework.
Definition: Algorithm.cpp:403
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
StatusCode setProperty(const Property &p) override
Implementation of IProperty::setProperty.
Definition: Algorithm.cpp:961
State GAUDI_API ChangeState(const Transition transition, const State state)
Function to get the new state according to the required transition, checking if the transition is all...
Definition: StateMachine.cpp:8
StatusCode service_i(const std::string &svcName, bool createIf, const InterfaceID &iid, void **ppSvc) const
implementation of service method
Definition: Algorithm.cpp:996
SmartIF< IChronoStatSvc > & chronoStatService() const
Obsoleted name, kept due to the backwards compatibility.
Definition: Algorithm.cpp:879
bool filterPassed() const override
Did this algorithm pass or fail its filter criterion for the last event?
Definition: Algorithm.cpp:817
GAUDI_API std::string getGaudiThreadGenericName(const std::string &name)
helper function to extract Gaudi instance name from thread copy name
Definition: ThreadGaudi.cpp:50
Data provider interface definition.
Property manager helper class.
Definition: PropertyMgr.h:34
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
SmartIF< IDataProviderSvc > & detDataService() const
Obsoleted name, kept due to the backwards compatibility.
Definition: Algorithm.cpp:883
This service manages tools.
Definition: ToolSvc.h:22
virtual const StatusCode & code() const
StatusCode for Exception.
StatusCode sysRestart() override
Restart method invoked by the framework.
Definition: Algorithm.cpp:325
SmartIF< IConversionSvc > & detDataCnvService() const
Obsoleted name, kept due to the backwards compatibility.
Definition: Algorithm.cpp:887
Random Generator service definition.
Definition: RndmGenSvc.h:49
const std::string & name() const override
The identifying name of the algorithm object.
Definition: Algorithm.cpp:792
The IChronoStatSvc is the interface implemented by the ChronoStatService.
Interface ID class.
Definition: IInterface.h:30
void setExecuted(bool state) override
Set the executed flag to the specified state.
Definition: Algorithm.cpp:804
Main interface for the JobOptions service.
StatusCode getProperty(Property *p) const override
Implementation of IProperty::getProperty.
Definition: Algorithm.cpp:970
StatusCode sysReinitialize() override
Reinitialization method invoked by the framework.
Definition: Algorithm.cpp:247
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:47
Random Generator service interface definition Definition of a interface for a service to access rando...
Definition: IRndmGenSvc.h:35
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
StatusCode sysExecute() override
The actions to be performed by the algorithm on an event.
Definition: Algorithm.cpp:545
bool isExecuted() const override
Has this algorithm been executed since the last reset?
Definition: Algorithm.cpp:800
StatusCode beginRun() override
Algorithm begin run.
Definition: Algorithm.cpp:469
StatusCode sysStart() override
Reinitialization method invoked by the framework.
Definition: Algorithm.cpp:175
Simple implementation of IExceptionSvc abstract interface.
Definition: ExceptionSvc.h:19
The IMessage is the interface implemented by the message service.
Definition: IMessageSvc.h:57
StatusCode sysFinalize() override
System finalization.
Definition: Algorithm.cpp:690
serviceAccessor(auditorSvc, IAuditorSvc,"AuditorSvc", m_pAuditorSvc) serviceAccessor(chronoSvc
virtual const std::string & tag() const
name tag for the exception, or exception type
Definition of the IHistogramSvc interface class.
Definition: IHistogramSvc.h:47
const std::vector< Property * > & getProperties() const override
Implementation of IProperty::getProperties.
Definition: Algorithm.cpp:979
The IAlgorithm is the interface implemented by the Algorithm base class.
Definition: IAlgorithm.h:19
Algorithm(const std::string &name, ISvcLocator *svcloc, const std::string &version=PACKAGE_VERSION)
Constructor.
Definition: Algorithm.cpp:36
void initOutputLevel(Property &prop)
callback for output level property
Definition: Algorithm.cpp:990
const std::vector< Algorithm * > * subAlgorithms() const
List of sub-algorithms. Returns a pointer to a vector of (sub) Algorithms.
Definition: Algorithm.cpp:825
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:61
Property base class allowing Property* collections to be "homogeneous".
Definition: Property.h:38
m_CSS m_DCS EventPersistencySvc
Definition: Algorithm.cpp:858
NTuple service.
Definition: NTupleSvc.h:24
bool isEnabled() const override
Is this algorithm enabled or disabled?
Definition: Algorithm.cpp:813
m_CSS DetectorPersistencySvc
Definition: Algorithm.cpp:856
StatusCode restart() override
the default (empty) implementation of IStateful::restart() method
Definition: Algorithm.cpp:775
bool hasProperty(const std::string &name) const override
Implementation of IProperty::hasProperty.
Definition: Algorithm.cpp:982
string s
Definition: gaudirun.py:246
tuple appMgr
Definition: IOTest.py:83
An abstract interface for Algorithm Context Service.
SmartIF< IDataProviderSvc > & eventDataService() const
Obsoleted name, kept due to the backwards compatibility.
Definition: Algorithm.cpp:891
#define UNLIKELY(x)
Definition: Kernel.h:126
SmartIF< IHistogramSvc > & histogramDataService() const
Obsoleted name, kept due to the backwards compatibility.
Definition: Algorithm.cpp:899
SmartIF< IMessageSvc > & messageService() const
Obsoleted name, kept due to the backwards compatibility.
Definition: Algorithm.cpp:903
StatusCode service(const std::string &name, T *&psvc, bool createIf=true) const
Access a service by name, creating it if it doesn't already exist.
Definition: Algorithm.h:208
void ignore() const
Definition: StatusCode.h:108
The IProperty is the basic interface for all components which have properties that can be set or get...
Definition: IProperty.h:21
It is a simple guard, which "locks" the scope for the Auditor Service is am exception-safe way...
Definition: Guards.h:214
The interface implemented by the IAuditorSvc base class.
Definition: IAuditorSvc.h:15
SmartIF< INTupleSvc > & ntupleService() const
Obsoleted name, kept due to the backwards compatibility.
Definition: Algorithm.cpp:907
StatusCode sysInitialize() override
Initialization method invoked by the framework.
Definition: Algorithm.cpp:87
StatusCode reinitialize() override
the default (empty) implementation of IStateful::reinitialize() method
Definition: Algorithm.cpp:753
void setFilterPassed(bool state) override
Set the filter passed flag to the specified state.
Definition: Algorithm.cpp:821
The abstract interface for exception handling service.
Definition: IExceptionSvc.h:24
tuple start
Definition: IOTest.py:88
void setOutputLevel(int level)
Set the output level for current algorithm.
Definition: Algorithm.cpp:833
The Chrono & Stat Sservice: service implements the IChronoStatSvc interface and provides the basic ch...
Definition: ChronoStatSvc.h:33
StatusCode sysStop() override
System stop.
Definition: Algorithm.cpp:634
string type
Definition: gaudirun.py:151