Gaudi Framework, version v21r11

Home   Generated: 30 Sep 2010

GaudiSequencer Class Reference

Sequencer for executing several algorithms, stopping when one is faulty. More...

#include <GaudiSequencer.h>

Inheritance diagram for GaudiSequencer:
[legend]
Collaboration diagram for GaudiSequencer:
[legend]

List of all members.

Public Member Functions

 GaudiSequencer (const std::string &name, ISvcLocator *pSvcLocator)
 Standard constructor.
virtual ~GaudiSequencer ()
 Destructor.
virtual StatusCode initialize ()
 Algorithm initialization.
virtual StatusCode execute ()
 Algorithm execution.
virtual StatusCode finalize ()
 Algorithm finalization.
virtual StatusCode beginRun ()
 Algorithm beginRun.
virtual StatusCode endRun ()
 Algorithm endRun.
void resetExecuted ()
 Called before an event processing.
void membershipHandler (Property &theProp)
 for asynchronous changes in the list of algorithms

Protected Member Functions

StatusCode decodeNames ()
 Decode a vector of string.

Private Member Functions

 GaudiSequencer (const GaudiSequencer &a)
 Private copy, copy not allowed.
GaudiSequenceroperator= (const GaudiSequencer &a)
 Private assignment operator: This is not allowed.

Private Attributes

StringArrayProperty m_names
 Input string, list of algorithms.
std::vector< AlgorithmEntrym_entries
 List of algorithms to process.
bool m_modeOR
 Indicates that the OR is wanted instead of AND.
bool m_shortCircuit
 Indicates whether to stop processing as soon as possible, or to always execute _all_ subalgorithms.
bool m_ignoreFilter
 True if one continues always.
bool m_isInitialized
 Indicate that we are ready.
bool m_measureTime
 Flag to measure time.
bool m_returnOK
 Forces the sequencer to return a good status.
ISequencerTimerToolm_timerTool
 Pointer to the timer tool.
int m_timer
 Timer number for the sequencer.

Classes

class  AlgorithmEntry


Detailed Description

Sequencer for executing several algorithms, stopping when one is faulty.

Author:
Olivier Callot
Date:
2004-05-13

Definition at line 18 of file GaudiSequencer.h.


Constructor & Destructor Documentation

GaudiSequencer::GaudiSequencer ( const std::string name,
ISvcLocator pSvcLocator 
)

Standard constructor.

Definition at line 20 of file GaudiSequencer.cpp.

00022   : GaudiAlgorithm ( name , pSvcLocator )
00023   , m_timerTool( 0 )
00024 {
00025   declareProperty( "Members"             , m_names                  );
00026   declareProperty( "ModeOR"              , m_modeOR         = false );
00027   declareProperty( "IgnoreFilterPassed"  , m_ignoreFilter   = false );
00028   declareProperty( "MeasureTime"         , m_measureTime    = false );
00029   declareProperty( "ReturnOK"            , m_returnOK       = false );
00030   declareProperty( "ShortCircuit"        , m_shortCircuit   = true  );
00031 
00032   m_names.declareUpdateHandler (& GaudiSequencer::membershipHandler, this );
00033 }

GaudiSequencer::~GaudiSequencer (  )  [virtual]

Destructor.

Definition at line 37 of file GaudiSequencer.cpp.

00037 {}

GaudiSequencer::GaudiSequencer ( const GaudiSequencer a  )  [private]

Private copy, copy not allowed.


Member Function Documentation

StatusCode GaudiSequencer::initialize (  )  [virtual]

Algorithm initialization.

Reimplemented from GaudiAlgorithm.

Definition at line 42 of file GaudiSequencer.cpp.

