Gaudi Framework, version v25r0

Home   Generated: Mon Feb 17 2014
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Sequencer.cpp
Go to the documentation of this file.
1 // Sequencer class
2 // Implements:
3 // 1) Common functionality of IInterface
4 // 2) Default behavior for the IAlgorithm
5 
6 #include "GaudiAlg/Sequencer.h"
7 
10 #include "GaudiKernel/MsgStream.h"
11 #include "GaudiKernel/Chrono.h"
12 #include "GaudiKernel/Stat.h"
14 
15 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
16 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
17 
21 Sequencer::Sequencer( const std::string& name, ISvcLocator* pSvcLocator )
22 : Algorithm( name, pSvcLocator ),
23  m_branchFilterPassed( false )
24 {
25 
26  // Create vector of branch algorithms
28 
29  // Declare Sequencer properties with their defaults
30  declareProperty( "Members", m_names );
31  declareProperty( "BranchMembers", m_branchNames );
32  declareProperty( "StopOverride", m_stopOverride=false );
33 
34  // Associate action handlers with the "Members" and "BranchMembers" properties
37 
38 }
39 
44 {
45  delete m_branchAlgs;
46 }
47 
50 {
52  MsgStream log( msgSvc( ), name( ) );
53 
54  std::vector<Algorithm*>* theAlgs;
57 
58  result = decodeMemberNames();
59  if( result.isFailure() ) {
60  log << MSG::ERROR << "Unable to configure one or more sequencer members " << endmsg;
61  return result;
62  }
63  result = decodeBranchMemberNames();
64  if( result.isFailure() ) {
65  log << MSG::ERROR << "Unable to configure one or more branch members " << endmsg;
66  return result;
67  }
68 
69  // Loop over all sub-algorithms
70  theAlgs = subAlgorithms( );
71  itend = theAlgs->end( );
72  for (it = theAlgs->begin(); it != itend; it++) {
73  Algorithm* theAlgorithm = (*it);
74  result = theAlgorithm->sysInitialize( );
75  if( result.isFailure() ) {
76  log << MSG::ERROR << "Unable to initialize Algorithm " << theAlgorithm->name() << endmsg;
77  return result;
78  }
79  }
80 
81  // Loop over all branches
82  theAlgs = branchAlgorithms( );
83  itend = theAlgs->end( );
84  for (it = theAlgs->begin(); it != itend; it++) {
85  Algorithm* theAlgorithm = (*it);
86  result = theAlgorithm->sysInitialize( );
87  if( result.isFailure() ) {
88  log << MSG::ERROR << "Unable to initialize Algorithm " << theAlgorithm->name() << endmsg;
89  return result;
90  }
91  }
92 
93  return result;
94 }
95 
98 {
99  // Bypass the loop if this sequencer is disabled
100  if ( isEnabled( ) ) {
101 
102  // Loop over all members calling their reinitialize functions
103  // if they are not disabled.
104  std::vector<Algorithm*>* theAlgms = subAlgorithms( );
106  std::vector<Algorithm*>::iterator itend = theAlgms->end( );
107  for (it = theAlgms->begin(); it != itend; it++) {
108  Algorithm* theAlgorithm = (*it);
109  if ( ! theAlgorithm->isEnabled( ) ) {
110  theAlgorithm->reinitialize( ).ignore();
111  }
112  }
113  // Loop over all branch members calling their reinitialize functions
114  // if they are not disabled.
115  theAlgms = branchAlgorithms( );
116  itend = theAlgms->end( );
117  for (it = theAlgms->begin(); it != itend; it++) {
118  Algorithm* theAlgorithm = (*it);
119  if ( ! theAlgorithm->isEnabled( ) ) {
120  theAlgorithm->reinitialize( ).ignore();
121  }
122  }
123 
124  }
125  return StatusCode::SUCCESS;
126 }
127 
130 {
132  MsgStream log( msgSvc( ), name( ) );
133 
134  ON_DEBUG log << MSG::DEBUG << name( ) << " Sequencer::execute( )" << endmsg;
135 
136  // Bypass the loop if this sequencer is disabled or has already been executed
137  if ( isEnabled( ) && ! isExecuted( ) ) {
138  Algorithm* lastAlgorithm;
139  result = execute( subAlgorithms( ), m_isInverted, lastAlgorithm );
140  if ( result.isSuccess( ) ) {
141  bool passed = filterPassed( );
142  if ( ! passed && ! isStopOverride( ) ) {
143 
144  // Filter failed and stop override not set. Execute the
145  // branch if there is one associated with the filter
146  // algorithm that failed. Note that the first member on
147  // the branch is the failing algorithm and so should
148  // be skipped.
150  if ( theAlgs->size( ) > 0 ) {
151  Algorithm* branchAlgorithm = (*theAlgs)[0];
152  if ( lastAlgorithm == branchAlgorithm ) {
153 
154  // Branch specified - Loop over branch members
155  result = execute( branchAlgorithms( ),
157  lastAlgorithm, 1 );
158  if ( result.isSuccess( ) ) {
159 
160  // The final filter passed state will be set true if either
161  // of the main or branches passed, otherwise false.
162 
163  // Save the branch filter passed state.
165  }
166  }
167  }
168  }
169  }
170 
171  // Prevent multiple executions of this sequencer for the current event
172  setExecuted( true );
173  }
174  return result;
175 }
176 
179 {
180  // Loop over all branch members calling their finalize functions
181  // if they are not disabled. Note that the Algorithm::sysFinalize
182  // function already does this for the main members.
185  std::vector<Algorithm*>::iterator itend = theAlgs->end( );
186  for (it = theAlgs->begin(); it != itend; it++) {
187  Algorithm* theAlgorithm = (*it);
188  if (theAlgorithm->sysFinalize( ).isFailure()) {
189  MsgStream log( msgSvc( ), name( ) );
190  log << MSG::ERROR << "Unable to finalize Algorithm "
191  << theAlgorithm->name() << endmsg;
192  }
193  }
194  return StatusCode::SUCCESS;
195 }
196 
199 {
201  MsgStream log( msgSvc( ), name( ) );
202 
203  std::vector<Algorithm*>* theAlgs;
206 
207  // Loop over all sub-algorithms
208  theAlgs = subAlgorithms( );
209  itend = theAlgs->end( );
210  for (it = theAlgs->begin(); it != itend; it++) {
211  Algorithm* theAlgorithm = (*it);
212  result = theAlgorithm->sysStart( );
213  if( result.isFailure() ) {
214  log << MSG::ERROR << "Unable to start Algorithm " << theAlgorithm->name() << endmsg;
215  return result;
216  }
217  }
218 
219  // Loop over all branches
220  theAlgs = branchAlgorithms( );
221  itend = theAlgs->end( );
222  for (it = theAlgs->begin(); it != itend; it++) {
223  Algorithm* theAlgorithm = (*it);
224  result = theAlgorithm->sysStart( );
225  if( result.isFailure() ) {
226  log << MSG::ERROR << "Unable to start Algorithm " << theAlgorithm->name() << endmsg;
227  return result;
228  }
229  }
230 
231  return result;
232 }
233 
236 {
237  // Loop over all branch members calling their finalize functions
238  // if they are not disabled.
239  std::vector<Algorithm*>* theAlgs;
242 
243  theAlgs = subAlgorithms( );
244  itend = theAlgs->end( );
245  for (it = theAlgs->begin(); it != itend; it++) {
246  Algorithm* theAlgorithm = (*it);
247  if (theAlgorithm->sysStop( ).isFailure()) {
248  MsgStream log( msgSvc( ), name( ) );
249  log << MSG::ERROR << "Unable to stop Algorithm "
250  << theAlgorithm->name() << endmsg;
251  }
252  }
253 
254  theAlgs = branchAlgorithms( );
255  itend = theAlgs->end( );
256  for (it = theAlgs->begin(); it != itend; it++) {
257  Algorithm* theAlgorithm = (*it);
258  if (theAlgorithm->sysStop( ).isFailure()) {
259  MsgStream log( msgSvc( ), name( ) );
260  log << MSG::ERROR << "Unable to stop Algorithm "
261  << theAlgorithm->name() << endmsg;
262  }
263  }
264  return StatusCode::SUCCESS;
265 }
266 
269 {
271  MsgStream log( msgSvc( ), name( ) );
272 
273  // Bypass the loop if this sequencer is disabled
274  if ( isEnabled( ) ) {
275 
276  // Loop over all members calling their sysInitialize functions
277  // if they are not disabled. Note that the Algoriithm::sysInitialize
278  // function protects this from affecting Algorithms that have already
279  // been initialized.
282  std::vector<Algorithm*>::iterator itend = theAlgs->end( );
283  for (it = theAlgs->begin(); it != itend; it++) {
284  Algorithm* theAlgorithm = (*it);
285  result = theAlgorithm->sysInitialize( );
286  if( result.isFailure() ) {
287  log << MSG::ERROR << "Unable to initialize Algorithm " << theAlgorithm->name() << endmsg;
288  break;
289  }
290  result = theAlgorithm->sysStart( );
291  if( result.isFailure() ) {
292  log << MSG::ERROR << "Unable to start Algorithm " << theAlgorithm->name() << endmsg;
293  break;
294  }
295  }
296 
297  // Loop over all members calling their beginRun functions
298  // if they are not disabled.
299  for (it = theAlgs->begin(); it != itend; it++) {
300  Algorithm* theAlgorithm = (*it);
301  if ( ! theAlgorithm->isEnabled( ) ) {
302  theAlgorithm->beginRun( ).ignore();
303  }
304  }
305 
306  // Loop over all branch members calling their sysInitialize functions
307  // if they are not disabled. Note that the Algoriithm::sysInitialize
308  // function protects this from affecting Algorithms that have already
309  // been initialized.
310  theAlgs = branchAlgorithms( );
311  itend = theAlgs->end( );
312  for (it = theAlgs->begin(); it != itend; it++) {
313  Algorithm* theAlgorithm = (*it);
314  result = theAlgorithm->sysInitialize( );
315  if( result.isFailure() ) {
316  log << MSG::ERROR << "Unable to initialize Algorithm " << theAlgorithm->name() << endmsg;
317  break;
318  }
319  result = theAlgorithm->sysStart( );
320  if( result.isFailure() ) {
321  log << MSG::ERROR << "Unable to start Algorithm " << theAlgorithm->name() << endmsg;
322  break;
323  }
324  }
325 
326  // Loop over all branch members calling their beginRun functions
327  // if they are not disabled.
328  for (it = theAlgs->begin(); it != itend; it++) {
329  Algorithm* theAlgorithm = (*it);
330  if ( ! theAlgorithm->isEnabled( ) ) {
331  theAlgorithm->beginRun( ).ignore();
332  }
333  }
334  }
335  return StatusCode::SUCCESS;
336 }
337 
340 {
341  // Bypass the loop if this sequencer is disabled
342  if ( isEnabled( ) ) {
343 
344  // Loop over all members calling their endRun functions
345  // if they are not disabled.
346  std::vector<Algorithm*>* theAlgms = subAlgorithms( );
348  std::vector<Algorithm*>::iterator itend = theAlgms->end( );
349  for (it = theAlgms->begin(); it != itend; it++) {
350  Algorithm* theAlgorithm = (*it);
351  if ( ! theAlgorithm->isEnabled( ) ) {
352  theAlgorithm->endRun( ).ignore();
353  }
354  }
355  // Loop over all branch members calling their endRun functions
356  // if they are not disabled.
357  theAlgms = branchAlgorithms( );
358  itend = theAlgms->end( );
359  for (it = theAlgms->begin(); it != itend; it++) {
360  Algorithm* theAlgorithm = (*it);
361  if ( ! theAlgorithm->isEnabled( ) ) {
362  theAlgorithm->endRun( ).ignore();
363  }
364  }
365  }
366  return StatusCode::SUCCESS;
367 }
368 
369 void
371 {
373 
374  // Loop over all members calling their resetExecuted functions
375  // if they are not disabled.
376  std::vector<Algorithm*>* subAlgms = subAlgorithms( );
378  std::vector<Algorithm*>::iterator itend = subAlgms->end( );
379  for (it = subAlgms->begin(); it != itend; it++) {
380  Algorithm* theAlgorithm = (*it);
381  theAlgorithm->resetExecuted( );
382  }
383 
384  // Loop over all branch members calling their resetExecuted functions
385  // if they are not disabled.
386  subAlgms = branchAlgorithms( );
387  itend = subAlgms->end( );
388  for (it = subAlgms->begin(); it != itend; it++) {
389  Algorithm* theAlgorithm = (*it);
390  theAlgorithm->resetExecuted( );
391  }
392 
393  // Reset the branch filter passed flag
394  m_branchFilterPassed = false;
395 }
396 
397 bool
399 {
400  return m_branchFilterPassed;
401 }
402 
405 {
407  return StatusCode::SUCCESS;
408 }
409 
410 bool
412 {
413  return m_stopOverride.value( );
414 }
415 
418 {
419  StatusCode result = append( pAlgorithm, subAlgorithms( ) );
420  return result;
421 }
422 
425 {
426  StatusCode result = append( pAlgorithm, branchAlgorithms( ) );
427  return result;
428 }
429 
432  const std::string& name,
433  Algorithm*& pAlgorithm )
434 {
435  StatusCode result = createAndAppend( type, name, pAlgorithm, subAlgorithms( ) );
436  return result;
437 }
438 
441  const std::string& name,
442  Algorithm*& pAlgorithm )
443 {
444  StatusCode result = createAndAppend( type, name, pAlgorithm, branchAlgorithms( ) );
445  return result;
446 }
447 
450 {
451  std::string theName = pAlgorithm->name( );
452  StatusCode result = remove( theName );
453  return result;
454 }
455 
458 {
459  StatusCode result = remove( algname, subAlgorithms( ) );
460  return result;
461 }
462 
465 {
466  std::string theName = pAlgorithm->name( );
467  StatusCode result = removeFromBranch( theName );
468  return result;
469 }
470 
473 {
474  StatusCode result = remove( algname, branchAlgorithms( ) );
475  return result;
476 }
477 
480  return m_branchAlgs;
481 }
482 
485 {
487 
488  // Decode the membership list
489  result = decodeNames( m_names,
490  subAlgorithms( ),
491  m_isInverted );
492 
493  return result;
494 }
495 
496 void
498 {
499  if ( isInitialized() ) decodeMemberNames();
500 }
501 
504 {
506 
507  // Decode the branch membership list
508  result = decodeNames( m_branchNames,
509  branchAlgorithms( ),
511 
512  return result;
513 }
514 
515 void
517 {
519 }
520 
527  std::vector<Algorithm*>* theAlgs )
528 {
530  // Check that the specified algorithm doesn't already exist in the membership list
532  std::vector<Algorithm*>::iterator itend = theAlgs->end( );
533  for (it = theAlgs->begin(); it != itend; it++) {
534  Algorithm* theAlgorithm = (*it);
535  if ( theAlgorithm == pAlgorithm ) {
536  result = StatusCode::FAILURE;
537  break;
538  }
539  }
540  if ( result.isSuccess( ) ) {
541  theAlgs->push_back( pAlgorithm );
542  pAlgorithm->addRef();
543  }
544  return result;
545 }
546 
549  const std::string& algName,
550  Algorithm*& pAlgorithm,
551  std::vector<Algorithm*>* theAlgs )
552 {
554  MsgStream log( msgSvc( ), name( ) );
555  SmartIF<IAlgManager> theAlgMgr(serviceLocator()->service("ApplicationMgr"));
556  if ( theAlgMgr.isValid() ) {
557  IAlgorithm* tmp;
558  result = theAlgMgr->createAlgorithm( type, algName, tmp );
559  if ( result.isSuccess( ) ) {
560  try{
561  pAlgorithm = dynamic_cast<Algorithm*>(tmp);
562  theAlgs->push_back( pAlgorithm );
563  } catch(...){
564  log << MSG::ERROR << "Unable to create Algorithm " << algName << endmsg;
565  result = StatusCode::FAILURE;
566  }
567  }
568  }
569  return result;
570 }
571 
574  std::vector<Algorithm*>* theAlgs,
575  std::vector<bool>& theLogic )
576 {
577  StatusCode result;
578  MsgStream log( msgSvc( ), name( ) );
579  SmartIF<IAlgManager> theAlgMgr(serviceLocator()->service("ApplicationMgr"));
580  if ( theAlgMgr.isValid() ) {
581  // Clear the existing list of algorithms
582  theAlgs->clear( );
583 
584  // Build the list of member algorithms from the contents of the
585  // theNames list.
586  const std::vector<std::string>& theNameVector = theNames.value( );
588  std::vector<std::string>::const_iterator itend = theNameVector.end( );
589  for (it = theNameVector.begin(); it != itend; it++) {
590 
591  // Parse the name for a syntax of the form:
592  //
593  // <type>/<name>
594  //
595  // Where <name> is the algorithm instance name, and <type> is the
596  // algorithm class type (being a subclass of Algorithm).
597  const Gaudi::Utils::TypeNameString typeName(*it);
598  std::string theName = typeName.name();
599  std::string theType = typeName.type();
600 
601  // Parse the name for a syntax of the form:
602  //
603  // <name>:invert
604  //
605  // Where <name> is the algorithm instance name and ":invert"
606  // indicates that the filter passed logic is inverted.
607  bool isInverted = false;
608  std::string::size_type invert = theName.find_first_of( ":" );
609  // Skip all occurrences of "::" (allow namespaces)
610  while ( std::string::npos != invert
611  && invert < (theName.size() - 1) && theName[invert+1] == ':' )
612  invert = theName.find_first_of( ":", invert+2 );
613  if ( std::string::npos != invert ) {
614  if ( theName == theType ) {
615  // This means that we got something like "Type:invert",
616  // so we have to strip the ":invert" from the type too.
617  theType = theType.substr( 0, invert );
618  }
619  theName = theName.substr( 0, invert );
620  isInverted = true;
621  }
622  // Check whether the supplied name corresponds to an existing
623  // Algorithm object.
624  SmartIF<IAlgorithm>& theIAlg = theAlgMgr->algorithm(theName, false);
625  Algorithm* theAlgorithm = 0;
627  if ( theIAlg.isValid() ) {
628  try{
629  theAlgorithm = dynamic_cast<Algorithm*>(theIAlg.get());
630  } catch(...){
631  log << MSG::WARNING << theName << " is not an Algorithm - Failed dynamic cast" << endmsg;
632  theAlgorithm = 0; // release
633  }
634  }
635  if ( theAlgorithm ) {
636 
637  // The specified Algorithm already exists - just append it to the membership list.
638  status = append( theAlgorithm, theAlgs );
639  if ( status.isSuccess( ) ) {
640  ON_DEBUG log << MSG::DEBUG << theName << " already exists - appended to member list" << endmsg;
641  } else {
642  log << MSG::WARNING << theName << " already exists - append failed!!!" << endmsg;
643  result = StatusCode::FAILURE;
644  }
645  } else {
646 
647  // The specified name doesn't exist - create a new object of the specified type
648  // and append it to the membership list.
649  status = createAndAppend( theType, theName, theAlgorithm, theAlgs );
650  if ( status.isSuccess( ) ) {
651  ON_DEBUG log << MSG::DEBUG << theName << " doesn't exist - created and appended to member list" << endmsg;
652  } else {
653  log << MSG::WARNING << theName << " doesn't exist - creation failed!!!" << endmsg;
654  result = StatusCode::FAILURE;
655  }
656  }
657  if ( status.isSuccess( ) ) {
658  theLogic.push_back( isInverted );
659  }
660  }
661 
662  }
663  // Print membership list
664  if ( result.isSuccess() && theAlgs->size() != 0 ) {
665  log << MSG::INFO << "Member list: ";
667  std::vector<bool>::iterator li = theLogic.begin();
668  for ( ; ai != theAlgs->end(); ++ai, ++li ) {
669 
670  if ( ai != theAlgs->begin() ) log << ", ";
671 
672  if ( (*ai)->name() == System::typeinfoName(typeid(**ai)) )
673  log << (*ai)->name();
674  else
675  log << System::typeinfoName(typeid(**ai)) << "/" << (*ai)->name();
676 
677  if (*li) log << ":invert";
678  }
679  log << endmsg;
680  }
681  return result;
682 }
683 
686  std::vector<bool>& theLogic,
687  Algorithm*& lastAlgorithm,
688  unsigned int first )
689 {
691 
692  // Loop over all algorithms calling their execute functions if they
693  // are (a) not disabled, and (b) aren't already executed. Note that
694  // in the latter case the filter state is still examined. Terminate
695  // the loop if an algorithm indicates that it's filter didn't pass.
696  unsigned int size = theAlgs->size( );
697  for (unsigned int i = first; i < size; i++) {
698  lastAlgorithm = (*theAlgs)[i];
699  result = executeMember( lastAlgorithm );
700  if ( result.isSuccess( ) ) {
701 
702  // Take the filter passed status of this algorithm as my own status.
703  // Note that we take into account inverted logic.
704  bool passed = lastAlgorithm->filterPassed( );
705  bool isInverted = theLogic[i];
706  if ( isInverted ) {
707  passed = ! passed;
708  }
709  setFilterPassed( passed );
710 
711  // The behaviour when the filter fails depends on the StopOverride property.
712  // The default action is to stop processing, but this default can be
713  // overridden by setting the "StopOverride" property to true.
714  if ( ! isStopOverride( ) ) {
715  if ( ! passed ) break;
716  }
717  } else {
718  break;
719  }
720  }
721  return result;
722 }
723 
726 {
728  if ( theAlgorithm->isEnabled( ) ) {
729  if ( ! theAlgorithm->isExecuted( ) ) {
730  result = theAlgorithm->sysExecute( );
731 
732  // Set the executed state of the algorithm.
733  // I think this should be done by the algorithm itself, but just in case...
734  theAlgorithm->setExecuted( true );
735  }
736  }
737  return result;
738 }
739 
742 {
743  MsgStream log( msgSvc( ), name( ) );
745 
746  // Test that the algorithm exists in the member list
748  std::vector<Algorithm*>::iterator itend = theAlgs->end( );
749  for (it = theAlgs->begin(); it != itend; it++) {
750  Algorithm* theAlgorithm = (*it);
751  if ( theAlgorithm->name( ) == algname ) {
752 
753  // Algorithm with specified name exists in the algorithm list - remove it
754  // THIS ISN'T IMPLEMENTED YET!!!!
755  log << MSG::INFO <<"Sequencer::remove( ) isn't implemented yet!!!!!" << endmsg;
756  result = StatusCode::SUCCESS;
757  break;
758  }
759  }
760  return result;
761 }

Generated at Mon Feb 17 2014 14:37:39 for Gaudi Framework, version v25r0 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004