Gaudi Framework, version v23r9

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

Generated at Thu Jul 18 2013 12:18:01 for Gaudi Framework, version v23r9 by Doxygen version 1.8.2 written by Dimitri van Heesch, © 1997-2004