00042                                       {
00043   GaudiAlgorithm::initialize();
00044 
00045   debug() << "==> Initialise" << endmsg;
00046 
00047   StatusCode status = decodeNames();
00048   if ( !status.isSuccess() ) return status;
00049 
00050   m_timerTool = tool<ISequencerTimerTool>( "SequencerTimerTool" );
00051   if ( m_timerTool->globalTiming() ) m_measureTime = true;
00052 
00053   if ( m_measureTime ) {
00054     m_timer = m_timerTool->addTimer( name() );
00055     m_timerTool->increaseIndent();
00056   } else {
00057     release( m_timerTool );
00058     m_timerTool = 0;
00059   }
00060 
00061   //== Initialize the algorithms
00062   std::vector<AlgorithmEntry>::iterator itE;
00063   for ( itE = m_entries.begin(); m_entries.end() != itE; itE++ ) {
00064     if ( m_measureTime ) {
00065       itE->setTimer( m_timerTool->addTimer( itE->algorithm()->name() ) );
00066     }
00067 
00068     status = itE->algorithm()->sysInitialize();
00069     if ( !status.isSuccess() ) {
00070       return Error( "Can not initialize " + itE->algorithm()->name(),
00071                     status );
00072     }
00073   }
00074   if ( m_measureTime ) m_timerTool->decreaseIndent();
00075 
00076   return StatusCode::SUCCESS;
00077 }

StatusCode GaudiSequencer::execute (  )  [virtual]

Algorithm execution.

Reimplemented from GaudiAlgorithm.

Definition at line 82 of file GaudiSequencer.cpp.

00082                                    {
00083 
00084   if ( m_measureTime ) m_timerTool->start( m_timer );
00085 
00086   debug() << "==> Execute" << endmsg;
00087 
00088   StatusCode result = StatusCode::SUCCESS;
00089 
00090   bool seqPass = !m_modeOR; //  for OR, result will be false, unless (at least) one is true
00091                             //  for AND, result will be true, unless (at least) one is false
00092                             //    also see comment below ....
00093 
00094   std::vector<AlgorithmEntry>::const_iterator itE;
00095   for ( itE = m_entries.begin(); m_entries.end() != itE; ++itE ) {
00096     Algorithm* myAlg = itE->algorithm();
00097     if ( ! myAlg->isEnabled() ) continue;
00098       if ( ! myAlg->isExecuted() ) {
00099       if ( m_measureTime ) m_timerTool->start( itE->timer() );
00100         result = myAlg->sysExecute();
00101       if ( m_measureTime ) m_timerTool->stop( itE->timer() );
00102         myAlg->setExecuted( true );
00103         if ( ! result.isSuccess() ) break;  //== Abort and return bad status
00104 
00105       }
00106       //== Check the returned status
00107       if ( !m_ignoreFilter ) {
00108         bool passed = myAlg->filterPassed();
00109       if ( itE->reverse() ) passed = !passed;
00110 
00111         //== indicate our own result. For OR, exit as soon as true.
00112         //        If no more, will exit with false.
00113         //== for AND, exit as soon as false. Else, will be true (default)
00114 
00115       // if not short-circuiting, make sure we latch iPass to 'true' in
00116       // OR mode (i.e. it is sufficient for one item to be true in order
00117       // to be true at the end, and thus we start out at 'false'), and latch
00118       // to 'false' in AND mode (i.e. it is sufficient for one item to
00119       // be false to the false in the end, and thus we start out at 'true')
00120       // -- i.e. we should not just blindly return the 'last' passed status!
00121 
00122       // or to put it another way: in OR mode, we don't care about things
00123       // which are false, as they leave our current state alone (provided
00124       // we stared as 'false'!), and in AND mode, we keep our current
00125       // state until someone returns 'false' (provided we started as 'true')
00126       if ( m_modeOR ? passed : !passed ) {
00127         seqPass = passed;
00128         if (m_shortCircuit) break;
00129       }
00130     }
00131 
00132   }
00133   if ( !m_ignoreFilter && !m_entries.empty() ) setFilterPassed( seqPass );
00134   setExecuted( true );
00135 
00136   if ( m_measureTime ) m_timerTool->stop( m_timer );
00137 
00138   return m_returnOK ? StatusCode::SUCCESS : result;
00139 }

StatusCode GaudiSequencer::finalize (  )  [virtual]

Algorithm finalization.

Reimplemented from GaudiAlgorithm.

Definition at line 144 of file GaudiSequencer.cpp.

00144                                     {
00145 
00146   debug() << "==> Finalize" << endmsg;
00147   return  GaudiAlgorithm::finalize();
00148 }

StatusCode GaudiSequencer::beginRun (  )  [virtual]

Algorithm beginRun.

Reimplemented from Algorithm.

Definition at line 153 of file GaudiSequencer.cpp.

00153                                       {
00154 
00155   if ( !isEnabled() ) return StatusCode::SUCCESS;
00156 
00157   debug() << "==> beginRun" << endmsg;
00158   return StatusCode::SUCCESS;
00159 }

StatusCode GaudiSequencer::endRun (  )  [virtual]

Algorithm endRun.

Reimplemented from Algorithm.

Definition at line 164 of file GaudiSequencer.cpp.

00164                                     {
00165 
00166   if ( !isEnabled() ) return StatusCode::SUCCESS;
00167 
00168   debug() << "==> endRun" << endmsg;
00169   return StatusCode::SUCCESS;
00170 }

void GaudiSequencer::resetExecuted (  )  [virtual]

Called before an event processing.

Reimplemented from Algorithm.

Definition at line 175 of file GaudiSequencer.cpp.

00175                                      {
00176   Algorithm::resetExecuted();
00177   // algorithm doesn't call resetExecuted of subalgos! should it???
00178   std::vector<AlgorithmEntry>::const_iterator itE;
00179   for ( itE = m_entries.begin(); m_entries.end() != itE; ++itE ) {
00180     itE->algorithm()->resetExecuted();
00181   }
00182 }

void GaudiSequencer::membershipHandler ( Property theProp  ) 

for asynchronous changes in the list of algorithms

Definition at line 364 of file GaudiSequencer.cpp.

00365 {
00366   // no action for not-yet initialized sequencer 
00367   if ( Gaudi::StateMachine::INITIALIZED > FSMState() ) { return ; } // RETURN 
00368   
00369   decodeNames().ignore();
00370   
00371   if  ( !m_measureTime ) { return ; }                                // RETURN 
00372   
00373   // add the entries into timer table: 
00374   
00375   if ( 0 == m_timerTool ) 
00376   { m_timerTool = tool<ISequencerTimerTool>( "SequencerTimerTool" ) ; }
00377   
00378   if ( m_timerTool->globalTiming() ) m_measureTime = true;
00379   
00380   m_timer = m_timerTool->addTimer( name() );
00381   m_timerTool->increaseIndent();
00382   
00383   for ( std::vector<AlgorithmEntry>::iterator itE = m_entries.begin() ; 
00384         m_entries.end() != itE; ++itE ) 
00385   {
00386     itE->setTimer( m_timerTool->addTimer( itE->algorithm()->name() ) );
00387   }
00388   
00389   m_timerTool->decreaseIndent();
00390   
00391 }

StatusCode GaudiSequencer::decodeNames (  )  [protected]

Decode a vector of string.

Definition at line 192 of file GaudiSequencer.cpp.

00192                                          {
00193 
00194   StatusCode final = StatusCode::SUCCESS;
00195   m_entries.clear();
00196 
00197   //== Get the "Context" option if in the file...
00198   IJobOptionsSvc* jos = svc<IJobOptionsSvc>( "JobOptionsSvc" );
00199   bool addedContext = false;  //= Have we added the context ?
00200   bool addedRootInTES = false;  //= Have we added the rootInTES ?
00201   bool addedGlobalTimeOffset = false;  //= Have we added the globalTimeOffset ?
00202 
00203 
00204   //= Get the Application manager, to see if algorithm exist
00205   IAlgManager* appMgr = svc<IAlgManager>("ApplicationMgr");
00206   const std::vector<std::string>& nameVector = m_names.value();
00207   std::vector<std::string>::const_iterator it;
00208   for ( it = nameVector.begin(); nameVector.end() != it; it++ ) {
00209     const Gaudi::Utils::TypeNameString typeName(*it);
00210     const std::string &theName = typeName.name();
00211     const std::string &theType = typeName.type();
00212 
00213     //== Check wether the specified algorithm already exists. If not, create it
00214     StatusCode result = StatusCode::SUCCESS;
00215     SmartIF<IAlgorithm> myIAlg = appMgr->algorithm(typeName, false); // do not create it now
00216     if ( !myIAlg.isValid() ) {
00217       //== Set the Context if not in the jobOptions list
00218       if ( ""  != context() ||
00219            ""  != rootInTES() ||
00220            0.0 != globalTimeOffset() ) {
00221         bool foundContext = false;
00222         bool foundRootInTES = false;
00223         bool foundGlobalTimeOffset = false;
00224         const std::vector<const Property*>* properties = jos->getProperties( theName );
00225         if ( 0 != properties ) {
00226           // Iterate over the list to set the options
00227           for ( std::vector<const Property*>::const_iterator itProp = properties->begin();
00228                itProp != properties->end();
00229                itProp++ )   {
00230             const StringProperty* sp = dynamic_cast<const StringProperty*>(*itProp);
00231             if ( 0 != sp )    {
00232               if ( "Context" == (*itProp)->name() ) {
00233                 foundContext = true;
00234               }
00235               if ( "RootInTES" == (*itProp)->name() ) {
00236                 foundRootInTES = true;
00237               }
00238               if ( "GlobalTimeOffset" == (*itProp)->name() ) {
00239                 foundGlobalTimeOffset = true;
00240               }
00241             }
00242           }
00243         }
00244         if ( !foundContext && "" != context() ) {
00245           StringProperty contextProperty( "Context", context() );
00246           jos->addPropertyToCatalogue( theName, contextProperty ).ignore();
00247           addedContext = true;
00248         }
00249         if ( !foundRootInTES && "" != rootInTES() ) {
00250           StringProperty rootInTESProperty( "RootInTES", rootInTES() );
00251           jos->addPropertyToCatalogue( theName, rootInTESProperty ).ignore();
00252           addedRootInTES = true;
00253         }
00254         if ( !foundGlobalTimeOffset && 0.0 != globalTimeOffset() ) {
00255           DoubleProperty globalTimeOffsetProperty( "GlobalTimeOffset", globalTimeOffset() );
00256           jos->addPropertyToCatalogue( theName, globalTimeOffsetProperty ).ignore();
00257           addedGlobalTimeOffset = true;
00258         }
00259       }
00260 
00261       Algorithm *myAlg = 0;
00262       result = createSubAlgorithm( theType, theName, myAlg );
00263       // (MCl) this should prevent bug #35199... even if I didn't manage to
00264       // reproduce it with a simple test.
00265       if (result.isSuccess()) myIAlg = myAlg;
00266     } else {
00267       Algorithm *myAlg = dynamic_cast<Algorithm*>(myIAlg.get());
00268       if (myAlg) {
00269         subAlgorithms()->push_back(myAlg);
00270         // when the algorithm is not created, the ref count is short by one, so we have to fix it.
00271         myAlg->addRef();
00272       }
00273     }
00274 
00275     //== Remove the property, in case this is not a GaudiAlgorithm...
00276     if ( addedContext ) {
00277       jos->removePropertyFromCatalogue( theName, "Context" ).ignore();
00278       addedContext = false;
00279     }
00280     if ( addedRootInTES ) {
00281       jos->removePropertyFromCatalogue( theName, "RootInTES" ).ignore();
00282       addedRootInTES = false;
00283     }
00284     if ( addedGlobalTimeOffset ) {
00285       jos->removePropertyFromCatalogue( theName, "GlobalTimeOffset" ).ignore();
00286       addedGlobalTimeOffset = false;
00287     }
00288 
00289     // propagate the sub-algorithm into own state. 
00290     if ( result.isSuccess () && 
00291          Gaudi::StateMachine::INITIALIZED <= FSMState() && 
00292          myIAlg.isValid   () && 
00293          Gaudi::StateMachine::INITIALIZED  > myIAlg->FSMState() ) 
00294     {
00295       StatusCode sc = myIAlg->sysInitialize() ;
00296       if  ( sc.isFailure() ) { result = sc ; }
00297     }
00298     
00299     // propagate the sub-algorithm into own state. 
00300     if ( result.isSuccess () && 
00301          Gaudi::StateMachine::RUNNING <= FSMState() && 
00302          myIAlg.isValid   () && 
00303          Gaudi::StateMachine::RUNNING  > myIAlg->FSMState() ) 
00304     {
00305       StatusCode sc = myIAlg->sysStart () ;
00306       if  ( sc.isFailure() ) { result = sc ; }
00307     }
00308 
00309     //== Is it an Algorithm ?  Strange test...
00310     if ( result.isSuccess() ) {
00311       // TODO: (MCl) it is possible to avoid the dynamic_cast in most of the
00312       //             cases by keeping the result of createSubAlgorithm.
00313       Algorithm*  myAlg = dynamic_cast<Algorithm*>(myIAlg.get());
00314       if (myAlg!=0) {
00315         // Note: The reference counting is kept by the system of sub-algorithms
00316         m_entries.push_back( AlgorithmEntry( myAlg ) );
00317         debug () << "Added algorithm " << theName << endmsg;
00318       } else {
00319         warning() << theName << " is not an Algorithm - failed dynamic_cast"
00320                   << endmsg;
00321         final = StatusCode::FAILURE;
00322       }
00323     } else {
00324       warning() << "Unable to find or create " << theName << endmsg;
00325       final = result;
00326     }
00327 
00328   }
00329 
00330   release(appMgr).ignore();
00331   release(jos).ignore();
00332 
00333   //== Print the list of algorithms
00334   MsgStream& msg = info();
00335   if ( m_modeOR ) msg << "OR ";
00336   msg << "Member list: ";
00337   std::vector<AlgorithmEntry>::iterator itE;
00338   for ( itE = m_entries.begin(); m_entries.end() != itE; itE++ ) {
00339     Algorithm* myAlg = (*itE).algorithm();
00340     std::string myAlgType = System::typeinfoName( typeid( *myAlg) ) ;
00341     if ( myAlg->name() == myAlgType ) {
00342       msg << myAlg->name();
00343     } else {
00344       msg << myAlgType << "/" << myAlg->name();
00345     }
00346     if ( itE+1 != m_entries.end() ) msg << ", ";
00347   }
00348   if ( "" != context() ) msg << ", with context '" << context() << "'";
00349   if ( "" != rootInTES() ) msg << ", with rootInTES '" << rootInTES() << "'";
00350   if ( 0.0 != globalTimeOffset() ) msg << ", with globalTimeOffset " << globalTimeOffset();
00351   msg << endmsg;
00352 
00353   return final;
00354 
00355 }

GaudiSequencer& GaudiSequencer::operator= ( const GaudiSequencer a  )  [private]

Private assignment operator: This is not allowed.


Member Data Documentation

Input string, list of algorithms.

Definition at line 72 of file GaudiSequencer.h.

List of algorithms to process.

Definition at line 73 of file GaudiSequencer.h.

bool GaudiSequencer::m_modeOR [private]

Indicates that the OR is wanted instead of AND.

Definition at line 74 of file GaudiSequencer.h.

Indicates whether to stop processing as soon as possible, or to always execute _all_ subalgorithms.

Definition at line 75 of file GaudiSequencer.h.

True if one continues always.

Definition at line 77 of file GaudiSequencer.h.

Indicate that we are ready.

Definition at line 78 of file GaudiSequencer.h.

Flag to measure time.

Definition at line 79 of file GaudiSequencer.h.

Forces the sequencer to return a good status.

Definition at line 80 of file GaudiSequencer.h.

Pointer to the timer tool.

Definition at line 81 of file GaudiSequencer.h.

int GaudiSequencer::m_timer [private]

Timer number for the sequencer.

Definition at line 82 of file GaudiSequencer.h.


The documentation for this class was generated from the following files:

Generated at Thu Sep 30 09:58:30 2010 for Gaudi Framework, version v21r11 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004